@ouro.bot/cli 0.0.1-alpha.0 → 0.1.0-alpha.1

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 (114) hide show
  1. package/AdoptionSpecialist.ouro/agent.json +20 -0
  2. package/AdoptionSpecialist.ouro/psyche/SOUL.md +22 -0
  3. package/AdoptionSpecialist.ouro/psyche/identities/basilisk.md +31 -0
  4. package/AdoptionSpecialist.ouro/psyche/identities/jafar.md +31 -0
  5. package/AdoptionSpecialist.ouro/psyche/identities/jormungandr.md +31 -0
  6. package/AdoptionSpecialist.ouro/psyche/identities/kaa.md +31 -0
  7. package/AdoptionSpecialist.ouro/psyche/identities/medusa.md +31 -0
  8. package/AdoptionSpecialist.ouro/psyche/identities/monty.md +31 -0
  9. package/AdoptionSpecialist.ouro/psyche/identities/nagini.md +31 -0
  10. package/AdoptionSpecialist.ouro/psyche/identities/ouroboros.md +31 -0
  11. package/AdoptionSpecialist.ouro/psyche/identities/python.md +31 -0
  12. package/AdoptionSpecialist.ouro/psyche/identities/quetzalcoatl.md +31 -0
  13. package/AdoptionSpecialist.ouro/psyche/identities/sir-hiss.md +31 -0
  14. package/AdoptionSpecialist.ouro/psyche/identities/the-serpent.md +31 -0
  15. package/AdoptionSpecialist.ouro/psyche/identities/the-snake.md +31 -0
  16. package/README.md +224 -6
  17. package/dist/heart/agent-entry.js +17 -0
  18. package/dist/heart/api-error.js +34 -0
  19. package/dist/heart/config.js +296 -0
  20. package/dist/heart/core.js +485 -0
  21. package/dist/heart/daemon/daemon-cli.js +626 -0
  22. package/dist/heart/daemon/daemon-entry.js +74 -0
  23. package/dist/heart/daemon/daemon.js +310 -0
  24. package/dist/heart/daemon/hatch-flow.js +284 -0
  25. package/dist/heart/daemon/hatch-specialist.js +107 -0
  26. package/dist/heart/daemon/health-monitor.js +79 -0
  27. package/dist/heart/daemon/message-router.js +98 -0
  28. package/dist/heart/daemon/ouro-bot-entry.js +23 -0
  29. package/dist/heart/daemon/ouro-bot-wrapper.js +90 -0
  30. package/dist/heart/daemon/ouro-entry.js +23 -0
  31. package/dist/heart/daemon/ouro-uti.js +212 -0
  32. package/dist/heart/daemon/process-manager.js +220 -0
  33. package/dist/heart/daemon/runtime-logging.js +98 -0
  34. package/dist/heart/daemon/subagent-installer.js +125 -0
  35. package/dist/heart/daemon/task-scheduler.js +237 -0
  36. package/dist/heart/harness.js +26 -0
  37. package/dist/heart/identity.js +270 -0
  38. package/dist/heart/kicks.js +144 -0
  39. package/dist/heart/primitives.js +4 -0
  40. package/dist/heart/providers/anthropic.js +329 -0
  41. package/dist/heart/providers/azure.js +66 -0
  42. package/dist/heart/providers/minimax.js +53 -0
  43. package/dist/heart/providers/openai-codex.js +162 -0
  44. package/dist/heart/streaming.js +412 -0
  45. package/dist/heart/turn-coordinator.js +62 -0
  46. package/dist/inner-worker-entry.js +4 -0
  47. package/dist/mind/associative-recall.js +176 -0
  48. package/dist/mind/bundle-manifest.js +118 -0
  49. package/dist/mind/context.js +218 -0
  50. package/dist/mind/first-impressions.js +43 -0
  51. package/dist/mind/format.js +56 -0
  52. package/dist/mind/friends/channel.js +41 -0
  53. package/dist/mind/friends/resolver.js +84 -0
  54. package/dist/mind/friends/store-file.js +171 -0
  55. package/dist/mind/friends/store.js +4 -0
  56. package/dist/mind/friends/tokens.js +26 -0
  57. package/dist/mind/friends/types.js +21 -0
  58. package/dist/mind/memory.js +326 -0
  59. package/dist/mind/phrases.js +43 -0
  60. package/dist/mind/prompt.js +254 -0
  61. package/dist/mind/token-estimate.js +119 -0
  62. package/dist/nerves/cli-logging.js +31 -0
  63. package/dist/nerves/coverage/audit-rules.js +81 -0
  64. package/dist/nerves/coverage/audit.js +200 -0
  65. package/dist/nerves/coverage/cli-main.js +5 -0
  66. package/dist/nerves/coverage/cli.js +51 -0
  67. package/dist/nerves/coverage/contract.js +23 -0
  68. package/dist/nerves/coverage/file-completeness.js +46 -0
  69. package/dist/nerves/coverage/run-artifacts.js +77 -0
  70. package/dist/nerves/coverage/source-scanner.js +34 -0
  71. package/dist/nerves/index.js +152 -0
  72. package/dist/nerves/runtime.js +38 -0
  73. package/dist/repertoire/ado-client.js +211 -0
  74. package/dist/repertoire/ado-context.js +73 -0
  75. package/dist/repertoire/ado-semantic.js +841 -0
  76. package/dist/repertoire/ado-templates.js +146 -0
  77. package/dist/repertoire/coding/index.js +36 -0
  78. package/dist/repertoire/coding/manager.js +489 -0
  79. package/dist/repertoire/coding/monitor.js +60 -0
  80. package/dist/repertoire/coding/reporter.js +45 -0
  81. package/dist/repertoire/coding/spawner.js +102 -0
  82. package/dist/repertoire/coding/tools.js +167 -0
  83. package/dist/repertoire/coding/types.js +2 -0
  84. package/dist/repertoire/data/ado-endpoints.json +122 -0
  85. package/dist/repertoire/data/graph-endpoints.json +212 -0
  86. package/dist/repertoire/github-client.js +64 -0
  87. package/dist/repertoire/graph-client.js +118 -0
  88. package/dist/repertoire/skills.js +156 -0
  89. package/dist/repertoire/tasks/board.js +122 -0
  90. package/dist/repertoire/tasks/index.js +210 -0
  91. package/dist/repertoire/tasks/lifecycle.js +80 -0
  92. package/dist/repertoire/tasks/middleware.js +65 -0
  93. package/dist/repertoire/tasks/parser.js +173 -0
  94. package/dist/repertoire/tasks/scanner.js +132 -0
  95. package/dist/repertoire/tasks/transitions.js +145 -0
  96. package/dist/repertoire/tasks/types.js +2 -0
  97. package/dist/repertoire/tools-base.js +622 -0
  98. package/dist/repertoire/tools-github.js +53 -0
  99. package/dist/repertoire/tools-teams.js +308 -0
  100. package/dist/repertoire/tools.js +199 -0
  101. package/dist/senses/cli-entry.js +15 -0
  102. package/dist/senses/cli.js +523 -0
  103. package/dist/senses/commands.js +98 -0
  104. package/dist/senses/inner-dialog-worker.js +61 -0
  105. package/dist/senses/inner-dialog.js +216 -0
  106. package/dist/senses/teams-entry.js +15 -0
  107. package/dist/senses/teams.js +695 -0
  108. package/dist/senses/trust-gate.js +150 -0
  109. package/package.json +34 -11
  110. package/subagents/README.md +71 -0
  111. package/subagents/work-doer.md +233 -0
  112. package/subagents/work-merger.md +593 -0
  113. package/subagents/work-planner.md +373 -0
  114. package/bin/ouro.js +0 -6
