greprag 5.64.1 → 5.65.1

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.
Files changed (42) hide show
  1. package/dist/commands/agent-doctrine-file.d.ts +30 -0
  2. package/dist/commands/agent-doctrine-file.js +104 -0
  3. package/dist/commands/agent-doctrine-file.js.map +1 -0
  4. package/dist/commands/agents.d.ts +15 -0
  5. package/dist/commands/agents.js +371 -0
  6. package/dist/commands/agents.js.map +1 -0
  7. package/dist/commands/codex-chip/native.d.ts +5 -0
  8. package/dist/commands/codex-chip/native.js +29 -4
  9. package/dist/commands/codex-chip/native.js.map +1 -1
  10. package/dist/commands/codex-chip/prompt.js +1 -0
  11. package/dist/commands/codex-chip/prompt.js.map +1 -1
  12. package/dist/commands/init.js +40 -3
  13. package/dist/commands/init.js.map +1 -1
  14. package/dist/commands/load.d.ts +2 -0
  15. package/dist/commands/load.js +52 -1
  16. package/dist/commands/load.js.map +1 -1
  17. package/dist/commands/mechanic-spawn.js +2 -1
  18. package/dist/commands/mechanic-spawn.js.map +1 -1
  19. package/dist/commands/opencode-interrupt.d.ts +1 -0
  20. package/dist/commands/opencode-interrupt.js +1 -0
  21. package/dist/commands/opencode-interrupt.js.map +1 -1
  22. package/dist/commands/parity.js +6 -4
  23. package/dist/commands/parity.js.map +1 -1
  24. package/dist/commands/reminder-registry.js +1 -1
  25. package/dist/commands/reminder-registry.js.map +1 -1
  26. package/dist/commands/reminder-types.d.ts +10 -5
  27. package/dist/commands/skill-mirror-reminder.d.ts +9 -13
  28. package/dist/commands/skill-mirror-reminder.js +38 -15
  29. package/dist/commands/skill-mirror-reminder.js.map +1 -1
  30. package/dist/hook.js +10 -4
  31. package/dist/hook.js.map +1 -1
  32. package/dist/index.js +4 -0
  33. package/dist/index.js.map +1 -1
  34. package/dist/opencode-plugin.bundle.js +220 -59
  35. package/dist/opencode-plugin.js +38 -1
  36. package/dist/opencode-plugin.js.map +1 -1
  37. package/dist/skill-activation-manifest.d.ts +37 -0
  38. package/dist/skill-activation-manifest.js +154 -0
  39. package/dist/skill-activation-manifest.js.map +1 -0
  40. package/package.json +1 -1
  41. package/skill/greprag/docs/codex-chip.md +3 -0
  42. package/skill/templates/codex-chip-spawn.md +18 -0
