greprag 5.49.10 → 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.
Files changed (48) hide show
  1. package/dist/commands/arm-reminder.d.ts +10 -3
  2. package/dist/commands/arm-reminder.js +18 -6
  3. package/dist/commands/arm-reminder.js.map +1 -1
  4. package/dist/commands/collision-check.d.ts +1 -2
  5. package/dist/commands/collision-check.js +1 -2
  6. package/dist/commands/collision-check.js.map +1 -1
  7. package/dist/commands/inbox-drain.d.ts +9 -10
  8. package/dist/commands/inbox-drain.js +9 -10
  9. package/dist/commands/inbox-drain.js.map +1 -1
  10. package/dist/commands/inbox-primer-reminder.d.ts +10 -5
  11. package/dist/commands/inbox-primer-reminder.js +35 -21
  12. package/dist/commands/inbox-primer-reminder.js.map +1 -1
  13. package/dist/commands/poll-registry.d.ts +52 -9
  14. package/dist/commands/poll-registry.js +176 -9
  15. package/dist/commands/poll-registry.js.map +1 -1
  16. package/dist/commands/procedure.d.ts +15 -0
  17. package/dist/commands/procedure.js +167 -0
  18. package/dist/commands/procedure.js.map +1 -0
  19. package/dist/commands/reminder-registry.d.ts +5 -0
  20. package/dist/commands/reminder-registry.js +7 -3
  21. package/dist/commands/reminder-registry.js.map +1 -1
  22. package/dist/commands/reminder-types.d.ts +7 -5
  23. package/dist/hook.js +26 -46
  24. package/dist/hook.js.map +1 -1
  25. package/dist/index.js +4 -12
  26. package/dist/index.js.map +1 -1
  27. package/dist/procedure.d.ts +88 -0
  28. package/dist/procedure.js +269 -0
  29. package/dist/procedure.js.map +1 -0
  30. package/package.json +1 -1
  31. package/dist/commands/checkpoint-reminder.d.ts +0 -14
  32. package/dist/commands/checkpoint-reminder.js +0 -50
  33. package/dist/commands/checkpoint-reminder.js.map +0 -1
  34. package/dist/commands/frontdesk-reminder.d.ts +0 -23
  35. package/dist/commands/frontdesk-reminder.js +0 -43
  36. package/dist/commands/frontdesk-reminder.js.map +0 -1
  37. package/dist/commands/inbox-poll.d.ts +0 -47
  38. package/dist/commands/inbox-poll.js +0 -261
  39. package/dist/commands/inbox-poll.js.map +0 -1
  40. package/dist/commands/inbox-spool.d.ts +0 -27
  41. package/dist/commands/inbox-spool.js +0 -151
  42. package/dist/commands/inbox-spool.js.map +0 -1
  43. package/dist/commands/lore.d.ts +0 -35
  44. package/dist/commands/lore.js +0 -504
  45. package/dist/commands/lore.js.map +0 -1
  46. package/dist/front-desk-mail.d.ts +0 -50
  47. package/dist/front-desk-mail.js +0 -206
  48. package/dist/front-desk-mail.js.map +0 -1
