@ouro.bot/cli 0.1.0-alpha.242 → 0.1.0-alpha.243
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,12 @@
|
|
|
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.243",
|
|
6
|
+
"changes": [
|
|
7
|
+
"fix(daemon): per-agent Git Sync in `ouro status` \u2014 was always showing `disabled` regardless of any agent's `agent.json`, because the daemon process has no argv-derived agent identity so `getSyncConfig()` fell into its catch. Status payload now carries a per-agent `sync` array (one row per enabled bundle) rendered as its own section like Senses and Workers, instead of a single global field on the overview block."
|
|
8
|
+
]
|
|
9
|
+
},
|
|
4
10
|
{
|
|
5
11
|
"version": "0.1.0-alpha.241",
|
|
6
12
|
"changes": [
|
|
@@ -34,6 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.listEnabledBundleAgents = listEnabledBundleAgents;
|
|
37
|
+
exports.listBundleSyncRows = listBundleSyncRows;
|
|
37
38
|
const fs = __importStar(require("fs"));
|
|
38
39
|
const path = __importStar(require("path"));
|
|
39
40
|
const identity_1 = require("../identity");
|
|
@@ -79,3 +80,36 @@ function listEnabledBundleAgents(options = {}) {
|
|
|
79
80
|
}
|
|
80
81
|
return discovered.sort((left, right) => left.localeCompare(right));
|
|
81
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Read the per-agent sync block from each enabled bundle's agent.json.
|
|
85
|
+
* Used by the daemon (and stopped-state status renderer) to build per-agent
|
|
86
|
+
* sync rows without depending on argv-derived global identity. Bundles that
|
|
87
|
+
* cannot be read are skipped silently.
|
|
88
|
+
*/
|
|
89
|
+
function listBundleSyncRows(options = {}) {
|
|
90
|
+
const bundlesRoot = options.bundlesRoot ?? (0, identity_1.getAgentBundlesRoot)();
|
|
91
|
+
const readFileSync = options.readFileSync ?? fs.readFileSync;
|
|
92
|
+
const agents = listEnabledBundleAgents(options);
|
|
93
|
+
const rows = [];
|
|
94
|
+
for (const agent of agents) {
|
|
95
|
+
const configPath = path.join(bundlesRoot, `${agent}.ouro`, "agent.json");
|
|
96
|
+
let enabled = false;
|
|
97
|
+
let remote = "origin";
|
|
98
|
+
try {
|
|
99
|
+
const raw = readFileSync(configPath, "utf-8");
|
|
100
|
+
const parsed = JSON.parse(raw);
|
|
101
|
+
if (parsed.sync && typeof parsed.sync === "object") {
|
|
102
|
+
if (typeof parsed.sync.enabled === "boolean")
|
|
103
|
+
enabled = parsed.sync.enabled;
|
|
104
|
+
if (typeof parsed.sync.remote === "string" && parsed.sync.remote.length > 0) {
|
|
105
|
+
remote = parsed.sync.remote;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
// Best-effort: bundle without readable config still gets a row with defaults
|
|
111
|
+
}
|
|
112
|
+
rows.push({ agent, enabled, remote });
|
|
113
|
+
}
|
|
114
|
+
return rows;
|
|
115
|
+
}
|
|
@@ -54,6 +54,7 @@ const runtime_mode_1 = require("./runtime-mode");
|
|
|
54
54
|
const identity_1 = require("../identity");
|
|
55
55
|
const daemon_tombstone_1 = require("./daemon-tombstone");
|
|
56
56
|
const daemon_health_1 = require("./daemon-health");
|
|
57
|
+
const agent_discovery_1 = require("./agent-discovery");
|
|
57
58
|
// ── Field extractors ──
|
|
58
59
|
function stringField(value) {
|
|
59
60
|
return typeof value === "string" ? value : null;
|
|
@@ -72,10 +73,14 @@ function parseStatusPayload(data) {
|
|
|
72
73
|
const overview = raw.overview;
|
|
73
74
|
const senses = raw.senses;
|
|
74
75
|
const workers = raw.workers;
|
|
76
|
+
const sync = raw.sync;
|
|
75
77
|
if (!overview || typeof overview !== "object" || Array.isArray(overview))
|
|
76
78
|
return null;
|
|
77
79
|
if (!Array.isArray(senses) || !Array.isArray(workers))
|
|
78
80
|
return null;
|
|
81
|
+
// sync is optional for backward compatibility — older daemons may omit it
|
|
82
|
+
if (sync !== undefined && !Array.isArray(sync))
|
|
83
|
+
return null;
|
|
79
84
|
const parsedOverview = {
|
|
80
85
|
daemon: stringField(overview.daemon) ?? "unknown",
|
|
81
86
|
health: stringField(overview.health) ?? "unknown",
|
|
@@ -89,8 +94,6 @@ function parseStatusPayload(data) {
|
|
|
89
94
|
senseCount: numberField(overview.senseCount) ?? 0,
|
|
90
95
|
entryPath: stringField(overview.entryPath) ?? "unknown",
|
|
91
96
|
mode: stringField(overview.mode) ?? "unknown",
|
|
92
|
-
syncEnabled: booleanField(overview.syncEnabled) ?? false,
|
|
93
|
-
syncRemote: stringField(overview.syncRemote) ?? "origin",
|
|
94
97
|
};
|
|
95
98
|
const parsedSenses = senses.map((entry) => {
|
|
96
99
|
if (!entry || typeof entry !== "object" || Array.isArray(entry))
|
|
@@ -135,12 +138,26 @@ function parseStatusPayload(data) {
|
|
|
135
138
|
lastSignal: stringField(row.lastSignal) ?? null,
|
|
136
139
|
};
|
|
137
140
|
});
|
|
138
|
-
|
|
141
|
+
const parsedSync = (sync ?? []).map((entry) => {
|
|
142
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry))
|
|
143
|
+
return null;
|
|
144
|
+
const row = entry;
|
|
145
|
+
const agent = stringField(row.agent);
|
|
146
|
+
const enabled = booleanField(row.enabled);
|
|
147
|
+
const remote = stringField(row.remote);
|
|
148
|
+
if (!agent || enabled === null || !remote)
|
|
149
|
+
return null;
|
|
150
|
+
return { agent, enabled, remote };
|
|
151
|
+
});
|
|
152
|
+
if (parsedSenses.some((row) => row === null) ||
|
|
153
|
+
parsedWorkers.some((row) => row === null) ||
|
|
154
|
+
parsedSync.some((row) => row === null))
|
|
139
155
|
return null;
|
|
140
156
|
return {
|
|
141
157
|
overview: parsedOverview,
|
|
142
158
|
senses: parsedSenses,
|
|
143
159
|
workers: parsedWorkers,
|
|
160
|
+
sync: parsedSync,
|
|
144
161
|
};
|
|
145
162
|
}
|
|
146
163
|
// ── ANSI color helpers (private) ──
|
|
@@ -232,9 +249,6 @@ function formatDaemonStatusOutput(response, fallback) {
|
|
|
232
249
|
lines.push(kvLine("Socket", ov.socketPath));
|
|
233
250
|
lines.push(kvLine("Outlook", ov.outlookUrl));
|
|
234
251
|
lines.push(kvLine("Health", `${statusDot(ov.health)} ${ov.health}`));
|
|
235
|
-
/* v8 ignore next -- cosmetic: sync-enabled branch requires agent with sync configured @preserve */
|
|
236
|
-
const syncLabel = ov.syncEnabled ? `${green("●")} enabled (remote: ${ov.syncRemote})` : `${dim("○")} disabled`;
|
|
237
|
-
lines.push(kvLine("Git Sync", syncLabel));
|
|
238
252
|
lines.push(kvLine("Updated", ov.lastUpdated));
|
|
239
253
|
lines.push("");
|
|
240
254
|
// ── Senses ──
|
|
@@ -295,6 +309,19 @@ function formatDaemonStatusOutput(response, fallback) {
|
|
|
295
309
|
}
|
|
296
310
|
lines.push("");
|
|
297
311
|
}
|
|
312
|
+
// ── Git Sync (per agent) ──
|
|
313
|
+
if (payload.sync.length > 0) {
|
|
314
|
+
lines.push(` ${teal("──")} ${bold("Git Sync")} ${teal("─".repeat(35))}`);
|
|
315
|
+
const agentNameWidth = Math.max(12, ...payload.sync.map((r) => r.agent.length));
|
|
316
|
+
for (const row of payload.sync) {
|
|
317
|
+
const name = row.agent.padEnd(agentNameWidth);
|
|
318
|
+
const dot = row.enabled ? green("●") : dim("○");
|
|
319
|
+
const stateText = (row.enabled ? "enabled " : "disabled").padEnd(10);
|
|
320
|
+
const detail = row.enabled ? `remote: ${row.remote}` : "";
|
|
321
|
+
lines.push(` ${name} ${dot} ${stateText} ${dim(detail)}`);
|
|
322
|
+
}
|
|
323
|
+
lines.push("");
|
|
324
|
+
}
|
|
298
325
|
return lines.join("\n");
|
|
299
326
|
}
|
|
300
327
|
function formatVersionOutput() {
|
|
@@ -304,7 +331,7 @@ function formatVersionOutput() {
|
|
|
304
331
|
return mode === "dev" ? `${version} (dev)` : version;
|
|
305
332
|
/* v8 ignore stop */
|
|
306
333
|
}
|
|
307
|
-
function buildStoppedStatusPayload(socketPath) {
|
|
334
|
+
function buildStoppedStatusPayload(socketPath, syncRows = []) {
|
|
308
335
|
const metadata = (0, runtime_metadata_1.getRuntimeMetadata)();
|
|
309
336
|
const repoRoot = (0, identity_1.getRepoRoot)();
|
|
310
337
|
return {
|
|
@@ -321,14 +348,23 @@ function buildStoppedStatusPayload(socketPath) {
|
|
|
321
348
|
senseCount: 0,
|
|
322
349
|
entryPath: path.join(repoRoot, "dist", "heart", "daemon", "daemon-entry.js"),
|
|
323
350
|
mode: (0, runtime_mode_1.detectRuntimeMode)(repoRoot),
|
|
324
|
-
syncEnabled: false,
|
|
325
|
-
syncRemote: "origin",
|
|
326
351
|
},
|
|
327
352
|
senses: [],
|
|
328
353
|
workers: [],
|
|
354
|
+
sync: syncRows,
|
|
329
355
|
};
|
|
330
356
|
}
|
|
331
357
|
function daemonUnavailableStatusOutput(socketPath, healthFilePath) {
|
|
358
|
+
// Read per-agent sync config from disk so the user still sees it when the daemon is down.
|
|
359
|
+
// Best-effort: any fs error returns [] and the section is omitted.
|
|
360
|
+
let syncRows = [];
|
|
361
|
+
try {
|
|
362
|
+
syncRows = (0, agent_discovery_1.listBundleSyncRows)();
|
|
363
|
+
}
|
|
364
|
+
catch {
|
|
365
|
+
// listBundleSyncRows already swallows fs errors internally; this catch is a defensive
|
|
366
|
+
// safety net for environments where the fs module itself is partially mocked.
|
|
367
|
+
}
|
|
332
368
|
/* v8 ignore start — tombstone read tested in daemon-status-tombstone.test; branch misreported @preserve */
|
|
333
369
|
const tombstone = (0, daemon_tombstone_1.readDaemonTombstone)();
|
|
334
370
|
const deathLine = tombstone
|
|
@@ -339,7 +375,7 @@ function daemonUnavailableStatusOutput(socketPath, healthFilePath) {
|
|
|
339
375
|
formatDaemonStatusOutput({
|
|
340
376
|
ok: true,
|
|
341
377
|
summary: "daemon not running",
|
|
342
|
-
data: buildStoppedStatusPayload(socketPath),
|
|
378
|
+
data: buildStoppedStatusPayload(socketPath, syncRows),
|
|
343
379
|
}, "daemon not running"),
|
|
344
380
|
"",
|
|
345
381
|
];
|
|
@@ -42,7 +42,7 @@ const net = __importStar(require("net"));
|
|
|
42
42
|
const os = __importStar(require("os"));
|
|
43
43
|
const path = __importStar(require("path"));
|
|
44
44
|
const identity_1 = require("../identity");
|
|
45
|
-
const
|
|
45
|
+
const agent_discovery_1 = require("./agent-discovery");
|
|
46
46
|
const runtime_1 = require("../../nerves/runtime");
|
|
47
47
|
const runtime_metadata_1 = require("./runtime-metadata");
|
|
48
48
|
const runtime_mode_1 = require("./runtime-mode");
|
|
@@ -234,7 +234,7 @@ class OuroDaemon {
|
|
|
234
234
|
const workers = buildWorkerRows(snapshots);
|
|
235
235
|
const senses = this.senseManager?.listSenseRows() ?? [];
|
|
236
236
|
const repoRoot = (0, identity_1.getRepoRoot)();
|
|
237
|
-
const
|
|
237
|
+
const sync = (0, agent_discovery_1.listBundleSyncRows)({ bundlesRoot: this.bundlesRoot });
|
|
238
238
|
return {
|
|
239
239
|
overview: {
|
|
240
240
|
daemon: "running",
|
|
@@ -246,11 +246,10 @@ class OuroDaemon {
|
|
|
246
246
|
senseCount: senses.length,
|
|
247
247
|
entryPath: path.join(repoRoot, "dist", "heart", "daemon", "daemon-entry.js"),
|
|
248
248
|
mode: (0, runtime_mode_1.detectRuntimeMode)(repoRoot),
|
|
249
|
-
syncEnabled: syncConfig.enabled,
|
|
250
|
-
syncRemote: syncConfig.remote,
|
|
251
249
|
},
|
|
252
250
|
workers,
|
|
253
251
|
senses,
|
|
252
|
+
sync,
|
|
254
253
|
};
|
|
255
254
|
}
|
|
256
255
|
async start() {
|