youmd 0.8.5 → 0.8.7
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/dist/commands/agent.d.ts +13 -0
- package/dist/commands/agent.d.ts.map +1 -0
- package/dist/commands/agent.js +233 -0
- package/dist/commands/agent.js.map +1 -0
- package/dist/commands/env.d.ts +1 -0
- package/dist/commands/env.d.ts.map +1 -1
- package/dist/commands/env.js +373 -3
- package/dist/commands/env.js.map +1 -1
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +16 -0
- package/dist/commands/sync.js.map +1 -1
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/api.d.ts +99 -0
- package/dist/lib/api.d.ts.map +1 -1
- package/dist/lib/api.js +51 -0
- package/dist/lib/api.js.map +1 -1
- package/dist/lib/machine-bootstrap-prompt.d.ts.map +1 -1
- package/dist/lib/machine-bootstrap-prompt.js +108 -27
- package/dist/lib/machine-bootstrap-prompt.js.map +1 -1
- package/dist/lib/realtime-sync.d.ts +47 -1
- package/dist/lib/realtime-sync.d.ts.map +1 -1
- package/dist/lib/realtime-sync.js +93 -8
- package/dist/lib/realtime-sync.js.map +1 -1
- package/package.json +1 -1
- package/skills/machine-bootstrap.md +40 -13
|
@@ -55,6 +55,16 @@ function envAssignment(name, value, options = {}) {
|
|
|
55
55
|
if (stringValue.startsWith("~/")) {
|
|
56
56
|
return `${name}="$HOME${stringValue.slice(1).replace(/["\\$`]/g, (char) => `\\${char}`)}"`;
|
|
57
57
|
}
|
|
58
|
+
if (stringValue === "$HOME")
|
|
59
|
+
return `${name}="$HOME"`;
|
|
60
|
+
if (stringValue.startsWith("$HOME/")) {
|
|
61
|
+
return `${name}="$HOME/${stringValue.slice("$HOME/".length).replace(/["\\$`]/g, (char) => `\\${char}`)}"`;
|
|
62
|
+
}
|
|
63
|
+
if (stringValue === "${HOME}")
|
|
64
|
+
return `${name}="$HOME"`;
|
|
65
|
+
if (stringValue.startsWith("${HOME}/")) {
|
|
66
|
+
return `${name}="$HOME/${stringValue.slice("${HOME}/".length).replace(/["\\$`]/g, (char) => `\\${char}`)}"`;
|
|
67
|
+
}
|
|
58
68
|
}
|
|
59
69
|
return `${name}=${shellQuote(stringValue)}`;
|
|
60
70
|
}
|
|
@@ -79,10 +89,47 @@ DAYS="\${YOUMD_ACTIVE_DAYS:-30}"
|
|
|
79
89
|
EXPAND_DAYS="\${YOUMD_EXPAND_ACTIVE_DAYS:-90}"
|
|
80
90
|
LIMIT="\${YOUMD_PROJECT_LIMIT:-80}"
|
|
81
91
|
HYDRATE_TIMEOUT="\${YOUMD_PORTFOLIO_HYDRATE_TIMEOUT_SECONDS:-180}"
|
|
92
|
+
MIN_YOUMD_VERSION="\${YOUMD_MIN_VERSION:-0.8.7}"
|
|
82
93
|
mkdir -p "$ROOT"
|
|
83
94
|
|
|
84
95
|
command_exists() { command -v "$1" >/dev/null 2>&1; }
|
|
85
96
|
node_major() { node -e 'console.log(process.versions.node.split(".")[0])' 2>/dev/null || echo 0; }
|
|
97
|
+
version_at_least() {
|
|
98
|
+
local current="\${1#v}"
|
|
99
|
+
local required="\${2#v}"
|
|
100
|
+
local IFS=.
|
|
101
|
+
local current_parts=($current)
|
|
102
|
+
local required_parts=($required)
|
|
103
|
+
local i current_value required_value
|
|
104
|
+
for i in 0 1 2; do
|
|
105
|
+
current_value="\${current_parts[$i]:-0}"
|
|
106
|
+
required_value="\${required_parts[$i]:-0}"
|
|
107
|
+
current_value="\${current_value%%[^0-9]*}"
|
|
108
|
+
required_value="\${required_value%%[^0-9]*}"
|
|
109
|
+
current_value="\${current_value:-0}"
|
|
110
|
+
required_value="\${required_value:-0}"
|
|
111
|
+
if ((10#$current_value > 10#$required_value)); then return 0; fi
|
|
112
|
+
if ((10#$current_value < 10#$required_value)); then return 1; fi
|
|
113
|
+
done
|
|
114
|
+
return 0
|
|
115
|
+
}
|
|
116
|
+
ensure_youmd_min_version() {
|
|
117
|
+
local installed
|
|
118
|
+
installed="$(youmd --version 2>/dev/null | tr -d '[:space:]' || true)"
|
|
119
|
+
echo "[you.md] installed version: \${installed:-unknown}"
|
|
120
|
+
if [ -n "$installed" ] && version_at_least "$installed" "$MIN_YOUMD_VERSION"; then
|
|
121
|
+
return 0
|
|
122
|
+
fi
|
|
123
|
+
echo "[you.md] installed youmd is older than required \${MIN_YOUMD_VERSION}; forcing GitHub source install"
|
|
124
|
+
curl -fsSL https://you.md/install.sh | YOUMD_INSTALL_CHANNEL=source YOUMD_SOURCE_REF=main bash
|
|
125
|
+
export PATH="$HOME/.youmd/bin:$HOME/.youmd/npm-global/bin:/opt/homebrew/opt/node@22/bin:/usr/local/opt/node@22/bin:/opt/homebrew/bin:/usr/local/bin:$PATH"
|
|
126
|
+
installed="$(youmd --version 2>/dev/null | tr -d '[:space:]' || true)"
|
|
127
|
+
echo "[you.md] installed version after forced source install: \${installed:-unknown}"
|
|
128
|
+
if [ -z "$installed" ] || ! version_at_least "$installed" "$MIN_YOUMD_VERSION"; then
|
|
129
|
+
echo "[you.md] youmd \${MIN_YOUMD_VERSION}+ is required for Secret Vault, agent bus, and fresh-machine restore. npm latest may still be behind; rerun after this commit is deployed or install from GitHub main." >&2
|
|
130
|
+
exit 1
|
|
131
|
+
fi
|
|
132
|
+
}
|
|
86
133
|
run_with_timeout() {
|
|
87
134
|
seconds="$1"
|
|
88
135
|
shift
|
|
@@ -165,13 +212,14 @@ ensure_github_auth() {
|
|
|
165
212
|
|
|
166
213
|
bootstrap_prereqs
|
|
167
214
|
|
|
168
|
-
echo "[you.md] installing runtime"
|
|
169
|
-
curl -fsSL https://you.md/install.sh | bash
|
|
215
|
+
echo "[you.md] installing runtime from GitHub main"
|
|
216
|
+
curl -fsSL https://you.md/install.sh | YOUMD_INSTALL_CHANNEL=source YOUMD_SOURCE_REF=main bash
|
|
170
217
|
export PATH="$HOME/.youmd/bin:$HOME/.youmd/npm-global/bin:/opt/homebrew/opt/node@22/bin:/usr/local/opt/node@22/bin:/opt/homebrew/bin:/usr/local/bin:$PATH"
|
|
171
218
|
if ! command_exists youmd; then
|
|
172
219
|
echo "[you.md] youmd was installed but is not on PATH. Try a new Terminal, then rerun this command." >&2
|
|
173
220
|
exit 1
|
|
174
221
|
fi
|
|
222
|
+
ensure_youmd_min_version
|
|
175
223
|
|
|
176
224
|
if [ -n "\${YOUMD_API_KEY:-}" ]; then
|
|
177
225
|
echo "[you.md] logging in with bootstrap key"
|
|
@@ -184,10 +232,12 @@ fi
|
|
|
184
232
|
echo "[you.md] pulling identity bundle and syncing local brain"
|
|
185
233
|
youmd pull
|
|
186
234
|
youmd sync
|
|
235
|
+
youmd agent send --channel machine-sync --kind status "fresh machine \$(hostname) authenticated, pulled identity, and started setup" || true
|
|
187
236
|
|
|
188
237
|
echo "[you.md] installing resident realtime/identity/skillstack/project-context daemons early"
|
|
189
238
|
youmd stack daemon install || true
|
|
190
239
|
youmd stack daemon status || true
|
|
240
|
+
youmd agent send --channel machine-sync --kind status "fresh machine \$(hostname) installed resident realtime/skillstack daemons" || true
|
|
191
241
|
|
|
192
242
|
GITHUB_READY=0
|
|
193
243
|
if ensure_github_auth; then
|
|
@@ -205,9 +255,11 @@ youmd mcp --install claude --auto || true
|
|
|
205
255
|
youmd mcp --install codex --auto || true
|
|
206
256
|
youmd skill link claude || true
|
|
207
257
|
youmd skill link codex || true
|
|
258
|
+
youmd agent send --channel machine-sync --kind status "fresh machine \$(hostname) restored shared skills/stacks and MCP config" || true
|
|
208
259
|
|
|
209
260
|
if [ "$GITHUB_READY" != "1" ]; then
|
|
210
261
|
echo "[you.md] GitHub auth is still missing; project clone pass skipped. Rerun after gh auth login."
|
|
262
|
+
youmd agent send --channel machine-sync --kind status "fresh machine \$(hostname) stopped: GitHub auth required before private project clone" || true
|
|
211
263
|
exit 2
|
|
212
264
|
fi
|
|
213
265
|
|
|
@@ -235,34 +287,50 @@ echo "[you.md] previewing graph-backed 30-day project setup plan (ACTIVE + Top P
|
|
|
235
287
|
run_machine_projects_recent_only "\${PROJECT_ARGS[@]}" --dry-run || true
|
|
236
288
|
echo "[you.md] creating code workspace and cloning ACTIVE + Top Priority/Focusing 30-day project repos"
|
|
237
289
|
run_machine_projects_recent_only "\${PROJECT_ARGS[@]}"
|
|
290
|
+
youmd agent send --channel machine-sync --kind status "fresh machine \$(hostname) finished 30-day active/focused project clone pass into $ROOT" || true
|
|
238
291
|
|
|
239
292
|
echo "[you.md] checking encrypted env-vault tooling without printing secrets"
|
|
240
293
|
youmd env backup --root "$ROOT" --preflight || true
|
|
294
|
+
SECRET_VAULT_RESTORED=0
|
|
295
|
+
ALLOW_LOCAL_ENV_VAULT_FALLBACK="\${YOUMD_ALLOW_LOCAL_ENV_VAULT_FALLBACK:-0}"
|
|
241
296
|
if [ -z "\${YOUMD_ENV_VAULT:-}" ] && [ "\${YOUMD_SECRET_VAULT_PULL:-1}" = "1" ]; then
|
|
242
297
|
SECRET_VAULT_DIR="\${YOUMD_SECRET_VAULT_DIR:-$HOME/.youmd/secret-vault}"
|
|
243
|
-
echo "[you.md]
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
298
|
+
echo "[you.md] registering this Mac as a trusted Secret Vault device"
|
|
299
|
+
youmd env vault device-register || true
|
|
300
|
+
echo "[you.md] checking You.md Secret Vault for the latest encrypted env vault and trusted-device envelope"
|
|
301
|
+
if youmd env vault pull --out "$SECRET_VAULT_DIR" --restore --root "$ROOT" --map-existing --existing-only --skip-agent-auth; then
|
|
302
|
+
SECRET_VAULT_RESTORED=1
|
|
303
|
+
echo "[you.md] restored env vault through trusted-device Secret Vault"
|
|
304
|
+
youmd agent send --channel machine-sync --kind status "fresh machine \$(hostname) restored encrypted env vault through trusted-device Secret Vault" || true
|
|
249
305
|
else
|
|
250
|
-
echo "[you.md] account-backed Secret Vault
|
|
306
|
+
echo "[you.md] account-backed Secret Vault restore is waiting for a trusted-device share"
|
|
307
|
+
echo "[you.md] source Mac action: youmd env vault share"
|
|
308
|
+
echo "[you.md] new Mac retry: youmd env vault pull --restore --root \\"$ROOT\\" --map-existing --existing-only --skip-agent-auth"
|
|
309
|
+
youmd agent send --channel machine-sync --kind status "fresh machine \$(hostname) registered Secret Vault device and is waiting for source Mac trusted-device share" || true
|
|
251
310
|
fi
|
|
252
311
|
fi
|
|
253
|
-
if [ -z "\${YOUMD_ENV_VAULT:-}" ]; then
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
if [ -
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
312
|
+
if [ "$SECRET_VAULT_RESTORED" != "1" ] && [ -z "\${YOUMD_ENV_VAULT:-}" ]; then
|
|
313
|
+
if [ "$ALLOW_LOCAL_ENV_VAULT_FALLBACK" = "1" ]; then
|
|
314
|
+
echo "[you.md] opt-in local/iCloud passphrase vault fallback enabled"
|
|
315
|
+
for DEFAULT_ENV_VAULT_DIR in "$HOME/Desktop/youmd-env-vault" "$HOME/Library/Mobile Documents/com~apple~CloudDocs/Desktop/youmd-env-vault" "$HOME/Library/Mobile Documents/com~apple~CloudDocs/youmd-env-vault"; do
|
|
316
|
+
if [ -d "$DEFAULT_ENV_VAULT_DIR" ]; then
|
|
317
|
+
DETECTED_ENV_VAULT="$(find "$DEFAULT_ENV_VAULT_DIR" -maxdepth 1 -type f \\( -name "env-vault-*.tar.enc" -o -name "env-vault-*.tar.age" -o -name "env-vault-*.tar.gpg" \\) -print 2>/dev/null | sort | tail -n 1 || true)"
|
|
318
|
+
if [ -n "$DETECTED_ENV_VAULT" ]; then
|
|
319
|
+
export YOUMD_ENV_VAULT="$DETECTED_ENV_VAULT"
|
|
320
|
+
echo "[you.md] using detected env vault: $YOUMD_ENV_VAULT"
|
|
321
|
+
break
|
|
322
|
+
fi
|
|
261
323
|
fi
|
|
262
|
-
|
|
263
|
-
|
|
324
|
+
done
|
|
325
|
+
else
|
|
326
|
+
echo "[you.md] local/iCloud passphrase vault fallback disabled by default"
|
|
327
|
+
echo "[you.md] set YOUMD_ALLOW_LOCAL_ENV_VAULT_FALLBACK=1 or YOUMD_ENV_VAULT=/path/to/env-vault only if you intentionally want the older passphrase flow"
|
|
328
|
+
fi
|
|
264
329
|
fi
|
|
265
|
-
if [
|
|
330
|
+
if [ "$SECRET_VAULT_RESTORED" = "1" ]; then
|
|
331
|
+
:
|
|
332
|
+
elif [ -n "\${YOUMD_ENV_VAULT:-}" ]; then
|
|
333
|
+
echo "[you.md] using explicit/opt-in local encrypted vault fallback"
|
|
266
334
|
if [ ! -f "$YOUMD_ENV_VAULT" ]; then
|
|
267
335
|
echo "[you.md] env vault path does not exist: $YOUMD_ENV_VAULT" >&2
|
|
268
336
|
exit 1
|
|
@@ -274,26 +342,34 @@ if [ -n "\${YOUMD_ENV_VAULT:-}" ]; then
|
|
|
274
342
|
unset ENV_VAULT_PASS_FROM_KEYCHAIN
|
|
275
343
|
echo "[you.md] loaded env-vault passphrase from macOS Keychain service: $KEYCHAIN_SERVICE"
|
|
276
344
|
else
|
|
277
|
-
echo "[you.md] no env-vault Keychain item found;
|
|
345
|
+
echo "[you.md] no env-vault Keychain item found; explicit local fallback may prompt for the passphrase"
|
|
278
346
|
fi
|
|
279
347
|
fi
|
|
280
348
|
echo "[you.md] listing encrypted .env.local vault before restore"
|
|
281
349
|
youmd env restore "$YOUMD_ENV_VAULT" --root "$ROOT" --list --map-existing --existing-only --skip-agent-auth
|
|
282
350
|
echo "[you.md] restoring encrypted .env.local vault into existing cloned project dirs"
|
|
283
351
|
youmd env restore "$YOUMD_ENV_VAULT" --root "$ROOT" --map-existing --existing-only --skip-agent-auth
|
|
352
|
+
youmd agent send --channel machine-sync --kind status "fresh machine \$(hostname) restored encrypted env vault into existing project dirs" || true
|
|
284
353
|
else
|
|
285
354
|
echo "[you.md] env vault not restored yet"
|
|
286
355
|
echo "[you.md] On the old/source Mac, create the encrypted vault first:"
|
|
287
356
|
echo "youmd env vault push --root ~/Desktop/CODE_2025 --out ~/Desktop/youmd-env-vault"
|
|
288
|
-
echo "[you.md]
|
|
357
|
+
echo "[you.md] Then share local decrypt access to registered trusted Macs:"
|
|
358
|
+
echo "youmd env vault share"
|
|
359
|
+
echo "[you.md] Then retry on this Mac:"
|
|
360
|
+
echo "youmd env vault pull --restore --root \\"$ROOT\\" --map-existing --existing-only --skip-agent-auth"
|
|
361
|
+
echo "[you.md] This strict fresh-machine flow intentionally does not ask for a local vault passphrase on the new Mac by default."
|
|
362
|
+
echo "[you.md] Optional fallback: create a transferable local copy without account sync:"
|
|
289
363
|
echo "youmd env backup --root ~/Desktop/CODE_2025 --out ~/Desktop/youmd-env-vault"
|
|
290
|
-
echo "[you.md]
|
|
364
|
+
echo "[you.md] Local/iCloud auto-detect is opt-in only. Rerun with:"
|
|
365
|
+
echo "YOUMD_ALLOW_LOCAL_ENV_VAULT_FALLBACK=1 YOUMD_REQUIRE_ENV_VAULT=1 <same command>"
|
|
291
366
|
echo "[you.md] Move the generated env-vault-*.tar.enc file to this Mac, then rerun this command with:"
|
|
292
367
|
echo "YOUMD_ENV_VAULT=/path/to/env-vault-YYYYMMDDTHHMMZ.tar.enc YOUMD_REQUIRE_ENV_VAULT=1 <same command>"
|
|
293
368
|
echo "[you.md] Or restore manually after clone:"
|
|
294
369
|
echo "youmd env restore <vault> --root \\"$ROOT\\" --map-existing --existing-only --skip-agent-auth"
|
|
295
370
|
if [ "\${YOUMD_REQUIRE_ENV_VAULT:-}" = "1" ]; then
|
|
296
|
-
echo "[you.md] strict proof
|
|
371
|
+
echo "[you.md] strict proof is waiting for trusted-device Secret Vault share or an explicitly provided local vault; stopping before readiness is marked complete" >&2
|
|
372
|
+
youmd agent send --channel machine-sync --kind status "fresh machine \$(hostname) stopped: waiting for trusted-device Secret Vault share or explicit local vault fallback" || true
|
|
297
373
|
exit 1
|
|
298
374
|
fi
|
|
299
375
|
fi
|
|
@@ -301,6 +377,7 @@ echo "[you.md] rehydrating portfolio graph with local README/project-context/env
|
|
|
301
377
|
run_with_timeout "$HYDRATE_TIMEOUT" youmd project portfolio-hydrate --root "$ROOT" --days "$DAYS" --limit "$LIMIT" || true
|
|
302
378
|
echo "[you.md] auditing cloned project readiness"
|
|
303
379
|
youmd machine verify --root "$ROOT" --max-projects "$LIMIT" --write-report --sync-report || true
|
|
380
|
+
youmd agent send --channel machine-sync --kind status "fresh machine \$(hostname) synced machine readiness proof for $ROOT" || true
|
|
304
381
|
FULL_PROJECT_SET_COMPLETE=0
|
|
305
382
|
EXPAND_TO_90="\${YOUMD_EXPAND_TO_90_DAYS:-}"
|
|
306
383
|
if [ -z "$EXPAND_TO_90" ] && [ "\${YOUMD_SKIP_90_DAY_EXPANSION_PROMPT:-}" != "1" ] && [ -t 0 ]; then
|
|
@@ -319,6 +396,7 @@ case "$EXPAND_TO_90" in
|
|
|
319
396
|
run_machine_projects_recent_only "\${EXPAND_PROJECT_ARGS[@]}"
|
|
320
397
|
run_with_timeout "$HYDRATE_TIMEOUT" youmd project portfolio-hydrate --root "$ROOT" --days "$EXPAND_DAYS" --limit "$LIMIT" || true
|
|
321
398
|
youmd machine verify --root "$ROOT" --max-projects "$LIMIT" --write-report --sync-report || true
|
|
399
|
+
youmd agent send --channel machine-sync --kind status "fresh machine \$(hostname) expanded to active/focused \${EXPAND_DAYS}-day project set and synced proof" || true
|
|
322
400
|
FULL_PROJECT_SET_COMPLETE=1
|
|
323
401
|
;;
|
|
324
402
|
*)
|
|
@@ -350,8 +428,10 @@ youmd stack daemon status || true
|
|
|
350
428
|
youmd status
|
|
351
429
|
if [ "$FULL_PROJECT_SET_COMPLETE" = "1" ]; then
|
|
352
430
|
echo "[you.md] fresh-machine full \${EXPAND_DAYS}-day project setup complete: $ROOT"
|
|
431
|
+
youmd agent send --channel machine-sync --kind status "fresh machine \$(hostname) complete: full \${EXPAND_DAYS}-day active/focused setup at $ROOT" || true
|
|
353
432
|
else
|
|
354
433
|
echo "[you.md] fresh-machine \${DAYS}-day setup pass complete; \${EXPAND_DAYS}-day expansion is still open: $ROOT"
|
|
434
|
+
youmd agent send --channel machine-sync --kind status "fresh machine \$(hostname) complete for \${DAYS}-day active/focused pass at $ROOT; \${EXPAND_DAYS}-day expansion still open" || true
|
|
355
435
|
fi`;
|
|
356
436
|
}
|
|
357
437
|
function buildFreshMachineBootstrapCommand(options = {}) {
|
|
@@ -385,7 +465,7 @@ function buildFreshMachineBootstrapPrompt(options = {}) {
|
|
|
385
465
|
"",
|
|
386
466
|
authLine,
|
|
387
467
|
"",
|
|
388
|
-
"Behind-the-scenes operating rule: use the You.md CLI and You Agent yourself before asking Houston to do anything. Run deterministic commands like `youmd status`, `youmd whoami`, `youmd pull`, `youmd sync`, `youmd skill install all`, `youmd skill sync`, `youmd env vault list`, `youmd env vault pull`, `youmd machine prompt`, `youmd machine verify`,
|
|
468
|
+
"Behind-the-scenes operating rule: use the You.md CLI and You Agent yourself before asking Houston to do anything. Run deterministic commands like `youmd status`, `youmd whoami`, `youmd pull`, `youmd sync`, `youmd skill install all`, `youmd skill sync`, `youmd env vault list`, `youmd env vault device-register`, `youmd env vault pull --restore`, `youmd machine prompt`, `youmd machine verify`, `youmd project portfolio-hydrate`, and `youmd agent status` as needed. Use `youmd agent send --channel machine-sync --kind status \"...\"` to report setup milestones back to Houston's other trusted Macs over the realtime agent bus. Use `you` / `youmd chat` only when you need the You Agent to synthesize or route context, then turn its output into concrete shell actions. Interrupt Houston only for true human-gated steps: GitHub browser auth, source-Mac Secret Vault share if the trusted-device envelope has not been created yet, local vault passphrase/Keychain only when `YOUMD_ALLOW_LOCAL_ENV_VAULT_FALLBACK=1` or `YOUMD_ENV_VAULT` is explicitly provided, npm OTP, OS permissions, or an explicit choice such as the 90-day expansion.",
|
|
389
469
|
"",
|
|
390
470
|
"Exact setup command:",
|
|
391
471
|
"",
|
|
@@ -402,15 +482,16 @@ function buildFreshMachineBootstrapPrompt(options = {}) {
|
|
|
402
482
|
"- install/configure MCP for Claude Code and Codex",
|
|
403
483
|
"- restore shared agent skills, stack config, Claude/Codex links, and agent host config",
|
|
404
484
|
"- use the installed You.md CLI behind the scenes for status, skill sync, Secret Vault pull, portfolio graph hydration, machine verification, and You Agent context routing instead of making Houston manually drive those steps",
|
|
485
|
+
"- publish setup milestones through `youmd agent send` so Houston's source Mac and realtime daemon can see the Mac mini come online without clipboard babysitting",
|
|
405
486
|
"- hydrate the portfolio graph from You.md + authenticated GitHub before cloning",
|
|
406
487
|
`- preview the graph-backed plan, create ${root}, and clone only projects marked ACTIVE plus Top Priority/Focusing from the last ${days} days first`,
|
|
407
488
|
`- ask whether to expand to all ACTIVE plus Top Priority/Focusing projects from the last ${expandDays} days before calling the full project clone set complete`,
|
|
408
|
-
"- check env-vault tooling, pull the latest account-backed You.md Secret Vault encrypted snapshot when available,
|
|
489
|
+
"- check env-vault tooling, register this Mac as a trusted Secret Vault device, pull the latest account-backed You.md Secret Vault encrypted snapshot when available, unwrap the vault passphrase locally through a trusted-device key envelope, restore env files into existing cloned project dirs with `--map-existing --existing-only --skip-agent-auth`, or stop with the exact source-Mac `youmd env vault share` action instead of asking for a passphrase on the new Mac. Local/iCloud passphrase fallback runs only when `YOUMD_ALLOW_LOCAL_ENV_VAULT_FALLBACK=1` or `YOUMD_ENV_VAULT` is explicitly provided. After env handling, rehydrate local project/env evidence.",
|
|
409
490
|
"- write and sync a secret-safe machine proof report, with optional bounded install/check/server proof flags",
|
|
410
491
|
"- bound portfolio hydration with `YOUMD_PORTFOLIO_HYDRATE_TIMEOUT_SECONDS` so large restored roots do not wedge setup",
|
|
411
492
|
"",
|
|
412
493
|
`Project source: You.md portfolio graph + authenticated GitHub recent repos, capped at ${limit} tracked projects before local audit evidence is merged. When the graph exists, new-computer setup clones only projects with status ACTIVE and focus Top Priority/Focusing; inactive, unsorted, on-ice, abandoned, killed, and unreviewed GitHub-only repos are skipped unless --include-inactive is explicitly used. First pass is ${days} days with out-of-window projects skipped; the ${expandDays}-day pass is explicit.`,
|
|
413
|
-
"Secret rule: .env.local values are never embedded here. Best path: on the old/source Mac, run `youmd env vault push --root ~/Desktop/CODE_2025 --out ~/Desktop/youmd-env-vault` once. That uploads only encrypted archive bytes plus
|
|
494
|
+
"Secret rule: .env.local values are never embedded here. Best path: on the old/source Mac, run `youmd env vault push --root ~/Desktop/CODE_2025 --out ~/Desktop/youmd-env-vault` once, then after the new Mac registers itself run `youmd env vault share` on the source Mac. That uploads only encrypted archive bytes plus safe manifest metadata, and stores only per-device encrypted passphrase envelopes. A trusted new Mac pulls the encrypted snapshot after login and decrypts locally with its private device key; raw env values never hit the browser, chat, or You.md servers. If the envelope is missing, the command stops and sends a machine-sync status telling the source Mac to run `youmd env vault share`. Local fallback is opt-in only: run `youmd env backup --root ~/Desktop/CODE_2025 --out ~/Desktop/youmd-env-vault`, move the generated `env-vault-*.tar.enc` file to the new machine, then rerun with `YOUMD_ALLOW_LOCAL_ENV_VAULT_FALLBACK=1` or explicit `YOUMD_ENV_VAULT=/path/to/env-vault-*.tar.enc`. The restore path lists variable names/counts and target paths only, never values, maps old folder names onto cloned dirs, and skips agent auth config so it does not clobber the new machine's active Claude/Codex login.",
|
|
414
495
|
"",
|
|
415
496
|
"After the command finishes, report:",
|
|
416
497
|
"- the `youmd status` sync state",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"machine-bootstrap-prompt.js","sourceRoot":"","sources":["../../src/lib/machine-bootstrap-prompt.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"machine-bootstrap-prompt.js","sourceRoot":"","sources":["../../src/lib/machine-bootstrap-prompt.ts"],"names":[],"mappings":"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"}
|
|
@@ -32,6 +32,14 @@ export type RealtimeSyncHead = {
|
|
|
32
32
|
brainDumps?: number;
|
|
33
33
|
machineProofs?: number;
|
|
34
34
|
};
|
|
35
|
+
agentBus?: {
|
|
36
|
+
status?: "active" | "idle" | string;
|
|
37
|
+
channelCount?: number;
|
|
38
|
+
recentCount?: number;
|
|
39
|
+
latestMessageAt?: number | null;
|
|
40
|
+
messages?: RealtimeAgentMessage[];
|
|
41
|
+
secretValuesExposed?: false;
|
|
42
|
+
};
|
|
35
43
|
repoMirror?: {
|
|
36
44
|
repoFullName?: string | null;
|
|
37
45
|
commitSha?: string | null;
|
|
@@ -52,6 +60,9 @@ export type RealtimeSyncHead = {
|
|
|
52
60
|
flow?: string;
|
|
53
61
|
available?: boolean;
|
|
54
62
|
snapshotCount?: number;
|
|
63
|
+
trustedDeviceCount?: number;
|
|
64
|
+
keyEnvelopeCount?: number;
|
|
65
|
+
latestSnapshotEnvelopeCount?: number;
|
|
55
66
|
id?: string | null;
|
|
56
67
|
label?: string | null;
|
|
57
68
|
createdAt?: number | null;
|
|
@@ -74,11 +85,41 @@ export type RealtimeSyncHead = {
|
|
|
74
85
|
};
|
|
75
86
|
};
|
|
76
87
|
export declare const REALTIME_SYNC_STATUS_PATH: string;
|
|
88
|
+
export declare const REALTIME_AGENT_INBOX_PATH: string;
|
|
89
|
+
export type RealtimeAgentMessage = {
|
|
90
|
+
id?: string;
|
|
91
|
+
messageId: string;
|
|
92
|
+
channel: string;
|
|
93
|
+
kind: string;
|
|
94
|
+
body: string;
|
|
95
|
+
sourceHost?: string | null;
|
|
96
|
+
sourceAgent: string;
|
|
97
|
+
sourceRuntime?: string | null;
|
|
98
|
+
targetHost?: string | null;
|
|
99
|
+
targetAgent?: string | null;
|
|
100
|
+
metadata?: unknown;
|
|
101
|
+
createdAt: number;
|
|
102
|
+
secretValuesExposed: false;
|
|
103
|
+
};
|
|
104
|
+
export type RealtimeAgentBusStatus = {
|
|
105
|
+
state: "active" | "idle" | "unknown";
|
|
106
|
+
summary: string;
|
|
107
|
+
channelCount: number;
|
|
108
|
+
recentCount: number;
|
|
109
|
+
latestMessageAt?: number | null;
|
|
110
|
+
messages: RealtimeAgentMessage[];
|
|
111
|
+
inboxPath: string;
|
|
112
|
+
sendCommand: string;
|
|
113
|
+
secretValuesExposed: false;
|
|
114
|
+
};
|
|
77
115
|
export type RealtimeSecretVaultStatus = {
|
|
78
116
|
state: "ready" | "missing" | "scope-missing" | "unknown";
|
|
79
|
-
flow: "account-backed-encrypted-snapshot";
|
|
117
|
+
flow: "account-backed-encrypted-snapshot+trusted-device-envelopes";
|
|
80
118
|
available: boolean;
|
|
81
119
|
snapshotCount: number;
|
|
120
|
+
trustedDeviceCount: number;
|
|
121
|
+
keyEnvelopeCount: number;
|
|
122
|
+
latestSnapshotEnvelopeCount: number;
|
|
82
123
|
summary: string;
|
|
83
124
|
latestSnapshot?: {
|
|
84
125
|
id?: string | null;
|
|
@@ -98,6 +139,8 @@ export type RealtimeSecretVaultStatus = {
|
|
|
98
139
|
sourceHost?: string | null;
|
|
99
140
|
sourceRoot?: string | null;
|
|
100
141
|
};
|
|
142
|
+
deviceRegisterCommand: string;
|
|
143
|
+
shareCommand: string;
|
|
101
144
|
pullCommand: string;
|
|
102
145
|
restoreCommand: string;
|
|
103
146
|
secretValuesExposed: false;
|
|
@@ -113,16 +156,19 @@ export type RealtimeSyncStatusFile = {
|
|
|
113
156
|
latestInstalledAt?: number | null;
|
|
114
157
|
};
|
|
115
158
|
portfolio?: RealtimeSyncHead["portfolio"];
|
|
159
|
+
agentBus: RealtimeAgentBusStatus;
|
|
116
160
|
repoMirror?: RealtimeSyncHead["repoMirror"];
|
|
117
161
|
github?: RealtimeSyncHead["github"];
|
|
118
162
|
secretVault: RealtimeSecretVaultStatus;
|
|
119
163
|
secretValuesExposed: false;
|
|
120
164
|
};
|
|
121
165
|
export declare function describeRealtimeSecretVault(head: RealtimeSyncHead | null | undefined): RealtimeSecretVaultStatus;
|
|
166
|
+
export declare function describeRealtimeAgentBus(head: RealtimeSyncHead | null | undefined): RealtimeAgentBusStatus;
|
|
122
167
|
export declare function realtimeSyncHeadSignature(head: RealtimeSyncHead | null | undefined): string;
|
|
123
168
|
export declare function summarizeRealtimeSyncHead(head: RealtimeSyncHead): string;
|
|
124
169
|
export declare function buildRealtimeSyncStatusFile(head: RealtimeSyncHead): RealtimeSyncStatusFile;
|
|
125
170
|
export declare function writeRealtimeSyncStatusFile(head: RealtimeSyncHead): void;
|
|
126
171
|
export declare function readRealtimeSyncStatusFile(): RealtimeSyncStatusFile | null;
|
|
172
|
+
export declare function writeRealtimeAgentInboxFile(head: RealtimeSyncHead): void;
|
|
127
173
|
export declare function shouldRunBoundedSync(lastRunAt: number, now: number, minIntervalMs: number): boolean;
|
|
128
174
|
//# sourceMappingURL=realtime-sync.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"realtime-sync.d.ts","sourceRoot":"","sources":["../../src/lib/realtime-sync.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,QAAQ,CAAC,EAAE;QACT,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACjC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAChC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACnC,CAAC;IACF,MAAM,CAAC,EAAE;QACP,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAClC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;KAClB,CAAC;IACF,SAAS,CAAC,EAAE;QACV,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,qBAAqB,CAAC,EAAE,MAAM,CAAC;QAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,UAAU,CAAC,EAAE;QACX,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,IAAI,CAAC;IACT,MAAM,CAAC,EAAE;QACP,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACpC,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACjC,GAAG,IAAI,CAAC;IACT,iBAAiB,CAAC,EAAE;QAClB,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,eAAe,GAAG,MAAM,CAAC;QACxD,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACnB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC5B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC/B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC/B,iBAAiB,CAAC,EAAE,OAAO,CAAC;QAC5B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,mBAAmB,CAAC,EAAE,KAAK,CAAC;KAC7B,CAAC;CACH,CAAC;AAEF,eAAO,MAAM,yBAAyB,QAAiE,CAAC;
|
|
1
|
+
{"version":3,"file":"realtime-sync.d.ts","sourceRoot":"","sources":["../../src/lib/realtime-sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -33,18 +33,21 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.REALTIME_SYNC_STATUS_PATH = void 0;
|
|
36
|
+
exports.REALTIME_AGENT_INBOX_PATH = exports.REALTIME_SYNC_STATUS_PATH = void 0;
|
|
37
37
|
exports.describeRealtimeSecretVault = describeRealtimeSecretVault;
|
|
38
|
+
exports.describeRealtimeAgentBus = describeRealtimeAgentBus;
|
|
38
39
|
exports.realtimeSyncHeadSignature = realtimeSyncHeadSignature;
|
|
39
40
|
exports.summarizeRealtimeSyncHead = summarizeRealtimeSyncHead;
|
|
40
41
|
exports.buildRealtimeSyncStatusFile = buildRealtimeSyncStatusFile;
|
|
41
42
|
exports.writeRealtimeSyncStatusFile = writeRealtimeSyncStatusFile;
|
|
42
43
|
exports.readRealtimeSyncStatusFile = readRealtimeSyncStatusFile;
|
|
44
|
+
exports.writeRealtimeAgentInboxFile = writeRealtimeAgentInboxFile;
|
|
43
45
|
exports.shouldRunBoundedSync = shouldRunBoundedSync;
|
|
44
46
|
const fs = __importStar(require("fs"));
|
|
45
47
|
const os = __importStar(require("os"));
|
|
46
48
|
const path = __importStar(require("path"));
|
|
47
49
|
exports.REALTIME_SYNC_STATUS_PATH = path.join(os.homedir(), ".youmd", "realtime-sync-status.json");
|
|
50
|
+
exports.REALTIME_AGENT_INBOX_PATH = path.join(os.homedir(), ".youmd", "agent-bus", "inbox.json");
|
|
48
51
|
function shortSha(value) {
|
|
49
52
|
if (!value)
|
|
50
53
|
return null;
|
|
@@ -59,6 +62,8 @@ function describeRealtimeSecretVault(head) {
|
|
|
59
62
|
: vault
|
|
60
63
|
? "missing"
|
|
61
64
|
: "unknown";
|
|
65
|
+
const deviceRegisterCommand = "youmd env vault device-register";
|
|
66
|
+
const shareCommand = "youmd env vault share";
|
|
62
67
|
const pullCommand = "youmd env vault pull --out ~/.youmd/secret-vault";
|
|
63
68
|
const restoreCommand = "youmd env vault pull --restore --root ~/Desktop/CODE_YOU --map-existing --existing-only --skip-agent-auth";
|
|
64
69
|
if (state === "ready") {
|
|
@@ -66,12 +71,17 @@ function describeRealtimeSecretVault(head) {
|
|
|
66
71
|
const vars = vault?.variableCount ?? 0;
|
|
67
72
|
const source = vault?.sourceHost ? ` from ${vault.sourceHost}` : "";
|
|
68
73
|
const hash = shortSha(vault?.sha256);
|
|
74
|
+
const trustedDevices = vault?.trustedDeviceCount ?? 0;
|
|
75
|
+
const latestEnvelopes = vault?.latestSnapshotEnvelopeCount ?? 0;
|
|
69
76
|
return {
|
|
70
77
|
state,
|
|
71
|
-
flow: "account-backed-encrypted-snapshot",
|
|
78
|
+
flow: "account-backed-encrypted-snapshot+trusted-device-envelopes",
|
|
72
79
|
available: true,
|
|
73
80
|
snapshotCount: vault?.snapshotCount ?? 1,
|
|
74
|
-
|
|
81
|
+
trustedDeviceCount: trustedDevices,
|
|
82
|
+
keyEnvelopeCount: vault?.keyEnvelopeCount ?? latestEnvelopes,
|
|
83
|
+
latestSnapshotEnvelopeCount: latestEnvelopes,
|
|
84
|
+
summary: `Secret Vault ready: ${projects} projects / ${vars} vars${source} / ${latestEnvelopes}/${trustedDevices} device envelopes${hash ? ` / ${hash}` : ""}`,
|
|
75
85
|
latestSnapshot: {
|
|
76
86
|
id: vault?.id ?? null,
|
|
77
87
|
label: vault?.label ?? null,
|
|
@@ -90,6 +100,8 @@ function describeRealtimeSecretVault(head) {
|
|
|
90
100
|
sourceHost: vault?.sourceHost ?? null,
|
|
91
101
|
sourceRoot: vault?.sourceRoot ?? null,
|
|
92
102
|
},
|
|
103
|
+
deviceRegisterCommand,
|
|
104
|
+
shareCommand,
|
|
93
105
|
pullCommand,
|
|
94
106
|
restoreCommand,
|
|
95
107
|
secretValuesExposed: false,
|
|
@@ -98,10 +110,15 @@ function describeRealtimeSecretVault(head) {
|
|
|
98
110
|
if (state === "scope-missing") {
|
|
99
111
|
return {
|
|
100
112
|
state,
|
|
101
|
-
flow: "account-backed-encrypted-snapshot",
|
|
113
|
+
flow: "account-backed-encrypted-snapshot+trusted-device-envelopes",
|
|
102
114
|
available: false,
|
|
103
115
|
snapshotCount: 0,
|
|
116
|
+
trustedDeviceCount: 0,
|
|
117
|
+
keyEnvelopeCount: 0,
|
|
118
|
+
latestSnapshotEnvelopeCount: 0,
|
|
104
119
|
summary: "Secret Vault unknown: current realtime key lacks vault scope",
|
|
120
|
+
deviceRegisterCommand,
|
|
121
|
+
shareCommand,
|
|
105
122
|
pullCommand,
|
|
106
123
|
restoreCommand,
|
|
107
124
|
secretValuesExposed: false,
|
|
@@ -110,10 +127,15 @@ function describeRealtimeSecretVault(head) {
|
|
|
110
127
|
if (state === "missing") {
|
|
111
128
|
return {
|
|
112
129
|
state,
|
|
113
|
-
flow: "account-backed-encrypted-snapshot",
|
|
130
|
+
flow: "account-backed-encrypted-snapshot+trusted-device-envelopes",
|
|
114
131
|
available: false,
|
|
115
132
|
snapshotCount: vault?.snapshotCount ?? 0,
|
|
116
|
-
|
|
133
|
+
trustedDeviceCount: vault?.trustedDeviceCount ?? 0,
|
|
134
|
+
keyEnvelopeCount: vault?.keyEnvelopeCount ?? 0,
|
|
135
|
+
latestSnapshotEnvelopeCount: vault?.latestSnapshotEnvelopeCount ?? 0,
|
|
136
|
+
summary: "Secret Vault missing: upload encrypted snapshot from the source Mac with `youmd env vault push`, then register/share trusted devices",
|
|
137
|
+
deviceRegisterCommand,
|
|
138
|
+
shareCommand,
|
|
117
139
|
pullCommand,
|
|
118
140
|
restoreCommand,
|
|
119
141
|
secretValuesExposed: false,
|
|
@@ -121,15 +143,47 @@ function describeRealtimeSecretVault(head) {
|
|
|
121
143
|
}
|
|
122
144
|
return {
|
|
123
145
|
state,
|
|
124
|
-
flow: "account-backed-encrypted-snapshot",
|
|
146
|
+
flow: "account-backed-encrypted-snapshot+trusted-device-envelopes",
|
|
125
147
|
available: false,
|
|
126
148
|
snapshotCount: 0,
|
|
149
|
+
trustedDeviceCount: 0,
|
|
150
|
+
keyEnvelopeCount: 0,
|
|
151
|
+
latestSnapshotEnvelopeCount: 0,
|
|
127
152
|
summary: "Secret Vault not observed yet: realtime daemon has not received a vault-scoped sync head",
|
|
153
|
+
deviceRegisterCommand,
|
|
154
|
+
shareCommand,
|
|
128
155
|
pullCommand,
|
|
129
156
|
restoreCommand,
|
|
130
157
|
secretValuesExposed: false,
|
|
131
158
|
};
|
|
132
159
|
}
|
|
160
|
+
function describeRealtimeAgentBus(head) {
|
|
161
|
+
const bus = head?.agentBus;
|
|
162
|
+
const messages = (bus?.messages ?? [])
|
|
163
|
+
.filter((message) => {
|
|
164
|
+
return Boolean(message &&
|
|
165
|
+
typeof message.messageId === "string" &&
|
|
166
|
+
typeof message.body === "string" &&
|
|
167
|
+
message.secretValuesExposed === false);
|
|
168
|
+
})
|
|
169
|
+
.slice(-12);
|
|
170
|
+
const latest = bus?.latestMessageAt ?? (messages.length ? messages[messages.length - 1]?.createdAt : null);
|
|
171
|
+
const state = bus?.status === "active" || messages.length ? "active" : bus ? "idle" : "unknown";
|
|
172
|
+
const latestLabel = latest ? new Date(latest).toISOString() : "none yet";
|
|
173
|
+
return {
|
|
174
|
+
state,
|
|
175
|
+
summary: state === "unknown"
|
|
176
|
+
? "Agent bus not observed yet"
|
|
177
|
+
: `${messages.length} recent agent message${messages.length === 1 ? "" : "s"} / latest ${latestLabel}`,
|
|
178
|
+
channelCount: bus?.channelCount ?? new Set(messages.map((message) => message.channel)).size,
|
|
179
|
+
recentCount: bus?.recentCount ?? messages.length,
|
|
180
|
+
latestMessageAt: latest,
|
|
181
|
+
messages,
|
|
182
|
+
inboxPath: exports.REALTIME_AGENT_INBOX_PATH,
|
|
183
|
+
sendCommand: 'youmd agent send "hello from this Mac"',
|
|
184
|
+
secretValuesExposed: false,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
133
187
|
function realtimeSyncHeadSignature(head) {
|
|
134
188
|
if (!head)
|
|
135
189
|
return "none";
|
|
@@ -146,12 +200,31 @@ function realtimeSyncHeadSignature(head) {
|
|
|
146
200
|
names: head.skills?.names ?? [],
|
|
147
201
|
},
|
|
148
202
|
portfolio: head.portfolio ?? null,
|
|
203
|
+
agentBus: {
|
|
204
|
+
status: head.agentBus?.status ?? null,
|
|
205
|
+
latestMessageAt: head.agentBus?.latestMessageAt ?? null,
|
|
206
|
+
recentCount: head.agentBus?.recentCount ?? 0,
|
|
207
|
+
messages: (head.agentBus?.messages ?? []).map((message) => ({
|
|
208
|
+
messageId: message.messageId,
|
|
209
|
+
channel: message.channel,
|
|
210
|
+
kind: message.kind,
|
|
211
|
+
body: message.body,
|
|
212
|
+
sourceHost: message.sourceHost ?? null,
|
|
213
|
+
sourceAgent: message.sourceAgent,
|
|
214
|
+
targetHost: message.targetHost ?? null,
|
|
215
|
+
targetAgent: message.targetAgent ?? null,
|
|
216
|
+
createdAt: message.createdAt,
|
|
217
|
+
})),
|
|
218
|
+
},
|
|
149
219
|
repoMirror: head.repoMirror ?? null,
|
|
150
220
|
github: head.github ?? null,
|
|
151
221
|
encryptedEnvVault: {
|
|
152
222
|
status: head.encryptedEnvVault?.status ?? null,
|
|
153
223
|
available: head.encryptedEnvVault?.available ?? false,
|
|
154
224
|
snapshotCount: head.encryptedEnvVault?.snapshotCount ?? 0,
|
|
225
|
+
trustedDeviceCount: head.encryptedEnvVault?.trustedDeviceCount ?? 0,
|
|
226
|
+
keyEnvelopeCount: head.encryptedEnvVault?.keyEnvelopeCount ?? 0,
|
|
227
|
+
latestSnapshotEnvelopeCount: head.encryptedEnvVault?.latestSnapshotEnvelopeCount ?? 0,
|
|
155
228
|
id: head.encryptedEnvVault?.id ?? null,
|
|
156
229
|
createdAt: head.encryptedEnvVault?.createdAt ?? null,
|
|
157
230
|
fileName: head.encryptedEnvVault?.fileName ?? null,
|
|
@@ -171,8 +244,9 @@ function summarizeRealtimeSyncHead(head) {
|
|
|
171
244
|
const skills = `${head.skills?.installedCount ?? 0} skills`;
|
|
172
245
|
const projects = `${head.portfolio?.projects ?? 0} projects`;
|
|
173
246
|
const tasks = `${head.portfolio?.tasks ?? 0} tasks`;
|
|
247
|
+
const agentMessages = `${head.agentBus?.recentCount ?? 0} agent msgs`;
|
|
174
248
|
const vault = describeRealtimeSecretVault(head).summary;
|
|
175
|
-
return `${bundle}, ${skills}, ${projects}, ${tasks}, ${vault}`;
|
|
249
|
+
return `${bundle}, ${skills}, ${projects}, ${tasks}, ${agentMessages}, ${vault}`;
|
|
176
250
|
}
|
|
177
251
|
function buildRealtimeSyncStatusFile(head) {
|
|
178
252
|
return {
|
|
@@ -186,6 +260,7 @@ function buildRealtimeSyncStatusFile(head) {
|
|
|
186
260
|
latestInstalledAt: head.skills?.latestInstalledAt ?? null,
|
|
187
261
|
},
|
|
188
262
|
portfolio: head.portfolio,
|
|
263
|
+
agentBus: describeRealtimeAgentBus(head),
|
|
189
264
|
repoMirror: head.repoMirror,
|
|
190
265
|
github: head.github,
|
|
191
266
|
secretVault: describeRealtimeSecretVault(head),
|
|
@@ -195,6 +270,7 @@ function buildRealtimeSyncStatusFile(head) {
|
|
|
195
270
|
function writeRealtimeSyncStatusFile(head) {
|
|
196
271
|
fs.mkdirSync(path.dirname(exports.REALTIME_SYNC_STATUS_PATH), { recursive: true, mode: 0o700 });
|
|
197
272
|
fs.writeFileSync(exports.REALTIME_SYNC_STATUS_PATH, JSON.stringify(buildRealtimeSyncStatusFile(head), null, 2), { mode: 0o600 });
|
|
273
|
+
writeRealtimeAgentInboxFile(head);
|
|
198
274
|
}
|
|
199
275
|
function readRealtimeSyncStatusFile() {
|
|
200
276
|
try {
|
|
@@ -209,6 +285,15 @@ function readRealtimeSyncStatusFile() {
|
|
|
209
285
|
return null;
|
|
210
286
|
}
|
|
211
287
|
}
|
|
288
|
+
function writeRealtimeAgentInboxFile(head) {
|
|
289
|
+
const agentBus = describeRealtimeAgentBus(head);
|
|
290
|
+
fs.mkdirSync(path.dirname(exports.REALTIME_AGENT_INBOX_PATH), { recursive: true, mode: 0o700 });
|
|
291
|
+
fs.writeFileSync(exports.REALTIME_AGENT_INBOX_PATH, JSON.stringify({
|
|
292
|
+
schemaVersion: "you-md/realtime-agent-bus-inbox/v1",
|
|
293
|
+
generatedAt: Date.now(),
|
|
294
|
+
...agentBus,
|
|
295
|
+
}, null, 2), { mode: 0o600 });
|
|
296
|
+
}
|
|
212
297
|
function shouldRunBoundedSync(lastRunAt, now, minIntervalMs) {
|
|
213
298
|
return lastRunAt === 0 || now - lastRunAt >= minIntervalMs;
|
|
214
299
|
}
|