@ouro.bot/cli 0.1.0-alpha.39 → 0.1.0-alpha.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/changelog.json CHANGED
@@ -1,6 +1,17 @@
1
1
  {
2
2
  "_note": "This changelog is maintained as part of the PR/version-bump workflow. Agent-curated, not auto-generated. Agents read this file directly via read_file to understand what changed between versions.",
3
3
  "versions": [
4
+ {
5
+ "version": "0.1.0-alpha.40",
6
+ "changes": [
7
+ "Removed dead backward-compat re-exports from core.ts (tools, streaming, prompt, kicks) — consumers already import from the canonical modules.",
8
+ "Removed dead exports: baseToolHandlers, teamsToolHandlers, teamsTools, __internal (token-estimate), TASK_STEM_PATTERN, checkAndRecord403 no-op and METHOD_TO_ACTION.",
9
+ "Consolidated duplicate sanitizeKey (config.ts + bluebubbles-mutation-log.ts) and slugify (hatch-flow.ts + tasks/index.ts) into shared exports from config.ts.",
10
+ "Replaced all as-any casts in source with proper TypeScript narrowing or Record<string, unknown> — only 2 SDK-required casts remain.",
11
+ "Removed unnecessary as-unknown-as casts on readdirSync (4 locations) and spawner double-cast.",
12
+ "Cleaned up commented-out kick detection code, stale TODOs, misplaced imports, and unused type imports."
13
+ ]
14
+ },
4
15
  {
5
16
  "version": "0.1.0-alpha.39",
6
17
  "changes": [
@@ -51,6 +51,8 @@ exports.getBlueBubblesChannelConfig = getBlueBubblesChannelConfig;
51
51
  exports.getIntegrationsConfig = getIntegrationsConfig;
52
52
  exports.getOpenAIEmbeddingsApiKey = getOpenAIEmbeddingsApiKey;
53
53
  exports.getLogsDir = getLogsDir;
54
+ exports.sanitizeKey = sanitizeKey;
55
+ exports.slugify = slugify;
54
56
  exports.resolveSessionPath = resolveSessionPath;
55
57
  exports.sessionPath = sessionPath;
56
58
  exports.logPath = logPath;
@@ -344,6 +346,14 @@ function getLogsDir() {
344
346
  function sanitizeKey(key) {
345
347
  return key.replace(/[/:]/g, "_");
346
348
  }
349
+ function slugify(value) {
350
+ return value
351
+ .trim()
352
+ .toLowerCase()
353
+ .replace(/[^a-z0-9]+/g, "-")
354
+ .replace(/^-+/, "")
355
+ .replace(/-+$/, "");
356
+ }
347
357
  function resolveSessionPath(friendId, channel, key, options) {
348
358
  const dir = path.join((0, identity_1.getAgentRoot)(), "state", "sessions", friendId, channel);
349
359
  if (options?.ensureDir) {
@@ -1,6 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.hasToolIntent = exports.buildSystem = exports.toResponsesTools = exports.toResponsesInput = exports.streamResponsesApi = exports.streamChatCompletion = exports.getToolsForChannel = exports.summarizeArgs = exports.execTool = exports.tools = void 0;
4
3
  exports.createProviderRegistry = createProviderRegistry;
5
4
  exports.resetProviderRuntime = resetProviderRuntime;
6
5
  exports.getModel = getModel;
@@ -16,9 +15,6 @@ const config_1 = require("./config");
16
15
  const identity_1 = require("./identity");
17
16
  const tools_1 = require("../repertoire/tools");
18
17
  const channel_1 = require("../mind/friends/channel");
19
- // Kick detection preserved but disabled — see comment in agent loop below.
20
- // import { detectKick } from "./kicks";
21
- // import type { KickReason } from "./kicks";
22
18
  const runtime_1 = require("../nerves/runtime");
23
19
  const context_1 = require("../mind/context");
24
20
  const prompt_1 = require("../mind/prompt");
@@ -114,24 +110,6 @@ function getProviderDisplayLabel() {
114
110
  };
115
111
  return providerLabelBuilders[getProvider()]();
116
112
  }
117
- // Re-export tools, execTool, summarizeArgs from ./tools for backward compat
118
- var tools_2 = require("../repertoire/tools");
119
- Object.defineProperty(exports, "tools", { enumerable: true, get: function () { return tools_2.tools; } });
120
- Object.defineProperty(exports, "execTool", { enumerable: true, get: function () { return tools_2.execTool; } });
121
- Object.defineProperty(exports, "summarizeArgs", { enumerable: true, get: function () { return tools_2.summarizeArgs; } });
122
- Object.defineProperty(exports, "getToolsForChannel", { enumerable: true, get: function () { return tools_2.getToolsForChannel; } });
123
- // Re-export streaming functions for backward compat
124
- var streaming_1 = require("./streaming");
125
- Object.defineProperty(exports, "streamChatCompletion", { enumerable: true, get: function () { return streaming_1.streamChatCompletion; } });
126
- Object.defineProperty(exports, "streamResponsesApi", { enumerable: true, get: function () { return streaming_1.streamResponsesApi; } });
127
- Object.defineProperty(exports, "toResponsesInput", { enumerable: true, get: function () { return streaming_1.toResponsesInput; } });
128
- Object.defineProperty(exports, "toResponsesTools", { enumerable: true, get: function () { return streaming_1.toResponsesTools; } });
129
- // Re-export prompt functions for backward compat
130
- var prompt_2 = require("../mind/prompt");
131
- Object.defineProperty(exports, "buildSystem", { enumerable: true, get: function () { return prompt_2.buildSystem; } });
132
- // Re-export kick utilities for backward compat
133
- var kicks_1 = require("./kicks");
134
- Object.defineProperty(exports, "hasToolIntent", { enumerable: true, get: function () { return kicks_1.hasToolIntent; } });
135
113
  function upsertSystemPrompt(messages, systemText) {
136
114
  const systemMessage = { role: "system", content: systemText };
137
115
  if (messages[0]?.role === "system") {
@@ -328,9 +306,6 @@ async function runAgent(messages, callbacks, channel, signal, options) {
328
306
  }
329
307
  }
330
308
  await (0, associative_recall_1.injectAssociativeRecall)(messages);
331
- // kickCount and lastKickReason preserved but unused while kick detection is disabled.
332
- // let kickCount = 0;
333
- // let lastKickReason: KickReason | null = null;
334
309
  let done = false;
335
310
  let lastUsage;
336
311
  let overflowRetried = false;
@@ -395,24 +370,9 @@ async function runAgent(messages, callbacks, channel, signal, options) {
395
370
  msg._reasoning_items = reasoningItems;
396
371
  }
397
372
  if (!result.toolCalls.length) {
398
- // Kick detection is disabled while tool_choice: required + final_answer
399
- // is the primary loop control mechanism. The model should never reach
400
- // this path (tool_choice: required forces a tool call), but if it does,
401
- // accept the response as-is rather than risk false-positive kicks.
402
- //
403
- // Preserved for future use — re-enable by uncommenting:
404
- // const kick = detectKick(result.content, options);
405
- // if (kick) {
406
- // kickCount++;
407
- // lastKickReason = kick.reason;
408
- // callbacks.onKick?.();
409
- // const kickContent = result.content
410
- // ? result.content + "\n\n" + kick.message
411
- // : kick.message;
412
- // messages.push({ role: "assistant", content: kickContent });
413
- // providerRuntime.resetTurnState(messages);
414
- // continue;
415
- // }
373
+ // No tool calls accept response as-is.
374
+ // (Kick detection disabled; tool_choice: required + final_answer
375
+ // is the primary loop control. See src/heart/kicks.ts to re-enable.)
416
376
  messages.push(msg);
417
377
  done = true;
418
378
  }
@@ -39,6 +39,7 @@ const fs = __importStar(require("fs"));
39
39
  const os = __importStar(require("os"));
40
40
  const path = __importStar(require("path"));
41
41
  const identity_1 = require("../identity");
42
+ const config_1 = require("../config");
42
43
  const runtime_1 = require("../../nerves/runtime");
43
44
  const hatch_specialist_1 = require("./hatch-specialist");
44
45
  function requiredCredentialKeys(provider) {
@@ -138,14 +139,6 @@ function writeReadme(dir, purpose) {
138
139
  fs.writeFileSync(readmePath, `# ${path.basename(dir)}\n\n${purpose}\n`, "utf-8");
139
140
  }
140
141
  }
141
- function slugify(value) {
142
- const trimmed = value.trim().toLowerCase();
143
- const slug = trimmed
144
- .replace(/[^a-z0-9]+/g, "-")
145
- .replace(/^-+/, "")
146
- .replace(/-+$/, "");
147
- return slug || "friend";
148
- }
149
142
  function pad(value) {
150
143
  return String(value).padStart(2, "0");
151
144
  }
@@ -182,7 +175,7 @@ function writeFriendImprint(bundleRoot, humanName, now) {
182
175
  const friendsDir = path.join(bundleRoot, "friends");
183
176
  fs.mkdirSync(friendsDir, { recursive: true });
184
177
  const nowIso = now.toISOString();
185
- const id = `friend-${slugify(humanName)}`;
178
+ const id = `friend-${(0, config_1.slugify)(humanName) || "friend"}`;
186
179
  const localExternalId = `${os.userInfo().username}@${os.hostname()}`;
187
180
  const record = {
188
181
  id,
@@ -1,25 +1,8 @@
1
1
  "use strict";
2
- // TODO: Kicks enforce "any action" but not "meaningful action". After a narration
3
- // kick, the model can satisfy the constraint by calling a no-op tool like
4
- // list_skills({}). We need to detect trivial compliance and either re-kick
5
- // or discount the tool call. Ideally, the kick message would suggest a specific
6
- // tool call based on conversation context (what the user asked, what tools are
7
- // relevant) rather than just saying "call a tool". That's a bigger piece of work —
8
- // it requires the kick system to be context-aware.
9
- // See ouroboros' observation: "i'm not chickening out. i'm satisfying a crude
10
- // constraint. poorly."
11
- //
12
- // A kick is a self-correction. When the harness detects a malformed response,
13
- // it injects an assistant-role message as if the model caught its own mistake.
14
- //
15
- // Kicks are:
16
- // - assistant role (self-correction, not external rebuke)
17
- // - first person ("I" not "you")
18
- // - forward-looking (what I'm doing next, not what I did wrong)
19
- // - short (one sentence)
20
2
  Object.defineProperty(exports, "__esModule", { value: true });
21
3
  exports.hasToolIntent = hasToolIntent;
22
4
  exports.detectKick = detectKick;
5
+ const runtime_1 = require("../nerves/runtime");
23
6
  const KICK_MESSAGES = {
24
7
  empty: "I sent an empty message by accident — let me try again.",
25
8
  narration: "I narrated instead of acting. Using the tool now -- if done, calling final_answer.",
@@ -141,4 +124,3 @@ function detectKick(content, options) {
141
124
  }
142
125
  return null;
143
126
  }
144
- const runtime_1 = require("../nerves/runtime");
@@ -50,17 +50,17 @@ function buildTrimmableBlocks(messages) {
50
50
  let i = 0;
51
51
  while (i < messages.length) {
52
52
  const msg = messages[i];
53
- if (msg?.role === "system") {
53
+ if (msg.role === "system") {
54
54
  i++;
55
55
  continue;
56
56
  }
57
57
  // Tool coherence block: assistant message with tool_calls + immediately following tool results
58
- if (msg?.role === "assistant" && Array.isArray(msg.tool_calls) && msg.tool_calls.length > 0) {
58
+ if (msg.role === "assistant" && Array.isArray(msg.tool_calls) && msg.tool_calls.length > 0) {
59
59
  const indices = [i];
60
60
  i++;
61
61
  while (i < messages.length) {
62
62
  const next = messages[i];
63
- if (next?.role !== "tool")
63
+ if (next.role !== "tool")
64
64
  break;
65
65
  indices.push(i);
66
66
  i++;
@@ -78,13 +78,13 @@ function buildTrimmableBlocks(messages) {
78
78
  function getSystemMessageIndices(messages) {
79
79
  const indices = [];
80
80
  for (let i = 0; i < messages.length; i++) {
81
- if (messages[i]?.role === "system")
81
+ if (messages[i].role === "system")
82
82
  indices.push(i);
83
83
  }
84
84
  return indices;
85
85
  }
86
86
  function buildTrimmedMessages(messages, kept) {
87
- return messages.filter((m, idx) => m?.role === "system" || kept.has(idx));
87
+ return messages.filter((m, idx) => m.role === "system" || kept.has(idx));
88
88
  }
89
89
  function trimMessages(messages, maxTokens, contextMargin, actualTokenCount) {
90
90
  const targetTokens = Math.floor(maxTokens * (1 - contextMargin / 100));
@@ -132,7 +132,7 @@ function trimMessages(messages, maxTokens, contextMargin, actualTokenCount) {
132
132
  let remaining = actualTokenCount;
133
133
  const kept = new Set();
134
134
  for (let i = 0; i < messages.length; i++) {
135
- if (messages[i]?.role !== "system")
135
+ if (messages[i].role !== "system")
136
136
  kept.add(i);
137
137
  }
138
138
  // Drop oldest blocks until we fall under target.
@@ -146,7 +146,7 @@ function trimMessages(messages, maxTokens, contextMargin, actualTokenCount) {
146
146
  let trimmed = buildTrimmedMessages(messages, kept);
147
147
  // If we're still above budget after dropping everything trimmable, preserve system only.
148
148
  if (remaining > targetTokens) {
149
- trimmed = messages.filter((m) => m?.role === "system");
149
+ trimmed = messages.filter((m) => m.role === "system");
150
150
  }
151
151
  const estimatedAfter = (0, token_estimate_1.estimateTokensForMessages)(trimmed);
152
152
  (0, runtime_1.emitNervesEvent)({
@@ -1,6 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.__internal = void 0;
4
3
  exports.estimateTokensForMessage = estimateTokensForMessage;
5
4
  exports.estimateTokensForMessages = estimateTokensForMessages;
6
5
  const runtime_1 = require("../nerves/runtime");
@@ -53,7 +52,7 @@ function countCharsInContent(content) {
53
52
  return c.text.length;
54
53
  if (typeof c.content === "string")
55
54
  return c.content.length;
56
- return safeStringify(content).length;
55
+ return safeStringify(c).length;
57
56
  }
58
57
  return 0;
59
58
  }
@@ -70,12 +69,13 @@ function countCharsInToolCalls(toolCalls) {
70
69
  if (typeof t.type === "string")
71
70
  total += t.type.length;
72
71
  if (t.function && typeof t.function === "object") {
73
- if (typeof t.function.name === "string")
74
- total += t.function.name.length;
75
- if (typeof t.function.arguments === "string")
76
- total += t.function.arguments.length;
77
- else if (t.function.arguments != null)
78
- total += safeStringify(t.function.arguments).length;
72
+ const fn = t.function;
73
+ if (typeof fn.name === "string")
74
+ total += fn.name.length;
75
+ if (typeof fn.arguments === "string")
76
+ total += fn.arguments.length;
77
+ else if (fn.arguments != null)
78
+ total += safeStringify(fn.arguments).length;
79
79
  }
80
80
  }
81
81
  return total;
@@ -113,7 +113,3 @@ function estimateTokensForMessages(msgs) {
113
113
  total += estimateTokensForMessage(msg);
114
114
  return total;
115
115
  }
116
- exports.__internal = {
117
- CHARS_PER_TOKEN,
118
- PER_MESSAGE_OVERHEAD_TOKENS,
119
- };
@@ -37,6 +37,7 @@ exports.getTaskModule = getTaskModule;
37
37
  exports.resetTaskModule = resetTaskModule;
38
38
  const fs = __importStar(require("fs"));
39
39
  const path = __importStar(require("path"));
40
+ const config_1 = require("../../heart/config");
40
41
  const runtime_1 = require("../../nerves/runtime");
41
42
  const board_1 = require("./board");
42
43
  const lifecycle_1 = require("./lifecycle");
@@ -55,14 +56,6 @@ function formatStemTimestamp(now = new Date()) {
55
56
  const minutes = String(now.getMinutes()).padStart(2, "0");
56
57
  return `${year}-${month}-${day}-${hours}${minutes}`;
57
58
  }
58
- function slugify(input) {
59
- return input
60
- .toLowerCase()
61
- .replace(/[^a-z0-9]+/g, "-")
62
- .replace(/^-+/, "")
63
- .replace(/-+$/, "")
64
- .slice(0, 64);
65
- }
66
59
  function findTask(index, nameOrStem) {
67
60
  return (index.tasks.find((task) => task.stem === nameOrStem || task.name === nameOrStem) ??
68
61
  index.tasks.find((task) => task.stem.endsWith(nameOrStem)) ??
@@ -98,7 +91,7 @@ class FileTaskModule {
98
91
  throw new Error(`invalid task status: ${String(input.status)}`);
99
92
  }
100
93
  const collection = (0, transitions_1.canonicalCollectionForTaskType)(type);
101
- const stem = `${formatStemTimestamp()}-${slugify(input.title) || "task"}`;
94
+ const stem = `${formatStemTimestamp()}-${(0, config_1.slugify)(input.title).slice(0, 64) || "task"}`;
102
95
  const filename = `${stem}.md`;
103
96
  const root = (0, scanner_1.getTaskRoot)();
104
97
  const filePath = path.join(root, collection, filename);
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TASK_REQUIRED_TEMPLATE_FIELDS = exports.TASK_FILENAME_PATTERN = exports.TASK_STEM_PATTERN = exports.TASK_RESERVED_DIRECTORIES = exports.TASK_TYPE_TO_COLLECTION = exports.TASK_CANONICAL_COLLECTIONS = exports.TASK_CANONICAL_TYPES = exports.TASK_STATUS_TRANSITIONS = exports.TASK_VALID_STATUSES = void 0;
3
+ exports.TASK_REQUIRED_TEMPLATE_FIELDS = exports.TASK_FILENAME_PATTERN = exports.TASK_RESERVED_DIRECTORIES = exports.TASK_TYPE_TO_COLLECTION = exports.TASK_CANONICAL_COLLECTIONS = exports.TASK_CANONICAL_TYPES = exports.TASK_STATUS_TRANSITIONS = exports.TASK_VALID_STATUSES = void 0;
4
4
  exports.canonicalCollectionForTaskType = canonicalCollectionForTaskType;
5
5
  exports.normalizeTaskType = normalizeTaskType;
6
6
  exports.normalizeTaskStatus = normalizeTaskStatus;
@@ -42,7 +42,6 @@ exports.TASK_TYPE_TO_COLLECTION = {
42
42
  habit: "habits",
43
43
  };
44
44
  exports.TASK_RESERVED_DIRECTORIES = ["templates", ".trash", "archive"];
45
- exports.TASK_STEM_PATTERN = /^\d{4}-\d{2}-\d{2}-\d{4}-[a-z0-9][a-z0-9-]*$/;
46
45
  exports.TASK_FILENAME_PATTERN = /^\d{4}-\d{2}-\d{2}-\d{4}-[a-z0-9][a-z0-9-]*\.md$/;
47
46
  exports.TASK_REQUIRED_TEMPLATE_FIELDS = {
48
47
  "one-shot": [
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.finalAnswerTool = exports.baseToolHandlers = exports.tools = exports.baseToolDefinitions = exports.editFileReadTracker = void 0;
36
+ exports.finalAnswerTool = exports.tools = exports.baseToolDefinitions = exports.editFileReadTracker = void 0;
37
37
  const fs = __importStar(require("fs"));
38
38
  const fg = __importStar(require("fast-glob"));
39
39
  const child_process_1 = require("child_process");
@@ -682,10 +682,7 @@ exports.baseToolDefinitions = [
682
682
  },
683
683
  ...tools_1.codingToolDefinitions,
684
684
  ];
685
- // Backward-compat: extract just the OpenAI tool schemas
686
685
  exports.tools = exports.baseToolDefinitions.map((d) => d.tool);
687
- // Backward-compat: extract just the handlers by name
688
- exports.baseToolHandlers = Object.fromEntries(exports.baseToolDefinitions.map((d) => [d.tool.function.name, d.handler]));
689
686
  exports.finalAnswerTool = {
690
687
  type: "function",
691
688
  function: {
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.teamsToolHandlers = exports.teamsTools = exports.teamsToolDefinitions = void 0;
6
+ exports.teamsToolDefinitions = void 0;
7
7
  exports.summarizeTeamsArgs = summarizeTeamsArgs;
8
8
  const graph_client_1 = require("./graph-client");
9
9
  const ado_client_1 = require("./ado-client");
@@ -11,16 +11,6 @@ const graph_endpoints_json_1 = __importDefault(require("./data/graph-endpoints.j
11
11
  const ado_endpoints_json_1 = __importDefault(require("./data/ado-endpoints.json"));
12
12
  const runtime_1 = require("../nerves/runtime");
13
13
  const MUTATE_METHODS = ["POST", "PATCH", "DELETE"];
14
- // Map HTTP method to authority action name for canWrite() checks
15
- const METHOD_TO_ACTION = {
16
- POST: "createWorkItem",
17
- PATCH: "updateWorkItem",
18
- DELETE: "deleteWorkItem",
19
- };
20
- // Check if a tool response indicates a 403 PERMISSION_DENIED (authority checker removed; this is now a no-op kept for call-site stability)
21
- function checkAndRecord403(_result, _integration, _scope, _action, _ctx) {
22
- // No-op: AuthorityChecker eliminated. 403 recording removed.
23
- }
24
14
  const DEFAULT_ADO_QUERY = "SELECT [System.Id], [System.Title], [System.State], [System.AssignedTo] FROM WorkItems WHERE [System.AssignedTo] = @Me AND [System.State] <> 'Closed' ORDER BY [System.ChangedDate] DESC";
25
15
  exports.teamsToolDefinitions = [
26
16
  // -- Generic Graph tools --
@@ -101,9 +91,7 @@ exports.teamsToolDefinitions = [
101
91
  return "AUTH_REQUIRED:ado -- I need access to Azure DevOps. Please sign in when prompted.";
102
92
  }
103
93
  const method = args.method || "GET";
104
- const result = await (0, ado_client_1.adoRequest)(ctx.adoToken, method, args.organization, args.path, args.body, args.host);
105
- checkAndRecord403(result, "ado", args.organization, method, ctx);
106
- return result;
94
+ return (0, ado_client_1.adoRequest)(ctx.adoToken, method, args.organization, args.path, args.body, args.host);
107
95
  },
108
96
  integration: "ado",
109
97
  },
@@ -133,11 +121,7 @@ exports.teamsToolDefinitions = [
133
121
  if (!MUTATE_METHODS.includes(args.method)) {
134
122
  return `Invalid method "${args.method}". Must be one of: ${MUTATE_METHODS.join(", ")}`;
135
123
  }
136
- /* v8 ignore next -- fallback unreachable: method is validated against MUTATE_METHODS above @preserve */
137
- const action = METHOD_TO_ACTION[args.method] || args.method;
138
- const result = await (0, ado_client_1.adoRequest)(ctx.adoToken, args.method, args.organization, args.path, args.body, args.host);
139
- checkAndRecord403(result, "ado", args.organization, action, ctx);
140
- return result;
124
+ return (0, ado_client_1.adoRequest)(ctx.adoToken, args.method, args.organization, args.path, args.body, args.host);
141
125
  },
142
126
  integration: "ado",
143
127
  confirmationRequired: true,
@@ -292,10 +276,6 @@ exports.teamsToolDefinitions = [
292
276
  integration: "ado",
293
277
  },
294
278
  ];
295
- // Backward-compat: extract just the OpenAI tool schemas
296
- exports.teamsTools = exports.teamsToolDefinitions.map((d) => d.tool);
297
- // Backward-compat: extract just the handlers by name
298
- exports.teamsToolHandlers = Object.fromEntries(exports.teamsToolDefinitions.map((d) => [d.tool.function.name, d.handler]));
299
279
  function searchEndpoints(entries, query) {
300
280
  (0, runtime_1.emitNervesEvent)({
301
281
  component: "repertoire",
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.REMOTE_BLOCKED_LOCAL_TOOLS = exports.teamsTools = exports.finalAnswerTool = exports.tools = void 0;
3
+ exports.REMOTE_BLOCKED_LOCAL_TOOLS = exports.finalAnswerTool = exports.tools = void 0;
4
4
  exports.getToolsForChannel = getToolsForChannel;
5
5
  exports.isConfirmationRequired = isConfirmationRequired;
6
6
  exports.execTool = execTool;
@@ -17,8 +17,6 @@ const runtime_1 = require("../nerves/runtime");
17
17
  var tools_base_2 = require("./tools-base");
18
18
  Object.defineProperty(exports, "tools", { enumerable: true, get: function () { return tools_base_2.tools; } });
19
19
  Object.defineProperty(exports, "finalAnswerTool", { enumerable: true, get: function () { return tools_base_2.finalAnswerTool; } });
20
- var tools_teams_2 = require("./tools-teams");
21
- Object.defineProperty(exports, "teamsTools", { enumerable: true, get: function () { return tools_teams_2.teamsTools; } });
22
20
  // All tool definitions in a single registry
23
21
  const allDefinitions = [...tools_base_1.baseToolDefinitions, ...tools_bluebubbles_1.bluebubblesToolDefinitions, ...tools_teams_1.teamsToolDefinitions, ...ado_semantic_1.adoSemanticToolDefinitions, ...tools_github_1.githubToolDefinitions];
24
22
  /** Tool names blocked for untrusted remote contexts. Shared with prompt.ts for restriction messaging. */
@@ -39,11 +39,9 @@ const fs = __importStar(require("node:fs"));
39
39
  const path = __importStar(require("node:path"));
40
40
  const runtime_1 = require("../nerves/runtime");
41
41
  const identity_1 = require("../heart/identity");
42
- function sanitizeKey(key) {
43
- return key.replace(/[/:]/g, "_");
44
- }
42
+ const config_1 = require("../heart/config");
45
43
  function getBlueBubblesMutationLogPath(agentName, sessionKey) {
46
- return path.join((0, identity_1.getAgentRoot)(agentName), "state", "senses", "bluebubbles", "mutations", `${sanitizeKey(sessionKey)}.ndjson`);
44
+ return path.join((0, identity_1.getAgentRoot)(agentName), "state", "senses", "bluebubbles", "mutations", `${(0, config_1.sanitizeKey)(sessionKey)}.ndjson`);
47
45
  }
48
46
  function recordBlueBubblesMutation(agentName, event) {
49
47
  const filePath = getBlueBubblesMutationLogPath(agentName, event.chat.sessionKey);
@@ -41,8 +41,7 @@ const identity_1 = require("../heart/identity");
41
41
  const runtime_1 = require("../nerves/runtime");
42
42
  const types_1 = require("../mind/friends/types");
43
43
  const pending_1 = require("../mind/pending");
44
- // TODO: agent should pre-configure auto-reply voice
45
- // This is a canned reply; in future the agent should compose their own first-contact message
44
+ // Canned reply; eventually agents should compose their own first-contact message
46
45
  exports.STRANGER_AUTO_REPLY = "I'm sorry, I'm not allowed to talk to strangers";
47
46
  function buildExternalKey(provider, externalId, tenantId) {
48
47
  return `${provider}:${tenantId ?? ""}:${externalId}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ouro.bot/cli",
3
- "version": "0.1.0-alpha.39",
3
+ "version": "0.1.0-alpha.40",
4
4
  "main": "dist/heart/daemon/ouro-entry.js",
5
5
  "bin": {
6
6
  "cli": "dist/heart/daemon/ouro-bot-entry.js",