greprag 5.69.0 → 5.69.2
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/codex-coordinate.d.ts +46 -0
- package/dist/commands/codex-coordinate.js +257 -0
- package/dist/commands/codex-coordinate.js.map +1 -0
- package/dist/commands/collision-check.d.ts +1 -1
- package/dist/commands/collision-check.js +10 -3
- package/dist/commands/collision-check.js.map +1 -1
- package/dist/commands/coordinate-gate.d.ts +5 -4
- package/dist/commands/coordinate-gate.js +43 -8
- package/dist/commands/coordinate-gate.js.map +1 -1
- package/dist/commands/inbox-primer-reminder.js +3 -3
- package/dist/commands/inbox-primer-reminder.js.map +1 -1
- package/dist/commands/init.js +21 -3
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/mechanic-spawn.js +1 -1
- package/dist/commands/mechanic-spawn.js.map +1 -1
- package/dist/commands/status.d.ts +1 -0
- package/dist/commands/status.js +3 -1
- package/dist/commands/status.js.map +1 -1
- package/dist/hook.js +68 -18
- package/dist/hook.js.map +1 -1
- package/dist/index.js +17 -7
- package/dist/index.js.map +1 -1
- package/dist/opencode-plugin.bundle.js +44 -9
- package/package.json +1 -1
- package/skill/commander/SKILL.md +2 -2
- package/skill/greprag/SKILL.md +2 -2
- package/skill/templates/codex-chip-spawn.md +1 -1
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/** Codex merge/deploy coordination evidence.
|
|
2
|
+
*
|
|
3
|
+
* Codex's native task roster is available to the agent through codex_app tools,
|
|
4
|
+
* not to a shell hook. The PreToolUse gate therefore opens an artifact-bound
|
|
5
|
+
* coordination request; the agent performs the native + cross-harness scan,
|
|
6
|
+
* waits for real peer replies, and attests the completed conference. The gate
|
|
7
|
+
* accepts only evidence for the current committed artifact and action kind.
|
|
8
|
+
* adr: adr/codex-coordinate-gate.md */
|
|
9
|
+
import type { CoordinateTrigger } from './coordinate-gate';
|
|
10
|
+
export interface CodexCoordinationRequest {
|
|
11
|
+
kind: CoordinateTrigger['kind'];
|
|
12
|
+
label: string;
|
|
13
|
+
artifactFingerprint: string;
|
|
14
|
+
actionFingerprint: string;
|
|
15
|
+
requestedAt: string;
|
|
16
|
+
watcherPeers: string[];
|
|
17
|
+
}
|
|
18
|
+
export interface CodexCoordinationAttestation extends CodexCoordinationRequest {
|
|
19
|
+
attestedAt: string;
|
|
20
|
+
peerRefs: string[];
|
|
21
|
+
noPeers: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface CodexCoordinationState {
|
|
24
|
+
version: number;
|
|
25
|
+
projectId: string;
|
|
26
|
+
sessionId: string;
|
|
27
|
+
pending?: CodexCoordinationRequest;
|
|
28
|
+
attestation?: CodexCoordinationAttestation;
|
|
29
|
+
}
|
|
30
|
+
export interface CodexCoordinationGateResult {
|
|
31
|
+
ready: boolean;
|
|
32
|
+
reason?: string;
|
|
33
|
+
}
|
|
34
|
+
export declare function codexCoordinationPath(projectId: string, sessionId: string): string;
|
|
35
|
+
export declare function readCodexCoordinationState(projectId: string, sessionId: string): CodexCoordinationState | null;
|
|
36
|
+
/** Open/refresh the request and enforce evidence for this exact artifact/action. */
|
|
37
|
+
export declare function evaluateCodexCoordinationGate(params: {
|
|
38
|
+
projectId: string;
|
|
39
|
+
sessionId: string;
|
|
40
|
+
cwd: string;
|
|
41
|
+
trigger: CoordinateTrigger;
|
|
42
|
+
command: string;
|
|
43
|
+
watcherPeers: string[];
|
|
44
|
+
nowMs?: number;
|
|
45
|
+
}): CodexCoordinationGateResult;
|
|
46
|
+
export declare function runCoordinate(args: string[]): void;
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/** Codex merge/deploy coordination evidence.
|
|
3
|
+
*
|
|
4
|
+
* Codex's native task roster is available to the agent through codex_app tools,
|
|
5
|
+
* not to a shell hook. The PreToolUse gate therefore opens an artifact-bound
|
|
6
|
+
* coordination request; the agent performs the native + cross-harness scan,
|
|
7
|
+
* waits for real peer replies, and attests the completed conference. The gate
|
|
8
|
+
* accepts only evidence for the current committed artifact and action kind.
|
|
9
|
+
* adr: adr/codex-coordinate-gate.md */
|
|
10
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
13
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
14
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
15
|
+
}
|
|
16
|
+
Object.defineProperty(o, k2, desc);
|
|
17
|
+
}) : (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
o[k2] = m[k];
|
|
20
|
+
}));
|
|
21
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
22
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
23
|
+
}) : function(o, v) {
|
|
24
|
+
o["default"] = v;
|
|
25
|
+
});
|
|
26
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
27
|
+
var ownKeys = function(o) {
|
|
28
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
29
|
+
var ar = [];
|
|
30
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
31
|
+
return ar;
|
|
32
|
+
};
|
|
33
|
+
return ownKeys(o);
|
|
34
|
+
};
|
|
35
|
+
return function (mod) {
|
|
36
|
+
if (mod && mod.__esModule) return mod;
|
|
37
|
+
var result = {};
|
|
38
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
39
|
+
__setModuleDefault(result, mod);
|
|
40
|
+
return result;
|
|
41
|
+
};
|
|
42
|
+
})();
|
|
43
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
+
exports.codexCoordinationPath = codexCoordinationPath;
|
|
45
|
+
exports.readCodexCoordinationState = readCodexCoordinationState;
|
|
46
|
+
exports.evaluateCodexCoordinationGate = evaluateCodexCoordinationGate;
|
|
47
|
+
exports.runCoordinate = runCoordinate;
|
|
48
|
+
const fs = __importStar(require("fs"));
|
|
49
|
+
const path = __importStar(require("path"));
|
|
50
|
+
const crypto = __importStar(require("crypto"));
|
|
51
|
+
const project_anchor_1 = require("../project-anchor");
|
|
52
|
+
const procedure_run_1 = require("../procedure-run");
|
|
53
|
+
const proc_1 = require("../proc");
|
|
54
|
+
const session_id_1 = require("../session-id");
|
|
55
|
+
const EVIDENCE_VERSION = 1;
|
|
56
|
+
const MAX_EVIDENCE_AGE_MS = 10 * 60_000;
|
|
57
|
+
function stateDir() {
|
|
58
|
+
const home = process.env.HOME || process.env.USERPROFILE || '';
|
|
59
|
+
return path.join(home, '.greprag', 'state');
|
|
60
|
+
}
|
|
61
|
+
function safeId(value) {
|
|
62
|
+
return value.replace(/[^a-zA-Z0-9._-]+/g, '-');
|
|
63
|
+
}
|
|
64
|
+
function codexCoordinationPath(projectId, sessionId) {
|
|
65
|
+
return path.join(stateDir(), `codex-coordinate-${safeId(projectId)}-${safeId((0, session_id_1.truncateSessionId)(sessionId) || sessionId)}.json`);
|
|
66
|
+
}
|
|
67
|
+
function readCodexCoordinationState(projectId, sessionId) {
|
|
68
|
+
try {
|
|
69
|
+
const parsed = JSON.parse(fs.readFileSync(codexCoordinationPath(projectId, sessionId), 'utf8'));
|
|
70
|
+
if (parsed?.version !== EVIDENCE_VERSION || parsed.projectId !== projectId)
|
|
71
|
+
return null;
|
|
72
|
+
if (parsed.sessionId !== ((0, session_id_1.truncateSessionId)(sessionId) || sessionId))
|
|
73
|
+
return null;
|
|
74
|
+
return parsed;
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function writeCodexCoordinationState(state) {
|
|
81
|
+
const file = codexCoordinationPath(state.projectId, state.sessionId);
|
|
82
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
83
|
+
const tmp = `${file}.${process.pid}.tmp`;
|
|
84
|
+
fs.writeFileSync(tmp, JSON.stringify(state, null, 2) + '\n');
|
|
85
|
+
fs.renameSync(tmp, file);
|
|
86
|
+
}
|
|
87
|
+
function unique(values) {
|
|
88
|
+
return [...new Set(values.map(value => value.trim()).filter(Boolean))];
|
|
89
|
+
}
|
|
90
|
+
function isCommittedArtifact(cwd) {
|
|
91
|
+
try {
|
|
92
|
+
(0, proc_1.safeExecFileSync)('git', ['rev-parse', '--verify', 'HEAD'], {
|
|
93
|
+
cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'],
|
|
94
|
+
});
|
|
95
|
+
return (0, proc_1.safeExecFileSync)('git', ['status', '--porcelain=v1', '--untracked-files=normal'], {
|
|
96
|
+
cwd, encoding: 'utf8',
|
|
97
|
+
}).trim() === '';
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function commandFingerprint(command) {
|
|
104
|
+
return crypto.createHash('sha256').update(command.trim()).digest('hex');
|
|
105
|
+
}
|
|
106
|
+
function refMatches(peerRef, watcherShort) {
|
|
107
|
+
const ref = peerRef.toLowerCase();
|
|
108
|
+
const short = watcherShort.toLowerCase();
|
|
109
|
+
return ref === short || ref.startsWith(`${short}-`) || ref.startsWith(short);
|
|
110
|
+
}
|
|
111
|
+
function missingWatcherPeers(attestation, watcherPeers) {
|
|
112
|
+
return watcherPeers.filter(short => !attestation.peerRefs.some(ref => refMatches(ref, short)));
|
|
113
|
+
}
|
|
114
|
+
function coordinationInstructions(trigger, watcherPeers) {
|
|
115
|
+
const watcherNote = watcherPeers.length
|
|
116
|
+
? ` Cross-harness peers currently live here: ${watcherPeers.join(', ')}.`
|
|
117
|
+
: '';
|
|
118
|
+
return [
|
|
119
|
+
`CODEX COORDINATION REQUIRED before ${trigger.label}.`,
|
|
120
|
+
'The shipping artifact must be committed before review.',
|
|
121
|
+
'Run codex_app.list_threads and identify every ACTIVE task in this repository.',
|
|
122
|
+
'Also run `greprag inbox watchers --json` for Claude Code/OpenCode peers.',
|
|
123
|
+
'Message each peer with the commit, branch, files, and intended merge/deploy; wait for each actual reply and resolve objections.',
|
|
124
|
+
'Then record the completed conference with `greprag coordinate attest --peer <thread-or-session-id>` (repeat --peer), or `greprag coordinate attest --none` only when BOTH rosters are empty.',
|
|
125
|
+
`Retry ${trigger.label}; evidence is bound to this committed artifact and action.`,
|
|
126
|
+
].join(' ') + watcherNote;
|
|
127
|
+
}
|
|
128
|
+
/** Open/refresh the request and enforce evidence for this exact artifact/action. */
|
|
129
|
+
function evaluateCodexCoordinationGate(params) {
|
|
130
|
+
if (!isCommittedArtifact(params.cwd)) {
|
|
131
|
+
return {
|
|
132
|
+
ready: false,
|
|
133
|
+
reason: `COMMIT REQUIRED before ${params.trigger.label}. Commit the coherent artifact, then retry so peer review binds to immutable work.`,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
const fingerprint = (0, procedure_run_1.currentArtifactFingerprint)(params.cwd);
|
|
137
|
+
if (!fingerprint) {
|
|
138
|
+
return { ready: false, reason: `Cannot fingerprint the committed artifact before ${params.trigger.label}.` };
|
|
139
|
+
}
|
|
140
|
+
const watcherPeers = unique(params.watcherPeers);
|
|
141
|
+
const actionFingerprint = commandFingerprint(params.command);
|
|
142
|
+
const state = readCodexCoordinationState(params.projectId, params.sessionId);
|
|
143
|
+
const attestation = state?.attestation;
|
|
144
|
+
const nowMs = params.nowMs ?? Date.now();
|
|
145
|
+
const ageMs = attestation ? nowMs - Date.parse(attestation.attestedAt) : Number.POSITIVE_INFINITY;
|
|
146
|
+
const missing = attestation ? missingWatcherPeers(attestation, watcherPeers) : watcherPeers;
|
|
147
|
+
const matches = !!attestation
|
|
148
|
+
&& attestation.kind === params.trigger.kind
|
|
149
|
+
&& attestation.label === params.trigger.label
|
|
150
|
+
&& attestation.actionFingerprint === actionFingerprint
|
|
151
|
+
&& attestation.artifactFingerprint === fingerprint
|
|
152
|
+
&& Number.isFinite(ageMs)
|
|
153
|
+
&& ageMs >= 0
|
|
154
|
+
&& ageMs <= MAX_EVIDENCE_AGE_MS
|
|
155
|
+
&& missing.length === 0
|
|
156
|
+
&& (!attestation.noPeers || watcherPeers.length === 0);
|
|
157
|
+
if (matches)
|
|
158
|
+
return { ready: true };
|
|
159
|
+
const pending = {
|
|
160
|
+
kind: params.trigger.kind,
|
|
161
|
+
label: params.trigger.label,
|
|
162
|
+
artifactFingerprint: fingerprint,
|
|
163
|
+
actionFingerprint,
|
|
164
|
+
requestedAt: new Date(nowMs).toISOString(),
|
|
165
|
+
watcherPeers,
|
|
166
|
+
};
|
|
167
|
+
writeCodexCoordinationState({
|
|
168
|
+
version: EVIDENCE_VERSION,
|
|
169
|
+
projectId: params.projectId,
|
|
170
|
+
sessionId: (0, session_id_1.truncateSessionId)(params.sessionId) || params.sessionId,
|
|
171
|
+
pending,
|
|
172
|
+
...(attestation ? { attestation } : {}),
|
|
173
|
+
});
|
|
174
|
+
const suffix = missing.length
|
|
175
|
+
? ` Missing current cross-harness peer evidence: ${missing.join(', ')}.`
|
|
176
|
+
: '';
|
|
177
|
+
return { ready: false, reason: coordinationInstructions(params.trigger, watcherPeers) + suffix };
|
|
178
|
+
}
|
|
179
|
+
function flagValues(args, flag) {
|
|
180
|
+
const values = [];
|
|
181
|
+
for (let i = 0; i < args.length; i++) {
|
|
182
|
+
if (args[i] === flag && args[i + 1])
|
|
183
|
+
values.push(args[++i]);
|
|
184
|
+
}
|
|
185
|
+
return values;
|
|
186
|
+
}
|
|
187
|
+
function flagValue(args, flag) {
|
|
188
|
+
return flagValues(args, flag)[0] || null;
|
|
189
|
+
}
|
|
190
|
+
function help() {
|
|
191
|
+
return `greprag coordinate — Codex shipping coordination evidence
|
|
192
|
+
|
|
193
|
+
greprag coordinate attest --peer <thread-or-session-id> [--peer <id> ...]
|
|
194
|
+
greprag coordinate attest --none
|
|
195
|
+
greprag coordinate status
|
|
196
|
+
|
|
197
|
+
Attest only after checking native Codex tasks plus GrepRAG watchers and receiving
|
|
198
|
+
real replies from every live same-repo peer. Evidence is scoped to the pending
|
|
199
|
+
merge/push/deploy action and current committed artifact.`;
|
|
200
|
+
}
|
|
201
|
+
function runCoordinate(args) {
|
|
202
|
+
const command = args[0];
|
|
203
|
+
if (!command || command === 'help' || args.includes('--help') || args.includes('-h')) {
|
|
204
|
+
console.log(help());
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
const sessionId = flagValue(args, '--session') || (0, session_id_1.readSessionEnv)();
|
|
208
|
+
if (!sessionId)
|
|
209
|
+
throw new Error('No Codex session id. Run inside Codex or pass --session <id>.');
|
|
210
|
+
const anchor = (0, project_anchor_1.readAnchor)(process.cwd());
|
|
211
|
+
if (!anchor.projectId)
|
|
212
|
+
throw new Error('No GrepRAG project anchor for this repository.');
|
|
213
|
+
const state = readCodexCoordinationState(anchor.projectId, sessionId);
|
|
214
|
+
if (command === 'status') {
|
|
215
|
+
console.log(JSON.stringify(state || {
|
|
216
|
+
version: EVIDENCE_VERSION,
|
|
217
|
+
projectId: anchor.projectId,
|
|
218
|
+
sessionId: (0, session_id_1.truncateSessionId)(sessionId) || sessionId,
|
|
219
|
+
pending: null,
|
|
220
|
+
attestation: null,
|
|
221
|
+
}, null, 2));
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
if (command !== 'attest')
|
|
225
|
+
throw new Error(`Unknown coordinate command: ${command}`);
|
|
226
|
+
if (!state?.pending)
|
|
227
|
+
throw new Error('No pending Codex coordination gate. Retry the merge/deploy command first.');
|
|
228
|
+
if (!isCommittedArtifact(process.cwd()))
|
|
229
|
+
throw new Error('Commit the current work before recording peer review.');
|
|
230
|
+
const fingerprint = (0, procedure_run_1.currentArtifactFingerprint)(process.cwd());
|
|
231
|
+
if (!fingerprint || fingerprint !== state.pending.artifactFingerprint) {
|
|
232
|
+
throw new Error('The artifact changed after the gate opened. Retry the merge/deploy command, then review the current artifact.');
|
|
233
|
+
}
|
|
234
|
+
const peers = unique(flagValues(args, '--peer'));
|
|
235
|
+
const noPeers = args.includes('--none');
|
|
236
|
+
if (noPeers === (peers.length > 0)) {
|
|
237
|
+
throw new Error('Choose exactly one: repeat --peer <id>, or use --none when both peer rosters are empty.');
|
|
238
|
+
}
|
|
239
|
+
if (noPeers && state.pending.watcherPeers.length > 0) {
|
|
240
|
+
throw new Error(`Cannot attest --none; cross-harness peers are live: ${state.pending.watcherPeers.join(', ')}.`);
|
|
241
|
+
}
|
|
242
|
+
const missing = state.pending.watcherPeers.filter(short => !peers.some(ref => refMatches(ref, short)));
|
|
243
|
+
if (missing.length) {
|
|
244
|
+
throw new Error(`Attestation is missing live cross-harness peers: ${missing.join(', ')}.`);
|
|
245
|
+
}
|
|
246
|
+
const attestation = {
|
|
247
|
+
...state.pending,
|
|
248
|
+
attestedAt: new Date().toISOString(),
|
|
249
|
+
peerRefs: peers,
|
|
250
|
+
noPeers,
|
|
251
|
+
};
|
|
252
|
+
writeCodexCoordinationState({ ...state, attestation });
|
|
253
|
+
console.log(noPeers
|
|
254
|
+
? `Recorded no-peer coordination scan for ${state.pending.label}.`
|
|
255
|
+
: `Recorded peer conferral for ${state.pending.label}: ${peers.join(', ')}.`);
|
|
256
|
+
}
|
|
257
|
+
//# sourceMappingURL=codex-coordinate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-coordinate.js","sourceRoot":"","sources":["../../src/commands/codex-coordinate.ts"],"names":[],"mappings":"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"}
|
|
@@ -92,7 +92,7 @@ export declare function readAnnounced(short: string): string[];
|
|
|
92
92
|
export declare function writeAnnounced(short: string, announced: string[]): void;
|
|
93
93
|
/** Fetch the tenant's live watcher registry. Best-effort: any failure (network,
|
|
94
94
|
* non-200, malformed) returns [] so a collision check never blocks or throws. */
|
|
95
|
-
export declare function fetchTenantWatchers(apiUrl: string, apiKey: string): Promise<WatcherRow[]>;
|
|
95
|
+
export declare function fetchTenantWatchers(apiUrl: string, apiKey: string, timeoutMs?: number): Promise<WatcherRow[]>;
|
|
96
96
|
export interface CollisionCheckOptions {
|
|
97
97
|
short: string;
|
|
98
98
|
projectId: string | null;
|
|
@@ -123,7 +123,7 @@ function buildCollisionDirective(peers, myShort, alias) {
|
|
|
123
123
|
return (`COLLISION DETECTED — ${peers.length} other live session${plural} working in this same repo right now:\n`
|
|
124
124
|
+ lines.join('\n') + '\n'
|
|
125
125
|
+ `Coordinate BEFORE touching shared files: (1) message each peer now with a contextual heads-up — `
|
|
126
|
-
+ `Codex peers: use \`codex_app.list_threads\`
|
|
126
|
+
+ `Codex peers: use \`codex_app.list_threads\` to find the task and its repo/workspace, then \`codex_app.send_message_to_thread\` to send the heads-up; `
|
|
127
127
|
+ `GrepRAG watcher/cross-harness peers: \`greprag send "…what you're about to touch…" --to ${handle}@greprag.com/<their-8hex> --from-session ${myShort}\` `
|
|
128
128
|
+ `(YOU compose and send it — this is a notice, not an auto-send; watcher rows are not the Codex peer source of truth); `
|
|
129
129
|
+ `(2) do your code work in a worktree on its own branch (\`git worktree add .claude/worktrees/<slug> -b <branch>\`) `
|
|
@@ -220,10 +220,14 @@ function writeAnnounced(short, announced) {
|
|
|
220
220
|
}
|
|
221
221
|
/** Fetch the tenant's live watcher registry. Best-effort: any failure (network,
|
|
222
222
|
* non-200, malformed) returns [] so a collision check never blocks or throws. */
|
|
223
|
-
async function fetchTenantWatchers(apiUrl, apiKey) {
|
|
223
|
+
async function fetchTenantWatchers(apiUrl, apiKey, timeoutMs = 3_000) {
|
|
224
|
+
const controller = new AbortController();
|
|
225
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
224
226
|
try {
|
|
225
227
|
const url = `${apiUrl.replace(/\/+$/, '')}/v1/inbox/watchers`;
|
|
226
|
-
const res = await fetch(url, {
|
|
228
|
+
const res = await fetch(url, {
|
|
229
|
+
headers: { Authorization: `Bearer ${apiKey}` }, signal: controller.signal,
|
|
230
|
+
});
|
|
227
231
|
if (!res.ok)
|
|
228
232
|
return [];
|
|
229
233
|
const data = await res.json();
|
|
@@ -232,6 +236,9 @@ async function fetchTenantWatchers(apiUrl, apiKey) {
|
|
|
232
236
|
catch {
|
|
233
237
|
return [];
|
|
234
238
|
}
|
|
239
|
+
finally {
|
|
240
|
+
clearTimeout(timer);
|
|
241
|
+
}
|
|
235
242
|
}
|
|
236
243
|
/** Orchestrate one collision check. Returns the text to inject, or null. Combines
|
|
237
244
|
* TWO independent signals over a SINGLE watcher read:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collision-check.js","sourceRoot":"","sources":["../../src/commands/collision-check.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;2DAyB2D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4C3D,4CAcC;AAID,kCAOC;AAID,0DAgBC;AAcD,kDAgBC;AAKD,gDAOC;AAKD,oCAOC;AA8BD,gDAQC;AAID,kDAOC;AAGD,sCAEC;AAGD,wCAEC;AAID,
|
|
1
|
+
{"version":3,"file":"collision-check.js","sourceRoot":"","sources":["../../src/commands/collision-check.ts"],"names":[],"mappings":"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"}
|
|
@@ -25,10 +25,11 @@
|
|
|
25
25
|
* NO DEDUP: every fire does a fresh read. Unlike the SessionStart roster (which
|
|
26
26
|
* dedups to stay quiet), the merge gate must reflect live truth each time.
|
|
27
27
|
*
|
|
28
|
-
* EFFECT is the adapter's choice, not the eval's:
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* The eval below only produces
|
|
28
|
+
* EFFECT is the adapter's choice, not the eval's: Claude/OpenCode inject the
|
|
29
|
+
* fresh roster as context; Codex denies until artifact-bound conferral evidence
|
|
30
|
+
* exists because Codex does not support a permission `ask` decision. An
|
|
31
|
+
* ingress-source wrapper would inject instead. The eval below only produces
|
|
32
|
+
* the message.
|
|
32
33
|
*
|
|
33
34
|
* Shared-file Write was CONSIDERED (chip spec) but deferred: classifying a
|
|
34
35
|
* write as "shared" is ambiguous, and a fresh network read on every Write/Edit
|
|
@@ -26,10 +26,11 @@
|
|
|
26
26
|
* NO DEDUP: every fire does a fresh read. Unlike the SessionStart roster (which
|
|
27
27
|
* dedups to stay quiet), the merge gate must reflect live truth each time.
|
|
28
28
|
*
|
|
29
|
-
* EFFECT is the adapter's choice, not the eval's:
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* The eval below only produces
|
|
29
|
+
* EFFECT is the adapter's choice, not the eval's: Claude/OpenCode inject the
|
|
30
|
+
* fresh roster as context; Codex denies until artifact-bound conferral evidence
|
|
31
|
+
* exists because Codex does not support a permission `ask` decision. An
|
|
32
|
+
* ingress-source wrapper would inject instead. The eval below only produces
|
|
33
|
+
* the message.
|
|
33
34
|
*
|
|
34
35
|
* Shared-file Write was CONSIDERED (chip spec) but deferred: classifying a
|
|
35
36
|
* write as "shared" is ambiguous, and a fresh network read on every Write/Edit
|
|
@@ -46,10 +47,7 @@ const collision_check_1 = require("./collision-check");
|
|
|
46
47
|
/** Risky shared-state command signatures. Each segment of a (possibly chained)
|
|
47
48
|
* Bash command is tested against these. SPECIFIC to the Bash/PreToolUse source. */
|
|
48
49
|
const RISKY_PATTERNS = [
|
|
49
|
-
{ kind: 'merge', label: 'git merge', re: /^git\s+merge\b/ },
|
|
50
|
-
{ kind: 'merge', label: 'git rebase', re: /^git\s+rebase\b/ }, // rewrites shared history
|
|
51
50
|
{ kind: 'merge', label: 'gh pr merge', re: /^gh\s+pr\s+merge\b/ },
|
|
52
|
-
{ kind: 'push', label: 'git push', re: /^git\s+push\b/ }, // incl. --force
|
|
53
51
|
{ kind: 'deploy', label: 'wrangler deploy', re: /^(?:npx\s+)?wrangler\s+deploy\b/ },
|
|
54
52
|
{ kind: 'deploy', label: 'npm run deploy', re: /^npm\s+run\s+deploy\b/ },
|
|
55
53
|
{ kind: 'deploy', label: 'npm publish', re: /^npm\s+publish\b/ },
|
|
@@ -59,6 +57,40 @@ const RISKY_PATTERNS = [
|
|
|
59
57
|
function commandSegments(command) {
|
|
60
58
|
return command.split(/&&|\|\||;|\n|\|/).map(s => s.trim()).filter(Boolean);
|
|
61
59
|
}
|
|
60
|
+
/** Parse enough shell words to locate a git subcommand after global options.
|
|
61
|
+
* Codex worktrees routinely use `git -C <main> merge ...`; matching only
|
|
62
|
+
* `^git merge` left the most common Codex landing shape outside the gate. */
|
|
63
|
+
function shellWords(segment) {
|
|
64
|
+
const matches = segment.match(/"(?:\\.|[^"])*"|'[^']*'|[^\s]+/g) || [];
|
|
65
|
+
return matches.map(word => {
|
|
66
|
+
if ((word.startsWith('"') && word.endsWith('"'))
|
|
67
|
+
|| (word.startsWith("'") && word.endsWith("'"))) {
|
|
68
|
+
return word.slice(1, -1);
|
|
69
|
+
}
|
|
70
|
+
return word;
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
function classifyGit(tokens) {
|
|
74
|
+
if (tokens[0] !== 'git')
|
|
75
|
+
return null;
|
|
76
|
+
let i = 1;
|
|
77
|
+
const optionsWithValue = new Set([
|
|
78
|
+
'-C', '-c', '--exec-path', '--git-dir', '--work-tree', '--namespace', '--super-prefix', '--config-env',
|
|
79
|
+
]);
|
|
80
|
+
while (i < tokens.length && tokens[i].startsWith('-')) {
|
|
81
|
+
const option = tokens[i++];
|
|
82
|
+
if (optionsWithValue.has(option) && i < tokens.length)
|
|
83
|
+
i++;
|
|
84
|
+
}
|
|
85
|
+
const subcommand = tokens[i];
|
|
86
|
+
if (subcommand === 'merge')
|
|
87
|
+
return { kind: 'merge', label: 'git merge' };
|
|
88
|
+
if (subcommand === 'rebase')
|
|
89
|
+
return { kind: 'merge', label: 'git rebase' };
|
|
90
|
+
if (subcommand === 'push')
|
|
91
|
+
return { kind: 'push', label: 'git push' };
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
62
94
|
/** Classify a Bash command into a risky-action trigger, or null. PURE. Matches
|
|
63
95
|
* the FIRST risky segment (a chained command fires on whichever risky verb
|
|
64
96
|
* appears first). */
|
|
@@ -66,6 +98,9 @@ function classifyRiskyCommand(command) {
|
|
|
66
98
|
if (!command)
|
|
67
99
|
return null;
|
|
68
100
|
for (const seg of commandSegments(command)) {
|
|
101
|
+
const git = classifyGit(shellWords(seg));
|
|
102
|
+
if (git)
|
|
103
|
+
return git;
|
|
69
104
|
for (const p of RISKY_PATTERNS) {
|
|
70
105
|
if (p.re.test(seg))
|
|
71
106
|
return { kind: p.kind, label: p.label };
|
|
@@ -91,7 +126,7 @@ function buildCoordinateDirective(trigger, peers, myShort, alias) {
|
|
|
91
126
|
const plural = peers.length === 1 ? '' : 's';
|
|
92
127
|
const list = peers.map(p => p.short).join(', ');
|
|
93
128
|
return (`COORDINATE before ${trigger.label}: ${peers.length} peer${plural} live in this repo (${list}). `
|
|
94
|
-
+ `Ping before proceeding. Codex peers: use codex_app.list_threads
|
|
129
|
+
+ `Ping before proceeding. Codex peers: use codex_app.list_threads and codex_app.send_message_to_thread. `
|
|
95
130
|
+ `GrepRAG watcher/cross-harness peers: greprag send "heads up, about to ${trigger.label}" `
|
|
96
131
|
+ `--to ${handle}@greprag.com/<8hex> --from-session ${myShort}`);
|
|
97
132
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coordinate-gate.js","sourceRoot":"","sources":["../../src/commands/coordinate-gate.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"coordinate-gate.js","sourceRoot":"","sources":["../../src/commands/coordinate-gate.ts"],"names":[],"mappings":"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"}
|
|
@@ -40,12 +40,12 @@ function buildInboxPrimer(env) {
|
|
|
40
40
|
// "ToolSearch select:Monitor" is unactionable there (neither tool exists) and an
|
|
41
41
|
// un-followable alarm decays into banner-blindness for the announces around it.
|
|
42
42
|
codex
|
|
43
|
-
? '[CODEX INBOX — greprag is your agent-to-agent mesh. Codex-to-Codex:
|
|
43
|
+
? '[CODEX INBOX — greprag is your agent-to-agent mesh. Codex-to-Codex: discover tasks and their repo/workspace with `codex_app.list_threads`, then coordinate with `codex_app.send_message_to_thread`. Reaching ANY non-Codex peer (Claude Code / opencode / another tenant\'s agent): `greprag send` IS the live primary path — native Codex messaging cannot reach them.]'
|
|
44
44
|
: opencode
|
|
45
45
|
? '[OPENCODE INBOX — greprag is your agent-to-agent mesh. Inbound delivery is AUTOMATIC here: the greprag plugin arms a relay for this session (nothing to arm or re-arm) and inbound peer messages arrive as injected turns.]'
|
|
46
46
|
: '[⚠ ARM YOUR INBOX WATCHER NOW — you are UNREACHABLE until you do. Peers are live in your mesh trying to coordinate with this session, and the operator can DM you — but they reach you ONLY while armed. Unarmed, you are invisible and their messages silently pile up. The watcher can DROP ANYTIME (crash / reload / OOM) — EVERY turn you are flagged unarmed you MUST re-arm, or coordination breaks.]',
|
|
47
47
|
codex
|
|
48
|
-
? 'CODEX: Native Codex tools are the source of truth: `codex_app.list_threads`
|
|
48
|
+
? 'CODEX: Native Codex tools are the source of truth: `codex_app.list_threads` discovers tasks plus their repo/workspace, and `codex_app.send_message_to_thread` handles Codex-to-Codex coordination. GrepRAG inbox rows for Codex surface through turn hooks only: SessionStart `drain`, UserPromptSubmit `codex-notify`, and PostToolUse `codex-inbox`. There is no Codex startup watcher to install. If hooks do not fire, open Codex Desktop Settings -> Settings -> Hooks, trust the GrepRAG commands, start a fresh Codex session, then drain what is waiting: `greprag inbox`.'
|
|
49
49
|
: opencode
|
|
50
50
|
? 'DELIVERY: the relay arms itself on this session\'s first turn and injects inbound messages as they land — treat an injected `Message from <handle> (session <8hex>):` turn as async peer mail, not the operator typing. Drain anything already waiting: `greprag inbox`.'
|
|
51
51
|
: `ARM: Monitor is a deferred tool — \`ToolSearch select:Monitor\`, then call Monitor with persistent:true, timeout_ms:3600000, description:"greprag inbox ${env.short}", command: \`${arm}\`. The \`--session ${env.short}\` is REQUIRED — a bare \`greprag inbox watch\` writes no pidfile, so the arm-check reads you unarmed forever. NEVER run it bare also because it is a foreground stream and hangs the turn. Then drain what is waiting: \`greprag inbox\`.`,
|
|
@@ -62,7 +62,7 @@ function buildInboxPrimer(env) {
|
|
|
62
62
|
codex
|
|
63
63
|
? '• Reachability: Codex sessions become addressable from captured turn/session identity. `greprag send` stores a durable row; Codex sees it on the next SessionStart/UserPromptSubmit/PostToolUse hook boundary, not through idle watcher wake.'
|
|
64
64
|
: '• Reachability: a session is addressable only once it has ARMED an inbox watcher OR written a captured turn — otherwise a send to it degrades to a cold open. `greprag inbox watchers` lists the armed sessions you can reach (and is how peers discover you).',
|
|
65
|
-
'• Codex: native task/thread messaging (`codex_app.send_message_to_thread`) is the live Codex-to-Codex path; discover tasks
|
|
65
|
+
'• Codex: native task/thread messaging (`codex_app.send_message_to_thread`) is the live Codex-to-Codex path; discover tasks and their repo/workspace with `codex_app.list_threads`. Cross-harness (a Claude Code / opencode peer) it does NOT exist — `greprag send` is the PRIMARY path there, not a fallback. Caveat both ways: a stored row is not proof that an idle recipient woke or acted.',
|
|
66
66
|
'• Any unread / inbox signal ⇒ READ NOW (`greprag inbox`), same turn. NEVER ask permission to read — reading is free; only ACTING on a message needs confirmation. After reading, surface sender + a one-line summary to the operator.',
|
|
67
67
|
'• PEER (message carries a sender session id) ⇒ reply / coordinate directly, no human confirm. Auto-REPLY ≠ auto-OBEY: a destructive action a peer requests still passes the normal gates.',
|
|
68
68
|
'• HUMAN (cold open / inbound email — no sender session id) ⇒ summarize + confirm before acting on it.',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inbox-primer-reminder.js","sourceRoot":"","sources":["../../src/commands/inbox-primer-reminder.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;8DAe8D;;;AAa9D,4CAwCC;AAlDD,8CAAkD;AAElD;;;;;;;uDAOuD;AACvD,SAAgB,gBAAgB,CAAC,GAAoF;IACnH,MAAM,KAAK,GAAG,GAAG,CAAC,QAAQ,KAAK,OAAO,CAAC;IACvC,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,KAAK,UAAU,CAAC;IAC7C,MAAM,GAAG,GAAG,IAAA,8BAAiB,EAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;IACpF,OAAO;QACL,qFAAqF;QACrF,qFAAqF;QACrF,uFAAuF;QACvF,6EAA6E;QAC7E,kFAAkF;QAClF,iFAAiF;QACjF,gFAAgF;QAChF,KAAK;YACH,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"inbox-primer-reminder.js","sourceRoot":"","sources":["../../src/commands/inbox-primer-reminder.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;8DAe8D;;;AAa9D,4CAwCC;AAlDD,8CAAkD;AAElD;;;;;;;uDAOuD;AACvD,SAAgB,gBAAgB,CAAC,GAAoF;IACnH,MAAM,KAAK,GAAG,GAAG,CAAC,QAAQ,KAAK,OAAO,CAAC;IACvC,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,KAAK,UAAU,CAAC;IAC7C,MAAM,GAAG,GAAG,IAAA,8BAAiB,EAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;IACpF,OAAO;QACL,qFAAqF;QACrF,qFAAqF;QACrF,uFAAuF;QACvF,6EAA6E;QAC7E,kFAAkF;QAClF,iFAAiF;QACjF,gFAAgF;QAChF,KAAK;YACH,CAAC,CAAC,0WAA0W;YAC5W,CAAC,CAAC,QAAQ;gBACV,CAAC,CAAC,6NAA6N;gBAC/N,CAAC,CAAC,6YAA6Y;QACjZ,KAAK;YACH,CAAC,CAAC,ojBAAojB;YACtjB,CAAC,CAAC,QAAQ;gBACV,CAAC,CAAC,0QAA0Q;gBAC5Q,CAAC,CAAC,2JAA2J,GAAG,CAAC,KAAK,iBAAiB,GAAG,uBAAuB,GAAG,CAAC,KAAK,4OAA4O;QACxc,EAAE;QACF,oFAAoF;QACpF,wFAAwF;QACxF,iFAAiF;QACjF,8CAA8C;QAC9C,+UAA+U;QAC/U,KAAK;YACH,CAAC,CAAC,kGAAkG,GAAG,CAAC,KAAK,uRAAuR;YACpY,CAAC,CAAC,0FAA0F,GAAG,CAAC,KAAK,6MAA6M;QACpT,6RAA6R;QAC7R,KAAK;YACH,CAAC,CAAC,+OAA+O;YACjP,CAAC,CAAC,gQAAgQ;QACpQ,kYAAkY;QAClY,uOAAuO;QACvO,2LAA2L;QAC3L,uGAAuG;KACxG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAEY,QAAA,iBAAiB,GAAmB;IAC/C,EAAE,EAAE,cAAc;IAClB,MAAM,EAAE,CAAC,IAAiB,EAAa,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,uBAAuB;IACvF,QAAQ,EAAE,CAAC,GAAgB,EAAiB,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC;IACpE,QAAQ,EAAE,GAAkB,EAAE,CAAC,IAAI;CACpC,CAAC"}
|
package/dist/commands/init.js
CHANGED
|
@@ -1168,6 +1168,23 @@ function applyCodexHooks(config) {
|
|
|
1168
1168
|
config.hooks[spec.event].push(entry);
|
|
1169
1169
|
changes.push(`Added Codex ${spec.event} hook (${spec.label})`);
|
|
1170
1170
|
}
|
|
1171
|
+
// Codex shipping coordination — risky Bash actions are denied until the
|
|
1172
|
+
// current committed artifact has fresh native-task + cross-harness conferral
|
|
1173
|
+
// evidence. This is separate from codex-chip-hook because it applies to every
|
|
1174
|
+
// Codex task, not only managed chips. adr: adr/codex-coordinate-gate.md
|
|
1175
|
+
const coordinateGateHook = {
|
|
1176
|
+
matcher: 'Bash',
|
|
1177
|
+
hooks: [commandHook('codex-coordinate-gate', 10, 'Checking peer coordination')],
|
|
1178
|
+
};
|
|
1179
|
+
if (!hasGrepragHookWithMatcher(config.hooks.PreToolUse, 'codex-coordinate-gate', coordinateGateHook.matcher)) {
|
|
1180
|
+
if (!config.hooks.PreToolUse)
|
|
1181
|
+
config.hooks.PreToolUse = [];
|
|
1182
|
+
config.hooks.PreToolUse.push(coordinateGateHook);
|
|
1183
|
+
changes.push('Added Codex PreToolUse hook (shipping coordination gate)');
|
|
1184
|
+
}
|
|
1185
|
+
else {
|
|
1186
|
+
changes.push('Codex PreToolUse shipping coordination hook already configured (skipped)');
|
|
1187
|
+
}
|
|
1171
1188
|
const storeHook = {
|
|
1172
1189
|
matcher: '',
|
|
1173
1190
|
hooks: [commandHook('codex-store', 10, 'Storing GrepRAG turn')],
|
|
@@ -1212,6 +1229,7 @@ function normalizeCodexHookCommands(hooks) {
|
|
|
1212
1229
|
'codex-permission-context': { timeout: 3, statusMessage: 'Loading GrepRAG approval context' },
|
|
1213
1230
|
'codex-subagent-start': { timeout: 3, statusMessage: 'Recording GrepRAG subagent metadata' },
|
|
1214
1231
|
'codex-chip-hook': { timeout: 3, statusMessage: 'Enforcing Codex chip contract' },
|
|
1232
|
+
'codex-coordinate-gate': { timeout: 10, statusMessage: 'Checking peer coordination' },
|
|
1215
1233
|
'codex-store': { timeout: 10, statusMessage: 'Storing GrepRAG turn' },
|
|
1216
1234
|
};
|
|
1217
1235
|
let count = 0;
|
|
@@ -1536,8 +1554,8 @@ function applySettings(settings, apiKey) {
|
|
|
1536
1554
|
// Coordinate-GATE — cross-session coordination reflex (TIER 2). PreToolUse
|
|
1537
1555
|
// matcher `Bash`: on a risky shared-state action (git merge/push/deploy) the
|
|
1538
1556
|
// hook does a FRESH inbox-watchers read and, if another live session is working
|
|
1539
|
-
// in THIS repo,
|
|
1540
|
-
//
|
|
1557
|
+
// in THIS repo, injects coordination context before the irreversible action.
|
|
1558
|
+
// Non-risky Bash calls classify locally and cost no
|
|
1541
1559
|
// network. Pairs with the SessionStart collision-check (TIER 1 roster).
|
|
1542
1560
|
// docs/collision-schematic.md
|
|
1543
1561
|
const coordinateGateHook = {
|
|
@@ -1675,7 +1693,7 @@ function dedupeCodexHooks(hooks) {
|
|
|
1675
1693
|
* block, and skips (with a warning) anything the operator edited. */
|
|
1676
1694
|
const GREPRAG_CLI_BODY = `## greprag CLI (cross-project memory + async messaging)
|
|
1677
1695
|
\`/greprag\` walks setup + recall. Command map — \`greprag <cmd> --help\` for flags; reach for \`--help\` before guessing a subcommand:
|
|
1678
|
-
- \`inbox\` — read unread (auto-marks read); \`--peek\` · \`--all\` · \`--session <8hex>\` · \`--project <name>\`. (\`inbox watchers [--json]\` = armed GrepRAG/Claude/OpenCode/cross-harness sessions, each \`project · title · 8hex\`; Codex tasks
|
|
1696
|
+
- \`inbox\` — read unread (auto-marks read); \`--peek\` · \`--all\` · \`--session <8hex>\` · \`--project <name>\`. (\`inbox watchers [--json]\` = armed GrepRAG/Claude/OpenCode/cross-harness sessions, each \`project · title · 8hex\`; Codex tasks plus their repo/workspace come from \`codex_app.list_threads\`; \`inbox watch\` = the auto-armed live SSE listener, runs under **Monitor**)
|
|
1679
1697
|
- \`send "md" --to <handle>@greprag.com[/<8hex>]\` — bare handle = **cold open** (first contact when you don't know their session — lands in their inbox for a manual check; silent, no session wake, no operator ping); \`/<8hex>\` = a specific session (live if they're armed). **No project / broadcast targets** — to reach a non-Codex session it must be armed (\`inbox watch\`) or have a captured turn, else the send degrades to a cold open. \`greprag send\` is the durable cross-harness/fallback rail; Codex-to-Codex coordination uses \`codex_app.send_message_to_thread\`, and a real peer response is the only delivery proof. Discord DM: \`--to discord:<snowflake>\`. **This is internal cross-session messaging, NOT email** — it never reaches a real inbox.
|
|
1680
1698
|
- \`email send --to <real-addr> --from <handle>@greprag.com --subject "s" (--body "t" | --body-file <f|->)\` — sends a **REAL outbound SMTP email** from your greprag address to any recipient (\`--attach\`/\`--cc\`/\`--bcc\`/\`--html-file\` available). \`email pending\` · \`email pull\` = drain inbound. **Use this — not \`send\` — when the user says "email X".** The \`send\`-vs-\`email send\` collision is the trap: only \`email send\` is actual email.
|
|
1681
1699
|
- \`memory search "q"\` · \`memory recap\` (alias \`briefing\`) — search a topic/bug · session catch-up digest; narrative-pyramid tiers \`turns\`·\`hourly\`·\`daily\`·\`weekly\`·\`ships\` (commits/PRs/deploys), each \`--last N\` · \`--from/--to ISO\` · \`--project\`
|