@ouro.bot/cli 0.1.0-alpha.665 → 0.1.0-alpha.667

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 (35) hide show
  1. package/changelog.json +13 -0
  2. package/dist/arc/flight-recorder.js +324 -5
  3. package/dist/heart/core.js +167 -4
  4. package/dist/heart/cross-chat-delivery.js +3 -2
  5. package/dist/heart/daemon/cli-exec.js +139 -1
  6. package/dist/heart/daemon/cli-help.js +13 -2
  7. package/dist/heart/daemon/cli-parse.js +138 -2
  8. package/dist/heart/daemon/daemon-entry.js +24 -5
  9. package/dist/heart/daemon/daemon.js +10 -1
  10. package/dist/heart/habits/habit-parser.js +8 -0
  11. package/dist/heart/habits/habit-runtime-state.js +17 -3
  12. package/dist/heart/habits/habit-scheduler.js +24 -5
  13. package/dist/heart/habits/habit-session-summary.js +318 -0
  14. package/dist/heart/habits/habit-session.js +618 -0
  15. package/dist/heart/mailbox/mailbox-http-hooks.js +29 -1
  16. package/dist/heart/mailbox/mailbox-http-routes.js +122 -1
  17. package/dist/heart/mailbox/mailbox-read.js +5 -1
  18. package/dist/heart/mailbox/readers/runtime-readers.js +87 -0
  19. package/dist/mailbox-ui/assets/index-CaTIFDmv.js +1 -0
  20. package/dist/mailbox-ui/assets/index-Du_9G9WO.css +1 -0
  21. package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
  22. package/dist/mailbox-ui/index.html +3 -2
  23. package/dist/repertoire/tools-notes.js +50 -0
  24. package/dist/repertoire/tools-record.js +13 -0
  25. package/dist/repertoire/tools-session.js +140 -0
  26. package/dist/repertoire/tools-surface.js +11 -0
  27. package/dist/repertoire/tools.js +7 -0
  28. package/dist/senses/habit-turn-message.js +41 -3
  29. package/dist/senses/inner-dialog-worker.js +264 -68
  30. package/dist/senses/inner-dialog.js +29 -15
  31. package/dist/senses/pipeline.js +2 -11
  32. package/dist/senses/surface-tool.js +2 -1
  33. package/package.json +1 -1
  34. package/dist/mailbox-ui/assets/index-BZ60na8O.js +0 -61
  35. package/dist/mailbox-ui/assets/index-DG6Xf5uL.css +0 -1
@@ -36,11 +36,77 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.createMailboxHttpRequestHandler = createMailboxHttpRequestHandler;
37
37
  const fs = __importStar(require("fs"));
38
38
  const path = __importStar(require("path"));
39
+ const mailbox_http_hooks_1 = require("./mailbox-http-hooks");
39
40
  const mailbox_http_response_1 = require("./mailbox-http-response");
40
41
  const mailbox_http_static_1 = require("./mailbox-http-static");
