greprag 5.74.6 → 5.74.7

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.
@@ -34,10 +34,14 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.pruneDependencyInstalls = pruneDependencyInstalls;
37
+ exports.codexManagedWorktreeRoot = codexManagedWorktreeRoot;
38
+ exports.cleanupCodexOrphanPath = cleanupCodexOrphanPath;
39
+ exports.runCleanupOrphanCommand = runCleanupOrphanCommand;
37
40
  exports.runCleanupCommand = runCleanupCommand;
38
41
  const fs = __importStar(require("fs"));
39
42
  const os = __importStar(require("os"));
40
43
  const path = __importStar(require("path"));
44
+ const proc_1 = require("../../proc");
41
45
  const git_1 = require("./git");
42
46
  const model_1 = require("./model");
43
47
  const store_1 = require("./store");
@@ -89,6 +93,80 @@ function pruneDependencyInstalls(checkout) {
89
93
  walk(root);
90
94
  return removed;
91
95
  }
96
+ function codexManagedWorktreeRoot() {
97
+ return path.resolve(process.env.CODEX_HOME || path.join(process.env.HOME || process.env.USERPROFILE || os.homedir(), '.codex'), 'worktrees');
98
+ }
99
+ function assertUnderManagedRoot(target, safeRoot = codexManagedWorktreeRoot()) {
100
+ const root = path.resolve(safeRoot);
101
+ const resolved = path.resolve(target);
102
+ const relative = path.relative(root, resolved);
103
+ if (!relative || relative.startsWith('..') || path.isAbsolute(relative)) {
104
+ throw new Error(`Refusing cleanup outside the managed Codex worktree root: ${root}.`);
105
+ }
106
+ return resolved;
107
+ }
108
+ function gitCandidateDirs(root) {
109
+ const candidates = [];
110
+ const walk = (dir) => {
111
+ let entries;
112
+ try {
113
+ entries = fs.readdirSync(dir, { withFileTypes: true });
114
+ }
115
+ catch {
116
+ return;
117
+ }
118
+ if (entries.some(entry => entry.name === '.git')) {
119
+ candidates.push(dir);
120
+ return;
121
+ }
122
+ for (const entry of entries) {
123
+ if (!entry.isDirectory() || entry.isSymbolicLink())
124
+ continue;
125
+ if (entry.name === 'node_modules')
126
+ continue;
127
+ walk(path.join(dir, entry.name));
128
+ }
129
+ };
130
+ if (fs.existsSync(root))
131
+ walk(root);
132
+ return candidates;
133
+ }
134
+ function isUsableGitCheckout(dir) {
135
+ try {
136
+ return (0, proc_1.safeExecFileSync)('git', ['-C', dir, 'rev-parse', '--is-inside-work-tree'], {
137
+ encoding: 'utf-8',
138
+ stdio: ['ignore', 'pipe', 'ignore'],
139
+ }).trim() === 'true';
140
+ }
141
+ catch {
142
+ return false;
143
+ }
144
+ }
145
+ function cleanupCodexOrphanPath(targetArg, opts = {}) {
146
+ if (!targetArg)
147
+ throw new Error('Orphan path is required.');
148
+ const target = assertUnderManagedRoot(targetArg);
149
+ if (!fs.existsSync(target))
150
+ return { target, removed: false, gitCandidates: [] };
151
+ const gitCandidates = gitCandidateDirs(target);
152
+ const usable = gitCandidates.filter(isUsableGitCheckout);
153
+ if (usable.length) {
154
+ throw new Error(`Refusing to remove a usable Git checkout under the orphan path: ${usable[0]}.`);
155
+ }
156
+ if (!opts.dryRun)
157
+ fs.rmSync(target, { recursive: true, force: true });
158
+ return { target, removed: !fs.existsSync(target), gitCandidates };
159
+ }
160
+ function runCleanupOrphanCommand(args) {
161
+ const target = args[0];
162
+ const result = cleanupCodexOrphanPath(target, { dryRun: args.includes('--dry-run'), json: args.includes('--json') });
163
+ if (args.includes('--json'))
164
+ return void console.log(JSON.stringify({
165
+ protocol: 'greprag-codex-orphan-cleanup-v1',
166
+ ...result,
167
+ }, null, 2));
168
+ console.log(`${result.removed ? 'removed' : 'not-found'} ${result.target}`);
169
+ }
92
170
  function runCleanupCommand(args) {
93
171
  const ref = args[0];
94
172
  if (!ref)
@@ -115,9 +193,7 @@ function runCleanupCommand(args) {
115
193
  }
116
194
  if (!manifest.worker?.settledAt && !force)
117
195
  throw new Error('Chip worker has not settled; wait or use --force for a dead stale worker.');
118
- const safeRoot = native
119
- ? path.resolve(process.env.CODEX_HOME || path.join(process.env.HOME || process.env.USERPROFILE || os.homedir(), '.codex'), 'worktrees')
120
- : path.resolve((0, store_1.chipWorktreeRoot)(manifest.project.id));
196
+ const safeRoot = native ? codexManagedWorktreeRoot() : path.resolve((0, store_1.chipWorktreeRoot)(manifest.project.id));
121
197
  const target = path.resolve(native ? (0, model_1.chipExecutionPath)(manifest) : manifest.worktree.path);
122
198
  const relative = path.relative(safeRoot, target);
123
199
  if (!relative || relative.startsWith('..') || path.isAbsolute(relative))
@@ -491,6 +491,8 @@ async function runCodexChip(args) {
491
491
  return blockChip(rest);
492
492
  if (sub === 'cleanup')
493
493
  return (0, cleanup_command_1.runCleanupCommand)(rest);
494
+ if (sub === 'cleanup-orphan')
495
+ return (0, cleanup_command_1.runCleanupOrphanCommand)(rest);
494
496
  if (sub === 'reconcile')
495
497
  return reconcile();
496
498
  if (sub === 'list') {
@@ -8,6 +8,7 @@ exports.CODEX_CHIP_HELP = `greprag codex chip — Codex task orchestration
8
8
  greprag codex chip handoff <id|name> [--json]
9
9
  greprag codex chip verify-title <id|name> <attestation flags from handoff>
10
10
  greprag codex chip attach|status|stop|cleanup <id|name>
11
+ greprag codex chip cleanup-orphan <path-under-CODEX_HOME/worktrees> [--json]
11
12
  greprag codex chip report <id|name> --summary "<result>" [--check "<check>"]
12
13
  greprag codex chip block <id|name> --reason "<blocker>" | list | reconcile
13
14
  greprag codex chip resume <id|name> | list | reconcile
@@ -4,6 +4,7 @@ exports.chipPrompt = chipPrompt;
4
4
  const model_1 = require("./model");
5
5
  /** The short native handoff keeps the real assignment dominant. */
6
6
  function chipPrompt(manifest, _cliCommand = 'greprag') {
7
+ // adr: adr/codex-chip-lifecycle.md
7
8
  const executionPath = manifest.codex.runtime === 'native' && !manifest.codex.nativeCwd
8
9
  ? 'the Codex-provided isolated worktree for this task'
9
10
  : (0, model_1.chipExecutionPath)(manifest);
@@ -15,24 +16,27 @@ function chipPrompt(manifest, _cliCommand = 'greprag') {
15
16
  ? '- Create a native top-level mission goal with `create_goal`, then run `get_goal` and verify the active goal names this mission before any child fanout.\n'
16
17
  : '';
17
18
  const native = manifest.codex.runtime === 'native';
19
+ const startupInstruction = native
20
+ ? `- After setup and bootstrap succeed, reply to the LEAD in the native Codex task thread: \`IN-FLIGHT: ${(0, model_1.chipTitle)(manifest)} — setup complete; work started\`. If setup fails, reply \`BLOCKED\` with the exact failure instead.\n`
21
+ : '';
18
22
  const reportInstruction = native
19
- ? '- Commit the completed durable result, including report-only artifacts, then reply to the LEAD in the native Codex task thread with status, commit hash, checks, caveats, cleanup parameters, and archive clearance.'
23
+ ? '- Commit the durable result, then reply to the LEAD in the native Codex task thread with `DONE` or `BLOCKED`, commit hash if any, checks, material caveats, cleanup parameters, and archive clearance.'
20
24
  : '- Commit the completed durable result, including report-only artifacts, then run `greprag codex chip report <id> --summary "<result>" --check "<check>"`. The report must carry the commit artifact back to the parent.';
21
25
  return `${(0, model_1.chipTitle)(manifest)}
22
26
 
23
27
  Setup — do this FIRST:
24
- ${mechanicSetup}${leaderSetup}- Stay in ${executionPath}; read AGENTS instructions and the session-start recap, then inspect the current repository state.
28
+ ${mechanicSetup}${leaderSetup}- Stay in ${executionPath}. Applicable AGENTS instructions and the session-start recap are already in context; inspect the current repository state.
25
29
  - Bootstrap this checkout before build/test: if \`scripts/ensure-npm-deps.cjs\` exists, run \`node scripts/ensure-npm-deps.cjs\`; if \`scripts/worktree-bootstrap.cjs\` exists, run \`node scripts/worktree-bootstrap.cjs\`. Never link or junction \`node_modules\` to another checkout.
26
- - Do not create a second worktree. This isolated worktree is fully writable; there are no leases, read-only mode, or GrepRAG goal gates.
30
+ - Do not create a second worktree. The selected workspace is fully writable; there are no leases, read-only mode, or GrepRAG goal gates.
27
31
  - The durable manifest is ${manifest.id}; it is task bookkeeping, not a scope or permission gate.
32
+ ${startupInstruction}
28
33
 
29
34
  Task:
30
35
  ${manifest.task}
31
36
  - Own repository discovery, design, implementation, and tests; do not wait for a parent-authored implementation plan.
32
- ${reportInstruction}
33
37
 
34
38
  Report when done:
35
- - In your final response to the parent, include the commit hash, concise result, checks, and caveats.
39
+ ${reportInstruction}
36
40
  - Include a \`Cleanup:\` line naming the archive/task action, worktree action, and branch action. Use \`Cleanup: archive task; Codex may prune managed worktree; parent may delete branch after merge\` when done, or \`Cleanup: keep task/worktree/branch because ...\` when anything must remain open.
37
41
  - Include \`Clearance: safe to archive\` when no follow-up is needed, or \`Clearance: keep open because ...\` when the lead should not archive yet.
38
42
  - Landing: do not independently merge, push, deploy, or delete the worktree — the parent is the delivery owner and integrates the result, follows the repo profile, and cleans up the task. If this task begins \`FIX:\` (a fix-spawn mission), hand the verified checkpoint to that owner without a human approval gate. If no live parent exists and this task carries the full-goal mission, become delivery owner. \`greprag fix spawn\` only prints the mission; visible Codex task dispatch creates the isolated checkout/worktree.`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "greprag",
3
- "version": "5.74.6",
3
+ "version": "5.74.7",
4
4
  "description": "GrepRAG — agent memory for Claude Code, Codex, and OpenCode.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -15,10 +15,13 @@ commit. Preserve the Codex-provided worktree, committed result artifact, and
15
15
  parent cleanup. The child opening prompt starts with the exact visible title
16
16
  alone (`Chip A: <Specific Purview>`, `LEAD: <Mission>`, `PLANNER: <Mission>`,
17
17
  `ADVISOR: <Purview>`, or `FIX: [type] <one friction unit>`) and then carries Block 1
18
- setup, task body, and Block 2 report-back. It has no lease,
19
- read-only, mandatory nested-goal, or nonce/ACK requirement. Completion is the
20
- native Codex parent-child task reply: commit the durable result, then reply to
21
- the LEAD with `DONE` or `BLOCKED`, commit hash if any, checks, caveats, and
18
+ setup, task body, and Block 2 report-back. After setup/bootstrap succeeds, the
19
+ child sends the native parent-task reply
20
+ `IN-FLIGHT: <exact title> setup complete; work started`; setup failure sends
21
+ `BLOCKED` with the exact failure. It has no lease, read-only, mandatory
22
+ nested-goal, or nonce/ACK requirement. Completion is another native
23
+ parent-child task reply: commit the durable result, then reply to the LEAD with
24
+ `DONE` or `BLOCKED`, commit hash if any, checks, caveats, and
22
25
  cleanup parameters (`Cleanup: archive task; Codex may prune managed worktree;
23
26
  parent may delete branch after merge` or `Cleanup: keep task/worktree/branch
24
27
  because ...`) plus archive clearance (`Clearance: safe to archive` or
@@ -4,27 +4,17 @@ Use this for Codex visible child tasks. Claude-side `spawn_task` rules do not
4
4
  apply to Codex: Codex creates the task, selects its workspace, and provides the
5
5
  native parent-child reply channel.
6
6
 
7
- ## What the agent provides
8
-
9
- - `title:` exact first line, one of:
10
- - `Chip A: <Specific Purview>`
11
- - `Chip B: <Specific Purview>`
12
- - `Chip C: <Specific Purview>`
13
- - `LEAD: <Mission>`
14
- - `PLANNER: <Mission>`
15
- - `ADVISOR: <Purview>`
16
- - `FIX: [harness|doctrine|injection|env|code] <one friction unit>`
17
- - `prompt:` Block 1 + task body + Block 2 below.
18
- - `target:` current project. Standard writable chips use
19
- `environment: { "type": "worktree" }`. A FIX chip uses the
20
- `workspaceMode` emitted by `greprag fix spawn`: `worktree` selects a
21
- worktree; `local` selects `environment: { "type": "local" }`.
22
- - `model` / `thinking:` selected from the role slot:
23
- - `Chip A/B/C` -> `chip.worker`
24
- - `LEAD` -> `chip.leader`
25
- - `PLANNER` -> `chip.planner`
26
- - `ADVISOR` -> `chip.advisor`
27
- - `FIX` -> `chip.fix`
7
+ ## Roles and models
8
+
9
+ The exact first-line title selects the governance and model slot:
10
+
11
+ | Title | Purpose | Model slot |
12
+ | --- | --- | --- |
13
+ | `Chip A/B/C: <Specific Purview>` | Independent implementation worker | `chip.worker` |
14
+ | `LEAD: <Mission>` | Own and integrate a multi-chip mission | `chip.leader` |
15
+ | `PLANNER: <Mission>` | Create and brief a separate LEAD | `chip.planner` |
16
+ | `ADVISOR: <Purview>` | Read-only consultation to the LEAD | `chip.advisor` |
17
+ | `FIX: [harness\|doctrine\|injection\|env\|code] <one friction unit>` | Root-cause repair | `chip.fix` |
28
18
 
29
19
  Check active slots with `greprag codex models show`. Pass the selected slot as
30
20
  top-level `model` and `thinking` in `codex_app__create_thread`; do not rely on
@@ -39,14 +29,16 @@ Codex Desktop defaults for a visible chip.
39
29
  - Bounded same-session work: use `greprag load codex-subagent-spawn` instead.
40
30
 
41
31
  A dedicated `LEAD: <Mission>` creates a native top-level goal with
42
- `create_goal`, verifies it with `get_goal`, then fans out children. No leases,
43
- read-only mode, GrepRAG goal gates, nonce ACK, or delivery-proof ceremony.
32
+ `create_goal`, verifies it with `get_goal`, then fans out children. PLANNER is
33
+ a handoff role: after briefing the LEAD it goes quiet until completion,
34
+ blocker, explicit decision request, or operator intervention.
44
35
 
45
36
  ## Workspace selection and project preflight
46
37
 
47
- For a FIX chip, run `greprag fix spawn` in the source project and read its
48
- top-level `workspaceMode`. This is capability detection, not a retry policy:
49
- never attempt a worktree first and fall back after it fails.
38
+ Standard writable chips use the current project with
39
+ `environment: { "type": "worktree" }`. For a FIX chip, run
40
+ `greprag fix spawn` in the source project and honor its top-level
41
+ `workspaceMode` without a fail-then-fallback attempt:
50
42
 
51
43
  - `workspaceMode=worktree`: use the project worktree target. Before the call,
52
44
  check the saved project/main repo for `.codex/environments/environment.toml`.
@@ -54,7 +46,8 @@ never attempt a worktree first and fall back after it fails.
54
46
  skill.
55
47
  - `workspaceMode=local`: use the project local target. The source has no usable
56
48
  Git HEAD, so do not initialize Git, invoke `codex-environments`, or request a
57
- worktree. The caller yields file writes until the FIX chip reports back.
49
+ worktree. This is the project-local task path with serialized writes: the
50
+ caller yields file writes until the FIX chip reports back.
58
51
  - Non-FIX writable chips remain worktree-only.
59
52
  - Missing for `PLANNER` or `ADVISOR` consultation: local/projectless fallback
60
53
  is allowed only when the prompt explicitly forbids writes and no child
@@ -62,58 +55,45 @@ never attempt a worktree first and fall back after it fails.
62
55
 
63
56
  ## Dispatch
64
57
 
65
- Call `codex_app__create_thread` as a standalone tool call. Never batch it with
66
- another spawn or subagent call.
58
+ Call `codex_app__create_thread` once as a standalone tool call:
67
59
 
68
60
  ```json
69
61
  {
70
62
  "target": {
71
63
  "type": "project",
72
64
  "projectId": "<current-project-id>",
73
- "environment": { "type": "worktree" }
65
+ "environment": { "type": "<worktree|local>" }
74
66
  },
75
67
  "prompt": "<Block 1 + Task + Block 2>",
76
- "model": "<selected chip role model>",
77
- "thinking": "<selected chip role effort>"
68
+ "model": "<selected role model>",
69
+ "thinking": "<selected role effort>"
78
70
  }
79
71
  ```
80
72
 
81
- For a FIX handoff with `workspaceMode=local`, change only the environment:
73
+ Creation success proves dispatch, not successful startup. If the result is
74
+ ambiguous, do not retry blindly: use `list_threads` for the expected title,
75
+ inspect candidates with `read_thread`, and retry only after proving no matching
76
+ task exists.
82
77
 
83
- ```json
84
- {
85
- "target": {
86
- "type": "project",
87
- "projectId": "<current-project-id>",
88
- "environment": { "type": "local" }
89
- },
90
- "prompt": "<Block 1 + Task + Block 2>",
91
- "model": "<selected chip role model>",
92
- "thinking": "<selected chip role effort>"
93
- }
94
- ```
95
-
96
- Once `create_thread` reports success, creation is complete. Do not call it
97
- again for the same mission. If it fails generically or the transport is
98
- ambiguous, recover first: `list_threads` for the expected title, then
99
- `read_thread` candidates. Retry only after that proves no matching child exists.
100
-
101
- ## Block 1 - Setup
78
+ ## Block 1 - Setup and startup acknowledgement
102
79
 
103
80
  Paste this at the top of the child prompt after the title.
104
81
 
105
82
  ```text
106
83
  ## Setup - do this FIRST
107
- Honor the selected workspace. Standard chips and `workspaceMode=worktree` FIX
108
- chips stay in the Codex-provided isolated worktree. A `workspaceMode=local` FIX
109
- chip works directly in the project directory, never initializes Git or creates
110
- a worktree, and requires the caller to yield file writes until it reports back.
111
- Read AGENTS.md and the session-start recap, then inspect the current repo state.
84
+ Stay in the selected workspace and inspect the current repository state.
85
+ Applicable AGENTS.md instructions and the session-start recap are already in
86
+ context. Do not create another worktree; a `workspaceMode=local` FIX stays in
87
+ the project directory and never initializes Git.
112
88
  Bootstrap this checkout before build/test: if `scripts/ensure-npm-deps.cjs`
113
89
  exists, run `node scripts/ensure-npm-deps.cjs`; if
114
90
  `scripts/worktree-bootstrap.cjs` exists, run
115
91
  `node scripts/worktree-bootstrap.cjs`. Never link or junction `node_modules` to
116
92
  another checkout.
93
+ After setup and bootstrap succeed, reply to the LEAD in the native Codex task
94
+ thread:
95
+ `IN-FLIGHT: <exact title> — setup complete; work started`
96
+ If setup fails, reply `BLOCKED` with the exact failure instead.
117
97
  If the exact first-line title is `LEAD: <Mission>`, create a native top-level
118
98
  mission goal with `create_goal`, then run `get_goal` and verify the active goal
119
99
  names this mission before any child fanout. Then create the listed
@@ -137,10 +117,11 @@ Keep the actual work dominant:
137
117
 
138
118
  ```text
139
119
  ## Task
140
- Outcome: <desired observable result>
141
- Why: <one sentence; omit if obvious>
142
- Seams: <shared files/contracts/order, or none>
143
- Starting state / integration: <what this worktree starts from and who integrates>
120
+ Outcome: <observable result>
121
+ Problem and evidence: <failure, request, or proof motivating the work>
122
+ Relevant files/contracts: <starting points; child still owns discovery>
123
+ Constraints and prior decisions: <invariants that must survive>
124
+ Seams and integration order: <shared contracts/order, or none>
144
125
  Acceptance: <checks/evidence that mean done>
145
126
  Own repository discovery, design, implementation, tests, and commit; do not
146
127
  wait for a parent-authored implementation plan.
@@ -175,38 +156,27 @@ If review is needed, the parent spawns a fresh review chip/session with an
175
156
  explicit review brief.
176
157
  ```
177
158
 
178
- ## FIX chips
159
+ ## FIX contract
179
160
 
180
161
  For `FIX:` tasks, the mission printed by `greprag fix spawn` is the source of
181
- truth. `fix spawn` detects workspace capability and emits `workspaceMode`:
182
- usable Git history selects an isolated worktree; non-Git, unavailable Git, or
183
- no commit selects the project-local task path with serialized writes. Dispatch
184
- must honor that value without trying a worktree first.
185
-
186
- The FIX chip keeps the existing `FIX:` route and carries its type in the title,
162
+ truth. The FIX chip keeps the existing route and carries its type in the title,
187
163
  for example `FIX: [doctrine] stale skill text sent Codex to Claude rules`.
188
164
  Type means durable repair surface: `harness` hooks/watchers/task dispatch,
189
165
  `doctrine` load entries/skills/rendered instructions, `injection`
190
166
  recap/Capture/doc-pointer/stateful injection, `env` bootstrap/deps/scripts, and
191
- `code` product/source behavior. Repo writes use the selected workspace mode;
192
- data-only repair rows and diagnosis need no writable task. The chip identifies
193
- the exact friction, makes the smallest durable root-cause fix, explains the
194
- friction and fix in human terms, verifies and checkpoints it, then hands the
195
- commit/result to the parent delivery owner without a second human approval
196
- gate. With no live parent and a full-goal mission, it becomes delivery owner
197
- and follows the repo profile.
198
- Removal comes first: remove offending text, gates, controls, duplicated
199
- doctrine, and wrong boundaries before adding new guidance. Add prose or
200
- controls only when no removal action can solve the friction; never wrap bad
201
- doctrine in explanatory caveats when deleting the bad boundary fixes it.
202
- As a child, it does not independently land, archive, or clean up selected
203
- workspace state; the parent delivery owner does that immediately after
204
- integration. The no-live-parent full-goal fallback owns those actions itself.
167
+ `code` product/source behavior. It identifies the exact friction, makes the
168
+ smallest durable root-cause fix, explains why it works, verifies and commits
169
+ it, then hands it to the parent delivery owner.
170
+
171
+ Removal comes first: remove offending doctrine, gates, controls, duplication,
172
+ or wrong boundaries before adding guidance. Add prose or controls only when
173
+ removal cannot solve the friction. Data-only repair rows and diagnosis do not
174
+ require a writable task.
205
175
 
206
176
  ## After spawning
207
177
 
208
- - Never retry `create_thread` blindly; recover with `list_threads` /
209
- `read_thread` first.
178
+ - Wait for the child-confirmed native `IN-FLIGHT` reply; task creation alone
179
+ does not prove setup/bootstrap succeeded.
210
180
  - In `workspaceMode=local`, yield parent file writes until the FIX chip reports
211
181
  back; both tasks share the same project directory.
212
182
  - Use native Codex parent-child task replies for Codex-to-Codex reporting.