greprag 5.74.9 → 5.74.11
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/codex-chip-hooks.js +1 -1
- package/dist/commands/codex-chip/help.js +3 -2
- package/dist/commands/codex-chip/prompt.js +2 -1
- package/dist/commands/codex-generated-cleanup.js +170 -0
- package/dist/commands/codex-model-policy.js +0 -16
- package/dist/commands/codex.js +6 -0
- package/dist/commands/doctor.js +7 -3
- package/dist/commands/friction-reminder.js +18 -42
- package/dist/commands/load-primer-reminder.js +1 -1
- package/dist/commands/load.js +3 -6
- package/dist/commands/mechanic-spawn.js +3 -2
- package/dist/commands/opencode-interrupt.js +3 -3
- package/dist/commands/os-primer-reminder.js +3 -2
- package/dist/commands/reminder-registry.js +3 -4
- package/dist/commands/status.js +6 -2
- package/dist/opencode-plugin.bundle.js +13 -30
- package/dist/windows-shims.js +19 -3
- package/package.json +1 -1
- package/skill/greprag/SKILL.md +3 -1
- package/skill/greprag/docs/codex-chip.md +10 -2
- package/skill/mechanic/SKILL.md +17 -15
- package/skill/mechanic/docs/skill-fix-conventions.md +1 -1
- package/skill/templates/codex-chip-spawn.md +166 -121
- package/skill/templates/os.md +15 -12
- package/skill/templates/codex-subagent-spawn.md +0 -34
package/dist/codex-chip-hooks.js
CHANGED
|
@@ -69,7 +69,7 @@ function context(input) {
|
|
|
69
69
|
'Landing: the parent is the delivery owner for merge, post-merge branch/manifest bookkeeping, and any profile-declared push/deploy/release; the child owns routine archival of its own task after the terminal message is delivered. Do not edit the parent checkout or independently cross delivery boundaries. A mission whose first line begins `FIX:` (emitted by `greprag fix spawn`) is writable in its isolated checkout/worktree and hands its verified checkpoint to that owner without a human approval gate. If no live parent exists and the chip carries the full-goal mission, it becomes delivery owner. `greprag fix spawn` only prints the mission; visible Codex task dispatch creates the isolated checkout/worktree.',
|
|
70
70
|
];
|
|
71
71
|
if ((0, model_1.chipMissionKind)(chip) === 'fix') {
|
|
72
|
-
lines.push('Harness: Codex. Mission: visible native FIX chip with ordinary writable authority, not
|
|
72
|
+
lines.push('Harness: Codex. Mission: visible native FIX chip with ordinary writable authority, not a same-session helper.', 'Scope: repair GrepRAG-owned harness surfaces in this checkout: load entries, skill templates, docs, hook context, CLI messages, and tests. Codex owns native task creation, worktrees, permissions, Git, and task lifecycle.', 'Own diagnosis, implementation, tests, commit, and parent report. Inspect Codex behavior only far enough to correct GrepRAG guidance or report a precise external blocker.', 'FIX peer handoff: if a peer offers to coordinate, integrate, rework, or take over a harness repair, hand off branch/commit, dirty files, checks, blockers, and caveats. Do not defend patch ownership; peers may take ownership within their assigned GrepRAG harness scope.', 'Visible delegation route: load `codex-chip-spawn` and create the child with `codex_app__create_thread` using the current project worktree target; load `chip-leader` for multi-chip seams. Same-session helper tools never satisfy a visible-chip requirement.');
|
|
73
73
|
}
|
|
74
74
|
return output(input.hook_event_name || 'SessionStart', lines.join('\n'));
|
|
75
75
|
}
|
|
@@ -15,8 +15,9 @@ exports.CODEX_CHIP_HELP = `greprag codex chip — Codex task orchestration
|
|
|
15
15
|
|
|
16
16
|
Native Codex Desktop is the default: omit --runtime. Use --runtime cli only for
|
|
17
17
|
the explicit headless fallback. Spawn prepares the Desktop create request and
|
|
18
|
-
handoff with
|
|
19
|
-
|
|
18
|
+
handoff with a Codex worktree environment plus
|
|
19
|
+
\`startingState.branchName\`. The standalone CLI does not create the Desktop
|
|
20
|
+
task itself. The active topology is an implicit LEAD for
|
|
20
21
|
quick chips, an explicit LEAD for multi-chip orchestration, and Chip A/B/C with
|
|
21
22
|
optional ADVISOR orientation. FIX missions are visible one-friction tasks from
|
|
22
23
|
\`greprag fix spawn\`: they select \`chip.fix\` and load mechanic doctrine.
|
|
@@ -26,7 +26,8 @@ function chipPrompt(manifest, _cliCommand = 'greprag') {
|
|
|
26
26
|
|
|
27
27
|
Setup — do this FIRST:
|
|
28
28
|
${mechanicSetup}${leaderSetup}- Stay in ${executionPath}. Applicable AGENTS instructions and the session-start recap are already in context; inspect the current repository state.
|
|
29
|
-
- Bootstrap this checkout before build/test: if \`scripts/
|
|
29
|
+
- Bootstrap this checkout before build/test: if \`scripts/worktree-bootstrap.cjs\` exists, run \`node scripts/worktree-bootstrap.cjs\`; if only \`scripts/ensure-npm-deps.cjs\` exists, run \`node scripts/ensure-npm-deps.cjs\`. Never link or junction \`node_modules\` to another checkout.
|
|
30
|
+
- When running build/test or other env-driven commands, use \`node scripts/codex-run.cjs -- <command ...>\` if that wrapper exists. It loads ignored env files from the main checkout; never copy or print secrets.
|
|
30
31
|
- Do not create a second worktree. The selected workspace is fully writable; there are no leases, read-only mode, or GrepRAG goal gates.
|
|
31
32
|
- The durable manifest is ${manifest.id}; it is task bookkeeping, not a scope or permission gate.
|
|
32
33
|
${startupInstruction}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.cleanupCodexGeneratedDist = cleanupCodexGeneratedDist;
|
|
37
|
+
exports.runCodexCleanGenerated = runCodexCleanGenerated;
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const proc_1 = require("../proc");
|
|
41
|
+
function samePath(left, right) {
|
|
42
|
+
const l = path.resolve(left);
|
|
43
|
+
const r = path.resolve(right);
|
|
44
|
+
return process.platform === 'win32' ? l.toLowerCase() === r.toLowerCase() : l === r;
|
|
45
|
+
}
|
|
46
|
+
function isInside(parent, child) {
|
|
47
|
+
const relative = path.relative(path.resolve(parent), path.resolve(child));
|
|
48
|
+
return !!relative && !relative.startsWith('..') && !path.isAbsolute(relative);
|
|
49
|
+
}
|
|
50
|
+
function gitRootFor(start) {
|
|
51
|
+
try {
|
|
52
|
+
return path.resolve(String((0, proc_1.safeExecFileSync)('git', ['-C', start, 'rev-parse', '--show-toplevel'], {
|
|
53
|
+
encoding: 'utf8',
|
|
54
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
55
|
+
})).trim());
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function assertDistLeaf(target) {
|
|
62
|
+
if (path.basename(target).toLowerCase() !== 'dist') {
|
|
63
|
+
throw new Error(`Refusing generated cleanup for non-dist path: ${target}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function assertNoRepoMetadata(target) {
|
|
67
|
+
if (fs.existsSync(path.join(target, '.git'))) {
|
|
68
|
+
throw new Error(`Refusing to remove a directory containing .git metadata: ${target}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function cleanupBound(target, opts) {
|
|
72
|
+
const cwd = path.resolve(opts.cwd || process.cwd());
|
|
73
|
+
if (opts.under) {
|
|
74
|
+
const bound = path.resolve(cwd, opts.under);
|
|
75
|
+
if (samePath(bound, target) || !isInside(bound, target)) {
|
|
76
|
+
throw new Error(`Refusing cleanup outside explicit --under bound: ${target}`);
|
|
77
|
+
}
|
|
78
|
+
return { bound, boundKind: 'explicit-under' };
|
|
79
|
+
}
|
|
80
|
+
const parent = path.dirname(target);
|
|
81
|
+
if (!fs.existsSync(parent)) {
|
|
82
|
+
throw new Error(`Refusing cleanup because parent directory does not exist: ${parent}`);
|
|
83
|
+
}
|
|
84
|
+
const gitStart = fs.existsSync(target) && fs.lstatSync(target).isDirectory() ? target : parent;
|
|
85
|
+
const gitRoot = gitRootFor(gitStart);
|
|
86
|
+
if (!gitRoot) {
|
|
87
|
+
throw new Error(`Refusing cleanup outside a Git worktree; pass --under <dir> for an explicit bound: ${target}`);
|
|
88
|
+
}
|
|
89
|
+
if (samePath(gitRoot, target) || !isInside(gitRoot, target)) {
|
|
90
|
+
throw new Error(`Refusing cleanup outside Git root ${gitRoot}: ${target}`);
|
|
91
|
+
}
|
|
92
|
+
return { bound: gitRoot, boundKind: 'git-root' };
|
|
93
|
+
}
|
|
94
|
+
function cleanupCodexGeneratedDist(targetArg, opts = {}) {
|
|
95
|
+
if (!targetArg || !targetArg.trim())
|
|
96
|
+
throw new Error('Missing generated directory path.');
|
|
97
|
+
const cwd = path.resolve(opts.cwd || process.cwd());
|
|
98
|
+
const target = path.resolve(cwd, targetArg);
|
|
99
|
+
assertDistLeaf(target);
|
|
100
|
+
const bound = cleanupBound(target, opts);
|
|
101
|
+
const dryRun = !!opts.dryRun;
|
|
102
|
+
if (!fs.existsSync(target)) {
|
|
103
|
+
return { target, ...bound, removed: false, dryRun, reason: 'missing' };
|
|
104
|
+
}
|
|
105
|
+
const stat = fs.lstatSync(target);
|
|
106
|
+
if (stat.isSymbolicLink()) {
|
|
107
|
+
throw new Error(`Refusing to remove symlink/reparse target: ${target}`);
|
|
108
|
+
}
|
|
109
|
+
if (!stat.isDirectory()) {
|
|
110
|
+
throw new Error(`Refusing to remove non-directory generated path: ${target}`);
|
|
111
|
+
}
|
|
112
|
+
assertNoRepoMetadata(target);
|
|
113
|
+
if (dryRun) {
|
|
114
|
+
return { target, ...bound, removed: false, dryRun, reason: 'dry-run' };
|
|
115
|
+
}
|
|
116
|
+
fs.rmSync(target, { recursive: true, force: false });
|
|
117
|
+
if (fs.existsSync(target))
|
|
118
|
+
throw new Error(`Cleanup did not remove target: ${target}`);
|
|
119
|
+
return { target, ...bound, removed: true, dryRun };
|
|
120
|
+
}
|
|
121
|
+
function parseArgs(args) {
|
|
122
|
+
let under;
|
|
123
|
+
let dryRun = false;
|
|
124
|
+
let json = false;
|
|
125
|
+
const positional = [];
|
|
126
|
+
for (let i = 0; i < args.length; i++) {
|
|
127
|
+
const arg = args[i];
|
|
128
|
+
if (arg === '--dry-run') {
|
|
129
|
+
dryRun = true;
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
if (arg === '--json') {
|
|
133
|
+
json = true;
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
if (arg === '--under') {
|
|
137
|
+
under = args[++i];
|
|
138
|
+
if (!under)
|
|
139
|
+
throw new Error('Missing value for --under.');
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
if (arg.startsWith('--'))
|
|
143
|
+
throw new Error(`Unknown clean-generated flag: ${arg}`);
|
|
144
|
+
positional.push(arg);
|
|
145
|
+
}
|
|
146
|
+
if (positional.length !== 1) {
|
|
147
|
+
throw new Error('Usage: greprag codex clean-generated <path-to-dist> [--under <dir>] [--dry-run] [--json]');
|
|
148
|
+
}
|
|
149
|
+
return { target: positional[0], under, dryRun, json };
|
|
150
|
+
}
|
|
151
|
+
function runCodexCleanGenerated(args) {
|
|
152
|
+
const parsed = parseArgs(args);
|
|
153
|
+
const result = cleanupCodexGeneratedDist(parsed.target, {
|
|
154
|
+
under: parsed.under,
|
|
155
|
+
dryRun: parsed.dryRun,
|
|
156
|
+
});
|
|
157
|
+
if (parsed.json) {
|
|
158
|
+
console.log(JSON.stringify(result));
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const action = result.reason === 'missing'
|
|
162
|
+
? 'already absent'
|
|
163
|
+
: result.reason === 'dry-run'
|
|
164
|
+
? 'would remove'
|
|
165
|
+
: result.removed
|
|
166
|
+
? 'removed'
|
|
167
|
+
: 'unchanged';
|
|
168
|
+
console.log(`Codex generated cleanup ${action}: ${result.target}`);
|
|
169
|
+
console.log(`Bound: ${result.boundKind} ${result.bound}`);
|
|
170
|
+
}
|
|
@@ -36,7 +36,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.KNOWN_CODEX_MODEL_EFFORTS = exports.DEFAULT_CODEX_MODEL_POLICY = exports.CODEX_MODEL_EFFORTS = void 0;
|
|
37
37
|
exports.loadCodexModelPolicy = loadCodexModelPolicy;
|
|
38
38
|
exports.resolveChipModelSlot = resolveChipModelSlot;
|
|
39
|
-
exports.resolveSubagentModelSlot = resolveSubagentModelSlot;
|
|
40
39
|
exports.printCodexModelPolicy = printCodexModelPolicy;
|
|
41
40
|
const fs = __importStar(require("fs"));
|
|
42
41
|
const os = __importStar(require("os"));
|
|
@@ -51,11 +50,6 @@ exports.DEFAULT_CODEX_MODEL_POLICY = {
|
|
|
51
50
|
advisor: { model: 'gpt-5.6-sol', effort: 'high' },
|
|
52
51
|
fix: { model: 'gpt-5.5', effort: 'high' },
|
|
53
52
|
},
|
|
54
|
-
subagent: {
|
|
55
|
-
fast_scan: { model: 'gpt-5.5', effort: 'medium' },
|
|
56
|
-
routine_worker: { model: 'gpt-5.5', effort: 'high' },
|
|
57
|
-
deep_worker: { model: 'gpt-5.6-luna', effort: 'xhigh' },
|
|
58
|
-
},
|
|
59
53
|
};
|
|
60
54
|
exports.KNOWN_CODEX_MODEL_EFFORTS = {
|
|
61
55
|
'gpt-5.6-sol': ['low', 'medium', 'high', 'xhigh', 'max', 'ultra'],
|
|
@@ -90,11 +84,6 @@ function applyPolicy(base, patch, source) {
|
|
|
90
84
|
throw new Error(`${source} has unknown chip model slot ${key}.`);
|
|
91
85
|
base.chip[key] = applySlot(base.chip[key], chipPatch[key] || {}, `${source} chip.${key}`);
|
|
92
86
|
}
|
|
93
|
-
for (const key of Object.keys(patch.subagent || {})) {
|
|
94
|
-
if (!(key in base.subagent))
|
|
95
|
-
throw new Error(`${source} has unknown subagent model slot ${key}.`);
|
|
96
|
-
base.subagent[key] = applySlot(base.subagent[key], patch.subagent[key] || {}, `${source} subagent.${key}`);
|
|
97
|
-
}
|
|
98
87
|
return base;
|
|
99
88
|
}
|
|
100
89
|
function readPolicyFile(filePath) {
|
|
@@ -148,9 +137,6 @@ function loadCodexModelPolicy(cwd = process.cwd(), homeDir = process.env.HOME ||
|
|
|
148
137
|
function resolveChipModelSlot(role, policy = loadCodexModelPolicy()) {
|
|
149
138
|
return policy.chip[role];
|
|
150
139
|
}
|
|
151
|
-
function resolveSubagentModelSlot(role, policy = loadCodexModelPolicy()) {
|
|
152
|
-
return policy.subagent[role];
|
|
153
|
-
}
|
|
154
140
|
function printCodexModelPolicy(args = []) {
|
|
155
141
|
const json = args.includes('--json');
|
|
156
142
|
const policy = loadCodexModelPolicy();
|
|
@@ -160,6 +146,4 @@ function printCodexModelPolicy(args = []) {
|
|
|
160
146
|
console.log('Config files: ~/.greprag/codex-models.json, then .greprag/codex-models.json');
|
|
161
147
|
for (const [role, slot] of Object.entries(policy.chip))
|
|
162
148
|
console.log(` chip.${role}: ${slot.model} / ${slot.effort}`);
|
|
163
|
-
for (const [role, slot] of Object.entries(policy.subagent))
|
|
164
|
-
console.log(` subagent.${role}: ${slot.model} / ${slot.effort}`);
|
|
165
149
|
}
|
package/dist/commands/codex.js
CHANGED
|
@@ -53,6 +53,7 @@ const codex_app_server_1 = require("./codex-app-server");
|
|
|
53
53
|
const codex_delivery_1 = require("./codex-delivery");
|
|
54
54
|
const codex_model_policy_1 = require("./codex-model-policy");
|
|
55
55
|
const codex_startup_1 = require("./codex-startup");
|
|
56
|
+
const codex_generated_cleanup_1 = require("./codex-generated-cleanup");
|
|
56
57
|
const codex_watch_health_1 = require("./codex-watch-health");
|
|
57
58
|
var codex_startup_2 = require("./codex-startup");
|
|
58
59
|
Object.defineProperty(exports, "codexStartupInfo", { enumerable: true, get: function () { return codex_startup_2.codexStartupInfo; } });
|
|
@@ -458,6 +459,7 @@ const HELP = `greprag codex — Codex-specific helpers.
|
|
|
458
459
|
greprag codex models show [--json]
|
|
459
460
|
greprag codex chip spawn "<task>" --name <name> [--role worker|leader|planner|advisor] [--runtime cli]
|
|
460
461
|
greprag codex chip list|status|steer|stop|report|block|cleanup|reconcile
|
|
462
|
+
greprag codex clean-generated <path-to-dist> [--under <dir>] [--dry-run] [--json]
|
|
461
463
|
greprag codex doctor
|
|
462
464
|
greprag codex startup remove
|
|
463
465
|
|
|
@@ -518,6 +520,10 @@ async function runCodex(args) {
|
|
|
518
520
|
await (0, command_1.runCodexChip)(args.slice(1));
|
|
519
521
|
return;
|
|
520
522
|
}
|
|
523
|
+
if (sub === 'clean-generated') {
|
|
524
|
+
(0, codex_generated_cleanup_1.runCodexCleanGenerated)(args.slice(1));
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
521
527
|
if (sub !== 'watch' && sub !== 'arm') {
|
|
522
528
|
console.error(`Unknown codex command: ${sub}\n`);
|
|
523
529
|
console.log(HELP);
|
package/dist/commands/doctor.js
CHANGED
|
@@ -275,8 +275,12 @@ async function runShimAudit(opts) {
|
|
|
275
275
|
console.log('Windows shims:');
|
|
276
276
|
for (const s of shims) {
|
|
277
277
|
const ver = s.version ? `v${s.version}` : '(version unknown)';
|
|
278
|
-
const
|
|
279
|
-
|
|
278
|
+
const details = [
|
|
279
|
+
...(s.incomplete ? [`missing ${s.missingFiles.join(', ')}`] : []),
|
|
280
|
+
...(s.volatileForward ? ['fnm temp forward'] : []),
|
|
281
|
+
];
|
|
282
|
+
const suffix = details.length ? ` ${details.join(', ')}` : '';
|
|
283
|
+
const flag = s.stale ? ` ⚠ STALE${suffix}` : s.incomplete ? ` ⚠ INCOMPLETE${suffix}` : s.volatileForward ? ` ⚠ VOLATILE${suffix}` : s.unresolvable ? ' ? unresolvable' : '';
|
|
280
284
|
console.log(` ${s.name}${s.active ? '' : ' (shadowed)'}: ${s.shimPath} → ${ver}${flag}`);
|
|
281
285
|
}
|
|
282
286
|
if (unhealthy.length === 0) {
|
|
@@ -291,7 +295,7 @@ async function runShimAudit(opts) {
|
|
|
291
295
|
if (!opts.yes) {
|
|
292
296
|
const fixable = repairs.filter(r => r.forwardTo);
|
|
293
297
|
for (const r of repairs.filter(x => !x.forwardTo)) {
|
|
294
|
-
console.log(` ✗ ${r.shim.shimPath} is unhealthy and no current ${r.shim.name} shim exists on PATH to forward to — run
|
|
298
|
+
console.log(` ✗ ${r.shim.shimPath} is unhealthy and no durable current ${r.shim.name} shim exists on PATH to forward to — run \`${(0, windows_shims_1.shimInstallCommand)()}\` first.`);
|
|
295
299
|
}
|
|
296
300
|
if (fixable.length === 0) {
|
|
297
301
|
console.log('');
|
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
* live stress level) rather than a binary resolvable deficiency.
|
|
6
6
|
*
|
|
7
7
|
* A reminder-interrupt MODULE is `{ id, detect, announce, reminder }` (reminder-types.ts):
|
|
8
|
-
* `detect(env)` reads the live state → a tier (`silent` = nothing to fix);
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* `detect(env)` reads the live state → a tier (`silent` = nothing to fix); the grepragOS
|
|
9
|
+
* primer owns the startup schema, and this module contributes only a thin live reminder.
|
|
10
|
+
* The container (reminder-registry.ts) wires every module; the hook (hook.ts) assembles
|
|
11
|
+
* the env and emits — see `injectReminders`.
|
|
12
12
|
*
|
|
13
13
|
* PURE: imports only the stress constants; returns strings + a tier + a tally. No fs, no
|
|
14
14
|
* network, no clock — the hook does ALL I/O. Keeping detect/tier a pure function is what
|
|
@@ -19,10 +19,10 @@ exports.frictionReminderTier = frictionReminderTier;
|
|
|
19
19
|
exports.buildMechanicLiveNotice = buildMechanicLiveNotice;
|
|
20
20
|
exports.buildFrictionReminder = buildFrictionReminder;
|
|
21
21
|
exports.buildBootstrapFrictionReminder = buildBootstrapFrictionReminder;
|
|
22
|
-
exports.buildMechanicAnnounce = buildMechanicAnnounce;
|
|
23
22
|
exports.tallyFrictionFire = tallyFrictionFire;
|
|
24
23
|
exports.tallyMechanicSpawn = tallyMechanicSpawn;
|
|
25
24
|
const state_trigger_1 = require("./state-trigger");
|
|
25
|
+
// adr: adr/friction-memory-first.md
|
|
26
26
|
function quoteForCommand(value) {
|
|
27
27
|
return value.replace(/[\r\n]+/g, ' ').replace(/"/g, '\\"').trim();
|
|
28
28
|
}
|
|
@@ -49,21 +49,22 @@ function frictionReminderTier(stress) {
|
|
|
49
49
|
return 'nudge';
|
|
50
50
|
return 'silent';
|
|
51
51
|
}
|
|
52
|
-
/** The per-turn reminder line — fires only on detected stress, points at
|
|
53
|
-
*
|
|
52
|
+
/** The per-turn reminder line — fires only on detected stress, points first at
|
|
53
|
+
* Memory for a known overcome, then at fix spawn for unresolved friction.
|
|
54
|
+
* Ends on a forced binary so it converts. null = calm.
|
|
54
55
|
* The queue-route (`mechanic friction`) and log-route (`fix log`) verbs were
|
|
55
|
-
* RETIRED as reflexes 2026-07-12 (grepragOS)
|
|
56
|
-
* one chip per unit. */
|
|
56
|
+
* RETIRED as reflexes 2026-07-12 (grepragOS). */
|
|
57
57
|
const FIX_SPAWN = 'greprag fix spawn --type <harness|doctrine|injection|env|code> "<one unit>"';
|
|
58
|
+
const MEMORY_SEARCH = 'greprag memory search "<exact error/friction + repo/tool>"';
|
|
58
59
|
function buildMechanicLiveNotice(_env) {
|
|
59
|
-
return `GrepRAG Mechanic is live. Friction
|
|
60
|
+
return `GrepRAG Mechanic is live. Friction order: \`${MEMORY_SEARCH}\` first; apply a clear overcome and continue. No answer, failed overcome, or repeated friction → \`${FIX_SPAWN}\`. Check role only when needed: \`greprag mechanic role\`.`;
|
|
60
61
|
}
|
|
61
62
|
function buildFrictionReminder(tier, env) {
|
|
62
63
|
switch (tier) {
|
|
63
64
|
case 'nag':
|
|
64
|
-
return `⚠ FRICTION HIGH (live signal: repetition / errors / churn) — STOP pushing through.
|
|
65
|
+
return `⚠ FRICTION HIGH (live signal: repetition / errors / churn) — STOP pushing through. MEMORY FIRST: \`${MEMORY_SEARCH}\`. Clear overcome → apply + continue. No answer, remembered overcome fails, or same friction repeats → \`${FIX_SPAWN}\`. No friction? say "clear" + continue.`;
|
|
65
66
|
case 'nudge':
|
|
66
|
-
return `⚠ Friction detected (live signal) — repeated yourself, fought a tool, or hit a wall?
|
|
67
|
+
return `⚠ Friction detected (live signal) — repeated yourself, fought a tool, or hit a wall? Search first: \`${MEMORY_SEARCH}\`. Apply a clear overcome + continue; no answer, failed overcome, or repeat → \`${FIX_SPAWN}\`. Otherwise say "clear" + continue.`;
|
|
67
68
|
default:
|
|
68
69
|
return null;
|
|
69
70
|
}
|
|
@@ -74,25 +75,8 @@ function buildBootstrapFrictionReminder(env) {
|
|
|
74
75
|
return null;
|
|
75
76
|
const repeats = b.repeats && b.repeats > 1 ? ` repeated ${b.repeats}x` : '';
|
|
76
77
|
const error = b.error ? ` Last error: ${b.error}` : '';
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
// ---------- The fix-reflex primer (announce-only) ----------------------------
|
|
80
|
-
/** SessionStart primer — the fix reflex, loaded ONCE. Full doctrine inline
|
|
81
|
-
* (a PRIMER, not a pointer): it teaches WHEN friction is a spawn-now signal
|
|
82
|
-
* and the chip's delivery-owner contract. Rewritten 2026-07-12 (grepragOS):
|
|
83
|
-
* the queue-route (`mechanic friction`), log-route (`fix log`) and the
|
|
84
|
-
* one-Mechanic-absorbs-all-friction model are RETIRED as reflexes — one unit
|
|
85
|
-
* of friction ⇒ one fix chip, spawned at the moment. */
|
|
86
|
-
function buildMechanicAnnounce() {
|
|
87
|
-
return [
|
|
88
|
-
'[Fix reflex — friction is fixed at the MOMENT it happens, one chip per unit (grepragOS law; full doctrine: `greprag load os`).]',
|
|
89
|
-
'WHEN friction happens — repeated yourself, fought a tool, got corrected >=2x on the same thing, rediscovered something already known, or hit a setup/toolchain failure not caused by code you just edited — spawn its fix chip NOW, then keep working. Ordinary misunderstanding or misreading user intent is not friction unless it repeats or exposes a durable doctrine/harness/injection/env/code failure. One unit = one chip; adjacent friction gets its own spawn. Never queue friction for later.',
|
|
90
|
-
'TYPE = durable repair surface: harness=hooks/watchers/task dispatch; doctrine=greprag load/skills/AGENTS; injection=recap/Capture/doc-pointer/stateful injection; env=bootstrap/deps/scripts/worktree setup; code=product/source behavior. Use: `greprag fix spawn --type <type> "<one unit>"`.',
|
|
91
|
-
'WORKSPACE ROUTING: `fix spawn` detects usable Git history before dispatch — Git uses an isolated worktree; non-Git, unavailable Git, or no commit uses the project-local task with serialized writes. No fail-then-fallback attempt.',
|
|
92
|
-
'THE CHIP\'S CONTRACT (it self-enforces; you just spawn): identify the exact friction → make the smallest durable root-cause fix → explain and verify it → checkpoint → hand it to the mission delivery owner. With no live parent and a full-goal mission, the chip becomes delivery owner and follows the repo profile. No second lifecycle approval.',
|
|
93
|
-
'Every repair is ROOT-CAUSE — fix the pattern that makes the friction class possible, never a guard on today\'s trigger.',
|
|
94
|
-
'A per-turn reminder fires ONLY when live friction is DETECTED (the stress signal — repetition / errors / churn), never on a timer — act on it, or say "clear" and continue.',
|
|
95
|
-
].join('\n');
|
|
78
|
+
const summary = bootstrapSummary(env);
|
|
79
|
+
return `⚠ BOOTSTRAP FRICTION detected${repeats}: setup/toolchain failure (${b.signal || 'setup'}) around \`${b.command || 'unknown command'}\`.${error} MEMORY FIRST: \`greprag memory search "${summary}"\`. Apply a clear overcome + continue. No answer, remembered overcome fails, or the same failure repeats → \`greprag fix spawn --type env "${summary}"\`.`;
|
|
96
80
|
}
|
|
97
81
|
/** Normalize any prior-stats blob (possibly missing/partial/corrupt) into a fully
|
|
98
82
|
* populated FrictionStats. Pure, total. */
|
|
@@ -136,13 +120,10 @@ function tallyMechanicSpawn(prior) {
|
|
|
136
120
|
return s;
|
|
137
121
|
}
|
|
138
122
|
// ---------- Registry module --------------------------------------------------
|
|
139
|
-
/** The active Mechanic
|
|
140
|
-
*
|
|
141
|
-
* 2026-06-22 as wallpaper). `dependsOn` the chip-spawn pointer so the chip concept
|
|
142
|
-
* it references is already loaded — the boot sequence places it AFTER chips. */
|
|
123
|
+
/** The active Mechanic reminder. The grepragOS primer owns the one startup schema;
|
|
124
|
+
* this module is reminder-only and fires only from live stress/bootstrap state. */
|
|
143
125
|
exports.mechanicFrictionModule = {
|
|
144
126
|
id: 'mechanic-friction',
|
|
145
|
-
dependsOn: ['chip-spawn-pointer'],
|
|
146
127
|
// Stress fires the real friction reminder. A designated Mechanic also creates a
|
|
147
128
|
// one-shot ambient route notice per source session/role epoch (hook-stamped).
|
|
148
129
|
detect: (env) => {
|
|
@@ -155,12 +136,7 @@ exports.mechanicFrictionModule = {
|
|
|
155
136
|
return { tier: 'ambient' };
|
|
156
137
|
return { tier: 'silent' };
|
|
157
138
|
},
|
|
158
|
-
announce: (
|
|
159
|
-
const base = buildMechanicAnnounce();
|
|
160
|
-
if (env.mechanicLive && !env.mechanic)
|
|
161
|
-
return `${base}\n\n${buildMechanicLiveNotice(env)}`;
|
|
162
|
-
return base;
|
|
163
|
-
},
|
|
139
|
+
announce: () => null,
|
|
164
140
|
reminder: (d, env) => {
|
|
165
141
|
if (d.detail?.kind === 'bootstrap-friction')
|
|
166
142
|
return buildBootstrapFrictionReminder(env);
|
|
@@ -46,7 +46,7 @@ exports.OPENCODE_CHIP_SPAWN_POINTER = [
|
|
|
46
46
|
/** POINTER — Codex Desktop's native chip path. This is intentionally distinct
|
|
47
47
|
* from Claude Code spawn_task: different lifecycle, runtime, and handoff. */
|
|
48
48
|
exports.CODEX_CHIP_SPAWN_POINTER = [
|
|
49
|
-
'[greprag Codex delegation —
|
|
49
|
+
'[greprag Codex delegation — 1–2-chip quick path with the initiator as LEAD, or a separate LEAD for larger/seamed missions.]',
|
|
50
50
|
'• About to delegate a Codex task? → run `greprag load codex-chip-spawn` FIRST. Use exact first-line titles `LEAD: <Mission>`, `Chip A/B/C: <Specific Purview>`, and `FIX: [type] <one friction unit>`. Chips are ordinary writable native tasks; completion is a native Codex task reply to the LEAD after committing. A `FIX:` task loads `greprag load mechanic` first.',
|
|
51
51
|
].join('\n');
|
|
52
52
|
exports.loadPrimerModule = {
|
package/dist/commands/load.js
CHANGED
|
@@ -63,7 +63,7 @@ const doc_mirror_client_1 = require("../doc-mirror-client");
|
|
|
63
63
|
const LIBRARY = {
|
|
64
64
|
os: {
|
|
65
65
|
files: ['skill/templates/os.md'],
|
|
66
|
-
purpose: 'grepragOS — the operating laws: doctrine vs state, discoverability, pull-before-derive, friction ⇒ fix spawn, teach the system not the chat.',
|
|
66
|
+
purpose: 'grepragOS — the operating laws: doctrine vs state, discoverability, pull-before-derive, memory-first friction recovery, unresolved friction ⇒ fix spawn, teach the system not the chat.',
|
|
67
67
|
},
|
|
68
68
|
'chip-spawn': {
|
|
69
69
|
files: ['skill/templates/chip-spawn.md'],
|
|
@@ -73,10 +73,6 @@ const LIBRARY = {
|
|
|
73
73
|
files: ['skill/templates/codex-chip-spawn.md'],
|
|
74
74
|
purpose: 'Spawn an independent writable native Codex Desktop task with an isolated worktree and native completion/cleanup.',
|
|
75
75
|
},
|
|
76
|
-
'codex-subagent-spawn': {
|
|
77
|
-
files: ['skill/templates/codex-subagent-spawn.md'],
|
|
78
|
-
purpose: 'Use bounded ephemeral Codex subagents inside the current session without a visible task, worktree, manifest, inbox identity, or goal.',
|
|
79
|
-
},
|
|
80
76
|
'skill-change': {
|
|
81
77
|
files: ['skill/templates/skill-change.md'],
|
|
82
78
|
purpose: 'Internal bundled schema for safely updating a skill after a run: when to edit, Convention A/B shapes, and when to propose instead.',
|
|
@@ -432,7 +428,8 @@ async function runLoad(args) {
|
|
|
432
428
|
return;
|
|
433
429
|
console.error(`Unknown load entry: ${name}\n`);
|
|
434
430
|
await printCatalog();
|
|
435
|
-
process.
|
|
431
|
+
process.exitCode = 1;
|
|
432
|
+
return;
|
|
436
433
|
}
|
|
437
434
|
const bodies = [];
|
|
438
435
|
for (const file of entry.files) {
|
|
@@ -148,8 +148,9 @@ function buildFixMission(friction, scope, parentSession, type = inferFixType(fri
|
|
|
148
148
|
'1. `greprag load mechanic`',
|
|
149
149
|
...workspace.setup,
|
|
150
150
|
'4. Read AGENTS.md and the session-start recap, then inspect the current repository state.',
|
|
151
|
-
'5. Bootstrap this checkout before build/test: if `scripts/
|
|
152
|
-
'6.
|
|
151
|
+
'5. Bootstrap this checkout before build/test: if `scripts/worktree-bootstrap.cjs` exists, run `node scripts/worktree-bootstrap.cjs`; if only `scripts/ensure-npm-deps.cjs` exists, run `node scripts/ensure-npm-deps.cjs`. Never link or junction `node_modules` to another checkout.',
|
|
152
|
+
'6. When running build/test or other env-driven commands, use `node scripts/codex-run.cjs -- <command ...>` if that wrapper exists. It loads ignored env files from the main checkout; never copy or print secrets.',
|
|
153
|
+
'7. Reproduce the friction before changing anything.',
|
|
153
154
|
'',
|
|
154
155
|
'**Repair contract**',
|
|
155
156
|
`- ${workspace.work}`,
|
|
@@ -29,9 +29,9 @@ function buildOpenCodeEnv(params) {
|
|
|
29
29
|
// No opencode-native friction detector is wired yet: Claude Code's stress /
|
|
30
30
|
// bootstrap-friction signals come from state-trigger.ts reading the
|
|
31
31
|
// transcript in hook.ts, and opencode has no equivalent source plumbed.
|
|
32
|
-
// 0 = calm keeps the mechanic-friction
|
|
33
|
-
//
|
|
34
|
-
// parked with scored options in the chip report
|
|
32
|
+
// 0 = calm keeps the reminder-only mechanic-friction module silent. The
|
|
33
|
+
// os-primer still lands the memory-first escalation doctrine every session.
|
|
34
|
+
// Detector design is parked with scored options in the chip report
|
|
35
35
|
// (chip/opencode-fix-chip-system-parity).
|
|
36
36
|
stress: 0,
|
|
37
37
|
armed: params.armed ?? false,
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
14
|
exports.osPrimerModule = void 0;
|
|
15
15
|
exports.buildOsPrimer = buildOsPrimer;
|
|
16
|
+
// adr: adr/friction-memory-first.md
|
|
16
17
|
function buildOsPrimer(env) {
|
|
17
18
|
// The chip-spawn method is per-harness (Codex never sees the Claude entry —
|
|
18
19
|
// the same wall the codex-chip-spawn pointer module enforces; opencode's
|
|
@@ -24,8 +25,8 @@ function buildOsPrimer(env) {
|
|
|
24
25
|
'[grepragOS — the operating laws. Full doctrine: `greprag load os`.]',
|
|
25
26
|
'• Doctrine vs state: methods ship in the CLI (`greprag load`); live state lives in the repo. A skill that depends on repo state carries a "STATE — read these first" block naming exact paths.',
|
|
26
27
|
'• Discoverability: every durable artifact must be findable next session — docs auto-register, skills auto-mirror, decisions get a dated ADR/decision-log entry, everything else gets its path named in the owning skill/doc. If nothing points at it, you didn\'t finish.',
|
|
27
|
-
'• Pull before derive: `greprag memory search` / `corpus search` / `load` BEFORE asking the operator or re-deriving what the project already knows. Named person/org/project/repo/customer/handle or unexplained proper noun → search Memory before guessing, unless fully defined in-turn.',
|
|
28
|
-
`•
|
|
28
|
+
'• Pull before derive: `greprag memory search` / `corpus search` / `load` BEFORE asking the operator or re-deriving what the project already knows. Friction or an env/toolchain/worktree/secret bootstrap roadblock → search Memory for the exact error/friction + repo/tool before inventing a workaround. Clear overcome → apply it and continue. Named person/org/project/repo/customer/handle or unexplained proper noun → search Memory before guessing, unless fully defined in-turn.',
|
|
29
|
+
`• Unresolved friction ⇒ fix: only when Memory has no answer, the remembered overcome fails, or the same friction repeats. Then type by durable repair surface (\`harness|doctrine|injection|env|code\`) ⇒ \`greprag fix spawn --type <type> "<unit>"\`. It PRINTS a fix-chip mission — YOU then create the visible child task with that mission as its first message (how: \`greprag load ${spawnEntry}\`, or your harness's native task tool). Repo write = isolated worktree; data-only row/diagnosis = no repo write. One unresolved unit per chip; the chip fixes, verifies, checkpoints, and hands it to the mission delivery owner.`,
|
|
29
30
|
'• Teach the system, not the chat: explained twice by the operator ⇒ it belongs in a skill / load entry / STATE block / ADR, not the conversation.',
|
|
30
31
|
].join('\n');
|
|
31
32
|
}
|
|
@@ -30,10 +30,9 @@ const loadout_reminder_1 = require("./loadout-reminder");
|
|
|
30
30
|
const delivery_reminder_1 = require("./delivery-reminder");
|
|
31
31
|
/** Registry order = display order. THE single agent-facing announce/reminder assembly:
|
|
32
32
|
* the hook does I/O → fills ReminderEnv → collectAnnounces (SessionStart) / collectReminders
|
|
33
|
-
* (per turn) render every module here in this order.
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* SessionStart. Add a module here to wire it into BOTH surfaces at once. */
|
|
33
|
+
* (per turn) render every module here in this order. A module may own either surface or both;
|
|
34
|
+
* os-primer owns startup friction doctrine and mechanic-friction is reminder-only.
|
|
35
|
+
* Add a module here to wire it into the appropriate surfaces at once. */
|
|
37
36
|
exports.REGISTRY = [
|
|
38
37
|
os_primer_reminder_1.osPrimerModule, // grepragOS constitution — the frame every other primer hangs off; boots FIRST
|
|
39
38
|
inbox_primer_reminder_1.inboxPrimerModule,
|
package/dist/commands/status.js
CHANGED
|
@@ -327,8 +327,12 @@ function renderShims(w) {
|
|
|
327
327
|
const lines = ['', 'Windows shims (what each PowerShell/CMD shim on PATH actually executes):'];
|
|
328
328
|
for (const s of w.shims) {
|
|
329
329
|
const ver = s.version ? `v${s.version}` : '(version unknown)';
|
|
330
|
-
const
|
|
331
|
-
|
|
330
|
+
const details = [
|
|
331
|
+
...(s.incomplete ? [`missing ${s.missingFiles.join(', ')}`] : []),
|
|
332
|
+
...(s.volatileForward ? ['fnm temp forward'] : []),
|
|
333
|
+
];
|
|
334
|
+
const suffix = details.length ? ` ${details.join(', ')}` : '';
|
|
335
|
+
const flag = s.stale ? ` ⚠ STALE${suffix}` : s.incomplete ? ` ⚠ INCOMPLETE${suffix}` : s.volatileForward ? ` ⚠ VOLATILE${suffix}` : s.unresolvable ? ' ? unresolvable' : '';
|
|
332
336
|
lines.push(` ${s.name}${s.active ? '' : ' (shadowed)'}: ${s.shimPath} → ${ver}${flag}`);
|
|
333
337
|
}
|
|
334
338
|
if (w.mismatch) {
|