@veewo/claw 0.2.23 → 0.2.25
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 +98 -21
- package/dist/cli.js.map +1 -1
- package/dist/command-service.js +13 -4
- package/dist/command-service.js.map +1 -1
- package/dist/dsh-capture.d.ts +22 -0
- package/dist/dsh-capture.js +34 -0
- package/dist/dsh-capture.js.map +1 -0
- package/dist/invocation-host.d.ts +16 -1
- package/dist/invocation-host.js +20 -1
- package/dist/invocation-host.js.map +1 -1
- package/package.json +3 -3
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,14 @@ 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, appendKnowledgeTaskConclusions, 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, 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";
|
|
9
|
+
import { buildDirectWorkflowGuidance, appendKnowledgeTaskConclusions, 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
13
|
import { extractLatestFinalAssistantMessage, extractTaskDoneConclusions, findCodexTranscriptPath, } from "./codex-transcript.js";
|
|
14
|
+
import { readDshKnowledgeCapture } from "./dsh-capture.js";
|
|
14
15
|
import { consumeBufferedHookInput } from "./knowledge-hook-preflight.js";
|
|
15
|
-
import { resolveInvocationHost, withoutInvocationHost } from "./invocation-host.js";
|
|
16
|
+
import { isSubagentPolicyHost, resolveInvocationHost, withoutInvocationHost } from "./invocation-host.js";
|
|
16
17
|
import { runOpencodeKnowledgeWriter } from "./opencode-runner.js";
|
|
17
18
|
import { ClawClient, ClawSessionError, } from "@veewo/claw-client";
|
|
18
19
|
const CLI_VERSION = readCliVersion();
|
|
@@ -1166,6 +1167,68 @@ async function runKnowledge(args) {
|
|
|
1166
1167
|
},
|
|
1167
1168
|
};
|
|
1168
1169
|
}
|
|
1170
|
+
if (queued.host === "dsh") {
|
|
1171
|
+
// The dsh-adapter plugin reads the DSH session log at the terminal
|
|
1172
|
+
// plan mutation and writes the extracted final message + task.done
|
|
1173
|
+
// conclusions to a capture file (mirroring the Codex transcript
|
|
1174
|
+
// hand-off). Only conclusions from THIS plan's window are used:
|
|
1175
|
+
// the job's reportCapture.startedAt (registry activeStartedAt) is
|
|
1176
|
+
// the authoritative window start, and each conclusion carries its
|
|
1177
|
+
// event time.
|
|
1178
|
+
const capture = readDshKnowledgeCapture(queued.sessionId);
|
|
1179
|
+
if (!capture || capture.sessionId !== queued.sessionId) {
|
|
1180
|
+
throw new Error(`DSH report capture is unavailable for knowledge session ${queued.sessionId}.`);
|
|
1181
|
+
}
|
|
1182
|
+
const startedAtMs = queued.reportCapture?.startedAt
|
|
1183
|
+
? Date.parse(queued.reportCapture.startedAt)
|
|
1184
|
+
: Number.NaN;
|
|
1185
|
+
const conclusions = (capture.taskConclusions ?? []).filter((conclusion) => {
|
|
1186
|
+
const time = conclusion.time;
|
|
1187
|
+
if (Number.isFinite(startedAtMs) && typeof time === "number") {
|
|
1188
|
+
return time >= startedAtMs;
|
|
1189
|
+
}
|
|
1190
|
+
return true;
|
|
1191
|
+
});
|
|
1192
|
+
const capturedAt = new Date().toISOString();
|
|
1193
|
+
appendKnowledgeTaskConclusions(queued.reportPath, queued.sessionId, conclusions, capturedAt);
|
|
1194
|
+
return {
|
|
1195
|
+
reportCapture: {
|
|
1196
|
+
...queued.reportCapture,
|
|
1197
|
+
status: "captured",
|
|
1198
|
+
capturedAt,
|
|
1199
|
+
messageCount: conclusions.length,
|
|
1200
|
+
},
|
|
1201
|
+
};
|
|
1202
|
+
}
|
|
1203
|
+
if (queued.host == null) {
|
|
1204
|
+
// A job created by a pre-dsh-host build has host null. The
|
|
1205
|
+
// dsh-adapter plugin is the only writer of the dsh-capture file,
|
|
1206
|
+
// so its presence proves this is a DSH-originated session; route it
|
|
1207
|
+
// through the dsh branch instead of failing as "host unknown".
|
|
1208
|
+
const capture = readDshKnowledgeCapture(queued.sessionId);
|
|
1209
|
+
if (capture && capture.sessionId === queued.sessionId) {
|
|
1210
|
+
const startedAtMs = queued.reportCapture?.startedAt
|
|
1211
|
+
? Date.parse(queued.reportCapture.startedAt)
|
|
1212
|
+
: Number.NaN;
|
|
1213
|
+
const conclusions = (capture.taskConclusions ?? []).filter((conclusion) => {
|
|
1214
|
+
const time = conclusion.time;
|
|
1215
|
+
if (Number.isFinite(startedAtMs) && typeof time === "number") {
|
|
1216
|
+
return time >= startedAtMs;
|
|
1217
|
+
}
|
|
1218
|
+
return true;
|
|
1219
|
+
});
|
|
1220
|
+
const capturedAt = new Date().toISOString();
|
|
1221
|
+
appendKnowledgeTaskConclusions(queued.reportPath, queued.sessionId, conclusions, capturedAt);
|
|
1222
|
+
return {
|
|
1223
|
+
reportCapture: {
|
|
1224
|
+
...queued.reportCapture,
|
|
1225
|
+
status: "captured",
|
|
1226
|
+
capturedAt,
|
|
1227
|
+
messageCount: conclusions.length,
|
|
1228
|
+
},
|
|
1229
|
+
};
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1169
1232
|
if (queued.host !== "codex") {
|
|
1170
1233
|
throw new Error(`Claim-time report capture is unavailable for host ${queued.host ?? "unknown"}.`);
|
|
1171
1234
|
}
|
|
@@ -1395,9 +1458,8 @@ async function runPlan(args, effectiveHost) {
|
|
|
1395
1458
|
if (current
|
|
1396
1459
|
&& !current.plan.parentPlan
|
|
1397
1460
|
&& 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 });
|
|
1461
|
+
&& !isSubagentPolicyHost(effectiveHost)) {
|
|
1462
|
+
throw new ClawError("PROJECT_CONFIG_INVALID", 'knowledgeWriter.executionPolicy "subagent" is supported only by the Codex, Cindy, or DSH host.', { host: effectiveHost ?? null });
|
|
1401
1463
|
}
|
|
1402
1464
|
const terminalRefresh = entersEndTerminal
|
|
1403
1465
|
? preparePlanTerminalRefresh(process.cwd(), ownerSessionKey)
|
|
@@ -1412,11 +1474,12 @@ async function runPlan(args, effectiveHost) {
|
|
|
1412
1474
|
});
|
|
1413
1475
|
const knowledgeDispatch = (current
|
|
1414
1476
|
&& project
|
|
1415
|
-
&& (effectiveHost
|
|
1477
|
+
&& (isSubagentPolicyHost(effectiveHost))
|
|
1416
1478
|
&& !current.plan.parentPlan
|
|
1417
1479
|
&& effectiveWriter?.executionPolicy === "subagent"
|
|
1418
1480
|
&& result.knowledgeFinalizeId)
|
|
1419
1481
|
? buildKnowledgeDispatch({
|
|
1482
|
+
// The isSubagentPolicyHost gate above guarantees this is codex | cindy | dsh.
|
|
1420
1483
|
host: effectiveHost,
|
|
1421
1484
|
finalizeId: result.knowledgeFinalizeId,
|
|
1422
1485
|
writer: effectiveWriter,
|
|
@@ -1506,9 +1569,8 @@ async function runPlan(args, effectiveHost) {
|
|
|
1506
1569
|
: undefined, effectiveHost);
|
|
1507
1570
|
if (!current.plan.parentPlan
|
|
1508
1571
|
&& 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 });
|
|
1572
|
+
&& !isSubagentPolicyHost(effectiveHost)) {
|
|
1573
|
+
throw new ClawError("PROJECT_CONFIG_INVALID", 'knowledgeWriter.executionPolicy "subagent" is supported only by the Codex, Cindy, or DSH host.', { host: effectiveHost ?? null });
|
|
1512
1574
|
}
|
|
1513
1575
|
const terminalRefresh = preparePlanTerminalRefresh(process.cwd(), ownerSessionKey);
|
|
1514
1576
|
const result = await editPlan({
|
|
@@ -1519,11 +1581,12 @@ async function runPlan(args, effectiveHost) {
|
|
|
1519
1581
|
host: effectiveHost,
|
|
1520
1582
|
ownerSessionKey,
|
|
1521
1583
|
});
|
|
1522
|
-
const knowledgeDispatch = ((effectiveHost
|
|
1584
|
+
const knowledgeDispatch = (isSubagentPolicyHost(effectiveHost)
|
|
1523
1585
|
&& !current.plan.parentPlan
|
|
1524
1586
|
&& effectiveWriter?.executionPolicy === "subagent"
|
|
1525
1587
|
&& result.knowledgeFinalizeId)
|
|
1526
1588
|
? buildKnowledgeDispatch({
|
|
1589
|
+
// The isSubagentPolicyHost gate above guarantees this is codex | cindy | dsh.
|
|
1527
1590
|
host: effectiveHost,
|
|
1528
1591
|
finalizeId: result.knowledgeFinalizeId,
|
|
1529
1592
|
writer: effectiveWriter,
|
|
@@ -1599,12 +1662,20 @@ async function runPlanSync(args, effectiveHost) {
|
|
|
1599
1662
|
return;
|
|
1600
1663
|
}
|
|
1601
1664
|
const project = resolveWorkflowProjectContext(process.cwd(), ownerSessionKey);
|
|
1665
|
+
const goalPlan = resolveThreadGoalPlan({
|
|
1666
|
+
cwd: process.cwd(),
|
|
1667
|
+
taskName: result.taskName,
|
|
1668
|
+
focusedPlan: result.plan,
|
|
1669
|
+
ownerSessionKey,
|
|
1670
|
+
});
|
|
1602
1671
|
const workflowGuidance = await buildPlanWorkflowGuidance({
|
|
1603
1672
|
taskName: result.taskName,
|
|
1604
1673
|
planFile: result.planFile,
|
|
1605
1674
|
plan: result.plan,
|
|
1606
1675
|
projectRoot: project.projectRoot,
|
|
1607
1676
|
projectConfig: project.projectConfig,
|
|
1677
|
+
goalPlan,
|
|
1678
|
+
goalProjectConfig: resolvePlanEffectiveConfig(project.projectConfig, goalPlan),
|
|
1608
1679
|
scope: project.scope,
|
|
1609
1680
|
previousStatus: "process.wait",
|
|
1610
1681
|
host: effectiveHost,
|
|
@@ -2752,7 +2823,7 @@ function buildSessionStartAdditionalContext(context, sessionCwd, effectiveHost)
|
|
|
2752
2823
|
if (activeWorkflow) {
|
|
2753
2824
|
const prompt = buildRecoveredWorkflowAdditionalContext(activeWorkflow, versionSyncPrompt);
|
|
2754
2825
|
const recoverySyncPrompt = effectiveHost === "codex" && activeWorkflow.planStatus === "process.active"
|
|
2755
|
-
? "Before continuing, run `claw plan sync` once through the fixed Codex driver to restore
|
|
2826
|
+
? "Before continuing, run `claw plan sync` once through the fixed Codex driver to restore focused-plan progress and reconcile the root-plan Goal."
|
|
2756
2827
|
: "";
|
|
2757
2828
|
const promptWithSync = recoverySyncPrompt ? `${prompt}\n${recoverySyncPrompt}` : prompt;
|
|
2758
2829
|
const promptWithSearch = searchGuidance ? `${promptWithSync}\n${searchGuidance}` : promptWithSync;
|
|
@@ -3080,6 +3151,8 @@ function stripBom(content) {
|
|
|
3080
3151
|
return content.charCodeAt(0) === 0xfeff ? content.slice(1) : content;
|
|
3081
3152
|
}
|
|
3082
3153
|
function buildKnowledgeDispatch(input) {
|
|
3154
|
+
// Cindy uses its Orca atomic dispatch; codex and dsh both dispatch through a
|
|
3155
|
+
// native-subagent delegate (DSH: subagent / subagent_fork).
|
|
3083
3156
|
if (input.host === "cindy") {
|
|
3084
3157
|
return buildKnowledgeAtomicDispatch(input);
|
|
3085
3158
|
}
|
|
@@ -3095,9 +3168,13 @@ function compactPlanCommandResult(command, result, effectiveHost, completionRefr
|
|
|
3095
3168
|
? completionRefresh.taskRetention.archivedCurrentTask.archivedPlanPath
|
|
3096
3169
|
: undefined;
|
|
3097
3170
|
const resolvedPlanPath = archivedPlanPath ?? result.planPath;
|
|
3098
|
-
|
|
3171
|
+
// codex and dsh share the same compact protocol and versioned hostActions
|
|
3172
|
+
// (schemaVersion 1: update_plan / create_goal / update_goal). The Codex
|
|
3173
|
+
// adapter consumes them via its fixed code-mode driver; the DSH adapter
|
|
3174
|
+
// consumes them inside the claw_run tool's execute.
|
|
3175
|
+
const hostActionsResult = effectiveHost === "codex" || effectiveHost === "dsh";
|
|
3099
3176
|
const cindyResult = effectiveHost === "cindy";
|
|
3100
|
-
const hostActions =
|
|
3177
|
+
const hostActions = hostActionsResult ? buildCodexHostActions(result, { forceProjectionSync, actionIdPrefix: command === "plan.sync" ? `plan.sync:${createHash("sha256").update(result.planPath).digest("hex").slice(0, 16)}` : undefined }) : [];
|
|
3101
3178
|
const nextsteps = [
|
|
3102
3179
|
...result.workflowGuidance.nextsteps,
|
|
3103
3180
|
...(knowledgeDispatch
|
|
@@ -3107,7 +3184,7 @@ function compactPlanCommandResult(command, result, effectiveHost, completionRefr
|
|
|
3107
3184
|
const planSummary = result.planView.collapsedSummary;
|
|
3108
3185
|
const includePlan = Boolean((command === "plan.create" || command === "subplan.create")
|
|
3109
3186
|
&& result.plan
|
|
3110
|
-
&& (!
|
|
3187
|
+
&& (!hostActionsResult || result.workflowGuidance.stage === "discussion"));
|
|
3111
3188
|
const achievement = result.planStatus === "end.completed" && result.plan
|
|
3112
3189
|
? {
|
|
3113
3190
|
status: result.planStatus,
|
|
@@ -3130,11 +3207,11 @@ function compactPlanCommandResult(command, result, effectiveHost, completionRefr
|
|
|
3130
3207
|
...(result.workflowGuidance.transition ? { transition: result.workflowGuidance.transition } : {}),
|
|
3131
3208
|
...(achievement ? { achievement } : {}),
|
|
3132
3209
|
...(knowledgeDispatch ? { knowledgeDispatch } : {}),
|
|
3133
|
-
...(!
|
|
3210
|
+
...(!hostActionsResult && result.previousPlanStatus ? { previousPlanStatus: result.previousPlanStatus } : {}),
|
|
3134
3211
|
...(hostActions.length ? { hostActions } : {}),
|
|
3135
|
-
...(!
|
|
3136
|
-
...(!
|
|
3137
|
-
...(
|
|
3212
|
+
...(!hostActionsResult && result.changedTaskIds?.length ? { changedTaskIds: result.changedTaskIds } : {}),
|
|
3213
|
+
...(!hostActionsResult && result.appendedTaskIds?.length ? { appendedTaskIds: result.appendedTaskIds } : {}),
|
|
3214
|
+
...(hostActionsResult ? { stage: result.workflowGuidance.stage } : {}),
|
|
3138
3215
|
nextsteps,
|
|
3139
3216
|
...(result.workflowGuidance.nextTask ? { nextTask: result.workflowGuidance.nextTask } : {}),
|
|
3140
3217
|
...(result.workflowGuidance.notes?.trim() && !cindyResult
|
|
@@ -3152,8 +3229,8 @@ function compactPlanCommandResult(command, result, effectiveHost, completionRefr
|
|
|
3152
3229
|
failedOperation: result.operationChain.failedOperation,
|
|
3153
3230
|
}
|
|
3154
3231
|
: {}),
|
|
3155
|
-
...(!
|
|
3156
|
-
...(!
|
|
3232
|
+
...(!hostActionsResult && !cindyResult && result.workflowGuidance.goalMode ? { goalMode: result.workflowGuidance.goalMode } : {}),
|
|
3233
|
+
...(!hostActionsResult && !cindyResult && result.workflowGuidance.goalTool ? { goalTool: result.workflowGuidance.goalTool } : {}),
|
|
3157
3234
|
...(includePlan && result.plan ? { plan: result.plan } : {}),
|
|
3158
3235
|
// Cindy's Ghost card is a Host-owned projection. It needs the
|
|
3159
3236
|
// canonical task list to render its expandable Todo view, but that
|
|
@@ -3169,7 +3246,7 @@ function compactPlanCommandResult(command, result, effectiveHost, completionRefr
|
|
|
3169
3246
|
},
|
|
3170
3247
|
}
|
|
3171
3248
|
: {}),
|
|
3172
|
-
...(!
|
|
3249
|
+
...(!hostActionsResult || !includePlan ? { planSummary } : {}),
|
|
3173
3250
|
};
|
|
3174
3251
|
}
|
|
3175
3252
|
function compactDirectCommandResult(command, workflowGuidance, completionRefresh) {
|