Dev - #464
Merged
Merged
Dev#464
Conversation
The star history chart is currently broken due to GitHub stargazer API restrictions, so the README and all localized READMEs now point to a working alternative. Also switch the chart image endpoints from /chart to /svg and the wrapping links to hash-based URLs.
Fix broken star history chart
The mkdocs source moves to CraftOS-dev/craftbot-live, where the rest of the product's web presence lives. Nothing in this repo referenced mkdocs/: no workflow built it, no script or spec pulled from it, and no file outside the directory linked into it, so the removal is self-contained. The one coupling ran the other way. mkdocs.yml generated its default-actions page by parsing the @action(...) decorators in app/data/action/. That generator moved with the docs and now runs on demand against a checkout of this repo, so the catalogue still comes from these decorators and stays refreshable after actions change here.
CraftBot V1.4.2 update: Connect to external app with multiple accounts, a graph-based Memory system as second brain, safer Living UI updates.
ActivityLogGuard.begin() had no way to tell a batch mate still running (execute_parallel dispatches all calls before any of them completes) apart from a row that survived a crash and restart. Track in-flight idem_keys per guard instance: a restart creates a fresh, empty set, so the crash-recovery path still fires exactly as before. Signed-off-by: Amir Fathi <amirfathi.me@gmail.com>
…ed memory processing logic
Prevent free-text submission during IME composition in question box
bug:context overflow causing event stream collapsed
Add per-file locks for write_file and stream_edit
Adds an Origin/Host allowlist plus a per-process session token for /ws, and an aiohttp middleware applying the same judgement to every /api/* route. Also fixes _validate_path to use path containment instead of a string prefix, and sanitises the chat-attachment download name. Verified: the /ws handshake and the /api guard were attacked with foreign origins, stolen tokens, absent Origin, DNS-rebinding Hosts, other loopback ports and case variants -- all refused. Legitimate traffic still passes in both topologies (run.py static proxy and the Vite dev server) and for the Agent App bridge. run.py now forwards Host/Origin/Sec-Fetch-Site so the proxy cannot launder them; confirmed urllib really does send the forwarded Host rather than overriding it. Full suite on the branch: 1189 passed, 1 failed -- the same pre-existing failure present on V1.4.3 before this PR.
…452) * fix: A2App agent-token gate is bypassed by sending any Origin header * fix validate checks * fix(a2app): fail closed without agent token, embed apps same-site, warn on destructive GET ops * fix: LAN Sharing * fix: validate checks
Applies guard_request to the passthrough and to the WebSocket upgrade, and replaces upstream Access-Control-* with the proxy's own CORS policy. Header copying uses .add() so multiple Set-Cookie survive. Includes a follow-up fix requiring a credential for OPTIONS through a share channel, which was otherwise forwarded upstream uncredentialed.
Removes the observation system. It could never succeed: run_observe_step built Python source by interpolating json.dumps() output, so any action output containing null/true/false raised NameError, and the retry loop then burned up to 60s (600s for observers built via from_dict, whose default disagreed with __init__) before reporting failure. Confirmed unused -- no persisted action, skill or JSON/YAML definition declares an observer, and Action.from_dict reads keys individually so older data carrying one still loads. Also replaces the process-wide sys.stdout/sys.stderr swap with per-thread routing in the installer, so a worker's output reaches the log panel without capturing every other thread. Includes a follow-up fix: the new wrapper held sys.stdout unconditionally, but the installer is frozen console=False, so under pythonw both streams are None -- every stray print from a non-routed thread became AttributeError, where print() had previously been a silent no-op. A null-stream stand-in restores that. Suite on the merged result: 1239 passed, 1 pre-existing failure.
Replaces killing by port-substring and by process name with a ledger of processes we started, identified by pid + creation time so a recycled pid can never be mistaken for ours. Conflict resolution, app/agent_app/manager.py: #452 moved the tunnel lifecycle out of manager.py into sharing.py, while this branch was fixing the cloudflared reap in manager.py's old copy. Taking either side alone loses something: ours drops the reap fix, theirs resurrects code that no longer belongs here. Resolved by keeping the sharing.py structure and PORTING the fix to where the tunnel now lives: * sharing.py registers each cloudflared it starts in the ledger (ROLE_TUNNEL, pid + start time); * _kill_orphans reaps by that recorded identity instead of running `Stop-Process -Name cloudflared` / `pkill -f cloudflared`, which took down every cloudflared on the machine -- including a tunnel the user runs for their own production work. Without this port the mass-kill would have survived the merge silently, since #452 carried it across into sharing.py untouched. Suite on the merged result: 1257 passed, 0 failed. This also clears the pre-existing failure in tests/test_agent_app_launch_lock.py (TestLiveness::test_a_live_external_app_is_not_dead), which was failing on V1.4.3 before any of these PRs -- the rewritten listener detection fixes it.
Makes requirements.txt the single source for Python packages; environment.yml keeps only what pip cannot provide (interpreter, tesseract, libcurl, the openssl pin, nodejs) and pulls the rest in with `-r requirements.txt`. Conflict resolution, environment.yml: #457 had just added psutil to the duplicated conda list that this PR removes wholesale. Took this PR's side -- psutil arrives via requirements.txt, where #457 also added it, so nothing is lost. Checked all 49 packages the old conda list carried: every one is either in requirements.txt or deliberately kept as conda-only. None dropped. Note for follow-up, not a defect in this PR: requirements.txt pins nothing (56 packages, zero ==). That predates this change -- the pins removed here lived only in environment.yml's duplicate list, and the default installer path is pip, which has always read the unpinned file. The practical effect is that a fresh install resolves anthropic/openai to majors the code has never been run against (this environment works on anthropic 0.83.0 while the manifest floor says >=0.97.0). Worth a deliberate pinning pass. Suite on the merged result: 1258 passed, 0 failed.
Documentation only: two AGENT.md files (the live agent_file_system copy and the template), version 8 -> 9. Verified the claims against the code on V1.4.3 rather than taking them on trust -- EXCLUSIVE_SOURCES, memory.processing_threshold, _merge_triggers and set_skip_unprocessed_logging all exist and behave as described. The gate was failing on a stale base: the branch was 9 commits behind, so the run was still testing the old validate.ts with its unused verifySystemHashes import, which #452 removed. Updating the branch produced a clean run on all three platforms.
…t-conflation fix: don't flag an in-flight parallel duplicate as crashed
Port of #443 (merged to dev) onto V1.4.3, which carries identical guard code and the identical bug. execute_parallel dispatches a whole batch before any call completes, so two identical irreversible calls issue two begin()s with no complete() between them; the second read the first's INTENT row as a crashed prior attempt and told the model the action may already have happened, while the first was still running. Verified on V1.4.3: the new test fails without the fix and passes with it. Full suite 1259 passed, 0 failed.
…are (#461) Four items from the V1.4.3 hardening list. docker.sock + root container: docker-compose.yml mounted the host's Docker control plane into a container that runs model-chosen shell commands, and the image had no USER. Confirmed nothing in the repo ever used the socket (no docker exec, no docker SDK, no DOCKER_HOST) before removing it, along with the Docker CLI and the gnupg/lsb-release that existed only to add its apt repo. Adds a fixed-uid non-root user and no-new-privileges. .dockerignore: excluded .env but not .credentials/, app/config/settings.json, config.json, agent_file_system/ or logs, so integration tokens and API keys were baked into layers the release workflow pushes to a public registry. MCP stdio injection: the spawn built a shell string, so one embedded quote in an argument ran everything after it. MCP config is editable in the UI, importable from a bundle and writable by the agent. Now a single exec path; the case a list cannot make safe (a Windows .cmd wrapper, which cmd.exe re-parses however it is spawned) is refused with a message saying what to do. Verified by running the injections. Bridge token: validate_bridge_token used == on a caller-supplied header guarding every connected integration. Now hmac.compare_digest on bytes. 1311 passed, ruff clean, 53 new tests. CAVEAT: the Docker image was never built -- no daemon was available. The USER change is the part that needs a real build before a release, and bind-mounted host dirs keep host ownership, so ./workspace needs chown -R 10001:10001 once.
* feat: unify the three install paths, replace the frozen agent * fix: resolve paths in the install E2E, report platforms with no lock * fix: parity check * fix: small ui update * fix: macOS lock file * fix: macos test workflow * ci: macOS debug workflow [vnc] * revert: macos check * feat(launcher): ship the native Rust/Slint launcher, retire the Tk installer * style(launcher): cargo fmt * style(launcher): cargo fmt, fix clippy redundant_closure * fix(launcher): make macOS bundle.sh executable * fix: install problem * retagged lock files
ahmad-ajmal
marked this pull request as ready for review
September 23, 2026 10:29
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.