@@ -0,0 +1,30 @@
1
+ /** Pure managed-follower block helpers for canonical agent doctrine. */
2
+ export interface DoctrineFollowerRender {
3
+ scopeKey: string;
4
+ harness: 'claude-code' | 'codex' | 'opencode';
5
+ revision: number;
6
+ body: string;
7
+ }
8
+ export type DoctrineFollowerOutcome = {
9
+ action: 'current';
10
+ content: string;
11
+ renderHash: string;
12
+ } | {
13
+ action: 'seed' | 'update' | 'adopt';
14
+ content: string;
15
+ renderHash: string;
16
+ } | {
17
+ action: 'diverged' | 'unmanaged';
18
+ content: string;
19
+ reason: string;
20
+ renderHash: string;
21
+ };
22
+ export declare function doctrineRenderHash(value: string): string;
23
+ export declare function renderDoctrineFollowerBlock(render: DoctrineFollowerRender): string;
24
+ /** Patch a generated follower without clobbering unadopted or hand-edited text.
25
+ * A prior generated block is replaceable only while its actual body still
26
+ * matches the hash declared in its own header. */
27
+ export declare function patchDoctrineFollower(source: string, render: DoctrineFollowerRender, options?: {
28
+ force?: boolean;
29
+ adoptWholeFile?: boolean;
30
+ }): DoctrineFollowerOutcome;
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ /** Pure managed-follower block helpers for canonical agent doctrine. */
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.doctrineRenderHash = doctrineRenderHash;
38
+ exports.renderDoctrineFollowerBlock = renderDoctrineFollowerBlock;
39
+ exports.patchDoctrineFollower = patchDoctrineFollower;
40
+ const crypto = __importStar(require("node:crypto"));
41
+ function normalizedBody(value) {
42
+ return value.replace(/\r\n/g, '\n').trim();
43
+ }
44
+ function doctrineRenderHash(value) {
45
+ return crypto.createHash('sha256').update(normalizedBody(value)).digest('hex');
46
+ }
47
+ function renderDoctrineFollowerBlock(render) {
48
+ const body = normalizedBody(render.body);
49
+ const hash = doctrineRenderHash(body);
50
+ return `<!-- greprag:agents:start scope=${render.scopeKey} harness=${render.harness} revision=${render.revision} hash=${hash} -->\n`
51
+ + `${body}\n<!-- greprag:agents:end -->`;
52
+ }
53
+ function findBlock(source) {
54
+ const pattern = /<!--\s*greprag:agents:start\s+scope=\S+\s+harness=\S+\s+revision=(\d+)\s+hash=([a-f0-9]{64})\s*-->\r?\n?([\s\S]*?)\r?\n?<!--\s*greprag:agents:end\s*-->/i;
55
+ const match = source.match(pattern);
56
+ return match ? {
57
+ whole: match[0],
58
+ revision: Number(match[1]),
59
+ declaredHash: match[2].toLowerCase(),
60
+ inner: match[3],
61
+ } : null;
62
+ }
63
+ /** Patch a generated follower without clobbering unadopted or hand-edited text.
64
+ * A prior generated block is replaceable only while its actual body still
65
+ * matches the hash declared in its own header. */
66
+ function patchDoctrineFollower(source, render, options = {}) {
67
+ const block = renderDoctrineFollowerBlock(render);
68
+ const renderHash = doctrineRenderHash(render.body);
69
+ const existing = findBlock(source);
70
+ if (!existing) {
71
+ if (!source.trim()) {
72
+ return { action: 'seed', content: block + '\n', renderHash };
73
+ }
74
+ if (options.force || options.adoptWholeFile) {
75
+ return { action: 'adopt', content: block + '\n', renderHash };
76
+ }
77
+ return {
78
+ action: 'unmanaged',
79
+ content: source,
80
+ renderHash,
81
+ reason: 'file has unmanaged content; explicitly adopt it or use --force',
82
+ };
83
+ }
84
+ const actualHash = doctrineRenderHash(existing.inner);
85
+ if (!options.force && actualHash !== existing.declaredHash) {
86
+ return {
87
+ action: 'diverged',
88
+ content: source,
89
+ renderHash,
90
+ reason: 'managed follower was edited after its last canonical render',
91
+ };
92
+ }
93
+ if (existing.revision === render.revision
94
+ && actualHash === renderHash
95
+ && existing.declaredHash === renderHash) {
96
+ return { action: 'current', content: source, renderHash };
97
+ }
98
+ return {
99
+ action: 'update',
100
+ content: source.replace(existing.whole, block),
101
+ renderHash,
102
+ };
103
+ }
104
+ //# sourceMappingURL=agent-doctrine-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-doctrine-file.js","sourceRoot":"","sources":["../../src/commands/agent-doctrine-file.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /** `greprag agents` — canonical agent-doctrine adoption and materialization. */
2
+ type Harness = 'claude-code' | 'codex' | 'opencode';
3
+ type Scope = 'global' | 'repo';
4
+ export interface AgentDoctrineBootstrapResult {
5
+ canonicalScopes: Scope[];
6
+ currentFollowers: number;
7
+ changedFollowers: number;
8
+ blockedFollowers: number;
9
+ }
10
+ /** Init-time seed for the active harness. No canon is a clean no-op; only a
11
+ * missing/empty follower is written. Every existing file, including a stale
12
+ * managed follower, requires an explicit `agents sync`. */
13
+ export declare function bootstrapAgentDoctrine(apiKey: string, harness: Harness): Promise<AgentDoctrineBootstrapResult>;
14
+ export declare function runAgents(args: string[]): Promise<void>;
15
+ export {};
@@ -0,0 +1,371 @@
1
+ "use strict";
2
+ /** `greprag agents` — canonical agent-doctrine adoption and materialization. */
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.bootstrapAgentDoctrine = bootstrapAgentDoctrine;
38
+ exports.runAgents = runAgents;
39
+ const crypto = __importStar(require("node:crypto"));
40
+ const fs = __importStar(require("node:fs"));
41
+ const os = __importStar(require("node:os"));
42
+ const path = __importStar(require("node:path"));
43
+ const project_anchor_1 = require("../project-anchor");
44
+ const proc_1 = require("../proc");
45
+ const agent_doctrine_file_1 = require("./agent-doctrine-file");
46
+ const HELP = `greprag agents — canonical CLAUDE.md / AGENTS.md doctrine
47
+
48
+ USAGE
49
+ greprag agents adopt <file> [--scope global|repo] [--harness <name>] [--raw] [--no-sync]
50
+ greprag agents optimize [--from <file>] [--scope global|repo] [--harness <name>] [--no-sync]
51
+ greprag agents sync [--scope global|repo|all] [--check] [--force]
52
+ greprag agents status [--scope global|repo|all]
53
+
54
+ MODEL
55
+ Adoption is bidirectional once. After adoption, load://agents is canonical
56
+ and instruction files are generated followers. Direct follower edits become
57
+ drift candidates; use optimize --from, inspect with load agents, then sync.
58
+ --no-sync advances canon without writing followers; use it as the preview gate.`;
59
+ function config(apiKeyOverride) {
60
+ return {
61
+ apiUrl: process.env.GREPRAG_API_URL || 'https://api.greprag.com',
62
+ apiKey: apiKeyOverride || process.env.GREPRAG_API_KEY || '',
63
+ };
64
+ }
65
+ function flag(args, name) {
66
+ const index = args.indexOf(name);
67
+ return index >= 0 ? args[index + 1] : undefined;
68
+ }
69
+ function repoRoot(cwd = process.cwd()) {
70
+ try {
71
+ return String((0, proc_1.safeExecSync)('git rev-parse --show-toplevel', {
72
+ cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'],
73
+ })).trim();
74
+ }
75
+ catch {
76
+ return path.resolve(cwd);
77
+ }
78
+ }
79
+ function relativeDirectory(root, requested) {
80
+ const absolute = requested
81
+ ? path.resolve(root, requested)
82
+ : path.resolve(process.cwd());
83
+ const relative = path.relative(root, absolute).replace(/\\/g, '/') || '.';
84
+ if (relative === '..' || relative.startsWith('../')) {
85
+ throw new Error('doctrine directory must be inside the current repo');
86
+ }
87
+ return relative;
88
+ }
89
+ function globalTargets() {
90
+ const home = os.homedir();
91
+ return [
92
+ {
93
+ harness: 'claude-code',
94
+ actualPath: path.join(home, '.claude', 'CLAUDE.md'),
95
+ manifestPath: '~/.claude/CLAUDE.md',
96
+ },
97
+ {
98
+ harness: 'codex',
99
+ actualPath: path.join(home, '.codex', 'AGENTS.md'),
100
+ manifestPath: '~/.codex/AGENTS.md',
101
+ },
102
+ {
103
+ harness: 'opencode',
104
+ actualPath: path.join(home, '.config', 'opencode', 'AGENTS.md'),
105
+ manifestPath: '~/.config/opencode/AGENTS.md',
106
+ },
107
+ ];
108
+ }
109
+ function repoTargets(root, directory) {
110
+ const base = directory === '.' ? root : path.join(root, ...directory.split('/'));
111
+ return [
112
+ {
113
+ harness: 'claude-code',
114
+ actualPath: path.join(base, 'CLAUDE.md'),
115
+ manifestPath: path.join(base, 'CLAUDE.md'),
116
+ },
117
+ {
118
+ harness: 'codex',
119
+ actualPath: path.join(base, 'AGENTS.md'),
120
+ manifestPath: path.join(base, 'AGENTS.md'),
121
+ note: 'shared AGENTS.md follower consumed by Codex and OpenCode',
122
+ combinedAgents: true,
123
+ },
124
+ ];
125
+ }
126
+ function parityUnitName(scope, projectId, directory) {
127
+ if (scope === 'global')
128
+ return 'agent-doctrine-global';
129
+ if (!projectId)
130
+ throw new Error('projectId required for repo doctrine');
131
+ const suffix = directory === '.'
132
+ ? 'root'
133
+ : crypto.createHash('sha256').update(directory).digest('hex').slice(0, 8);
134
+ return `agent-doctrine-${projectId.slice(0, 8)}-${suffix}`;
135
+ }
136
+ function renderSection(title, value) {
137
+ return value.trim() ? `## ${title}\n\n${value.trim()}` : '';
138
+ }
139
+ function renderForTarget(doc, target) {
140
+ const parts = [doc.shared.trim()];
141
+ if (target.combinedAgents) {
142
+ parts.push(renderSection('Codex Overlay', doc.overlays.codex));
143
+ parts.push(renderSection('OpenCode Overlay', doc.overlays.opencode));
144
+ }
145
+ else {
146
+ parts.push(renderSection(`${target.harness} Overlay`, doc.overlays[target.harness]));
147
+ }
148
+ return parts.filter(Boolean).join('\n\n').trim() + '\n';
149
+ }
150
+ async function apiJson(pathname, init, apiKeyOverride) {
151
+ const cfg = config(apiKeyOverride);
152
+ if (!cfg.apiKey)
153
+ throw new Error('GREPRAG_API_KEY not set — run `greprag init` first.');
154
+ const response = await fetch(`${cfg.apiUrl}${pathname}`, {
155
+ ...init,
156
+ headers: {
157
+ 'Authorization': `Bearer ${cfg.apiKey}`,
158
+ ...(init?.body ? { 'Content-Type': 'application/json' } : {}),
159
+ ...(init?.headers || {}),
160
+ },
161
+ });
162
+ const body = await response.json().catch(() => ({}));
163
+ if (!response.ok)
164
+ throw new Error(body.error || `HTTP ${response.status}`);
165
+ return body;
166
+ }
167
+ function context(scope, args) {
168
+ const root = repoRoot();
169
+ if (scope === 'global') {
170
+ return { projectId: null, directory: '.', root, targets: globalTargets() };
171
+ }
172
+ const anchor = (0, project_anchor_1.readAnchor)(root);
173
+ const directory = relativeDirectory(root, flag(args, '--directory'));
174
+ return {
175
+ projectId: anchor.projectId,
176
+ directory,
177
+ root,
178
+ targets: repoTargets(root, directory),
179
+ };
180
+ }
181
+ async function fetchDocument(scope, projectId, directory, apiKey) {
182
+ const params = new URLSearchParams({ scope, directory, harness: 'all' });
183
+ if (projectId)
184
+ params.set('projectId', projectId);
185
+ try {
186
+ const body = await apiJson(`/v1/agents?${params.toString()}`, undefined, apiKey);
187
+ return body.documents[0] || null;
188
+ }
189
+ catch (error) {
190
+ if (error instanceof Error && /not found/.test(error.message))
191
+ return null;
192
+ throw error;
193
+ }
194
+ }
195
+ function inferHarness(file, explicit) {
196
+ if (explicit === 'claude-code' || explicit === 'codex' || explicit === 'opencode')
197
+ return explicit;
198
+ return file && path.basename(file).toUpperCase() === 'CLAUDE.MD' ? 'claude-code' : 'codex';
199
+ }
200
+ function inferScope(file, explicit) {
201
+ if (explicit === 'global' || explicit === 'repo')
202
+ return explicit;
203
+ if (file) {
204
+ const absolute = path.resolve(file).toLowerCase();
205
+ if (globalTargets().some((target) => target.actualPath.toLowerCase() === absolute))
206
+ return 'global';
207
+ }
208
+ return 'repo';
209
+ }
210
+ async function reportSync(unitName, target, revision, renderHash, apiKey) {
211
+ await apiJson('/v1/agents/sync', {
212
+ method: 'POST',
213
+ body: JSON.stringify({
214
+ unitName,
215
+ harness: target.harness,
216
+ path: target.manifestPath,
217
+ revision,
218
+ renderHash,
219
+ }),
220
+ }, apiKey);
221
+ }
222
+ function targetMatchesHarness(target, harness) {
223
+ if (!harness || target.harness === harness)
224
+ return true;
225
+ return harness === 'opencode' && target.combinedAgents === true;
226
+ }
227
+ async function syncOne(params) {
228
+ const ctx = context(params.scope, params.args);
229
+ const doc = await fetchDocument(params.scope, ctx.projectId, ctx.directory, params.apiKey);
230
+ if (!doc) {
231
+ if (!params.quiet)
232
+ console.log(`${params.scope}: no canonical doctrine`);
233
+ return { canonical: false, current: 0, changed: 0, blocked: 0, drift: 0 };
234
+ }
235
+ const unitName = parityUnitName(params.scope, ctx.projectId, ctx.directory);
236
+ const stats = { canonical: true, current: 0, changed: 0, blocked: 0, drift: 0 };
237
+ for (const target of ctx.targets.filter(t => targetMatchesHarness(t, params.harness))) {
238
+ const source = fs.existsSync(target.actualPath)
239
+ ? fs.readFileSync(target.actualPath, 'utf8')
240
+ : '';
241
+ const adopting = !!params.adoptSourcePath
242
+ && path.resolve(params.adoptSourcePath).toLowerCase() === path.resolve(target.actualPath).toLowerCase();
243
+ const outcome = (0, agent_doctrine_file_1.patchDoctrineFollower)(source, {
244
+ scopeKey: doc.scopeKey,
245
+ harness: target.harness,
246
+ revision: doc.revision,
247
+ body: renderForTarget(doc, target),
248
+ }, { force: params.force, adoptWholeFile: adopting });
249
+ const current = outcome.action === 'current';
250
+ if (current)
251
+ stats.current++;
252
+ else
253
+ stats.drift++;
254
+ const detail = 'reason' in outcome ? ` — ${outcome.reason}` : '';
255
+ if (!params.quiet) {
256
+ console.log(` ${current ? 'fresh' : outcome.action.padEnd(9)} ${target.actualPath}${detail}`);
257
+ }
258
+ const seedOnlyBlocked = params.seedOnly && !current && outcome.action !== 'seed';
259
+ if (outcome.action === 'diverged' || outcome.action === 'unmanaged' || seedOnlyBlocked) {
260
+ stats.blocked++;
261
+ continue;
262
+ }
263
+ if (params.check || current)
264
+ continue;
265
+ fs.mkdirSync(path.dirname(target.actualPath), { recursive: true });
266
+ fs.writeFileSync(target.actualPath, outcome.content, 'utf8');
267
+ await reportSync(unitName, target, doc.revision, outcome.renderHash, params.apiKey);
268
+ stats.changed++;
269
+ }
270
+ return stats;
271
+ }
272
+ async function writeCommand(args, adopt) {
273
+ const positional = adopt && args[0] && !args[0].startsWith('-') ? args[0] : undefined;
274
+ const from = flag(args, '--from') || positional;
275
+ if (adopt && !from)
276
+ throw new Error('adopt requires a source file');
277
+ const sourcePath = from ? path.resolve(from) : undefined;
278
+ if (sourcePath && !fs.existsSync(sourcePath))
279
+ throw new Error(`source file not found: ${sourcePath}`);
280
+ const scope = inferScope(sourcePath, flag(args, '--scope'));
281
+ let harness = inferHarness(sourcePath, flag(args, '--harness'));
282
+ const ctx = context(scope, args);
283
+ const current = adopt ? null : await fetchDocument(scope, ctx.projectId, ctx.directory);
284
+ if (!sourcePath && current && !flag(args, '--harness'))
285
+ harness = current.sourceHarness;
286
+ const body = await apiJson(`/v1/agents/${adopt ? 'adopt' : 'optimize'}`, {
287
+ method: 'POST',
288
+ body: JSON.stringify({
289
+ scope,
290
+ projectId: ctx.projectId,
291
+ directory: ctx.directory,
292
+ sourceHarness: harness,
293
+ sourcePath: sourcePath || null,
294
+ ...(sourcePath ? { content: fs.readFileSync(sourcePath, 'utf8') } : {}),
295
+ optimize: !args.includes('--raw'),
296
+ expectedRevision: current?.revision ?? null,
297
+ followers: ctx.targets.map((target) => ({
298
+ harness: target.harness,
299
+ path: target.manifestPath,
300
+ note: target.note,
301
+ })),
302
+ }),
303
+ });
304
+ console.log(`${adopt ? 'Adopted' : 'Optimized'} ${body.document.scopeKey} revision ${body.document.revision}.`);
305
+ if (!args.includes('--no-sync')) {
306
+ await syncOne({
307
+ scope,
308
+ args,
309
+ check: false,
310
+ force: args.includes('--force'),
311
+ adoptSourcePath: adopt ? sourcePath : undefined,
312
+ });
313
+ }
314
+ }
315
+ async function syncCommand(args, checkOverride = false) {
316
+ const requested = flag(args, '--scope') || 'all';
317
+ if (!['global', 'repo', 'all'].includes(requested)) {
318
+ throw new Error('--scope must be global|repo|all');
319
+ }
320
+ const scopes = requested === 'all' ? ['global', 'repo'] : [requested];
321
+ const check = checkOverride || args.includes('--check');
322
+ let drift = 0;
323
+ for (const scope of scopes) {
324
+ console.log(`${scope}:`);
325
+ const stats = await syncOne({ scope, args, check, force: args.includes('--force') });
326
+ drift += stats.drift;
327
+ }
328
+ if (check && drift > 0) {
329
+ console.error(`${drift} follower(s) need sync or reconciliation.`);
330
+ process.exitCode = 1;
331
+ }
332
+ else if (check) {
333
+ console.log('All materialized followers are current.');
334
+ }
335
+ }
336
+ /** Init-time seed for the active harness. No canon is a clean no-op; only a
337
+ * missing/empty follower is written. Every existing file, including a stale
338
+ * managed follower, requires an explicit `agents sync`. */
339
+ async function bootstrapAgentDoctrine(apiKey, harness) {
340
+ const result = {
341
+ canonicalScopes: [], currentFollowers: 0, changedFollowers: 0, blockedFollowers: 0,
342
+ };
343
+ for (const scope of ['global', 'repo']) {
344
+ const stats = await syncOne({
345
+ scope, args: [], check: false, force: false, apiKey, harness, quiet: true, seedOnly: true,
346
+ });
347
+ if (stats.canonical)
348
+ result.canonicalScopes.push(scope);
349
+ result.currentFollowers += stats.current;
350
+ result.changedFollowers += stats.changed;
351
+ result.blockedFollowers += stats.blocked;
352
+ }
353
+ return result;
354
+ }
355
+ async function runAgents(args) {
356
+ const sub = args[0];
357
+ if (!sub || sub === 'help' || sub === '--help' || sub === '-h') {
358
+ console.log(HELP);
359
+ return;
360
+ }
361
+ if (sub === 'adopt')
362
+ return writeCommand(args.slice(1), true);
363
+ if (sub === 'optimize')
364
+ return writeCommand(args.slice(1), false);
365
+ if (sub === 'sync')
366
+ return syncCommand(args.slice(1));
367
+ if (sub === 'status')
368
+ return syncCommand(args.slice(1), true);
369
+ throw new Error(`unknown agents command: ${sub}`);
370
+ }
371
+ //# sourceMappingURL=agents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/commands/agents.ts"],"names":[],"mappings":"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"}
@@ -28,6 +28,11 @@ export interface NativeChipHandoff {
28
28
  retryDelayMs: 750;
29
29
  settleBeforeRename?: true;
30
30
  };
