greprag 5.49.9 → 5.49.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/commands/arm-reminder.d.ts +10 -3
- package/dist/commands/arm-reminder.js +18 -6
- package/dist/commands/arm-reminder.js.map +1 -1
- package/dist/commands/collision-check.d.ts +1 -2
- package/dist/commands/collision-check.js +1 -2
- package/dist/commands/collision-check.js.map +1 -1
- package/dist/commands/inbox-drain.d.ts +9 -10
- package/dist/commands/inbox-drain.js +9 -10
- package/dist/commands/inbox-drain.js.map +1 -1
- package/dist/commands/inbox-primer-reminder.d.ts +10 -5
- package/dist/commands/inbox-primer-reminder.js +35 -21
- package/dist/commands/inbox-primer-reminder.js.map +1 -1
- package/dist/commands/memory.js +70 -0
- package/dist/commands/memory.js.map +1 -1
- package/dist/commands/poll-registry.d.ts +52 -9
- package/dist/commands/poll-registry.js +176 -9
- package/dist/commands/poll-registry.js.map +1 -1
- package/dist/commands/procedure.d.ts +15 -0
- package/dist/commands/procedure.js +167 -0
- package/dist/commands/procedure.js.map +1 -0
- package/dist/commands/reminder-registry.d.ts +5 -0
- package/dist/commands/reminder-registry.js +7 -5
- package/dist/commands/reminder-registry.js.map +1 -1
- package/dist/commands/reminder-types.d.ts +7 -15
- package/dist/hook.js +30 -73
- package/dist/hook.js.map +1 -1
- package/dist/index.js +8 -12
- package/dist/index.js.map +1 -1
- package/dist/procedure.d.ts +88 -0
- package/dist/procedure.js +269 -0
- package/dist/procedure.js.map +1 -0
- package/package.json +1 -1
- package/dist/commands/checkpoint-reminder.d.ts +0 -14
- package/dist/commands/checkpoint-reminder.js +0 -50
- package/dist/commands/checkpoint-reminder.js.map +0 -1
- package/dist/commands/frontdesk-reminder.d.ts +0 -23
- package/dist/commands/frontdesk-reminder.js +0 -43
- package/dist/commands/frontdesk-reminder.js.map +0 -1
- package/dist/commands/inbox-poll.d.ts +0 -47
- package/dist/commands/inbox-poll.js +0 -261
- package/dist/commands/inbox-poll.js.map +0 -1
- package/dist/commands/inbox-spool.d.ts +0 -27
- package/dist/commands/inbox-spool.js +0 -151
- package/dist/commands/inbox-spool.js.map +0 -1
- package/dist/commands/lore.d.ts +0 -35
- package/dist/commands/lore.js +0 -504
- package/dist/commands/lore.js.map +0 -1
- package/dist/front-desk-mail.d.ts +0 -50
- package/dist/front-desk-mail.js +0 -206
- package/dist/front-desk-mail.js.map +0 -1
package/dist/commands/lore.d.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/** greprag lore — the Mechanic's per-project fix queue (back-compat alias).
|
|
2
|
-
*
|
|
3
|
-
* `greprag lore` is the deprecated alias for `greprag fix` (the canonical
|
|
4
|
-
* surface — friction → fix → repair, docs/mechanic.md). It backs both: the
|
|
5
|
-
* `fix` verb layer (commands/fix.ts) delegates here via runLore. Entries are
|
|
6
|
-
* project-specific emergent knowledge — discovered constraints, gotchas,
|
|
7
|
-
* tribal knowledge that drifts as the codebase evolves — plus raw smells
|
|
8
|
-
* (scope='smell'). Reviewed via /mechanic. Distinct from static project
|
|
9
|
-
* knowledge (CLAUDE.md / docs / code structure).
|
|
10
|
-
*
|
|
11
|
-
* Pull-based: agents seed fixes they wish a future spawned chip had known;
|
|
12
|
-
* future chips query the relevant scope at spawn time and skip the discovery
|
|
13
|
-
* they would otherwise repeat. All server work delegates to the fix service in
|
|
14
|
-
* @greprag/core; the CLI is a thin HTTP printer + project resolver.
|
|
15
|
-
*
|
|
16
|
-
* Server endpoints: canonical /v1/fix; this CLI still calls the /v1/lore alias
|
|
17
|
-
* (kept working server-side). Read responses carry `fix` / `lore` / `facts`
|
|
18
|
-
* keys — this CLI parses `lore` (falls back to `facts`). The kind=lore→kind=fix
|
|
19
|
-
* store rename landed in migration 056. adr: adr/lore-rename.md.
|
|
20
|
-
*
|
|
21
|
-
* Subcommands:
|
|
22
|
-
* add "<text>" --scope <S> [--project <name>] [--source-session <id>]
|
|
23
|
-
* smell "<text>" [--project <name>] raw signal for /mechanic to digest
|
|
24
|
-
* smells [--all] [--project <name>] the raw smell queue (interim: scope=smell);
|
|
25
|
-
* --all = tenant-wide census, project-annotated
|
|
26
|
-
* query [--scope <S>] [--query "<intent>"] [--project <name>]
|
|
27
|
-
* [--limit <N=10>] [--format markdown|json]
|
|
28
|
-
* list [--project <name>] [--format markdown|json]
|
|
29
|
-
* delete <nodeId> [--project <name>]
|
|
30
|
-
* scopes [--project <name>]
|
|
31
|
-
*
|
|
32
|
-
* Project resolution: without --project, uses the current cwd's project
|
|
33
|
-
* anchor (readAnchor). With --project <name>, hits /v1/inbox/projects to
|
|
34
|
-
* resolve name → projectId (case-insensitive). */
|
|
35
|
-
export declare function runLore(args: string[]): Promise<void>;
|
package/dist/commands/lore.js
DELETED
|
@@ -1,504 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// adr: adr/lore-rename.md
|
|
3
|
-
/** greprag lore — the Mechanic's per-project fix queue (back-compat alias).
|
|
4
|
-
*
|
|
5
|
-
* `greprag lore` is the deprecated alias for `greprag fix` (the canonical
|
|
6
|
-
* surface — friction → fix → repair, docs/mechanic.md). It backs both: the
|
|
7
|
-
* `fix` verb layer (commands/fix.ts) delegates here via runLore. Entries are
|
|
8
|
-
* project-specific emergent knowledge — discovered constraints, gotchas,
|
|
9
|
-
* tribal knowledge that drifts as the codebase evolves — plus raw smells
|
|
10
|
-
* (scope='smell'). Reviewed via /mechanic. Distinct from static project
|
|
11
|
-
* knowledge (CLAUDE.md / docs / code structure).
|
|
12
|
-
*
|
|
13
|
-
* Pull-based: agents seed fixes they wish a future spawned chip had known;
|
|
14
|
-
* future chips query the relevant scope at spawn time and skip the discovery
|
|
15
|
-
* they would otherwise repeat. All server work delegates to the fix service in
|
|
16
|
-
* @greprag/core; the CLI is a thin HTTP printer + project resolver.
|
|
17
|
-
*
|
|
18
|
-
* Server endpoints: canonical /v1/fix; this CLI still calls the /v1/lore alias
|
|
19
|
-
* (kept working server-side). Read responses carry `fix` / `lore` / `facts`
|
|
20
|
-
* keys — this CLI parses `lore` (falls back to `facts`). The kind=lore→kind=fix
|
|
21
|
-
* store rename landed in migration 056. adr: adr/lore-rename.md.
|
|
22
|
-
*
|
|
23
|
-
* Subcommands:
|
|
24
|
-
* add "<text>" --scope <S> [--project <name>] [--source-session <id>]
|
|
25
|
-
* smell "<text>" [--project <name>] raw signal for /mechanic to digest
|
|
26
|
-
* smells [--all] [--project <name>] the raw smell queue (interim: scope=smell);
|
|
27
|
-
* --all = tenant-wide census, project-annotated
|
|
28
|
-
* query [--scope <S>] [--query "<intent>"] [--project <name>]
|
|
29
|
-
* [--limit <N=10>] [--format markdown|json]
|
|
30
|
-
* list [--project <name>] [--format markdown|json]
|
|
31
|
-
* delete <nodeId> [--project <name>]
|
|
32
|
-
* scopes [--project <name>]
|
|
33
|
-
*
|
|
34
|
-
* Project resolution: without --project, uses the current cwd's project
|
|
35
|
-
* anchor (readAnchor). With --project <name>, hits /v1/inbox/projects to
|
|
36
|
-
* resolve name → projectId (case-insensitive). */
|
|
37
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
38
|
-
if (k2 === undefined) k2 = k;
|
|
39
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
40
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
41
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
42
|
-
}
|
|
43
|
-
Object.defineProperty(o, k2, desc);
|
|
44
|
-
}) : (function(o, m, k, k2) {
|
|
45
|
-
if (k2 === undefined) k2 = k;
|
|
46
|
-
o[k2] = m[k];
|
|
47
|
-
}));
|
|
48
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
49
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
50
|
-
}) : function(o, v) {
|
|
51
|
-
o["default"] = v;
|
|
52
|
-
});
|
|
53
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
54
|
-
var ownKeys = function(o) {
|
|
55
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
56
|
-
var ar = [];
|
|
57
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
58
|
-
return ar;
|
|
59
|
-
};
|
|
60
|
-
return ownKeys(o);
|
|
61
|
-
};
|
|
62
|
-
return function (mod) {
|
|
63
|
-
if (mod && mod.__esModule) return mod;
|
|
64
|
-
var result = {};
|
|
65
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
66
|
-
__setModuleDefault(result, mod);
|
|
67
|
-
return result;
|
|
68
|
-
};
|
|
69
|
-
})();
|
|
70
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
71
|
-
exports.runLore = runLore;
|
|
72
|
-
const fs = __importStar(require("fs"));
|
|
73
|
-
const path = __importStar(require("path"));
|
|
74
|
-
const project_anchor_1 = require("../project-anchor");
|
|
75
|
-
const API_URL_DEFAULT = 'https://api.greprag.com';
|
|
76
|
-
// Reserved scope for raw, undigested SMELLS (docs/lore-smell.md). Interim store:
|
|
77
|
-
// smells reuse the lore store under this scope until a true `kind=lore_smell`
|
|
78
|
-
// ships server-side. Durable readers (query/list/scopes) exclude it; only
|
|
79
|
-
// `lore smells` surfaces it. Migration later = move these rows to the new kind.
|
|
80
|
-
const SMELL_SCOPE = 'smell';
|
|
81
|
-
// ---------- Config / env (mirrors corpus.ts) ------------------------------
|
|
82
|
-
function loadEnvFile(filePath) {
|
|
83
|
-
try {
|
|
84
|
-
const content = fs.readFileSync(filePath, 'utf-8');
|
|
85
|
-
for (const line of content.split('\n')) {
|
|
86
|
-
const trimmed = line.trim();
|
|
87
|
-
if (!trimmed || trimmed.startsWith('#'))
|
|
88
|
-
continue;
|
|
89
|
-
const eqIdx = trimmed.indexOf('=');
|
|
90
|
-
if (eqIdx < 1)
|
|
91
|
-
continue;
|
|
92
|
-
const key = trimmed.slice(0, eqIdx).trim();
|
|
93
|
-
let value = trimmed.slice(eqIdx + 1).trim();
|
|
94
|
-
if ((value.startsWith('"') && value.endsWith('"')) ||
|
|
95
|
-
(value.startsWith("'") && value.endsWith("'"))) {
|
|
96
|
-
value = value.slice(1, -1);
|
|
97
|
-
}
|
|
98
|
-
if (!process.env[key])
|
|
99
|
-
process.env[key] = value;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
catch { /* file missing — fine */ }
|
|
103
|
-
}
|
|
104
|
-
function getConfig() {
|
|
105
|
-
const homeDir = process.env.HOME || process.env.USERPROFILE || '';
|
|
106
|
-
if (homeDir)
|
|
107
|
-
loadEnvFile(path.join(homeDir, '.greprag', '.env'));
|
|
108
|
-
if (!process.env.GREPRAG_API_KEY)
|
|
109
|
-
loadEnvFile(path.join(process.cwd(), '.env'));
|
|
110
|
-
return {
|
|
111
|
-
apiUrl: process.env.GREPRAG_API_URL || API_URL_DEFAULT,
|
|
112
|
-
apiKey: process.env.GREPRAG_API_KEY || '',
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
async function apiCall(url, apiKey, body) {
|
|
116
|
-
const res = await fetch(url, {
|
|
117
|
-
method: 'POST',
|
|
118
|
-
headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
|
|
119
|
-
body: JSON.stringify(body),
|
|
120
|
-
});
|
|
121
|
-
if (!res.ok)
|
|
122
|
-
throw new Error(`API ${res.status}: ${await res.text()}`);
|
|
123
|
-
return res.json();
|
|
124
|
-
}
|
|
125
|
-
async function apiGet(url, apiKey) {
|
|
126
|
-
const res = await fetch(url, { headers: { 'Authorization': `Bearer ${apiKey}` } });
|
|
127
|
-
if (!res.ok)
|
|
128
|
-
throw new Error(`API ${res.status}: ${await res.text()}`);
|
|
129
|
-
return res.json();
|
|
130
|
-
}
|
|
131
|
-
async function apiDelete(url, apiKey) {
|
|
132
|
-
const res = await fetch(url, {
|
|
133
|
-
method: 'DELETE',
|
|
134
|
-
headers: { 'Authorization': `Bearer ${apiKey}` },
|
|
135
|
-
});
|
|
136
|
-
if (!res.ok)
|
|
137
|
-
throw new Error(`API ${res.status}: ${await res.text()}`);
|
|
138
|
-
return res.json();
|
|
139
|
-
}
|
|
140
|
-
// ---------- Helpers --------------------------------------------------------
|
|
141
|
-
function getFlag(args, flag) {
|
|
142
|
-
const idx = args.indexOf(flag);
|
|
143
|
-
if (idx === -1 || idx + 1 >= args.length)
|
|
144
|
-
return undefined;
|
|
145
|
-
return args[idx + 1];
|
|
146
|
-
}
|
|
147
|
-
function abortNotConfigured() {
|
|
148
|
-
console.error('Not configured. Run: greprag init');
|
|
149
|
-
process.exit(1);
|
|
150
|
-
}
|
|
151
|
-
/** Resolve which project a lore command operates on. --project <name> wins
|
|
152
|
-
* via the tenant's projects registry; otherwise the cwd's anchor decides. */
|
|
153
|
-
async function resolveProject(args, apiUrl, apiKey) {
|
|
154
|
-
const projectArg = getFlag(args, '--project');
|
|
155
|
-
if (!projectArg) {
|
|
156
|
-
const anchor = (0, project_anchor_1.readAnchor)(process.cwd());
|
|
157
|
-
return { projectId: anchor.projectId, projectName: anchor.projectName };
|
|
158
|
-
}
|
|
159
|
-
// The tenant-wide project registry list is served by /v1/inbox/projects
|
|
160
|
-
// (same endpoint memory.ts + the inbox subcommand use). /v1/projects mounts
|
|
161
|
-
// only /orphans, /merge, /discover — a bare GET 404s.
|
|
162
|
-
const r = await apiGet(`${apiUrl}/v1/inbox/projects`, apiKey);
|
|
163
|
-
const needle = projectArg.trim().toLowerCase();
|
|
164
|
-
const match = (r.projects || []).find(p => p.project_name.toLowerCase() === needle);
|
|
165
|
-
if (!match) {
|
|
166
|
-
throw new Error(`project "${projectArg}" not found under this tenant. ` +
|
|
167
|
-
`Register it via 'greprag init' in that directory, then retry.`);
|
|
168
|
-
}
|
|
169
|
-
return { projectId: match.project_id, projectName: match.project_name };
|
|
170
|
-
}
|
|
171
|
-
/** Try to read the current session's UUID from the harness env (Claude Code
|
|
172
|
-
* exposes it as CLAUDE_SESSION_ID on hook invocations). Falls back to
|
|
173
|
-
* undefined — callers should pass --source-session explicitly when they
|
|
174
|
-
* know it. */
|
|
175
|
-
function readSessionEnv() {
|
|
176
|
-
return process.env.CLAUDE_SESSION_ID || process.env.GREPRAG_SESSION_ID || null;
|
|
177
|
-
}
|
|
178
|
-
// ---------- add -----------------------------------------------------------
|
|
179
|
-
async function addCmd(args) {
|
|
180
|
-
const cfg = getConfig();
|
|
181
|
-
if (!cfg.apiKey)
|
|
182
|
-
abortNotConfigured();
|
|
183
|
-
const text = args[0];
|
|
184
|
-
if (!text || text.startsWith('--')) {
|
|
185
|
-
console.error('Usage: greprag lore add "<text>" --scope <scope> [--project <name>] [--source-session <id>]');
|
|
186
|
-
process.exit(1);
|
|
187
|
-
}
|
|
188
|
-
const scope = getFlag(args, '--scope');
|
|
189
|
-
if (!scope) {
|
|
190
|
-
console.error('Usage: greprag lore add "<text>" --scope <scope> [--project <name>]');
|
|
191
|
-
process.exit(1);
|
|
192
|
-
}
|
|
193
|
-
const sourceSession = getFlag(args, '--source-session') || readSessionEnv();
|
|
194
|
-
const { projectId, projectName } = await resolveProject(args, cfg.apiUrl, cfg.apiKey);
|
|
195
|
-
const result = await apiCall(`${cfg.apiUrl}/v1/lore/${projectId}`, cfg.apiKey, {
|
|
196
|
-
text, scope,
|
|
197
|
-
sourceSessionId: sourceSession,
|
|
198
|
-
projectName,
|
|
199
|
-
});
|
|
200
|
-
if (!result.ok || !result.nodeId)
|
|
201
|
-
throw new Error(result.error || 'add failed');
|
|
202
|
-
console.log(`Added fix [${result.nodeId}] scope=${scope} project=${projectName}`);
|
|
203
|
-
}
|
|
204
|
-
// ---------- smell (capture) ----------------------------------------------
|
|
205
|
-
/** greprag lore smell "<text>" — leave a RAW signal for /mechanic to digest.
|
|
206
|
-
* Zero structure by design: no --scope, no trigger. A smell is NOT lore — it's
|
|
207
|
-
* an item awaiting digestion (the advisor decides fix-vs-instantiate, assigns
|
|
208
|
-
* scope + injection trigger). Frictionless capture is the whole point; defer all
|
|
209
|
-
* judgment to digestion. docs/lore-smell.md. */
|
|
210
|
-
async function smellCmd(args) {
|
|
211
|
-
const cfg = getConfig();
|
|
212
|
-
if (!cfg.apiKey)
|
|
213
|
-
abortNotConfigured();
|
|
214
|
-
const text = args[0];
|
|
215
|
-
if (!text || text.startsWith('--')) {
|
|
216
|
-
console.error('Usage: greprag lore smell "<text>" [--project <name>]');
|
|
217
|
-
console.error('Leave a raw signal for the Mechanic to digest — a broken mechanism,');
|
|
218
|
-
console.error('a missing guardrail, or a durable truth not yet captured. Not lore itself.');
|
|
219
|
-
process.exit(1);
|
|
220
|
-
}
|
|
221
|
-
const sourceSession = getFlag(args, '--source-session') || readSessionEnv();
|
|
222
|
-
const { projectId, projectName } = await resolveProject(args, cfg.apiUrl, cfg.apiKey);
|
|
223
|
-
const result = await apiCall(`${cfg.apiUrl}/v1/lore/${projectId}`, cfg.apiKey, { text, scope: SMELL_SCOPE, sourceSessionId: sourceSession, projectName });
|
|
224
|
-
if (!result.ok || !result.nodeId)
|
|
225
|
-
throw new Error(result.error || 'smell failed');
|
|
226
|
-
console.log(`Fix logged [${result.nodeId}] in ${projectName}. Digest via /mechanic.`);
|
|
227
|
-
}
|
|
228
|
-
/** greprag lore smells [--all] — the raw smell queue awaiting digestion. The
|
|
229
|
-
* only reader that surfaces SMELL_SCOPE entries; durable query/list/scopes
|
|
230
|
-
* hide them. Without --all: the current project only. With --all: every
|
|
231
|
-
* project in the tenant, each row project-annotated (the Mechanic's
|
|
232
|
-
* Phase 0 census — so a backlog in another venture root can't hide). */
|
|
233
|
-
async function smellsCmd(args) {
|
|
234
|
-
const cfg = getConfig();
|
|
235
|
-
if (!cfg.apiKey)
|
|
236
|
-
abortNotConfigured();
|
|
237
|
-
const format = (getFlag(args, '--format') || 'text').toLowerCase();
|
|
238
|
-
if (args.includes('--all')) {
|
|
239
|
-
return smellsAllCmd(cfg, format);
|
|
240
|
-
}
|
|
241
|
-
const { projectId, projectName } = await resolveProject(args, cfg.apiUrl, cfg.apiKey);
|
|
242
|
-
const result = await apiGet(`${cfg.apiUrl}/v1/lore/${projectId}/list`, cfg.apiKey);
|
|
243
|
-
if (!result.ok)
|
|
244
|
-
throw new Error(result.error || 'smells failed');
|
|
245
|
-
const rows = (result.lore ?? result.facts ?? []).filter(r => r.scope === SMELL_SCOPE);
|
|
246
|
-
if (format === 'json') {
|
|
247
|
-
console.log(JSON.stringify({ project: projectName, smells: rows }, null, 2));
|
|
248
|
-
return;
|
|
249
|
-
}
|
|
250
|
-
if (rows.length === 0) {
|
|
251
|
-
console.log(`No fixes awaiting digestion in ${projectName}.`);
|
|
252
|
-
return;
|
|
253
|
-
}
|
|
254
|
-
console.log(`\n${rows.length} fix${rows.length === 1 ? '' : 'es'} awaiting digestion in ${projectName}:\n`);
|
|
255
|
-
for (const r of rows) {
|
|
256
|
-
const date = r.createdAt ? r.createdAt.slice(0, 10) : '';
|
|
257
|
-
console.log(` [${r.nodeId}] ${date} ${r.text}`);
|
|
258
|
-
}
|
|
259
|
-
console.log(`\nDigest: /mechanic · retire one: greprag lore delete <nodeId>`);
|
|
260
|
-
}
|
|
261
|
-
/** greprag lore smells --all — the tenant-wide smell census. One server call
|
|
262
|
-
* returns every smell across every project; the CLI groups them and stamps
|
|
263
|
-
* the top-level total + byProject summary the Mechanic skill consumes.
|
|
264
|
-
* JSON shape is a stable contract (docs above) — do not reshape casually. */
|
|
265
|
-
async function smellsAllCmd(cfg, format) {
|
|
266
|
-
const result = await apiGet(`${cfg.apiUrl}/v1/lore/census/smells`, cfg.apiKey);
|
|
267
|
-
if (!result.ok || !result.smells)
|
|
268
|
-
throw new Error(result.error || 'smells census failed');
|
|
269
|
-
// Project the server rows onto the published smell shape (drop projectId and
|
|
270
|
-
// any other server-internal fields so the JSON contract stays exactly:
|
|
271
|
-
// id, nodeId, text, scope, sourceSessionId, createdAt, project).
|
|
272
|
-
const smells = result.smells.map(s => ({
|
|
273
|
-
id: s.id,
|
|
274
|
-
nodeId: s.nodeId,
|
|
275
|
-
text: s.text,
|
|
276
|
-
scope: s.scope,
|
|
277
|
-
sourceSessionId: s.sourceSessionId,
|
|
278
|
-
createdAt: s.createdAt,
|
|
279
|
-
project: s.project,
|
|
280
|
-
}));
|
|
281
|
-
const total = smells.length;
|
|
282
|
-
// Per-project counts, ordered by count desc then name asc (busiest first).
|
|
283
|
-
const counts = new Map();
|
|
284
|
-
for (const s of smells)
|
|
285
|
-
counts.set(s.project, (counts.get(s.project) ?? 0) + 1);
|
|
286
|
-
const byProject = [...counts.entries()]
|
|
287
|
-
.map(([project, count]) => ({ project, count }))
|
|
288
|
-
.sort((a, b) => b.count - a.count || a.project.localeCompare(b.project));
|
|
289
|
-
if (format === 'json') {
|
|
290
|
-
console.log(JSON.stringify({ total, byProject, smells }, null, 2));
|
|
291
|
-
return;
|
|
292
|
-
}
|
|
293
|
-
if (total === 0) {
|
|
294
|
-
console.log('No fixes awaiting digestion across any project.');
|
|
295
|
-
return;
|
|
296
|
-
}
|
|
297
|
-
console.log(`\n${total} fix${total === 1 ? '' : 'es'} awaiting digestion across ${byProject.length} project${byProject.length === 1 ? '' : 's'}:\n`);
|
|
298
|
-
const grouped = new Map();
|
|
299
|
-
for (const s of smells) {
|
|
300
|
-
if (!grouped.has(s.project))
|
|
301
|
-
grouped.set(s.project, []);
|
|
302
|
-
grouped.get(s.project).push(s);
|
|
303
|
-
}
|
|
304
|
-
for (const { project, count } of byProject) {
|
|
305
|
-
console.log(`${project} (${count}):`);
|
|
306
|
-
for (const r of grouped.get(project) ?? []) {
|
|
307
|
-
const date = r.createdAt ? r.createdAt.slice(0, 10) : '';
|
|
308
|
-
console.log(` [${r.nodeId}] ${date} ${r.text}`);
|
|
309
|
-
}
|
|
310
|
-
console.log('');
|
|
311
|
-
}
|
|
312
|
-
console.log(`Digest: /mechanic · retire one: greprag lore delete <nodeId> --project <name>`);
|
|
313
|
-
}
|
|
314
|
-
// ---------- query ---------------------------------------------------------
|
|
315
|
-
async function queryCmd(args) {
|
|
316
|
-
const cfg = getConfig();
|
|
317
|
-
if (!cfg.apiKey)
|
|
318
|
-
abortNotConfigured();
|
|
319
|
-
const scope = getFlag(args, '--scope');
|
|
320
|
-
const queryStr = getFlag(args, '--query');
|
|
321
|
-
const limit = parseInt(getFlag(args, '--limit') || '10', 10);
|
|
322
|
-
const format = (getFlag(args, '--format') || 'markdown').toLowerCase();
|
|
323
|
-
if (format !== 'markdown' && format !== 'json') {
|
|
324
|
-
console.error('--format must be markdown or json');
|
|
325
|
-
process.exit(1);
|
|
326
|
-
}
|
|
327
|
-
const { projectId, projectName } = await resolveProject(args, cfg.apiUrl, cfg.apiKey);
|
|
328
|
-
const params = new URLSearchParams();
|
|
329
|
-
if (scope)
|
|
330
|
-
params.set('scope', scope);
|
|
331
|
-
if (queryStr)
|
|
332
|
-
params.set('query', queryStr);
|
|
333
|
-
params.set('limit', String(limit));
|
|
334
|
-
const result = await apiGet(`${cfg.apiUrl}/v1/lore/${projectId}?${params.toString()}`, cfg.apiKey);
|
|
335
|
-
const allRows = result.lore ?? result.facts;
|
|
336
|
-
if (!result.ok || !allRows)
|
|
337
|
-
throw new Error(result.error || 'query failed');
|
|
338
|
-
// Hide raw smells from durable reads — unless the caller explicitly asked for
|
|
339
|
-
// that scope (`--scope smell`), which is a deliberate queue peek.
|
|
340
|
-
const rows = scope ? allRows : allRows.filter(r => r.scope !== SMELL_SCOPE);
|
|
341
|
-
if (format === 'json') {
|
|
342
|
-
console.log(JSON.stringify({
|
|
343
|
-
project: projectName,
|
|
344
|
-
scope: scope ?? null,
|
|
345
|
-
query: queryStr ?? null,
|
|
346
|
-
lore: rows,
|
|
347
|
-
}, null, 2));
|
|
348
|
-
return;
|
|
349
|
-
}
|
|
350
|
-
if (rows.length === 0) {
|
|
351
|
-
const scopeNote = scope ? ` (scope=${scope})` : '';
|
|
352
|
-
const queryNote = queryStr ? ` matching "${queryStr}"` : '';
|
|
353
|
-
console.log(`No fixes in ${projectName}${scopeNote}${queryNote}.`);
|
|
354
|
-
return;
|
|
355
|
-
}
|
|
356
|
-
for (let i = 0; i < rows.length; i++) {
|
|
357
|
-
console.log(`${i + 1}. ${rows[i].text}`);
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
// ---------- list ----------------------------------------------------------
|
|
361
|
-
async function listCmd(args) {
|
|
362
|
-
const cfg = getConfig();
|
|
363
|
-
if (!cfg.apiKey)
|
|
364
|
-
abortNotConfigured();
|
|
365
|
-
const format = (getFlag(args, '--format') || 'text').toLowerCase();
|
|
366
|
-
if (format !== 'text' && format !== 'json' && format !== 'markdown') {
|
|
367
|
-
console.error('--format must be text, markdown, or json');
|
|
368
|
-
process.exit(1);
|
|
369
|
-
}
|
|
370
|
-
const { projectId, projectName } = await resolveProject(args, cfg.apiUrl, cfg.apiKey);
|
|
371
|
-
const result = await apiGet(`${cfg.apiUrl}/v1/lore/${projectId}/list`, cfg.apiKey);
|
|
372
|
-
const allRows = result.lore ?? result.facts;
|
|
373
|
-
if (!result.ok || !allRows)
|
|
374
|
-
throw new Error(result.error || 'list failed');
|
|
375
|
-
// `lore list` is the durable-review surface — never show raw smells (see `lore smells`).
|
|
376
|
-
const rows = allRows.filter(r => r.scope !== SMELL_SCOPE);
|
|
377
|
-
if (format === 'json') {
|
|
378
|
-
console.log(JSON.stringify({
|
|
379
|
-
project: projectName,
|
|
380
|
-
lore: rows,
|
|
381
|
-
}, null, 2));
|
|
382
|
-
return;
|
|
383
|
-
}
|
|
384
|
-
if (rows.length === 0) {
|
|
385
|
-
console.log(`No fixes recorded in ${projectName} yet.`);
|
|
386
|
-
console.log('Add one: greprag fix log "<text>"');
|
|
387
|
-
return;
|
|
388
|
-
}
|
|
389
|
-
// Group by scope (server already orders scope ASC, createdAt DESC).
|
|
390
|
-
const grouped = new Map();
|
|
391
|
-
for (const f of rows) {
|
|
392
|
-
const scope = f.scope || '(no scope)';
|
|
393
|
-
if (!grouped.has(scope))
|
|
394
|
-
grouped.set(scope, []);
|
|
395
|
-
grouped.get(scope).push(f);
|
|
396
|
-
}
|
|
397
|
-
console.log(`\n${rows.length} fix entr${rows.length === 1 ? 'y' : 'ies'} in ${projectName}:\n`);
|
|
398
|
-
for (const [scope, rows] of grouped) {
|
|
399
|
-
console.log(`## ${scope} (${rows.length})`);
|
|
400
|
-
for (const f of rows) {
|
|
401
|
-
const date = f.createdAt ? f.createdAt.slice(0, 10) : '';
|
|
402
|
-
console.log(` [${f.nodeId}] ${date} ${f.text}`);
|
|
403
|
-
}
|
|
404
|
-
console.log('');
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
// ---------- delete --------------------------------------------------------
|
|
408
|
-
async function deleteCmd(args) {
|
|
409
|
-
const cfg = getConfig();
|
|
410
|
-
if (!cfg.apiKey)
|
|
411
|
-
abortNotConfigured();
|
|
412
|
-
const nodeId = args[0];
|
|
413
|
-
if (!nodeId || nodeId.startsWith('--')) {
|
|
414
|
-
console.error('Usage: greprag lore delete <nodeId> [--project <name>]');
|
|
415
|
-
process.exit(1);
|
|
416
|
-
}
|
|
417
|
-
if (!/^[0-9a-f]{8}$/i.test(nodeId)) {
|
|
418
|
-
console.error('nodeId must be 8 hex chars (printed in `greprag lore list`).');
|
|
419
|
-
process.exit(1);
|
|
420
|
-
}
|
|
421
|
-
const { projectId, projectName } = await resolveProject(args, cfg.apiUrl, cfg.apiKey);
|
|
422
|
-
const result = await apiDelete(`${cfg.apiUrl}/v1/lore/${projectId}/${nodeId}`, cfg.apiKey);
|
|
423
|
-
if (!result.ok)
|
|
424
|
-
throw new Error(result.error || 'delete failed');
|
|
425
|
-
console.log(`Deleted fix [${nodeId}] from ${projectName}`);
|
|
426
|
-
}
|
|
427
|
-
// ---------- scopes --------------------------------------------------------
|
|
428
|
-
async function scopesCmd(args) {
|
|
429
|
-
const cfg = getConfig();
|
|
430
|
-
if (!cfg.apiKey)
|
|
431
|
-
abortNotConfigured();
|
|
432
|
-
const { projectId, projectName } = await resolveProject(args, cfg.apiUrl, cfg.apiKey);
|
|
433
|
-
const result = await apiGet(`${cfg.apiUrl}/v1/lore/${projectId}/scopes`, cfg.apiKey);
|
|
434
|
-
if (!result.ok || !result.scopes)
|
|
435
|
-
throw new Error(result.error || 'scopes failed');
|
|
436
|
-
// The reserved smell scope is an internal queue, not a durable scope label.
|
|
437
|
-
const scopes = result.scopes.filter(s => s !== SMELL_SCOPE);
|
|
438
|
-
if (scopes.length === 0) {
|
|
439
|
-
console.log(`No scopes in ${projectName} yet.`);
|
|
440
|
-
return;
|
|
441
|
-
}
|
|
442
|
-
for (const s of scopes)
|
|
443
|
-
console.log(s);
|
|
444
|
-
}
|
|
445
|
-
// ---------- Dispatch ------------------------------------------------------
|
|
446
|
-
const SUB_HELP = `
|
|
447
|
-
greprag lore — per-project LEARNINGS substrate.
|
|
448
|
-
|
|
449
|
-
Subcommands:
|
|
450
|
-
add "<text>" --scope <S> [--project <name>] [--source-session <id>]
|
|
451
|
-
Append a new lore entry under the given scope.
|
|
452
|
-
smell "<text>" [--project <name>]
|
|
453
|
-
Leave a RAW signal for /mechanic to digest — a
|
|
454
|
-
broken mechanism, a missing guardrail, or a durable
|
|
455
|
-
truth not yet captured. NOT lore itself; an item
|
|
456
|
-
awaiting digestion (advisor assigns scope + fix/trigger).
|
|
457
|
-
Frictionless by design: text only, no flags.
|
|
458
|
-
(Top-level alias: greprag smell "<text>".)
|
|
459
|
-
smells [--all] [--project <name>] [--format json]
|
|
460
|
-
The raw smell queue awaiting digestion. --all =
|
|
461
|
-
tenant-wide census across every project (each row
|
|
462
|
-
project-annotated; JSON adds total + byProject).
|
|
463
|
-
query [--scope <S>] [--query "<intent>"] [--project <name>]
|
|
464
|
-
[--limit N=10] [--format markdown|json]
|
|
465
|
-
Read lore. With --query, lexical-rank by
|
|
466
|
-
relevance. Without, most recent first.
|
|
467
|
-
list [--project <name>] [--format markdown|json]
|
|
468
|
-
Every lore entry grouped by scope (for review).
|
|
469
|
-
delete <nodeId> [--project <name>]
|
|
470
|
-
Drop one lore entry by its 8-char nodeId.
|
|
471
|
-
scopes [--project <name>] Distinct scope labels present in this project.
|
|
472
|
-
|
|
473
|
-
Examples:
|
|
474
|
-
greprag lore add "Migrations live at repo root, not packages/api/migrations." --scope chip-startup
|
|
475
|
-
greprag lore query --scope chip-startup --limit 10 --format markdown
|
|
476
|
-
greprag lore query --query "where do migrations live" --limit 5
|
|
477
|
-
greprag lore list
|
|
478
|
-
greprag lore delete a3f2c1d4
|
|
479
|
-
greprag lore scopes
|
|
480
|
-
`.trim();
|
|
481
|
-
async function runLore(args) {
|
|
482
|
-
const sub = args[0];
|
|
483
|
-
const rest = args.slice(1);
|
|
484
|
-
switch (sub) {
|
|
485
|
-
case 'add': return addCmd(rest);
|
|
486
|
-
case 'smell': return smellCmd(rest);
|
|
487
|
-
case 'smells': return smellsCmd(rest);
|
|
488
|
-
case 'query': return queryCmd(rest);
|
|
489
|
-
case 'list': return listCmd(rest);
|
|
490
|
-
case 'delete': return deleteCmd(rest);
|
|
491
|
-
case 'scopes': return scopesCmd(rest);
|
|
492
|
-
case undefined:
|
|
493
|
-
case 'help':
|
|
494
|
-
case '--help':
|
|
495
|
-
case '-h':
|
|
496
|
-
console.log(SUB_HELP);
|
|
497
|
-
return;
|
|
498
|
-
default:
|
|
499
|
-
console.error(`Unknown subcommand: ${sub}\n`);
|
|
500
|
-
console.log(SUB_HELP);
|
|
501
|
-
process.exit(1);
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
//# sourceMappingURL=lore.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"lore.js","sourceRoot":"","sources":["../../src/commands/lore.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
/** "You've got mail" — the front-desk turn notification (Chip B).
|
|
2
|
-
*
|
|
3
|
-
* A turn-based announcement, NOT a live watcher interrupt: each turn the hook
|
|
4
|
-
* asks the server for ENVELOPE-ONLY pending front-desk mail and, for any
|
|
5
|
-
* arrival it hasn't announced yet this machine, injects a one-line "you've got
|
|
6
|
-
* mail from X" notice. It feeds the human sign-off gate — it announces that a
|
|
7
|
-
* record arrived; it NEVER ingests body content (front-desk store contract
|
|
8
|
-
* invariant 2/3). The envelope type carries no `body` field, so body-leakage is
|
|
9
|
-
* impossible by construction here, and the server's `/v1/email/pending`
|
|
10
|
-
* projection withholds body too — defense at both ends.
|
|
11
|
-
*
|
|
12
|
-
* De-dupe: each record id is announced once (stamped in ~/.greprag/state.json),
|
|
13
|
-
* so a still-unread message doesn't re-nag every single turn — only genuinely
|
|
14
|
-
* new arrivals fire. The agent makes it stop by acting on the mail
|
|
15
|
-
* (`greprag email`), which marks it read and drops it from `pending`.
|
|
16
|
-
*/
|
|
17
|
-
/** Envelope of a pending front-desk record. NO `body` — by design. */
|
|
18
|
-
export interface FrontDeskEnvelope {
|
|
19
|
-
id: string;
|
|
20
|
-
nodeId: string;
|
|
21
|
-
from: string | null;
|
|
22
|
-
subject: string | null;
|
|
23
|
-
trustVerdict: 'verified' | 'unverified' | 'failed' | null;
|
|
24
|
-
attachmentCount: number;
|
|
25
|
-
createdAt: string;
|
|
26
|
-
}
|
|
27
|
-
/** Strip control chars / newlines and truncate untrusted envelope text before
|
|
28
|
-
* it enters the agent's context. The subject + from are attacker-controllable;
|
|
29
|
-
* rendering them on one clean line (no embedded newlines / escape sequences)
|
|
30
|
-
* blunts the obvious injection shapes without pretending the text is trusted.
|
|
31
|
-
*
|
|
32
|
-
* Done as a codepoint scan rather than a control-char regex on purpose — it is
|
|
33
|
-
* unambiguous in source (no literal control bytes in the file) and replaces
|
|
34
|
-
* every C0 control char + DEL with a space. */
|
|
35
|
-
export declare function sanitizeEnvelopeText(text: string | null, max: number): string;
|
|
36
|
-
/** Render the envelope-only notice. Pure: takes envelopes, returns a string (or
|
|
37
|
-
* null when there's nothing to announce). Provably body-free — `FrontDeskEnvelope`
|
|
38
|
-
* has no body field to render. */
|
|
39
|
-
export declare function renderFrontDeskNotice(envelopes: FrontDeskEnvelope[]): string | null;
|
|
40
|
-
/** Fetch envelope-only pending front-desk mail. Returns [] on any error so the
|
|
41
|
-
* hook never blocks a turn. */
|
|
42
|
-
export declare function fetchPendingMail(apiUrl: string, apiKey: string): Promise<FrontDeskEnvelope[]>;
|
|
43
|
-
/** Filter envelopes to those NOT yet announced. Pure given `stamps`. */
|
|
44
|
-
export declare function filterUnannounced(envelopes: FrontDeskEnvelope[], stamps: Record<string, string>): FrontDeskEnvelope[];
|
|
45
|
-
/** Mark a batch of ids announced and persist (pruning stale stamps). Best-effort. */
|
|
46
|
-
export declare function stampAnnounced(ids: string[]): void;
|
|
47
|
-
/** End-to-end: fetch pending mail, drop already-announced ids, render the
|
|
48
|
-
* envelope-only notice, stamp the freshly-announced ids. Returns null when
|
|
49
|
-
* there's nothing new. The data path is body-free throughout. */
|
|
50
|
-
export declare function buildFrontDeskNotice(apiUrl: string, apiKey: string): Promise<string | null>;
|