@ouro.bot/cli 0.1.0-alpha.21 → 0.1.0-alpha.211

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 (233) hide show
  1. package/README.md +187 -191
  2. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +3 -2
  3. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +1 -1
  4. package/changelog.json +1318 -0
  5. package/dist/arc/attention-types.js +8 -0
  6. package/dist/arc/cares.js +140 -0
  7. package/dist/arc/episodes.js +119 -0
  8. package/dist/arc/intentions.js +133 -0
  9. package/dist/arc/json-store.js +120 -0
  10. package/dist/arc/obligations.js +237 -0
  11. package/dist/arc/presence.js +185 -0
  12. package/dist/heart/active-work.js +832 -0
  13. package/dist/heart/agent-entry.js +37 -2
  14. package/dist/heart/auth/auth-flow.js +444 -0
  15. package/dist/heart/bridges/manager.js +358 -0
  16. package/dist/heart/bridges/state-machine.js +135 -0
  17. package/dist/heart/bridges/store.js +123 -0
  18. package/dist/heart/commitments.js +111 -0
  19. package/dist/heart/config-registry.js +305 -0
  20. package/dist/heart/config.js +59 -30
  21. package/dist/heart/core.js +606 -131
  22. package/dist/heart/cross-chat-delivery.js +146 -0
  23. package/dist/heart/daemon/agent-config-check.js +149 -0
  24. package/dist/heart/daemon/agent-discovery.js +81 -0
  25. package/dist/heart/daemon/agent-service.js +360 -0
  26. package/dist/heart/daemon/cadence.js +70 -0
  27. package/dist/heart/daemon/cli-defaults.js +557 -0
  28. package/dist/heart/daemon/cli-exec.js +1847 -0
  29. package/dist/heart/daemon/cli-parse.js +759 -0
  30. package/dist/heart/daemon/cli-render.js +316 -0
  31. package/dist/heart/daemon/cli-types.js +8 -0
  32. package/dist/heart/daemon/daemon-cli.js +29 -1163
  33. package/dist/heart/daemon/daemon-entry.js +182 -4
  34. package/dist/heart/daemon/daemon-health.js +136 -0
  35. package/dist/heart/daemon/daemon-runtime-sync.js +153 -12
  36. package/dist/heart/daemon/daemon-tombstone.js +123 -0
  37. package/dist/heart/daemon/daemon.js +491 -18
  38. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  39. package/dist/heart/daemon/hooks/bundle-meta.js +206 -0
  40. package/dist/heart/daemon/inner-status.js +89 -0
  41. package/dist/heart/daemon/launchd.js +165 -0
  42. package/dist/heart/daemon/log-tailer.js +4 -3
  43. package/dist/heart/daemon/message-router.js +17 -8
  44. package/dist/heart/daemon/os-cron-deps.js +134 -0
  45. package/dist/heart/daemon/ouro-bot-entry.js +1 -1
  46. package/dist/heart/daemon/process-manager.js +123 -0
  47. package/dist/heart/daemon/run-hooks.js +39 -0
  48. package/dist/heart/daemon/runtime-logging.js +58 -15
  49. package/dist/heart/daemon/runtime-metadata.js +101 -0
  50. package/dist/heart/daemon/runtime-mode.js +67 -0
  51. package/dist/heart/daemon/safe-mode.js +161 -0
  52. package/dist/heart/daemon/sense-manager.js +71 -2
  53. package/dist/heart/daemon/session-id-resolver.js +131 -0
  54. package/dist/heart/daemon/skill-management-installer.js +94 -0
  55. package/dist/heart/daemon/socket-client.js +202 -0
  56. package/dist/heart/daemon/task-scheduler.js +3 -25
  57. package/dist/heart/daemon/thoughts.js +507 -0
  58. package/dist/heart/delegation.js +62 -0
  59. package/dist/heart/habits/habit-migration.js +181 -0
  60. package/dist/heart/habits/habit-parser.js +119 -0
  61. package/dist/heart/habits/habit-scheduler.js +369 -0
  62. package/dist/heart/{daemon → hatch}/hatch-flow.js +29 -119
  63. package/dist/heart/{daemon → hatch}/hatch-specialist.js +3 -3
  64. package/dist/heart/{daemon → hatch}/specialist-prompt.js +10 -7
  65. package/dist/heart/{daemon → hatch}/specialist-tools.js +49 -3
  66. package/dist/heart/identity.js +144 -55
  67. package/dist/heart/kicks.js +2 -20
  68. package/dist/heart/mcp/mcp-server.js +608 -0
  69. package/dist/heart/migrate-config.js +127 -0
  70. package/dist/heart/model-capabilities.js +48 -0
  71. package/dist/heart/outlook/outlook-http.js +439 -0
  72. package/dist/heart/outlook/outlook-read.js +1618 -0
  73. package/dist/heart/outlook/outlook-render.js +1032 -0
  74. package/dist/heart/outlook/outlook-types.js +7 -0
  75. package/dist/heart/outlook/outlook-view.js +194 -0
  76. package/dist/heart/progress-story.js +42 -0
  77. package/dist/heart/provider-failover.js +88 -0
  78. package/dist/heart/provider-ping.js +162 -0
  79. package/dist/heart/providers/anthropic-token.js +163 -0
  80. package/dist/heart/providers/anthropic.js +187 -41
  81. package/dist/heart/providers/azure.js +116 -10
  82. package/dist/heart/providers/github-copilot.js +157 -0
  83. package/dist/heart/providers/minimax.js +33 -3
  84. package/dist/heart/providers/openai-codex.js +51 -16
  85. package/dist/heart/session-activity.js +172 -0
  86. package/dist/heart/session-recall.js +216 -0
  87. package/dist/heart/start-of-turn-packet.js +330 -0
  88. package/dist/heart/streaming.js +36 -27
  89. package/dist/heart/sync.js +217 -0
  90. package/dist/heart/target-resolution.js +127 -0
  91. package/dist/heart/tempo.js +93 -0
  92. package/dist/heart/temporal-view.js +41 -0
  93. package/dist/heart/tool-activity-callbacks.js +36 -0
  94. package/dist/heart/tool-description.js +135 -0
  95. package/dist/heart/tool-loop.js +200 -0
  96. package/dist/heart/turn-context.js +358 -0
  97. package/dist/heart/turn-coordinator.js +28 -0
  98. package/dist/heart/versioning/ouro-bot-global-installer.js +128 -0
  99. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  100. package/dist/heart/{daemon → versioning}/ouro-path-installer.js +78 -35
  101. package/dist/heart/versioning/ouro-version-manager.js +171 -0
  102. package/dist/heart/versioning/staged-restart.js +138 -0
  103. package/dist/heart/versioning/update-checker.js +111 -0
  104. package/dist/heart/versioning/update-hooks.js +138 -0
  105. package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +41 -3
  106. package/dist/mind/associative-recall.js +126 -66
  107. package/dist/mind/bundle-manifest.js +19 -1
  108. package/dist/mind/context.js +125 -14
  109. package/dist/mind/{memory.js → diary.js} +73 -96
  110. package/dist/mind/embedding-provider.js +60 -0
  111. package/dist/mind/file-state.js +179 -0
  112. package/dist/mind/first-impressions.js +16 -2
  113. package/dist/mind/friends/channel.js +56 -0
  114. package/dist/mind/friends/group-context.js +144 -0
  115. package/dist/mind/friends/store-file.js +36 -0
  116. package/dist/mind/friends/trust-explanation.js +74 -0
  117. package/dist/mind/friends/types.js +8 -0
  118. package/dist/mind/journal-index.js +161 -0
  119. package/dist/mind/obligation-steering.js +221 -0
  120. package/dist/mind/pending.js +76 -9
  121. package/dist/mind/phrases.js +1 -0
  122. package/dist/mind/prompt.js +795 -108
  123. package/dist/mind/scrutiny.js +173 -0
  124. package/dist/mind/token-estimate.js +8 -12
  125. package/dist/nerves/coverage/audit.js +1 -1
  126. package/dist/nerves/coverage/file-completeness.js +47 -5
  127. package/dist/nerves/coverage/run-artifacts.js +1 -1
  128. package/dist/nerves/event-buffer.js +111 -0
  129. package/dist/nerves/index.js +63 -3
  130. package/dist/nerves/observation.js +20 -0
  131. package/dist/nerves/runtime.js +5 -1
  132. package/dist/outlook-ui/assets/index-Ck8agNeO.js +61 -0
  133. package/dist/outlook-ui/assets/index-LwChZTgL.css +1 -0
  134. package/dist/outlook-ui/index.html +15 -0
  135. package/dist/repertoire/ado-client.js +15 -56
  136. package/dist/repertoire/ado-semantic.js +11 -5
  137. package/dist/repertoire/api-client.js +71 -0
  138. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  139. package/dist/repertoire/coding/context-pack.js +330 -0
  140. package/dist/repertoire/coding/feedback.js +197 -30
  141. package/dist/repertoire/coding/manager.js +149 -2
  142. package/dist/repertoire/coding/spawner.js +55 -9
  143. package/dist/repertoire/coding/tools.js +170 -7
  144. package/dist/repertoire/github-client.js +14 -55
  145. package/dist/repertoire/graph-client.js +11 -52
  146. package/dist/repertoire/guardrails.js +291 -0
  147. package/dist/repertoire/mcp-client.js +254 -0
  148. package/dist/repertoire/mcp-manager.js +251 -0
  149. package/dist/repertoire/shell-sessions.js +133 -0
  150. package/dist/repertoire/skills.js +14 -23
  151. package/dist/repertoire/tasks/board.js +43 -5
  152. package/dist/repertoire/tasks/fix.js +182 -0
  153. package/dist/repertoire/tasks/index.js +28 -10
  154. package/dist/repertoire/tasks/lifecycle.js +2 -2
  155. package/dist/repertoire/tasks/parser.js +3 -2
  156. package/dist/repertoire/tasks/scanner.js +194 -37
  157. package/dist/repertoire/tasks/transitions.js +11 -28
  158. package/dist/repertoire/tools-base.js +31 -771
  159. package/dist/repertoire/tools-bluebubbles.js +94 -0
  160. package/dist/repertoire/tools-bridge.js +141 -0
  161. package/dist/repertoire/tools-config.js +266 -0
  162. package/dist/repertoire/tools-continuity.js +248 -0
  163. package/dist/repertoire/tools-files.js +342 -0
  164. package/dist/repertoire/tools-flow.js +62 -0
  165. package/dist/repertoire/tools-github.js +1 -6
  166. package/dist/repertoire/tools-memory.js +347 -0
  167. package/dist/repertoire/tools-session.js +682 -0
  168. package/dist/repertoire/tools-shell.js +120 -0
  169. package/dist/repertoire/tools-surface.js +228 -0
  170. package/dist/repertoire/tools-teams.js +12 -59
  171. package/dist/repertoire/tools.js +132 -124
  172. package/dist/scripts/claude-code-hook.js +41 -0
  173. package/dist/scripts/claude-code-stop-hook.js +47 -0
  174. package/dist/senses/attention-queue.js +97 -0
  175. package/dist/senses/bluebubbles-client.js +102 -3
  176. package/dist/senses/bluebubbles-entry.js +2 -0
  177. package/dist/senses/bluebubbles-inbound-log.js +109 -0
  178. package/dist/senses/bluebubbles-media.js +118 -23
  179. package/dist/senses/bluebubbles-model.js +12 -4
  180. package/dist/senses/bluebubbles-mutation-log.js +45 -5
  181. package/dist/senses/bluebubbles-runtime-state.js +109 -0
  182. package/dist/senses/bluebubbles-session-cleanup.js +72 -0
  183. package/dist/senses/bluebubbles.js +1008 -102
  184. package/dist/senses/cli/adapter.js +274 -0
  185. package/dist/senses/cli/ink-app.js +156 -0
  186. package/dist/senses/cli/inline-diff.js +64 -0
  187. package/dist/senses/cli/message-list.js +51 -0
  188. package/dist/senses/cli/ouro-tui.js +358 -0
  189. package/dist/senses/cli/spinner-imperative.js +135 -0
  190. package/dist/senses/cli/spinner.js +101 -0
  191. package/dist/senses/cli/status-line.js +60 -0
  192. package/dist/senses/cli/streaming-markdown.js +526 -0
  193. package/dist/senses/cli/tool-display.js +83 -0
  194. package/dist/senses/cli/tool-render.js +85 -0
  195. package/dist/senses/cli/tui-store.js +198 -0
  196. package/dist/senses/cli/virtual-list.js +35 -0
  197. package/dist/senses/cli-entry.js +1 -1
  198. package/dist/senses/cli-layout.js +187 -0
  199. package/dist/senses/cli.js +508 -243
  200. package/dist/senses/commands.js +65 -1
  201. package/dist/senses/continuity.js +94 -0
  202. package/dist/senses/habit-turn-message.js +108 -0
  203. package/dist/senses/inner-dialog-worker.js +112 -19
  204. package/dist/senses/inner-dialog.js +591 -84
  205. package/dist/senses/pipeline.js +559 -0
  206. package/dist/senses/shared-turn.js +196 -0
  207. package/dist/senses/surface-tool.js +68 -0
  208. package/dist/senses/teams.js +667 -120
  209. package/dist/senses/trust-gate.js +112 -2
  210. package/package.json +16 -6
  211. package/skills/configure-dev-tools.md +81 -0
  212. package/subagents/README.md +4 -70
  213. package/dist/heart/daemon/subagent-installer.js +0 -134
  214. package/dist/senses/debug-activity.js +0 -107
  215. package/subagents/work-doer.md +0 -235
  216. package/subagents/work-merger.md +0 -618
  217. package/subagents/work-planner.md +0 -382
  218. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  219. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  220. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  221. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  222. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  223. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  224. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  225. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  226. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  227. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  228. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  229. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +0 -0
  230. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  231. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  232. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  233. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.bluebubblesToolDefinitions = void 0;
