@ouro.bot/cli 0.1.0-alpha.6 → 0.1.0-alpha.61

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 (119) hide show
  1. package/AdoptionSpecialist.ouro/agent.json +70 -9
  2. package/AdoptionSpecialist.ouro/psyche/SOUL.md +5 -2
  3. package/AdoptionSpecialist.ouro/psyche/identities/monty.md +2 -2
  4. package/README.md +147 -205
  5. package/assets/ouroboros.png +0 -0
  6. package/changelog.json +334 -0
  7. package/dist/heart/active-work.js +178 -0
  8. package/dist/heart/bridges/manager.js +358 -0
  9. package/dist/heart/bridges/state-machine.js +135 -0
  10. package/dist/heart/bridges/store.js +123 -0
  11. package/dist/heart/config.js +57 -23
  12. package/dist/heart/core.js +236 -90
  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/auth-flow.js +351 -0
  16. package/dist/heart/daemon/daemon-cli.js +1175 -232
  17. package/dist/heart/daemon/daemon-entry.js +55 -6
  18. package/dist/heart/daemon/daemon-runtime-sync.js +212 -0
  19. package/dist/heart/daemon/daemon.js +189 -10
  20. package/dist/heart/daemon/hatch-animation.js +10 -3
  21. package/dist/heart/daemon/hatch-flow.js +4 -82
  22. package/dist/heart/daemon/hooks/bundle-meta.js +92 -0
  23. package/dist/heart/daemon/launchd.js +159 -0
  24. package/dist/heart/daemon/log-tailer.js +4 -3
  25. package/dist/heart/daemon/message-router.js +17 -8
  26. package/dist/heart/daemon/ouro-bot-entry.js +0 -0
  27. package/dist/heart/daemon/ouro-bot-global-installer.js +128 -0
  28. package/dist/heart/daemon/ouro-entry.js +0 -0
  29. package/dist/heart/daemon/ouro-path-installer.js +178 -0
  30. package/dist/heart/daemon/ouro-uti.js +11 -2
  31. package/dist/heart/daemon/process-manager.js +14 -1
  32. package/dist/heart/daemon/run-hooks.js +37 -0
  33. package/dist/heart/daemon/runtime-logging.js +58 -15
  34. package/dist/heart/daemon/runtime-metadata.js +219 -0
  35. package/dist/heart/daemon/runtime-mode.js +67 -0
  36. package/dist/heart/daemon/sense-manager.js +307 -0
  37. package/dist/heart/daemon/skill-management-installer.js +73 -0
  38. package/dist/heart/daemon/socket-client.js +202 -0
  39. package/dist/heart/daemon/specialist-orchestrator.js +53 -84
  40. package/dist/heart/daemon/specialist-prompt.js +64 -5
  41. package/dist/heart/daemon/specialist-tools.js +213 -58
  42. package/dist/heart/daemon/staged-restart.js +114 -0
  43. package/dist/heart/daemon/thoughts.js +379 -0
  44. package/dist/heart/daemon/update-checker.js +111 -0
  45. package/dist/heart/daemon/update-hooks.js +138 -0
  46. package/dist/heart/daemon/wrapper-publish-guard.js +86 -0
  47. package/dist/heart/delegation.js +62 -0
  48. package/dist/heart/identity.js +122 -19
  49. package/dist/heart/kicks.js +1 -19
  50. package/dist/heart/model-capabilities.js +40 -0
  51. package/dist/heart/progress-story.js +42 -0
  52. package/dist/heart/providers/anthropic.js +74 -9
  53. package/dist/heart/providers/azure.js +86 -7
  54. package/dist/heart/providers/minimax.js +4 -0
  55. package/dist/heart/providers/openai-codex.js +12 -3
  56. package/dist/heart/safe-workspace.js +228 -0
  57. package/dist/heart/sense-truth.js +61 -0
  58. package/dist/heart/session-activity.js +169 -0
  59. package/dist/heart/session-recall.js +116 -0
  60. package/dist/heart/streaming.js +100 -22
  61. package/dist/heart/target-resolution.js +123 -0
  62. package/dist/heart/turn-coordinator.js +28 -0
  63. package/dist/mind/associative-recall.js +14 -2
  64. package/dist/mind/bundle-manifest.js +70 -0
  65. package/dist/mind/context.js +27 -11
  66. package/dist/mind/first-impressions.js +16 -2
  67. package/dist/mind/friends/channel.js +35 -0
  68. package/dist/mind/friends/group-context.js +144 -0
  69. package/dist/mind/friends/store-file.js +19 -0
  70. package/dist/mind/friends/trust-explanation.js +74 -0
  71. package/dist/mind/friends/types.js +8 -0
  72. package/dist/mind/memory.js +27 -26
  73. package/dist/mind/pending.js +72 -9
  74. package/dist/mind/phrases.js +1 -0
  75. package/dist/mind/prompt.js +299 -77
  76. package/dist/mind/token-estimate.js +8 -12
  77. package/dist/nerves/cli-logging.js +15 -2
  78. package/dist/nerves/coverage/run-artifacts.js +1 -1
  79. package/dist/repertoire/ado-client.js +4 -2
  80. package/dist/repertoire/coding/feedback.js +134 -0
  81. package/dist/repertoire/coding/index.js +4 -1
  82. package/dist/repertoire/coding/manager.js +62 -4
  83. package/dist/repertoire/coding/spawner.js +3 -3
  84. package/dist/repertoire/coding/tools.js +41 -2
  85. package/dist/repertoire/data/ado-endpoints.json +188 -0
  86. package/dist/repertoire/skills.js +3 -26
  87. package/dist/repertoire/tasks/board.js +12 -0
  88. package/dist/repertoire/tasks/index.js +23 -9
  89. package/dist/repertoire/tasks/transitions.js +1 -2
  90. package/dist/repertoire/tools-base.js +629 -251
  91. package/dist/repertoire/tools-bluebubbles.js +93 -0
  92. package/dist/repertoire/tools-teams.js +58 -25
  93. package/dist/repertoire/tools.js +92 -48
  94. package/dist/senses/bluebubbles-client.js +210 -5
  95. package/dist/senses/bluebubbles-entry.js +2 -0
  96. package/dist/senses/bluebubbles-inbound-log.js +109 -0
  97. package/dist/senses/bluebubbles-media.js +339 -0
  98. package/dist/senses/bluebubbles-model.js +12 -4
  99. package/dist/senses/bluebubbles-mutation-log.js +45 -5
  100. package/dist/senses/bluebubbles-runtime-state.js +109 -0
  101. package/dist/senses/bluebubbles-session-cleanup.js +72 -0
  102. package/dist/senses/bluebubbles.js +890 -45
  103. package/dist/senses/cli-layout.js +87 -0
  104. package/dist/senses/cli.js +345 -144
  105. package/dist/senses/continuity.js +94 -0
  106. package/dist/senses/debug-activity.js +148 -0
  107. package/dist/senses/inner-dialog-worker.js +47 -18
  108. package/dist/senses/inner-dialog.js +330 -84
  109. package/dist/senses/pipeline.js +278 -0
  110. package/dist/senses/teams.js +570 -129
  111. package/dist/senses/trust-gate.js +112 -2
  112. package/package.json +14 -3
  113. package/subagents/README.md +4 -70
  114. package/dist/heart/daemon/specialist-session.js +0 -142
  115. package/dist/heart/daemon/subagent-installer.js +0 -125
  116. package/dist/inner-worker-entry.js +0 -4
  117. package/subagents/work-doer.md +0 -233
  118. package/subagents/work-merger.md +0 -624
  119. package/subagents/work-planner.md +0 -373
