@ouro.bot/cli 0.1.0-alpha.17 → 0.1.0-alpha.170

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 (168) hide show
  1. package/AdoptionSpecialist.ouro/agent.json +3 -2
  2. package/AdoptionSpecialist.ouro/psyche/SOUL.md +3 -3
  3. package/AdoptionSpecialist.ouro/psyche/identities/monty.md +2 -2
  4. package/README.md +187 -191
  5. package/changelog.json +1145 -0
  6. package/dist/heart/active-work.js +633 -0
  7. package/dist/heart/bridges/manager.js +358 -0
  8. package/dist/heart/bridges/state-machine.js +135 -0
  9. package/dist/heart/bridges/store.js +123 -0
  10. package/dist/heart/commitments.js +105 -0
  11. package/dist/heart/config.js +40 -30
  12. package/dist/heart/core.js +608 -123
  13. package/dist/heart/cross-chat-delivery.js +146 -0
  14. package/dist/heart/daemon/agent-discovery.js +81 -0
  15. package/dist/heart/daemon/agent-service.js +360 -0
  16. package/dist/heart/daemon/auth-flow.js +477 -0
  17. package/dist/heart/daemon/cadence.js +70 -0
  18. package/dist/heart/daemon/daemon-cli.js +2473 -206
  19. package/dist/heart/daemon/daemon-entry.js +140 -4
  20. package/dist/heart/daemon/daemon-health.js +136 -0
  21. package/dist/heart/daemon/daemon-runtime-sync.js +212 -0
  22. package/dist/heart/daemon/daemon-tombstone.js +123 -0
  23. package/dist/heart/daemon/daemon.js +446 -17
  24. package/dist/heart/daemon/habit-migration.js +181 -0
  25. package/dist/heart/daemon/habit-parser.js +119 -0
  26. package/dist/heart/daemon/habit-scheduler.js +369 -0
  27. package/dist/heart/daemon/hatch-animation.js +10 -3
  28. package/dist/heart/daemon/hatch-flow.js +30 -111
  29. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  30. package/dist/heart/daemon/hooks/bundle-meta.js +92 -0
  31. package/dist/heart/daemon/inner-status.js +89 -0
  32. package/dist/heart/daemon/launchd.js +161 -0
  33. package/dist/heart/daemon/log-tailer.js +4 -3
  34. package/dist/heart/daemon/mcp-server.js +591 -0
  35. package/dist/heart/daemon/message-router.js +17 -8
  36. package/dist/heart/daemon/os-cron-deps.js +134 -0
  37. package/dist/heart/daemon/ouro-bot-global-installer.js +128 -0
  38. package/dist/heart/daemon/ouro-path-installer.js +78 -34
  39. package/dist/heart/daemon/ouro-version-manager.js +171 -0
  40. package/dist/heart/daemon/outlook-http.js +399 -0
  41. package/dist/heart/daemon/outlook-read.js +1291 -0
  42. package/dist/heart/daemon/outlook-render.js +1032 -0
  43. package/dist/heart/daemon/outlook-types.js +7 -0
  44. package/dist/heart/daemon/outlook-view.js +194 -0
  45. package/dist/heart/daemon/process-manager.js +75 -0
  46. package/dist/heart/daemon/run-hooks.js +39 -0
  47. package/dist/heart/daemon/runtime-logging.js +58 -15
  48. package/dist/heart/daemon/runtime-metadata.js +219 -0
  49. package/dist/heart/daemon/runtime-mode.js +67 -0
  50. package/dist/heart/daemon/safe-mode.js +161 -0
  51. package/dist/heart/daemon/sense-manager.js +50 -2
  52. package/dist/heart/daemon/session-id-resolver.js +131 -0
  53. package/dist/heart/daemon/skill-management-installer.js +94 -0
  54. package/dist/heart/daemon/socket-client.js +202 -0
  55. package/dist/heart/daemon/specialist-orchestrator.js +2 -2
  56. package/dist/heart/daemon/specialist-prompt.js +13 -8
  57. package/dist/heart/daemon/specialist-tools.js +53 -4
  58. package/dist/heart/daemon/staged-restart.js +114 -0
  59. package/dist/heart/daemon/task-scheduler.js +3 -25
  60. package/dist/heart/daemon/thoughts.js +507 -0
  61. package/dist/heart/daemon/update-checker.js +111 -0
  62. package/dist/heart/daemon/update-hooks.js +138 -0
  63. package/dist/heart/daemon/wrapper-publish-guard.js +86 -0
  64. package/dist/heart/delegation.js +62 -0
  65. package/dist/heart/identity.js +136 -55
  66. package/dist/heart/kicks.js +2 -20
  67. package/dist/heart/migrate-config.js +127 -0
  68. package/dist/heart/model-capabilities.js +48 -0
  69. package/dist/heart/obligations.js +197 -0
  70. package/dist/heart/progress-story.js +42 -0
  71. package/dist/heart/provider-failover.js +88 -0
  72. package/dist/heart/provider-ping.js +172 -0
  73. package/dist/heart/providers/anthropic-token.js +163 -0
  74. package/dist/heart/providers/anthropic.js +196 -36
  75. package/dist/heart/providers/azure.js +116 -10
  76. package/dist/heart/providers/github-copilot.js +157 -0
  77. package/dist/heart/providers/minimax.js +33 -3
  78. package/dist/heart/providers/openai-codex.js +51 -16
  79. package/dist/heart/session-activity.js +172 -0
  80. package/dist/heart/session-recall.js +216 -0
  81. package/dist/heart/streaming.js +62 -32
  82. package/dist/heart/target-resolution.js +127 -0
  83. package/dist/heart/tool-activity-callbacks.js +36 -0
  84. package/dist/heart/tool-description.js +135 -0
  85. package/dist/heart/tool-loop.js +200 -0
  86. package/dist/heart/turn-coordinator.js +28 -0
  87. package/dist/mind/associative-recall.js +122 -32
  88. package/dist/mind/bundle-manifest.js +14 -0
  89. package/dist/mind/context.js +125 -14
  90. package/dist/mind/{memory.js → diary.js} +70 -56
  91. package/dist/mind/first-impressions.js +16 -2
  92. package/dist/mind/friends/channel.js +56 -0
  93. package/dist/mind/friends/group-context.js +144 -0
  94. package/dist/mind/friends/store-file.js +19 -0
  95. package/dist/mind/friends/trust-explanation.js +74 -0
  96. package/dist/mind/friends/types.js +8 -0
  97. package/dist/mind/journal-index.js +161 -0
  98. package/dist/mind/obligation-steering.js +221 -0
  99. package/dist/mind/obligations.js +134 -0
  100. package/dist/mind/pending.js +76 -9
  101. package/dist/mind/phrases.js +1 -0
  102. package/dist/mind/prompt.js +649 -89
  103. package/dist/mind/token-estimate.js +8 -12
  104. package/dist/nerves/cli-logging.js +15 -2
  105. package/dist/nerves/coverage/run-artifacts.js +1 -1
  106. package/dist/nerves/event-buffer.js +111 -0
  107. package/dist/nerves/index.js +63 -3
  108. package/dist/nerves/observation.js +20 -0
  109. package/dist/nerves/runtime.js +5 -1
  110. package/dist/outlook-ui/assets/index-CBueh0d3.css +1 -0
  111. package/dist/outlook-ui/assets/index-GtHoFpRM.js +61 -0
  112. package/dist/outlook-ui/index.html +15 -0
  113. package/dist/repertoire/ado-semantic.js +6 -0
  114. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  115. package/dist/repertoire/coding/context-pack.js +254 -0
  116. package/dist/repertoire/coding/feedback.js +197 -30
  117. package/dist/repertoire/coding/manager.js +149 -2
  118. package/dist/repertoire/coding/spawner.js +55 -9
  119. package/dist/repertoire/coding/tools.js +135 -2
  120. package/dist/repertoire/guardrails.js +291 -0
  121. package/dist/repertoire/mcp-client.js +254 -0
  122. package/dist/repertoire/mcp-manager.js +198 -0
  123. package/dist/repertoire/skills.js +14 -23
  124. package/dist/repertoire/tasks/board.js +43 -5
  125. package/dist/repertoire/tasks/fix.js +182 -0
  126. package/dist/repertoire/tasks/index.js +28 -10
  127. package/dist/repertoire/tasks/lifecycle.js +2 -2
  128. package/dist/repertoire/tasks/parser.js +3 -2
  129. package/dist/repertoire/tasks/scanner.js +194 -37
  130. package/dist/repertoire/tasks/transitions.js +11 -28
  131. package/dist/repertoire/tools-base.js +991 -272
  132. package/dist/repertoire/tools-bluebubbles.js +94 -0
  133. package/dist/repertoire/tools-github.js +1 -6
  134. package/dist/repertoire/tools-teams.js +12 -59
  135. package/dist/repertoire/tools.js +281 -122
  136. package/dist/scripts/claude-code-hook.js +41 -0
  137. package/dist/scripts/claude-code-stop-hook.js +47 -0
  138. package/dist/senses/attention-queue.js +97 -0
  139. package/dist/senses/bluebubbles-client.js +102 -3
  140. package/dist/senses/bluebubbles-entry.js +2 -0
  141. package/dist/senses/bluebubbles-inbound-log.js +109 -0
  142. package/dist/senses/bluebubbles-media.js +118 -23
  143. package/dist/senses/bluebubbles-model.js +12 -4
  144. package/dist/senses/bluebubbles-mutation-log.js +45 -5
  145. package/dist/senses/bluebubbles-runtime-state.js +109 -0
  146. package/dist/senses/bluebubbles-session-cleanup.js +72 -0
  147. package/dist/senses/bluebubbles.js +1008 -102
  148. package/dist/senses/cli-entry.js +1 -1
  149. package/dist/senses/cli-layout.js +187 -0
  150. package/dist/senses/cli.js +419 -152
  151. package/dist/senses/commands.js +38 -1
  152. package/dist/senses/continuity.js +94 -0
  153. package/dist/senses/habit-turn-message.js +108 -0
  154. package/dist/senses/inner-dialog-worker.js +112 -19
  155. package/dist/senses/inner-dialog.js +592 -84
  156. package/dist/senses/pipeline.js +502 -0
  157. package/dist/senses/shared-turn.js +196 -0
  158. package/dist/senses/surface-tool.js +95 -0
  159. package/dist/senses/teams.js +667 -120
  160. package/dist/senses/trust-gate.js +112 -2
  161. package/package.json +13 -5
  162. package/skills/configure-dev-tools.md +81 -0
  163. package/subagents/README.md +4 -70
  164. package/dist/heart/daemon/subagent-installer.js +0 -134
  165. package/dist/senses/debug-activity.js +0 -107
  166. package/subagents/work-doer.md +0 -235
  167. package/subagents/work-merger.md +0 -618
  168. package/subagents/work-planner.md +0 -382
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deriveCommitments = deriveCommitments;
4
+ exports.formatCommitments = formatCommitments;
5
+ const obligations_1 = require("./obligations");
6
+ const runtime_1 = require("../nerves/runtime");
7
+ function describeActiveObligation(obligation) {
8
+ if (obligation.status === "pending") {
9
+ return `i owe ${obligation.origin.friendId}: ${obligation.content}`;
10
+ }
11
+ const surface = obligation.currentSurface?.label;
12
+ const statusText = obligation.status.replaceAll("_", " ");
13
+ if (surface) {
14
+ return `i owe ${obligation.origin.friendId}: ${obligation.content} (${statusText} in ${surface})`;
15
+ }
16
+ return `i owe ${obligation.origin.friendId}: ${obligation.content} (${statusText})`;
17
+ }
18
+ function deriveCommitments(activeWorkFrame, innerJob, pendingObligations) {
19
+ const committedTo = [];
20
+ const completionCriteria = [];
21
+ const safeToIgnore = [];
22
+ // Persistent obligations from the obligation store
23
+ if (pendingObligations && pendingObligations.length > 0) {
24
+ let hasAdvancedObligation = false;
25
+ for (const ob of pendingObligations) {
26
+ if (!(0, obligations_1.isOpenObligationStatus)(ob.status))
27
+ continue;
28
+ committedTo.push(describeActiveObligation(ob));
29
+ if (ob.status !== "pending")
30
+ hasAdvancedObligation = true;
31
+ }
32
+ completionCriteria.push("fulfill my outstanding obligations");
33
+ if (hasAdvancedObligation) {
34
+ completionCriteria.push("close my active obligation loops");
35
+ }
36
+ }
37
+ // Inner job
38
+ if (innerJob.status === "queued" || innerJob.status === "running") {
39
+ const contentSuffix = innerJob.content ? ` -- ${innerJob.content.slice(0, 60)}` : "";
40
+ committedTo.push(`i'm thinking through something privately${contentSuffix}`);
41
+ }
42
+ else if (innerJob.status === "surfaced") {
43
+ committedTo.push("i finished thinking about something and need to bring it back");
44
+ }
45
+ // mustResolveBeforeHandoff
46
+ if (activeWorkFrame.mustResolveBeforeHandoff) {
47
+ committedTo.push("i need to finish what i started before moving on");
48
+ completionCriteria.push("resolve the current thread before moving on");
49
+ }
50
+ // Bridges
51
+ for (const bridge of activeWorkFrame.bridges) {
52
+ committedTo.push(`i have shared work: ${bridge.summary || bridge.objective}`);
53
+ }
54
+ if (activeWorkFrame.bridges.length > 0) {
55
+ completionCriteria.push("keep shared work aligned across sessions");
56
+ }
57
+ // Tasks
58
+ for (const taskName of activeWorkFrame.taskPressure?.liveTaskNames ?? []) {
59
+ committedTo.push(`i'm tracking: ${taskName}`);
60
+ }
61
+ // Obligation completion criteria
62
+ if (innerJob.obligationStatus === "pending") {
63
+ const name = innerJob.origin?.friendName ?? innerJob.origin?.friendId ?? "them";
64
+ completionCriteria.push(`bring my answer back to ${name}`);
65
+ }
66
+ // Default completion criteria
67
+ if (completionCriteria.length === 0) {
68
+ completionCriteria.push("just be present in this conversation");
69
+ }
70
+ // Safe to ignore
71
+ if (innerJob.status === "idle" && !(activeWorkFrame.inner?.hasPending)) {
72
+ safeToIgnore.push("no private thinking in progress");
73
+ }
74
+ if (activeWorkFrame.bridges.length === 0) {
75
+ safeToIgnore.push("no shared work to coordinate");
76
+ }
77
+ if ((activeWorkFrame.taskPressure?.liveTaskNames ?? []).length === 0) {
78
+ safeToIgnore.push("no active tasks to track");
79
+ }
80
+ (0, runtime_1.emitNervesEvent)({
81
+ component: "engine",
82
+ event: "engine.commitments_derive",
83
+ message: "derived commitments frame",
84
+ meta: { committedCount: committedTo.length, criteriaCount: completionCriteria.length },
85
+ });
86
+ return { committedTo, completionCriteria, safeToIgnore };
87
+ }
88
+ function formatCommitments(commitments) {
89
+ const sections = [];
90
+ if (commitments.committedTo.length === 0) {
91
+ sections.push("i'm not holding anything specific right now. i'm free to be present.");
92
+ }
93
+ else {
94
+ sections.push("## what i'm holding right now");
95
+ sections.push("");
96
+ sections.push(commitments.committedTo.map((c) => `- ${c}`).join("\n"));
97
+ }
98
+ sections.push("");
99
+ sections.push("## what \"done\" looks like");
100
+ sections.push(commitments.completionCriteria.map((c) => `- ${c}`).join("\n"));
101
+ sections.push("");
102
+ sections.push("## what i can let go of");
103
+ sections.push(commitments.safeToIgnore.map((c) => `- ${c}`).join("\n"));
104
+ return sections.join("\n");
105
+ }
@@ -40,6 +40,7 @@ exports.getAzureConfig = getAzureConfig;
40
40
  exports.getMinimaxConfig = getMinimaxConfig;