31
+ createRecovery?: {
32
+ failureClass: string;
33
+ beforeRetry: readonly string[];
34
+ recoveredClientThreadId: string;
35
+ };
31
36
  dispatchSequence: readonly string[];
32
37
  verifyTitleCommand?: string;
33
38
  attachCommand?: string;
@@ -61,6 +61,18 @@ function expectedNativeTitle(manifest) {
61
61
  function fallbackNativeModel() {
62
62
  return (0, codex_model_policy_1.resolveChipModelSlot)('worker').model;
63
63
  }
64
+ function ambiguousCreateRecovery(title, chipId) {
65
+ return {
66
+ failureClass: 'generic or transport create_thread failure after a visible task may have been created',
67
+ recoveredClientThreadId: 'recovered-create-thread:<threadId>',
68
+ beforeRetry: [
69
+ `Treat the failure as ambiguous success. Do not call create_thread again until recovery checks prove no existing ${title} task exists.`,
70
+ `Run list_threads with query ${JSON.stringify(title)} or ${chipId.slice(0, 8)}, then read_thread each candidate.`,
71
+ `Recover only if exactly one candidate contains durable manifest ${chipId} or the exact expected title; then continue title verification on that thread.`,
72
+ 'For recovered tasks where no clientThreadId was returned, pass --client-thread recovered-create-thread:<threadId> to verifyTitleCommand.',
73
+ ],
74
+ };
75
+ }
64
76
  /** Parent-side Desktop adapter primitive. Set early, then correct the observed
65
77
  * auto-title race with two consecutive read-backs. */
66
78
  async function verifyDesktopTitle(expected, surface, maxAttempts = 3) {
@@ -126,6 +138,7 @@ function nativeHandoff(manifest) {
126
138
  model: manifest.codex.model || fallbackNativeModel(),
127
139
  thinking: (0, selection_1.resolveDesktopThinking)(manifest.codex.effort),
128
140
  },
141
+ createRecovery: ambiguousCreateRecovery(title, manifest.id),
129
142
  titleVerification: {
130
143
  maxAttempts: 3, exactTitle: title, consecutiveReadBacks: 2, retryDelayMs: 750,
131
144
  },
@@ -142,6 +155,7 @@ function nativeHandoff(manifest) {
142
155
  'Rerun this handoff after attach only to inspect state; never replay the mission.',
143
156
  ] : [
144
157
  'Call create_thread with createRequest exactly. It contains the real mission, model, thinking, and native worktree; this is the only mission turn.',
158
+ 'If create_thread returns a generic/transport failure, treat it as ambiguous success: run createRecovery.beforeRetry and recover a matching visible task before any retry.',
145
159
  'The UserPromptSubmit chip hook provisionally binds the task/cwd before tool use while setup continues.',
146
160
  'Resolve threadId and native cwd immediately. Call set_thread_title as soon as the thread appears, then read it back twice; retry only if auto-title overwrites it.',
147
161
  'Only after read_thread returns the exact title, run verifyTitleCommand. Fail loudly if the title is not durable.',
@@ -232,13 +246,21 @@ function verifyNativeBinding(manifest, params) {
232
246
  const idPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
233
247
  const clientMatch = /^(?:client-new-thread:)?([0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})$/i
234
248
  .exec(params.clientThreadId);
235
- if (!clientMatch || !idPattern.test(params.threadId)) {
236
- throw new Error('Attach requires the Codex-issued clientThreadId token and resolved threadId UUID.');
249
+ const recoveredClientMatch = /^recovered-create-thread:([0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})$/i
250
+ .exec(params.clientThreadId);
251
+ const clientToken = clientMatch?.[1] || recoveredClientMatch?.[1];
252
+ if (!clientToken || !idPattern.test(params.threadId)) {
253
+ throw new Error('Attach requires the Codex-issued clientThreadId token, or recovered-create-thread:<threadId>, and resolved threadId UUID.');
237
254
  }
238
- if (clientMatch[1].toLowerCase() === params.threadId.toLowerCase() ||
239
- params.threadId.toLowerCase() === manifest.parent.sessionId?.toLowerCase()) {
255
+ if (params.threadId.toLowerCase() === manifest.parent.sessionId?.toLowerCase()) {
240
256
  throw new Error('Native binding must identify a distinct resolved child task.');
241
257
  }
258
+ if (recoveredClientMatch && clientToken.toLowerCase() !== params.threadId.toLowerCase()) {
259
+ throw new Error('Recovered create_thread binding must name the same resolved child task as --thread.');
260
+ }
261
+ if (!recoveredClientMatch && clientToken.toLowerCase() === params.threadId.toLowerCase()) {
262
+ throw new Error('Native binding must identify a distinct client token and resolved child task.');
263
+ }
242
264
  const expectedTitle = expectedNativeTitle(manifest);
243
265
  if (params.title !== expectedTitle)
244
266
  throw new Error(`Native title was not durably verified as ${expectedTitle}.`);
@@ -251,6 +273,9 @@ function verifyNativeBinding(manifest, params) {
251
273
  !manifest.codex.threadId || !manifest.codex.nativeCwd)) {
252
274
  throw new Error('Native v4 title verification requires the initial mission hook to provisionally bind the task first.');
253
275
  }
276
+ if (recoveredClientMatch && manifest.version < 2) {
277
+ throw new Error('Recovered create_thread binding is only supported for native v4 mission tasks.');
278
+ }
254
279
  if (params.projectId !== manifest.codex.projectId || params.baseSha !== manifest.parent.baseSha) {
255
280
  throw new Error('Native project/base attestation does not match the prepared task.');
256
281
  }