@@ -0,0 +1,107 @@
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.getSpecialistIdentitySourceDir = getSpecialistIdentitySourceDir;
37
+ exports.getRepoSpecialistIdentitiesDir = getRepoSpecialistIdentitiesDir;
38
+ exports.syncSpecialistIdentities = syncSpecialistIdentities;
39
+ exports.pickRandomSpecialistIdentity = pickRandomSpecialistIdentity;
40
+ const fs = __importStar(require("fs"));
41
+ const os = __importStar(require("os"));
42
+ const path = __importStar(require("path"));
43
+ const runtime_1 = require("../../nerves/runtime");
44
+ function getSpecialistIdentitySourceDir() {
45
+ return path.join(os.homedir(), "AgentBundles", "AdoptionSpecialist.ouro", "psyche", "identities");
46
+ }
47
+ function getRepoSpecialistIdentitiesDir() {
48
+ return path.join(process.cwd(), "AdoptionSpecialist.ouro", "psyche", "identities");
49
+ }
50
+ function listMarkdownIdentityFiles(dir) {
51
+ let entries;
52
+ try {
53
+ entries = fs.readdirSync(dir);
54
+ }
55
+ catch {
56
+ return [];
57
+ }
58
+ return entries
59
+ .filter((entry) => entry.endsWith(".md"))
60
+ .sort((left, right) => left.localeCompare(right));
61
+ }
62
+ function syncSpecialistIdentities(input) {
63
+ (0, runtime_1.emitNervesEvent)({
64
+ component: "daemon",
65
+ event: "daemon.hatch_identity_sync_start",
66
+ message: "syncing specialist identity files",
67
+ meta: { sourceDir: input.sourceDir, targetDir: input.targetDir },
68
+ });
69
+ const files = listMarkdownIdentityFiles(input.sourceDir);
70
+ fs.mkdirSync(input.targetDir, { recursive: true });
71
+ for (const fileName of files) {
72
+ const sourcePath = path.join(input.sourceDir, fileName);
73
+ const targetPath = path.join(input.targetDir, fileName);
74
+ fs.copyFileSync(sourcePath, targetPath);
75
+ }
76
+ (0, runtime_1.emitNervesEvent)({
77
+ component: "daemon",
78
+ event: "daemon.hatch_identity_sync_end",
79
+ message: "synced specialist identity files",
80
+ meta: { copiedCount: files.length },
81
+ });
82
+ return files;
83
+ }
84
+ function pickRandomSpecialistIdentity(input) {
85
+ const files = listMarkdownIdentityFiles(input.identitiesDir);
86
+ if (files.length === 0) {
87
+ (0, runtime_1.emitNervesEvent)({
88
+ level: "error",
89
+ component: "daemon",
90
+ event: "daemon.hatch_identity_pick_error",
91
+ message: "no specialist identities were found",
92
+ meta: { identitiesDir: input.identitiesDir },
93
+ });
94
+ throw new Error(`No specialist identities found in ${input.identitiesDir}`);
95
+ }
96
+ const random = input.random ?? Math.random;
97
+ const index = Math.min(files.length - 1, Math.floor(random() * files.length));
98
+ const fileName = files[index];
99
+ const content = fs.readFileSync(path.join(input.identitiesDir, fileName), "utf-8");
100
+ (0, runtime_1.emitNervesEvent)({
101
+ component: "daemon",
102
+ event: "daemon.hatch_identity_pick",
103
+ message: "picked specialist identity",
104
+ meta: { fileName },
105
+ });
106
+ return { fileName, content };
107
+ }
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HealthMonitor = void 0;
4
+ const runtime_1 = require("../../nerves/runtime");
5
+ class HealthMonitor {
6
+ processManager;
7
+ scheduler;
8
+ alertSink;
9
+ diskUsagePercent;
10
+ constructor(options) {
11
+ this.processManager = options.processManager;
12
+ this.scheduler = options.scheduler;
13
+ this.alertSink = options.alertSink ?? (() => undefined);
14
+ this.diskUsagePercent = options.diskUsagePercent ?? (() => 0);
15
+ }
16
+ async runChecks() {
17
+ const results = [];
18
+ const snapshots = this.processManager.listAgentSnapshots();
19
+ const unhealthy = snapshots.filter((snapshot) => snapshot.status !== "running");
20
+ if (unhealthy.length > 0) {
21
+ results.push({
22
+ name: "agent-processes",
23
+ status: "critical",
24
+ message: `non-running agents: ${unhealthy.map((item) => item.name).join(", ")}`,
25
+ });
26
+ }
27
+ else {
28
+ results.push({ name: "agent-processes", status: "ok", message: "all managed agents running" });
29
+ }
30
+ const jobs = this.scheduler.listJobs();
31
+ const neverRan = jobs.filter((job) => !job.lastRun);
32
+ if (neverRan.length > 0) {
33
+ results.push({
34
+ name: "cron-health",
35
+ status: "warn",
36
+ message: `jobs never run: ${neverRan.map((job) => job.id).join(", ")}`,
37
+ });
38
+ }
39
+ else {
40
+ results.push({ name: "cron-health", status: "ok", message: "cron jobs are healthy" });
41
+ }
42
+ const diskPercent = this.diskUsagePercent();
43
+ if (diskPercent >= 90) {
44
+ results.push({
45
+ name: "disk-space",
46
+ status: "critical",
47
+ message: `disk usage critical (${diskPercent}%)`,
48
+ });
49
+ }
50
+ else if (diskPercent >= 80) {
51
+ results.push({
52
+ name: "disk-space",
53
+ status: "warn",
54
+ message: `disk usage high (${diskPercent}%)`,
55
+ });
56
+ }
57
+ else {
58
+ results.push({
59
+ name: "disk-space",
60
+ status: "ok",
61
+ message: `disk usage healthy (${diskPercent}%)`,
62
+ });
63
+ }
64
+ for (const result of results) {
65
+ (0, runtime_1.emitNervesEvent)({
66
+ level: result.status === "critical" ? "error" : result.status === "warn" ? "warn" : "info",
67
+ component: "daemon",
68
+ event: "daemon.health_result",
69
+ message: "daemon health check result",
70
+ meta: { name: result.name, status: result.status },
71
+ });
72
+ if (result.status === "critical") {
73
+ await this.alertSink(`[critical] ${result.name}: ${result.message}`);
74
+ }
75
+ }
76
+ return results;
77
+ }
78
+ }
79
+ exports.HealthMonitor = HealthMonitor;
@@ -0,0 +1,98 @@
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.FileMessageRouter = void 0;
37
+ const fs = __importStar(require("fs"));
38
+ const os = __importStar(require("os"));
39
+ const path = __importStar(require("path"));
40
+ const runtime_1 = require("../../nerves/runtime");
41
+ function messageId(nowIso) {
42
+ return `msg-${nowIso.replace(/[^0-9]/g, "")}`;
43
+ }
44
+ class FileMessageRouter {
45
+ baseDir;
46
+ now;
47
+ constructor(options = {}) {
48
+ this.baseDir = options.baseDir ?? path.join(os.homedir(), ".agentstate", "messages");
49
+ this.now = options.now ?? (() => new Date().toISOString());
50
+ fs.mkdirSync(this.baseDir, { recursive: true });
51
+ }
52
+ async send(input) {
53
+ const queuedAt = this.now();
54
+ const id = messageId(queuedAt);
55
+ const message = {
56
+ id,
57
+ from: input.from,
58
+ to: input.to,
59
+ content: input.content,
60
+ queuedAt,
61
+ priority: input.priority ?? "normal",
62
+ sessionId: input.sessionId,
63
+ taskRef: input.taskRef,
64
+ };
65
+ const inboxPath = this.inboxPath(input.to);
66
+ fs.appendFileSync(inboxPath, `${JSON.stringify(message)}\n`, "utf-8");
67
+ (0, runtime_1.emitNervesEvent)({
68
+ component: "daemon",
69
+ event: "daemon.message_queued",
70
+ message: "queued inter-agent message",
71
+ meta: { id, from: input.from, to: input.to },
72
+ });
73
+ return { id, queuedAt };
74
+ }
75
+ pollInbox(agent) {
76
+ const inboxPath = this.inboxPath(agent);
77
+ if (!fs.existsSync(inboxPath))
78
+ return [];
79
+ const raw = fs.readFileSync(inboxPath, "utf-8");
80
+ fs.writeFileSync(inboxPath, "", "utf-8");
81
+ const messages = raw
82
+ .split("\n")
83
+ .map((line) => line.trim())
84
+ .filter((line) => line.length > 0)
85
+ .map((line) => JSON.parse(line));
86
+ (0, runtime_1.emitNervesEvent)({
87
+ component: "daemon",
88
+ event: "daemon.message_polled",
89
+ message: "polled inter-agent inbox",
90
+ meta: { agent, messageCount: messages.length },
91
+ });
92
+ return messages;
93
+ }
94
+ inboxPath(agent) {
95
+ return path.join(this.baseDir, `${agent}-inbox.jsonl`);
96
+ }
97
+ }
98
+ exports.FileMessageRouter = FileMessageRouter;
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const runtime_1 = require("../../nerves/runtime");
5
+ const runtime_logging_1 = require("./runtime-logging");
6
+ const ouro_bot_wrapper_1 = require("./ouro-bot-wrapper");
7
+ (0, runtime_logging_1.configureDaemonRuntimeLogger)("ouro-bot");
8
+ (0, runtime_1.emitNervesEvent)({
9
+ component: "daemon",
10
+ event: "daemon.ouro_bot_entry_start",
11
+ message: "starting ouro.bot wrapper entrypoint",
12
+ meta: { args: process.argv.slice(2) },
13
+ });
14
+ void (0, ouro_bot_wrapper_1.runOuroBotWrapper)(process.argv.slice(2)).catch((error) => {
15
+ (0, runtime_1.emitNervesEvent)({
16
+ level: "error",
17
+ component: "daemon",
18
+ event: "daemon.ouro_bot_entry_error",
19
+ message: "ouro.bot wrapper entrypoint failed",
20
+ meta: { error: error instanceof Error ? error.message : String(error) },
21
+ });
22
+ process.exit(1);
23
+ });
@@ -0,0 +1,90 @@
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.runOuroBotWrapper = runOuroBotWrapper;
37
+ const runtime_1 = require("../../nerves/runtime");
38
+ const daemon_cli_1 = require("./daemon-cli");
39
+ async function defaultLoadCanonicalRunner() {
40
+ const packageName = "@ouro.bot/cli";
41
+ const specifier = packageName;
42
+ const loaded = await Promise.resolve(`${specifier}`).then(s => __importStar(require(s)));
43
+ const candidate = Object.prototype.hasOwnProperty.call(loaded, "runOuroCli")
44
+ ? loaded["runOuroCli"]
45
+ : undefined;
46
+ if (typeof candidate === "function") {
47
+ return candidate;
48
+ }
49
+ throw new Error("@ouro.bot/cli does not export runOuroCli");
50
+ }
51
+ function defaultWriteStdout(_text) {
52
+ // Wrapper is intentionally silent by default to avoid duplicate terminal output.
53
+ }
54
+ async function runOuroBotWrapper(args, deps = {}) {
55
+ (0, runtime_1.emitNervesEvent)({
56
+ component: "daemon",
57
+ event: "daemon.ouro_bot_wrapper_start",
58
+ message: "starting ouro.bot wrapper delegation",
59
+ meta: { args },
60
+ });
61
+ const loadCanonicalRunner = deps.loadCanonicalRunner ?? defaultLoadCanonicalRunner;
62
+ const fallbackRunCli = deps.fallbackRunCli ?? daemon_cli_1.runOuroCli;
63
+ const writeStdout = deps.writeStdout ?? defaultWriteStdout;
64
+ let delegatedTo = "@ouro.bot/cli";
65
+ let runner = fallbackRunCli;
66
+ try {
67
+ runner = await loadCanonicalRunner();
68
+ }
69
+ catch (error) {
70
+ delegatedTo = "local-fallback";
71
+ (0, runtime_1.emitNervesEvent)({
72
+ level: "warn",
73
+ component: "daemon",
74
+ event: "daemon.ouro_bot_wrapper_fallback",
75
+ message: "canonical ouro.bot package unavailable; falling back to local CLI",
76
+ meta: { error: error instanceof Error ? error.message : String(error) },
77
+ });
78
+ }
79
+ const result = await runner(args);
80
+ if (result.trim().length > 0) {
81
+ writeStdout(result);
82
+ }
83
+ (0, runtime_1.emitNervesEvent)({
84
+ component: "daemon",
85
+ event: "daemon.ouro_bot_wrapper_end",
86
+ message: "completed ouro.bot wrapper delegation",
87
+ meta: { delegatedTo },
88
+ });
89
+ return result;
90
+ }
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const runtime_1 = require("../../nerves/runtime");
5
+ const daemon_cli_1 = require("./daemon-cli");
6
+ const runtime_logging_1 = require("./runtime-logging");
7
+ (0, runtime_logging_1.configureDaemonRuntimeLogger)("ouro");
8
+ (0, runtime_1.emitNervesEvent)({
9
+ component: "daemon",
10
+ event: "daemon.cli_entry_start",
11
+ message: "starting ouro CLI entrypoint",
12
+ meta: { args: process.argv.slice(2) },
13
+ });
14
+ void (0, daemon_cli_1.runOuroCli)(process.argv.slice(2)).catch((error) => {
15
+ (0, runtime_1.emitNervesEvent)({
16
+ level: "error",
17
+ component: "daemon",
18
+ event: "daemon.cli_entry_error",
19
+ message: "ouro CLI entrypoint failed",
20
+ meta: { error: error instanceof Error ? error.message : String(error) },
21
+ });
22
+ process.exit(1);
23
+ });
@@ -0,0 +1,212 @@
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.registerOuroBundleUti = registerOuroBundleUti;
37
+ const child_process_1 = require("child_process");
38
+ const fs = __importStar(require("fs"));
39
+ const os = __importStar(require("os"));
40
+ const path = __importStar(require("path"));
41
+ const identity_1 = require("../identity");
42
+ const runtime_1 = require("../../nerves/runtime");
43
+ const LSREGISTER_PATH = "/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister";
44
+ const ICON_SIZES = [16, 32, 128, 256, 512];
45
+ function resolveIconSourcePath(repoRoot) {
46
+ return path.resolve(repoRoot, "..", "ouroboros-website", "public", "images", "ouroboros.png");
47
+ }
48
+ function buildIconAsset(iconSourcePath, icnsPath, iconsetDir, deps) {
49
+ try {
50
+ deps.mkdirSync(iconsetDir, { recursive: true });
51
+ for (const size of ICON_SIZES) {
52
+ const basePng = path.join(iconsetDir, `icon_${size}x${size}.png`);
53
+ const retinaPng = path.join(iconsetDir, `icon_${size}x${size}@2x.png`);
54
+ deps.execFileSync("sips", ["-z", String(size), String(size), iconSourcePath, "--out", basePng]);
55
+ deps.execFileSync("sips", ["-z", String(size * 2), String(size * 2), iconSourcePath, "--out", retinaPng]);
56
+ }
57
+ deps.execFileSync("iconutil", ["-c", "icns", iconsetDir, "-o", icnsPath]);
58
+ deps.rmSync(iconsetDir, { recursive: true, force: true });
59
+ return true;
60
+ }
61
+ catch (error) {
62
+ deps.rmSync(iconsetDir, { recursive: true, force: true });
63
+ (0, runtime_1.emitNervesEvent)({
64
+ level: "warn",
65
+ component: "daemon",
66
+ event: "daemon.ouro_uti_icon_error",
67
+ message: "failed building .ouro icon; continuing without custom icon",
68
+ meta: { error: error instanceof Error ? error.message : String(error) },
69
+ });
70
+ return false;
71
+ }
72
+ }
73
+ function buildInfoPlist(iconInstalled) {
74
+ const iconTag = iconInstalled ? "\n <key>CFBundleTypeIconFile</key>\n <string>ouro</string>" : "";
75
+ return [
76
+ '<?xml version="1.0" encoding="UTF-8"?>',
77
+ '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">',
78
+ '<plist version="1.0">',
79
+ "<dict>",
80
+ " <key>CFBundleIdentifier</key>",
81
+ " <string>bot.ouro.bundle-registry</string>",
82
+ " <key>CFBundleName</key>",
83
+ " <string>Ouro Bundle Registry</string>",
84
+ " <key>CFBundlePackageType</key>",
85
+ " <string>APPL</string>",
86
+ " <key>UTExportedTypeDeclarations</key>",
87
+ " <array>",
88
+ " <dict>",
89
+ " <key>UTTypeIdentifier</key>",
90
+ " <string>bot.ouro.bundle</string>",
91
+ " <key>UTTypeConformsTo</key>",
92
+ " <array>",
93
+ " <string>public.folder</string>",
94
+ " </array>",
95
+ " <key>UTTypeTagSpecification</key>",
96
+ " <dict>",
97
+ " <key>public.filename-extension</key>",
98
+ " <array>",
99
+ " <string>ouro</string>",
100
+ " </array>",
101
+ " </dict>",
102
+ " </dict>",
103
+ " </array>",
104
+ " <key>CFBundleDocumentTypes</key>",
105
+ " <array>",
106
+ " <dict>",
107
+ " <key>CFBundleTypeName</key>",
108
+ " <string>Ouro Agent Bundle</string>",
109
+ " <key>LSItemContentTypes</key>",
110
+ " <array>",
111
+ " <string>bot.ouro.bundle</string>",
112
+ " </array>",
113
+ " <key>CFBundleTypeRole</key>",
114
+ " <string>Editor</string>",
115
+ ` ${iconTag.trim()}`,
116
+ " </dict>",
117
+ " </array>",
118
+ "</dict>",
119
+ "</plist>",
120
+ "",
121
+ ]
122
+ .filter((line) => line.length > 0)
123
+ .join("\n");
124
+ }
125
+ function registerOuroBundleUti(deps = {}) {
126
+ const platform = deps.platform ?? process.platform;
127
+ if (platform !== "darwin") {
128
+ (0, runtime_1.emitNervesEvent)({
129
+ component: "daemon",
130
+ event: "daemon.ouro_uti_register_skip",
131
+ message: "skipped .ouro UTI registration on non-macOS platform",
132
+ meta: { platform },
133
+ });
134
+ return {
135
+ attempted: false,
136
+ registered: false,
137
+ iconInstalled: false,
138
+ skippedReason: "non-macos",
139
+ };
140
+ }
141
+ const homeDir = deps.homeDir ?? os.homedir();
142
+ const repoRoot = deps.repoRoot ?? (0, identity_1.getRepoRoot)();
143
+ const existsSync = deps.existsSync ?? fs.existsSync;
144
+ const mkdirSync = deps.mkdirSync ?? fs.mkdirSync;
145
+ const writeFileSync = deps.writeFileSync ?? fs.writeFileSync;
146
+ const rmSync = deps.rmSync ?? fs.rmSync;
147
+ const exec = deps.execFileSync ?? ((file, args) => (0, child_process_1.execFileSync)(file, args));
148
+ const supportRoot = path.join(homeDir, "Library", "Application Support", "ouro", "uti");
149
+ const appBundlePath = path.join(supportRoot, "OuroBundleRegistry.app");
150
+ const contentsDir = path.join(appBundlePath, "Contents");
151
+ const resourcesDir = path.join(contentsDir, "Resources");
152
+ const plistPath = path.join(contentsDir, "Info.plist");
153
+ const icnsPath = path.join(resourcesDir, "ouro.icns");
154
+ const iconsetDir = path.join(supportRoot, "ouro.iconset");
155
+ const iconSourcePath = resolveIconSourcePath(repoRoot);
156
+ (0, runtime_1.emitNervesEvent)({
157
+ component: "daemon",
158
+ event: "daemon.ouro_uti_register_start",
159
+ message: "registering .ouro UTI on macOS",
160
+ meta: { appBundlePath },
161
+ });
162
+ let iconInstalled = false;
163
+ try {
164
+ mkdirSync(resourcesDir, { recursive: true });
165
+ if (existsSync(iconSourcePath)) {
166
+ iconInstalled = buildIconAsset(iconSourcePath, icnsPath, iconsetDir, {
167
+ mkdirSync,
168
+ rmSync,
169
+ execFileSync: exec,
170
+ });
171
+ }
172
+ else {
173
+ (0, runtime_1.emitNervesEvent)({
174
+ component: "daemon",
175
+ event: "daemon.ouro_uti_icon_skip",
176
+ message: "icon source image missing; continuing without custom icon",
177
+ meta: { iconSourcePath },
178
+ });
179
+ }
180
+ writeFileSync(plistPath, buildInfoPlist(iconInstalled), "utf-8");
181
+ exec(LSREGISTER_PATH, ["-f", appBundlePath]);
182
+ (0, runtime_1.emitNervesEvent)({
183
+ component: "daemon",
184
+ event: "daemon.ouro_uti_register_end",
185
+ message: "registered .ouro UTI on macOS",
186
+ meta: { iconInstalled },
187
+ });
188
+ return {
189
+ attempted: true,
190
+ registered: true,
191
+ iconInstalled,
192
+ registrationBundlePath: appBundlePath,
193
+ };
194
+ }
195
+ catch (error) {
196
+ const reason = error instanceof Error ? error.message : String(error);
197
+ (0, runtime_1.emitNervesEvent)({
198
+ level: "warn",
199
+ component: "daemon",
200
+ event: "daemon.ouro_uti_register_error",
201
+ message: "failed .ouro UTI registration; continuing non-blocking",
202
+ meta: { reason },
203
+ });
204
+ return {
205
+ attempted: true,
206
+ registered: false,
207
+ iconInstalled,
208
+ skippedReason: reason,
209
+ registrationBundlePath: appBundlePath,
210
+ };
211
+ }
212
+ }