41
41
  exports.getAnthropicConfig = getAnthropicConfig;
42
42
  exports.getOpenAICodexConfig = getOpenAICodexConfig;
43
+ exports.getGithubCopilotConfig = getGithubCopilotConfig;
43
44
  exports.getTeamsConfig = getTeamsConfig;
44
45
  exports.getTeamsSecondaryConfig = getTeamsSecondaryConfig;
45
46
  exports.getContextConfig = getContextConfig;
@@ -51,36 +52,37 @@ exports.getBlueBubblesChannelConfig = getBlueBubblesChannelConfig;
51
52
  exports.getIntegrationsConfig = getIntegrationsConfig;
52
53
  exports.getOpenAIEmbeddingsApiKey = getOpenAIEmbeddingsApiKey;
53
54
  exports.getLogsDir = getLogsDir;
55
+ exports.sanitizeKey = sanitizeKey;
56
+ exports.slugify = slugify;
57
+ exports.resolveSessionPath = resolveSessionPath;
54
58
  exports.sessionPath = sessionPath;
55
59
  exports.logPath = logPath;
56
60
  const fs = __importStar(require("fs"));
57
61
  const path = __importStar(require("path"));
58
- const os = __importStar(require("os"));
59
62
  const identity_1 = require("./identity");
60
63
  const runtime_1 = require("../nerves/runtime");
