greprag 5.64.0 → 5.65.0
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/dist/commands/agent-doctrine-file.d.ts +30 -0
- package/dist/commands/agent-doctrine-file.js +104 -0
- package/dist/commands/agent-doctrine-file.js.map +1 -0
- package/dist/commands/agents.d.ts +15 -0
- package/dist/commands/agents.js +370 -0
- package/dist/commands/agents.js.map +1 -0
- package/dist/commands/codex-chip/native.d.ts +5 -0
- package/dist/commands/codex-chip/native.js +29 -4
- package/dist/commands/codex-chip/native.js.map +1 -1
- package/dist/commands/codex-chip/prompt.js +1 -0
- package/dist/commands/codex-chip/prompt.js.map +1 -1
- package/dist/commands/codex.js +1 -1
- package/dist/commands/codex.js.map +1 -1
- package/dist/commands/fix.d.ts +9 -9
- package/dist/commands/fix.js +18 -19
- package/dist/commands/fix.js.map +1 -1
- package/dist/commands/inbox-drain.js +1 -1
- package/dist/commands/inbox-drain.js.map +1 -1
- package/dist/commands/inbox-watch.js +1 -1
- package/dist/commands/inbox-watch.js.map +1 -1
- package/dist/commands/init.js +40 -3
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/load.d.ts +2 -0
- package/dist/commands/load.js +52 -1
- package/dist/commands/load.js.map +1 -1
- package/dist/commands/mechanic-live.js +6 -12
- package/dist/commands/mechanic-live.js.map +1 -1
- package/dist/commands/mechanic-spawn.js +3 -2
- package/dist/commands/mechanic-spawn.js.map +1 -1
- package/dist/commands/mechanic.js +4 -5
- package/dist/commands/mechanic.js.map +1 -1
- package/dist/commands/opencode-interrupt.d.ts +1 -0
- package/dist/commands/opencode-interrupt.js +1 -0
- package/dist/commands/opencode-interrupt.js.map +1 -1
- package/dist/commands/opencode-relay.js +1 -1
- package/dist/commands/opencode-relay.js.map +1 -1
- package/dist/commands/parity.js +6 -4
- package/dist/commands/parity.js.map +1 -1
- package/dist/commands/reminder-registry.js +1 -1
- package/dist/commands/reminder-registry.js.map +1 -1
- package/dist/commands/reminder-types.d.ts +10 -5
- package/dist/commands/skill-mirror-reminder.d.ts +9 -13
- package/dist/commands/skill-mirror-reminder.js +38 -15
- package/dist/commands/skill-mirror-reminder.js.map +1 -1
- package/dist/hook.js +18 -34
- package/dist/hook.js.map +1 -1
- package/dist/index.js +10 -5
- package/dist/index.js.map +1 -1
- package/dist/mechanic-friction.d.ts +0 -17
- package/dist/mechanic-friction.js +10 -76
- package/dist/mechanic-friction.js.map +1 -1
- package/dist/opencode-plugin.bundle.js +220 -59
- package/dist/opencode-plugin.js +38 -1
- package/dist/opencode-plugin.js.map +1 -1
- package/dist/skill-activation-manifest.d.ts +37 -0
- package/dist/skill-activation-manifest.js +154 -0
- package/dist/skill-activation-manifest.js.map +1 -0
- package/package.json +1 -1
- package/skill/greprag/docs/codex-chip.md +3 -0
- package/skill/mechanic/SKILL.md +24 -25
- package/skill/mechanic/docs/skill-fix-conventions.md +2 -2
- 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,370 @@
|
|
|
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]
|
|
50
|
+
greprag agents optimize [--from <file>] [--scope global|repo] [--harness <name>]
|
|
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, then sync.`;
|
|
58
|
+
function config(apiKeyOverride) {
|
|
59
|
+
return {
|
|
60
|
+
apiUrl: process.env.GREPRAG_API_URL || 'https://api.greprag.com',
|
|
61
|
+
apiKey: apiKeyOverride || process.env.GREPRAG_API_KEY || '',
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function flag(args, name) {
|
|
65
|
+
const index = args.indexOf(name);
|
|
66
|
+
return index >= 0 ? args[index + 1] : undefined;
|
|
67
|
+
}
|
|
68
|
+
function repoRoot(cwd = process.cwd()) {
|
|
69
|
+
try {
|
|
70
|
+
return String((0, proc_1.safeExecSync)('git rev-parse --show-toplevel', {
|
|
71
|
+
cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'],
|
|
72
|
+
})).trim();
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return path.resolve(cwd);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function relativeDirectory(root, requested) {
|
|
79
|
+
const absolute = requested
|
|
80
|
+
? path.resolve(root, requested)
|
|
81
|
+
: path.resolve(process.cwd());
|
|
82
|
+
const relative = path.relative(root, absolute).replace(/\\/g, '/') || '.';
|
|
83
|
+
if (relative === '..' || relative.startsWith('../')) {
|
|
84
|
+
throw new Error('doctrine directory must be inside the current repo');
|
|
85
|
+
}
|
|
86
|
+
return relative;
|
|
87
|
+
}
|
|
88
|
+
function globalTargets() {
|
|
89
|
+
const home = os.homedir();
|
|
90
|
+
return [
|
|
91
|
+
{
|
|
92
|
+
harness: 'claude-code',
|
|
93
|
+
actualPath: path.join(home, '.claude', 'CLAUDE.md'),
|
|
94
|
+
manifestPath: '~/.claude/CLAUDE.md',
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
harness: 'codex',
|
|
98
|
+
actualPath: path.join(home, '.codex', 'AGENTS.md'),
|
|
99
|
+
manifestPath: '~/.codex/AGENTS.md',
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
harness: 'opencode',
|
|
103
|
+
actualPath: path.join(home, '.config', 'opencode', 'AGENTS.md'),
|
|
104
|
+
manifestPath: '~/.config/opencode/AGENTS.md',
|
|
105
|
+
},
|
|
106
|
+
];
|
|
107
|
+
}
|
|
108
|
+
function repoTargets(root, directory) {
|
|
109
|
+
const base = directory === '.' ? root : path.join(root, ...directory.split('/'));
|
|
110
|
+
return [
|
|
111
|
+
{
|
|
112
|
+
harness: 'claude-code',
|
|
113
|
+
actualPath: path.join(base, 'CLAUDE.md'),
|
|
114
|
+
manifestPath: path.join(base, 'CLAUDE.md'),
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
harness: 'codex',
|
|
118
|
+
actualPath: path.join(base, 'AGENTS.md'),
|
|
119
|
+
manifestPath: path.join(base, 'AGENTS.md'),
|
|
120
|
+
note: 'shared AGENTS.md follower consumed by Codex and OpenCode',
|
|
121
|
+
combinedAgents: true,
|
|
122
|
+
},
|
|
123
|
+
];
|
|
124
|
+
}
|
|
125
|
+
function parityUnitName(scope, projectId, directory) {
|
|
126
|
+
if (scope === 'global')
|
|
127
|
+
return 'agent-doctrine-global';
|
|
128
|
+
if (!projectId)
|
|
129
|
+
throw new Error('projectId required for repo doctrine');
|
|
130
|
+
const suffix = directory === '.'
|
|
131
|
+
? 'root'
|
|
132
|
+
: crypto.createHash('sha256').update(directory).digest('hex').slice(0, 8);
|
|
133
|
+
return `agent-doctrine-${projectId.slice(0, 8)}-${suffix}`;
|
|
134
|
+
}
|
|
135
|
+
function renderSection(title, value) {
|
|
136
|
+
return value.trim() ? `## ${title}\n\n${value.trim()}` : '';
|
|
137
|
+
}
|
|
138
|
+
function renderForTarget(doc, target) {
|
|
139
|
+
const parts = [doc.shared.trim()];
|
|
140
|
+
if (target.combinedAgents) {
|
|
141
|
+
parts.push(renderSection('Codex Overlay', doc.overlays.codex));
|
|
142
|
+
parts.push(renderSection('OpenCode Overlay', doc.overlays.opencode));
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
parts.push(renderSection(`${target.harness} Overlay`, doc.overlays[target.harness]));
|
|
146
|
+
}
|
|
147
|
+
return parts.filter(Boolean).join('\n\n').trim() + '\n';
|
|
148
|
+
}
|
|
149
|
+
async function apiJson(pathname, init, apiKeyOverride) {
|
|
150
|
+
const cfg = config(apiKeyOverride);
|
|
151
|
+
if (!cfg.apiKey)
|
|
152
|
+
throw new Error('GREPRAG_API_KEY not set — run `greprag init` first.');
|
|
153
|
+
const response = await fetch(`${cfg.apiUrl}${pathname}`, {
|
|
154
|
+
...init,
|
|
155
|
+
headers: {
|
|
156
|
+
'Authorization': `Bearer ${cfg.apiKey}`,
|
|
157
|
+
...(init?.body ? { 'Content-Type': 'application/json' } : {}),
|
|
158
|
+
...(init?.headers || {}),
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
const body = await response.json().catch(() => ({}));
|
|
162
|
+
if (!response.ok)
|
|
163
|
+
throw new Error(body.error || `HTTP ${response.status}`);
|
|
164
|
+
return body;
|
|
165
|
+
}
|
|
166
|
+
function context(scope, args) {
|
|
167
|
+
const root = repoRoot();
|
|
168
|
+
if (scope === 'global') {
|
|
169
|
+
return { projectId: null, directory: '.', root, targets: globalTargets() };
|
|
170
|
+
}
|
|
171
|
+
const anchor = (0, project_anchor_1.readAnchor)(root);
|
|
172
|
+
const directory = relativeDirectory(root, flag(args, '--directory'));
|
|
173
|
+
return {
|
|
174
|
+
projectId: anchor.projectId,
|
|
175
|
+
directory,
|
|
176
|
+
root,
|
|
177
|
+
targets: repoTargets(root, directory),
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
async function fetchDocument(scope, projectId, directory, apiKey) {
|
|
181
|
+
const params = new URLSearchParams({ scope, directory, harness: 'all' });
|
|
182
|
+
if (projectId)
|
|
183
|
+
params.set('projectId', projectId);
|
|
184
|
+
try {
|
|
185
|
+
const body = await apiJson(`/v1/agents?${params.toString()}`, undefined, apiKey);
|
|
186
|
+
return body.documents[0] || null;
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
if (error instanceof Error && /not found/.test(error.message))
|
|
190
|
+
return null;
|
|
191
|
+
throw error;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
function inferHarness(file, explicit) {
|
|
195
|
+
if (explicit === 'claude-code' || explicit === 'codex' || explicit === 'opencode')
|
|
196
|
+
return explicit;
|
|
197
|
+
return file && path.basename(file).toUpperCase() === 'CLAUDE.MD' ? 'claude-code' : 'codex';
|
|
198
|
+
}
|
|
199
|
+
function inferScope(file, explicit) {
|
|
200
|
+
if (explicit === 'global' || explicit === 'repo')
|
|
201
|
+
return explicit;
|
|
202
|
+
if (file) {
|
|
203
|
+
const absolute = path.resolve(file).toLowerCase();
|
|
204
|
+
if (globalTargets().some((target) => target.actualPath.toLowerCase() === absolute))
|
|
205
|
+
return 'global';
|
|
206
|
+
}
|
|
207
|
+
return 'repo';
|
|
208
|
+
}
|
|
209
|
+
async function reportSync(unitName, target, revision, renderHash, apiKey) {
|
|
210
|
+
await apiJson('/v1/agents/sync', {
|
|
211
|
+
method: 'POST',
|
|
212
|
+
body: JSON.stringify({
|
|
213
|
+
unitName,
|
|
214
|
+
harness: target.harness,
|
|
215
|
+
path: target.manifestPath,
|
|
216
|
+
revision,
|
|
217
|
+
renderHash,
|
|
218
|
+
}),
|
|
219
|
+
}, apiKey);
|
|
220
|
+
}
|
|
221
|
+
function targetMatchesHarness(target, harness) {
|
|
222
|
+
if (!harness || target.harness === harness)
|
|
223
|
+
return true;
|
|
224
|
+
return harness === 'opencode' && target.combinedAgents === true;
|
|
225
|
+
}
|
|
226
|
+
async function syncOne(params) {
|
|
227
|
+
const ctx = context(params.scope, params.args);
|
|
228
|
+
const doc = await fetchDocument(params.scope, ctx.projectId, ctx.directory, params.apiKey);
|
|
229
|
+
if (!doc) {
|
|
230
|
+
if (!params.quiet)
|
|
231
|
+
console.log(`${params.scope}: no canonical doctrine`);
|
|
232
|
+
return { canonical: false, current: 0, changed: 0, blocked: 0, drift: 0 };
|
|
233
|
+
}
|
|
234
|
+
const unitName = parityUnitName(params.scope, ctx.projectId, ctx.directory);
|
|
235
|
+
const stats = { canonical: true, current: 0, changed: 0, blocked: 0, drift: 0 };
|
|
236
|
+
for (const target of ctx.targets.filter(t => targetMatchesHarness(t, params.harness))) {
|
|
237
|
+
const source = fs.existsSync(target.actualPath)
|
|
238
|
+
? fs.readFileSync(target.actualPath, 'utf8')
|
|
239
|
+
: '';
|
|
240
|
+
const adopting = !!params.adoptSourcePath
|
|
241
|
+
&& path.resolve(params.adoptSourcePath).toLowerCase() === path.resolve(target.actualPath).toLowerCase();
|
|
242
|
+
const outcome = (0, agent_doctrine_file_1.patchDoctrineFollower)(source, {
|
|
243
|
+
scopeKey: doc.scopeKey,
|
|
244
|
+
harness: target.harness,
|
|
245
|
+
revision: doc.revision,
|
|
246
|
+
body: renderForTarget(doc, target),
|
|
247
|
+
}, { force: params.force, adoptWholeFile: adopting });
|
|
248
|
+
const current = outcome.action === 'current';
|
|
249
|
+
if (current)
|
|
250
|
+
stats.current++;
|
|
251
|
+
else
|
|
252
|
+
stats.drift++;
|
|
253
|
+
const detail = 'reason' in outcome ? ` — ${outcome.reason}` : '';
|
|
254
|
+
if (!params.quiet) {
|
|
255
|
+
console.log(` ${current ? 'fresh' : outcome.action.padEnd(9)} ${target.actualPath}${detail}`);
|
|
256
|
+
}
|
|
257
|
+
const seedOnlyBlocked = params.seedOnly && !current && outcome.action !== 'seed';
|
|
258
|
+
if (outcome.action === 'diverged' || outcome.action === 'unmanaged' || seedOnlyBlocked) {
|
|
259
|
+
stats.blocked++;
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
if (params.check || current)
|
|
263
|
+
continue;
|
|
264
|
+
fs.mkdirSync(path.dirname(target.actualPath), { recursive: true });
|
|
265
|
+
fs.writeFileSync(target.actualPath, outcome.content, 'utf8');
|
|
266
|
+
await reportSync(unitName, target, doc.revision, outcome.renderHash, params.apiKey);
|
|
267
|
+
stats.changed++;
|
|
268
|
+
}
|
|
269
|
+
return stats;
|
|
270
|
+
}
|
|
271
|
+
async function writeCommand(args, adopt) {
|
|
272
|
+
const positional = adopt && args[0] && !args[0].startsWith('-') ? args[0] : undefined;
|
|
273
|
+
const from = flag(args, '--from') || positional;
|
|
274
|
+
if (adopt && !from)
|
|
275
|
+
throw new Error('adopt requires a source file');
|
|
276
|
+
const sourcePath = from ? path.resolve(from) : undefined;
|
|
277
|
+
if (sourcePath && !fs.existsSync(sourcePath))
|
|
278
|
+
throw new Error(`source file not found: ${sourcePath}`);
|
|
279
|
+
const scope = inferScope(sourcePath, flag(args, '--scope'));
|
|
280
|
+
let harness = inferHarness(sourcePath, flag(args, '--harness'));
|
|
281
|
+
const ctx = context(scope, args);
|
|
282
|
+
const current = adopt ? null : await fetchDocument(scope, ctx.projectId, ctx.directory);
|
|
283
|
+
if (!sourcePath && current && !flag(args, '--harness'))
|
|
284
|
+
harness = current.sourceHarness;
|
|
285
|
+
const body = await apiJson(`/v1/agents/${adopt ? 'adopt' : 'optimize'}`, {
|
|
286
|
+
method: 'POST',
|
|
287
|
+
body: JSON.stringify({
|
|
288
|
+
scope,
|
|
289
|
+
projectId: ctx.projectId,
|
|
290
|
+
directory: ctx.directory,
|
|
291
|
+
sourceHarness: harness,
|
|
292
|
+
sourcePath: sourcePath || null,
|
|
293
|
+
...(sourcePath ? { content: fs.readFileSync(sourcePath, 'utf8') } : {}),
|
|
294
|
+
optimize: !args.includes('--raw'),
|
|
295
|
+
expectedRevision: current?.revision ?? null,
|
|
296
|
+
followers: ctx.targets.map((target) => ({
|
|
297
|
+
harness: target.harness,
|
|
298
|
+
path: target.manifestPath,
|
|
299
|
+
note: target.note,
|
|
300
|
+
})),
|
|
301
|
+
}),
|
|
302
|
+
});
|
|
303
|
+
console.log(`${adopt ? 'Adopted' : 'Optimized'} ${body.document.scopeKey} revision ${body.document.revision}.`);
|
|
304
|
+
if (!args.includes('--no-sync')) {
|
|
305
|
+
await syncOne({
|
|
306
|
+
scope,
|
|
307
|
+
args,
|
|
308
|
+
check: false,
|
|
309
|
+
force: args.includes('--force'),
|
|
310
|
+
adoptSourcePath: adopt ? sourcePath : undefined,
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
async function syncCommand(args, checkOverride = false) {
|
|
315
|
+
const requested = flag(args, '--scope') || 'all';
|
|
316
|
+
if (!['global', 'repo', 'all'].includes(requested)) {
|
|
317
|
+
throw new Error('--scope must be global|repo|all');
|
|
318
|
+
}
|
|
319
|
+
const scopes = requested === 'all' ? ['global', 'repo'] : [requested];
|
|
320
|
+
const check = checkOverride || args.includes('--check');
|
|
321
|
+
let drift = 0;
|
|
322
|
+
for (const scope of scopes) {
|
|
323
|
+
console.log(`${scope}:`);
|
|
324
|
+
const stats = await syncOne({ scope, args, check, force: args.includes('--force') });
|
|
325
|
+
drift += stats.drift;
|
|
326
|
+
}
|
|
327
|
+
if (check && drift > 0) {
|
|
328
|
+
console.error(`${drift} follower(s) need sync or reconciliation.`);
|
|
329
|
+
process.exitCode = 1;
|
|
330
|
+
}
|
|
331
|
+
else if (check) {
|
|
332
|
+
console.log('All materialized followers are current.');
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
/** Init-time seed for the active harness. No canon is a clean no-op; only a
|
|
336
|
+
* missing/empty follower is written. Every existing file, including a stale
|
|
337
|
+
* managed follower, requires an explicit `agents sync`. */
|
|
338
|
+
async function bootstrapAgentDoctrine(apiKey, harness) {
|
|
339
|
+
const result = {
|
|
340
|
+
canonicalScopes: [], currentFollowers: 0, changedFollowers: 0, blockedFollowers: 0,
|
|
341
|
+
};
|
|
342
|
+
for (const scope of ['global', 'repo']) {
|
|
343
|
+
const stats = await syncOne({
|
|
344
|
+
scope, args: [], check: false, force: false, apiKey, harness, quiet: true, seedOnly: true,
|
|
345
|
+
});
|
|
346
|
+
if (stats.canonical)
|
|
347
|
+
result.canonicalScopes.push(scope);
|
|
348
|
+
result.currentFollowers += stats.current;
|
|
349
|
+
result.changedFollowers += stats.changed;
|
|
350
|
+
result.blockedFollowers += stats.blocked;
|
|
351
|
+
}
|
|
352
|
+
return result;
|
|
353
|
+
}
|
|
354
|
+
async function runAgents(args) {
|
|
355
|
+
const sub = args[0];
|
|
356
|
+
if (!sub || sub === 'help' || sub === '--help' || sub === '-h') {
|
|
357
|
+
console.log(HELP);
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
if (sub === 'adopt')
|
|
361
|
+
return writeCommand(args.slice(1), true);
|
|
362
|
+
if (sub === 'optimize')
|
|
363
|
+
return writeCommand(args.slice(1), false);
|
|
364
|
+
if (sub === 'sync')
|
|
365
|
+
return syncCommand(args.slice(1));
|
|
366
|
+
if (sub === 'status')
|
|
367
|
+
return syncCommand(args.slice(1), true);
|
|
368
|
+
throw new Error(`unknown agents command: ${sub}`);
|
|
369
|
+
}
|
|
370
|
+
//# 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
|
-
|
|
236
|
-
|
|
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 (
|
|
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
|
}
|