@ouro.bot/cli 0.1.0-alpha.696 → 0.1.0-alpha.698
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 +18 -0
- package/dist/heart/agent-entry.js +32 -2
- package/dist/heart/autonomy-budget.js +434 -0
- package/dist/heart/core.js +11 -0
- package/dist/heart/daemon/cadence.js +110 -0
- package/dist/heart/daemon/cli-exec.js +20 -0
- package/dist/heart/daemon/cli-help.js +74 -0
- package/dist/heart/daemon/cli-parse.js +466 -0
- package/dist/heart/daemon/daemon-entry.js +104 -3
- package/dist/heart/daemon/daemon.js +24 -3
- package/dist/heart/daemon/doctor.js +151 -0
- package/dist/heart/daemon/stale-bundle-prune.js +23 -6
- package/dist/heart/habits/habit-parser.js +4 -1
- package/dist/heart/habits/habit-scheduler.js +46 -38
- package/dist/heart/habits/habit-session.js +2 -3
- package/dist/heart/provider-credentials.js +16 -0
- package/dist/heart/run-ledger.js +247 -0
- package/dist/heart/runtime-credentials.js +12 -3
- package/dist/mind/prompt-budget.js +380 -0
- package/dist/repertoire/tools-base.js +2 -0
- package/dist/repertoire/tools-rsvp.js +139 -0
- package/dist/rsvp/aisleplanner-client.js +354 -0
- package/dist/rsvp/cli.js +704 -0
- package/dist/rsvp/config.js +327 -0
- package/dist/rsvp/cutover.js +431 -0
- package/dist/rsvp/diagnostics.js +222 -0
- package/dist/rsvp/diff-renderer.js +161 -0
- package/dist/rsvp/habit-policy.js +85 -0
- package/dist/rsvp/habit-stage.js +93 -0
- package/dist/rsvp/incident-bundle.js +97 -0
- package/dist/rsvp/migration.js +204 -0
- package/dist/rsvp/outbound-state.js +254 -0
- package/dist/rsvp/query.js +118 -0
- package/dist/rsvp/replay.js +233 -0
- package/dist/rsvp/snapshot.js +232 -0
- package/dist/senses/bluebubbles/client.js +13 -7
- package/dist/senses/bluebubbles/index.js +227 -22
- package/dist/senses/bluebubbles/outbound-state.js +304 -0
- package/dist/senses/bluebubbles/replay.js +147 -0
- package/dist/senses/context-packet-ledger.js +245 -0
- package/dist/senses/context-packets.js +154 -0
- package/dist/senses/pipeline.js +91 -1
- package/dist/senses/private-runtime-worker.js +170 -31
- package/dist/senses/private-runtime.js +13 -1
- package/dist/senses/voice/twilio-phone.js +9 -5
- package/package.json +1 -1
|
@@ -0,0 +1,327 @@
|
|
|
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.RSVP_CONFIG_POLICY_VERSION = void 0;
|
|
37
|
+
exports.rsvpConfigPath = rsvpConfigPath;
|
|
38
|
+
exports.readRsvpConfig = readRsvpConfig;
|
|
39
|
+
exports.writeRsvpConfig = writeRsvpConfig;
|
|
40
|
+
exports.validateRsvpReadiness = validateRsvpReadiness;
|
|
41
|
+
exports.importLegacyRsvpConfig = importLegacyRsvpConfig;
|
|
42
|
+
const fs = __importStar(require("node:fs"));
|
|
43
|
+
const path = __importStar(require("node:path"));
|
|
44
|
+
const runtime_1 = require("../nerves/runtime");
|
|
45
|
+
const runtime_credentials_1 = require("../heart/runtime-credentials");
|
|
46
|
+
exports.RSVP_CONFIG_POLICY_VERSION = "rsvp-config/v1";
|
|
47
|
+
function rsvpConfigPath(agentRoot) {
|
|
48
|
+
return path.join(agentRoot, "rsvp", "config.json");
|
|
49
|
+
}
|
|
50
|
+
function isRecord(value) {
|
|
51
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
52
|
+
}
|
|
53
|
+
function text(value) {
|
|
54
|
+
return typeof value === "string" ? value.trim() : "";
|
|
55
|
+
}
|
|
56
|
+
function idText(value) {
|
|
57
|
+
if (typeof value === "string" || typeof value === "number")
|
|
58
|
+
return String(value).trim();
|
|
59
|
+
return "";
|
|
60
|
+
}
|
|
61
|
+
function optionalText(value) {
|
|
62
|
+
const normalized = text(value);
|
|
63
|
+
return normalized || undefined;
|
|
64
|
+
}
|
|
65
|
+
function parseRsvpConfig(value) {
|
|
66
|
+
if (!isRecord(value))
|
|
67
|
+
return null;
|
|
68
|
+
if (value.schemaVersion !== 1)
|
|
69
|
+
return null;
|
|
70
|
+
if (value.policyVersion !== exports.RSVP_CONFIG_POLICY_VERSION)
|
|
71
|
+
return null;
|
|
72
|
+
if (typeof value.agent !== "string")
|
|
73
|
+
return null;
|
|
74
|
+
if (value.mode !== "shadow" && value.mode !== "live")
|
|
75
|
+
return null;
|
|
76
|
+
const source = isRecord(value.source) ? value.source : null;
|
|
77
|
+
if (!source || source.kind !== "aisleplanner")
|
|
78
|
+
return null;
|
|
79
|
+
if (typeof source.weddingId !== "string" || typeof source.eventId !== "string")
|
|
80
|
+
return null;
|
|
81
|
+
const credentialRef = isRecord(value.credentialRef) ? value.credentialRef : null;
|
|
82
|
+
if (!credentialRef
|
|
83
|
+
|| credentialRef.runtimeConfigItem !== "runtime/config"
|
|
84
|
+
|| credentialRef.runtimeConfigPath !== "rsvp.aisleplanner")
|
|
85
|
+
return null;
|
|
86
|
+
const route = isRecord(value.bluebubblesRoute) ? value.bluebubblesRoute : null;
|
|
87
|
+
if (!route || typeof route.chatGuid !== "string")
|
|
88
|
+
return null;
|
|
89
|
+
if (route.chatIdentifier !== undefined && typeof route.chatIdentifier !== "string")
|
|
90
|
+
return null;
|
|
91
|
+
if (route.accountId !== undefined && typeof route.accountId !== "string")
|
|
92
|
+
return null;
|
|
93
|
+
const cutover = value.cutover === undefined ? undefined : isRecord(value.cutover) ? value.cutover : null;
|
|
94
|
+
if (cutover === null)
|
|
95
|
+
return null;
|
|
96
|
+
if (cutover && typeof cutover.legacyRoot !== "string")
|
|
97
|
+
return null;
|
|
98
|
+
return value;
|
|
99
|
+
}
|
|
100
|
+
function readRsvpConfig(agentRoot) {
|
|
101
|
+
const configPath = rsvpConfigPath(agentRoot);
|
|
102
|
+
if (!fs.existsSync(configPath)) {
|
|
103
|
+
return { ok: false, reason: "missing", path: configPath, message: "missing native RSVP config" };
|
|
104
|
+
}
|
|
105
|
+
try {
|
|
106
|
+
const parsed = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
107
|
+
const config = parseRsvpConfig(parsed);
|
|
108
|
+
if (!config) {
|
|
109
|
+
return { ok: false, reason: "malformed", path: configPath, message: "native RSVP config is malformed" };
|
|
110
|
+
}
|
|
111
|
+
return { ok: true, config, path: configPath };
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return { ok: false, reason: "malformed", path: configPath, message: "native RSVP config is not valid JSON" };
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
function writeRsvpConfig(agentRoot, config) {
|
|
118
|
+
const configPath = rsvpConfigPath(agentRoot);
|
|
119
|
+
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
|
120
|
+
fs.writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\n`, "utf-8");
|
|
121
|
+
(0, runtime_1.emitNervesEvent)({
|
|
122
|
+
component: "rsvp",
|
|
123
|
+
event: "rsvp.config_written",
|
|
124
|
+
message: "wrote native RSVP config",
|
|
125
|
+
meta: { agent: config.agent, mode: config.mode, configPath },
|
|
126
|
+
});
|
|
127
|
+
return configPath;
|
|
128
|
+
}
|
|
129
|
+
function check(id, status, actor, detail) {
|
|
130
|
+
return { id, status, actor, detail };
|
|
131
|
+
}
|
|
132
|
+
function runtimeRsvpConfig(runtimeConfig) {
|
|
133
|
+
if (!runtimeConfig.ok)
|
|
134
|
+
return null;
|
|
135
|
+
const rsvp = isRecord(runtimeConfig.config.rsvp) ? runtimeConfig.config.rsvp : null;
|
|
136
|
+
return isRecord(rsvp?.aisleplanner) ? rsvp.aisleplanner : null;
|
|
137
|
+
}
|
|
138
|
+
function resolveCredentials(runtimeConfig) {
|
|
139
|
+
const aisleplanner = runtimeRsvpConfig(runtimeConfig);
|
|
140
|
+
const username = text(aisleplanner?.username);
|
|
141
|
+
const password = text(aisleplanner?.password);
|
|
142
|
+
return username && password ? { username, password } : null;
|
|
143
|
+
}
|
|
144
|
+
function bluebubblesAttachmentReady(machineRuntimeConfig) {
|
|
145
|
+
if (!machineRuntimeConfig?.ok)
|
|
146
|
+
return false;
|
|
147
|
+
const bluebubbles = isRecord(machineRuntimeConfig.config.bluebubbles) ? machineRuntimeConfig.config.bluebubbles : null;
|
|
148
|
+
return !!text(bluebubbles?.serverUrl) && !!text(bluebubbles?.password);
|
|
149
|
+
}
|
|
150
|
+
function redacted(config, runtimeConfig, machineRuntimeConfig) {
|
|
151
|
+
return {
|
|
152
|
+
config,
|
|
153
|
+
credentials: {
|
|
154
|
+
itemPath: runtimeConfig.itemPath,
|
|
155
|
+
aisleplanner: resolveCredentials(runtimeConfig) ? "present" : "missing",
|
|
156
|
+
},
|
|
157
|
+
bluebubblesAttachment: {
|
|
158
|
+
itemPath: machineRuntimeConfig?.itemPath ?? "missing",
|
|
159
|
+
status: bluebubblesAttachmentReady(machineRuntimeConfig) ? "present" : "missing",
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function validateRsvpReadiness(input) {
|
|
164
|
+
const configResult = input.config ?? readRsvpConfig(input.agentRoot);
|
|
165
|
+
const checks = [];
|
|
166
|
+
let config;
|
|
167
|
+
if (!configResult.ok) {
|
|
168
|
+
checks.push(check("rsvp.native_config", "fail", "agent-runnable", `${configResult.message}: ${configResult.path}`));
|
|
169
|
+
return {
|
|
170
|
+
status: "blocked",
|
|
171
|
+
checks,
|
|
172
|
+
redacted: redacted(undefined, input.runtimeConfig, input.machineRuntimeConfig),
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
config = configResult.config;
|
|
176
|
+
checks.push(check("rsvp.native_config", "pass", "agent-runnable", configResult.path));
|
|
177
|
+
const missingSource = [];
|
|
178
|
+
if (!text(config.source.weddingId))
|
|
179
|
+
missingSource.push("weddingId");
|
|
180
|
+
if (!text(config.source.eventId))
|
|
181
|
+
missingSource.push("eventId");
|
|
182
|
+
checks.push(missingSource.length === 0
|
|
183
|
+
? check("rsvp.aisleplanner_source", "pass", "agent-runnable", `${config.source.weddingId}/${config.source.eventId}`)
|
|
184
|
+
: check("rsvp.aisleplanner_source", "fail", "agent-runnable", `missing ${missingSource.join("/")}`));
|
|
185
|
+
const credentials = resolveCredentials(input.runtimeConfig);
|
|
186
|
+
if (credentials) {
|
|
187
|
+
checks.push(check("rsvp.aisleplanner_credentials", "pass", "human-required", `${input.runtimeConfig.itemPath}: present`));
|
|
188
|
+
}
|
|
189
|
+
else if (input.runtimeConfig.ok) {
|
|
190
|
+
checks.push(check("rsvp.aisleplanner_credentials", "fail", "human-required", `${input.runtimeConfig.itemPath}: missing rsvp.aisleplanner username/password`));
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
checks.push(check("rsvp.aisleplanner_credentials", "fail", "human-required", `${input.runtimeConfig.itemPath}: ${input.runtimeConfig.error}`));
|
|
194
|
+
}
|
|
195
|
+
const chatGuid = text(config.bluebubblesRoute.chatGuid);
|
|
196
|
+
checks.push(chatGuid
|
|
197
|
+
? check("rsvp.bluebubbles_route", "pass", "agent-runnable", chatGuid)
|
|
198
|
+
: check("rsvp.bluebubbles_route", "fail", "agent-runnable", "missing bluebubblesRoute.chatGuid"));
|
|
199
|
+
if (bluebubblesAttachmentReady(input.machineRuntimeConfig)) {
|
|
200
|
+
checks.push(check("rsvp.bluebubbles_attachment", "pass", "agent-runnable", `${input.machineRuntimeConfig.itemPath}: present`));
|
|
201
|
+
}
|
|
202
|
+
else if (input.machineRuntimeConfig?.ok) {
|
|
203
|
+
checks.push(check("rsvp.bluebubbles_attachment", "fail", "agent-runnable", `${input.machineRuntimeConfig.itemPath}: missing bluebubbles.serverUrl/password`));
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
checks.push(check("rsvp.bluebubbles_attachment", "fail", "agent-runnable", `${input.machineRuntimeConfig?.itemPath ?? "machine runtime/config"}: ${input.machineRuntimeConfig?.error ?? "missing"}`));
|
|
207
|
+
}
|
|
208
|
+
const status = checks.every((entry) => entry.status === "pass") ? "ready" : "blocked";
|
|
209
|
+
const base = {
|
|
210
|
+
status,
|
|
211
|
+
checks,
|
|
212
|
+
config,
|
|
213
|
+
redacted: redacted(config, input.runtimeConfig, input.machineRuntimeConfig),
|
|
214
|
+
};
|
|
215
|
+
return status === "ready" && credentials
|
|
216
|
+
? { ...base, status: "ready", credentials }
|
|
217
|
+
: { ...base, status: "blocked" };
|
|
218
|
+
}
|
|
219
|
+
function fail(reason, actor, message) {
|
|
220
|
+
return { ok: false, reason, actor, message };
|
|
221
|
+
}
|
|
222
|
+
function redactKnownSecrets(message, secrets) {
|
|
223
|
+
let redactedMessage = message;
|
|
224
|
+
for (const secret of secrets.filter((value) => value.length > 0)) {
|
|
225
|
+
redactedMessage = redactedMessage.split(secret).join("[redacted]");
|
|
226
|
+
}
|
|
227
|
+
return redactedMessage;
|
|
228
|
+
}
|
|
229
|
+
function readLegacyConfig(legacyRoot) {
|
|
230
|
+
try {
|
|
231
|
+
const parsed = JSON.parse(fs.readFileSync(path.join(legacyRoot, "config.json"), "utf-8"));
|
|
232
|
+
return isRecord(parsed) ? parsed : null;
|
|
233
|
+
}
|
|
234
|
+
catch {
|
|
235
|
+
return null;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
function legacyConfigExists(legacyRoot) {
|
|
239
|
+
return fs.existsSync(path.join(legacyRoot, "config.json"));
|
|
240
|
+
}
|
|
241
|
+
async function importLegacyRsvpConfig(input) {
|
|
242
|
+
if (!input.confirm) {
|
|
243
|
+
return fail("confirmation_required", "human-required", "legacy RSVP config import requires explicit confirmation");
|
|
244
|
+
}
|
|
245
|
+
if (!legacyConfigExists(input.legacyRoot)) {
|
|
246
|
+
return fail("missing_legacy_config", "agent-runnable", "legacy RSVP config.json is missing");
|
|
247
|
+
}
|
|
248
|
+
const legacy = readLegacyConfig(input.legacyRoot);
|
|
249
|
+
if (!legacy)
|
|
250
|
+
return fail("malformed_legacy_config", "agent-runnable", "legacy RSVP config.json is malformed");
|
|
251
|
+
const aisleplanner = isRecord(legacy.aisleplanner) ? legacy.aisleplanner : null;
|
|
252
|
+
const bluebubbles = isRecord(legacy.bluebubbles) ? legacy.bluebubbles : null;
|
|
253
|
+
const username = text(aisleplanner?.username);
|
|
254
|
+
const password = text(aisleplanner?.password);
|
|
255
|
+
if (!username || !password) {
|
|
256
|
+
return fail("missing_secret", "human-required", "legacy RSVP config is missing AislePlanner username/password");
|
|
257
|
+
}
|
|
258
|
+
const weddingId = idText(aisleplanner?.wedding_id);
|
|
259
|
+
const eventId = idText(aisleplanner?.event_id);
|
|
260
|
+
const chatGuid = text(bluebubbles?.chat_guid);
|
|
261
|
+
if (!weddingId || !eventId || !chatGuid) {
|
|
262
|
+
return fail("missing_coordinates", "agent-runnable", "legacy RSVP config is missing wedding_id/event_id/bluebubbles.chat_guid");
|
|
263
|
+
}
|
|
264
|
+
const now = input.now ?? new Date();
|
|
265
|
+
const merge = input.mergeRuntimeConfig ?? runtime_credentials_1.mergeRuntimeCredentialConfig;
|
|
266
|
+
let runtimeConfig;
|
|
267
|
+
try {
|
|
268
|
+
runtimeConfig = await merge(input.agent, {
|
|
269
|
+
rsvp: {
|
|
270
|
+
aisleplanner: {
|
|
271
|
+
username,
|
|
272
|
+
password,
|
|
273
|
+
},
|
|
274
|
+
},
|
|
275
|
+
}, now);
|
|
276
|
+
}
|
|
277
|
+
catch (error) {
|
|
278
|
+
const message = redactKnownSecrets(String(error), [username, password]);
|
|
279
|
+
return fail("vault_unavailable", "human-required", `could not write AislePlanner credentials to runtime/config: ${message}`);
|
|
280
|
+
}
|
|
281
|
+
const nativeConfig = {
|
|
282
|
+
schemaVersion: 1,
|
|
283
|
+
policyVersion: exports.RSVP_CONFIG_POLICY_VERSION,
|
|
284
|
+
agent: input.agent,
|
|
285
|
+
mode: input.mode,
|
|
286
|
+
source: {
|
|
287
|
+
kind: "aisleplanner",
|
|
288
|
+
weddingId,
|
|
289
|
+
eventId,
|
|
290
|
+
},
|
|
291
|
+
credentialRef: {
|
|
292
|
+
runtimeConfigItem: "runtime/config",
|
|
293
|
+
runtimeConfigPath: "rsvp.aisleplanner",
|
|
294
|
+
},
|
|
295
|
+
bluebubblesRoute: {
|
|
296
|
+
chatGuid,
|
|
297
|
+
...(optionalText(bluebubbles?.account_id) ? { accountId: optionalText(bluebubbles?.account_id) } : {}),
|
|
298
|
+
},
|
|
299
|
+
cutover: {
|
|
300
|
+
legacyRoot: input.legacyRoot,
|
|
301
|
+
},
|
|
302
|
+
};
|
|
303
|
+
let configPath;
|
|
304
|
+
try {
|
|
305
|
+
configPath = writeRsvpConfig(input.agentRoot, nativeConfig);
|
|
306
|
+
}
|
|
307
|
+
catch (error) {
|
|
308
|
+
const message = String(error);
|
|
309
|
+
return fail("write_failed", "agent-runnable", `could not write native RSVP config: ${message}`);
|
|
310
|
+
}
|
|
311
|
+
(0, runtime_1.emitNervesEvent)({
|
|
312
|
+
component: "rsvp",
|
|
313
|
+
event: "rsvp.legacy_config_imported",
|
|
314
|
+
message: "imported legacy RSVP config into native config and runtime credentials",
|
|
315
|
+
meta: { agent: input.agent, mode: input.mode, configPath, runtimeConfigItem: runtimeConfig.itemPath },
|
|
316
|
+
});
|
|
317
|
+
return {
|
|
318
|
+
ok: true,
|
|
319
|
+
configPath,
|
|
320
|
+
runtimeConfigItem: runtimeConfig.itemPath,
|
|
321
|
+
redactedConfig: {
|
|
322
|
+
source: nativeConfig.source,
|
|
323
|
+
bluebubblesRoute: nativeConfig.bluebubblesRoute,
|
|
324
|
+
mode: nativeConfig.mode,
|
|
325
|
+
},
|
|
326
|
+
};
|
|
327
|
+
}
|