61
64
  const DEFAULT_SECRETS_TEMPLATE = {
62
65
  providers: {
63
- // Keep provider field ordering consistent: model first, then auth credentials,
64
- // then provider-specific transport fields.
65
66
  azure: {
66
- modelName: "",
67
67
  apiKey: "",
68
68
  endpoint: "",
69
69
  deployment: "",
70
70
  apiVersion: "2025-04-01-preview",
71
+ managedIdentityClientId: "",
71
72
  },
72
73
  minimax: {
73
- model: "",
74
74
  apiKey: "",
75
75
  },
76
76
  anthropic: {
77
- model: "claude-opus-4-6",
78
77
  setupToken: "",
79
78
  },
80
79
  "openai-codex": {
81
- model: "gpt-5.2",
82
80
  oauthAccessToken: "",
83
81
  },
82
+ "github-copilot": {
83
+ githubToken: "",
84
+ baseUrl: "",
85
+ },
84
86
  },
85
87
  teams: {
86
88
  clientId: "",
@@ -125,6 +127,7 @@ function defaultRuntimeConfig() {
125
127
  minimax: { ...DEFAULT_SECRETS_TEMPLATE.providers.minimax },
126
128
  anthropic: { ...DEFAULT_SECRETS_TEMPLATE.providers.anthropic },
127
129
  "openai-codex": { ...DEFAULT_SECRETS_TEMPLATE.providers["openai-codex"] },
130
+ "github-copilot": { ...DEFAULT_SECRETS_TEMPLATE.providers["github-copilot"] },
128
131
  },
129
132
  teams: { ...DEFAULT_SECRETS_TEMPLATE.teams },
130
133
  teamsSecondary: { ...DEFAULT_SECRETS_TEMPLATE.teamsSecondary },
@@ -136,7 +139,7 @@ function defaultRuntimeConfig() {
136
139
  integrations: { ...DEFAULT_SECRETS_TEMPLATE.integrations },
137
140
  };
138
141
  }
139
- let _cachedConfig = null;
142
+ let _runtimeConfigOverride = null;
140
143
  let _testContextOverride = null;
141
144
  function resolveConfigPath() {
142
145
  return (0, identity_1.getAgentSecretsPath)();
@@ -158,15 +161,6 @@ function deepMerge(defaults, partial) {
158
161
  return result;
159
162
  }
160
163
  function loadConfig() {
161
- if (_cachedConfig) {
162
- (0, runtime_1.emitNervesEvent)({
163
- event: "config.load",
164
- component: "config/identity",
165
- message: "config loaded from cache",
166
- meta: { source: "cache" },
167
- });
168
- return _cachedConfig;
169
- }
170
164
  const configPath = resolveConfigPath();
171
165
  // Auto-create config directory if it doesn't exist
172
166
  const configDir = path.dirname(configPath);
@@ -227,7 +221,10 @@ function loadConfig() {
227
221
  },
228
222
  });
229
223
  }