@@ -1,206 +0,0 @@
1
- "use strict";
2
- /** "You've got mail" — the front-desk turn notification (Chip B).
3
- *
4
- * A turn-based announcement, NOT a live watcher interrupt: each turn the hook
5
- * asks the server for ENVELOPE-ONLY pending front-desk mail and, for any
6
- * arrival it hasn't announced yet this machine, injects a one-line "you've got
7
- * mail from X" notice. It feeds the human sign-off gate — it announces that a
8
- * record arrived; it NEVER ingests body content (front-desk store contract
9
- * invariant 2/3). The envelope type carries no `body` field, so body-leakage is
10
- * impossible by construction here, and the server's `/v1/email/pending`
11
- * projection withholds body too — defense at both ends.
12
- *
13
- * De-dupe: each record id is announced once (stamped in ~/.greprag/state.json),
14
- * so a still-unread message doesn't re-nag every single turn — only genuinely
15
- * new arrivals fire. The agent makes it stop by acting on the mail
16
- * (`greprag email`), which marks it read and drops it from `pending`.
17
- */
18
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
19
- if (k2 === undefined) k2 = k;
20
- var desc = Object.getOwnPropertyDescriptor(m, k);
21
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
22
- desc = { enumerable: true, get: function() { return m[k]; } };
23
- }
24
- Object.defineProperty(o, k2, desc);
25
- }) : (function(o, m, k, k2) {
26
- if (k2 === undefined) k2 = k;
27
- o[k2] = m[k];
28
- }));
29
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
30
- Object.defineProperty(o, "default", { enumerable: true, value: v });
31
- }) : function(o, v) {
32
- o["default"] = v;
33
- });
34
- var __importStar = (this && this.__importStar) || (function () {
35
- var ownKeys = function(o) {
36
- ownKeys = Object.getOwnPropertyNames || function (o) {
37
- var ar = [];
38
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
39
- return ar;
40
- };
41
- return ownKeys(o);
42
- };
43
- return function (mod) {
44
- if (mod && mod.__esModule) return mod;
45
- var result = {};
46
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
47
- __setModuleDefault(result, mod);
48
- return result;
49
- };
50
- })();
51
- Object.defineProperty(exports, "__esModule", { value: true });
52
- exports.sanitizeEnvelopeText = sanitizeEnvelopeText;
53
- exports.renderFrontDeskNotice = renderFrontDeskNotice;
54
- exports.fetchPendingMail = fetchPendingMail;
55
- exports.filterUnannounced = filterUnannounced;
56
- exports.stampAnnounced = stampAnnounced;
57
- exports.buildFrontDeskNotice = buildFrontDeskNotice;
58
- const path = __importStar(require("path"));
59
- const fs = __importStar(require("fs"));
60
- const SUBJECT_MAX = 80;
61
- const FROM_MAX = 60;
62
- /** Strip control chars / newlines and truncate untrusted envelope text before
63
- * it enters the agent's context. The subject + from are attacker-controllable;
64
- * rendering them on one clean line (no embedded newlines / escape sequences)
65
- * blunts the obvious injection shapes without pretending the text is trusted.
66
- *
67
- * Done as a codepoint scan rather than a control-char regex on purpose — it is
68
- * unambiguous in source (no literal control bytes in the file) and replaces
69
- * every C0 control char + DEL with a space. */
70
- function sanitizeEnvelopeText(text, max) {
71
- if (!text)
72
- return '';
73
- let out = '';
74
- for (const ch of text) {
75
- const code = ch.codePointAt(0) ?? 0;
76
- out += (code < 0x20 || code === 0x7f) ? ' ' : ch;
77
- }
78
- const oneLine = out.replace(/\s+/g, ' ').trim();
79
- return oneLine.length > max ? oneLine.slice(0, max - 1) + '…' : oneLine;
80
- }
81
- function verdictTag(v) {
82
- switch (v) {
83
- case 'verified': return 'verified';
84
- case 'failed': return '⚠ FAILED-AUTH';
85
- case 'unverified': return 'unverified';
86
- default: return 'unverified';
87
- }
88
- }
89
- /** Render the envelope-only notice. Pure: takes envelopes, returns a string (or
90
- * null when there's nothing to announce). Provably body-free — `FrontDeskEnvelope`
91
- * has no body field to render. */
92
- function renderFrontDeskNotice(envelopes) {
93
- if (!envelopes || envelopes.length === 0)
94
- return null;
95
- const n = envelopes.length;
96
- const lines = [];
97
- lines.push(`📬 You've got mail — ${n} new front-desk message${n === 1 ? '' : 's'} (envelope only; body stays sealed until you sign off):`);
98
- for (const e of envelopes) {
99
- const from = sanitizeEnvelopeText(e.from, FROM_MAX) || '(unknown sender)';
100
- const subject = sanitizeEnvelopeText(e.subject, SUBJECT_MAX) || '(no subject)';
101
- const att = e.attachmentCount > 0
102
- ? ` (${e.attachmentCount} attachment${e.attachmentCount === 1 ? '' : 's'})`
103
- : '';
104
- lines.push(` · [${verdictTag(e.trustVerdict)}] from ${from} — "${subject}"${att}`);
105
- }
106
- lines.push(`Act on it: \`greprag email\` reads the body deliberately. unverified/failed mail never auto-acts — you sign off first.`);
107
- return lines.join('\n');
108
- }
109
- /** Fetch envelope-only pending front-desk mail. Returns [] on any error so the
110
- * hook never blocks a turn. */
111
- async function fetchPendingMail(apiUrl, apiKey) {
112
- try {
113
- const url = `${apiUrl.replace(/\/+$/, '')}/v1/email/pending`;
114
- const res = await fetch(url, { headers: { Authorization: `Bearer ${apiKey}` } });
115
- if (!res.ok)
116
- return [];
117
- const data = await res.json();
118
- return (data.pending || []).map(r => ({
119
- id: r.id,
120
- nodeId: r.node_id,
121
- from: r.from,
122
- subject: r.subject,
123
- trustVerdict: r.trust_verdict,
124
- attachmentCount: r.attachment_count ?? 0,
125
- createdAt: r.created_at,
126
- }));
127
- }
128
- catch {
129
- return [];
130
- }
131
- }
132
- // ---- Once-per-arrival de-dupe (state.json) ---------------------------------
133
- const ANNOUNCE_TTL_MS = 30 * 86_400_000; // prune stamps older than 30 days
134
- function statePath() {
135
- const home = process.env.HOME || process.env.USERPROFILE || '';
136
- if (!home)
137
- return null;
138
- return path.join(home, '.greprag', 'state.json');
139
- }
140
- function readState() {
141
- const file = statePath();
142
- if (!file)
143
- return {};
144
- try {
145
- const parsed = JSON.parse(fs.readFileSync(file, 'utf-8'));
146
- return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : {};
147
- }
148
- catch {
149
- return {};
150
- }
151
- }
152
- function readAnnouncedStamps(state) {
153
- const stamps = state.frontDeskAnnounced;
154
- return stamps && typeof stamps === 'object' && !Array.isArray(stamps)
155
- ? stamps
156
- : {};
157
- }
158
- /** Filter envelopes to those NOT yet announced. Pure given `stamps`. */
159
- function filterUnannounced(envelopes, stamps) {
160
- return envelopes.filter(e => !stamps[e.id]);
161
- }
162
- /** Mark a batch of ids announced and persist (pruning stale stamps). Best-effort. */
163
- function stampAnnounced(ids) {
164
- const file = statePath();
165
- if (!file || ids.length === 0)
166
- return;
167
- try {
168
- const state = readState();
169
- const stamps = readAnnouncedStamps(state);
170
- const nowIso = new Date().toISOString();
171
- const nowMs = Date.now();
172
- for (const id of ids)
173
- stamps[id] = nowIso;
174
- // Prune stale stamps so the map can't grow without bound.
175
- for (const [id, iso] of Object.entries(stamps)) {
176
- const ms = Date.parse(iso);
177
- if (Number.isFinite(ms) && nowMs - ms > ANNOUNCE_TTL_MS)
178
- delete stamps[id];
179
- }
180
- state.frontDeskAnnounced = stamps;
181
- const dir = path.dirname(file);
182
- if (!fs.existsSync(dir))
183
- fs.mkdirSync(dir, { recursive: true });
184
- fs.writeFileSync(file, JSON.stringify(state, null, 2) + '\n');
185
- }
186
- catch {
187
- /* best-effort — a missed stamp just means a possible re-announce */
188
- }
189
- }
190
- /** End-to-end: fetch pending mail, drop already-announced ids, render the
191
- * envelope-only notice, stamp the freshly-announced ids. Returns null when
192
- * there's nothing new. The data path is body-free throughout. */
193
- async function buildFrontDeskNotice(apiUrl, apiKey) {
194
- const envelopes = await fetchPendingMail(apiUrl, apiKey);
195
- if (envelopes.length === 0)
196
- return null;
197
- const stamps = readAnnouncedStamps(readState());
198
- const fresh = filterUnannounced(envelopes, stamps);
199
- if (fresh.length === 0)
200
- return null;
201
- const notice = renderFrontDeskNotice(fresh);
202
- if (notice)
203
- stampAnnounced(fresh.map(e => e.id));
204
- return notice;
205
- }
206
- //# sourceMappingURL=front-desk-mail.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"front-desk-mail.js","sourceRoot":"","sources":["../src/front-desk-mail.ts"],"names":[],"mappings":"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"}