4
+ const runtime_1 = require("../nerves/runtime");
5
+ exports.bluebubblesToolDefinitions = [
6
+ {
7
+ tool: {
8
+ type: "function",
9
+ function: {
10
+ name: "bluebubbles_set_reply_target",
11
+ description: "choose where the current iMessage turn should land. use this when you want to widen back to top-level or route your update into a specific active thread in the same chat.",
12
+ parameters: {
13
+ type: "object",
14
+ properties: {
15
+ target: {
16
+ type: "string",
17
+ enum: ["current_lane", "top_level", "thread"],
18
+ description: "current_lane mirrors the current inbound lane, top_level answers in the main chat, and thread targets a specific active thread.",
19
+ },
20
+ threadOriginatorGuid: {
21
+ type: "string",
22
+ description: "required when target=thread; use one of the thread ids surfaced in the inbound iMessage context.",
23
+ },
24
+ },
25
+ required: ["target"],
26
+ },
27
+ },
28
+ },
29
+ handler: (args, ctx) => {
30
+ const target = typeof args.target === "string" ? args.target.trim() : "";
31
+ const controller = ctx?.bluebubblesReplyTarget;
32
+ if (!controller) {
33
+ (0, runtime_1.emitNervesEvent)({
34
+ level: "warn",
35
+ component: "tools",
36
+ event: "tool.error",
37
+ message: "bluebubbles reply target missing controller",
38
+ meta: { target },
39
+ });
40
+ return "bluebubbles reply targeting is not available in this context.";
41
+ }
42
+ if (target === "current_lane") {
43
+ const result = controller.setSelection({ target: "current_lane" });
44
+ (0, runtime_1.emitNervesEvent)({
45
+ component: "tools",
46
+ event: "tool.end",
47
+ message: "bluebubbles reply target updated",
48
+ meta: { target: "current_lane", success: true },
49
+ });
50
+ return result;
51
+ }
52
+ if (target === "top_level") {
53
+ const result = controller.setSelection({ target: "top_level" });
54
+ (0, runtime_1.emitNervesEvent)({
55
+ component: "tools",
56
+ event: "tool.end",
57
+ message: "bluebubbles reply target updated",
58
+ meta: { target: "top_level", success: true },
59
+ });
60
+ return result;
61
+ }
62
+ if (target === "thread") {
63
+ const threadOriginatorGuid = typeof args.threadOriginatorGuid === "string" ? args.threadOriginatorGuid.trim() : "";
64
+ if (!threadOriginatorGuid) {
65
+ (0, runtime_1.emitNervesEvent)({
66
+ level: "warn",
67
+ component: "tools",
68
+ event: "tool.error",
69
+ message: "bluebubbles reply target missing thread id",
70
+ meta: { target: "thread" },
71
+ });
72
+ return "threadOriginatorGuid is required when target=thread.";
73
+ }
74
+ const result = controller.setSelection({ target: "thread", threadOriginatorGuid });
75
+ (0, runtime_1.emitNervesEvent)({
76
+ component: "tools",
77
+ event: "tool.end",
78
+ message: "bluebubbles reply target updated",
79
+ meta: { target: "thread", success: true },
80
+ });
81
+ return result;
82
+ }
83
+ (0, runtime_1.emitNervesEvent)({
84
+ level: "warn",
85
+ component: "tools",
86
+ event: "tool.error",
87
+ message: "bluebubbles reply target invalid target",
88
+ meta: { target },
89
+ });
90
+ return "target must be one of: current_lane, top_level, thread.";
91
+ },
92
+ summaryKeys: ["target", "threadOriginatorGuid"],
93
+ },
94
+ ];
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.bridgeToolDefinitions = void 0;
4
+ const config_1 = require("../heart/config");
5
+ const manager_1 = require("../heart/bridges/manager");
6
+ const runtime_1 = require("../nerves/runtime");
7
+ const session_recall_1 = require("../heart/session-recall");
8
+ const NO_SESSION_FOUND_MESSAGE = "no session found for that friend/channel/key combination.";
9
+ const EMPTY_SESSION_MESSAGE = "session exists but has no non-system messages.";
10
+ async function recallSessionSafely(options) {
11
+ try {
12
+ return await (0, session_recall_1.recallSession)(options);
13
+ }
14
+ catch (error) {
15
+ if (options.summarize) {
16
+ (0, runtime_1.emitNervesEvent)({
17
+ component: "daemon",
18
+ event: "daemon.session_recall_summary_fallback",
19
+ message: "session recall summarization failed; using raw transcript",
20
+ meta: {
21
+ friendId: options.friendId,
22
+ channel: options.channel,
23
+ key: options.key,
24
+ /* v8 ignore next -- branch: String(error) fallback only for non-Error throws @preserve */
25
+ error: error instanceof Error ? error.message : String(error),
26
+ },
27
+ });
28
+ try {
29
+ return await (0, session_recall_1.recallSession)({
30
+ ...options,
31
+ summarize: undefined,
32
+ });
33
+ }
34
+ catch {
35
+ return { kind: "missing" };
36
+ }
37
+ }
38
+ return { kind: "missing" };
39
+ }
40
+ }
41
+ exports.bridgeToolDefinitions = [
42
+ // -- cross-session awareness --
43
+ {
44
+ tool: {
45
+ type: "function",
46
+ function: {
47
+ name: "bridge_manage",
48
+ description: "create and manage shared live-work bridges across already-active sessions.",
49
+ parameters: {
50
+ type: "object",
51
+ properties: {
52
+ action: {
53
+ type: "string",
54
+ enum: ["begin", "attach", "status", "promote_task", "complete", "cancel"],
55
+ },
56
+ bridgeId: { type: "string", description: "bridge id for all actions except begin" },
57
+ objective: { type: "string", description: "objective for begin" },
58
+ summary: { type: "string", description: "optional concise shared-work summary" },
59
+ friendId: { type: "string", description: "target friend id for attach" },
60
+ channel: { type: "string", description: "target channel for attach" },
61
+ key: { type: "string", description: "target session key for attach (defaults to 'session')" },
62
+ title: { type: "string", description: "task title override for promote_task" },
63
+ category: { type: "string", description: "task category override for promote_task" },
64
+ body: { type: "string", description: "task body override for promote_task" },
65
+ },
66
+ required: ["action"],
67
+ },
68
+ },
69
+ },
70
+ handler: async (args, ctx) => {
71
+ const manager = (0, manager_1.createBridgeManager)();
72
+ const action = (args.action || "").trim();
73
+ if (action === "begin") {
74
+ if (!ctx?.currentSession) {
75
+ return "bridge_manage begin requires an active session context.";
76
+ }
77
+ const objective = (args.objective || "").trim();
78
+ if (!objective)
79
+ return "objective is required for bridge begin.";
80
+ return (0, manager_1.formatBridgeStatus)(manager.beginBridge({
81
+ objective,
82
+ summary: (args.summary || objective).trim(),
83
+ session: ctx.currentSession,
84
+ }));
85
+ }
86
+ const bridgeId = (args.bridgeId || "").trim();
87
+ if (!bridgeId) {
88
+ return "bridgeId is required for this bridge action.";
89
+ }
90
+ if (action === "attach") {
91
+ const friendId = (args.friendId || "").trim();
92
+ const channel = (args.channel || "").trim();
93
+ const key = (args.key || "session").trim();
94
+ if (!friendId || !channel) {
95
+ return "friendId and channel are required for bridge attach.";
96
+ }
97
+ const sessionPath = (0, config_1.resolveSessionPath)(friendId, channel, key);
98
+ const recall = await recallSessionSafely({
99
+ sessionPath,
100
+ friendId,
101
+ channel,
102
+ key,
103
+ messageCount: 20,
104
+ trustLevel: ctx?.context?.friend?.trustLevel,
105
+ summarize: ctx?.summarize,
106
+ });
107
+ if (recall.kind === "missing") {
108
+ return NO_SESSION_FOUND_MESSAGE;
109
+ }
110
+ return (0, manager_1.formatBridgeStatus)(manager.attachSession(bridgeId, {
111
+ friendId,
112
+ channel,
113
+ key,
114
+ sessionPath,
115
+ snapshot: recall.kind === "ok" ? recall.snapshot : EMPTY_SESSION_MESSAGE,
116
+ }));
117
+ }
118
+ if (action === "status") {
119
+ const bridge = manager.getBridge(bridgeId);
120
+ if (!bridge)
121
+ return `bridge not found: ${bridgeId}`;
122
+ return (0, manager_1.formatBridgeStatus)(bridge);
123
+ }
124
+ if (action === "promote_task") {
125
+ return (0, manager_1.formatBridgeStatus)(manager.promoteBridgeToTask(bridgeId, {
126
+ title: args.title,
127
+ category: args.category,
128
+ body: args.body,
129
+ }));
130
+ }
131
+ if (action === "complete") {
132
+ return (0, manager_1.formatBridgeStatus)(manager.completeBridge(bridgeId));
133
+ }
134
+ if (action === "cancel") {
135
+ return (0, manager_1.formatBridgeStatus)(manager.cancelBridge(bridgeId));
136
+ }
137
+ return `unknown bridge action: ${action}`;
138
+ },
139
+ summaryKeys: ["action", "bridgeId", "objective", "friendId", "channel", "key"],
140
+ },
141
+ ];
@@ -0,0 +1,266 @@
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.configToolDefinitions = void 0;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const runtime_1 = require("../nerves/runtime");
40
+ const identity_1 = require("../heart/identity");
41
+ const config_registry_1 = require("../heart/config-registry");
42
+ exports.configToolDefinitions = [
43
+ {
44
+ tool: {
45
+ type: "function",
46
+ function: {
47
+ name: "read_config",
48
+ description: "Read current agent configuration with tier annotations, descriptions, defaults, and effects. Optionally filter by topic to see only related settings.",
49
+ parameters: {
50
+ type: "object",
51
+ properties: {
52
+ related_to: {
53
+ type: "string",
54
+ description: "Optional topic to filter results (e.g., 'model', 'logging', 'senses'). Case-insensitive partial match.",
55
+ },
56
+ },
57
+ },
58
+ },
59
+ },
60
+ handler: (a) => {
61
+ const entries = a.related_to
62
+ ? (0, config_registry_1.getRegistryEntriesByTopic)(a.related_to)
63
+ : (0, config_registry_1.getRegistryEntries)();
64
+ const agentRoot = (0, identity_1.getAgentRoot)();
65
+ const configPath = path.join(agentRoot, "agent.json");
66
+ let rawConfig = {};
67
+ try {
68
+ rawConfig = JSON.parse(fs.readFileSync(configPath, "utf-8"));
69
+ }
70
+ catch {
71
+ /* v8 ignore next -- defensive: agent.json read failure in read_config @preserve */
72
+ (0, runtime_1.emitNervesEvent)({ component: "repertoire", event: "repertoire.read_config_error", message: "failed to read agent.json", meta: { path: configPath } });
73
+ }
74
+ const result = entries.map((entry) => {
75
+ const parts = entry.path.split(".");
76
+ let current = rawConfig;
77
+ for (const part of parts) {
78
+ if (current && typeof current === "object" && !Array.isArray(current)) {
79
+ current = current[part];
80
+ }
81
+ else {
82
+ current = undefined;
83
+ break;
84
+ }
85
+ }
86
+ const isExplicit = current !== undefined;
87
+ let source;
88
+ let currentValue;
89
+ if (isExplicit) {
90
+ source = "explicit";
91
+ currentValue = current;
92
+ }
93
+ else if (entry.default !== undefined) {
94
+ source = "default";
95
+ currentValue = entry.default;
96
+ }
97
+ else {
98
+ source = "unset";
99
+ currentValue = null;
100
+ }
101
+ return {
102
+ path: entry.path,
103
+ currentValue,
104
+ source,
105
+ tier: entry.tier,
106
+ description: entry.description,
107
+ default: entry.default !== undefined ? entry.default : null,
108
+ effects: entry.effects,
109
+ topics: entry.topics,
110
+ };
111
+ });
112
+ (0, runtime_1.emitNervesEvent)({ component: "repertoire", event: "repertoire.read_config", message: `read_config returned ${result.length} entries`, meta: { count: result.length, topic: a.related_to ?? null } });
113
+ return JSON.stringify({ entries: result }, null, 2);
114
+ },
115
+ },
116
+ {
117
+ tool: {
118
+ type: "function",
119
+ function: {
120
+ name: "update_config",
121
+ description: "Update a Tier 1 (self-service) agent configuration value immediately. For Tier 2 keys that require operator approval, use propose_config instead. Tier 3 (operator-only) keys are refused.",
122
+ parameters: {
123
+ type: "object",
124
+ properties: {
125
+ path: { type: "string", description: "Config key in dot-notation (e.g., 'context.contextMargin', 'logging.level')" },
126
+ value: { type: "string", description: "New value as JSON (e.g., '25', '\"debug\"', '[\"terminal\", \"ndjson\"]')" },
127
+ },
128
+ required: ["path", "value"],
129
+ },
130
+ },
131
+ },
132
+ handler: (a) => {
133
+ const entry = (0, config_registry_1.getRegistryEntry)(a.path);
134
+ if (!entry) {
135
+ (0, runtime_1.emitNervesEvent)({ component: "repertoire", event: "repertoire.update_config_error", message: `unknown config path: ${a.path}`, meta: { path: a.path } });
136
+ return `Error: unknown config path "${a.path}". Use read_config to see available paths.`;
137
+ }
138
+ let parsedValue;
139
+ try {
140
+ parsedValue = JSON.parse(a.value);
141
+ }
142
+ catch {
143
+ (0, runtime_1.emitNervesEvent)({ component: "repertoire", event: "repertoire.update_config_error", message: `invalid JSON value for ${a.path}`, meta: { path: a.path, value: a.value } });
144
+ return `Error: invalid JSON value. Provide value as valid JSON (e.g., 25, "debug", ["terminal"]).`;
145
+ }
146
+ // Validate value against registry entry's validator
147
+ /* v8 ignore next -- all current entries have validators; guard kept for future entries without one @preserve */
148
+ if (entry.validate) {
149
+ const validationError = entry.validate(parsedValue);
150
+ if (validationError) {
151
+ (0, runtime_1.emitNervesEvent)({ component: "repertoire", event: "repertoire.update_config_error", message: `validation failed for ${a.path}: ${validationError}`, meta: { path: a.path, value: a.value, validationError } });
152
+ return `Error: validation failed for "${a.path}": ${validationError}`;
153
+ }
154
+ }
155
+ // Tier 3: refuse
156
+ if (entry.tier === 3) {
157
+ (0, runtime_1.emitNervesEvent)({ component: "repertoire", event: "repertoire.update_config_refused", message: `refused T3 change to ${a.path}`, meta: { path: a.path, tier: 3 } });
158
+ return `Refused: "${a.path}" is an operator-only (Tier 3) key. ${entry.description} Only the operator can change this value directly in agent.json.`;
159
+ }
160
+ // Tier 2: refuse — must use propose_config
161
+ if (entry.tier === 2) {
162
+ (0, runtime_1.emitNervesEvent)({ component: "repertoire", event: "repertoire.update_config_refused", message: `refused T2 change to ${a.path} — use propose_config`, meta: { path: a.path, tier: 2 } });
163
+ return `Refused: "${a.path}" is a Tier 2 (proposal) key that requires operator approval. Use propose_config instead of update_config to propose this change.`;
164
+ }
165
+ const agentRoot = (0, identity_1.getAgentRoot)();
166
+ const configPath = path.join(agentRoot, "agent.json");
167
+ let rawConfig;
168
+ try {
169
+ rawConfig = JSON.parse(fs.readFileSync(configPath, "utf-8"));
170
+ }
171
+ catch {
172
+ /* v8 ignore next -- defensive: agent.json read failure in update_config @preserve */
173
+ return `Error: failed to read agent.json at ${configPath}`;
174
+ }
175
+ // Apply T1 change immediately
176
+ const parts = entry.path.split(".");
177
+ let target = rawConfig;
178
+ for (let i = 0; i < parts.length - 1; i++) {
179
+ if (!(parts[i] in target) || typeof target[parts[i]] !== "object" || target[parts[i]] === null) {
180
+ target[parts[i]] = {};
181
+ }
182
+ target = target[parts[i]];
183
+ }
184
+ target[parts[parts.length - 1]] = parsedValue;
185
+ fs.writeFileSync(configPath, JSON.stringify(rawConfig, null, 2) + "\n", "utf-8");
186
+ (0, runtime_1.emitNervesEvent)({ component: "repertoire", event: "repertoire.update_config_applied", message: `applied config change to ${a.path}`, meta: { path: a.path, tier: entry.tier, value: parsedValue } });
187
+ return `Success: "${a.path}" updated to ${JSON.stringify(parsedValue)}. Change applied immediately.`;
188
+ },
189
+ },
190
+ {
191
+ tool: {
192
+ type: "function",
193
+ function: {
194
+ name: "propose_config",
195
+ description: "Propose a change to a Tier 2 (proposal) agent configuration value. Requires operator approval before the change is applied. For Tier 1 self-service keys, use update_config instead.",
196
+ parameters: {
197
+ type: "object",
198
+ properties: {
199
+ path: { type: "string", description: "Config key in dot-notation (e.g., 'context.maxTokens', 'humanFacing.model')" },
200
+ value: { type: "string", description: "New value as JSON (e.g., '120000', '\"azure\"', '{\"enabled\": true}')" },
201
+ },
202
+ required: ["path", "value"],
203
+ },
204
+ },
205
+ },
206
+ confirmationRequired: true,
207
+ confirmationAlwaysRequired: true,
208
+ handler: (a) => {
209
+ const entry = (0, config_registry_1.getRegistryEntry)(a.path);
210
+ if (!entry) {
211
+ (0, runtime_1.emitNervesEvent)({ component: "repertoire", event: "repertoire.propose_config_error", message: `unknown config path: ${a.path}`, meta: { path: a.path } });
212
+ return `Error: unknown config path "${a.path}". Use read_config to see available paths.`;
213
+ }
214
+ let parsedValue;
215
+ try {
216
+ parsedValue = JSON.parse(a.value);
217
+ }
218
+ catch {
219
+ (0, runtime_1.emitNervesEvent)({ component: "repertoire", event: "repertoire.propose_config_error", message: `invalid JSON value for ${a.path}`, meta: { path: a.path, value: a.value } });
220
+ return `Error: invalid JSON value. Provide value as valid JSON (e.g., 120000, "azure", {"enabled": true}).`;
221
+ }
222
+ // Validate value against registry entry's validator
223
+ /* v8 ignore next -- all current entries have validators; guard kept for future entries without one @preserve */
224
+ if (entry.validate) {
225
+ const validationError = entry.validate(parsedValue);
226
+ if (validationError) {
227
+ (0, runtime_1.emitNervesEvent)({ component: "repertoire", event: "repertoire.propose_config_error", message: `validation failed for ${a.path}: ${validationError}`, meta: { path: a.path, value: a.value, validationError } });
228
+ return `Error: validation failed for "${a.path}": ${validationError}`;
229
+ }
230
+ }
231
+ // Tier 3: refuse
232
+ if (entry.tier === 3) {
233
+ (0, runtime_1.emitNervesEvent)({ component: "repertoire", event: "repertoire.propose_config_refused", message: `refused T3 change to ${a.path}`, meta: { path: a.path, tier: 3 } });
234
+ return `Refused: "${a.path}" is an operator-only (Tier 3) key. ${entry.description} Only the operator can change this value directly in agent.json.`;
235
+ }
236
+ // Tier 1: refuse — use update_config for self-service keys
237
+ if (entry.tier === 1) {
238
+ (0, runtime_1.emitNervesEvent)({ component: "repertoire", event: "repertoire.propose_config_refused", message: `refused T1 change to ${a.path} — use update_config`, meta: { path: a.path, tier: 1 } });
239
+ return `Refused: "${a.path}" is a Tier 1 (self-service) key. Use update_config instead — no operator approval needed.`;
240
+ }
241
+ const agentRoot = (0, identity_1.getAgentRoot)();
242
+ const configPath = path.join(agentRoot, "agent.json");
243
+ let rawConfig;
244
+ try {
245
+ rawConfig = JSON.parse(fs.readFileSync(configPath, "utf-8"));
246
+ }
247
+ catch {
248
+ /* v8 ignore next -- defensive: agent.json read failure in propose_config @preserve */
249
+ return `Error: failed to read agent.json at ${configPath}`;
250
+ }
251
+ // Apply T2 change (operator confirmation already obtained via confirmationAlwaysRequired)
252
+ const parts = entry.path.split(".");
253
+ let target = rawConfig;
254
+ for (let i = 0; i < parts.length - 1; i++) {
255
+ if (!(parts[i] in target) || typeof target[parts[i]] !== "object" || target[parts[i]] === null) {
256
+ target[parts[i]] = {};
257
+ }
258
+ target = target[parts[i]];
259
+ }
260
+ target[parts[parts.length - 1]] = parsedValue;
261
+ fs.writeFileSync(configPath, JSON.stringify(rawConfig, null, 2) + "\n", "utf-8");
262
+ (0, runtime_1.emitNervesEvent)({ component: "repertoire", event: "repertoire.propose_config_applied", message: `applied approved config change to ${a.path}`, meta: { path: a.path, tier: entry.tier, value: parsedValue } });
263
+ return `Success: "${a.path}" updated to ${JSON.stringify(parsedValue)}. Change approved and applied.`;
264
+ },
265
+ },
266
+ ];