230
- _cachedConfig = deepMerge(defaultRuntimeConfig(), sanitizedFileData);
224
+ const mergedConfig = deepMerge(defaultRuntimeConfig(), sanitizedFileData);
225
+ const config = _runtimeConfigOverride
226
+ ? deepMerge(mergedConfig, _runtimeConfigOverride)
227
+ : mergedConfig;
231
228
  (0, runtime_1.emitNervesEvent)({
232
229
  event: "config.load",
233
230
  component: "config/identity",
@@ -235,22 +232,22 @@ function loadConfig() {
235
232
  meta: {
236
233
  source: "disk",
237
234
  used_defaults_only: Object.keys(fileData).length === 0,
235
+ override_applied: _runtimeConfigOverride !== null,
238
236
  },
239
237
  });
240
- return _cachedConfig;
238
+ return config;
241
239
  }
242
240
  function resetConfigCache() {
243
- _cachedConfig = null;
241
+ _runtimeConfigOverride = null;
244
242
  _testContextOverride = null;
245
243
  }
246
244
  function patchRuntimeConfig(partial) {
247
- loadConfig(); // ensure _cachedConfig exists
248
245
  const contextPatch = partial.context;
249
246
  if (contextPatch) {
250
247
  const base = _testContextOverride ?? identity_1.DEFAULT_AGENT_CONTEXT;
251
248
  _testContextOverride = deepMerge(base, contextPatch);
252
249
  }
253
- _cachedConfig = deepMerge(_cachedConfig, partial);
250
+ _runtimeConfigOverride = deepMerge((_runtimeConfigOverride ?? {}), partial);
254
251
  }
