@ouro.bot/cli 0.1.0-alpha.674 → 0.1.0-alpha.676
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/README.md +11 -5
- package/changelog.json +19 -0
- package/dist/arc/evolution.js +13 -10
- package/dist/arc/obligations.js +1 -1
- package/dist/heart/active-work.js +3 -3
- package/dist/heart/agent-entry.js +8 -8
- package/dist/heart/commitments.js +1 -1
- package/dist/heart/core.js +45 -23
- package/dist/heart/daemon/agent-config-check.js +24 -0
- package/dist/heart/daemon/agent-discovery.js +28 -17
- package/dist/heart/daemon/agent-service.js +6 -6
- package/dist/heart/daemon/await-private-wake.js +59 -0
- package/dist/heart/daemon/cli-exec.js +180 -24
- package/dist/heart/daemon/cli-help.js +20 -2
- package/dist/heart/daemon/cli-parse.js +45 -2
- package/dist/heart/daemon/cli-render.js +1 -0
- package/dist/heart/daemon/daemon-entry.js +122 -25
- package/dist/heart/daemon/daemon.js +223 -20
- package/dist/heart/daemon/habit-private-wake.js +56 -0
- package/dist/heart/daemon/inner-status.js +3 -3
- package/dist/heart/daemon/message-router.js +39 -3
- package/dist/heart/daemon/pulse.js +43 -7
- package/dist/heart/daemon/socket-client.js +14 -2
- package/dist/heart/daemon/startup-tui.js +9 -1
- package/dist/heart/daemon/thoughts.js +39 -39
- package/dist/heart/habits/habit-scheduler.js +24 -4
- package/dist/heart/mailbox/mailbox-view.js +1 -1
- package/dist/heart/mailbox/readers/agent-machine.js +7 -7
- package/dist/heart/primitives.js +1 -1
- package/dist/heart/private-runtime/decision-renderer.js +156 -0
- package/dist/heart/private-runtime/index.js +18 -0
- package/dist/heart/private-runtime/ledger.js +218 -0
- package/dist/heart/private-runtime/policy.js +205 -0
- package/dist/heart/private-runtime/types.js +2 -0
- package/dist/heart/progress-story.js +1 -1
- package/dist/heart/session-transcript.js +1 -1
- package/dist/heart/tool-activity-callbacks.js +1 -1
- package/dist/heart/tool-description.js +2 -2
- package/dist/heart/tool-loop.js +2 -2
- package/dist/heart/turn-context.js +5 -5
- package/dist/mailbox-ui/assets/index-J8zDwHmE.js +1 -0
- package/dist/mailbox-ui/index.html +1 -1
- package/dist/mailroom/attention.js +1 -1
- package/dist/mind/context.js +2 -2
- package/dist/mind/pending.js +12 -5
- package/dist/mind/prompt.js +32 -25
- package/dist/repertoire/coding/feedback.js +25 -4
- package/dist/repertoire/tools-awaiting.js +2 -2
- package/dist/repertoire/tools-flow.js +4 -4
- package/dist/repertoire/tools-record.js +1 -1
- package/dist/repertoire/tools-session.js +33 -67
- package/dist/repertoire/tools-surface.js +3 -3
- package/dist/senses/cli.js +2 -2
- package/dist/senses/inner-dialog-worker.js +13 -519
- package/dist/senses/inner-dialog.js +10 -961
- package/dist/senses/mail.js +21 -5
- package/dist/senses/pipeline.js +1 -1
- package/dist/senses/private-runtime-worker.js +578 -0
- package/dist/senses/private-runtime.js +1145 -0
- package/dist/senses/shared-turn.js +1 -1
- package/dist/senses/trust-gate.js +2 -2
- package/package.json +1 -1
- package/dist/mailbox-ui/assets/index-CaTIFDmv.js +0 -1
|
@@ -100,6 +100,7 @@ const core_2 = require("../../nerves/review/core");
|
|
|
100
100
|
const cli_render_1 = require("./cli-render");
|
|
101
101
|
const cli_defaults_1 = require("./cli-defaults");
|
|
102
102
|
const agent_config_check_1 = require("./agent-config-check");
|
|
103
|
+
const private_runtime_1 = require("../private-runtime");
|
|
103
104
|
const doctor_1 = require("./doctor");
|
|
104
105
|
const cli_render_doctor_1 = require("./cli-render-doctor");
|
|
105
106
|
const interactive_repair_1 = require("./interactive-repair");
|
|
@@ -312,10 +313,13 @@ function providerStatusRowsCoverAgents(rows, agents) {
|
|
|
312
313
|
}
|
|
313
314
|
return true;
|
|
314
315
|
}
|
|
316
|
+
function providerRowNeedsLiveReadinessRefresh(row) {
|
|
317
|
+
return row.provider !== "unconfigured" && row.readiness === "unknown";
|
|
318
|
+
}
|
|
315
319
|
async function checkAgentProvidersFromDaemonStatus(deps, agents, onProgress) {
|
|
316
320
|
const uniqueAgents = [...new Set(agents)];
|
|
317
321
|
if (uniqueAgents.length === 0)
|
|
318
|
-
return [];
|
|
322
|
+
return { degraded: [], needsLiveReadinessRefresh: false };
|
|
319
323
|
let response;
|
|
320
324
|
try {
|
|
321
325
|
response = await deps.sendCommand(deps.socketPath, { kind: "daemon.status" });
|
|
@@ -342,7 +346,10 @@ async function checkAgentProvidersFromDaemonStatus(deps, agents, onProgress) {
|
|
|
342
346
|
onProgress?.(degraded.length === 0
|
|
343
347
|
? "provider readiness confirmed by daemon status"
|
|
344
348
|
: "provider readiness reported by daemon status");
|
|
345
|
-
return
|
|
349
|
+
return {
|
|
350
|
+
degraded,
|
|
351
|
+
needsLiveReadinessRefresh: rows.some(providerRowNeedsLiveReadinessRefresh),
|
|
352
|
+
};
|
|
346
353
|
}
|
|
347
354
|
async function checkAgentProviderHealth(agentName, bundlesRoot, deps, onProgress, options = {}) {
|
|
348
355
|
const liveDeps = {};
|
|
@@ -425,11 +432,12 @@ function agentResolutionFailureMode(command) {
|
|
|
425
432
|
case "attention.list":
|
|
426
433
|
case "attention.show":
|
|
427
434
|
case "attention.history":
|
|
435
|
+
case "private.decisions":
|
|
436
|
+
case "private.status":
|
|
428
437
|
case "work.card":
|
|
429
438
|
case "work.gauntlet":
|
|
430
439
|
case "work.sentinel":
|
|
431
440
|
case "work.sentinel.refresh":
|
|
432
|
-
case "inner.status":
|
|
433
441
|
case "session.list":
|
|
434
442
|
return "return-message";
|
|
435
443
|
case "a2a.card":
|
|
@@ -513,9 +521,57 @@ function managedAgentsSignature(agentNames) {
|
|
|
513
521
|
async function checkAlreadyRunningAgentProviders(deps, onProgress) {
|
|
514
522
|
const agents = await listCliAgents(deps);
|
|
515
523
|
const statusResult = await checkAgentProvidersFromDaemonStatus(deps, agents, onProgress);
|
|
516
|
-
if (statusResult)
|
|
517
|
-
|
|
518
|
-
|
|
524
|
+
if (statusResult) {
|
|
525
|
+
const configResult = await checkAgentConfigsOffline(deps, agents);
|
|
526
|
+
if (configResult.length > 0) {
|
|
527
|
+
return { degraded: [...statusResult.degraded, ...configResult], source: "daemon-status" };
|
|
528
|
+
}
|
|
529
|
+
if (statusResult.needsLiveReadinessRefresh) {
|
|
530
|
+
return { degraded: await checkAgentProviders(deps, agents, onProgress), source: "live-provider-check" };
|
|
531
|
+
}
|
|
532
|
+
return { degraded: statusResult.degraded, source: "daemon-status" };
|
|
533
|
+
}
|
|
534
|
+
return { degraded: await checkAgentConfigsOffline(deps, agents, onProgress), source: "offline-config" };
|
|
535
|
+
}
|
|
536
|
+
async function checkAgentConfigsOffline(deps, agents, onProgress) {
|
|
537
|
+
const bundlesRoot = deps.bundlesRoot ?? (0, identity_1.getAgentBundlesRoot)();
|
|
538
|
+
const degraded = [];
|
|
539
|
+
for (const agent of [...new Set(agents)]) {
|
|
540
|
+
try {
|
|
541
|
+
const result = (0, agent_config_check_1.checkAgentConfig)(agent, bundlesRoot);
|
|
542
|
+
if (result.ok)
|
|
543
|
+
continue;
|
|
544
|
+
const errorReason = result.error ?? "agent config validation failed";
|
|
545
|
+
const fixHint = result.fix ?? "";
|
|
546
|
+
degraded.push({ agent, errorReason, fixHint, ...(result.issue ? { issue: result.issue } : {}) });
|
|
547
|
+
(0, runtime_1.emitNervesEvent)({
|
|
548
|
+
level: "error",
|
|
549
|
+
component: "daemon",
|
|
550
|
+
event: "daemon.agent_config_invalid",
|
|
551
|
+
message: errorReason,
|
|
552
|
+
meta: { agent, fixProvided: fixHint.length > 0, source: "already-running-offline-config-check" },
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
catch (error) {
|
|
556
|
+
const errorReason = error instanceof Error ? error.message : String(error);
|
|
557
|
+
degraded.push({
|
|
558
|
+
agent,
|
|
559
|
+
errorReason,
|
|
560
|
+
fixHint: "Run 'ouro doctor' for diagnostics, then retry 'ouro up'.",
|
|
561
|
+
});
|
|
562
|
+
(0, runtime_1.emitNervesEvent)({
|
|
563
|
+
level: "error",
|
|
564
|
+
component: "daemon",
|
|
565
|
+
event: "daemon.agent_config_invalid",
|
|
566
|
+
message: errorReason,
|
|
567
|
+
meta: { agent, fixProvided: true, source: "already-running-offline-config-check" },
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
onProgress?.(degraded.length === 0
|
|
572
|
+
? "agent config validated offline; provider readiness will refresh on explicit provider commands"
|
|
573
|
+
: "agent config validation reported by offline startup check");
|
|
574
|
+
return degraded;
|
|
519
575
|
}
|
|
520
576
|
function readinessIssueFromDegraded(entry) {
|
|
521
577
|
return entry.issue ?? (0, readiness_repair_1.genericReadinessIssue)({
|
|
@@ -548,6 +604,23 @@ function providerRepairCountSummary(count) {
|
|
|
548
604
|
return "selected providers answered live checks";
|
|
549
605
|
return `${count} ${count === 1 ? "needs" : "need"} attention`;
|
|
550
606
|
}
|
|
607
|
+
function startupConfigCheckSummary(count) {
|
|
608
|
+
if (count === 0)
|
|
609
|
+
return "agent config validated offline";
|
|
610
|
+
return `${count} ${count === 1 ? "needs" : "need"} attention`;
|
|
611
|
+
}
|
|
612
|
+
function startupProviderCheckSummary(result) {
|
|
613
|
+
if (result.source === "daemon-status" && result.degraded.length === 0) {
|
|
614
|
+
return "provider readiness confirmed by daemon status";
|
|
615
|
+
}
|
|
616
|
+
if (result.source === "daemon-status") {
|
|
617
|
+
return providerRepairCountSummary(result.degraded.length);
|
|
618
|
+
}
|
|
619
|
+
if (result.source === "live-provider-check") {
|
|
620
|
+
return providerRepairCountSummary(result.degraded.length);
|
|
621
|
+
}
|
|
622
|
+
return startupConfigCheckSummary(result.degraded.length);
|
|
623
|
+
}
|
|
551
624
|
/**
|
|
552
625
|
* Layer 2: human-readable summary of boot-sync-probe findings, written to
|
|
553
626
|
* stdout when any non-clean finding surfaces. The order reads "blockers
|
|
@@ -910,7 +983,13 @@ async function ensureDaemonRunning(deps, options = {}) {
|
|
|
910
983
|
}
|
|
911
984
|
return null;
|
|
912
985
|
};
|
|
913
|
-
|
|
986
|
+
let alive;
|
|
987
|
+
if (typeof options.initialAlive === "boolean") {
|
|
988
|
+
alive = options.initialAlive;
|
|
989
|
+
}
|
|
990
|
+
else {
|
|
991
|
+
alive = await deps.checkSocketAlive(deps.socketPath);
|
|
992
|
+
}
|
|
914
993
|
if (alive) {
|
|
915
994
|
const localRuntime = (0, runtime_metadata_1.getRuntimeMetadata)();
|
|
916
995
|
const localManagedAgents = managedAgentsSignature((0, agent_discovery_1.listEnabledBundleAgents)({
|
|
@@ -1362,6 +1441,12 @@ function writeAgentVaultConfig(agentName, configPath, config, vault) {
|
|
|
1362
1441
|
function isJsonRecord(value) {
|
|
1363
1442
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
1364
1443
|
}
|
|
1444
|
+
function daemonMessageReceiptId(response) {
|
|
1445
|
+
if (!isJsonRecord(response.data))
|
|
1446
|
+
return undefined;
|
|
1447
|
+
const id = response.data.id;
|
|
1448
|
+
return typeof id === "string" && id.trim().length > 0 ? id : undefined;
|
|
1449
|
+
}
|
|
1365
1450
|
function cloneJsonRecord(value) {
|
|
1366
1451
|
return JSON.parse(JSON.stringify(value));
|
|
1367
1452
|
}
|
|
@@ -3850,6 +3935,22 @@ function makeBackgroundOperationId(kind) {
|
|
|
3850
3935
|
const prefix = kind === "mail.import-mbox" ? "op_mail_import" : "op_mail_backfill";
|
|
3851
3936
|
return `${prefix}_${(0, crypto_1.randomUUID)().slice(0, 8)}`;
|
|
3852
3937
|
}
|
|
3938
|
+
function buildMailOperationPrivateWakeCommand(agentName, record) {
|
|
3939
|
+
const status = record.status === "failed" ? "failed" : "succeeded";
|
|
3940
|
+
return {
|
|
3941
|
+
kind: "private.wake",
|
|
3942
|
+
agent: agentName,
|
|
3943
|
+
reason: "mail background operation private attention",
|
|
3944
|
+
triggerSource: "mail-background-operation",
|
|
3945
|
+
budgetClass: "interactive",
|
|
3946
|
+
idempotencyKey: `mail-operation:${agentName}:${record.id}:${status}`,
|
|
3947
|
+
originRefs: [
|
|
3948
|
+
{ kind: "background-operation", id: record.id },
|
|
3949
|
+
{ kind: "mail-operation", id: record.kind },
|
|
3950
|
+
{ kind: "mail-operation-status", id: status },
|
|
3951
|
+
],
|
|
3952
|
+
};
|
|
3953
|
+
}
|
|
3853
3954
|
async function notifyMailOperation(agentName, record, deps) {
|
|
3854
3955
|
const lines = [
|
|
3855
3956
|
"[Background Operation]",
|
|
@@ -3881,7 +3982,7 @@ async function notifyMailOperation(agentName, record, deps) {
|
|
|
3881
3982
|
mode: "reflect",
|
|
3882
3983
|
});
|
|
3883
3984
|
await queueMailOperationTargetNotification(agentName, content, deps).catch(() => undefined);
|
|
3884
|
-
await deps.sendCommand(deps.socketPath,
|
|
3985
|
+
await deps.sendCommand(deps.socketPath, buildMailOperationPrivateWakeCommand(agentName, record))
|
|
3885
3986
|
.then(() => undefined)
|
|
3886
3987
|
.catch(() => undefined);
|
|
3887
3988
|
}
|
|
@@ -6159,9 +6260,10 @@ async function runOuroCli(args, deps = (0, cli_defaults_1.createDefaultOuroCliDe
|
|
|
6159
6260
|
}
|
|
6160
6261
|
}
|
|
6161
6262
|
progress.startPhase("provider checks");
|
|
6162
|
-
const
|
|
6263
|
+
const providerCheck = await checkAlreadyRunningAgentProviders(deps, (msg) => progress.updateDetail(msg));
|
|
6264
|
+
const providerDegraded = providerCheck.degraded;
|
|
6163
6265
|
daemonResult.stability = mergeStartupStability(daemonResult.stability, providerDegraded);
|
|
6164
|
-
progress.completePhase("provider checks",
|
|
6266
|
+
progress.completePhase("provider checks", startupProviderCheckSummary(providerCheck));
|
|
6165
6267
|
progress.startPhase("final daemon check");
|
|
6166
6268
|
const finalDaemonCheck = await verifyDaemonReadyForHandoff(deps, {
|
|
6167
6269
|
allowDegradedHealth: Boolean(command.noRepair
|
|
@@ -6616,7 +6718,7 @@ async function runOuroCli(args, deps = (0, cli_defaults_1.createDefaultOuroCliDe
|
|
|
6616
6718
|
// when the daemon socket file doesn't exist — otherwise every
|
|
6617
6719
|
// Claude Code lifecycle event during a daemon-down window logs two
|
|
6618
6720
|
// ENOENT errors in ouro.ndjson (one for message.send, one for
|
|
6619
|
-
//
|
|
6721
|
+
// private.wake) which makes it hard to read the log around outages.
|
|
6620
6722
|
// The hook is best-effort: dropping notifications when the daemon
|
|
6621
6723
|
// is down is the correct behavior; we just don't want to log spam
|
|
6622
6724
|
// about it.
|
|
@@ -6627,14 +6729,25 @@ async function runOuroCli(args, deps = (0, cli_defaults_1.createDefaultOuroCliDe
|
|
|
6627
6729
|
// single tool use. A long Claude Code working session can fire
|
|
6628
6730
|
// dozens of post-tool-use hooks per minute; waking the agent
|
|
6629
6731
|
// synchronously on each one creates a feedback storm where the
|
|
6630
|
-
//
|
|
6732
|
+
// private runtime is re-prompted faster than it can rest, the
|
|
6631
6733
|
// "...time passing. anything stirring?" probe fires back-to-back,
|
|
6632
6734
|
// and the agent burns its attention budget responding to wakes
|
|
6633
6735
|
// instead of doing actual work. The message is still delivered
|
|
6634
6736
|
// either way (above); the agent picks it up on its next natural
|
|
6635
6737
|
// turn.
|
|
6636
6738
|
if (eventType === "session-start" || eventType === "stop") {
|
|
6637
|
-
await deps.sendCommand(deps.socketPath, {
|
|
6739
|
+
await deps.sendCommand(deps.socketPath, {
|
|
6740
|
+
kind: "private.wake",
|
|
6741
|
+
agent: command.agent,
|
|
6742
|
+
reason: `Claude Code ${eventType} hook`,
|
|
6743
|
+
triggerSource: "dev-tool-hook",
|
|
6744
|
+
budgetClass: "interactive",
|
|
6745
|
+
idempotencyKey: `dev-tool-hook:${command.agent}:${eventType}:${sessionId}`,
|
|
6746
|
+
originRefs: [
|
|
6747
|
+
{ kind: "dev-tool-hook", id: eventType },
|
|
6748
|
+
{ kind: "session", id: sessionId },
|
|
6749
|
+
],
|
|
6750
|
+
}).catch(() => { });
|
|
6638
6751
|
}
|
|
6639
6752
|
}
|
|
6640
6753
|
catch { /* daemon not running — silent */ }
|
|
@@ -6817,6 +6930,32 @@ async function runOuroCli(args, deps = (0, cli_defaults_1.createDefaultOuroCliDe
|
|
|
6817
6930
|
return "";
|
|
6818
6931
|
}
|
|
6819
6932
|
/* v8 ignore stop */
|
|
6933
|
+
if (command.kind === "private.decisions") {
|
|
6934
|
+
let response;
|
|
6935
|
+
try {
|
|
6936
|
+
response = await deps.sendCommand(deps.socketPath, {
|
|
6937
|
+
kind: "private.decisions",
|
|
6938
|
+
agent: command.agent,
|
|
6939
|
+
limit: command.limit,
|
|
6940
|
+
});
|
|
6941
|
+
}
|
|
6942
|
+
catch {
|
|
6943
|
+
const message = "daemon unavailable — start with `ouro up` first";
|
|
6944
|
+
deps.writeStdout(message);
|
|
6945
|
+
return message;
|
|
6946
|
+
}
|
|
6947
|
+
if (!response.ok) {
|
|
6948
|
+
const message = response.error ?? "unknown error";
|
|
6949
|
+
deps.writeStdout(message);
|
|
6950
|
+
return message;
|
|
6951
|
+
}
|
|
6952
|
+
const payload = (0, private_runtime_1.privateDecisionReadPayloadFromDaemonData)(response.data, command.agent);
|
|
6953
|
+
const message = command.json
|
|
6954
|
+
? (0, private_runtime_1.formatPrivateDecisionReadJson)(payload)
|
|
6955
|
+
: (0, private_runtime_1.formatPrivateDecisionReadText)(payload);
|
|
6956
|
+
deps.writeStdout(message);
|
|
6957
|
+
return message;
|
|
6958
|
+
}
|
|
6820
6959
|
// ── mcp subcommands (routed through daemon socket) ──
|
|
6821
6960
|
if (command.kind === "mcp.list" || command.kind === "mcp.call") {
|
|
6822
6961
|
const daemonCommand = toDaemonCommand(command);
|
|
@@ -7371,7 +7510,7 @@ async function runOuroCli(args, deps = (0, cli_defaults_1.createDefaultOuroCliDe
|
|
|
7371
7510
|
/* v8 ignore next -- production fallback: tests always inject bundlesRoot via createTmpBundle @preserve */
|
|
7372
7511
|
const bundlesRoot = deps.bundlesRoot ?? (0, identity_1.getAgentBundlesRoot)();
|
|
7373
7512
|
const agentRoot = path.join(bundlesRoot, `${command.agent}.ouro`);
|
|
7374
|
-
const sessionFilePath = (0, thoughts_1.
|
|
7513
|
+
const sessionFilePath = (0, thoughts_1.getPrivateRuntimeSessionPath)(agentRoot);
|
|
7375
7514
|
if (command.json) {
|
|
7376
7515
|
try {
|
|
7377
7516
|
const raw = fs.readFileSync(sessionFilePath, "utf-8");
|
|
@@ -7379,12 +7518,12 @@ async function runOuroCli(args, deps = (0, cli_defaults_1.createDefaultOuroCliDe
|
|
|
7379
7518
|
return raw;
|
|
7380
7519
|
}
|
|
7381
7520
|
catch {
|
|
7382
|
-
const message = "no
|
|
7521
|
+
const message = "no private-runtime session found";
|
|
7383
7522
|
deps.writeStdout(message);
|
|
7384
7523
|
return message;
|
|
7385
7524
|
}
|
|
7386
7525
|
}
|
|
7387
|
-
const turns = (0, thoughts_1.
|
|
7526
|
+
const turns = (0, thoughts_1.parsePrivateRuntimeSession)(sessionFilePath);
|
|
7388
7527
|
const message = (0, thoughts_1.formatThoughtTurns)(turns, command.last ?? 10);
|
|
7389
7528
|
deps.writeStdout(message);
|
|
7390
7529
|
if (command.follow) {
|
|
@@ -7516,9 +7655,9 @@ async function runOuroCli(args, deps = (0, cli_defaults_1.createDefaultOuroCliDe
|
|
|
7516
7655
|
deps.writeStdout(message);
|
|
7517
7656
|
return message;
|
|
7518
7657
|
}
|
|
7519
|
-
// ──
|
|
7520
|
-
/* v8 ignore start --
|
|
7521
|
-
if (command.kind === "
|
|
7658
|
+
// ── private runtime status (local, no daemon socket needed) ──
|
|
7659
|
+
/* v8 ignore start -- private status handler: requires real agent state on disk @preserve */
|
|
7660
|
+
if (command.kind === "private.status") {
|
|
7522
7661
|
try {
|
|
7523
7662
|
const agentRoot = deps.agentBundleRoot ?? (0, identity_1.getAgentRoot)(command.agent);
|
|
7524
7663
|
const { buildInnerStatusOutput } = await Promise.resolve().then(() => __importStar(require("./inner-status")));
|
|
@@ -7526,8 +7665,8 @@ async function runOuroCli(args, deps = (0, cli_defaults_1.createDefaultOuroCliDe
|
|
|
7526
7665
|
const { parseFrontmatter } = await Promise.resolve().then(() => __importStar(require("../../util/frontmatter")));
|
|
7527
7666
|
const { listActiveReturnObligations } = await Promise.resolve().then(() => __importStar(require("../../arc/obligations")));
|
|
7528
7667
|
const { resolveDeskRecordPaths } = await Promise.resolve().then(() => __importStar(require("../../mind/record-paths")));
|
|
7529
|
-
// Read runtime state
|
|
7530
|
-
const innerSessionPath = (0, thoughts_1.
|
|
7668
|
+
// Read runtime state from the persisted historical session location.
|
|
7669
|
+
const innerSessionPath = (0, thoughts_1.getPrivateRuntimeSessionPath)(agentRoot);
|
|
7531
7670
|
const runtimeJsonPath = path.join(path.dirname(innerSessionPath), "runtime.json");
|
|
7532
7671
|
let runtimeState = null;
|
|
7533
7672
|
try {
|
|
@@ -7580,7 +7719,7 @@ async function runOuroCli(args, deps = (0, cli_defaults_1.createDefaultOuroCliDe
|
|
|
7580
7719
|
catch { /* no habits — heartbeat unknown */ }
|
|
7581
7720
|
// Attention count
|
|
7582
7721
|
const activeObligations = listActiveReturnObligations(command.agent);
|
|
7583
|
-
const
|
|
7722
|
+
const statusOutput = buildInnerStatusOutput({
|
|
7584
7723
|
agentName: command.agent,
|
|
7585
7724
|
runtimeState,
|
|
7586
7725
|
recordSummary,
|
|
@@ -7588,6 +7727,9 @@ async function runOuroCli(args, deps = (0, cli_defaults_1.createDefaultOuroCliDe
|
|
|
7588
7727
|
attentionCount: activeObligations.length,
|
|
7589
7728
|
now: Date.now(),
|
|
7590
7729
|
});
|
|
7730
|
+
const message = command.legacyAlias === "inner"
|
|
7731
|
+
? [`legacy alias: use \`ouro private status --agent ${command.agent}\``, statusOutput].join("\n")
|
|
7732
|
+
: statusOutput;
|
|
7591
7733
|
deps.writeStdout(message);
|
|
7592
7734
|
return message;
|
|
7593
7735
|
}
|
|
@@ -7901,11 +8043,25 @@ async function runOuroCli(args, deps = (0, cli_defaults_1.createDefaultOuroCliDe
|
|
|
7901
8043
|
response = await deps.sendCommand(deps.socketPath, daemonCommand);
|
|
7902
8044
|
// `ouro msg` is operator-driven and expects the recipient to process the
|
|
7903
8045
|
// message now (vs. on next natural turn). message.send is queue-only as
|
|
7904
|
-
// of the 2026-05-11 fix; we explicitly fire
|
|
8046
|
+
// of the 2026-05-11 fix; we explicitly fire private.wake to preserve the
|
|
7905
8047
|
// historical CLI UX. Background callers (hooks, API) deliberately omit
|
|
7906
8048
|
// this and let the agent pick up notifications on its next turn.
|
|
7907
8049
|
if (command.kind === "message.send" && command.from === "ouro-cli") {
|
|
7908
|
-
|
|
8050
|
+
const receiptId = daemonMessageReceiptId(response);
|
|
8051
|
+
await deps.sendCommand(deps.socketPath, {
|
|
8052
|
+
kind: "private.wake",
|
|
8053
|
+
agent: command.to,
|
|
8054
|
+
reason: "operator CLI message",
|
|
8055
|
+
triggerSource: "operator-cli",
|
|
8056
|
+
budgetClass: "interactive",
|
|
8057
|
+
idempotencyKey: receiptId
|
|
8058
|
+
? `cli:message:${command.to}:${receiptId}`
|
|
8059
|
+
: `cli:message:${command.to}:unreceipted`,
|
|
8060
|
+
originRefs: [
|
|
8061
|
+
{ kind: "cli-command", id: "ouro msg" },
|
|
8062
|
+
...(receiptId ? [{ kind: "daemon-receipt", id: receiptId }] : []),
|
|
8063
|
+
],
|
|
8064
|
+
}).catch(() => { });
|
|
7909
8065
|
}
|
|
7910
8066
|
}
|
|
7911
8067
|
catch (error) {
|
|
@@ -273,15 +273,23 @@ exports.COMMAND_REGISTRY = {
|
|
|
273
273
|
},
|
|
274
274
|
thoughts: {
|
|
275
275
|
category: "Internal",
|
|
276
|
-
description: "View
|
|
276
|
+
description: "View private runtime transcript turns",
|
|
277
277
|
usage: "ouro thoughts [--last <n>] [--json] [--follow] [--agent <name>]",
|
|
278
278
|
example: "ouro thoughts --last 5 --follow",
|
|
279
279
|
},
|
|
280
|
+
private: {
|
|
281
|
+
category: "Internal",
|
|
282
|
+
description: "Inspect private-runtime status and policy decisions",
|
|
283
|
+
usage: "ouro private status|decisions [--agent <name>] [--limit <n>] [--json]",
|
|
284
|
+
example: "ouro private status --agent ouroboros",
|
|
285
|
+
subcommands: ["status", "decisions"],
|
|
286
|
+
},
|
|
280
287
|
inner: {
|
|
281
288
|
category: "Internal",
|
|
282
|
-
description: "
|
|
289
|
+
description: "Legacy alias for `ouro private status`",
|
|
283
290
|
usage: "ouro inner [--agent <name>]",
|
|
284
291
|
example: "ouro inner",
|
|
292
|
+
hidden: true,
|
|
285
293
|
},
|
|
286
294
|
attention: {
|
|
287
295
|
category: "Internal",
|
|
@@ -331,6 +339,16 @@ exports.COMMAND_REGISTRY = {
|
|
|
331
339
|
},
|
|
332
340
|
};
|
|
333
341
|
const SUBCOMMAND_HELP = {
|
|
342
|
+
"private decisions": {
|
|
343
|
+
description: "Read recent private-runtime allow/deny decisions from the policy ledger",
|
|
344
|
+
usage: "ouro private decisions [--agent <name>] [--limit <n>] [--json]",
|
|
345
|
+
example: "ouro private decisions --agent ouroboros --json",
|
|
346
|
+
},
|
|
347
|
+
"private status": {
|
|
348
|
+
description: "Show private-runtime status from local agent state",
|
|
349
|
+
usage: "ouro private status [--agent <name>]",
|
|
350
|
+
example: "ouro private status --agent ouroboros",
|
|
351
|
+
},
|
|
334
352
|
"auth verify": {
|
|
335
353
|
description: "Verify agent provider credentials without changing provider/model lanes",
|
|
336
354
|
usage: "ouro auth verify [--agent <name>] [--provider <provider>]",
|
|
@@ -118,9 +118,10 @@ function usage() {
|
|
|
118
118
|
" ouro friend create --name <name> [--trust <level>] [--agent <name>]",
|
|
119
119
|
" ouro friend update <id> --trust <level> [--agent <name>]",
|
|
120
120
|
" ouro thoughts [--last <n>] [--json] [--follow] [--agent <name>]",
|
|
121
|
+
" ouro private decisions [--agent <name>] [--limit <n>] [--json]",
|
|
122
|
+
" ouro private status [--agent <name>]",
|
|
121
123
|
" ouro work card|gauntlet|sentinel [refresh] [--agent <name>] [--format text|json|--json]",
|
|
122
124
|
" ouro nerves-review [--agent <name>] [--process <name>] [--component <substr>] [--event <substr>] [--level <level>] [--since <duration>] [--limit <n>] [--json]",
|
|
123
|
-
" ouro inner [--agent <name>]",
|
|
124
125
|
" ouro friend link <agent> --friend <id> --provider <p> --external-id <eid>",
|
|
125
126
|
" ouro friend unlink <agent> --friend <id> --provider <p> --external-id <eid>",
|
|
126
127
|
" ouro a2a card [--agent <name>] [--base-url <url>] [--json]",
|
|
@@ -1637,6 +1638,46 @@ function parseNervesReviewCommand(args) {
|
|
|
1637
1638
|
json,
|
|
1638
1639
|
};
|
|
1639
1640
|
}
|
|
1641
|
+
function parsePrivateCommand(args) {
|
|
1642
|
+
const [subcommand] = args;
|
|
1643
|
+
if (subcommand === "status") {
|
|
1644
|
+
const { agent, rest } = extractAgentFlag(args.slice(1));
|
|
1645
|
+
if (rest.length > 0) {
|
|
1646
|
+
throw new Error("Usage: ouro private status [--agent <name>]");
|
|
1647
|
+
}
|
|
1648
|
+
return { kind: "private.status", ...(agent ? { agent } : {}) };
|
|
1649
|
+
}
|
|
1650
|
+
if (subcommand !== "decisions") {
|
|
1651
|
+
throw new Error("Usage: ouro private decisions [--agent <name>] [--limit <n>] [--json] OR ouro private status [--agent <name>]");
|
|
1652
|
+
}
|
|
1653
|
+
const { agent, rest } = extractAgentFlag(args.slice(1));
|
|
1654
|
+
let limit = 20;
|
|
1655
|
+
let json = false;
|
|
1656
|
+
for (let i = 0; i < rest.length; i += 1) {
|
|
1657
|
+
const token = rest[i];
|
|
1658
|
+
const next = rest[i + 1];
|
|
1659
|
+
if (token === "--json") {
|
|
1660
|
+
json = true;
|
|
1661
|
+
continue;
|
|
1662
|
+
}
|
|
1663
|
+
if (token === "--limit" && next) {
|
|
1664
|
+
const parsed = Number.parseInt(next, 10);
|
|
1665
|
+
if (!Number.isInteger(parsed) || String(parsed) !== next || parsed < 1 || parsed > 1000) {
|
|
1666
|
+
throw new Error("private decisions --limit must be an integer between 1 and 1000");
|
|
1667
|
+
}
|
|
1668
|
+
limit = parsed;
|
|
1669
|
+
i += 1;
|
|
1670
|
+
continue;
|
|
1671
|
+
}
|
|
1672
|
+
throw new Error("Usage: ouro private decisions [--agent <name>] [--limit <n>] [--json]");
|
|
1673
|
+
}
|
|
1674
|
+
return {
|
|
1675
|
+
kind: "private.decisions",
|
|
1676
|
+
...(agent ? { agent } : {}),
|
|
1677
|
+
limit,
|
|
1678
|
+
json,
|
|
1679
|
+
};
|
|
1680
|
+
}
|
|
1640
1681
|
// ── Main dispatch ──
|
|
1641
1682
|
function parseOuroCommand(args) {
|
|
1642
1683
|
const [head, second] = args;
|
|
@@ -1787,13 +1828,15 @@ function parseOuroCommand(args) {
|
|
|
1787
1828
|
}
|
|
1788
1829
|
if (head === "thoughts")
|
|
1789
1830
|
return parseThoughtsCommand(args.slice(1));
|
|
1831
|
+
if (head === "private")
|
|
1832
|
+
return parsePrivateCommand(args.slice(1));
|
|
1790
1833
|
if (head === "attention")
|
|
1791
1834
|
return parseAttentionCommand(args.slice(1));
|
|
1792
1835
|
if (head === "work")
|
|
1793
1836
|
return parseWorkCommand(args.slice(1));
|
|
1794
1837
|
if (head === "inner") {
|
|
1795
1838
|
const { agent } = extractAgentFlag(args.slice(1));
|
|
1796
|
-
return { kind: "
|
|
1839
|
+
return { kind: "private.status", ...(agent ? { agent } : {}), legacyAlias: "inner" };
|
|
1797
1840
|
}
|
|
1798
1841
|
if (head === "chat") {
|
|
1799
1842
|
if (!second)
|