@ouro.bot/cli 0.1.0-alpha.658 → 0.1.0-alpha.659
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/changelog.json +6 -0
- package/dist/heart/context-loss-gauntlet.js +354 -0
- package/dist/heart/daemon/cli-exec.js +13 -0
- package/dist/heart/daemon/cli-help.js +11 -4
- package/dist/heart/daemon/cli-parse.js +6 -5
- package/dist/heart/mailbox/mailbox-http-hooks.js +1 -0
- package/dist/heart/mailbox/mailbox-http-routes.js +4 -0
- package/dist/heart/mailbox/mailbox-read.js +2 -1
- package/dist/heart/mailbox/readers/continuity-readers.js +5 -0
- package/dist/heart/work-card.js +1 -1
- package/dist/mailbox-ui/assets/index-B-V9vRQ0.js +61 -0
- package/dist/mailbox-ui/assets/index-BOZbGbkL.css +1 -0
- package/dist/mailbox-ui/index.html +2 -2
- package/package.json +1 -1
- package/dist/mailbox-ui/assets/index-CWzt267f.css +0 -1
- package/dist/mailbox-ui/assets/index-Cbasiy6y.js +0 -61
package/changelog.json
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_note": "This changelog is maintained as part of the PR/version-bump workflow. Agent-curated, not auto-generated. Agents read this file directly via read_file to understand what changed between versions.",
|
|
3
3
|
"versions": [
|
|
4
|
+
{
|
|
5
|
+
"version": "0.1.0-alpha.659",
|
|
6
|
+
"changes": [
|
|
7
|
+
"Add a deterministic context-loss gauntlet that scores Arc/flight-recorder/Desk recovery readiness through CLI, Mailbox HTTP, and Workbench visibility surfaces."
|
|
8
|
+
]
|
|
9
|
+
},
|
|
4
10
|
{
|
|
5
11
|
"version": "0.1.0-alpha.658",
|
|
6
12
|
"changes": [
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.runContextLossGauntlet = runContextLossGauntlet;
|
|
37
|
+
exports.formatContextLossGauntletText = formatContextLossGauntletText;
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const flight_recorder_1 = require("../arc/flight-recorder");
|
|
41
|
+
const record_paths_1 = require("../mind/record-paths");
|
|
42
|
+
const runtime_1 = require("../nerves/runtime");
|
|
43
|
+
const work_card_1 = require("./work-card");
|
|
44
|
+
function makeCheck(input) {
|
|
45
|
+
return input;
|
|
46
|
+
}
|
|
47
|
+
function flightRecorderEvidence(card) {
|
|
48
|
+
return card.sources.filter((source) => source.kind === "flight_recorder").slice(0, 1);
|
|
49
|
+
}
|
|
50
|
+
function currentAskCheck(card) {
|
|
51
|
+
const evidence = flightRecorderEvidence(card);
|
|
52
|
+
if (!card.currentAsk.available) {
|
|
53
|
+
return makeCheck({
|
|
54
|
+
id: "current_ask",
|
|
55
|
+
label: "Current ask",
|
|
56
|
+
status: "fail",
|
|
57
|
+
score: 0,
|
|
58
|
+
maxScore: 15,
|
|
59
|
+
detail: "No durable current ask is available after context loss.",
|
|
60
|
+
evidence,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
if (card.currentAsk.confidence !== "current") {
|
|
64
|
+
return makeCheck({
|
|
65
|
+
id: "current_ask",
|
|
66
|
+
label: "Current ask",
|
|
67
|
+
status: "warn",
|
|
68
|
+
score: 10,
|
|
69
|
+
maxScore: 15,
|
|
70
|
+
detail: `Current ask is available but marked ${card.currentAsk.confidence}.`,
|
|
71
|
+
evidence,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return makeCheck({
|
|
75
|
+
id: "current_ask",
|
|
76
|
+
label: "Current ask",
|
|
77
|
+
status: "pass",
|
|
78
|
+
score: 15,
|
|
79
|
+
maxScore: 15,
|
|
80
|
+
detail: "Current ask is preserved in the flight recorder.",
|
|
81
|
+
evidence,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
function nextSafeActionCheck(card) {
|
|
85
|
+
const evidence = card.nextAction.source ? [card.nextAction.source] : [];
|
|
86
|
+
if (card.nextAction.actor === "unknown") {
|
|
87
|
+
return makeCheck({
|
|
88
|
+
id: "next_safe_action",
|
|
89
|
+
label: "Next safe action",
|
|
90
|
+
status: "fail",
|
|
91
|
+
score: 0,
|
|
92
|
+
maxScore: 20,
|
|
93
|
+
detail: card.nextAction.summary,
|
|
94
|
+
evidence,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
return makeCheck({
|
|
98
|
+
id: "next_safe_action",
|
|
99
|
+
label: "Next safe action",
|
|
100
|
+
status: "pass",
|
|
101
|
+
score: 20,
|
|
102
|
+
maxScore: 20,
|
|
103
|
+
detail: `${card.nextAction.actor}: ${card.nextAction.summary}`,
|
|
104
|
+
evidence,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
function staleGuardCheck(resume, card) {
|
|
108
|
+
const evidence = flightRecorderEvidence(card);
|
|
109
|
+
if (resume.canContinue && resume.hasCompleteState && resume.recorderHealth.status === "ok" && resume.blockedBecause.length === 0) {
|
|
110
|
+
return makeCheck({
|
|
111
|
+
id: "stale_guard",
|
|
112
|
+
label: "Stale-state guard",
|
|
113
|
+
status: "pass",
|
|
114
|
+
score: 15,
|
|
115
|
+
maxScore: 15,
|
|
116
|
+
detail: "Flight recorder permits continuation with complete state.",
|
|
117
|
+
evidence,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
const reasons = [
|
|
121
|
+
"canContinue is false",
|
|
122
|
+
...(!resume.hasCompleteState ? ["incomplete resume state"] : []),
|
|
123
|
+
...(resume.recorderHealth.status !== "ok" ? [`recorder health is ${resume.recorderHealth.status}`] : []),
|
|
124
|
+
...(resume.blockedBecause.length > 0 ? resume.blockedBecause : []),
|
|
125
|
+
];
|
|
126
|
+
return makeCheck({
|
|
127
|
+
id: "stale_guard",
|
|
128
|
+
label: "Stale-state guard",
|
|
129
|
+
status: "fail",
|
|
130
|
+
score: 0,
|
|
131
|
+
maxScore: 15,
|
|
132
|
+
detail: `Flight recorder says continuation is unsafe: ${reasons.join("; ")}.`,
|
|
133
|
+
evidence,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
function obligationsCheck(card) {
|
|
137
|
+
if (card.counts.owed === 0) {
|
|
138
|
+
return makeCheck({
|
|
139
|
+
id: "obligations_visible",
|
|
140
|
+
label: "Obligations",
|
|
141
|
+
status: "not_applicable",
|
|
142
|
+
score: 0,
|
|
143
|
+
maxScore: 0,
|
|
144
|
+
detail: "No owed obligations are active.",
|
|
145
|
+
evidence: [],
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
const evidence = card.owed.map((item) => item.source);
|
|
149
|
+
return makeCheck({
|
|
150
|
+
id: "obligations_visible",
|
|
151
|
+
label: "Obligations",
|
|
152
|
+
status: "pass",
|
|
153
|
+
score: 10,
|
|
154
|
+
maxScore: 10,
|
|
155
|
+
detail: `${card.counts.owed} owed obligation(s) have source locators.`,
|
|
156
|
+
evidence,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
function returnRoutesCheck(card) {
|
|
160
|
+
if (card.counts.returnObligations === 0) {
|
|
161
|
+
return makeCheck({
|
|
162
|
+
id: "return_routes_visible",
|
|
163
|
+
label: "Return routes",
|
|
164
|
+
status: "not_applicable",
|
|
165
|
+
score: 0,
|
|
166
|
+
maxScore: 0,
|
|
167
|
+
detail: "No active return obligations are queued.",
|
|
168
|
+
evidence: [],
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
const evidence = card.returnObligations.map((item) => item.source);
|
|
172
|
+
return makeCheck({
|
|
173
|
+
id: "return_routes_visible",
|
|
174
|
+
label: "Return routes",
|
|
175
|
+
status: "pass",
|
|
176
|
+
score: 10,
|
|
177
|
+
maxScore: 10,
|
|
178
|
+
detail: `${card.counts.returnObligations} return route(s) are visible.`,
|
|
179
|
+
evidence,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
function blockersCheck(card) {
|
|
183
|
+
if (card.counts.waitingOnHuman === 0) {
|
|
184
|
+
return makeCheck({
|
|
185
|
+
id: "blockers_surface",
|
|
186
|
+
label: "Blockers",
|
|
187
|
+
status: "not_applicable",
|
|
188
|
+
score: 0,
|
|
189
|
+
maxScore: 0,
|
|
190
|
+
detail: "No waiting or blocked work is active.",
|
|
191
|
+
evidence: [],
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
const evidence = card.waitingOnOthers.map((item) => item.source);
|
|
195
|
+
return makeCheck({
|
|
196
|
+
id: "blockers_surface",
|
|
197
|
+
label: "Blockers",
|
|
198
|
+
status: "pass",
|
|
199
|
+
score: 10,
|
|
200
|
+
maxScore: 10,
|
|
201
|
+
detail: "Waiting work controls the next action.",
|
|
202
|
+
evidence,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
function deskRecordCheck(agentRoot) {
|
|
206
|
+
const recordPaths = (0, record_paths_1.resolveDeskRecordPaths)(agentRoot);
|
|
207
|
+
const requiredPaths = [
|
|
208
|
+
recordPaths.recordRoot,
|
|
209
|
+
recordPaths.diaryRoot,
|
|
210
|
+
recordPaths.diaryDailyDir,
|
|
211
|
+
recordPaths.notesRoot,
|
|
212
|
+
recordPaths.factsPath,
|
|
213
|
+
recordPaths.entitiesPath,
|
|
214
|
+
];
|
|
215
|
+
const missing = requiredPaths
|
|
216
|
+
.filter((entry) => !fs.existsSync(entry))
|
|
217
|
+
.map((entry) => path.relative(agentRoot, entry));
|
|
218
|
+
const legacyRoots = ["journal", "diary"]
|
|
219
|
+
.map((entry) => path.join(agentRoot, entry))
|
|
220
|
+
.filter((entry) => fs.existsSync(entry))
|
|
221
|
+
.map((entry) => path.relative(agentRoot, entry));
|
|
222
|
+
if (legacyRoots.length > 0) {
|
|
223
|
+
return makeCheck({
|
|
224
|
+
id: "desk_record_ready",
|
|
225
|
+
label: "Desk record",
|
|
226
|
+
status: "fail",
|
|
227
|
+
score: 0,
|
|
228
|
+
maxScore: 10,
|
|
229
|
+
detail: `Legacy active record root(s) still exist: ${legacyRoots.join(", ")}.`,
|
|
230
|
+
evidence: [],
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
if (missing.length > 0) {
|
|
234
|
+
return makeCheck({
|
|
235
|
+
id: "desk_record_ready",
|
|
236
|
+
label: "Desk record",
|
|
237
|
+
status: "warn",
|
|
238
|
+
score: 5,
|
|
239
|
+
maxScore: 10,
|
|
240
|
+
detail: `Canonical Desk record scaffold is incomplete: ${missing.join(", ")}.`,
|
|
241
|
+
evidence: [],
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
return makeCheck({
|
|
245
|
+
id: "desk_record_ready",
|
|
246
|
+
label: "Desk record",
|
|
247
|
+
status: "pass",
|
|
248
|
+
score: 10,
|
|
249
|
+
maxScore: 10,
|
|
250
|
+
detail: "Canonical Desk record scaffold is present and no legacy record roots are active.",
|
|
251
|
+
evidence: [],
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
function sourceProvenanceCheck(card) {
|
|
255
|
+
const evidence = card.sources;
|
|
256
|
+
if (card.degraded.issues.length > 0) {
|
|
257
|
+
return makeCheck({
|
|
258
|
+
id: "source_provenance",
|
|
259
|
+
label: "Source provenance",
|
|
260
|
+
status: "fail",
|
|
261
|
+
score: 0,
|
|
262
|
+
maxScore: 15,
|
|
263
|
+
detail: `${card.degraded.issues.length} Work Card source issue(s) are present.`,
|
|
264
|
+
evidence,
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
return makeCheck({
|
|
268
|
+
id: "source_provenance",
|
|
269
|
+
label: "Source provenance",
|
|
270
|
+
status: "pass",
|
|
271
|
+
score: 15,
|
|
272
|
+
maxScore: 15,
|
|
273
|
+
detail: "Work Card source locators are intact.",
|
|
274
|
+
evidence,
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
function summarize(verdict) {
|
|
278
|
+
if (verdict === "ready")
|
|
279
|
+
return "ready: durable Arc, flight recorder, and Desk state can carry context-loss recovery";
|
|
280
|
+
if (verdict === "watch")
|
|
281
|
+
return "watch: recovery is possible, but warnings need attention";
|
|
282
|
+
return "blocked: context-loss recovery would lose or mislead the agent";
|
|
283
|
+
}
|
|
284
|
+
function runContextLossGauntlet(agentName, agentRoot, options = {}) {
|
|
285
|
+
const flightRecorderResume = (0, flight_recorder_1.readFlightRecorderResume)(agentRoot);
|
|
286
|
+
const card = (0, work_card_1.buildWorkCard)(agentName, agentRoot, { ...options, flightRecorderResume });
|
|
287
|
+
const generatedAt = (options.now ?? (() => new Date()))().toISOString();
|
|
288
|
+
const checks = [
|
|
289
|
+
currentAskCheck(card),
|
|
290
|
+
nextSafeActionCheck(card),
|
|
291
|
+
staleGuardCheck(flightRecorderResume, card),
|
|
292
|
+
obligationsCheck(card),
|
|
293
|
+
returnRoutesCheck(card),
|
|
294
|
+
blockersCheck(card),
|
|
295
|
+
deskRecordCheck(agentRoot),
|
|
296
|
+
sourceProvenanceCheck(card),
|
|
297
|
+
];
|
|
298
|
+
const earned = checks.reduce((sum, check) => sum + check.score, 0);
|
|
299
|
+
const possible = checks.reduce((sum, check) => sum + check.maxScore, 0);
|
|
300
|
+
const percentage = Math.round((earned / possible) * 100);
|
|
301
|
+
const verdict = checks.some((check) => check.status === "fail")
|
|
302
|
+
? "blocked"
|
|
303
|
+
: checks.some((check) => check.status === "warn")
|
|
304
|
+
? "watch"
|
|
305
|
+
: "ready";
|
|
306
|
+
const report = {
|
|
307
|
+
schemaVersion: 1,
|
|
308
|
+
agent: card.agent,
|
|
309
|
+
generatedAt,
|
|
310
|
+
verdict,
|
|
311
|
+
summary: summarize(verdict),
|
|
312
|
+
score: { earned, possible, percentage },
|
|
313
|
+
currentAsk: card.currentAsk,
|
|
314
|
+
nextAction: card.nextAction,
|
|
315
|
+
counts: card.counts,
|
|
316
|
+
checks,
|
|
317
|
+
workCard: card,
|
|
318
|
+
};
|
|
319
|
+
(0, runtime_1.emitNervesEvent)({
|
|
320
|
+
component: "engine",
|
|
321
|
+
event: "engine.context_loss_gauntlet_ran",
|
|
322
|
+
message: "context-loss gauntlet scored durable recovery state",
|
|
323
|
+
meta: {
|
|
324
|
+
agent: card.agent,
|
|
325
|
+
verdict: report.verdict,
|
|
326
|
+
scorePercentage: report.score.percentage,
|
|
327
|
+
failedChecks: report.checks.filter((check) => check.status === "fail").map((check) => check.id),
|
|
328
|
+
warnedChecks: report.checks.filter((check) => check.status === "warn").map((check) => check.id),
|
|
329
|
+
},
|
|
330
|
+
});
|
|
331
|
+
return report;
|
|
332
|
+
}
|
|
333
|
+
function statusToken(status) {
|
|
334
|
+
if (status === "not_applicable")
|
|
335
|
+
return "N/A";
|
|
336
|
+
return status.toUpperCase();
|
|
337
|
+
}
|
|
338
|
+
function formatContextLossGauntletText(report) {
|
|
339
|
+
return [
|
|
340
|
+
`Context-loss gauntlet - ${report.agent}`,
|
|
341
|
+
`generated: ${report.generatedAt}`,
|
|
342
|
+
`verdict: ${report.verdict} (${report.score.earned}/${report.score.possible}, ${report.score.percentage}%)`,
|
|
343
|
+
`summary: ${report.summary}`,
|
|
344
|
+
"",
|
|
345
|
+
"Recovery",
|
|
346
|
+
report.currentAsk.available
|
|
347
|
+
? ` current ask: ${report.currentAsk.value} (${report.currentAsk.confidence})`
|
|
348
|
+
: ` current ask: unavailable (${report.currentAsk.source})`,
|
|
349
|
+
` next action: ${report.nextAction.actor}: ${report.nextAction.summary}`,
|
|
350
|
+
"",
|
|
351
|
+
"Checks",
|
|
352
|
+
...report.checks.map((check) => ` - ${statusToken(check.status)} ${check.id}: ${check.detail}`),
|
|
353
|
+
].join("\n").trim();
|
|
354
|
+
}
|
|
@@ -366,6 +366,7 @@ function agentResolutionFailureMode(command) {
|
|
|
366
366
|
case "attention.show":
|
|
367
367
|
case "attention.history":
|
|
368
368
|
case "work.card":
|
|
369
|
+
case "work.gauntlet":
|
|
369
370
|
case "inner.status":
|
|
370
371
|
case "session.list":
|
|
371
372
|
return "return-message";
|
|
@@ -7290,6 +7291,18 @@ async function runOuroCli(args, deps = (0, cli_defaults_1.createDefaultOuroCliDe
|
|
|
7290
7291
|
deps.writeStdout(message);
|
|
7291
7292
|
return message;
|
|
7292
7293
|
}
|
|
7294
|
+
// ── context-loss gauntlet (local, no daemon socket needed) ──
|
|
7295
|
+
if (command.kind === "work.gauntlet") {
|
|
7296
|
+
const { runContextLossGauntlet, formatContextLossGauntletText } = await Promise.resolve().then(() => __importStar(require("../context-loss-gauntlet")));
|
|
7297
|
+
if (!command.agent)
|
|
7298
|
+
throw new Error("work gauntlet requires --agent <name>");
|
|
7299
|
+
const bundlesRoot = deps.bundlesRoot ?? (0, identity_1.getAgentBundlesRoot)();
|
|
7300
|
+
const agentRoot = deps.agentBundleRoot ?? path.join(bundlesRoot, `${command.agent}.ouro`);
|
|
7301
|
+
const report = runContextLossGauntlet(command.agent, agentRoot, { homeDir: deps.homeDir });
|
|
7302
|
+
const message = command.format === "json" ? JSON.stringify(report, null, 2) : formatContextLossGauntletText(report);
|
|
7303
|
+
deps.writeStdout(message);
|
|
7304
|
+
return message;
|
|
7305
|
+
}
|
|
7293
7306
|
// ── inner dialog status (local, no daemon socket needed) ──
|
|
7294
7307
|
/* v8 ignore start -- inner status handler: requires real agent state on disk @preserve */
|
|
7295
7308
|
if (command.kind === "inner.status") {
|
|
@@ -153,10 +153,10 @@ exports.COMMAND_REGISTRY = {
|
|
|
153
153
|
},
|
|
154
154
|
work: {
|
|
155
155
|
category: "Tasks",
|
|
156
|
-
description: "Show
|
|
157
|
-
usage: "ouro work card [--agent <name>] [--format text|json|--json]",
|
|
158
|
-
example: "ouro work
|
|
159
|
-
subcommands: ["card"],
|
|
156
|
+
description: "Show durable Arc work state or run the context-loss gauntlet.",
|
|
157
|
+
usage: "ouro work card|gauntlet [--agent <name>] [--format text|json|--json]",
|
|
158
|
+
example: "ouro work gauntlet --agent slugger --format json",
|
|
159
|
+
subcommands: ["card", "gauntlet"],
|
|
160
160
|
},
|
|
161
161
|
"work card": {
|
|
162
162
|
category: "Tasks",
|
|
@@ -165,6 +165,13 @@ exports.COMMAND_REGISTRY = {
|
|
|
165
165
|
example: "ouro work card --agent slugger --format json",
|
|
166
166
|
hidden: true,
|
|
167
167
|
},
|
|
168
|
+
"work gauntlet": {
|
|
169
|
+
category: "Tasks",
|
|
170
|
+
description: "Score whether durable Arc, flight recorder, and Desk state can recover after context loss.",
|
|
171
|
+
usage: "ouro work gauntlet [--agent <name>] [--format text|json|--json]",
|
|
172
|
+
example: "ouro work gauntlet --agent slugger --format json",
|
|
173
|
+
hidden: true,
|
|
174
|
+
},
|
|
168
175
|
"migrate-to-desk": {
|
|
169
176
|
category: "Tasks",
|
|
170
177
|
description: "Migrate a legacy `tasks/` tree into the new `desk/` shape (copy semantics — source untouched).",
|
|
@@ -114,7 +114,7 @@ function usage() {
|
|
|
114
114
|
" ouro friend create --name <name> [--trust <level>] [--agent <name>]",
|
|
115
115
|
" ouro friend update <id> --trust <level> [--agent <name>]",
|
|
116
116
|
" ouro thoughts [--last <n>] [--json] [--follow] [--agent <name>]",
|
|
117
|
-
" ouro work card [--agent <name>] [--format text|json|--json]",
|
|
117
|
+
" ouro work card|gauntlet [--agent <name>] [--format text|json|--json]",
|
|
118
118
|
" ouro inner [--agent <name>]",
|
|
119
119
|
" ouro friend link <agent> --friend <id> --provider <p> --external-id <eid>",
|
|
120
120
|
" ouro friend unlink <agent> --friend <id> --provider <p> --external-id <eid>",
|
|
@@ -1004,8 +1004,9 @@ function parseAttentionCommand(args) {
|
|
|
1004
1004
|
function parseWorkCommand(args) {
|
|
1005
1005
|
const { agent, rest: cleaned } = extractAgentFlag(args);
|
|
1006
1006
|
const sub = cleaned[0];
|
|
1007
|
-
if (sub !== "card")
|
|
1008
|
-
throw new Error("Usage: ouro work card [--agent <name>] [--format text|json|--json]");
|
|
1007
|
+
if (sub !== "card" && sub !== "gauntlet") {
|
|
1008
|
+
throw new Error("Usage: ouro work card|gauntlet [--agent <name>] [--format text|json|--json]");
|
|
1009
|
+
}
|
|
1009
1010
|
let format = "text";
|
|
1010
1011
|
for (let i = 1; i < cleaned.length; i += 1) {
|
|
1011
1012
|
if (cleaned[i] === "--json") {
|
|
@@ -1020,9 +1021,9 @@ function parseWorkCommand(args) {
|
|
|
1020
1021
|
format = value;
|
|
1021
1022
|
continue;
|
|
1022
1023
|
}
|
|
1023
|
-
throw new Error(
|
|
1024
|
+
throw new Error(`Usage: ouro work ${sub} [--agent <name>] [--format text|json|--json]`);
|
|
1024
1025
|
}
|
|
1025
|
-
return { kind: "work.card", ...(agent ? { agent } : {}), ...(format !== "text" ? { format } : {}) };
|
|
1026
|
+
return { kind: sub === "card" ? "work.card" : "work.gauntlet", ...(agent ? { agent } : {}), ...(format !== "text" ? { format } : {}) };
|
|
1026
1027
|
}
|
|
1027
1028
|
function parseThoughtsCommand(args) {
|
|
1028
1029
|
const { agent, rest: cleaned } = extractAgentFlag(args);
|
|
@@ -54,6 +54,7 @@ function createMailboxHttpReadHooks(options) {
|
|
|
54
54
|
readAgentObligations: options.readAgentObligations ?? ((agentName) => (0, mailbox_read_1.readObligationDetailView)(agentRoot(agentName))),
|
|
55
55
|
readAgentChanges: options.readAgentChanges ?? ((agentName) => (0, mailbox_read_1.readChangesView)(agentRoot(agentName))),
|
|
56
56
|
readAgentSelfFix: options.readAgentSelfFix ?? ((agentName) => (0, mailbox_read_1.readSelfFixView)(agentRoot(agentName))),
|
|
57
|
+
readAgentContextLossGauntlet: options.readAgentContextLossGauntlet ?? ((agentName) => (0, mailbox_read_1.readContextLossGauntletView)(agentRoot(agentName), agentName)),
|
|
57
58
|
readAgentNoteDecisions: options.readAgentNoteDecisions ?? ((agentName) => (0, mailbox_read_1.readNoteDecisionView)(agentRoot(agentName))),
|
|
58
59
|
readAgentHabits: options.readAgentHabits ?? ((agentName) => (0, mailbox_read_1.readHabitView)(agentRoot(agentName))),
|
|
59
60
|
readAgentMail: options.readAgentMail ?? ((agentName) => (0, mailbox_read_1.readMailView)(agentName)),
|
|
@@ -172,6 +172,10 @@ async function handleAgentRoute(request, response, context) {
|
|
|
172
172
|
(0, mailbox_http_response_1.writeJson)(response, 200, options.hooks.readAgentSelfFix(agent));
|
|
173
173
|
return;
|
|
174
174
|
}
|
|
175
|
+
if (surface === "context-loss-gauntlet") {
|
|
176
|
+
(0, mailbox_http_response_1.writeJson)(response, 200, options.hooks.readAgentContextLossGauntlet(agent));
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
175
179
|
if (surface === "note-decisions") {
|
|
176
180
|
(0, mailbox_http_response_1.writeJson)(response, 200, options.hooks.readAgentNoteDecisions(agent));
|
|
177
181
|
return;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.readSelfFixView = exports.readMailboxContinuity = exports.readOrientationView = exports.readObligationDetailView = exports.readNoteDecisionView = exports.readChangesView = exports.readNeedsMeView = exports.readNotesView = exports.readLogView = exports.readHabitView = exports.readFriendView = exports.readDeskPrefs = exports.readDaemonHealthDeep = exports.readCodingDeep = exports.readBridgeInventory = exports.readAttentionView = exports.readMailView = exports.readMailMessageView = exports.readSessionTranscript = exports.readSessionInventory = exports.readMailboxMachineState = exports.readMailboxAgentState = exports.readObligationSummary = void 0;
|
|
3
|
+
exports.readSelfFixView = exports.readMailboxContinuity = exports.readOrientationView = exports.readObligationDetailView = exports.readNoteDecisionView = exports.readContextLossGauntletView = exports.readChangesView = exports.readNeedsMeView = exports.readNotesView = exports.readLogView = exports.readHabitView = exports.readFriendView = exports.readDeskPrefs = exports.readDaemonHealthDeep = exports.readCodingDeep = exports.readBridgeInventory = exports.readAttentionView = exports.readMailView = exports.readMailMessageView = exports.readSessionTranscript = exports.readSessionInventory = exports.readMailboxMachineState = exports.readMailboxAgentState = exports.readObligationSummary = void 0;
|
|
4
4
|
var agent_machine_1 = require("./readers/agent-machine");
|
|
5
5
|
Object.defineProperty(exports, "readObligationSummary", { enumerable: true, get: function () { return agent_machine_1.readObligationSummary; } });
|
|
6
6
|
Object.defineProperty(exports, "readMailboxAgentState", { enumerable: true, get: function () { return agent_machine_1.readMailboxAgentState; } });
|
|
@@ -24,6 +24,7 @@ Object.defineProperty(exports, "readNotesView", { enumerable: true, get: functio
|
|
|
24
24
|
Object.defineProperty(exports, "readNeedsMeView", { enumerable: true, get: function () { return runtime_readers_1.readNeedsMeView; } });
|
|
25
25
|
var continuity_readers_1 = require("./readers/continuity-readers");
|
|
26
26
|
Object.defineProperty(exports, "readChangesView", { enumerable: true, get: function () { return continuity_readers_1.readChangesView; } });
|
|
27
|
+
Object.defineProperty(exports, "readContextLossGauntletView", { enumerable: true, get: function () { return continuity_readers_1.readContextLossGauntletView; } });
|
|
27
28
|
Object.defineProperty(exports, "readNoteDecisionView", { enumerable: true, get: function () { return continuity_readers_1.readNoteDecisionView; } });
|
|
28
29
|
Object.defineProperty(exports, "readObligationDetailView", { enumerable: true, get: function () { return continuity_readers_1.readObligationDetailView; } });
|
|
29
30
|
Object.defineProperty(exports, "readOrientationView", { enumerable: true, get: function () { return continuity_readers_1.readOrientationView; } });
|
|
@@ -38,6 +38,7 @@ exports.readOrientationView = readOrientationView;
|
|
|
38
38
|
exports.readObligationDetailView = readObligationDetailView;
|
|
39
39
|
exports.readChangesView = readChangesView;
|
|
40
40
|
exports.readSelfFixView = readSelfFixView;
|
|
41
|
+
exports.readContextLossGauntletView = readContextLossGauntletView;
|
|
41
42
|
exports.readNoteDecisionView = readNoteDecisionView;
|
|
42
43
|
const fs = __importStar(require("fs"));
|
|
43
44
|
const path = __importStar(require("path"));
|
|
@@ -48,6 +49,7 @@ const obligations_1 = require("../../../arc/obligations");
|
|
|
48
49
|
const presence_1 = require("../../../arc/presence");
|
|
49
50
|
const active_work_1 = require("../../active-work");
|
|
50
51
|
const session_activity_1 = require("../../session-activity");
|
|
52
|
+
const context_loss_gauntlet_1 = require("../../context-loss-gauntlet");
|
|
51
53
|
const agent_machine_1 = require("./agent-machine");
|
|
52
54
|
function sortOpenObligations(obligations) {
|
|
53
55
|
const statusPriority = {
|
|
@@ -290,6 +292,9 @@ function readSelfFixView(_agentRoot) {
|
|
|
290
292
|
});
|
|
291
293
|
return { active: false, currentStep: null, steps: [] };
|
|
292
294
|
}
|
|
295
|
+
function readContextLossGauntletView(agentRoot, agentName) {
|
|
296
|
+
return (0, context_loss_gauntlet_1.runContextLossGauntlet)(agentName, agentRoot);
|
|
297
|
+
}
|
|
293
298
|
function readNoteDecisionView(agentRoot, limit = 50) {
|
|
294
299
|
const logPath = path.join(agentRoot, "state", "mailbox", "note-decisions.jsonl");
|
|
295
300
|
const legacyLogPath = path.join(agentRoot, "state", "outlook", "note-decisions.jsonl");
|
package/dist/heart/work-card.js
CHANGED
|
@@ -246,7 +246,7 @@ function buildWorkCard(agentName, agentRoot, options = {}) {
|
|
|
246
246
|
const evolutionCases = (0, evolution_1.listOpenEvolutionCases)(agentRoot).map(evolutionItem);
|
|
247
247
|
const activeWork = [...activePackets, ...evolutionCases];
|
|
248
248
|
const waiting = waitingOnHuman([...owed, ...returnObligations, ...activeWork]);
|
|
249
|
-
const flightRecorderResume = (0, flight_recorder_1.readFlightRecorderResume)(agentRoot);
|
|
249
|
+
const flightRecorderResume = options.flightRecorderResume ?? (0, flight_recorder_1.readFlightRecorderResume)(agentRoot);
|
|
250
250
|
const claims = {
|
|
251
251
|
available: false,
|
|
252
252
|
unavailableReason: "WorkClaim store is not implemented yet; unverified claim counts are unknown, not zero.",
|