bootstrap clide-hosted Claude sessions (Epic B)
Per D-83 the clide-hosted stream-json session is the primary dogfood target — the process clide spawns, so the one clide can fully equip. Adds a Flutter-free agent_bootstrap module and injects it centrally in ClaudeSessionOrchestrator.spawn so every hosted session (primary, secondary, fork, teammate) is handed: - CLIDE_SOCK (the per-workspace socket, D-70) + CLIDE_WORKSPACE in its env, and `clide` prepended to PATH when not already resolvable, so `clide …` works with zero manual socket discovery (T-215); - a system-prompt context note (--append-system-prompt) telling it it is inside clide and how to drive the IDE via `clide …`, plus the D-6 parity contract; the note merges with the team preamble into one --append-system-prompt (T-216); - a Bash(clide:*) allow rule (--allowedTools) so clide calls aren't prompted (T-217). The PATH resolver no-ops when clide is already on PATH (installed case, T-211) and falls back to ~/.local/bin and the dev native/<os>-<arch> tree; it degrades gracefully when none is found. Pure helpers are unit-tested; the fork-args test is made position-independent. Closes T-214, T-215, T-216, T-217 (under T-208 "Give Claude hands"). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -58,3 +58,10 @@ INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by,
|
||||
|
||||
Resolved (2026-06-03): recorded as D-83. Decision — clide commits to BOTH agent models with the clide-HOSTED stream-json session (D-77/D-78) as the PRIMARY dogfood target (the one clide spawns, so the one Epic B/T-214 bootstraps: CLIDE_SOCK/CLIDE_WORKSPACE + PATH + context note + Bash(clide *) allow rule), and the EXTERNAL CLI driver (D-68) as a first-class but SECONDARY, best-effort integration (manual install via T-212; no promise to observe its non-clide tool use). Epic C/T-218 parity is scoped to clide''s own surfaces reflected through the CLI in both directions; an external agent''s side-channel reads/tests/git are out of parity scope.', NULL, '2026-06-03 09:05:48', '2026-06-03 09:05:48', '2026-06-03 09:05:48', NULL, 'c6b6237b6f3d7f072a4b9b0a4cc30bc9', 1) ON CONFLICT(hash) DO NOTHING;
|
||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-224', 'status', 'in_progress', 'done', NULL, '2026-06-03 09:05:50', '2026-06-03 09:05:50', '2026-06-03 09:05:50', NULL, 'e6b1c1f085d251762e927b9ea9d20076', 1) ON CONFLICT(hash) DO NOTHING;
|
||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-215', 'status', 'backlog', 'in_progress', NULL, '2026-06-03 09:09:43', '2026-06-03 09:09:43', '2026-06-03 09:09:43', NULL, '6fc70c3a2c6102268eefaa757bf6b1d9', 1) ON CONFLICT(hash) DO NOTHING;
|
||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-217', 'status', 'backlog', 'in_progress', NULL, '2026-06-03 09:09:43', '2026-06-03 09:09:43', '2026-06-03 09:09:43', NULL, '7751a9475bab7a458df1fa29ba115167', 1) ON CONFLICT(hash) DO NOTHING;
|
||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-216', 'status', 'backlog', 'in_progress', NULL, '2026-06-03 09:09:43', '2026-06-03 09:09:43', '2026-06-03 09:09:43', NULL, 'a21641c8d9b1e859255cceffe93db738', 1) ON CONFLICT(hash) DO NOTHING;
|
||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-217', 'status', 'in_progress', 'done', NULL, '2026-06-03 09:18:28', '2026-06-03 09:18:28', '2026-06-03 09:18:28', NULL, '980afb083f759f6210c2ef24fea52c37', 1) ON CONFLICT(hash) DO NOTHING;
|
||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-216', 'status', 'in_progress', 'done', NULL, '2026-06-03 09:18:28', '2026-06-03 09:18:28', '2026-06-03 09:18:28', NULL, 'a76b209ff9d4985dd2f78a858a64c8cc', 1) ON CONFLICT(hash) DO NOTHING;
|
||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-215', 'status', 'in_progress', 'done', NULL, '2026-06-03 09:18:28', '2026-06-03 09:18:28', '2026-06-03 09:18:28', NULL, 'ff89bb398cb6f4911b1c5aac4e307834', 1) ON CONFLICT(hash) DO NOTHING;
|
||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-214', 'status', 'backlog', 'done', NULL, '2026-06-03 09:18:38', '2026-06-03 09:18:38', '2026-06-03 09:18:38', NULL, '6266403d6e099befafc78b5d368e938a', 1) ON CONFLICT(hash) DO NOTHING;
|
||||
|
||||
@@ -85,3 +85,7 @@ INSERT INTO tickets (id, type, parent_id, title, description, status, priority,
|
||||
INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-224', 'task', 'T-208', 'Decide the dogfood agent model (governance Q/D record)', 'Gap 5 from self-analysis.md — foundational. Two distinct ''Claude inside clide'' stories with different gaps: (A) the clide-HOSTED stream-json session (D-77/D-78) — the user''s primary Claude pane, which itself needs `clide` on PATH to drive the surrounding IDE; (B) an EXTERNAL agent (e.g. a Claude Code harness, TERM_PROGRAM=zed as observed) driving via `clide ...` IPC, which clide cannot fully observe because plain file reads / `make test` / `git` bypass clide. Decide the intended model — hosted, external, or both — and record it under governance/ (claim via `pql decisions claim`). Gates how Epic B bootstraps and how Epic C frames observability.
|
||||
|
||||
Resolved (2026-06-03): recorded as D-83. Decision — clide commits to BOTH agent models with the clide-HOSTED stream-json session (D-77/D-78) as the PRIMARY dogfood target (the one clide spawns, so the one Epic B/T-214 bootstraps: CLIDE_SOCK/CLIDE_WORKSPACE + PATH + context note + Bash(clide *) allow rule), and the EXTERNAL CLI driver (D-68) as a first-class but SECONDARY, best-effort integration (manual install via T-212; no promise to observe its non-clide tool use). Epic C/T-218 parity is scoped to clide''s own surfaces reflected through the CLI in both directions; an external agent''s side-channel reads/tests/git are out of parity scope.', 'done', 'high', NULL, NULL, 'D-77', '2026-06-02 18:13:52', '2026-06-03 09:05:50', NULL, '8ba80265666e3103ea82c02fdf48e632', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
|
||||
INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-215', 'task', 'T-214', 'Export CLIDE_SOCK/CLIDE_WORKSPACE + ensure clide on the child PATH', 'When clide spawns/hosts an agent (the stream-json session per D-77, and any launched agent), inject CLIDE_SOCK (the per-workspace deterministic socket, D-70) and CLIDE_WORKSPACE into the child env, and guarantee `clide` is on the child PATH. Acceptance: a hosted agent''s shell has both vars and `clide ping` works with zero manual socket discovery. Blocked by Epic A delivery.', 'done', 'high', NULL, NULL, NULL, '2026-06-02 18:13:52', '2026-06-03 09:18:28', NULL, '220432969915ff7b84a64a3ef880399f', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
|
||||
INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-217', 'task', 'T-214', 'Pre-seed a Bash(clide *) permission allow rule for hosted agents', 'So the hosted agent is not prompted on every `clide ...` call. Acceptance: clide-hosted sessions get a Bash(clide *) allow rule in their effective settings.', 'done', 'medium', NULL, NULL, NULL, '2026-06-02 18:13:52', '2026-06-03 09:18:28', NULL, 'e592d53b85d813172fc1eab377c407ba', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
|
||||
INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-216', 'task', 'T-214', 'Inject an agent context note describing the CLI surface + parity contract', 'Give the hosted agent a short note (CLAUDE.md fragment / system reminder) stating it is inside clide and how to drive the editor / git / file tree / panes via `clide ...`, plus the D-6 parity contract. Acceptance: a hosted agent is told, without the user having to explain it.', 'done', 'medium', NULL, NULL, NULL, '2026-06-02 18:13:52', '2026-06-03 09:18:28', NULL, 'ec64cf891f2150b6b6421a85e842899f', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
|
||||
INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-214', 'epic', 'T-208', 'Bootstrap the clide-hosted/launched agent', 'Gap 2 from self-analysis.md. Even with the binary installed, a fresh session has no signal it is hosted by clide. There IS an MCP discovery lock (~/.claude/ide/<pid>.lock pointing at workspace + SSE URL) but NOTHING for the Bash/CLI path: no CLIDE_SOCK/CLIDE_WORKSPACE env var, no injected context note, no pre-seeded Bash(clide *) allow rule. Discovery is the difference between a capability existing and getting used — the probing agent had to be told ''you''re inside clide'' and then hunt for the socket.', 'done', 'high', NULL, NULL, 'D-6', '2026-06-02 18:13:52', '2026-06-03 09:18:38', NULL, '5c952e43be93015d72028c67267cc608', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
|
||||
|
||||
Reference in New Issue
Block a user