@veewo/claw 0.2.24 → 0.2.26
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/README.md +141 -141
- package/dist/cli.js +59 -88
- package/dist/cli.js.map +1 -1
- package/dist/command-service.js +4 -3
- package/dist/command-service.js.map +1 -1
- package/dist/invocation-host.d.ts +16 -1
- package/dist/invocation-host.js +20 -1
- package/dist/invocation-host.js.map +1 -1
- package/dist/report-collector-registry.d.ts +20 -0
- package/dist/report-collector-registry.js +42 -0
- package/dist/report-collector-registry.js.map +1 -0
- package/package.json +3 -3
- package/dist/codex-transcript.d.ts +0 -7
- package/dist/codex-transcript.js +0 -313
- package/dist/codex-transcript.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,141 +1,141 @@
|
|
|
1
|
-
# @veewo/claw
|
|
2
|
-
|
|
3
|
-
`@veewo/claw` is the CLI entrypoint for running the `.claw` workflow in a project.
|
|
4
|
-
|
|
5
|
-
It gives agents and developers a concrete way to plan work, recall project knowledge, deposit truth and ADR notes, and close rounds out cleanly instead of leaving project state scattered across transient chats.
|
|
6
|
-
|
|
7
|
-
## What the CLI is for
|
|
8
|
-
|
|
9
|
-
- initialize and normalize the `.claw` project surface
|
|
10
|
-
- run project-scoped planning and task lifecycle commands
|
|
11
|
-
- index and query project documentation recall
|
|
12
|
-
- support truth ingestion and closeout flows
|
|
13
|
-
|
|
14
|
-
## Install
|
|
15
|
-
|
|
16
|
-
```bash
|
|
17
|
-
npm install -g @veewo/claw
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
After installing the CLI, project search still needs one-time setup inside each `.claw` project:
|
|
21
|
-
|
|
22
|
-
1. Run `claw context` so `.claw/project.json` is normalized and the default local embedding config is present.
|
|
23
|
-
2. Run `claw search index --refresh` once so the local embedding model can be downloaded or reused and the first vector index can be built.
|
|
24
|
-
|
|
25
|
-
## Host startup context
|
|
26
|
-
|
|
27
|
-
`claw context --host <host>` is the single structured startup-state entrypoint
|
|
28
|
-
for host adapters. A host Hook owns its native event payload, validates its
|
|
29
|
-
trusted cwd and session identity, invokes `context`, and maps the JSON result
|
|
30
|
-
to its own prompt, card, or host-action surface. The CLI does not own platform
|
|
31
|
-
Hook event names or Hook-output envelopes.
|
|
32
|
-
|
|
33
|
-
The result may contain `activeWorkflow`, `error`, `startupRecovery.versionSync`,
|
|
34
|
-
and `searchGuidance`, in addition to project and session state. Adapters must
|
|
35
|
-
not accept cwd or session identity from model input. A missing `activeWorkflow`
|
|
36
|
-
means the session has no bound plan; it does not authorize plan discovery by
|
|
37
|
-
scanning unrelated project tasks.
|
|
38
|
-
|
|
39
|
-
Then run:
|
|
40
|
-
|
|
41
|
-
```bash
|
|
42
|
-
claw init
|
|
43
|
-
claw search index --refresh
|
|
44
|
-
claw search "existing truth or ADR topic"
|
|
45
|
-
claw plan create --title "My task" --goal "Define the first task"
|
|
46
|
-
claw plan create "My templated task" --template default --goal "Route through the default template"
|
|
47
|
-
claw plan create "Ephemeral harness" --scope session --goal "Use plan and Goal workflows without project deposition"
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
`claw plan create` uses explicit `--template` first, otherwise the project's configured `defaultPlanTemplate`, and finally falls back to the built-in `default` template. You can select a template explicitly with `claw plan create "<title>" --template <name>` or `claw plan create --template <name> --title "<title>"`.
|
|
51
|
-
|
|
52
|
-
New project tasks are grouped under `.claw/tasks/YYYY-MM-DD/`. On the first `claw context` call of each local calendar day, claw performs a lock-protected maintenance pass: it removes expired entries from `.claw/runtime/tmp/`, removes workflow task directories that exceed the task TTL even when incomplete, moves eligible date-scoped task folders into the archive, applies `maxTasksToKeep` and archive TTL, removes expired or invalid bindings, and sweeps expired session workflows. This is lazy maintenance, not a background scheduler.
|
|
53
|
-
|
|
54
|
-
`--scope session` stores the workflow in a user-level directory keyed by the platform session id, so it works without a project `.claw` directory and recovers across cwd changes. It preserves plan/task/subplan/Goal behavior while disabling project knowledge capture and project retention. When the session's frozen origin belongs to a valid claw project, its terminal transition refreshes that project's memory and enabled GitNexus index; otherwise it creates no refresh state. Use `claw session clean` for the current session or `claw session clean --expired` for the seven-day TTL sweep.
|
|
55
|
-
|
|
56
|
-
Projects can add reusable templates directly under `.claw/templates` with `.json`, `.js`, `.mjs`, or `.cjs` files. Put `defaultPlanTemplate` in `.claw/project.json` for a shared team default, or in `.claw/project-override.json` for a local personal override.
|
|
57
|
-
|
|
58
|
-
When `.claw/project.json` has `planning: true`, the default `default` template seeds one planning task in `process.discussing`. It loads the effective `externalPlanningSkill`, falling back to `claw-kit:planning`, and stays open while the requirements and proposed solution are discussed and confirmed with the user. Use `plan start` when execution tasks remain; when planning itself resolves the request, complete task 1 and close the plan.
|
|
59
|
-
|
|
60
|
-
When `planning: false`, `claw plan create` seeds the smallest executable plan directly in `process.active`.
|
|
61
|
-
|
|
62
|
-
## Workflow shape
|
|
63
|
-
|
|
64
|
-
In a typical round, the CLI helps land this loop in a project:
|
|
65
|
-
|
|
66
|
-
`plan` -> `search and recall` -> `execute` -> `deposit truth / ADR` -> `close out`
|
|
67
|
-
|
|
68
|
-
That project-level plan structure helps agents carry longer-running work more cleanly than leaving the task in loose chat state alone.
|
|
69
|
-
|
|
70
|
-
## Persistent sessions
|
|
71
|
-
|
|
72
|
-
Open a persistent terminal with:
|
|
73
|
-
|
|
74
|
-
```bash
|
|
75
|
-
claw session open <dir> <agent-session-id>
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
The workdir is immutable for the lifetime of that session. Opening another
|
|
79
|
-
directory closes the prior live connection and opens the composite identity
|
|
80
|
-
`(canonical workdir, agent session id)`; two directories with the same agent id
|
|
81
|
-
remain isolated.
|
|
82
|
-
|
|
83
|
-
Inside the terminal, these commands implicitly target `currentPlan`:
|
|
84
|
-
|
|
85
|
-
```text
|
|
86
|
-
plan show [--simple]
|
|
87
|
-
plan edit ...
|
|
88
|
-
plan wait
|
|
89
|
-
plan done --retrospective "..."
|
|
90
|
-
task add ...
|
|
91
|
-
task edit --id ...
|
|
92
|
-
task done --id ...
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
Use `plan resume` to resume the retained current plan, `plan resume <planId>` to
|
|
96
|
-
make a specified resumable plan current, and `plan leave` to enter
|
|
97
|
-
`end.leave` and clear focus. Every `end.*` triggers end-state finalization;
|
|
98
|
-
`end.leave` remains resumable and does not set `completedAt`.
|
|
99
|
-
|
|
100
|
-
`search --dir <dir> <query>` changes only that search operation. It never
|
|
101
|
-
changes the session workdir or current plan.
|
|
102
|
-
|
|
103
|
-
On an interrupted connection, mutations are never replayed automatically.
|
|
104
|
-
Reopen with the exact command returned by the error, then inspect
|
|
105
|
-
`plan show --simple`. Retained v2 state expires seven days after its last
|
|
106
|
-
update. Legacy session caches are not migrated and canonical plans are never
|
|
107
|
-
deleted by v2 cleanup.
|
|
108
|
-
|
|
109
|
-
Host adapters remain compatible with the stateless CLI. They can adopt
|
|
110
|
-
`@veewo/claw-client` incrementally once they consume the same structured
|
|
111
|
-
post-commit effects; opening a persistent session does not change existing
|
|
112
|
-
adapter behavior.
|
|
113
|
-
|
|
114
|
-
Codex startup workflow should rely on the session hook or startup recovery path instead of treating any extra manual recovery step as required after plan creation.
|
|
115
|
-
|
|
116
|
-
## Search and recall
|
|
117
|
-
|
|
118
|
-
`claw search` is the project recall command for `.claw` memory, truth, ADR, and declared markdown docs. Use it for retained project context rather than code search.
|
|
119
|
-
|
|
120
|
-
When a task needs deeper code investigation or relationship tracing, GitNexus can complement this workflow, but it is optional rather than required for using `claw` itself.
|
|
121
|
-
|
|
122
|
-
Typical setup:
|
|
123
|
-
|
|
124
|
-
```bash
|
|
125
|
-
claw context
|
|
126
|
-
claw search index --refresh
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
If you need deeper backup detail on config or recall behavior, use the adapter reference notes in [packages/codex-adapter/references/project-config-reference.md](../codex-adapter/references/project-config-reference.md) or [packages/opencode-adapter/references/project-config-reference.md](../opencode-adapter/references/project-config-reference.md).
|
|
130
|
-
|
|
131
|
-
## Configuration
|
|
132
|
-
|
|
133
|
-
If you need backup `.claw/project.json` detail, start with the adapter reference notes above and use [docs/project-json-reference.md](../../docs/project-json-reference.md) only for deeper canonical detail.
|
|
134
|
-
|
|
135
|
-
`claw-kit` also stays usable alongside other harnesses or external skills, so the CLI does not assume a single host or investigation surface.
|
|
136
|
-
|
|
137
|
-
The config model is team-friendly as well: `.claw/project.json` carries the shared canonical workflow, while `.claw/project-override.json` leaves room for personal runtime preferences.
|
|
138
|
-
|
|
139
|
-
## Repository
|
|
140
|
-
|
|
141
|
-
- [claw-kit](https://github.com/chanyuenpang/claw-kit)
|
|
1
|
+
# @veewo/claw
|
|
2
|
+
|
|
3
|
+
`@veewo/claw` is the CLI entrypoint for running the `.claw` workflow in a project.
|
|
4
|
+
|
|
5
|
+
It gives agents and developers a concrete way to plan work, recall project knowledge, deposit truth and ADR notes, and close rounds out cleanly instead of leaving project state scattered across transient chats.
|
|
6
|
+
|
|
7
|
+
## What the CLI is for
|
|
8
|
+
|
|
9
|
+
- initialize and normalize the `.claw` project surface
|
|
10
|
+
- run project-scoped planning and task lifecycle commands
|
|
11
|
+
- index and query project documentation recall
|
|
12
|
+
- support truth ingestion and closeout flows
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install -g @veewo/claw
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
After installing the CLI, project search still needs one-time setup inside each `.claw` project:
|
|
21
|
+
|
|
22
|
+
1. Run `claw context` so `.claw/project.json` is normalized and the default local embedding config is present.
|
|
23
|
+
2. Run `claw search index --refresh` once so the local embedding model can be downloaded or reused and the first vector index can be built.
|
|
24
|
+
|
|
25
|
+
## Host startup context
|
|
26
|
+
|
|
27
|
+
`claw context --host <host>` is the single structured startup-state entrypoint
|
|
28
|
+
for host adapters. A host Hook owns its native event payload, validates its
|
|
29
|
+
trusted cwd and session identity, invokes `context`, and maps the JSON result
|
|
30
|
+
to its own prompt, card, or host-action surface. The CLI does not own platform
|
|
31
|
+
Hook event names or Hook-output envelopes.
|
|
32
|
+
|
|
33
|
+
The result may contain `activeWorkflow`, `error`, `startupRecovery.versionSync`,
|
|
34
|
+
and `searchGuidance`, in addition to project and session state. Adapters must
|
|
35
|
+
not accept cwd or session identity from model input. A missing `activeWorkflow`
|
|
36
|
+
means the session has no bound plan; it does not authorize plan discovery by
|
|
37
|
+
scanning unrelated project tasks.
|
|
38
|
+
|
|
39
|
+
Then run:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
claw init
|
|
43
|
+
claw search index --refresh
|
|
44
|
+
claw search "existing truth or ADR topic"
|
|
45
|
+
claw plan create --title "My task" --goal "Define the first task"
|
|
46
|
+
claw plan create "My templated task" --template default --goal "Route through the default template"
|
|
47
|
+
claw plan create "Ephemeral harness" --scope session --goal "Use plan and Goal workflows without project deposition"
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
`claw plan create` uses explicit `--template` first, otherwise the project's configured `defaultPlanTemplate`, and finally falls back to the built-in `default` template. You can select a template explicitly with `claw plan create "<title>" --template <name>` or `claw plan create --template <name> --title "<title>"`.
|
|
51
|
+
|
|
52
|
+
New project tasks are grouped under `.claw/tasks/YYYY-MM-DD/`. On the first `claw context` call of each local calendar day, claw performs a lock-protected maintenance pass: it removes expired entries from `.claw/runtime/tmp/`, removes workflow task directories that exceed the task TTL even when incomplete, moves eligible date-scoped task folders into the archive, applies `maxTasksToKeep` and archive TTL, removes expired or invalid bindings, and sweeps expired session workflows. This is lazy maintenance, not a background scheduler.
|
|
53
|
+
|
|
54
|
+
`--scope session` stores the workflow in a user-level directory keyed by the platform session id, so it works without a project `.claw` directory and recovers across cwd changes. It preserves plan/task/subplan/Goal behavior while disabling project knowledge capture and project retention. When the session's frozen origin belongs to a valid claw project, its terminal transition refreshes that project's memory and enabled GitNexus index; otherwise it creates no refresh state. Use `claw session clean` for the current session or `claw session clean --expired` for the seven-day TTL sweep.
|
|
55
|
+
|
|
56
|
+
Projects can add reusable templates directly under `.claw/templates` with `.json`, `.js`, `.mjs`, or `.cjs` files. Put `defaultPlanTemplate` in `.claw/project.json` for a shared team default, or in `.claw/project-override.json` for a local personal override.
|
|
57
|
+
|
|
58
|
+
When `.claw/project.json` has `planning: true`, the default `default` template seeds one planning task in `process.discussing`. It loads the effective `externalPlanningSkill`, falling back to `claw-kit:planning`, and stays open while the requirements and proposed solution are discussed and confirmed with the user. Use `plan start` when execution tasks remain; when planning itself resolves the request, complete task 1 and close the plan.
|
|
59
|
+
|
|
60
|
+
When `planning: false`, `claw plan create` seeds the smallest executable plan directly in `process.active`.
|
|
61
|
+
|
|
62
|
+
## Workflow shape
|
|
63
|
+
|
|
64
|
+
In a typical round, the CLI helps land this loop in a project:
|
|
65
|
+
|
|
66
|
+
`plan` -> `search and recall` -> `execute` -> `deposit truth / ADR` -> `close out`
|
|
67
|
+
|
|
68
|
+
That project-level plan structure helps agents carry longer-running work more cleanly than leaving the task in loose chat state alone.
|
|
69
|
+
|
|
70
|
+
## Persistent sessions
|
|
71
|
+
|
|
72
|
+
Open a persistent terminal with:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
claw session open <dir> <agent-session-id>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
The workdir is immutable for the lifetime of that session. Opening another
|
|
79
|
+
directory closes the prior live connection and opens the composite identity
|
|
80
|
+
`(canonical workdir, agent session id)`; two directories with the same agent id
|
|
81
|
+
remain isolated.
|
|
82
|
+
|
|
83
|
+
Inside the terminal, these commands implicitly target `currentPlan`:
|
|
84
|
+
|
|
85
|
+
```text
|
|
86
|
+
plan show [--simple]
|
|
87
|
+
plan edit ...
|
|
88
|
+
plan wait
|
|
89
|
+
plan done --retrospective "..."
|
|
90
|
+
task add ...
|
|
91
|
+
task edit --id ...
|
|
92
|
+
task done --id ...
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Use `plan resume` to resume the retained current plan, `plan resume <planId>` to
|
|
96
|
+
make a specified resumable plan current, and `plan leave` to enter
|
|
97
|
+
`end.leave` and clear focus. Every `end.*` triggers end-state finalization;
|
|
98
|
+
`end.leave` remains resumable and does not set `completedAt`.
|
|
99
|
+
|
|
100
|
+
`search --dir <dir> <query>` changes only that search operation. It never
|
|
101
|
+
changes the session workdir or current plan.
|
|
102
|
+
|
|
103
|
+
On an interrupted connection, mutations are never replayed automatically.
|
|
104
|
+
Reopen with the exact command returned by the error, then inspect
|
|
105
|
+
`plan show --simple`. Retained v2 state expires seven days after its last
|
|
106
|
+
update. Legacy session caches are not migrated and canonical plans are never
|
|
107
|
+
deleted by v2 cleanup.
|
|
108
|
+
|
|
109
|
+
Host adapters remain compatible with the stateless CLI. They can adopt
|
|
110
|
+
`@veewo/claw-client` incrementally once they consume the same structured
|
|
111
|
+
post-commit effects; opening a persistent session does not change existing
|
|
112
|
+
adapter behavior.
|
|
113
|
+
|
|
114
|
+
Codex startup workflow should rely on the session hook or startup recovery path instead of treating any extra manual recovery step as required after plan creation.
|
|
115
|
+
|
|
116
|
+
## Search and recall
|
|
117
|
+
|
|
118
|
+
`claw search` is the project recall command for `.claw` memory, truth, ADR, and declared markdown docs. Use it for retained project context rather than code search.
|
|
119
|
+
|
|
120
|
+
When a task needs deeper code investigation or relationship tracing, GitNexus can complement this workflow, but it is optional rather than required for using `claw` itself.
|
|
121
|
+
|
|
122
|
+
Typical setup:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
claw context
|
|
126
|
+
claw search index --refresh
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
If you need deeper backup detail on config or recall behavior, use the adapter reference notes in [packages/codex-adapter/references/project-config-reference.md](../codex-adapter/references/project-config-reference.md) or [packages/opencode-adapter/references/project-config-reference.md](../opencode-adapter/references/project-config-reference.md).
|
|
130
|
+
|
|
131
|
+
## Configuration
|
|
132
|
+
|
|
133
|
+
If you need backup `.claw/project.json` detail, start with the adapter reference notes above and use [docs/project-json-reference.md](../../docs/project-json-reference.md) only for deeper canonical detail.
|
|
134
|
+
|
|
135
|
+
`claw-kit` also stays usable alongside other harnesses or external skills, so the CLI does not assume a single host or investigation surface.
|
|
136
|
+
|
|
137
|
+
The config model is team-friendly as well: `.claw/project.json` carries the shared canonical workflow, while `.claw/project-override.json` leaves room for personal runtime preferences.
|
|
138
|
+
|
|
139
|
+
## Repository
|
|
140
|
+
|
|
141
|
+
- [claw-kit](https://github.com/chanyuenpang/claw-kit)
|
package/dist/cli.js
CHANGED
|
@@ -6,13 +6,13 @@ import { createInterface } from "node:readline";
|
|
|
6
6
|
import { pathToFileURL } from "node:url";
|
|
7
7
|
import { createHash } from "node:crypto";
|
|
8
8
|
import { spawn, spawnSync } from "node:child_process";
|
|
9
|
-
import { buildDirectWorkflowGuidance,
|
|
9
|
+
import { buildDirectWorkflowGuidance, buildKnowledgeAtomicDispatch, buildKnowledgeDelegateDispatch, buildKnowledgeAssignmentTemplate, buildDirectKnowledgeAssignments, buildKnowledgeWriterAssignments, DEFAULT_MAX_TASKS_TO_KEEP, checkProjectProtocol, ClawError, assertRootPlanCreateAllowedForPlan, buildPlanWorkflowGuidance, buildMemoryIndex, buildSessionStartDefaultPrompt, buildSessionStartRecoveredPrompt, editPlan, ensureProjectProtocol, enforceTaskRetention, findKnowledgeFinalizationJobPath, findTaskDirectory, runDailyMaintenance, ingestTruth, initProject, getTemplateTaskDoneChoices, resolvePlanTemplateFile, resolvePlanEffectiveConfig, resolveThreadGoalPlan, resolveKnowledgeWriterForHost, resolveProjectContext, resolveWorkflowProjectContext, resolveSessionWorkflowContext, deleteSessionWorkflow, sweepExpiredSessionWorkflows, resolveSessionBoundPlan, resolveContext, resolveSeedPlanTemplate, searchMemoryAsync, warmProjectMemoryEmbedding, showPlan, createSubplan, createPlanRef, switchTask, tryCaptureKnowledgeStop, claimKnowledgeFinalizationJob, doneKnowledgeFinalizationJob, readKnowledgeFinalizationJob, waitForKnowledgeFinalizationJobReady, listKnowledgeFinalizationJobs, listRetryableKnowledgeFinalizationJobs, normalizeTruthMarkdownEncoding, governKnowledgeMarkdownPaths, resolveKnowledgeDocUpdateSnapshot, recordKnowledgeFinalizationResult, unbindSession, writePlan, } from "@veewo/claw-core";
|
|
10
10
|
import { buildCodexDriverEnvelope } from "./codex-driver.js";
|
|
11
11
|
import { buildCodexHostActions } from "./codex-host-actions.js";
|
|
12
12
|
import { checkCodexRuntime, resolveCodexSdkEntryPath } from "./codex-runtime.js";
|
|
13
|
-
import {
|
|
13
|
+
import { collectReport, registerReportCollector } from "./report-collector-registry.js";
|
|
14
14
|
import { consumeBufferedHookInput } from "./knowledge-hook-preflight.js";
|
|
15
|
-
import { resolveInvocationHost, withoutInvocationHost } from "./invocation-host.js";
|
|
15
|
+
import { isSubagentPolicyHost, resolveInvocationHost, withoutInvocationHost } from "./invocation-host.js";
|
|
16
16
|
import { runOpencodeKnowledgeWriter } from "./opencode-runner.js";
|
|
17
17
|
import { ClawClient, ClawSessionError, } from "@veewo/claw-client";
|
|
18
18
|
const CLI_VERSION = readCliVersion();
|
|
@@ -563,6 +563,9 @@ async function main() {
|
|
|
563
563
|
case "knowledge":
|
|
564
564
|
await runKnowledge(args);
|
|
565
565
|
return;
|
|
566
|
+
case "internal-report-collector-register":
|
|
567
|
+
runInternalReportCollectorRegister(args);
|
|
568
|
+
return;
|
|
566
569
|
case "direct":
|
|
567
570
|
runDirect(args, effectiveHost);
|
|
568
571
|
return;
|
|
@@ -1012,34 +1015,18 @@ function serializeSessionError(error) {
|
|
|
1012
1015
|
}
|
|
1013
1016
|
return { code: "SESSION_COMMAND_FAILED", message: error instanceof Error ? error.message : String(error) };
|
|
1014
1017
|
}
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
catch {
|
|
1025
|
-
throw new ClawError("PROJECT_CONFIG_INVALID", "Cindy knowledge claim report input is invalid JSON.");
|
|
1026
|
-
}
|
|
1027
|
-
const sessionId = typeof parsed.session_id === "string" ? parsed.session_id.trim() : "";
|
|
1028
|
-
const turnId = typeof parsed.turn_id === "string" ? parsed.turn_id.trim() : "";
|
|
1029
|
-
const taskConclusions = Array.isArray(parsed.task_conclusions)
|
|
1030
|
-
? parsed.task_conclusions.flatMap((entry) => {
|
|
1031
|
-
if (!entry || typeof entry !== "object" || Array.isArray(entry))
|
|
1032
|
-
return [];
|
|
1033
|
-
const item = entry;
|
|
1034
|
-
const itemTurnId = typeof item.turnId === "string" ? item.turnId.trim() : "";
|
|
1035
|
-
const message = typeof item.message === "string" ? item.message.trim() : "";
|
|
1036
|
-
return itemTurnId && message ? [{ turnId: itemTurnId, message }] : [];
|
|
1037
|
-
})
|
|
1038
|
-
: [];
|
|
1039
|
-
if (!sessionId || !turnId) {
|
|
1040
|
-
throw new ClawError("PROJECT_CONFIG_INVALID", "Cindy knowledge claim report input requires session_id and turn_id.");
|
|
1018
|
+
/** Adapter-only registration. The descriptor contains no host history schema. */
|
|
1019
|
+
function runInternalReportCollectorRegister(args) {
|
|
1020
|
+
const projectRoot = path.resolve(readRequiredFlag(args, "--project-root"));
|
|
1021
|
+
const host = readRequiredFlag(args, "--collector-host");
|
|
1022
|
+
const executable = readRequiredFlag(args, "--executable");
|
|
1023
|
+
const collectorArgs = readRepeatedFlag(args, "--arg");
|
|
1024
|
+
assertNoRemainingArgs(args, "internal-report-collector-register");
|
|
1025
|
+
if (host !== "codex" && host !== "dsh" && host !== "cindy") {
|
|
1026
|
+
throw new ClawError("PROJECT_CONFIG_INVALID", "report collector host must be codex, dsh, or cindy.");
|
|
1041
1027
|
}
|
|
1042
|
-
|
|
1028
|
+
registerReportCollector(projectRoot, { host, executable, args: collectorArgs });
|
|
1029
|
+
printJson({ ok: true, command: "internal-report-collector-register", host });
|
|
1043
1030
|
}
|
|
1044
1031
|
async function runKnowledge(args) {
|
|
1045
1032
|
const subcommand = args.shift();
|
|
@@ -1124,8 +1111,6 @@ async function runKnowledge(args) {
|
|
|
1124
1111
|
const explicitJobPath = readOptionalFlag(args, "--job");
|
|
1125
1112
|
const projectRoot = readOptionalFlag(args, "--project-root");
|
|
1126
1113
|
const finalizeId = readOptionalFlag(args, "--finalize-id");
|
|
1127
|
-
const captureCindyReport = readBooleanFlag(args, "--cindy-report-stdin");
|
|
1128
|
-
const cindyCapture = captureCindyReport ? readCindyKnowledgeClaimCaptureInput() : undefined;
|
|
1129
1114
|
if (explicitJobPath && (projectRoot || finalizeId)) {
|
|
1130
1115
|
throw new ClawError("PROJECT_CONFIG_INVALID", "knowledge claim accepts either --job or --project-root with --finalize-id.");
|
|
1131
1116
|
}
|
|
@@ -1138,9 +1123,6 @@ async function runKnowledge(args) {
|
|
|
1138
1123
|
throw new Error(`Knowledge finalization ${finalizeId} is unavailable.`);
|
|
1139
1124
|
}
|
|
1140
1125
|
const queued = readKnowledgeFinalizationJob(jobPath);
|
|
1141
|
-
if (queued.host === "codex" && queued.writer?.executionPolicy === "subagent" && queued.reportCapture?.mode === "claim" && queued.reportCapture.status !== "captured") {
|
|
1142
|
-
await new Promise((resolve) => setTimeout(resolve, 10_000));
|
|
1143
|
-
}
|
|
1144
1126
|
const job = claimKnowledgeFinalizationJob(jobPath, {
|
|
1145
1127
|
prepare: (queued) => {
|
|
1146
1128
|
if (queued.writer?.executionPolicy !== "subagent"
|
|
@@ -1148,41 +1130,22 @@ async function runKnowledge(args) {
|
|
|
1148
1130
|
|| queued.reportCapture.status === "captured") {
|
|
1149
1131
|
return;
|
|
1150
1132
|
}
|
|
1151
|
-
if (queued.host
|
|
1152
|
-
if (!cindyCapture) {
|
|
1153
|
-
throw new Error(`Cindy report capture is unavailable for knowledge session ${queued.sessionId}.`);
|
|
1154
|
-
}
|
|
1155
|
-
if (cindyCapture.sessionId !== queued.sessionId) {
|
|
1156
|
-
throw new Error("Cindy report capture does not match the originating knowledge session.");
|
|
1157
|
-
}
|
|
1158
|
-
const capturedAt = new Date().toISOString();
|
|
1159
|
-
appendKnowledgeTaskConclusions(queued.reportPath, queued.sessionId, cindyCapture.taskConclusions, capturedAt);
|
|
1160
|
-
return {
|
|
1161
|
-
reportCapture: {
|
|
1162
|
-
...queued.reportCapture,
|
|
1163
|
-
status: "captured",
|
|
1164
|
-
capturedAt,
|
|
1165
|
-
messageCount: cindyCapture.taskConclusions.length,
|
|
1166
|
-
},
|
|
1167
|
-
};
|
|
1168
|
-
}
|
|
1169
|
-
if (queued.host !== "codex") {
|
|
1133
|
+
if (queued.host !== "codex" && queued.host !== "dsh" && queued.host !== "cindy") {
|
|
1170
1134
|
throw new Error(`Claim-time report capture is unavailable for host ${queued.host ?? "unknown"}.`);
|
|
1171
1135
|
}
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1136
|
+
collectReport({
|
|
1137
|
+
host: queued.host,
|
|
1138
|
+
sessionId: queued.sessionId,
|
|
1139
|
+
projectRoot: queued.projectRoot,
|
|
1140
|
+
planPath: queued.planPath,
|
|
1141
|
+
canonicalReportPath: queued.reportPath,
|
|
1142
|
+
startedAt: queued.reportCapture.startedAt,
|
|
1143
|
+
});
|
|
1179
1144
|
return {
|
|
1180
1145
|
reportCapture: {
|
|
1181
1146
|
...queued.reportCapture,
|
|
1182
1147
|
status: "captured",
|
|
1183
|
-
capturedAt,
|
|
1184
|
-
transcriptPath,
|
|
1185
|
-
messageCount: conclusions.length,
|
|
1148
|
+
capturedAt: new Date().toISOString(),
|
|
1186
1149
|
},
|
|
1187
1150
|
};
|
|
1188
1151
|
},
|
|
@@ -1395,9 +1358,8 @@ async function runPlan(args, effectiveHost) {
|
|
|
1395
1358
|
if (current
|
|
1396
1359
|
&& !current.plan.parentPlan
|
|
1397
1360
|
&& effectiveWriter?.executionPolicy === "subagent"
|
|
1398
|
-
&& effectiveHost
|
|
1399
|
-
|
|
1400
|
-
throw new ClawError("PROJECT_CONFIG_INVALID", 'knowledgeWriter.executionPolicy "subagent" is supported only by the Codex or Cindy host.', { host: effectiveHost ?? null });
|
|
1361
|
+
&& !isSubagentPolicyHost(effectiveHost)) {
|
|
1362
|
+
throw new ClawError("PROJECT_CONFIG_INVALID", 'knowledgeWriter.executionPolicy "subagent" is supported only by the Codex, Cindy, or DSH host.', { host: effectiveHost ?? null });
|
|
1401
1363
|
}
|
|
1402
1364
|
const terminalRefresh = entersEndTerminal
|
|
1403
1365
|
? preparePlanTerminalRefresh(process.cwd(), ownerSessionKey)
|
|
@@ -1412,11 +1374,12 @@ async function runPlan(args, effectiveHost) {
|
|
|
1412
1374
|
});
|
|
1413
1375
|
const knowledgeDispatch = (current
|
|
1414
1376
|
&& project
|
|
1415
|
-
&& (effectiveHost
|
|
1377
|
+
&& (isSubagentPolicyHost(effectiveHost))
|
|
1416
1378
|
&& !current.plan.parentPlan
|
|
1417
1379
|
&& effectiveWriter?.executionPolicy === "subagent"
|
|
1418
1380
|
&& result.knowledgeFinalizeId)
|
|
1419
1381
|
? buildKnowledgeDispatch({
|
|
1382
|
+
// The isSubagentPolicyHost gate above guarantees this is codex | cindy | dsh.
|
|
1420
1383
|
host: effectiveHost,
|
|
1421
1384
|
finalizeId: result.knowledgeFinalizeId,
|
|
1422
1385
|
writer: effectiveWriter,
|
|
@@ -1506,9 +1469,8 @@ async function runPlan(args, effectiveHost) {
|
|
|
1506
1469
|
: undefined, effectiveHost);
|
|
1507
1470
|
if (!current.plan.parentPlan
|
|
1508
1471
|
&& effectiveWriter?.executionPolicy === "subagent"
|
|
1509
|
-
&& effectiveHost
|
|
1510
|
-
|
|
1511
|
-
throw new ClawError("PROJECT_CONFIG_INVALID", 'knowledgeWriter.executionPolicy "subagent" is supported only by the Codex or Cindy host.', { host: effectiveHost ?? null });
|
|
1472
|
+
&& !isSubagentPolicyHost(effectiveHost)) {
|
|
1473
|
+
throw new ClawError("PROJECT_CONFIG_INVALID", 'knowledgeWriter.executionPolicy "subagent" is supported only by the Codex, Cindy, or DSH host.', { host: effectiveHost ?? null });
|
|
1512
1474
|
}
|
|
1513
1475
|
const terminalRefresh = preparePlanTerminalRefresh(process.cwd(), ownerSessionKey);
|
|
1514
1476
|
const result = await editPlan({
|
|
@@ -1519,11 +1481,12 @@ async function runPlan(args, effectiveHost) {
|
|
|
1519
1481
|
host: effectiveHost,
|
|
1520
1482
|
ownerSessionKey,
|
|
1521
1483
|
});
|
|
1522
|
-
const knowledgeDispatch = ((effectiveHost
|
|
1484
|
+
const knowledgeDispatch = (isSubagentPolicyHost(effectiveHost)
|
|
1523
1485
|
&& !current.plan.parentPlan
|
|
1524
1486
|
&& effectiveWriter?.executionPolicy === "subagent"
|
|
1525
1487
|
&& result.knowledgeFinalizeId)
|
|
1526
1488
|
? buildKnowledgeDispatch({
|
|
1489
|
+
// The isSubagentPolicyHost gate above guarantees this is codex | cindy | dsh.
|
|
1527
1490
|
host: effectiveHost,
|
|
1528
1491
|
finalizeId: result.knowledgeFinalizeId,
|
|
1529
1492
|
writer: effectiveWriter,
|
|
@@ -2174,16 +2137,14 @@ async function runStopHook(effectiveHost) {
|
|
|
2174
2137
|
const hookCwd = resolveHookCwd(payload);
|
|
2175
2138
|
const sessionId = resolveOwnerSessionKey(payload);
|
|
2176
2139
|
const turnId = readHookString(payload, "turn_id");
|
|
2177
|
-
const transcriptPath = readHookString(payload, "transcript_path");
|
|
2178
2140
|
const payloadMessage = readHookString(payload, "message");
|
|
2179
2141
|
if (!hookCwd || !sessionId || !turnId || !containsClawDir(hookCwd)) {
|
|
2180
2142
|
return;
|
|
2181
2143
|
}
|
|
2182
2144
|
try {
|
|
2183
2145
|
const project = resolveProjectContext(hookCwd);
|
|
2184
|
-
//
|
|
2185
|
-
|
|
2186
|
-
const message = payloadMessage ?? (transcriptPath ? extractLatestFinalAssistantMessage(transcriptPath, turnId) : null);
|
|
2146
|
+
// Host adapters own history parsing and pass their current final inline.
|
|
2147
|
+
const message = payloadMessage;
|
|
2187
2148
|
if (!message) {
|
|
2188
2149
|
return;
|
|
2189
2150
|
}
|
|
@@ -2193,7 +2154,7 @@ async function runStopHook(effectiveHost) {
|
|
|
2193
2154
|
turnId,
|
|
2194
2155
|
message,
|
|
2195
2156
|
host: effectiveHost,
|
|
2196
|
-
taskConclusions:
|
|
2157
|
+
taskConclusions: [],
|
|
2197
2158
|
});
|
|
2198
2159
|
// Current named hosts own their runner in their adapters. Keep the CLI
|
|
2199
2160
|
// launcher only for jobs written by pre-adapter releases with no host.
|
|
@@ -3088,6 +3049,8 @@ function stripBom(content) {
|
|
|
3088
3049
|
return content.charCodeAt(0) === 0xfeff ? content.slice(1) : content;
|
|
3089
3050
|
}
|
|
3090
3051
|
function buildKnowledgeDispatch(input) {
|
|
3052
|
+
// Cindy uses its Orca atomic dispatch; codex and dsh both dispatch through a
|
|
3053
|
+
// native-subagent delegate (DSH: subagent / subagent_fork).
|
|
3091
3054
|
if (input.host === "cindy") {
|
|
3092
3055
|
return buildKnowledgeAtomicDispatch(input);
|
|
3093
3056
|
}
|
|
@@ -3103,19 +3066,27 @@ function compactPlanCommandResult(command, result, effectiveHost, completionRefr
|
|
|
3103
3066
|
? completionRefresh.taskRetention.archivedCurrentTask.archivedPlanPath
|
|
3104
3067
|
: undefined;
|
|
3105
3068
|
const resolvedPlanPath = archivedPlanPath ?? result.planPath;
|
|
3106
|
-
|
|
3069
|
+
// codex and dsh share the same compact protocol and versioned hostActions
|
|
3070
|
+
// (schemaVersion 1: update_plan / create_goal / update_goal). The Codex
|
|
3071
|
+
// adapter consumes them via its fixed code-mode driver; the DSH adapter
|
|
3072
|
+
// consumes them inside the claw_run tool's execute.
|
|
3073
|
+
const hostActionsResult = effectiveHost === "codex" || effectiveHost === "dsh";
|
|
3107
3074
|
const cindyResult = effectiveHost === "cindy";
|
|
3108
|
-
const hostActions =
|
|
3075
|
+
const hostActions = hostActionsResult ? buildCodexHostActions(result, { forceProjectionSync, actionIdPrefix: command === "plan.sync" ? `plan.sync:${createHash("sha256").update(result.planPath).digest("hex").slice(0, 16)}` : undefined }) : [];
|
|
3109
3076
|
const nextsteps = [
|
|
3110
3077
|
...result.workflowGuidance.nextsteps,
|
|
3111
|
-
|
|
3078
|
+
// Manual-dispatch instruction for hosts WITHOUT automatic writer
|
|
3079
|
+
// dispatch (codex/cindy/opencode). DSH's adapter auto-dispatches the
|
|
3080
|
+
// writer subagent inside claw_run, so the model must NOT re-dispatch;
|
|
3081
|
+
// injecting this line there would ask it to duplicate the dispatch.
|
|
3082
|
+
...(knowledgeDispatch && effectiveHost !== "dsh"
|
|
3112
3083
|
? ["A knowledgeDispatch is present: dispatch its unchanged prompt through the current Host's designated knowledge-finalizer now, then immediately end the Lead turn; do not wait for or poll that worker."]
|
|
3113
3084
|
: []),
|
|
3114
3085
|
];
|
|
3115
3086
|
const planSummary = result.planView.collapsedSummary;
|
|
3116
3087
|
const includePlan = Boolean((command === "plan.create" || command === "subplan.create")
|
|
3117
3088
|
&& result.plan
|
|
3118
|
-
&& (!
|
|
3089
|
+
&& (!hostActionsResult || result.workflowGuidance.stage === "discussion"));
|
|
3119
3090
|
const achievement = result.planStatus === "end.completed" && result.plan
|
|
3120
3091
|
? {
|
|
3121
3092
|
status: result.planStatus,
|
|
@@ -3138,11 +3109,11 @@ function compactPlanCommandResult(command, result, effectiveHost, completionRefr
|
|
|
3138
3109
|
...(result.workflowGuidance.transition ? { transition: result.workflowGuidance.transition } : {}),
|
|
3139
3110
|
...(achievement ? { achievement } : {}),
|
|
3140
3111
|
...(knowledgeDispatch ? { knowledgeDispatch } : {}),
|
|
3141
|
-
...(!
|
|
3112
|
+
...(!hostActionsResult && result.previousPlanStatus ? { previousPlanStatus: result.previousPlanStatus } : {}),
|
|
3142
3113
|
...(hostActions.length ? { hostActions } : {}),
|
|
3143
|
-
...(!
|
|
3144
|
-
...(!
|
|
3145
|
-
...(
|
|
3114
|
+
...(!hostActionsResult && result.changedTaskIds?.length ? { changedTaskIds: result.changedTaskIds } : {}),
|
|
3115
|
+
...(!hostActionsResult && result.appendedTaskIds?.length ? { appendedTaskIds: result.appendedTaskIds } : {}),
|
|
3116
|
+
...(hostActionsResult ? { stage: result.workflowGuidance.stage } : {}),
|
|
3146
3117
|
nextsteps,
|
|
3147
3118
|
...(result.workflowGuidance.nextTask ? { nextTask: result.workflowGuidance.nextTask } : {}),
|
|
3148
3119
|
...(result.workflowGuidance.notes?.trim() && !cindyResult
|
|
@@ -3160,8 +3131,8 @@ function compactPlanCommandResult(command, result, effectiveHost, completionRefr
|
|
|
3160
3131
|
failedOperation: result.operationChain.failedOperation,
|
|
3161
3132
|
}
|
|
3162
3133
|
: {}),
|
|
3163
|
-
...(!
|
|
3164
|
-
...(!
|
|
3134
|
+
...(!hostActionsResult && !cindyResult && result.workflowGuidance.goalMode ? { goalMode: result.workflowGuidance.goalMode } : {}),
|
|
3135
|
+
...(!hostActionsResult && !cindyResult && result.workflowGuidance.goalTool ? { goalTool: result.workflowGuidance.goalTool } : {}),
|
|
3165
3136
|
...(includePlan && result.plan ? { plan: result.plan } : {}),
|
|
3166
3137
|
// Cindy's Ghost card is a Host-owned projection. It needs the
|
|
3167
3138
|
// canonical task list to render its expandable Todo view, but that
|
|
@@ -3177,7 +3148,7 @@ function compactPlanCommandResult(command, result, effectiveHost, completionRefr
|
|
|
3177
3148
|
},
|
|
3178
3149
|
}
|
|
3179
3150
|
: {}),
|
|
3180
|
-
...(!
|
|
3151
|
+
...(!hostActionsResult || !includePlan ? { planSummary } : {}),
|
|
3181
3152
|
};
|
|
3182
3153
|
}
|
|
3183
3154
|
function compactDirectCommandResult(command, workflowGuidance, completionRefresh) {
|