42
+ function decodePathSegment(value) {
43
+ try {
44
+ return decodeURIComponent(value);
45
+ }
46
+ catch {
47
+ return null;
48
+ }
49
+ }
50
+ function rawRequestTargetsUnsafeAgent(urlValue = "/") {
51
+ const rawTarget = urlValue.split(/[?#]/, 1)[0];
52
+ const rawPath = rawTarget.replace(/\/+$/, "") || "/";
53
+ const pathname = (0, mailbox_http_static_1.normalizeLegacyMailboxApiPath)(rawPath);
54
+ const rawAgentMatch = /^\/api\/agents\/([^/]+)(?:\/|$)/.exec(pathname);
55
+ if (!rawAgentMatch)
56
+ return false;
57
+ const agent = decodePathSegment(rawAgentMatch[1]);
58
+ return !agent || !(0, mailbox_http_hooks_1.isSafeMailboxAgentName)(agent);
59
+ }
60
+ function parseHabitRunLimit(urlValue) {
61
+ const rawLimit = new URL(urlValue, "http://127.0.0.1").searchParams.get("limit");
62
+ if (rawLimit === null)
63
+ return undefined;
64
+ if (!/^[1-9][0-9]*$/.test(rawLimit))
65
+ return null;
66
+ const limit = Number.parseInt(rawLimit, 10);
67
+ return limit >= 1 && limit <= 100 ? limit : null;
68
+ }
69
+ const VALID_HABIT_SUMMARY_WHICH = new Set(["latest", "previous", "latest-success", "latest-failure"]);
70
+ function firstQueryValue(params, names) {
71
+ for (const name of names) {
72
+ const value = params.get(name);
73
+ if (value !== null && value.trim().length > 0)
74
+ return value;
75
+ }
76
+ return undefined;
77
+ }
78
+ function parseHabitSummarySelector(urlValue) {
79
+ const params = new URL(urlValue, "http://127.0.0.1").searchParams;
80
+ const runId = firstQueryValue(params, ["runId", "run-id"]);
81
+ const habitName = firstQueryValue(params, ["habitName", "habit"]);
82
+ const operationId = firstQueryValue(params, ["operationId", "operation-id"]);
83
+ const which = firstQueryValue(params, ["which"]);
84
+ if (runId !== undefined && (habitName !== undefined || operationId !== undefined || which !== undefined)) {
85
+ return { ok: false, error: "--run-id cannot be combined with --habit, --operation-id, or --which" };
86
+ }
87
+ if (runId === undefined && habitName === undefined && operationId === undefined) {
88
+ return { ok: false, error: "provide runId, habitName, or operationId" };
89
+ }
90
+ if (which !== undefined && !VALID_HABIT_SUMMARY_WHICH.has(which)) {
91
+ return { ok: false, error: "which must be latest, previous, latest-success, or latest-failure" };
92
+ }
93
+ return {
94
+ ok: true,
95
+ selector: {
96
+ ...(runId ? { runId } : {}),
97
+ ...(habitName ? { habitName } : {}),
98
+ ...(operationId ? { operationId } : {}),
99
+ ...(which ? { which } : {}),
100
+ },
101
+ };
102
+ }
41
103
  function createMailboxHttpRequestHandler(options) {
42
104
  const staticFiles = options.staticFiles ?? { resolveSpaDistDir: mailbox_http_static_1.resolveSpaDistDir, serveStaticFile: mailbox_http_static_1.serveStaticFile };
43
105
  return (request, response) => {
106
+ if (rawRequestTargetsUnsafeAgent(request.url)) {
107
+ (0, mailbox_http_response_1.writeJson)(response, 400, { ok: false, error: "agent name must be a safe bundle name" });
108
+ return;
109
+ }
44
110
  let pathname = (0, mailbox_http_static_1.normalizeMailboxRequestPath)(request.url);
45
111
  const origin = `http://${options.host}:${options.getPort()}`;
46
112
  if (pathname.startsWith("/assets/")) {
@@ -82,8 +148,14 @@ function createMailboxHttpRequestHandler(options) {
82
148
  }
83
149
  const agentMatch = /^\/api\/agents\/([^/]+)(?:\/(.+))?$/.exec(pathname);
84
150
  if (agentMatch) {
151
+ const agent = decodePathSegment(agentMatch[1]);
152
+ /* v8 ignore next -- rawRequestTargetsUnsafeAgent rejects unsafe/malformed agent segments before normalization @preserve */
153
+ if (!agent || !(0, mailbox_http_hooks_1.isSafeMailboxAgentName)(agent)) {
154
+ (0, mailbox_http_response_1.writeJson)(response, 400, { ok: false, error: "agent name must be a safe bundle name" });
155
+ return;
156
+ }
85
157
  void handleAgentRoute(request, response, {
86
- agent: decodeURIComponent(agentMatch[1]),
158
+ agent,
87
159
  surface: agentMatch[2] ?? null,
88
160
  options,
89
161
  }).catch((error) => {
@@ -200,6 +272,55 @@ async function handleAgentRoute(request, response, context) {
200
272
  (0, mailbox_http_response_1.writeJson)(response, 200, options.hooks.readAgentHabits(agent));
201
273
  return;
202
274
  }
275
+ if (surface === "habit-runs") {
276
+ const limit = parseHabitRunLimit(request.url);
277
+ if (limit === null) {
278
+ (0, mailbox_http_response_1.writeJson)(response, 400, { ok: false, error: "limit must be an integer between 1 and 100" });
279
+ return;
280
+ }
281
+ const view = limit === undefined
282
+ ? options.hooks.readAgentHabitRuns(agent)
283
+ : options.hooks.readAgentHabitRuns(agent, { limit });
284
+ (0, mailbox_http_response_1.writeJson)(response, 200, view);
285
+ return;
286
+ }
287
+ if (surface === "habit-run-summaries") {
288
+ const limit = parseHabitRunLimit(request.url);
289
+ if (limit === null) {
290
+ (0, mailbox_http_response_1.writeJson)(response, 400, { ok: false, error: "limit must be an integer between 1 and 100" });
291
+ return;
292
+ }
293
+ const view = limit === undefined
294
+ ? options.hooks.readAgentHabitRunSummaries(agent)
295
+ : options.hooks.readAgentHabitRunSummaries(agent, { limit });
296
+ (0, mailbox_http_response_1.writeJson)(response, 200, view);
297
+ return;
298
+ }
299
+ if (surface === "habit-run-summary") {
300
+ const parsed = parseHabitSummarySelector(request.url);
301
+ if (!parsed.ok) {
302
+ (0, mailbox_http_response_1.writeJson)(response, 400, { ok: false, error: parsed.error });
303
+ return;
304
+ }
305
+ const summary = options.hooks.readAgentHabitRunSummary(agent, parsed.selector);
306
+ if (!summary) {
307
+ (0, mailbox_http_response_1.writeJson)(response, 404, { ok: false, error: "habit summary not found" });
308
+ return;
309
+ }
310
+ (0, mailbox_http_response_1.writeJson)(response, 200, summary);
311
+ return;
312
+ }
313
+ if (surface.startsWith("habit-runs/")) {
314
+ const rawRunId = surface.slice("habit-runs/".length);
315
+ const runId = decodePathSegment(rawRunId);
316
+ const view = runId ? options.hooks.readAgentHabitRun(agent, runId) : null;
317
+ if (!view) {
318
+ (0, mailbox_http_response_1.writeJson)(response, 404, { ok: false, error: `habit run '${rawRunId}' not found` });
319
+ return;
320
+ }
321
+ (0, mailbox_http_response_1.writeJson)(response, 200, view);
322
+ return;
323
+ }
203
324
  if (surface === "mail") {
204
325
  (0, mailbox_http_response_1.writeJson)(response, 200, await options.hooks.readAgentMail(agent));
205
326
  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.readSentinelView = 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;
3
+ exports.readSelfFixView = exports.readMailboxContinuity = exports.readOrientationView = exports.readObligationDetailView = exports.readNoteDecisionView = exports.readSentinelView = exports.readContextLossGauntletView = exports.readChangesView = exports.readNeedsMeView = exports.readNotesView = exports.readLogView = exports.readHabitView = exports.readHabitRunView = exports.readHabitRunReceiptView = exports.readHabitSessionSummaryView = exports.readHabitSessionSummaryListView = 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; } });
@@ -18,6 +18,10 @@ Object.defineProperty(exports, "readCodingDeep", { enumerable: true, get: functi
18
18
  Object.defineProperty(exports, "readDaemonHealthDeep", { enumerable: true, get: function () { return runtime_readers_1.readDaemonHealthDeep; } });
19
19
  Object.defineProperty(exports, "readDeskPrefs", { enumerable: true, get: function () { return runtime_readers_1.readDeskPrefs; } });
20
20
  Object.defineProperty(exports, "readFriendView", { enumerable: true, get: function () { return runtime_readers_1.readFriendView; } });
21
+ Object.defineProperty(exports, "readHabitSessionSummaryListView", { enumerable: true, get: function () { return runtime_readers_1.readHabitSessionSummaryListView; } });
22
+ Object.defineProperty(exports, "readHabitSessionSummaryView", { enumerable: true, get: function () { return runtime_readers_1.readHabitSessionSummaryView; } });
23
+ Object.defineProperty(exports, "readHabitRunReceiptView", { enumerable: true, get: function () { return runtime_readers_1.readHabitRunReceiptView; } });
24
+ Object.defineProperty(exports, "readHabitRunView", { enumerable: true, get: function () { return runtime_readers_1.readHabitRunView; } });
21
25
  Object.defineProperty(exports, "readHabitView", { enumerable: true, get: function () { return runtime_readers_1.readHabitView; } });
22
26
  Object.defineProperty(exports, "readLogView", { enumerable: true, get: function () { return runtime_readers_1.readLogView; } });
23
27
  Object.defineProperty(exports, "readNotesView", { enumerable: true, get: function () { return runtime_readers_1.readNotesView; } });
@@ -41,6 +41,10 @@ exports.readNotesView = readNotesView;
41
41
  exports.readFriendView = readFriendView;
42
42
  exports.readLogView = readLogView;
43
43
  exports.readHabitView = readHabitView;
44
+ exports.readHabitRunView = readHabitRunView;
45
+ exports.readHabitRunReceiptView = readHabitRunReceiptView;
46
+ exports.readHabitSessionSummaryListView = readHabitSessionSummaryListView;
47
+ exports.readHabitSessionSummaryView = readHabitSessionSummaryView;
44
48
  exports.readNeedsMeView = readNeedsMeView;
45
49
  exports.readDeskPrefs = readDeskPrefs;
46
50
  const fs = __importStar(require("fs"));
@@ -48,13 +52,17 @@ const path = __importStar(require("path"));
48
52
  const runtime_1 = require("../../../nerves/runtime");
49
53
  const habit_parser_1 = require("../../habits/habit-parser");
50
54
  const habit_runtime_state_1 = require("../../habits/habit-runtime-state");
55
+ const habit_session_summary_1 = require("../../habits/habit-session-summary");
51
56
  const identity_1 = require("../../identity");
52
57
  const daemon_health_1 = require("../../daemon/daemon-health");
58
+ const flight_recorder_1 = require("../../../arc/flight-recorder");
53
59
  const shared_1 = require("./shared");
54
60
  const agent_machine_1 = require("./agent-machine");
55
61
  const sessions_1 = require("./sessions");
56
62
  const record_paths_1 = require("../../../mind/record-paths");
57
63
  const NOTES_VIEW_LIMIT = 20;
64
+ const DEFAULT_HABIT_RUN_LIMIT = 20;
65
+ const MAX_HABIT_RUN_LIMIT = 100;
58
66
  /* v8 ignore start — defensive parsing of on-disk JSON, fallback branches are safety nets */
59
67
  function readCodingDeep(agentRoot) {
60
68
  const stateFilePath = path.join(agentRoot, "state", "coding", "sessions.json");
@@ -600,6 +608,85 @@ function readHabitView(agentRoot, options = {}) {
600
608
  items,
601
609
  };
602
610
  }
611
+ function normalizeHabitRunLimit(limit) {
612
+ if (limit === undefined || !Number.isInteger(limit))
613
+ return DEFAULT_HABIT_RUN_LIMIT;
614
+ return Math.min(MAX_HABIT_RUN_LIMIT, Math.max(1, limit));
615
+ }
616
+ function summarizeHabitRunReceipt(receipt) {
617
+ return {
618
+ runId: receipt.runId,
619
+ habitName: receipt.habitName,
620
+ trigger: receipt.trigger,
621
+ startedAt: receipt.startedAt,
622
+ endedAt: receipt.endedAt,
623
+ outcome: receipt.outcome,
624
+ nextRunAt: receipt.nextRunAt,
625
+ permissionEnvelope: receipt.permissionEnvelope,
626
+ toolPolicy: receipt.toolPolicy,
627
+ producedRefs: receipt.producedRefs,
628
+ surfaceAttempts: receipt.surfaceAttempts,
629
+ errorCount: receipt.errors.length,
630
+ errors: receipt.errors,
631
+ receiptLocator: receipt.receiptLocator,
632
+ sessionLocator: receipt.sessionLocator,
633
+ runtimeStateLocator: receipt.runtimeStateLocator,
634
+ };
635
+ }
636
+ function readHabitRunView(agentRoot, options = {}) {
637
+ const limit = normalizeHabitRunLimit(options.limit);
638
+ const receipts = (0, flight_recorder_1.listHabitRunReceipts)(agentRoot);
639
+ const items = receipts.slice(0, limit).map(summarizeHabitRunReceipt);
640
+ (0, runtime_1.emitNervesEvent)({
641
+ component: "heart",
642
+ event: "heart.mailbox_habit_runs_read",
643
+ message: "reading mailbox habit run receipts",
644
+ meta: { agentRoot, totalCount: receipts.length, limit, itemCount: items.length },
645
+ });
646
+ return {
647
+ totalCount: receipts.length,
648
+ limit,
649
+ items,
650
+ };
651
+ }
652
+ function readHabitRunReceiptView(agentRoot, runId) {
653
+ const receipt = (0, flight_recorder_1.readHabitRunReceipt)(agentRoot, runId);
654
+ (0, runtime_1.emitNervesEvent)({
655
+ component: "heart",
656
+ event: "heart.mailbox_habit_run_receipt_read",
657
+ message: "reading mailbox habit run receipt",
658
+ meta: { agentRoot, runId, found: receipt !== null },
659
+ });
660
+ return receipt ? { receipt } : null;
661
+ }
662
+ function readHabitSessionSummaryListView(agentRoot, options = {}) {
663
+ const limit = normalizeHabitRunLimit(options.limit);
664
+ const receipts = (0, flight_recorder_1.listHabitRunReceipts)(agentRoot);
665
+ const items = receipts.slice(0, limit)
666
+ .map((receipt) => (0, habit_session_summary_1.readHabitSessionSummary)(agentRoot, { runId: receipt.runId }))
667
+ .filter((summary) => summary !== null);
668
+ (0, runtime_1.emitNervesEvent)({
669
+ component: "heart",
670
+ event: "heart.mailbox_habit_run_summaries_read",
671
+ message: "reading mailbox habit run summaries",
672
+ meta: { agentRoot, totalCount: receipts.length, limit, itemCount: items.length },
673
+ });
674
+ return {
675
+ totalCount: receipts.length,
676
+ limit,
677
+ items,
678
+ };
679
+ }
680
+ function readHabitSessionSummaryView(agentRoot, selector) {
681
+ const summary = (0, habit_session_summary_1.readHabitSessionSummary)(agentRoot, selector);
682
+ (0, runtime_1.emitNervesEvent)({
683
+ component: "heart",
684
+ event: "heart.mailbox_habit_run_summary_read",
685
+ message: "reading mailbox habit run summary",
686
+ meta: { agentRoot, runId: summary?.runId ?? null, habitName: summary?.habitName ?? selector.habitName ?? null, found: summary !== null },
687
+ });
688
+ return summary;
689
+ }
603
690
  function readNeedsMeView(agentName, options = {}) {
604
691
  const bundlesRoot = options.bundlesRoot ?? (0, identity_1.getAgentBundlesRoot)();
605
692
  const now = options.now?.() ?? new Date();