greprag 5.76.0 → 5.78.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/app.css +342 -0
- package/app/app.js +360 -0
- package/app/favicon.svg +4 -0
- package/app/index.html +54 -0
- package/dist/app-settings.js +162 -0
- package/dist/commands/app-model.js +308 -0
- package/dist/commands/app.js +310 -0
- package/dist/commands/codex-doctor.js +1 -0
- package/dist/commands/delivery-reminder.js +5 -5
- package/dist/commands/init.js +18 -3
- package/dist/commands/opencode-interrupt.js +11 -2
- package/dist/commands/persona-reminder.js +9 -0
- package/dist/commands/persona.js +191 -0
- package/dist/commands/reminder-registry.js +2 -0
- package/dist/commands/status.js +1 -0
- package/dist/hook.js +30 -4
- package/dist/index.js +23 -1
- package/dist/opencode-plugin.bundle.js +360 -279
- package/dist/opencode-plugin.js +45 -2
- package/dist/reminder-injector.js +2 -1
- package/package.json +2 -1
- package/scripts/postinstall.js +2 -1
package/dist/commands/init.js
CHANGED
|
@@ -719,6 +719,7 @@ function applyGrokHooks(config) {
|
|
|
719
719
|
add('PreToolUse', '*', 'guard', 5, 'guard');
|
|
720
720
|
add('Stop', '', 'store', 15, 'turn capture');
|
|
721
721
|
add('Stop', '', 'drain', 8, 'inbox drain');
|
|
722
|
+
add('PostCompact', '', 'recompact', 15, 'Interrupt re-announce');
|
|
722
723
|
add('PostCompact', '', 'session-id', 5, 'session-id');
|
|
723
724
|
return changes;
|
|
724
725
|
}
|
|
@@ -1411,14 +1412,27 @@ function applyCodexHooks(config) {
|
|
|
1411
1412
|
else {
|
|
1412
1413
|
changes.push('Codex Stop hook already configured (skipped)');
|
|
1413
1414
|
}
|
|
1414
|
-
const
|
|
1415
|
+
const postCompactAnnounceHook = {
|
|
1416
|
+
matcher: 'manual|auto',
|
|
1417
|
+
hooks: [commandHook('recompact', 10, 'Re-announcing GrepRAG primers')],
|
|
1418
|
+
};
|
|
1419
|
+
if (!hasGrepragHookWithMatcher(config.hooks.PostCompact, 'recompact', postCompactAnnounceHook.matcher)) {
|
|
1420
|
+
if (!config.hooks.PostCompact)
|
|
1421
|
+
config.hooks.PostCompact = [];
|
|
1422
|
+
config.hooks.PostCompact.push(postCompactAnnounceHook);
|
|
1423
|
+
changes.push('Added Codex PostCompact hook (Interrupt re-announce)');
|
|
1424
|
+
}
|
|
1425
|
+
else {
|
|
1426
|
+
changes.push('Codex PostCompact Interrupt re-announce hook already configured (skipped)');
|
|
1427
|
+
}
|
|
1428
|
+
const postCompactSessionHook = {
|
|
1415
1429
|
matcher: 'manual|auto',
|
|
1416
1430
|
hooks: [commandHook('session-id', 3, 'Restoring GrepRAG session id')],
|
|
1417
1431
|
};
|
|
1418
|
-
if (!hasGrepragHookWithMatcher(config.hooks.PostCompact, 'session-id',
|
|
1432
|
+
if (!hasGrepragHookWithMatcher(config.hooks.PostCompact, 'session-id', postCompactSessionHook.matcher)) {
|
|
1419
1433
|
if (!config.hooks.PostCompact)
|
|
1420
1434
|
config.hooks.PostCompact = [];
|
|
1421
|
-
config.hooks.PostCompact.push(
|
|
1435
|
+
config.hooks.PostCompact.push(postCompactSessionHook);
|
|
1422
1436
|
changes.push('Added Codex PostCompact hook (session-id awareness)');
|
|
1423
1437
|
}
|
|
1424
1438
|
else {
|
|
@@ -1432,6 +1446,7 @@ function normalizeCodexHookCommands(hooks) {
|
|
|
1432
1446
|
const desired = {
|
|
1433
1447
|
recap: { timeout: 10, statusMessage: 'Loading GrepRAG memory' },
|
|
1434
1448
|
'codex-recap': { timeout: 10, statusMessage: 'Loading GrepRAG memory' },
|
|
1449
|
+
recompact: { timeout: 10, statusMessage: 'Re-announcing GrepRAG primers' },
|
|
1435
1450
|
'session-id': { timeout: 3, statusMessage: 'Loading GrepRAG session id' },
|
|
1436
1451
|
drain: { timeout: 5, statusMessage: 'Draining GrepRAG inbox' },
|
|
1437
1452
|
'codex-notify': { timeout: 300, statusMessage: 'Checking GrepRAG inbox', runner: 'greprag-codex-hook' },
|
|
@@ -3,8 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.OPENCODE_QUOTA_WAITLIST_ANNOUNCE = exports.opencodeRegistry = void 0;
|
|
4
4
|
exports.buildOpenCodeEnv = buildOpenCodeEnv;
|
|
5
5
|
exports.getOpenCodeAnnounces = getOpenCodeAnnounces;
|
|
6
|
+
exports.getOpenCodePersistentAnnounces = getOpenCodePersistentAnnounces;
|
|
6
7
|
exports.getOpenCodeReminders = getOpenCodeReminders;
|
|
7
8
|
const reminder_registry_1 = require("./reminder-registry");
|
|
9
|
+
const app_settings_1 = require("../app-settings");
|
|
8
10
|
/** The opencode registry is DERIVED from the canon, never hand-whitelisted.
|
|
9
11
|
* Every REGISTRY module ships to opencode unless it declares a `harnesses`
|
|
10
12
|
* list excluding it (reminder-types.ts) — so a new module wired into
|
|
@@ -44,11 +46,18 @@ function buildOpenCodeEnv(params) {
|
|
|
44
46
|
updateAvailable: params.updateAvailable ?? null,
|
|
45
47
|
procedureAnnounces: params.procedureAnnounces ?? [],
|
|
46
48
|
mirroredSkills: params.mirroredSkills,
|
|
49
|
+
personaAnnounce: params.personaAnnounce ?? null,
|
|
47
50
|
};
|
|
48
51
|
}
|
|
49
52
|
function getOpenCodeAnnounces(env) {
|
|
50
|
-
return [...(0, reminder_registry_1.collectAnnounces)(env, exports.opencodeRegistry), exports.OPENCODE_QUOTA_WAITLIST_ANNOUNCE];
|
|
53
|
+
return [...(0, reminder_registry_1.collectAnnounces)(env, (0, app_settings_1.filterEnabledInterrupts)(exports.opencodeRegistry)), exports.OPENCODE_QUOTA_WAITLIST_ANNOUNCE];
|
|
54
|
+
}
|
|
55
|
+
/** OpenCode rebuilds output.system for every model call. Persona is the one
|
|
56
|
+
* startup primer that must remain behaviorally active on later calls, so the
|
|
57
|
+
* plugin replays this shared-registry module from its bounded session cache. */
|
|
58
|
+
function getOpenCodePersistentAnnounces(env) {
|
|
59
|
+
return (0, reminder_registry_1.collectAnnounces)(env, (0, app_settings_1.filterEnabledInterrupts)(exports.opencodeRegistry.filter((m) => m.id === 'persona-announce')));
|
|
51
60
|
}
|
|
52
61
|
function getOpenCodeReminders(env) {
|
|
53
|
-
return (0, reminder_registry_1.collectReminders)(env, exports.opencodeRegistry);
|
|
62
|
+
return (0, reminder_registry_1.collectReminders)(env, (0, app_settings_1.filterEnabledInterrupts)(exports.opencodeRegistry));
|
|
54
63
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.personaAnnounceModule = void 0;
|
|
4
|
+
exports.personaAnnounceModule = {
|
|
5
|
+
id: 'persona-announce',
|
|
6
|
+
detect: () => ({ tier: 'silent' }),
|
|
7
|
+
announce: (env) => env.personaAnnounce || null,
|
|
8
|
+
reminder: () => null,
|
|
9
|
+
};
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/** greprag persona — tenant-scoped speaking instructions. adr: adr/persona.md
|
|
3
|
+
*
|
|
4
|
+
* Thin HTTP wrapper over /v1/persona. The server owns built-in template content;
|
|
5
|
+
* custom text is sent verbatim and injected without rewriting.
|
|
6
|
+
*/
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
+
}) : function(o, v) {
|
|
21
|
+
o["default"] = v;
|
|
22
|
+
});
|
|
23
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
+
var ownKeys = function(o) {
|
|
25
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
+
var ar = [];
|
|
27
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
+
return ar;
|
|
29
|
+
};
|
|
30
|
+
return ownKeys(o);
|
|
31
|
+
};
|
|
32
|
+
return function (mod) {
|
|
33
|
+
if (mod && mod.__esModule) return mod;
|
|
34
|
+
var result = {};
|
|
35
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
+
__setModuleDefault(result, mod);
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
})();
|
|
40
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
+
exports.runPersona = runPersona;
|
|
42
|
+
const fs = __importStar(require("fs"));
|
|
43
|
+
function getConfig() {
|
|
44
|
+
return {
|
|
45
|
+
apiUrl: process.env.GREPRAG_API_URL || 'https://api.greprag.com',
|
|
46
|
+
apiKey: process.env.GREPRAG_API_KEY || '',
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function getFlag(args, flag) {
|
|
50
|
+
const idx = args.indexOf(flag);
|
|
51
|
+
return idx === -1 || idx + 1 >= args.length ? undefined : args[idx + 1];
|
|
52
|
+
}
|
|
53
|
+
const HELP = `greprag persona — tenant-scoped instructions for how agents speak to you
|
|
54
|
+
|
|
55
|
+
USAGE
|
|
56
|
+
greprag persona list
|
|
57
|
+
List built-in Persona templates.
|
|
58
|
+
|
|
59
|
+
greprag persona use <template>
|
|
60
|
+
Activate a built-in template, e.g. vibe-shaper.
|
|
61
|
+
|
|
62
|
+
greprag persona set <text>
|
|
63
|
+
greprag persona set --file <path>
|
|
64
|
+
greprag persona set --stdin
|
|
65
|
+
Save and activate a custom Persona verbatim.
|
|
66
|
+
|
|
67
|
+
greprag persona show
|
|
68
|
+
Show the active Persona.
|
|
69
|
+
|
|
70
|
+
greprag persona clear
|
|
71
|
+
Remove the active Persona.`;
|
|
72
|
+
async function api(method, pathname, body) {
|
|
73
|
+
const cfg = getConfig();
|
|
74
|
+
if (!cfg.apiKey) {
|
|
75
|
+
console.error('GREPRAG_API_KEY not set — run `greprag init` first.');
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
const res = await fetch(`${cfg.apiUrl}${pathname}`, {
|
|
79
|
+
method,
|
|
80
|
+
headers: {
|
|
81
|
+
'Authorization': `Bearer ${cfg.apiKey}`,
|
|
82
|
+
'Content-Type': 'application/json',
|
|
83
|
+
},
|
|
84
|
+
body: body === undefined ? undefined : JSON.stringify(body),
|
|
85
|
+
});
|
|
86
|
+
let data = {};
|
|
87
|
+
try {
|
|
88
|
+
data = await res.json();
|
|
89
|
+
}
|
|
90
|
+
catch { /* non-JSON */ }
|
|
91
|
+
return { ok: res.ok, status: res.status, data };
|
|
92
|
+
}
|
|
93
|
+
function fail(data, status) {
|
|
94
|
+
console.error(`Error${status ? ` (${status})` : ''}: ${data.error || 'request failed'}`);
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
function readPersonaInput(args) {
|
|
98
|
+
const file = getFlag(args, '--file');
|
|
99
|
+
if (file) {
|
|
100
|
+
try {
|
|
101
|
+
return file === '-' ? fs.readFileSync(0, 'utf-8') : fs.readFileSync(file, 'utf-8');
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
console.error(`persona set: could not read --file ${file}: ${err.message}`);
|
|
105
|
+
process.exit(1);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (args.includes('--stdin')) {
|
|
109
|
+
try {
|
|
110
|
+
return fs.readFileSync(0, 'utf-8');
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
console.error(`persona set: could not read stdin: ${err.message}`);
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return args.filter((a) => a !== '--stdin').join(' ');
|
|
118
|
+
}
|
|
119
|
+
async function list() {
|
|
120
|
+
const { ok, status, data } = await api('GET', '/v1/persona/templates');
|
|
121
|
+
if (!ok)
|
|
122
|
+
fail(data, status);
|
|
123
|
+
const templates = data.templates || [];
|
|
124
|
+
if (!templates.length) {
|
|
125
|
+
console.log('No built-in Persona templates.');
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
console.log('Built-in Persona templates:\n');
|
|
129
|
+
for (const t of templates) {
|
|
130
|
+
console.log(` ${t.id} — ${t.name}`);
|
|
131
|
+
console.log(` ${t.description}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
async function useTemplate(id) {
|
|
135
|
+
if (!id) {
|
|
136
|
+
console.error('Usage: greprag persona use <template>');
|
|
137
|
+
process.exit(1);
|
|
138
|
+
}
|
|
139
|
+
const { ok, status, data } = await api('PUT', '/v1/persona/template', { templateId: id });
|
|
140
|
+
if (!ok)
|
|
141
|
+
fail(data, status);
|
|
142
|
+
const p = data.persona;
|
|
143
|
+
console.log(`Persona active: ${p.templateId} (built-in template)`);
|
|
144
|
+
}
|
|
145
|
+
async function set(args) {
|
|
146
|
+
const content = readPersonaInput(args);
|
|
147
|
+
const { ok, status, data } = await api('PUT', '/v1/persona/custom', { content });
|
|
148
|
+
if (!ok)
|
|
149
|
+
fail(data, status);
|
|
150
|
+
const p = data.persona;
|
|
151
|
+
console.log(`Persona active: custom (${p.content?.length ?? content.length} chars)`);
|
|
152
|
+
}
|
|
153
|
+
async function show() {
|
|
154
|
+
const { ok, status, data } = await api('GET', '/v1/persona');
|
|
155
|
+
if (!ok)
|
|
156
|
+
fail(data, status);
|
|
157
|
+
const p = data.persona;
|
|
158
|
+
if (!p) {
|
|
159
|
+
console.log('No Persona set.');
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const source = p.mode === 'template' ? `template ${p.templateId}` : 'custom';
|
|
163
|
+
console.log(`Persona (${source})`);
|
|
164
|
+
console.log('');
|
|
165
|
+
console.log(p.content || '');
|
|
166
|
+
}
|
|
167
|
+
async function clear() {
|
|
168
|
+
const { ok, status, data } = await api('DELETE', '/v1/persona');
|
|
169
|
+
if (!ok)
|
|
170
|
+
fail(data, status);
|
|
171
|
+
console.log(data.removed ? 'Persona cleared.' : 'No Persona was set.');
|
|
172
|
+
}
|
|
173
|
+
async function runPersona(args) {
|
|
174
|
+
const sub = args[0];
|
|
175
|
+
const rest = args.slice(1);
|
|
176
|
+
if (!sub || sub === '--help' || sub === '-h' || sub === 'help') {
|
|
177
|
+
console.log(HELP);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
switch (sub) {
|
|
181
|
+
case 'list': return list();
|
|
182
|
+
case 'use': return useTemplate(rest[0]);
|
|
183
|
+
case 'set': return set(rest);
|
|
184
|
+
case 'show': return show();
|
|
185
|
+
case 'clear': return clear();
|
|
186
|
+
default:
|
|
187
|
+
console.error(`Unknown persona command: ${sub}\n`);
|
|
188
|
+
console.log(HELP);
|
|
189
|
+
process.exit(1);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
@@ -28,6 +28,7 @@ const skill_mirror_reminder_1 = require("./skill-mirror-reminder");
|
|
|
28
28
|
const procedure_reminder_1 = require("./procedure-reminder");
|
|
29
29
|
const loadout_reminder_1 = require("./loadout-reminder");
|
|
30
30
|
const delivery_reminder_1 = require("./delivery-reminder");
|
|
31
|
+
const persona_reminder_1 = require("./persona-reminder");
|
|
31
32
|
/** Registry order = display order. THE single agent-facing announce/reminder assembly:
|
|
32
33
|
* the hook does I/O → fills ReminderEnv → collectAnnounces (SessionStart) / collectReminders
|
|
33
34
|
* (per turn) render every module here in this order. A module may own either surface or both;
|
|
@@ -46,6 +47,7 @@ exports.REGISTRY = [
|
|
|
46
47
|
skill_mirror_reminder_1.skillMirrorAnnounceModule, // native-equivalent activation index for load-only mirrored skills
|
|
47
48
|
procedure_reminder_1.procedureAnnounceModule, // active project procedures, rendered generically from operator-owned installs
|
|
48
49
|
delivery_reminder_1.deliveryControlModule, // repo-scoped announce-first Delivery System pilot (all harnesses)
|
|
50
|
+
persona_reminder_1.personaAnnounceModule, // tenant-scoped Persona, shared across projects/harnesses
|
|
49
51
|
loadout_reminder_1.loadoutRegistrarModule, // equipped loadouts: one advisor announce each + per-turn keyword Match (docs/loadout.md)
|
|
50
52
|
setup_reminder_1.setupWarningModule,
|
|
51
53
|
version_reminder_1.versionUpgradeModule, // Deficiency-gated announce — silent unless a newer release exists
|
package/dist/commands/status.js
CHANGED
|
@@ -191,6 +191,7 @@ function buildStatus(cwd, platform = 'all') {
|
|
|
191
191
|
pre_tool_use_chip_guard: hasCodexHook(codexHooks.hooks?.PreToolUse, 'codex-pretooluse')
|
|
192
192
|
|| hasCodexHook(codexHooks.hooks?.PreToolUse, 'codex-chip-hook'),
|
|
193
193
|
stop_store: hasCodexHook(codexHooks.hooks?.Stop, 'codex-store'),
|
|
194
|
+
post_compact_reannounce: hasCodexHook(codexHooks.hooks?.PostCompact, 'recompact'),
|
|
194
195
|
post_compact_session_id: hasCodexHook(codexHooks.hooks?.PostCompact, 'session-id'),
|
|
195
196
|
};
|
|
196
197
|
const opencodePluginInstalled = fs.existsSync(opencodePluginPath);
|
package/dist/hook.js
CHANGED
|
@@ -83,6 +83,7 @@ const guard_1 = require("./guard");
|
|
|
83
83
|
// auto-silences when resolved (the arm-check pattern). The hook below assembles the
|
|
84
84
|
// live env (ALL I/O) and emits; the modules are pure.
|
|
85
85
|
const reminder_registry_1 = require("./commands/reminder-registry");
|
|
86
|
+
const app_settings_1 = require("./app-settings");
|
|
86
87
|
const inbox_primer_reminder_1 = require("./commands/inbox-primer-reminder");
|
|
87
88
|
const skill_activation_manifest_1 = require("./skill-activation-manifest");
|
|
88
89
|
const worktree_state_1 = require("./worktree-state");
|
|
@@ -1613,11 +1614,29 @@ async function recap(input, mode = 'plain', opts = {}) {
|
|
|
1613
1614
|
return empty;
|
|
1614
1615
|
}
|
|
1615
1616
|
})();
|
|
1617
|
+
// Tenant Persona primer. The server owns both template resolution and
|
|
1618
|
+
// the provenance envelope; harnesses transport it unchanged. adr: adr/persona.md
|
|
1619
|
+
const personaPromise = (async () => {
|
|
1620
|
+
try {
|
|
1621
|
+
const res = await fetch(`${cfg.apiUrl}/v1/persona`, {
|
|
1622
|
+
headers: { 'Authorization': `Bearer ${cfg.apiKey}` },
|
|
1623
|
+
});
|
|
1624
|
+
if (!res.ok)
|
|
1625
|
+
return null;
|
|
1626
|
+
const data = await res.json();
|
|
1627
|
+
return typeof data.announce === 'string' && data.announce.length > 0
|
|
1628
|
+
? data.announce
|
|
1629
|
+
: null;
|
|
1630
|
+
}
|
|
1631
|
+
catch {
|
|
1632
|
+
return null;
|
|
1633
|
+
}
|
|
1634
|
+
})();
|
|
1616
1635
|
const updateAvailablePromise = checkForUpdate();
|
|
1617
1636
|
const bodyPromise = (!opts.compact && anchor.sessionStartRecap)
|
|
1618
1637
|
? (0, opencode_plugin_helpers_1.buildRecapBody)(cfg.apiUrl, cfg.apiKey, anchor)
|
|
1619
1638
|
: Promise.resolve('');
|
|
1620
|
-
const [, corpusApiDocs, docPointers, enrichmentDown, skillGains, mirroredSkills, loadoutState, updateAvailable, body,] = await Promise.all([
|
|
1639
|
+
const [, corpusApiDocs, docPointers, enrichmentDown, skillGains, mirroredSkills, loadoutState, personaAnnounce, updateAvailable, body,] = await Promise.all([
|
|
1621
1640
|
matchsetPromise,
|
|
1622
1641
|
corpusApiDocsPromise,
|
|
1623
1642
|
docPointersPromise,
|
|
@@ -1625,6 +1644,7 @@ async function recap(input, mode = 'plain', opts = {}) {
|
|
|
1625
1644
|
skillGainsPromise,
|
|
1626
1645
|
mirroredSkillsPromise,
|
|
1627
1646
|
loadoutStatePromise,
|
|
1647
|
+
personaPromise,
|
|
1628
1648
|
updateAvailablePromise,
|
|
1629
1649
|
bodyPromise,
|
|
1630
1650
|
]);
|
|
@@ -1704,11 +1724,14 @@ async function recap(input, mode = 'plain', opts = {}) {
|
|
|
1704
1724
|
mirroredSkills,
|
|
1705
1725
|
procedureAnnounces,
|
|
1706
1726
|
equippedLoadouts,
|
|
1727
|
+
personaAnnounce,
|
|
1707
1728
|
updateAvailable,
|
|
1708
1729
|
activeCommandDrift: activeCommandDrift(),
|
|
1709
1730
|
loadoutUpdateRequired,
|
|
1710
1731
|
};
|
|
1711
|
-
let announceReg = (0,
|
|
1732
|
+
let announceReg = (0, app_settings_1.filterEnabledInterrupts)(reminder_registry_1.REGISTRY);
|
|
1733
|
+
if ((0, reminder_injector_1.mechanicKilled)())
|
|
1734
|
+
announceReg = announceReg.filter(m => m.id !== 'mechanic-friction');
|
|
1712
1735
|
if (!announceShort)
|
|
1713
1736
|
announceReg = announceReg.filter(m => m.id !== 'watcher-arm');
|
|
1714
1737
|
// PostCompact: a compaction wiped the once-loaded SessionStart announces from context.
|
|
@@ -2191,7 +2214,7 @@ async function coordinateGate(input) {
|
|
|
2191
2214
|
toolCommand: typeof toolInput.command === 'string' ? toolInput.command : '',
|
|
2192
2215
|
collisionPeers: peers,
|
|
2193
2216
|
};
|
|
2194
|
-
const fired = (0, reminder_registry_1.collectReminders)(env, (0, reminder_registry_1.commandModules)());
|
|
2217
|
+
const fired = (0, reminder_registry_1.collectReminders)(env, (0, app_settings_1.filterEnabledInterrupts)((0, reminder_registry_1.commandModules)()));
|
|
2195
2218
|
if (!fired.length)
|
|
2196
2219
|
return;
|
|
2197
2220
|
// Effect: inject as additionalContext — advisory heads-up, NO permission pause.
|
|
@@ -2264,7 +2287,10 @@ async function main() {
|
|
|
2264
2287
|
// opt out per-module with reannounceOnCompact:false) so the doctrine the compaction
|
|
2265
2288
|
// wiped (incl. the watcher-arm announce) returns. additionalContext = the JSON form
|
|
2266
2289
|
// PostCompact injects. adr: adr/monitor-resilience.md, docs/reminder-interrupt.md
|
|
2267
|
-
await recap(input, 'additionalContext', {
|
|
2290
|
+
await recap(input, 'additionalContext', {
|
|
2291
|
+
compact: true,
|
|
2292
|
+
platform: harness === 'grok' ? 'grok' : undefined,
|
|
2293
|
+
});
|
|
2268
2294
|
}
|
|
2269
2295
|
else if (subcommand === 'codex-recap') {
|
|
2270
2296
|
await recap(input, 'additionalContext', { platform: 'codex' });
|
package/dist/index.js
CHANGED
|
@@ -66,6 +66,7 @@ const doc_1 = require("./commands/doc");
|
|
|
66
66
|
const parity_1 = require("./commands/parity");
|
|
67
67
|
const agents_1 = require("./commands/agents");
|
|
68
68
|
const loadout_1 = require("./commands/loadout");
|
|
69
|
+
const persona_1 = require("./commands/persona");
|
|
69
70
|
const assistant_1 = require("./commands/assistant");
|
|
70
71
|
const email_1 = require("./commands/email");
|
|
71
72
|
const sms_1 = require("./commands/sms");
|
|
@@ -79,6 +80,7 @@ const crush_stats_1 = require("./commands/crush-stats");
|
|
|
79
80
|
const archive_1 = require("./commands/archive");
|
|
80
81
|
const inbox_watch_1 = require("./commands/inbox-watch");
|
|
81
82
|
const grok_spawn_1 = require("./commands/grok-spawn");
|
|
83
|
+
const app_1 = require("./commands/app");
|
|
82
84
|
const inbox_attachments_1 = require("./inbox-attachments");
|
|
83
85
|
const discord_1 = require("./commands/discord");
|
|
84
86
|
const project_anchor_1 = require("./project-anchor");
|
|
@@ -1284,6 +1286,8 @@ const HELP = `
|
|
|
1284
1286
|
greprag — agent memory for Claude Code, Codex, OpenCode, and Grok Build
|
|
1285
1287
|
|
|
1286
1288
|
Commands:
|
|
1289
|
+
(no command) Open the local GrepRAG app
|
|
1290
|
+
app | dashboard [--port N] Open the local app (use --no-open on remote machines)
|
|
1287
1291
|
init [--api-key <key>] [--tenant-id <handle>]
|
|
1288
1292
|
Auto-detect/ask for Codex, Claude Code, or OpenCode
|
|
1289
1293
|
init --claude [--api-key <key>] [--tenant-id <handle>]
|
|
@@ -1568,6 +1572,14 @@ Loadout (gift a skill bundle to another tenant — offer, never auto-install):
|
|
|
1568
1572
|
loadout unequip <name> [--delete-skills]
|
|
1569
1573
|
Stop a loadout's auto-inflate.
|
|
1570
1574
|
|
|
1575
|
+
Persona (tenant-scoped speaking instructions):
|
|
1576
|
+
persona list List built-in Persona templates.
|
|
1577
|
+
persona use <template> Activate a built-in Persona template.
|
|
1578
|
+
persona set <text>|--file <f>|--stdin
|
|
1579
|
+
Save and activate a custom Persona verbatim.
|
|
1580
|
+
persona show Show the active Persona.
|
|
1581
|
+
persona clear Remove the active Persona.
|
|
1582
|
+
|
|
1571
1583
|
GrepRAG Instructions (canonical global/repo CLAUDE.md + AGENTS.md):
|
|
1572
1584
|
instructions pull <file> [--scope global|repo] [--push]
|
|
1573
1585
|
Pull disk instructions into canon.
|
|
@@ -1607,6 +1619,7 @@ Other:
|
|
|
1607
1619
|
full --help — the complete, always-current guide.
|
|
1608
1620
|
|
|
1609
1621
|
Examples:
|
|
1622
|
+
greprag # open the local customer app
|
|
1610
1623
|
greprag init # standard repo setup
|
|
1611
1624
|
greprag init --global # Cowork / unanchored sessions
|
|
1612
1625
|
greprag init --all # register every sibling repo for inbox
|
|
@@ -1639,6 +1652,7 @@ const HELP_ALL_GROUPS = [
|
|
|
1639
1652
|
['delivery', delivery_1.runDelivery],
|
|
1640
1653
|
['assistant', assistant_1.runAssistant],
|
|
1641
1654
|
['instructions', agents_1.runInstructions],
|
|
1655
|
+
['persona', persona_1.runPersona],
|
|
1642
1656
|
['doc', doc_1.runDoc],
|
|
1643
1657
|
['skill', skill_1.runSkill],
|
|
1644
1658
|
['opencode', opencode],
|
|
@@ -1833,7 +1847,11 @@ async function printHelpAll() {
|
|
|
1833
1847
|
async function main() {
|
|
1834
1848
|
const args = process.argv.slice(2);
|
|
1835
1849
|
const command = args[0];
|
|
1836
|
-
if (!command
|
|
1850
|
+
if (!command) {
|
|
1851
|
+
await (0, app_1.runApp)([]);
|
|
1852
|
+
return;
|
|
1853
|
+
}
|
|
1854
|
+
if (command === 'help' || command === '--help' || command === '-h') {
|
|
1837
1855
|
if (args.includes('--all')) {
|
|
1838
1856
|
await printHelpAll();
|
|
1839
1857
|
return;
|
|
@@ -1850,6 +1868,8 @@ async function main() {
|
|
|
1850
1868
|
ensureEnv();
|
|
1851
1869
|
const subArgs = args.slice(1);
|
|
1852
1870
|
switch (command) {
|
|
1871
|
+
case 'app':
|
|
1872
|
+
case 'dashboard': return (0, app_1.runApp)(subArgs);
|
|
1853
1873
|
case 'init': {
|
|
1854
1874
|
if (subArgs.includes('--help') || subArgs.includes('-h') || subArgs.includes('help')) {
|
|
1855
1875
|
console.log(INIT_HELP);
|
|
@@ -1871,6 +1891,7 @@ async function main() {
|
|
|
1871
1891
|
const name = getFlag(args, '--name');
|
|
1872
1892
|
const root = getFlag(args, '--root');
|
|
1873
1893
|
await (0, init_1.runInit)({ apiKey, tenantId, installWatcher, global, claude, opencode, codex, grok, all, name, root });
|
|
1894
|
+
console.log('\n Open your local settings any time with: greprag\n');
|
|
1874
1895
|
return;
|
|
1875
1896
|
}
|
|
1876
1897
|
case 'project-id': {
|
|
@@ -1926,6 +1947,7 @@ async function main() {
|
|
|
1926
1947
|
case 'instructions': return (0, agents_1.runInstructions)(subArgs); // Canonical GrepRAG Instructions + rendered followers
|
|
1927
1948
|
case 'agents': return (0, agents_1.runAgents)(subArgs); // Deprecated alias for GrepRAG Instructions
|
|
1928
1949
|
case 'loadout': return (0, loadout_1.runLoadout)(subArgs); // Loadout: cross-tenant skill-bundle gifting (docs/loadout.md)
|
|
1950
|
+
case 'persona': return (0, persona_1.runPersona)(subArgs); // tenant-scoped speaking instructions
|
|
1929
1951
|
case 'assistant': return (0, assistant_1.runAssistant)(subArgs); // designate this project as the tenant's Assistant (role flag)
|
|
1930
1952
|
case 'opencode': return opencode(subArgs);
|
|
1931
1953
|
case 'grok': return (0, grok_spawn_1.runGrok)(subArgs);
|