255
252
  function getAzureConfig() {
256
253
  const config = loadConfig();
@@ -268,6 +265,10 @@ function getOpenAICodexConfig() {
268
265
  const config = loadConfig();
269
266
  return { ...config.providers["openai-codex"] };
270
267
  }
268
+ function getGithubCopilotConfig() {
269
+ const config = loadConfig();
270
+ return { ...config.providers["github-copilot"] };
271
+ }
271
272
  function getTeamsConfig() {
272
273
  const config = loadConfig();
273
274
  return { ...config.teams };
@@ -339,20 +340,29 @@ function getOpenAIEmbeddingsApiKey() {
339
340
  return getIntegrationsConfig().openaiEmbeddingsApiKey;
340
341
  }
341
342
  function getLogsDir() {
342
- return path.join(os.homedir(), ".agentstate", (0, identity_1.getAgentName)(), "logs");
343
+ return path.join((0, identity_1.getAgentRoot)(), "state", "logs");
343
344
  }
344
345
  function sanitizeKey(key) {
345
346
  return key.replace(/[/:]/g, "_");
346
347
  }
347
- function sessionPath(friendId, channel, key) {
348
- // On Azure App Service, os.homedir() returns /root which is ephemeral.
349
- // Use /home (persistent storage) when WEBSITE_SITE_NAME is set.
350
- /* v8 ignore next -- Azure vs local path branch; environment-specific @preserve */
351
- const homeBase = process.env.WEBSITE_SITE_NAME ? "/home" : os.homedir();
352
- const dir = path.join(homeBase, ".agentstate", (0, identity_1.getAgentName)(), "sessions", friendId, channel);
353
- fs.mkdirSync(dir, { recursive: true });
348
+ function slugify(value) {
349
+ return value
350
+ .trim()
351
+ .toLowerCase()
352
+ .replace(/[^a-z0-9]+/g, "-")
353
+ .replace(/^-+/, "")
354
+ .replace(/-+$/, "");
355
+ }
356
+ function resolveSessionPath(friendId, channel, key, options) {
357
+ const dir = path.join((0, identity_1.getAgentRoot)(), "state", "sessions", friendId, channel);
358
+ if (options?.ensureDir) {
359
+ fs.mkdirSync(dir, { recursive: true });
360
+ }
354
361
  return path.join(dir, sanitizeKey(key) + ".json");
355
362
  }
363
+ function sessionPath(friendId, channel, key) {
364
+ return resolveSessionPath(friendId, channel, key, { ensureDir: true });
365
+ }
356
366
  function logPath(channel, key) {
357
367
  return path.join(getLogsDir(), channel, sanitizeKey(key) + ".ndjson");
358
368
  }