@ouro.bot/cli 0.1.0-alpha.19 → 0.1.0-alpha.20

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.
@@ -54,6 +54,7 @@ const hatch_flow_1 = require("./hatch-flow");
54
54
  const specialist_orchestrator_1 = require("./specialist-orchestrator");
55
55
  const specialist_prompt_1 = require("./specialist-prompt");
56
56
  const specialist_tools_1 = require("./specialist-tools");
57
+ const runtime_metadata_1 = require("./runtime-metadata");
57
58
  function stringField(value) {
58
59
  return typeof value === "string" ? value : null;
59
60
  }
@@ -78,6 +79,8 @@ function parseStatusPayload(data) {
78
79
  daemon: stringField(overview.daemon) ?? "unknown",
79
80
  health: stringField(overview.health) ?? "unknown",
80
81
  socketPath: stringField(overview.socketPath) ?? "unknown",
82
+ version: stringField(overview.version) ?? "unknown",
83
+ lastUpdated: stringField(overview.lastUpdated) ?? "unknown",
81
84
  workerCount: numberField(overview.workerCount) ?? 0,
82
85
  senseCount: numberField(overview.senseCount) ?? 0,
83
86
  };
@@ -158,6 +161,8 @@ function formatDaemonStatusOutput(response, fallback) {
158
161
  const overviewRows = [
159
162
  ["Daemon", payload.overview.daemon],
160
163
  ["Socket", payload.overview.socketPath],
164
+ ["Version", payload.overview.version],
165
+ ["Last Updated", payload.overview.lastUpdated],
161
166
  ["Workers", String(payload.overview.workerCount)],
162
167
  ["Senses", String(payload.overview.senseCount)],
163
168
  ["Health", payload.overview.health],
@@ -207,12 +212,49 @@ function usage() {
207
212
  "Usage:",
208
213
  " ouro [up]",
209
214
  " ouro stop|status|logs|hatch",
215
+ " ouro -v|--version",
210
216
  " ouro chat <agent>",
211
217
  " ouro msg --to <agent> [--session <id>] [--task <ref>] <message>",
212
218
  " ouro poke <agent> --task <task-id>",
213
219
  " ouro link <agent> --friend <id> --provider <provider> --external-id <external-id>",
214
220
  ].join("\n");
215
221
  }
222
+ function formatVersionOutput() {
223
+ return (0, runtime_metadata_1.getRuntimeMetadata)().version;
224
+ }
225
+ function buildStoppedStatusPayload(socketPath) {
226
+ const metadata = (0, runtime_metadata_1.getRuntimeMetadata)();
227
+ return {
228
+ overview: {
229
+ daemon: "stopped",
230
+ health: "warn",
231
+ socketPath,
232
+ version: metadata.version,
233
+ lastUpdated: metadata.lastUpdated,
234
+ workerCount: 0,
235
+ senseCount: 0,
236
+ },
237
+ senses: [],
238
+ workers: [],
239
+ };
240
+ }
241
+ function daemonUnavailableStatusOutput(socketPath) {
242
+ return [
243
+ formatDaemonStatusOutput({
244
+ ok: true,
245
+ summary: "daemon not running",
246
+ data: buildStoppedStatusPayload(socketPath),
247
+ }, "daemon not running"),
248
+ "",
249
+ "daemon not running; run `ouro up`",
250
+ ].join("\n");
251
+ }
252
+ function isDaemonUnavailableError(error) {
253
+ const code = typeof error === "object" && error !== null && "code" in error
254
+ ? String(error.code ?? "")
255
+ : "";
256
+ return code === "ENOENT" || code === "ECONNREFUSED";
257
+ }
216
258
  function parseMessageCommand(args) {
217
259
  let to;
218
260
  let sessionId;
@@ -953,6 +995,11 @@ async function runOuroCli(args, deps = createDefaultOuroCliDeps()) {
953
995
  deps.writeStdout(text);
954
996
  return text;
955
997
  }
998
+ if (args.length === 1 && (args[0] === "-v" || args[0] === "--version")) {
999
+ const text = formatVersionOutput();
1000
+ deps.writeStdout(text);
1001
+ return text;
1002
+ }
956
1003
  let command;
957
1004
  try {
958
1005
  command = parseOuroCommand(args);
@@ -1085,6 +1132,16 @@ async function runOuroCli(args, deps = createDefaultOuroCliDeps()) {
1085
1132
  deps.writeStdout(message);
1086
1133
  return message;
1087
1134
  }
1135
+ if (command.kind === "daemon.status" && isDaemonUnavailableError(error)) {
1136
+ const message = daemonUnavailableStatusOutput(deps.socketPath);
1137
+ deps.writeStdout(message);
1138
+ return message;
1139
+ }
1140
+ if (command.kind === "daemon.stop" && isDaemonUnavailableError(error)) {
1141
+ const message = "daemon not running";
1142
+ deps.writeStdout(message);
1143
+ return message;
1144
+ }
1088
1145
  throw error;
1089
1146
  }
1090
1147
  const fallbackMessage = response.summary ?? response.message ?? (response.ok ? "ok" : `error: ${response.error ?? "unknown error"}`);
@@ -39,6 +39,7 @@ const net = __importStar(require("net"));
39
39
  const path = __importStar(require("path"));
40
40
  const identity_1 = require("../identity");
41
41
  const runtime_1 = require("../../nerves/runtime");
42
+ const runtime_metadata_1 = require("./runtime-metadata");
42
43
  function buildWorkerRows(snapshots) {
43
44
  return snapshots.map((snapshot) => ({
44
45
  agent: snapshot.name,
@@ -242,6 +243,7 @@ class OuroDaemon {
242
243
  daemon: "running",
243
244
  health: workers.every((worker) => worker.status === "running") ? "ok" : "warn",
244
245
  socketPath: this.socketPath,
246
+ ...(0, runtime_metadata_1.getRuntimeMetadata)(),
245
247
  workerCount: workers.length,
246
248
  senseCount: senses.length,
247
249
  },
@@ -0,0 +1,118 @@
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.getRuntimeMetadata = getRuntimeMetadata;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const childProcess = __importStar(require("child_process"));
40
+ const identity_1 = require("../identity");
41
+ const runtime_1 = require("../../nerves/runtime");
42
+ const UNKNOWN_METADATA = "unknown";
43
+ function optionalFunction(target, key) {
44
+ try {
45
+ const candidate = target[key];
46
+ return typeof candidate === "function" ? candidate : null;
47
+ }
48
+ catch {
49
+ return null;
50
+ }
51
+ }
52
+ function readVersion(packageJsonPath, readFileSyncImpl) {
53
+ try {
54
+ const parsed = JSON.parse(readFileSyncImpl(packageJsonPath, "utf-8"));
55
+ return typeof parsed.version === "string" && parsed.version.trim().length > 0
56
+ ? parsed.version.trim()
57
+ : UNKNOWN_METADATA;
58
+ }
59
+ catch {
60
+ return UNKNOWN_METADATA;
61
+ }
62
+ }
63
+ function readLastUpdated(repoRoot, packageJsonPath, statSyncImpl, execFileSyncImpl) {
64
+ try {
65
+ const raw = execFileSyncImpl("git", ["log", "-1", "--format=%cI"], {
66
+ cwd: repoRoot,
67
+ encoding: "utf-8",
68
+ stdio: ["ignore", "pipe", "ignore"],
69
+ }).trim();
70
+ if (raw.length > 0) {
71
+ return { value: raw, source: "git" };
72
+ }
73
+ }
74
+ catch {
75
+ // fall through to mtime fallback
76
+ }
77
+ try {
78
+ const stats = statSyncImpl(packageJsonPath);
79
+ return {
80
+ value: stats.mtime.toISOString(),
81
+ source: "package-json-mtime",
82
+ };
83
+ }
84
+ catch {
85
+ return { value: UNKNOWN_METADATA, source: "unknown" };
86
+ }
87
+ }
88
+ function getRuntimeMetadata(deps = {}) {
89
+ const repoRoot = deps.repoRoot ?? (0, identity_1.getRepoRoot)();
90
+ const readFileSyncImpl = deps.readFileSync ?? optionalFunction(fs, "readFileSync")?.bind(fs) ?? null;
91
+ const statSyncImpl = deps.statSync ?? optionalFunction(fs, "statSync")?.bind(fs) ?? null;
92
+ const execFileSyncImpl = deps.execFileSync
93
+ ?? optionalFunction(childProcess, "execFileSync")?.bind(childProcess)
94
+ ?? null;
95
+ const packageJsonPath = path.join(repoRoot, "package.json");
96
+ const version = readFileSyncImpl
97
+ ? readVersion(packageJsonPath, readFileSyncImpl)
98
+ : UNKNOWN_METADATA;
99
+ const lastUpdated = statSyncImpl
100
+ ? readLastUpdated(repoRoot, packageJsonPath, statSyncImpl, execFileSyncImpl ?? (() => {
101
+ throw new Error("git unavailable");
102
+ }))
103
+ : { value: UNKNOWN_METADATA, source: "unknown" };
104
+ (0, runtime_1.emitNervesEvent)({
105
+ component: "daemon",
106
+ event: "daemon.runtime_metadata_read",
107
+ message: "read runtime metadata",
108
+ meta: {
109
+ version,
110
+ lastUpdated: lastUpdated.value,
111
+ lastUpdatedSource: lastUpdated.source,
112
+ },
113
+ });
114
+ return {
115
+ version,
116
+ lastUpdated: lastUpdated.value,
117
+ };
118
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ouro.bot/cli",
3
- "version": "0.1.0-alpha.19",
3
+ "version": "0.1.0-alpha.20",
4
4
  "main": "dist/heart/daemon/ouro-entry.js",
5
5
  "bin": {
6
6
  "cli": "dist/heart/daemon/ouro-bot-entry.js",