codedeck 0.5.0 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +15 -0
- package/dist/cli/commands/doctor.js +10 -2
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/open.js +49 -12
- package/dist/cli/commands/open.js.map +1 -1
- package/dist/cli/commands/profile.js +191 -0
- package/dist/cli/commands/profile.js.map +1 -0
- package/dist/cli/commands/run.js +36 -5
- package/dist/cli/commands/run.js.map +1 -1
- package/dist/cli/commands/setup.js +175 -23
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/config/config.js +82 -2
- package/dist/config/config.js.map +1 -1
- package/dist/daemon/daemon.js +1 -0
- package/dist/daemon/daemon.js.map +1 -1
- package/dist/drivers/codex/parser.js +14 -10
- package/dist/drivers/codex/parser.js.map +1 -1
- package/dist/drivers/helpers.js +17 -1
- package/dist/drivers/helpers.js.map +1 -1
- package/dist/drivers/session-runtime.js +3 -0
- package/dist/drivers/session-runtime.js.map +1 -1
- package/dist/open/contract.js.map +1 -1
- package/dist/open/launchers/claude.js +8 -2
- package/dist/open/launchers/claude.js.map +1 -1
- package/dist/plugin/agents/auditor.md +2 -0
- package/dist/plugin/agents/general.md +10 -2
- package/dist/plugin/agents/orchestrator-edit.md +10 -2
- package/dist/plugin/agents/orchestrator-read.md +10 -2
- package/dist/plugin/agents/orchestrator.md +18 -3
- package/dist/plugin/prompts/_partials/dispatch.md +2 -0
- package/dist/plugin/prompts/_partials/reports-dispatch.md +5 -0
- package/dist/plugin/prompts/_partials/reports-general.md +5 -0
- package/dist/plugin/prompts/_partials/spec-gates.md +6 -0
- package/dist/plugin/prompts/_partials/worktree.md +1 -1
- package/dist/plugin/prompts/roles/general.md +1 -0
- package/dist/plugin/prompts/roles/orchestrator-edit.md +1 -0
- package/dist/plugin/prompts/roles/orchestrator-read.md +1 -0
- package/dist/plugin/prompts/roles/orchestrator.md +3 -1
- package/dist/utils/process.js +88 -0
- package/dist/utils/process.js.map +1 -1
- package/dist/web/canvas-page.js +79 -33
- package/dist/web/canvas-page.js.map +1 -1
- package/dist/web/review-page.js +121 -22
- package/dist/web/review-page.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
# DO NOT EDIT: generated from roles/general.md + partials (review-self, worktree, dispatch, proof, rename-run, commit, pr-writer).
|
|
2
|
+
# DO NOT EDIT: generated from roles/general.md + partials (review-self, worktree, dispatch, proof, rename-run, commit, pr-writer, reports-general).
|
|
3
3
|
# Do not hand-edit; edit the manifest or partials and rebuild.
|
|
4
4
|
name: general
|
|
5
5
|
description: Do CodeDeck work directly in the current workspace, with evidence.
|
|
@@ -11,11 +11,13 @@ description: Do CodeDeck work directly in the current workspace, with evidence.
|
|
|
11
11
|
- If the human waived review, or the change is small enough that review would be wasteful, say that you skipped it and why. Do not skip silently.
|
|
12
12
|
|
|
13
13
|
- Use `codedeck run --role <role> --worktree "<briefing>"` so the worker has an attributable worktree, diff, and role contract.
|
|
14
|
-
- Worktree is a choice, not a default. `--worktree` is a fresh checkout of the current repo at HEAD, so it cannot reach another repository
|
|
14
|
+
- Worktree is a choice, not a default. `--worktree` is a fresh checkout of the current repo at HEAD, so it cannot reach another repository, an uncommitted working tree, or gitignored/untracked files (e.g. `.specs/`) elsewhere. A slice that reproduces or fixes a bug in place, that touches a different repo, or names gitignored/untracked files runs `--no-worktree --cwd <target>` instead, on a harness whose file access can reach that target.
|
|
15
15
|
|
|
16
16
|
- Always include `--role`. It selects the harness and model the human configured for that role. It also loads that role's contract into the worker prompt, including for non-Claude harnesses.
|
|
17
17
|
- Without `--role`, `codedeck run` uses the default harness and sends only a loose briefing. It ignores the user's role binding and gives a more expensive worker less direction.
|
|
18
18
|
- The role owns the harness and the model. `--agent` and `--model` are ignored for a bound role (run warns and keeps the binding), so you cannot swap the worker onto another harness. Changing the pairing is a `codedeck setup` decision, not a dispatch flag.
|
|
19
|
+
- Dispatch only via `run --role ... --bg --json`; `open` is interactive, never dispatch.
|
|
20
|
+
- `doctor` shows Role bindings; never probe `dist/` or `setup --help`, and an unbound role warns.
|
|
19
21
|
- Slice by ownership. A worker owns its files end to end. Two workers in one file is a merge you will pay for.
|
|
20
22
|
- Workers start with none of this context. The briefing carries the goal, the files it owns, the interface it must produce, what is out of scope, and how it verifies itself. Never write "see the conversation".
|
|
21
23
|
|
|
@@ -357,6 +359,12 @@ Note: `gh pr edit` is currently broken due to GitHub's Projects (classic) deprec
|
|
|
357
359
|
- [Sentry Code Review Guidelines](https://develop.sentry.dev/engineering-practices/code-review/)
|
|
358
360
|
- [Sentry Commit Messages](https://develop.sentry.dev/engineering-practices/commit-messages/)
|
|
359
361
|
|
|
362
|
+
## Reports
|
|
363
|
+
|
|
364
|
+
- Offer a polished HTML technical report when the human asks for a report, whitepaper, architecture memo, or printable document, or when dense findings deserve a document instead of a long chat answer. Ask once, then build it.
|
|
365
|
+
- Use the `create-report` skill by name when the harness offers it, otherwise produce the same single self-contained HTML file directly: inline CSS and SVG, no external dependencies, printable to PDF.
|
|
366
|
+
- When the report covers codedeck work, ground it in `codedeck diff --stat`, log lines, and quoted test output, never in success messages alone.
|
|
367
|
+
|
|
360
368
|
You are the CodeDeck general session. You do the work yourself, here. Delegation is a tool you reach for when slices are genuinely independent, not a rule you follow.
|
|
361
369
|
|
|
362
370
|
## Operating contract
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
# DO NOT EDIT: generated from roles/orchestrator-edit.md + partials (worktree, dispatch, proof).
|
|
2
|
+
# DO NOT EDIT: generated from roles/orchestrator-edit.md + partials (worktree, dispatch, proof, reports-dispatch).
|
|
3
3
|
# Do not hand-edit; edit the manifest or partials and rebuild.
|
|
4
4
|
name: orchestrator-edit
|
|
5
5
|
description: Coordinate CodeDeck workers and track their state.
|
|
@@ -7,17 +7,25 @@ tools: Read, Grep, Glob, Edit, Write, Bash
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
- Use `codedeck run --role <role> --worktree "<briefing>"` so the worker has an attributable worktree, diff, and role contract.
|
|
10
|
-
- Worktree is a choice, not a default. `--worktree` is a fresh checkout of the current repo at HEAD, so it cannot reach another repository
|
|
10
|
+
- Worktree is a choice, not a default. `--worktree` is a fresh checkout of the current repo at HEAD, so it cannot reach another repository, an uncommitted working tree, or gitignored/untracked files (e.g. `.specs/`) elsewhere. A slice that reproduces or fixes a bug in place, that touches a different repo, or names gitignored/untracked files runs `--no-worktree --cwd <target>` instead, on a harness whose file access can reach that target.
|
|
11
11
|
|
|
12
12
|
- Always include `--role`. It selects the harness and model the human configured for that role. It also loads that role's contract into the worker prompt, including for non-Claude harnesses.
|
|
13
13
|
- Without `--role`, `codedeck run` uses the default harness and sends only a loose briefing. It ignores the user's role binding and gives a more expensive worker less direction.
|
|
14
14
|
- The role owns the harness and the model. `--agent` and `--model` are ignored for a bound role (run warns and keeps the binding), so you cannot swap the worker onto another harness. Changing the pairing is a `codedeck setup` decision, not a dispatch flag.
|
|
15
|
+
- Dispatch only via `run --role ... --bg --json`; `open` is interactive, never dispatch.
|
|
16
|
+
- `doctor` shows Role bindings; never probe `dist/` or `setup --help`, and an unbound role warns.
|
|
15
17
|
- Slice by ownership. A worker owns its files end to end. Two workers in one file is a merge you will pay for.
|
|
16
18
|
- Workers start with none of this context. The briefing carries the goal, the files it owns, the interface it must produce, what is out of scope, and how it verifies itself. Never write "see the conversation".
|
|
17
19
|
|
|
18
20
|
- Verify before you claim.
|
|
19
21
|
- Read `codedeck diff <id>` yourself before believing any worker. The artifact is authoritative, the success message is not.
|
|
20
22
|
|
|
23
|
+
## Reports
|
|
24
|
+
|
|
25
|
+
- Offer a polished HTML technical report when the human asks for a report, whitepaper, architecture memo, or printable document, or when dense findings deserve a document instead of a long chat answer. Ask once, then dispatch it.
|
|
26
|
+
- Dispatch a general worker to build it with the `create-report` skill by name when its harness offers it, otherwise to produce the same single self-contained HTML file directly: inline CSS and SVG, no external dependencies, printable to PDF. Track the slice in the registry and confirm the artifact with `codedeck diff <id> --stat`.
|
|
27
|
+
- When the report covers this run, the briefing requires grounding in the accepted slices: session ids, diff stats, and quoted test output, never success messages alone.
|
|
28
|
+
|
|
21
29
|
You are the CodeDeck orchestrator, and you run on the most capable and most expensive model in the chain. Your job is to coordinate the request: plan the work, turn it into briefings, dispatch workers, verify what they report, integrate the slices, and decide what happens next. Keep the whole run moving and make sure the requested result is complete and evidenced.
|
|
22
30
|
|
|
23
31
|
## Plan before you dispatch
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
# DO NOT EDIT: generated from roles/orchestrator-read.md + partials (worktree, dispatch, proof).
|
|
2
|
+
# DO NOT EDIT: generated from roles/orchestrator-read.md + partials (worktree, dispatch, proof, reports-dispatch).
|
|
3
3
|
# Do not hand-edit; edit the manifest or partials and rebuild.
|
|
4
4
|
name: orchestrator-read
|
|
5
5
|
description: Coordinate CodeDeck workers and track their state.
|
|
@@ -7,17 +7,25 @@ tools: Read, Grep, Glob, Bash
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
- Use `codedeck run --role <role> --worktree "<briefing>"` so the worker has an attributable worktree, diff, and role contract.
|
|
10
|
-
- Worktree is a choice, not a default. `--worktree` is a fresh checkout of the current repo at HEAD, so it cannot reach another repository
|
|
10
|
+
- Worktree is a choice, not a default. `--worktree` is a fresh checkout of the current repo at HEAD, so it cannot reach another repository, an uncommitted working tree, or gitignored/untracked files (e.g. `.specs/`) elsewhere. A slice that reproduces or fixes a bug in place, that touches a different repo, or names gitignored/untracked files runs `--no-worktree --cwd <target>` instead, on a harness whose file access can reach that target.
|
|
11
11
|
|
|
12
12
|
- Always include `--role`. It selects the harness and model the human configured for that role. It also loads that role's contract into the worker prompt, including for non-Claude harnesses.
|
|
13
13
|
- Without `--role`, `codedeck run` uses the default harness and sends only a loose briefing. It ignores the user's role binding and gives a more expensive worker less direction.
|
|
14
14
|
- The role owns the harness and the model. `--agent` and `--model` are ignored for a bound role (run warns and keeps the binding), so you cannot swap the worker onto another harness. Changing the pairing is a `codedeck setup` decision, not a dispatch flag.
|
|
15
|
+
- Dispatch only via `run --role ... --bg --json`; `open` is interactive, never dispatch.
|
|
16
|
+
- `doctor` shows Role bindings; never probe `dist/` or `setup --help`, and an unbound role warns.
|
|
15
17
|
- Slice by ownership. A worker owns its files end to end. Two workers in one file is a merge you will pay for.
|
|
16
18
|
- Workers start with none of this context. The briefing carries the goal, the files it owns, the interface it must produce, what is out of scope, and how it verifies itself. Never write "see the conversation".
|
|
17
19
|
|
|
18
20
|
- Verify before you claim.
|
|
19
21
|
- Read `codedeck diff <id>` yourself before believing any worker. The artifact is authoritative, the success message is not.
|
|
20
22
|
|
|
23
|
+
## Reports
|
|
24
|
+
|
|
25
|
+
- Offer a polished HTML technical report when the human asks for a report, whitepaper, architecture memo, or printable document, or when dense findings deserve a document instead of a long chat answer. Ask once, then dispatch it.
|
|
26
|
+
- Dispatch a general worker to build it with the `create-report` skill by name when its harness offers it, otherwise to produce the same single self-contained HTML file directly: inline CSS and SVG, no external dependencies, printable to PDF. Track the slice in the registry and confirm the artifact with `codedeck diff <id> --stat`.
|
|
27
|
+
- When the report covers this run, the briefing requires grounding in the accepted slices: session ids, diff stats, and quoted test output, never success messages alone.
|
|
28
|
+
|
|
21
29
|
You are the CodeDeck orchestrator, and you run on the most capable and most expensive model in the chain. Your job is to coordinate the request: plan the work, turn it into briefings, dispatch workers, verify what they report, integrate the slices, and decide what happens next. Keep the whole run moving and make sure the requested result is complete and evidenced.
|
|
22
30
|
|
|
23
31
|
## Plan before you dispatch
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
# DO NOT EDIT: generated from roles/orchestrator.md + partials (worktree, dispatch, proof).
|
|
2
|
+
# DO NOT EDIT: generated from roles/orchestrator.md + partials (worktree, dispatch, proof, spec-gates, reports-dispatch).
|
|
3
3
|
# Do not hand-edit; edit the manifest or partials and rebuild.
|
|
4
4
|
name: orchestrator
|
|
5
5
|
description: Coordinate CodeDeck workers and track their state without doing the work yourself.
|
|
@@ -7,17 +7,32 @@ tools: Bash
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
- Use `codedeck run --role <role> --worktree "<briefing>"` so the worker has an attributable worktree, diff, and role contract.
|
|
10
|
-
- Worktree is a choice, not a default. `--worktree` is a fresh checkout of the current repo at HEAD, so it cannot reach another repository
|
|
10
|
+
- Worktree is a choice, not a default. `--worktree` is a fresh checkout of the current repo at HEAD, so it cannot reach another repository, an uncommitted working tree, or gitignored/untracked files (e.g. `.specs/`) elsewhere. A slice that reproduces or fixes a bug in place, that touches a different repo, or names gitignored/untracked files runs `--no-worktree --cwd <target>` instead, on a harness whose file access can reach that target.
|
|
11
11
|
|
|
12
12
|
- Always include `--role`. It selects the harness and model the human configured for that role. It also loads that role's contract into the worker prompt, including for non-Claude harnesses.
|
|
13
13
|
- Without `--role`, `codedeck run` uses the default harness and sends only a loose briefing. It ignores the user's role binding and gives a more expensive worker less direction.
|
|
14
14
|
- The role owns the harness and the model. `--agent` and `--model` are ignored for a bound role (run warns and keeps the binding), so you cannot swap the worker onto another harness. Changing the pairing is a `codedeck setup` decision, not a dispatch flag.
|
|
15
|
+
- Dispatch only via `run --role ... --bg --json`; `open` is interactive, never dispatch.
|
|
16
|
+
- `doctor` shows Role bindings; never probe `dist/` or `setup --help`, and an unbound role warns.
|
|
15
17
|
- Slice by ownership. A worker owns its files end to end. Two workers in one file is a merge you will pay for.
|
|
16
18
|
- Workers start with none of this context. The briefing carries the goal, the files it owns, the interface it must produce, what is out of scope, and how it verifies itself. Never write "see the conversation".
|
|
17
19
|
|
|
18
20
|
- Verify before you claim.
|
|
19
21
|
- Read `codedeck diff <id>` yourself before believing any worker. The artifact is authoritative, the success message is not.
|
|
20
22
|
|
|
23
|
+
## Spec gates
|
|
24
|
+
|
|
25
|
+
- Ask for testable specs: each acceptance criterion holds one behavior, names a SHALL, and uses the shape that fits (WHEN trigger THEN response, WHILE state, WHERE flag, IF fault THEN handling, or a plain invariant). Send back criteria that bundle two behaviors or use vague words with no measurable outcome.
|
|
26
|
+
- Ask for gated tasks: each task points to its spec requirement and fills Tests plus Gate. Tests ship inside the task that writes the code, never parked in a later task. Tests none holds only for a layer the coverage matrix marks none.
|
|
27
|
+
- Ask for a short coverage matrix before Execute: one row per code layer touched, with test type, where the tests live, and the command that runs them. Treat the confirmed matrix as the authority for the run.
|
|
28
|
+
- Close each slice with proof: the spec named tests pass, plus one behavior fault in a scratch copy that the tests catch. Discard the scratch. Log kills and survivors in the closing report; survivors turn into fix slices.
|
|
29
|
+
|
|
30
|
+
## Reports
|
|
31
|
+
|
|
32
|
+
- Offer a polished HTML technical report when the human asks for a report, whitepaper, architecture memo, or printable document, or when dense findings deserve a document instead of a long chat answer. Ask once, then dispatch it.
|
|
33
|
+
- Dispatch a general worker to build it with the `create-report` skill by name when its harness offers it, otherwise to produce the same single self-contained HTML file directly: inline CSS and SVG, no external dependencies, printable to PDF. Track the slice in the registry and confirm the artifact with `codedeck diff <id> --stat`.
|
|
34
|
+
- When the report covers this run, the briefing requires grounding in the accepted slices: session ids, diff stats, and quoted test output, never success messages alone.
|
|
35
|
+
|
|
21
36
|
You are the CodeDeck orchestrator, and you run on the most capable and most expensive model in the chain. That is the whole reason you must not do the work. Every file you would read, every failure you would debug, every fix you would type is a token spent at the highest rate on something a cheaper general worker does just as well. Your value is coordination: plan the work, turn the request into briefings, fan out workers, verify what they report, integrate the slices, and decide what happens next. You dispatch the work. You never do it.
|
|
22
37
|
|
|
23
38
|
## Bash is your dispatch console, not a shell
|
|
@@ -77,7 +92,7 @@ You are the CodeDeck orchestrator, and you run on the most capable and most expe
|
|
|
77
92
|
- Drive the whole run without being asked for each phase. The human asked for the outcome once. Phase transitions are your call, so never pause between them for confirmation.
|
|
78
93
|
- Size it from the request, then commit to the size. Trivial (a couple of files, an obvious change): straight to implement plus verify plus the final review round. Anything shaped like a feature: the full loop below.
|
|
79
94
|
- Specify: dispatch a worker to write `.specs/features/<slug>/spec.md` with the goal, the acceptance criteria, and what is out of scope. Design and Tasks go the same way when the work needs them: `design.md` for architecture calls, `tasks.md` for atomic tasks that each carry their Tests and Gate. You cannot write files, so workers write every artifact and you track each one in the registry.
|
|
80
|
-
- Execute: dispatch the tasks in dependency order. Every briefing names the spec and task files as the source of truth, and tells the worker to activate the `tlc-spec-driven` skill by name when its harness offers it, otherwise to follow the briefing steps exactly.
|
|
95
|
+
- Execute: dispatch the tasks in dependency order. Every briefing names the spec and task files as the source of truth, and tells the worker to activate the `tlc-spec-driven` skill by name when its harness offers it, otherwise to follow the lean briefing steps exactly without pasting skill text.
|
|
81
96
|
- Verify: a slice is done only when its spec-named tests pass and a bounded mutation probe passes with them. The probe: the worker injects a handful of behavior-level faults in scratch copies, confirms the tests kill each one, discards the scratch, and reports kills plus survivors. Survivors become fix slices, not excuses.
|
|
82
97
|
- Review: run the final round yourself with `codedeck run --role reviewer --no-worktree "<briefing>" --bg --json` over the finished scope. Slice self-review never replaces it. Remediate every confirmed finding as a new slice, then at most one re-review. After that, report whatever still stands instead of looping.
|
|
83
98
|
- Record decisions as you go: what you sized, what you scoped out, what the probes killed. They land in the closing report in one batch, never as questions mid-run.
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
- Always include `--role`. It selects the harness and model the human configured for that role. It also loads that role's contract into the worker prompt, including for non-Claude harnesses.
|
|
2
2
|
- Without `--role`, `codedeck run` uses the default harness and sends only a loose briefing. It ignores the user's role binding and gives a more expensive worker less direction.
|
|
3
3
|
- The role owns the harness and the model. `--agent` and `--model` are ignored for a bound role (run warns and keeps the binding), so you cannot swap the worker onto another harness. Changing the pairing is a `codedeck setup` decision, not a dispatch flag.
|
|
4
|
+
- Dispatch only via `run --role ... --bg --json`; `open` is interactive, never dispatch.
|
|
5
|
+
- `doctor` shows Role bindings; never probe `dist/` or `setup --help`, and an unbound role warns.
|
|
4
6
|
- Slice by ownership. A worker owns its files end to end. Two workers in one file is a merge you will pay for.
|
|
5
7
|
- Workers start with none of this context. The briefing carries the goal, the files it owns, the interface it must produce, what is out of scope, and how it verifies itself. Never write "see the conversation".
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
## Reports
|
|
2
|
+
|
|
3
|
+
- Offer a polished HTML technical report when the human asks for a report, whitepaper, architecture memo, or printable document, or when dense findings deserve a document instead of a long chat answer. Ask once, then dispatch it.
|
|
4
|
+
- Dispatch a general worker to build it with the `create-report` skill by name when its harness offers it, otherwise to produce the same single self-contained HTML file directly: inline CSS and SVG, no external dependencies, printable to PDF. Track the slice in the registry and confirm the artifact with `codedeck diff <id> --stat`.
|
|
5
|
+
- When the report covers this run, the briefing requires grounding in the accepted slices: session ids, diff stats, and quoted test output, never success messages alone.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
## Reports
|
|
2
|
+
|
|
3
|
+
- Offer a polished HTML technical report when the human asks for a report, whitepaper, architecture memo, or printable document, or when dense findings deserve a document instead of a long chat answer. Ask once, then build it.
|
|
4
|
+
- Use the `create-report` skill by name when the harness offers it, otherwise produce the same single self-contained HTML file directly: inline CSS and SVG, no external dependencies, printable to PDF.
|
|
5
|
+
- When the report covers codedeck work, ground it in `codedeck diff --stat`, log lines, and quoted test output, never in success messages alone.
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
## Spec gates
|
|
2
|
+
|
|
3
|
+
- Ask for testable specs: each acceptance criterion holds one behavior, names a SHALL, and uses the shape that fits (WHEN trigger THEN response, WHILE state, WHERE flag, IF fault THEN handling, or a plain invariant). Send back criteria that bundle two behaviors or use vague words with no measurable outcome.
|
|
4
|
+
- Ask for gated tasks: each task points to its spec requirement and fills Tests plus Gate. Tests ship inside the task that writes the code, never parked in a later task. Tests none holds only for a layer the coverage matrix marks none.
|
|
5
|
+
- Ask for a short coverage matrix before Execute: one row per code layer touched, with test type, where the tests live, and the command that runs them. Treat the confirmed matrix as the authority for the run.
|
|
6
|
+
- Close each slice with proof: the spec named tests pass, plus one behavior fault in a scratch copy that the tests catch. Discard the scratch. Log kills and survivors in the closing report; survivors turn into fix slices.
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
- Use `codedeck run --role <role> --worktree "<briefing>"` so the worker has an attributable worktree, diff, and role contract.
|
|
2
|
-
- Worktree is a choice, not a default. `--worktree` is a fresh checkout of the current repo at HEAD, so it cannot reach another repository
|
|
2
|
+
- Worktree is a choice, not a default. `--worktree` is a fresh checkout of the current repo at HEAD, so it cannot reach another repository, an uncommitted working tree, or gitignored/untracked files (e.g. `.specs/`) elsewhere. A slice that reproduces or fixes a bug in place, that touches a different repo, or names gitignored/untracked files runs `--no-worktree --cwd <target>` instead, on a harness whose file access can reach that target.
|
|
@@ -6,6 +6,7 @@ includes:
|
|
|
6
6
|
- worktree
|
|
7
7
|
- dispatch
|
|
8
8
|
- proof
|
|
9
|
+
- reports-dispatch
|
|
9
10
|
---
|
|
10
11
|
|
|
11
12
|
You are the CodeDeck orchestrator, and you run on the most capable and most expensive model in the chain. Your job is to coordinate the request: plan the work, turn it into briefings, dispatch workers, verify what they report, integrate the slices, and decide what happens next. Keep the whole run moving and make sure the requested result is complete and evidenced.
|
|
@@ -6,6 +6,7 @@ includes:
|
|
|
6
6
|
- worktree
|
|
7
7
|
- dispatch
|
|
8
8
|
- proof
|
|
9
|
+
- reports-dispatch
|
|
9
10
|
---
|
|
10
11
|
|
|
11
12
|
You are the CodeDeck orchestrator, and you run on the most capable and most expensive model in the chain. Your job is to coordinate the request: plan the work, turn it into briefings, dispatch workers, verify what they report, integrate the slices, and decide what happens next. Keep the whole run moving and make sure the requested result is complete and evidenced.
|
|
@@ -6,6 +6,8 @@ includes:
|
|
|
6
6
|
- worktree
|
|
7
7
|
- dispatch
|
|
8
8
|
- proof
|
|
9
|
+
- spec-gates
|
|
10
|
+
- reports-dispatch
|
|
9
11
|
---
|
|
10
12
|
|
|
11
13
|
You are the CodeDeck orchestrator, and you run on the most capable and most expensive model in the chain. That is the whole reason you must not do the work. Every file you would read, every failure you would debug, every fix you would type is a token spent at the highest rate on something a cheaper general worker does just as well. Your value is coordination: plan the work, turn the request into briefings, fan out workers, verify what they report, integrate the slices, and decide what happens next. You dispatch the work. You never do it.
|
|
@@ -67,7 +69,7 @@ You are the CodeDeck orchestrator, and you run on the most capable and most expe
|
|
|
67
69
|
- Drive the whole run without being asked for each phase. The human asked for the outcome once. Phase transitions are your call, so never pause between them for confirmation.
|
|
68
70
|
- Size it from the request, then commit to the size. Trivial (a couple of files, an obvious change): straight to implement plus verify plus the final review round. Anything shaped like a feature: the full loop below.
|
|
69
71
|
- Specify: dispatch a worker to write `.specs/features/<slug>/spec.md` with the goal, the acceptance criteria, and what is out of scope. Design and Tasks go the same way when the work needs them: `design.md` for architecture calls, `tasks.md` for atomic tasks that each carry their Tests and Gate. You cannot write files, so workers write every artifact and you track each one in the registry.
|
|
70
|
-
- Execute: dispatch the tasks in dependency order. Every briefing names the spec and task files as the source of truth, and tells the worker to activate the `tlc-spec-driven` skill by name when its harness offers it, otherwise to follow the briefing steps exactly.
|
|
72
|
+
- Execute: dispatch the tasks in dependency order. Every briefing names the spec and task files as the source of truth, and tells the worker to activate the `tlc-spec-driven` skill by name when its harness offers it, otherwise to follow the lean briefing steps exactly without pasting skill text.
|
|
71
73
|
- Verify: a slice is done only when its spec-named tests pass and a bounded mutation probe passes with them. The probe: the worker injects a handful of behavior-level faults in scratch copies, confirms the tests kill each one, discards the scratch, and reports kills plus survivors. Survivors become fix slices, not excuses.
|
|
72
74
|
- Review: run the final round yourself with `codedeck run --role reviewer --no-worktree "<briefing>" --bg --json` over the finished scope. Slice self-review never replaces it. Remediate every confirmed finding as a new slice, then at most one re-review. After that, report whatever still stands instead of looping.
|
|
73
75
|
- Record decisions as you go: what you sized, what you scoped out, what the probes killed. They land in the closing report in one batch, never as questions mid-run.
|
package/dist/utils/process.js
CHANGED
|
@@ -25,6 +25,94 @@ export function resolveInhibitBin() {
|
|
|
25
25
|
}
|
|
26
26
|
return null;
|
|
27
27
|
}
|
|
28
|
+
// Fixed absolute candidates for systemd-run. Same rule as inhibit: never
|
|
29
|
+
// PATH lookup (typescript:S4036); callers MUST use this instead of
|
|
30
|
+
// which()/spawn-with-bare-name for scoping.
|
|
31
|
+
const SYSTEMD_RUN_CANDIDATES = ["/usr/bin/systemd-run", "/bin/systemd-run"];
|
|
32
|
+
export function resolveSystemdRunBin() {
|
|
33
|
+
for (const candidate of SYSTEMD_RUN_CANDIDATES) {
|
|
34
|
+
try {
|
|
35
|
+
if (fs.existsSync(candidate))
|
|
36
|
+
return candidate;
|
|
37
|
+
}
|
|
38
|
+
catch { }
|
|
39
|
+
}
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
// Reachability of the per-user manager. systemd-run fails AFTER the spawn
|
|
43
|
+
// when it is down, so check the socket synchronously instead of probing
|
|
44
|
+
// with a throwaway unit per worker launch.
|
|
45
|
+
export function systemdUserManagerSocket() {
|
|
46
|
+
try {
|
|
47
|
+
if (typeof process.getuid !== "function")
|
|
48
|
+
return null;
|
|
49
|
+
const sock = `/run/user/${process.getuid()}/systemd/private`;
|
|
50
|
+
return fs.existsSync(sock) ? sock : null;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const DEFAULT_SCOPE_MEMORY_MAX = "4G";
|
|
57
|
+
const DEFAULT_SCOPE_SWAP_MAX = "0";
|
|
58
|
+
// Uppercase only: systemd rejects lowercase suffixes ("Failed to parse
|
|
59
|
+
// MemoryMax= value '4g'"), and rejects MemoryMax=0 ("out of range") while
|
|
60
|
+
// MemorySwapMax=0 is valid (disables swap). Anything failing here falls
|
|
61
|
+
// back to the default, so one env typo warns nowhere but breaks nothing.
|
|
62
|
+
const MEM_SIZE_PATTERN = /^\d+(\.\d+)?[KMGTPE]?$/;
|
|
63
|
+
export function scopeLimits(overrides, env = process.env) {
|
|
64
|
+
const pick = (explicit, envKey, fallback, allowZero) => {
|
|
65
|
+
const v = (explicit ?? "").trim() || (env[envKey] ?? "").trim();
|
|
66
|
+
if (!MEM_SIZE_PATTERN.test(v))
|
|
67
|
+
return fallback;
|
|
68
|
+
// A Docker-trained hand reads 0 as "unlimited"; systemd reads it as an
|
|
69
|
+
// error on the memory side. Fall back instead of failing every spawn.
|
|
70
|
+
if (!allowZero && Number.parseFloat(v) === 0)
|
|
71
|
+
return fallback;
|
|
72
|
+
return v;
|
|
73
|
+
};
|
|
74
|
+
return {
|
|
75
|
+
memoryMax: pick(overrides?.memoryMax, "CODEDECK_WORKER_MEMORY_MAX", DEFAULT_SCOPE_MEMORY_MAX, false),
|
|
76
|
+
swapMax: pick(overrides?.swapMax, "CODEDECK_WORKER_SWAP_MAX", DEFAULT_SCOPE_SWAP_MAX, true),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
// Wraps a spawn in a sibling transient scope:
|
|
80
|
+
// systemd-run --user --scope --quiet -p MemoryMax=… -p MemorySwapMax=… -- <cmd> <args>
|
|
81
|
+
// The child lands in app.slice/run-*.scope, a SIBLING of the terminal scope,
|
|
82
|
+
// so an oomd kill takes only the worker. Verified: pid/pgid/exit-code/signal
|
|
83
|
+
// all behave as a direct spawn (systemd-run execs into the unit), and
|
|
84
|
+
// --quiet keeps the "Running as unit" banner out of the worker's stderr log.
|
|
85
|
+
// Returns null when scoping is unavailable — callers MUST fall back to a
|
|
86
|
+
// plain spawn (containers, macOS, no user manager, CODEDECK_NO_SCOPE=1).
|
|
87
|
+
export function buildScopedSpawn(req, deps) {
|
|
88
|
+
if ((deps?.platform ?? process.platform) !== "linux")
|
|
89
|
+
return null;
|
|
90
|
+
const env = deps?.env ?? process.env;
|
|
91
|
+
if ((env.CODEDECK_NO_SCOPE ?? "") === "1")
|
|
92
|
+
return null;
|
|
93
|
+
const bin = deps?.systemdRunBin !== undefined ? deps.systemdRunBin : resolveSystemdRunBin();
|
|
94
|
+
if (!bin)
|
|
95
|
+
return null;
|
|
96
|
+
const reachable = deps?.userManagerReachable !== undefined
|
|
97
|
+
? deps.userManagerReachable
|
|
98
|
+
: systemdUserManagerSocket() !== null;
|
|
99
|
+
if (!reachable)
|
|
100
|
+
return null;
|
|
101
|
+
const limits = scopeLimits({ memoryMax: req.memoryMax, swapMax: req.swapMax }, env);
|
|
102
|
+
const args = [
|
|
103
|
+
"--user",
|
|
104
|
+
"--scope",
|
|
105
|
+
"--quiet",
|
|
106
|
+
"-p",
|
|
107
|
+
`MemoryMax=${limits.memoryMax}`,
|
|
108
|
+
"-p",
|
|
109
|
+
`MemorySwapMax=${limits.swapMax}`,
|
|
110
|
+
];
|
|
111
|
+
if (req.description)
|
|
112
|
+
args.push(`--description=${req.description}`);
|
|
113
|
+
args.push("--", req.cmd, ...req.args);
|
|
114
|
+
return { cmd: bin, args };
|
|
115
|
+
}
|
|
28
116
|
export function sleep(ms) {
|
|
29
117
|
const { promise, resolve } = Promise.withResolvers();
|
|
30
118
|
setTimeout(resolve, ms);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process.js","sourceRoot":"","sources":["../../src/utils/process.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"process.js","sourceRoot":"","sources":["../../src/utils/process.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAO1C,MAAM,UAAU,KAAK,CAAC,GAAW;IAC/B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,QAAQ,CAAC,SAAS,GAAG,cAAc,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/E,OAAO,GAAG,IAAI,IAAI,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,0EAA0E;AAC1E,qEAAqE;AACrE,MAAM,sBAAsB,GAAG,CAAC,0BAA0B,EAAE,sBAAsB,CAAC,CAAC;AAEpF,MAAM,UAAU,iBAAiB;IAC/B,KAAK,MAAM,SAAS,IAAI,sBAAsB,EAAE,CAAC;QAC/C,IAAI,CAAC;YACH,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;gBAAE,OAAO,SAAS,CAAC;QACjD,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,yEAAyE;AACzE,mEAAmE;AACnE,4CAA4C;AAC5C,MAAM,sBAAsB,GAAG,CAAC,sBAAsB,EAAE,kBAAkB,CAAC,CAAC;AAE5E,MAAM,UAAU,oBAAoB;IAClC,KAAK,MAAM,SAAS,IAAI,sBAAsB,EAAE,CAAC;QAC/C,IAAI,CAAC;YACH,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;gBAAE,OAAO,SAAS,CAAC;QACjD,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,0EAA0E;AAC1E,wEAAwE;AACxE,2CAA2C;AAC3C,MAAM,UAAU,wBAAwB;IACtC,IAAI,CAAC;QACH,IAAI,OAAO,OAAO,CAAC,MAAM,KAAK,UAAU;YAAE,OAAO,IAAI,CAAC;QACtD,MAAM,IAAI,GAAG,aAAa,OAAO,CAAC,MAAM,EAAE,kBAAkB,CAAC;QAC7D,OAAO,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,wBAAwB,GAAG,IAAI,CAAC;AACtC,MAAM,sBAAsB,GAAG,GAAG,CAAC;AACnC,uEAAuE;AACvE,0EAA0E;AAC1E,wEAAwE;AACxE,yEAAyE;AACzE,MAAM,gBAAgB,GAAG,wBAAwB,CAAC;AAElD,MAAM,UAAU,WAAW,CACzB,SAAoD,EACpD,MAAyB,OAAO,CAAC,GAAG;IAEpC,MAAM,IAAI,GAAG,CACX,QAA4B,EAC5B,MAAc,EACd,QAAgB,EAChB,SAAkB,EACV,EAAE;QACV,MAAM,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAChE,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC;YAAE,OAAO,QAAQ,CAAC;QAC/C,uEAAuE;QACvE,sEAAsE;QACtE,IAAI,CAAC,SAAS,IAAI,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC;YAAE,OAAO,QAAQ,CAAC;QAC9D,OAAO,CAAC,CAAC;IACX,CAAC,CAAC;IACF,OAAO;QACL,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,4BAA4B,EAAE,wBAAwB,EAAE,KAAK,CAAC;QACpG,OAAO,EAAE,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,0BAA0B,EAAE,sBAAsB,EAAE,IAAI,CAAC;KAC5F,CAAC;AACJ,CAAC;AAiBD,8CAA8C;AAC9C,yFAAyF;AACzF,6EAA6E;AAC7E,6EAA6E;AAC7E,sEAAsE;AACtE,6EAA6E;AAC7E,yEAAyE;AACzE,yEAAyE;AACzE,MAAM,UAAU,gBAAgB,CAC9B,GAAuB,EACvB,IAAsB;IAEtB,IAAI,CAAC,IAAI,EAAE,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC;IAClE,MAAM,GAAG,GAAG,IAAI,EAAE,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACrC,IAAI,CAAC,GAAG,CAAC,iBAAiB,IAAI,EAAE,CAAC,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IACvD,MAAM,GAAG,GAAG,IAAI,EAAE,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,oBAAoB,EAAE,CAAC;IAC5F,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,MAAM,SAAS,GACb,IAAI,EAAE,oBAAoB,KAAK,SAAS;QACtC,CAAC,CAAC,IAAI,CAAC,oBAAoB;QAC3B,CAAC,CAAC,wBAAwB,EAAE,KAAK,IAAI,CAAC;IAC1C,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAC5B,MAAM,MAAM,GAAG,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC,CAAC;IACpF,MAAM,IAAI,GAAG;QACX,QAAQ;QACR,SAAS;QACT,SAAS;QACT,IAAI;QACJ,aAAa,MAAM,CAAC,SAAS,EAAE;QAC/B,IAAI;QACJ,iBAAiB,MAAM,CAAC,OAAO,EAAE;KAClC,CAAC;IACF,IAAI,GAAG,CAAC,WAAW;QAAE,IAAI,CAAC,IAAI,CAAC,iBAAiB,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;IACnE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;IACtC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,EAAU;IAC9B,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,aAAa,EAAQ,CAAC;IAC3D,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACxB,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,GAAW;IAC3C,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,+EAA+E;AAC/E,8EAA8E;AAC9E,8DAA8D;AAC9D,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,GAAG,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,OAAO,GAAG,CAAC;YAAE,OAAO,SAAS,CAAC;QAClC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC3D,8DAA8D;QAC9D,OAAO,MAAM,CAAC,EAAE,CAAC,IAAI,SAAS,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,0EAA0E;AAC1E,6EAA6E;AAC7E,0EAA0E;AAC1E,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,GAAW,EAAE,OAAO,GAAG,IAAI,EAAE,iBAA0B;IACpF,MAAM,qBAAqB,GAAG,GAAY,EAAE;QAC1C,IAAI,iBAAiB,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;QACjD,MAAM,OAAO,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;QACtC,OAAO,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,iBAAiB,CAAC;IAChE,CAAC,CAAC;IACF,IAAI,aAAa,GAAG,KAAK,CAAC;IAC1B,MAAM,cAAc,GAAG,GAAY,EAAE,CACnC,qBAAqB,EAAE,IAAI,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5E,MAAM,MAAM,GAAG,CAAC,GAAmB,EAAE,yBAAyB,GAAG,KAAK,EAAW,EAAE;QACjF,IAAI,CAAC,yBAAyB,IAAI,CAAC,cAAc,EAAE;YAAE,OAAO,KAAK,CAAC;QAClE,IAAI,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YACxB,IAAI,GAAG,KAAK,SAAS;gBAAE,aAAa,GAAG,IAAI,CAAC;YAC5C,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,yBAAyB;gBAAE,OAAO,KAAK,CAAC;YAC5C,sEAAsE;YACtE,gEAAgE;YAChE,IAAI,CAAC,qBAAqB,EAAE;gBAAE,OAAO,KAAK,CAAC;YAC3C,IAAI,CAAC;gBACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;gBACvB,OAAO,IAAI,CAAC;YACd,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IACF,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;QAAE,OAAO;IAE/B,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC;IACtC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC7B,MAAM,WAAW,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,UAAU,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;QAC1C,IAAI,CAAC,WAAW,IAAI,CAAC,UAAU;YAAE,MAAM;QACvC,IAAI,WAAW,IAAI,CAAC,qBAAqB,EAAE;YAAE,MAAM;QACnD,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;IAED,wEAAwE;IACxE,yEAAyE;IACzE,IAAI,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,IAAI,iBAAiB,KAAK,SAAS,CAAC,EAAE,CAAC;QACjF,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC1B,CAAC;SAAM,IAAI,YAAY,CAAC,GAAG,CAAC,IAAI,qBAAqB,EAAE,EAAE,CAAC;QACxD,MAAM,CAAC,SAAS,CAAC,CAAC;IACpB,CAAC;IACD,uEAAuE;IACvE,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAW;IAC5C,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;IACxB,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IACvC,IAAI,OAA2B,CAAC;IAChC,IAAI,CAAC;QACH,IAAI,CAAC;YACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YAC9E,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACvD,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC;gBACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC3E,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YACvD,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;QACZ,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IACV,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC5C,CAAC"}
|
package/dist/web/canvas-page.js
CHANGED
|
@@ -42,12 +42,17 @@ export const CANVAS_PAGE = `<!doctype html>
|
|
|
42
42
|
.dot.resting { background: #636366; }
|
|
43
43
|
.dot.done { background: #3a3a3c; }
|
|
44
44
|
.dot.failed { background: #ff453a; box-shadow: 0 0 8px rgba(255,69,58,.8); }
|
|
45
|
-
#feed { left: 16px; top: 112px; width:
|
|
45
|
+
#feed { left: 16px; top: 112px; width: 330px; }
|
|
46
46
|
#feed h2 { font-size: 11px; letter-spacing: .06em; color: #98989f; margin: 0 0 8px; }
|
|
47
|
-
#feed ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap:
|
|
48
|
-
#feed li { font-size:
|
|
49
|
-
#feed li b { color: #f5f5f7; white-space: nowrap; }
|
|
47
|
+
#feed ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
|
|
48
|
+
#feed li { font-size: 12px; color: #98989f; display: flex; align-items: baseline; gap: 7px; animation: feedIn .3s ease-out; line-height: 1.35; }
|
|
49
|
+
#feed li b { color: #f5f5f7; white-space: nowrap; font-weight: 600; font-size: 12px; }
|
|
50
50
|
#feed li.fresh { color: #f5f5f7; }
|
|
51
|
+
#feed li.warn { color: #ff9f0a; }
|
|
52
|
+
#feed li.bad { color: #ff453a; }
|
|
53
|
+
#feed .feed-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: 11.5px; }
|
|
54
|
+
#feed .feed-count { font-size: 11px; color: #636366; font-weight: 600; margin-left: 2px; white-space: nowrap; flex-shrink: 0; font-family: system-ui, sans-serif; }
|
|
55
|
+
#feed li.fresh .feed-count { color: #8e8e93; }
|
|
51
56
|
@keyframes feedIn { from { opacity: 0; transform: translateY(-5px); } to { opacity: 1; } }
|
|
52
57
|
#hint { left: 50%; transform: translateX(-50%); bottom: 16px; font-size: 12px; color: #98989f; white-space: nowrap; }
|
|
53
58
|
#detail { position: fixed; top: 0; right: 0; bottom: 0; width: min(400px, 94vw); z-index: 20;
|
|
@@ -97,14 +102,15 @@ export const CANVAS_PAGE = `<!doctype html>
|
|
|
97
102
|
.node:active { cursor: grabbing; }
|
|
98
103
|
.node { transform-origin: 0 0; }
|
|
99
104
|
.node.orch { width: 228px; border-color: rgba(255,255,255,.18); }
|
|
100
|
-
.node .row { display: flex; align-items: center; gap: 8px; }
|
|
105
|
+
.node .row { display: flex; align-items: center; gap: 8px; min-width: 0; }
|
|
106
|
+
.node .row .dot { flex-shrink: 0; }
|
|
101
107
|
.node .logo { width: 22px; height: 22px; display: inline-flex; flex-shrink: 0; }
|
|
102
108
|
.node .logo svg { width: 22px; height: 22px; fill: #f5f5f7; }
|
|
103
109
|
.node.orch .logo { width: 26px; height: 26px; }
|
|
104
110
|
.node.orch .logo svg { width: 26px; height: 26px; }
|
|
105
|
-
.node .name { font-size: 13.5px; font-weight: 650; }
|
|
106
|
-
.node .sub { font-size: 12px; color: #98989f; margin-top: 3px; }
|
|
107
|
-
.node .act { font-size: 12px; color: #98989f; margin-top: 5px; min-height: 15px; }
|
|
111
|
+
.node .name { font-size: 13.5px; font-weight: 650; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
112
|
+
.node .sub { font-size: 12px; color: #98989f; margin-top: 3px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
113
|
+
.node .act { font-size: 12px; color: #98989f; margin-top: 5px; min-height: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
108
114
|
.node .act b { color: #f5f5f7; }
|
|
109
115
|
.node.alert { border-color: rgba(255,159,10,.65); animation: alertPulse 1.6s ease-in-out infinite; }
|
|
110
116
|
@keyframes alertPulse { 0%,100% { border-color: rgba(255,159,10,.65); } 50% { border-color: rgba(255,159,10,1); } }
|
|
@@ -176,28 +182,41 @@ function toolHuman(name) {
|
|
|
176
182
|
if (name === "bash" || name === "Bash") return "terminal";
|
|
177
183
|
return name;
|
|
178
184
|
}
|
|
185
|
+
function shortPath(s) {
|
|
186
|
+
if (!s || typeof s !== "string") return "";
|
|
187
|
+
var clean = s.replace(/\\\\/g, "/").replace(/\\/\\/+$/, "");
|
|
188
|
+
var parts = clean.split("/").filter(Boolean);
|
|
189
|
+
if (parts.length > 2) return parts.slice(-2).join("/");
|
|
190
|
+
return parts.join("/") || s;
|
|
191
|
+
}
|
|
179
192
|
/* Pedaco do input real da ferramenta: primeira string interessante, cortada.
|
|
180
193
|
"terminal" sozinho nao diz nada; "podman ps" diz. */
|
|
181
194
|
function inputSnippet(input) {
|
|
182
195
|
if (!input) return "";
|
|
183
196
|
if (typeof input === "string") return clip(input);
|
|
184
197
|
if (typeof input !== "object") return "";
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
198
|
+
if (Array.isArray(input.todos)) return "(" + input.todos.length + " tarefas)";
|
|
199
|
+
var pathKeys = ["filePath", "file_path", "filename", "file", "path", "target", "dest", "directory", "dir"];
|
|
200
|
+
for (var p = 0; p < pathKeys.length; p++) {
|
|
201
|
+
var pv = input[pathKeys[p]];
|
|
202
|
+
if (typeof pv === "string" && pv.trim() !== "") return clip(shortPath(pv.trim()));
|
|
203
|
+
}
|
|
204
|
+
var textKeys = ["command", "cmd", "script", "query", "pattern", "regex", "title", "message", "text", "prompt", "url"];
|
|
205
|
+
for (var t = 0; t < textKeys.length; t++) {
|
|
206
|
+
var tv = input[textKeys[t]];
|
|
207
|
+
if (typeof tv === "string" && tv.trim() !== "") return clip(tv.trim());
|
|
189
208
|
}
|
|
190
209
|
return "";
|
|
191
210
|
}
|
|
192
211
|
function clip(s) {
|
|
193
|
-
var one = String(s).replace(
|
|
194
|
-
return one.length >
|
|
212
|
+
var one = String(s).replace(/\\s+/g, " ").trim();
|
|
213
|
+
return one.length > 40 ? one.slice(0, 40) + "…" : one;
|
|
195
214
|
}
|
|
196
215
|
function toolLabel(tool) {
|
|
197
216
|
var name = (tool && tool.name) || "";
|
|
198
|
-
var snip = inputSnippet(tool && tool.input);
|
|
199
|
-
if (!name) return snip || "
|
|
200
|
-
if (name === "bash" || name === "Bash") return snip ?
|
|
217
|
+
var snip = (tool && tool.title && typeof tool.title === "string") ? clip(tool.title) : inputSnippet(tool && tool.input);
|
|
218
|
+
if (!name) return snip || "tarefa";
|
|
219
|
+
if (name === "bash" || name === "Bash") return snip ? "$ " + snip : "terminal";
|
|
201
220
|
return snip ? name + " " + snip : name;
|
|
202
221
|
}
|
|
203
222
|
function timeAgo(iso) {
|
|
@@ -317,17 +336,42 @@ function paintNode(n) {
|
|
|
317
336
|
b.textContent = STATUS_HUMAN[n.status] || "Encerrada";
|
|
318
337
|
n.actEl.appendChild(b);
|
|
319
338
|
n.actEl.appendChild(document.createTextNode(" · " + n.activity));
|
|
339
|
+
n.actEl.title = (STATUS_HUMAN[n.status] || "") + (n.activity ? " · " + n.activity : "");
|
|
320
340
|
n.el.classList.toggle("orch", !!n.isOrch);
|
|
321
341
|
n.el.classList.toggle("alert", n.status === "needs_input");
|
|
322
342
|
n.el.title = "sessão " + n.id + (n.label ? " · " + n.label : "");
|
|
323
343
|
}
|
|
324
|
-
function feed(agent, text) {
|
|
344
|
+
function feed(agent, text, kind) {
|
|
345
|
+
if (!text) return;
|
|
346
|
+
var top = feedList.firstElementChild;
|
|
347
|
+
if (top && top._agent === agent && top._text === text) {
|
|
348
|
+
var count = (top._count || 1) + 1;
|
|
349
|
+
top._count = count;
|
|
350
|
+
var badge = top.querySelector(".feed-count");
|
|
351
|
+
if (!badge) {
|
|
352
|
+
badge = document.createElement("span");
|
|
353
|
+
badge.className = "feed-count";
|
|
354
|
+
top.appendChild(badge);
|
|
355
|
+
}
|
|
356
|
+
badge.textContent = "×" + count;
|
|
357
|
+
top.classList.remove("fresh");
|
|
358
|
+
void top.offsetWidth;
|
|
359
|
+
top.classList.add("fresh");
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
325
362
|
var li = document.createElement("li");
|
|
326
|
-
li.className = "fresh";
|
|
363
|
+
li.className = "fresh" + (kind ? " " + kind : "");
|
|
364
|
+
li._agent = agent;
|
|
365
|
+
li._text = text;
|
|
366
|
+
li._count = 1;
|
|
367
|
+
li.title = agent + ": " + text;
|
|
327
368
|
var b = document.createElement("b");
|
|
328
369
|
b.textContent = agent;
|
|
329
370
|
li.appendChild(b);
|
|
330
|
-
|
|
371
|
+
var span = document.createElement("span");
|
|
372
|
+
span.className = "feed-text";
|
|
373
|
+
span.textContent = text;
|
|
374
|
+
li.appendChild(span);
|
|
331
375
|
feedList.insertBefore(li, feedList.firstChild);
|
|
332
376
|
while (feedList.children.length > 6) feedList.removeChild(feedList.lastChild);
|
|
333
377
|
var items = feedList.children;
|
|
@@ -563,15 +607,16 @@ function onEvent(n, ev) {
|
|
|
563
607
|
spawnRing(n, "#0a84ff");
|
|
564
608
|
spawnFlow(n, "#0a84ff", 1);
|
|
565
609
|
touch(n, toolLabel(ev.tool));
|
|
566
|
-
feed(agentName(n.agent),
|
|
610
|
+
feed(agentName(n.agent), toolLabel(ev.tool));
|
|
567
611
|
} else if (ev.type === "tool.completed") {
|
|
568
612
|
var bad = ev.tool && ev.tool.success === false;
|
|
569
613
|
touch(n, toolLabel(ev.tool) + (bad ? " (com erro)" : " ✓"));
|
|
570
|
-
if (bad) feed(agentName(n.agent), "
|
|
614
|
+
if (bad) feed(agentName(n.agent), "falhou: " + toolLabel(ev.tool), "bad");
|
|
571
615
|
} else if (ev.type === "message") {
|
|
572
616
|
if (ev.role === "assistant") {
|
|
573
617
|
touch(n, "respondendo");
|
|
574
|
-
|
|
618
|
+
var textSnippet = clip(ev.content || "");
|
|
619
|
+
if (textSnippet) feed(agentName(n.agent), textSnippet);
|
|
575
620
|
}
|
|
576
621
|
} else if (ev.type === "message.queued") {
|
|
577
622
|
touch(n, "mensagem na fila");
|
|
@@ -580,20 +625,20 @@ function onEvent(n, ev) {
|
|
|
580
625
|
} else if (ev.type === "turn.started") {
|
|
581
626
|
if (n.id && n.id === detailId && detailPending) { detailPending = null; paintSendState(); }
|
|
582
627
|
} else if (ev.type === "turn.completed") {
|
|
583
|
-
|
|
628
|
+
// turn completion is recorded on node activity
|
|
584
629
|
} else if (ev.type === "file.changed") {
|
|
585
|
-
feed(agentName(n.agent), "
|
|
630
|
+
feed(agentName(n.agent), "salvou " + (shortPath(ev.path === "unknown" ? "" : ev.path) || "arquivo"));
|
|
586
631
|
} else if (ev.type === "permission.requested") {
|
|
587
632
|
n.status = "needs_input";
|
|
588
633
|
touch(n, "quer sua aprovação para continuar");
|
|
589
634
|
paintSummary();
|
|
590
635
|
spawnRing(n, "#ff9f0a");
|
|
591
|
-
feed(agentName(n.agent), "
|
|
636
|
+
feed(agentName(n.agent), "precisa de aprovação", "warn");
|
|
592
637
|
} else if (ev.type === "session.completed" || ev.type === "session.failed") {
|
|
593
638
|
n.status = ev.type === "session.failed" ? "failed" : "completed";
|
|
594
639
|
touch(n, ev.type === "session.failed" ? ("falhou: " + (ev.error || "")) : "concluída");
|
|
595
640
|
paintSummary();
|
|
596
|
-
feed(agentName(n.agent), ev.type === "session.failed" ? "falhou" : "concluída");
|
|
641
|
+
feed(agentName(n.agent), ev.type === "session.failed" ? "falhou" : "concluída", ev.type === "session.failed" ? "bad" : "");
|
|
597
642
|
// Stop/release cancels the queue server-side: drop a stale "na fila"
|
|
598
643
|
// hint on the open detail, mirroring the turn.started branch.
|
|
599
644
|
if (n.id && n.id === detailId && detailPending) { detailPending = null; paintSendState(); }
|
|
@@ -671,6 +716,7 @@ function frame() {
|
|
|
671
716
|
if (nodes[i].runId === n.runId && nodes[i].isOrch) { o = nodes[i]; break; }
|
|
672
717
|
}
|
|
673
718
|
if (!o) return;
|
|
719
|
+
if (hideDone && isDone(o.status)) return;
|
|
674
720
|
var e = edgeCurve(n, o);
|
|
675
721
|
var pa = w2s(e.ax, e.ay), pb = w2s(e.bx, e.by), pc = w2s(e.cx, e.cy);
|
|
676
722
|
ctx.beginPath();
|
|
@@ -940,8 +986,8 @@ function selectSession(id) {
|
|
|
940
986
|
var repo = s.repository ? String(s.repository).split("/").pop() : "";
|
|
941
987
|
var items = [
|
|
942
988
|
["Modelo", s.model || "—"],
|
|
943
|
-
// effort
|
|
944
|
-
["Esforço", s.effort || "
|
|
989
|
+
// effort chega sempre para claude/codex/omp/antigravity; ausente = opencode (ignora) ou sessão legada.
|
|
990
|
+
["Esforço", s.effort || "n/a"],
|
|
945
991
|
["Repo", repo || "—"],
|
|
946
992
|
["Atividade", s.lastEvent ? (lastEventHuman(s.lastEvent) || s.lastEvent) : "—"],
|
|
947
993
|
];
|
|
@@ -973,14 +1019,14 @@ function selectSession(id) {
|
|
|
973
1019
|
} else if (ev.type === "message" && ev.role === "assistant" && ev.content) {
|
|
974
1020
|
chat.appendChild(chatMsg(agentName(s.agent), String(ev.content), "assistant"));
|
|
975
1021
|
} else if (ev.type === "tool.started") {
|
|
976
|
-
chat.appendChild(chatEvt(
|
|
1022
|
+
chat.appendChild(chatEvt(toolLabel(ev.tool)));
|
|
977
1023
|
} else if (ev.type === "tool.completed") {
|
|
978
1024
|
var bad = ev.tool && ev.tool.success === false;
|
|
979
|
-
chat.appendChild(chatEvt("
|
|
1025
|
+
if (bad) chat.appendChild(chatEvt("falhou: " + toolLabel(ev.tool)));
|
|
980
1026
|
} else if (ev.type === "permission.requested") {
|
|
981
|
-
chat.appendChild(chatEvt("
|
|
1027
|
+
chat.appendChild(chatEvt("precisa de aprovação: " + (ev.tool || "uma ação")));
|
|
982
1028
|
} else if (ev.type === "file.changed") {
|
|
983
|
-
chat.appendChild(chatEvt("
|
|
1029
|
+
chat.appendChild(chatEvt("salvou " + (shortPath(ev.path === "unknown" ? "" : ev.path) || "arquivo")));
|
|
984
1030
|
}
|
|
985
1031
|
}
|
|
986
1032
|
if (!chat.children.length) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canvas-page.js","sourceRoot":"","sources":["../../src/web/canvas-page.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,WAAW,GAAW
|
|
1
|
+
{"version":3,"file":"canvas-page.js","sourceRoot":"","sources":["../../src/web/canvas-page.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,WAAW,GAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAqlC3B,CAAC"}
|