Commit graph

1023 commits

Author SHA1 Message Date
d231d21a8c Merge pull request 'fix: feat: disinto secrets add — store individual encrypted secrets (#31)' (#35) from fix/issue-31 into main
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
2026-03-28 19:14:02 +00:00
Claude
ec58cb1745 fix: suppress terminal echo for secret input and guard against overwrites
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
- Use `read -rs` to hide typed secret value from terminal
- Prompt for confirmation before overwriting an existing secret

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 19:10:55 +00:00
Claude
1b52761336 fix: feat: disinto secrets add — store individual encrypted secrets (#31)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 19:10:55 +00:00
Agent
e0fe5c80ea fix: feat: disinto secrets migrate — encrypt existing plaintext .env (#33)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
2026-03-28 19:10:46 +00:00
d70301766c Merge pull request 'fix: fix: mount age key directory into agents containers (#32)' (#36) from fix/issue-32 into main
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
2026-03-28 19:04:01 +00:00
johba
e351e02f60 chore: remove smoke-init CI workflow
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
smoke-init spins up a full Forgejo instance inside CI and never
finishes within the 5-minute timeout. It blocks all PRs.

Remove it entirely until it can be optimized to run fast enough.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 18:58:56 +00:00
Agent
3d84390a54 fix: fix: mount age key directory into agents containers (#32)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/push/smoke-init removed
ci/woodpecker/pr/smoke-init removed
2026-03-28 18:53:35 +00:00
johba
6b0e9b5f4d feat: add entrypoint for llama dev-agent container (#29)
Some checks failed
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/smoke-init Pipeline failed
Simple while-true loop that runs dev-poll with llama backend env vars.
No cron, no guard files, no activation state — just polls and spawns.
Repo auto-cloned on first start.

To be used with a separate agents-llama compose service that sets
ANTHROPIC_BASE_URL to the llama-server address.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 17:33:09 +00:00
e6b57dc9f1 fix: fix: install networkx in agents container for build-graph.py (#14) (#28)
Some checks failed
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/smoke-init Pipeline failed
Fixes #14

## Changes

Co-authored-by: Claude <noreply@anthropic.com>
Reviewed-on: #28
Co-authored-by: dev-bot <dev-bot@disinto.local>
Co-committed-by: dev-bot <dev-bot@disinto.local>
2026-03-28 17:12:27 +00:00
2c5f495987 Merge pull request 'fix: fix: remove PROMPT.md files — formulas are the source of truth (#12)' (#27) from fix/issue-12 into main
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
2026-03-28 16:46:16 +00:00
Claude
aa73ff88c4 fix: remove PROMPT.md files — formulas are the source of truth (#12)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
- Delete gardener/PROMPT.md (dust-vs-ore rules already in run-gardener.toml)
- Delete supervisor/PROMPT.md (content covered by run-supervisor.toml;
  migrate unique "Learning" section into formula's journal step)
- Delete vault/PROMPT.md and create formulas/run-vault.toml as the
  source-of-truth formula for vault action classification/routing
- Update supervisor/supervisor-poll.sh to read from formula instead of PROMPT.md
- Update vault/vault-agent.sh to read from formula instead of PROMPT.md
- Update supervisor/AGENTS.md, vault/AGENTS.md, README.md references

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 16:40:21 +00:00
johba
3ce6354f4f fix: add FORGE_URL and PROJECT_REPO_ROOT to crontab env template
Some checks failed
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/smoke-init Pipeline failed
Cron does not inherit compose env vars. Without these, dev-poll fails
with cd: /home/johba/disinto: No such file or directory (host path
instead of container path).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 16:30:43 +00:00
johba
c1939fbb9a chore: delete obsolete skill/ folder — replaced by disinto-factory/
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
The old skill/ reflects tmux-based pre-containerization architecture.
disinto-factory/ is the current skill with Docker Compose setup.

Closes #16

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 15:33:48 +00:00
7fd61e9d0e Merge pull request 'fix: fix: smoke-init should only run on pull_request events, not push (#21)' (#22) from fix/issue-21 into main
Some checks are pending
ci/woodpecker/push/ci Pipeline is pending
ci/woodpecker/push/smoke-init Pipeline is pending
Reviewed-on: #22
2026-03-28 15:32:41 +00:00
Claude
79ae7f8690 fix: fix: smoke-init should only run on pull_request events, not push (#21)
Some checks failed
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/pr/smoke-init Pipeline failed
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 15:32:34 +00:00
johba
55406b1e3d chore: delete unused gardener/recipes — formulas are the source of truth
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
These 4 recipe files (cascade-rebase, chicken-egg-ci, flaky-test,
shellcheck-violations) are never referenced by any script.
The gardener uses formulas/run-gardener.toml.

Closes #23

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 15:31:12 +00:00
645cf82327 Merge pull request 'fix: fix: review-poll.sh still uses tmux for session cleanup and injection (#11)' (#18) from fix/issue-11 into main
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
2026-03-28 15:14:01 +00:00
Claude
d485d5e005 fix: remove unused PR_BRANCH variable after inject function removal
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/push/smoke-init skipped (not init-related)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 14:43:51 +00:00
Claude
42a5a4ef85 fix: review-poll.sh still uses tmux for session cleanup and injection (#11)
Replace tmux session discovery with .sid file globbing for stale session
cleanup and re-review triggering. Remove inject_review_into_dev_session
(dead code — both review and dev sessions now use SDK agent_run).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 14:43:51 +00:00
johba
8c368c632e feat: set 5-minute pipeline timeout after WP repo activation
Some checks failed
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/smoke-init Pipeline failed
Prevents smoke-init and other heavy CI steps from hanging for 40+ min.
Applied automatically during disinto init.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 14:41:17 +00:00
johba
44b180b783 fix: remove lib/env.sh from smoke-init path filter
Some checks failed
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/smoke-init Pipeline failed
env.sh changes don't need a full Forgejo init smoke test.
Prevents 40-minute CI hangs on env fixes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 14:38:35 +00:00
johba
80811498e4 fix: local keyword outside function in env.sh
Some checks failed
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/smoke-init Pipeline failed
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:59:07 +00:00
johba
d82d80cabb fix: preserve FORGE_URL when sourcing .env inside container
Some checks failed
ci/woodpecker/push/ci Pipeline failed
ci/woodpecker/push/smoke-init Pipeline failed
source .env clobbers FORGE_URL from http://forgejo:3000 (Docker DNS)
to http://localhost:3000 (unreachable inside container). Save and
restore FORGE_URL around the source.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:58:46 +00:00
johba
a80bdde5e4 fix: cron polls get no FORGE_TOKEN — env.sh skipped .env in container
Some checks failed
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/smoke-init Pipeline failed
Root cause: env.sh skipped sourcing .env when DISINTO_CONTAINER=1,
assuming compose injects all env vars. But cron jobs do NOT inherit
compose env vars — they only get crontab-level variables.

Result: FORGE_TOKEN was empty in every cron poll. API calls returned
nothing, polls silently found "no open PRs" and exited.

Fix: always source .env regardless of DISINTO_CONTAINER. Compose env
vars (FORGE_URL) are set in the crontab env and take precedence.
Entrypoint also adds FORGE_URL to crontab env vars.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:43:17 +00:00
47d22e014b Merge pull request 'fix: Migrate planner, predictor, supervisor to SDK (#6)' (#17) from fix/issue-6 into main
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
2026-03-28 13:32:18 +00:00
Claude
ab5f96dc96 fix: guard cd in formula_worktree_setup with || return (SC2164)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:16:29 +00:00
Claude
de2e7dc1fb fix: Migrate planner, predictor, supervisor to SDK (#6)
Some checks failed
ci/woodpecker/push/ci Pipeline failed
ci/woodpecker/pr/ci Pipeline failed
Replace tmux-based run_formula_and_monitor() with synchronous agent_run()
from lib/agent-sdk.sh, matching the pattern established in gardener-run.sh.

Key changes per agent:
- Drop agent-session.sh, use agent-sdk.sh (SID_FILE, LOGFILE)
- Remove SESSION_NAME, PHASE_FILE, PHASE_POLL_INTERVAL (tmux/phase artifacts)
- Strip phase protocol from prompt footer (SDK mode needs no phase signals)
- Preserve all prompt composition: context blocks, memory, journal, preflight

Shared helpers added to lib/formula-session.sh:
- build_sdk_prompt_footer(): build_prompt_footer minus phase protocol
- formula_worktree_setup(): fetch + cleanup + create worktree + EXIT trap

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 13:06:34 +00:00
johba
8f389d9dab fix: add USER=agent to crontab env (unbound variable in cron)
Some checks are pending
ci/woodpecker/push/ci Pipeline is pending
ci/woodpecker/push/smoke-init Pipeline is pending
env.sh references $USER which is not set in cron environment.
With set -u (pipefail), this causes env.sh to exit before setting
DISINTO_LOG_DIR, resulting in log writes to the read-only mount.

Root cause of silent cron failures since containerized setup.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:50:57 +00:00
johba
afeb50fc18 fix: cron env missing DISINTO_CONTAINER=1, logs go to ro mount
Some checks failed
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/smoke-init Pipeline failed
Cron jobs run with minimal environment — no Docker compose env vars.
Without DISINTO_CONTAINER=1, env.sh falls back to FACTORY_ROOT for
log paths, which is the read-only disinto mount. Polls silently fail.

Fix: set DISINTO_CONTAINER=1 as crontab environment variable.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:42:34 +00:00
johba
a054e0791d fix: cron entries log to cron.log instead of /dev/null
Some checks failed
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/smoke-init Pipeline failed
Cron poll errors were silently swallowed, making it impossible to
diagnose why agents stopped picking up issues. Now logs to
/home/agent/data/logs/cron.log.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:37:50 +00:00
74d9b328e7 Merge pull request 'fix: Migrate action-agent.sh to SDK + shared libraries (#5)' (#13) from fix/issue-5 into main
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
2026-03-28 11:25:53 +00:00
johba
0762ab73ff fix: review-poll.sh writes log to read-only mount
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
LOGFILE pointed to SCRIPT_DIR (inside the ro disinto mount).
Use DISINTO_LOG_DIR which points to writable /home/agent/data/logs/.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:19:24 +00:00
Claude
6f64013fc6 fix: Migrate action-agent.sh to SDK + shared libraries (#5)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
Rewrite action-agent from tmux session + phase-handler pattern to
synchronous SDK pattern (agent_run via claude -p). Uses shared libraries:
- agent-sdk.sh for one-shot Claude invocation
- issue-lifecycle.sh for issue_check_deps/issue_close/issue_block
- pr-lifecycle.sh for pr_create/pr_walk_to_merge
- worktree.sh for worktree_create/worktree_cleanup

Add default callback stubs to phase-handler.sh (cleanup_worktree,
cleanup_labels) so it is self-contained now that action-agent.sh
no longer sources it. Update agent-smoke.sh accordingly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:15:10 +00:00
Claude
83ab2930e6 fix: Migrate action-agent.sh to SDK + shared libraries (#5)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:15:10 +00:00
johba
02dd03eaaf chore: remove BOOTSTRAP.md, slim CLAUDE.md
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
BOOTSTRAP.md is superseded by the disinto-factory skill (SKILL.md).
CLAUDE.md now just points to AGENTS.md and the skill.
Updated AGENTS.md reference accordingly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:14:42 +00:00
johba
cbe5df52b2 feat: add disinto-factory skill for guided setup and operations
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
Distributable skill file (SKILL.md) that walks an AI agent through:
- First-time factory setup with interactive [ASK] prompts
- Post-init verification checklist
- Mirror configuration to GitHub/Codeberg
- Backlog seeding and issue creation
- Ongoing monitoring: agent status, CI, PRs
- Unsticking blocked issues

Includes:
- scripts/factory-status.sh — one-command factory health check
- references/troubleshooting.md — common issues from real deployments
- Slimmed CLAUDE.md pointing to the skill

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:13:24 +00:00
johba
ed43f9db11 docs: add CLAUDE.md skill file for factory setup and operations
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
Comprehensive guide for AI coding agents (Claude Code, etc.) to:
- Set up a new factory instance in an LXD container
- Run disinto init and verify the stack
- Configure mirrors to GitHub/Codeberg
- Check on dev-agent, review-agent, and CI status
- Unstick blocked issues and trigger manual polls
- File issues for the factory to work on
- Known workarounds for LXD nested Docker

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:08:55 +00:00
johba
10aabf7820 fix: scope smoke-init CI to init-related paths only (#8)
Some checks failed
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/smoke-init Pipeline failed
Skip the heavyweight smoke-init test (spins up full Forgejo inside CI)
for PRs that do not touch init-related code. Saves ~25min of CPU per
unrelated PR.

Closes #8

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 10:42:30 +00:00
johba
481f9fc53a fix: set Docker network for WP CI step containers
Some checks failed
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/smoke-init Pipeline failed
CI step containers spawned by the WP agent (running on host network)
cannot resolve Docker service names like forgejo. Setting
WOODPECKER_BACKEND_DOCKER_NETWORK puts CI containers on the compose
network so they can reach Forgejo for git clone.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 10:14:01 +00:00
johba
83bd909378 fix: allow webhooks to private hosts in Forgejo compose template
Some checks failed
ci/woodpecker/push/ci Pipeline failed
ci/woodpecker/push/smoke-init Pipeline failed
Forgejo blocks outgoing webhooks to non-allowlisted hosts by default.
Woodpecker CI requires webhook delivery for pipeline triggering.
Setting ALLOWED_HOST_LIST=private allows webhooks to any RFC1918 address.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 10:09:59 +00:00
johba
38a7253c11 fix: WP CI agent gRPC: use host networking to bypass Docker bridge (#813)
Docker bridge networking inside LXD (and potentially other nested container
environments) breaks gRPC/HTTP2 between containers. The gRPC handshake
times out because HTTP/2 frames are not properly forwarded.

Fix: run the WP agent with network_mode: host + privileged, connecting
to the server via localhost:9000 (port mapped from the server container).

- Add port 9000 mapping to woodpecker server
- Switch agent to network_mode: host with privileged: true
- Connect agent to localhost:9000 instead of woodpecker:9000
- Add WOODPECKER_GRPC_SECURE=false
- Move healthcheck to port 3333 (avoid clash with Forgejo on 3000)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 09:40:44 +00:00
johba
883cdc812c fix: compose template: SSH mount, PROJECT_REPO_ROOT, revert WOODPECKER_HOST
- Add ~/.ssh mount to agents container (needed for mirror pushes)
- Add PROJECT_REPO_ROOT env to agents and vault-runner containers
- Revert WOODPECKER_HOST to http://woodpecker:8000 (localhost breaks gRPC)
- Remove WOODPECKER_GRPC_ADDR (did not fix gRPC issue)
- Keep WOODPECKER_OPEN for OAuth2 first-user registration

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 09:24:19 +00:00
johba
12d4e6925b fix: disinto init OAuth2 + WP v3 compatibility (#812, #814)
- Rewrite URL-encoded Docker-internal hostnames in OAuth2 redirect
- Submit all Forgejo grant form fields (client_id, state, redirect_uri, granted)
- Add WOODPECKER_OPEN to compose template for first user OAuth registration
- Add WOODPECKER_GRPC_ADDR to compose template
- Fix WP repo activation: use query param with numeric Forgejo repo ID
- WP v3 PAT creation via session cookie + CSRF header

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 08:37:14 +00:00
johba
2b8e250247 Merge pull request 'fix: Migrate gardener-run.sh to SDK + pr-lifecycle (#801)' (#811) from fix/issue-801 into main 2026-03-28 08:32:32 +01:00
openhands
6ab1aeb17c fix: Migrate gardener-run.sh to SDK + pr-lifecycle (#801)
Reuse build_prompt_footer() from formula-session.sh instead of
hand-rolling the API reference and environment sections. Replace
the phase protocol section with SDK completion protocol.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 07:05:18 +00:00
openhands
5adf34e695 fix: Migrate gardener-run.sh to SDK + pr-lifecycle (#801)
Replace tmux-based run_formula_and_monitor architecture with synchronous
agent_run() from agent-sdk.sh. Replace custom CI/review/merge phase
callbacks (~350 lines) with pr_walk_to_merge() from pr-lifecycle.sh.

Key changes:
- Source agent-sdk.sh + pr-lifecycle.sh instead of agent-session.sh
- One-shot claude -p invocation replaces tmux session management
- Bash script IS the state machine (no phase files needed)
- Keep _gardener_execute_manifest() for post-merge manifest execution
- Keep all guards, formula loading, context building unchanged

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 07:02:55 +00:00
johba
1912a24c46 feat: edge proxy + staging container to docker stack (#807)
This PR implements issue #764 by adding two Caddy-based containers to the disinto docker stack:

## Changes

### Edge Proxy Service
- Caddy reverse proxy serving on ports 80/443
- Routes /forgejo/* -> Forgejo:3000
- Routes /ci/* -> Woodpecker:8000
- Default route -> staging container

### Staging Service
- Caddy static file server for staging artifacts
- Serves a default "Nothing shipped yet" page
- CI pipelines can write to the staging-site volume to update content

### Files Modified
- bin/disinto: Updated generate_compose() to add edge + staging services
- bin/disinto: Added generate_caddyfile() function
- bin/disinto: Added generate_staging_index() function
- docker/staging-index.html: New default staging page

## Acceptance Criteria
- [x] disinto init generates docker-compose.yml with edge + staging services
- [x] Edge proxy routes /forgejo/*, /ci/*, and default routes correctly
- [x] Staging container serves default "Nothing shipped yet" page
- [x] docker/ directory contains Caddyfile template generated by disinto init
- [x] disinto up starts all containers including edge and staging

Co-authored-by: johba <johba@users.noreply.codeberg.org>
Reviewed-on: https://codeberg.org/johba/disinto/pulls/807
2026-03-28 07:58:17 +01:00
johba
15f87ead85 Merge pull request 'fix: Migrate review-pr.sh to SDK + pr-lifecycle (#800)' (#810) from fix/issue-800 into main 2026-03-28 07:47:47 +01:00
openhands
d2c71e5dcd fix: Migrate review-pr.sh to SDK + pr-lifecycle (#800)
Register lib/agent-sdk.sh in the CI smoke test so agent_recover_session
resolves for dev-agent.sh and review-pr.sh.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 06:36:32 +00:00
openhands
8f41230fa0 fix: Migrate review-pr.sh to SDK + pr-lifecycle (#800)
Move SID_FILE recovery into agent_recover_session() in lib/agent-sdk.sh
to eliminate remaining duplicate block between dev-agent.sh and
review-pr.sh.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 06:34:26 +00:00