@@ -50,10 +50,6 @@ function getSkillsDir() {
50
50
  function getProtocolMirrorDir() {
51
51
  return path.join(getSkillsDir(), "protocols");
52
52
  }
53
- // Canonical protocol source lives in {repoRoot}/subagents/.
54
- function getCanonicalProtocolsDir() {
55
- return path.join((0, identity_1.getRepoRoot)(), "subagents");
56
- }
57
53
  function listMarkdownBasenames(dir) {
58
54
  if (!fs.existsSync(dir))
59
55
  return [];
@@ -74,8 +70,7 @@ function listSkills() {
74
70
  });
75
71
  const baseSkills = listMarkdownBasenames(getSkillsDir());
76
72
  const protocolMirrors = listMarkdownBasenames(getProtocolMirrorDir());
77
- const canonicalProtocols = listMarkdownBasenames(getCanonicalProtocolsDir());
78
- const skills = [...new Set([...baseSkills, ...protocolMirrors, ...canonicalProtocols])].sort();
73
+ const skills = [...new Set([...baseSkills, ...protocolMirrors])].sort();
79
74
  (0, runtime_1.emitNervesEvent)({
80
75
  event: "repertoire.load_end",
81
76
  component: "repertoire",
@@ -93,7 +88,6 @@ function loadSkill(skillName) {
93
88
  });
94
89
  const directSkillPath = path.join(getSkillsDir(), `${skillName}.md`);
95
90
  const protocolMirrorPath = path.join(getProtocolMirrorDir(), `${skillName}.md`);
96
- const canonicalProtocolPath = path.join(getCanonicalProtocolsDir(), `${skillName}.md`);
97
91
  let resolvedPath = null;
98
92
  // 1) Direct agent skill.
99
93
  if (fs.existsSync(directSkillPath)) {
@@ -103,22 +97,6 @@ function loadSkill(skillName) {
103
97
  else if (fs.existsSync(protocolMirrorPath)) {
104
98
  resolvedPath = protocolMirrorPath;
105
99
  }
106
- // 3) Canonical protocol fallback.
107
- else if (fs.existsSync(canonicalProtocolPath)) {
108
- (0, runtime_1.emitNervesEvent)({
109
- level: "warn",
110
- event: "repertoire.error",
111
- component: "repertoire",
112
- message: "protocol mirror missing; using canonical fallback",
113
- meta: {
114
- operation: "loadSkill",
115
- skill: skillName,
116
- mirrorPath: protocolMirrorPath,
117
- canonicalPath: canonicalProtocolPath,
118
- },
119
- });
120
- resolvedPath = canonicalProtocolPath;
121
- }
122
100
  if (!resolvedPath) {
123
101
  (0, runtime_1.emitNervesEvent)({
124
102
  level: "error",
@@ -128,13 +106,12 @@ function loadSkill(skillName) {
128
106
  meta: {
129
107
  operation: "loadSkill",
130
108
  skill: skillName,
131
- checkedPaths: [directSkillPath, protocolMirrorPath, canonicalProtocolPath],
109
+ checkedPaths: [directSkillPath, protocolMirrorPath],
132
110
  },
133
111
  });
134
112
  throw new Error(`skill '${skillName}' not found in:\n` +
135
113
  `- ${directSkillPath}\n` +
136
- `- ${protocolMirrorPath}\n` +
137
- `- ${canonicalProtocolPath}`);
114
+ `- ${protocolMirrorPath}`);
138
115
  }
139
116
  const content = fs.readFileSync(resolvedPath, "utf-8");
140
117
  if (!loadedSkills.includes(skillName)) {
@@ -59,6 +59,12 @@ function activeSessionLines(tasks) {
59
59
  });
60
60
  return active.map((task) => task.stem).sort();
61
61
  }
62
+ function activeBridgeLines(tasks) {
63
+ return tasks
64
+ .filter((task) => typeof task.frontmatter.active_bridge === "string" && String(task.frontmatter.active_bridge).trim())
65
+ .map((task) => `${task.stem} -> ${String(task.frontmatter.active_bridge).trim()}`)
66
+ .sort();
67
+ }
62
68
  function actionRequired(index, byStatus) {
63
69
  const actions = [...index.parseErrors, ...index.invalidFilenames.map((filePath) => `bad filename: ${filePath}`)];
64
70
  if (byStatus.blocked.length > 0) {
@@ -99,6 +105,11 @@ function buildTaskBoard(index) {
99
105
  fullLines.push("## active sessions");
100
106
  fullLines.push(active.map((line) => `- ${line}`).join("\n"));
101
107
  }
108
+ const activeBridges = activeBridgeLines(index.tasks);
109
+ if (activeBridges.length > 0) {
110
+ fullLines.push("## active bridges");
111
+ fullLines.push(activeBridges.map((line) => `- ${line}`).join("\n"));
112
+ }
102
113
  return {
103
114
  compact,
104
115
  full: fullLines.join("\n\n"),
@@ -106,6 +117,7 @@ function buildTaskBoard(index) {
106
117
  actionRequired: actionRequired(index, byStatus),
107
118
  unresolvedDependencies: unresolved,
108
119
  activeSessions: active,
120
+ activeBridges,
109
121
  };
110
122
  }
111
123
  function boardStatus(board, status) {
@@ -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);
@@ -122,6 +115,12 @@ class FileTaskModule {
122
115
  frontmatter.parent_task = null;
123
116
  frontmatter.depends_on = [];
124
117
  }
118
+ if (input.activeBridge && input.activeBridge.trim()) {
119
+ frontmatter.active_bridge = input.activeBridge.trim();
120
+ }
121
+ if (Array.isArray(input.bridgeSessions) && input.bridgeSessions.length > 0) {
122
+ frontmatter.bridge_sessions = input.bridgeSessions.filter((value) => typeof value === "string" && value.trim());
123
+ }
125
124
  const content = (0, parser_1.renderTaskFile)(frontmatter, input.body);
126
125
  const validation = (0, middleware_1.validateWrite)(filePath, content);
127
126
  if (!validation.ok) {
@@ -132,6 +131,21 @@ class FileTaskModule {
132
131
  (0, scanner_1.clearTaskScanCache)();
133
132
  return filePath;
134
133
  }
134
+ bindBridge(name, input) {
135
+ const task = this.getTask(name);
136
+ if (!task) {
137
+ return { ok: false, reason: `task not found: ${name}` };
138
+ }
139
+ const content = fs.readFileSync(task.path, "utf-8");
140
+ const parsed = (0, parser_1.parseTaskFile)(content, task.path);
141
+ const frontmatter = removeRuntimeFrontmatter(parsed.frontmatter);
142
+ frontmatter.active_bridge = input.bridgeId.trim();
143
+ frontmatter.bridge_sessions = input.sessionRefs.filter((value) => value.trim().length > 0);
144
+ frontmatter.updated = formatDate();
145
+ fs.writeFileSync(task.path, (0, parser_1.renderTaskFile)(frontmatter, parsed.body), "utf-8");
146
+ (0, scanner_1.clearTaskScanCache)();
147
+ return { ok: true, path: task.path };
148
+ }
135
149
  updateStatus(name, toStatus) {
136
150
  const normalized = (0, transitions_1.normalizeTaskStatus)(toStatus);
137
151
  if (!normalized) {
@@ -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": [