youmd 0.8.2 → 0.8.6

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 (46) hide show
  1. package/dist/commands/agent.d.ts +13 -0
  2. package/dist/commands/agent.d.ts.map +1 -0
  3. package/dist/commands/agent.js +233 -0
  4. package/dist/commands/agent.js.map +1 -0
  5. package/dist/commands/chat.d.ts.map +1 -1
  6. package/dist/commands/chat.js +17 -0
  7. package/dist/commands/chat.js.map +1 -1
  8. package/dist/commands/env.d.ts +20 -4
  9. package/dist/commands/env.d.ts.map +1 -1
  10. package/dist/commands/env.js +613 -21
  11. package/dist/commands/env.js.map +1 -1
  12. package/dist/commands/stack.d.ts.map +1 -1
  13. package/dist/commands/stack.js +8 -2
  14. package/dist/commands/stack.js.map +1 -1
  15. package/dist/commands/status.d.ts.map +1 -1
  16. package/dist/commands/status.js +8 -1
  17. package/dist/commands/status.js.map +1 -1
  18. package/dist/commands/sync.d.ts +1 -0
  19. package/dist/commands/sync.d.ts.map +1 -1
  20. package/dist/commands/sync.js +200 -0
  21. package/dist/commands/sync.js.map +1 -1
  22. package/dist/index.js +71 -4
  23. package/dist/index.js.map +1 -1
  24. package/dist/lib/api.d.ts +173 -0
  25. package/dist/lib/api.d.ts.map +1 -1
  26. package/dist/lib/api.js +87 -0
  27. package/dist/lib/api.js.map +1 -1
  28. package/dist/lib/daemon.d.ts +3 -0
  29. package/dist/lib/daemon.d.ts.map +1 -1
  30. package/dist/lib/daemon.js +21 -0
  31. package/dist/lib/daemon.js.map +1 -1
  32. package/dist/lib/machine-bootstrap-prompt.d.ts.map +1 -1
  33. package/dist/lib/machine-bootstrap-prompt.js +372 -184
  34. package/dist/lib/machine-bootstrap-prompt.js.map +1 -1
  35. package/dist/lib/realtime-sync.d.ts +174 -0
  36. package/dist/lib/realtime-sync.d.ts.map +1 -0
  37. package/dist/lib/realtime-sync.js +300 -0
  38. package/dist/lib/realtime-sync.js.map +1 -0
  39. package/package.json +2 -1
  40. package/scripts/env-vault/README.md +9 -0
  41. package/scripts/env-vault/restore.sh +85 -12
  42. package/scripts/skillstack-sync/README.md +24 -6
  43. package/scripts/skillstack-sync/bootstrap-new-mac.sh +31 -0
  44. package/scripts/skillstack-sync/com.youmd.realtime-sync.plist +35 -0
  45. package/scripts/skillstack-sync/install-daemons.sh +4 -1
  46. package/skills/machine-bootstrap.md +114 -19
@@ -45,10 +45,28 @@ exports.DEFAULT_FRESH_MACHINE_LIMIT = 80;
45
45
  function shellQuote(value) {
46
46
  return `'${value.replace(/'/g, `'\"'\"'`)}'`;
47
47
  }
48
- function envAssignment(name, value) {
48
+ function envAssignment(name, value, options = {}) {
49
49
  if (value === undefined || value === null || `${value}`.trim() === "")
50
50
  return null;
51
- return `${name}=${shellQuote(String(value))}`;
51
+ const stringValue = String(value);
52
+ if (options.expandHome) {
53
+ if (stringValue === "~")
54
+ return `${name}="$HOME"`;
55
+ if (stringValue.startsWith("~/")) {
56
+ return `${name}="$HOME${stringValue.slice(1).replace(/["\\$`]/g, (char) => `\\${char}`)}"`;
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
+ }
68
+ }
69
+ return `${name}=${shellQuote(stringValue)}`;
52
70
  }
53
71
  function portableHomePath(value) {
54
72
  if (!value)
@@ -64,193 +82,356 @@ function portableHomePath(value) {
64
82
  return value;
65
83
  }
66
84
  function buildFreshMachineBootstrapScript() {
67
- return [
68
- "set -euo pipefail",
69
- 'ROOT="${YOUMD_CODE_ROOT:-$HOME/Desktop/CODE_YOU}"',
70
- 'DAYS="${YOUMD_ACTIVE_DAYS:-30}"',
71
- 'EXPAND_DAYS="${YOUMD_EXPAND_ACTIVE_DAYS:-90}"',
72
- 'LIMIT="${YOUMD_PROJECT_LIMIT:-80}"',
73
- 'HYDRATE_TIMEOUT="${YOUMD_PORTFOLIO_HYDRATE_TIMEOUT_SECONDS:-180}"',
74
- 'run_with_timeout() {',
75
- ' seconds="$1"',
76
- " shift",
77
- ' if command -v gtimeout >/dev/null 2>&1; then',
78
- ' gtimeout "$seconds" "$@"',
79
- ' elif command -v timeout >/dev/null 2>&1; then',
80
- ' timeout "$seconds" "$@"',
81
- " else",
82
- ' "$@" &',
83
- " pid=$!",
84
- ' ( sleep "$seconds"; if kill -0 "$pid" >/dev/null 2>&1; then echo "[you.md] timeout after ${seconds}s: $*" >&2; kill "$pid" >/dev/null 2>&1 || true; fi ) &',
85
- " watcher=$!",
86
- ' wait "$pid"',
87
- " status=$?",
88
- ' kill "$watcher" >/dev/null 2>&1 || true',
89
- ' wait "$watcher" 2>/dev/null || true',
90
- ' return "$status"',
91
- " fi",
92
- "}",
93
- 'echo "[you.md] installing runtime"',
94
- "curl -fsSL https://you.md/install.sh | bash",
95
- 'if [ -n "${YOUMD_API_KEY:-}" ]; then',
96
- ' echo "[you.md] logging in with bootstrap key"',
97
- ' youmd login --key "$YOUMD_API_KEY"',
98
- "else",
99
- ' echo "[you.md] no YOUMD_API_KEY set; starting interactive login"',
100
- " youmd login",
101
- "fi",
102
- 'echo "[you.md] pulling identity bundle and syncing local brain"',
103
- "youmd pull",
104
- "youmd sync",
105
- 'echo "[you.md] restoring shared skills, stacks, and agent host config"',
106
- "youmd machine setup",
107
- "youmd skill install all",
108
- "youmd skill sync",
109
- "youmd mcp --install claude --auto || true",
110
- "youmd mcp --install codex --auto || true",
111
- "youmd skill link claude || true",
112
- "youmd skill link codex || true",
113
- 'if command -v gh >/dev/null 2>&1; then',
114
- " gh auth status >/dev/null 2>&1 || gh auth login",
115
- "else",
116
- ' echo "[you.md] GitHub CLI missing; private repo clones may need gh installed"',
117
- "fi",
118
- "RECENT_ONLY_ARGS=()",
119
- 'if youmd machine --help 2>/dev/null | grep -q -- "--recent-only"; then',
120
- " RECENT_ONLY_ARGS=(--recent-only)",
121
- "else",
122
- ' echo "[you.md] installed CLI does not expose --recent-only yet; using noninteractive no-to-older-projects fallback"',
123
- "fi",
124
- "run_machine_projects_recent_only() {",
125
- ' if [ "${#RECENT_ONLY_ARGS[@]}" -gt 0 ]; then',
126
- ' youmd machine projects "$@"',
127
- " else",
128
- ' youmd machine projects "$@" </dev/null',
129
- " fi",
130
- "}",
131
- 'echo "[you.md] hydrating portfolio graph from You.md/GitHub before the 30-day local clone pass"',
132
- 'run_with_timeout "$HYDRATE_TIMEOUT" youmd project portfolio-hydrate --root "$ROOT" --days "$DAYS" --limit "$LIMIT" || true',
133
- 'PROJECT_ARGS=(--root "$ROOT" --days "$DAYS" "${RECENT_ONLY_ARGS[@]}")',
134
- 'if [ -n "${YOUMD_MAX_CLONE_PROJECTS:-}" ]; then',
135
- ' PROJECT_ARGS+=(--max-clone-projects "$YOUMD_MAX_CLONE_PROJECTS")',
136
- "fi",
137
- 'echo "[you.md] previewing graph-backed 30-day project setup plan (ACTIVE + Top Priority/Focusing only)"',
138
- 'run_machine_projects_recent_only "${PROJECT_ARGS[@]}" --dry-run || true',
139
- 'echo "[you.md] creating code workspace and cloning ACTIVE + Top Priority/Focusing 30-day project repos"',
140
- 'run_machine_projects_recent_only "${PROJECT_ARGS[@]}"',
141
- 'echo "[you.md] checking encrypted env-vault tooling without printing secrets"',
142
- 'youmd env backup --root "$ROOT" --preflight || true',
143
- 'if [ -z "${YOUMD_ENV_VAULT:-}" ]; then',
144
- ' DEFAULT_ENV_VAULT_DIR="$HOME/Desktop/youmd-env-vault"',
145
- ' if [ -d "$DEFAULT_ENV_VAULT_DIR" ]; then',
146
- ' 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)"',
147
- ' if [ -n "$DETECTED_ENV_VAULT" ]; then',
148
- ' export YOUMD_ENV_VAULT="$DETECTED_ENV_VAULT"',
149
- ' echo "[you.md] using detected env vault: $YOUMD_ENV_VAULT"',
150
- " fi",
151
- " fi",
152
- "fi",
153
- 'if [ -n "${YOUMD_ENV_VAULT:-}" ]; then',
154
- ' if [ ! -f "$YOUMD_ENV_VAULT" ]; then',
155
- ' echo "[you.md] env vault path does not exist: $YOUMD_ENV_VAULT" >&2',
156
- " exit 1",
157
- " fi",
158
- ' if [ -z "${ENV_VAULT_PASS:-}" ] && command -v security >/dev/null 2>&1; then',
159
- ' KEYCHAIN_SERVICE="${YOUMD_ENV_VAULT_KEYCHAIN_SERVICE:-youmd-env-vault}"',
160
- ' if ENV_VAULT_PASS_FROM_KEYCHAIN="$(security find-generic-password -a "${USER:-${LOGNAME:-houston}}" -s "$KEYCHAIN_SERVICE" -w 2>/dev/null)"; then',
161
- ' export ENV_VAULT_PASS="$ENV_VAULT_PASS_FROM_KEYCHAIN"',
162
- ' unset ENV_VAULT_PASS_FROM_KEYCHAIN',
163
- ' echo "[you.md] loaded env-vault passphrase from macOS Keychain service: $KEYCHAIN_SERVICE"',
164
- " else",
165
- ' echo "[you.md] no env-vault Keychain item found; restore will prompt for the passphrase"',
166
- " fi",
167
- " fi",
168
- ' echo "[you.md] listing encrypted .env.local vault before restore"',
169
- ' youmd env restore "$YOUMD_ENV_VAULT" --root "$ROOT" --list',
170
- ' echo "[you.md] restoring encrypted .env.local vault"',
171
- ' youmd env restore "$YOUMD_ENV_VAULT" --root "$ROOT"',
172
- "else",
173
- ' echo "[you.md] env vault not restored yet"',
174
- ' echo "[you.md] On the old/source Mac, create the encrypted vault first:"',
175
- ' echo "youmd env backup --root ~/Desktop/CODE_2025 --out ~/Desktop/youmd-env-vault"',
176
- ' echo "[you.md] Move the generated env-vault-*.tar.enc file to this Mac, then rerun this command with:"',
177
- ' echo "YOUMD_ENV_VAULT=/path/to/env-vault-YYYYMMDDTHHMMZ.tar.enc YOUMD_REQUIRE_ENV_VAULT=1 <same command>"',
178
- ' echo "[you.md] Or restore manually after clone:"',
179
- ' echo "youmd env restore <vault> --root \\"$ROOT\\""',
180
- ' if [ "${YOUMD_REQUIRE_ENV_VAULT:-}" = "1" ]; then',
181
- ' echo "[you.md] strict proof requires YOUMD_ENV_VAULT; stopping before readiness is marked complete" >&2',
182
- " exit 1",
183
- " fi",
184
- "fi",
185
- 'echo "[you.md] rehydrating portfolio graph with local README/project-context/env-key evidence"',
186
- 'run_with_timeout "$HYDRATE_TIMEOUT" youmd project portfolio-hydrate --root "$ROOT" --days "$DAYS" --limit "$LIMIT" || true',
187
- 'echo "[you.md] auditing cloned project readiness"',
188
- 'youmd machine verify --root "$ROOT" --max-projects "$LIMIT" --write-report --sync-report || true',
189
- "FULL_PROJECT_SET_COMPLETE=0",
190
- 'EXPAND_TO_90="${YOUMD_EXPAND_TO_90_DAYS:-}"',
191
- 'if [ -z "$EXPAND_TO_90" ] && [ "${YOUMD_SKIP_90_DAY_EXPANSION_PROMPT:-}" != "1" ] && [ -t 0 ]; then',
192
- ' printf "\\n[you.md] expand to all active projects from the last ${EXPAND_DAYS} days before calling setup complete? [y/N] "',
193
- ' read -r EXPAND_TO_90',
194
- "fi",
195
- 'case "$EXPAND_TO_90" in',
196
- ' y|Y|yes|YES|1|true|TRUE)',
197
- ' echo "[you.md] expanding workspace to active ${EXPAND_DAYS}-day project set"',
198
- ' run_with_timeout "$HYDRATE_TIMEOUT" youmd project portfolio-hydrate --root "$ROOT" --days "$EXPAND_DAYS" --limit "$LIMIT" || true',
199
- ' EXPAND_PROJECT_ARGS=(--root "$ROOT" --days "$EXPAND_DAYS" "${RECENT_ONLY_ARGS[@]}")',
200
- ' if [ -n "${YOUMD_MAX_CLONE_PROJECTS:-}" ]; then',
201
- ' EXPAND_PROJECT_ARGS+=(--max-clone-projects "$YOUMD_MAX_CLONE_PROJECTS")',
202
- " fi",
203
- ' run_machine_projects_recent_only "${EXPAND_PROJECT_ARGS[@]}" --dry-run || true',
204
- ' run_machine_projects_recent_only "${EXPAND_PROJECT_ARGS[@]}"',
205
- ' run_with_timeout "$HYDRATE_TIMEOUT" youmd project portfolio-hydrate --root "$ROOT" --days "$EXPAND_DAYS" --limit "$LIMIT" || true',
206
- ' youmd machine verify --root "$ROOT" --max-projects "$LIMIT" --write-report --sync-report || true',
207
- " FULL_PROJECT_SET_COMPLETE=1",
208
- ' ;;',
209
- ' *)',
210
- ' echo "[you.md] stopped after the ${DAYS}-day active project setup; ${EXPAND_DAYS}-day expansion remains intentionally open."',
211
- ' ;;',
212
- "esac",
213
- 'if [ "${YOUMD_RUN_CHECKS:-}" = "1" ]; then',
214
- ' echo "[you.md] running bounded package checks"',
215
- ' youmd machine verify --root "$ROOT" --max-projects "$LIMIT" --run-checks --max-check-projects "${YOUMD_MAX_CHECK_PROJECTS:-8}" --check-timeout-ms "${YOUMD_CHECK_TIMEOUT_MS:-120000}" --write-report --sync-report || true',
216
- "else",
217
- ' echo "[you.md] bounded package checks skipped; set YOUMD_RUN_CHECKS=1 to run lint/typecheck/test/build caps"',
218
- "fi",
219
- 'if [ "${YOUMD_INSTALL_DEPS:-}" = "1" ] || [ "${YOUMD_PROBE_SERVERS:-}" = "1" ]; then',
220
- ' echo "[you.md] running bounded clean-host install/server proof"',
221
- ' VERIFY_ARGS=(--root "$ROOT" --max-projects "$LIMIT")',
222
- ' if [ "${YOUMD_INSTALL_DEPS:-}" = "1" ]; then',
223
- ' VERIFY_ARGS+=(--install-deps --max-install-projects "${YOUMD_MAX_INSTALL_PROJECTS:-4}" --install-timeout-ms "${YOUMD_INSTALL_TIMEOUT_MS:-180000}")',
224
- " fi",
225
- ' if [ "${YOUMD_PROBE_SERVERS:-}" = "1" ]; then',
226
- ' VERIFY_ARGS+=(--probe-servers --max-server-projects "${YOUMD_MAX_SERVER_PROJECTS:-3}" --server-timeout-ms "${YOUMD_SERVER_TIMEOUT_MS:-45000}" --server-start-port "${YOUMD_SERVER_START_PORT:-4310}")',
227
- " fi",
228
- ' youmd machine verify "${VERIFY_ARGS[@]}" --write-report --sync-report || true',
229
- "else",
230
- ' echo "[you.md] clean-host install/server proof skipped; set YOUMD_INSTALL_DEPS=1 and YOUMD_PROBE_SERVERS=1 to install deps and smoke-probe local dev servers"',
231
- "fi",
232
- 'echo "[you.md] installing resident identity/skillstack/project-context daemons"',
233
- "youmd stack daemon install || true",
234
- "youmd stack daemon status || true",
235
- "youmd status",
236
- 'if [ "$FULL_PROJECT_SET_COMPLETE" = "1" ]; then',
237
- ' echo "[you.md] fresh-machine full ${EXPAND_DAYS}-day project setup complete: $ROOT"',
238
- "else",
239
- ' echo "[you.md] fresh-machine ${DAYS}-day setup pass complete; ${EXPAND_DAYS}-day expansion is still open: $ROOT"',
240
- "fi",
241
- ].join("\n");
85
+ return `set -euo pipefail
86
+ 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"
87
+ ROOT="\${YOUMD_CODE_ROOT:-$HOME/Desktop/CODE_YOU}"
88
+ DAYS="\${YOUMD_ACTIVE_DAYS:-30}"
89
+ EXPAND_DAYS="\${YOUMD_EXPAND_ACTIVE_DAYS:-90}"
90
+ LIMIT="\${YOUMD_PROJECT_LIMIT:-80}"
91
+ HYDRATE_TIMEOUT="\${YOUMD_PORTFOLIO_HYDRATE_TIMEOUT_SECONDS:-180}"
92
+ MIN_YOUMD_VERSION="\${YOUMD_MIN_VERSION:-0.8.6}"
93
+ mkdir -p "$ROOT"
94
+
95
+ command_exists() { command -v "$1" >/dev/null 2>&1; }
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
+ }
133
+ run_with_timeout() {
134
+ seconds="$1"
135
+ shift
136
+ if command_exists gtimeout; then
137
+ gtimeout "$seconds" "$@"
138
+ elif command_exists timeout; then
139
+ timeout "$seconds" "$@"
140
+ else
141
+ "$@" &
142
+ pid=$!
143
+ ( sleep "$seconds"; if kill -0 "$pid" >/dev/null 2>&1; then echo "[you.md] timeout after \${seconds}s: $*" >&2; kill "$pid" >/dev/null 2>&1 || true; fi ) &
144
+ watcher=$!
145
+ wait "$pid"
146
+ status=$?
147
+ kill "$watcher" >/dev/null 2>&1 || true
148
+ wait "$watcher" 2>/dev/null || true
149
+ return "$status"
150
+ fi
151
+ }
152
+
153
+ bootstrap_prereqs() {
154
+ echo "[you.md] checking local prerequisites: Homebrew, Node 22/npm, git, gh, bun, pnpm"
155
+ if [ "$(uname -s 2>/dev/null || echo unknown)" = "Darwin" ] && ! command_exists brew; then
156
+ echo "[you.md] Homebrew missing; installing it first so the rest of setup can stay boring"
157
+ NONINTERACTIVE=1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" || true
158
+ fi
159
+ if [ -x /opt/homebrew/bin/brew ]; then eval "$(/opt/homebrew/bin/brew shellenv)" || true; fi
160
+ if [ -x /usr/local/bin/brew ]; then eval "$(/usr/local/bin/brew shellenv)" || true; fi
161
+ 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"
162
+
163
+ if command_exists brew; then
164
+ MAJOR="$(node_major)"
165
+ if ! command_exists node || [ "$MAJOR" -lt 20 ] || [ "$MAJOR" -ge 23 ]; then
166
+ echo "[you.md] installing Node 22 for modern Next/Convex projects"
167
+ brew install node@22 || brew install node || true
168
+ brew link --overwrite --force node@22 || true
169
+ fi
170
+ command_exists git || brew install git || true
171
+ command_exists gh || brew install gh || true
172
+ command_exists bun || brew install bun || brew install oven-sh/bun/bun || true
173
+ fi
174
+
175
+ 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"
176
+ command_exists corepack && corepack enable || true
177
+ if command_exists corepack && ! command_exists pnpm; then
178
+ corepack prepare pnpm@latest --activate || true
179
+ fi
180
+
181
+ for required in node npm git; do
182
+ if ! command_exists "$required"; then
183
+ echo "[you.md] required tool missing after bootstrap: $required" >&2
184
+ exit 1
185
+ fi
186
+ done
187
+ }
188
+
189
+ ensure_github_auth() {
190
+ if ! command_exists gh; then
191
+ echo "[you.md] GitHub CLI is missing, so private repo clone/setup cannot continue yet." >&2
192
+ return 1
193
+ fi
194
+ if gh auth status >/dev/null 2>&1; then
195
+ echo "[you.md] GitHub auth is ready"
196
+ return 0
197
+ fi
198
+ echo "[you.md] GitHub auth is required before private skill/project repos can clone."
199
+ if [ -t 0 ]; then
200
+ gh auth login -h github.com -p https -s repo || true
201
+ fi
202
+ if gh auth status >/dev/null 2>&1; then
203
+ echo "[you.md] GitHub auth is ready"
204
+ return 0
205
+ fi
206
+ echo "[you.md] GitHub auth still is not complete."
207
+ echo "[you.md] Open a normal Terminal on this Mac and run:"
208
+ echo " $(command -v gh || echo gh) auth login -h github.com -p https -s repo"
209
+ echo "[you.md] Then rerun this same setup prompt/command."
210
+ return 1
211
+ }
212
+
213
+ bootstrap_prereqs
214
+
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
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"
218
+ if ! command_exists youmd; then
219
+ echo "[you.md] youmd was installed but is not on PATH. Try a new Terminal, then rerun this command." >&2
220
+ exit 1
221
+ fi
222
+ ensure_youmd_min_version
223
+
224
+ if [ -n "\${YOUMD_API_KEY:-}" ]; then
225
+ echo "[you.md] logging in with bootstrap key"
226
+ youmd login --key "$YOUMD_API_KEY"
227
+ else
228
+ echo "[you.md] no YOUMD_API_KEY set; starting interactive login"
229
+ youmd login
230
+ fi
231
+
232
+ echo "[you.md] pulling identity bundle and syncing local brain"
233
+ youmd pull
234
+ youmd sync
235
+ youmd agent send --channel machine-sync --kind status "fresh machine \$(hostname) authenticated, pulled identity, and started setup" || true
236
+
237
+ echo "[you.md] installing resident realtime/identity/skillstack/project-context daemons early"
238
+ youmd stack daemon install || true
239
+ youmd stack daemon status || true
240
+ youmd agent send --channel machine-sync --kind status "fresh machine \$(hostname) installed resident realtime/skillstack daemons" || true
241
+
242
+ GITHUB_READY=0
243
+ if ensure_github_auth; then
244
+ GITHUB_READY=1
245
+ elif [ "\${YOUMD_REQUIRE_GITHUB_AUTH:-1}" = "1" ]; then
246
+ echo "[you.md] stopping after You.md identity/daemon setup because GitHub auth is required for private repos." >&2
247
+ exit 2
248
+ fi
249
+
250
+ echo "[you.md] restoring shared skills, stacks, and agent host config"
251
+ youmd machine setup || echo "[you.md] machine setup reported a warning; continuing to skills/MCP so the next run can self-heal"
252
+ youmd skill install all || true
253
+ youmd skill sync || true
254
+ youmd mcp --install claude --auto || true
255
+ youmd mcp --install codex --auto || true
256
+ youmd skill link claude || true
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
259
+
260
+ if [ "$GITHUB_READY" != "1" ]; then
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
263
+ exit 2
264
+ fi
265
+
266
+ RECENT_ONLY_ARGS=()
267
+ if youmd machine --help 2>/dev/null | grep -q -- "--recent-only"; then
268
+ RECENT_ONLY_ARGS=(--recent-only)
269
+ else
270
+ echo "[you.md] installed CLI does not expose --recent-only yet; using noninteractive no-to-older-projects fallback"
271
+ fi
272
+ run_machine_projects_recent_only() {
273
+ if [ "\${#RECENT_ONLY_ARGS[@]}" -gt 0 ]; then
274
+ youmd machine projects "$@"
275
+ else
276
+ youmd machine projects "$@" </dev/null
277
+ fi
278
+ }
279
+
280
+ echo "[you.md] hydrating portfolio graph from You.md/GitHub before the 30-day local clone pass"
281
+ run_with_timeout "$HYDRATE_TIMEOUT" youmd project portfolio-hydrate --root "$ROOT" --days "$DAYS" --limit "$LIMIT" || true
282
+ PROJECT_ARGS=(--root "$ROOT" --days "$DAYS" "\${RECENT_ONLY_ARGS[@]}")
283
+ if [ -n "\${YOUMD_MAX_CLONE_PROJECTS:-}" ]; then
284
+ PROJECT_ARGS+=(--max-clone-projects "$YOUMD_MAX_CLONE_PROJECTS")
285
+ fi
286
+ echo "[you.md] previewing graph-backed 30-day project setup plan (ACTIVE + Top Priority/Focusing only)"
287
+ run_machine_projects_recent_only "\${PROJECT_ARGS[@]}" --dry-run || true
288
+ echo "[you.md] creating code workspace and cloning ACTIVE + Top Priority/Focusing 30-day project repos"
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
291
+
292
+ echo "[you.md] checking encrypted env-vault tooling without printing secrets"
293
+ youmd env backup --root "$ROOT" --preflight || true
294
+ SECRET_VAULT_RESTORED=0
295
+ if [ -z "\${YOUMD_ENV_VAULT:-}" ] && [ "\${YOUMD_SECRET_VAULT_PULL:-1}" = "1" ]; then
296
+ SECRET_VAULT_DIR="\${YOUMD_SECRET_VAULT_DIR:-$HOME/.youmd/secret-vault}"
297
+ echo "[you.md] registering this Mac as a trusted Secret Vault device"
298
+ youmd env vault device-register || true
299
+ echo "[you.md] checking You.md Secret Vault for the latest encrypted env vault and trusted-device envelope"
300
+ if youmd env vault pull --out "$SECRET_VAULT_DIR" --restore --root "$ROOT" --map-existing --existing-only --skip-agent-auth; then
301
+ SECRET_VAULT_RESTORED=1
302
+ echo "[you.md] restored env vault through trusted-device Secret Vault"
303
+ youmd agent send --channel machine-sync --kind status "fresh machine \$(hostname) restored encrypted env vault through trusted-device Secret Vault" || true
304
+ else
305
+ echo "[you.md] account-backed Secret Vault restore not available yet; falling back to local/iCloud vault discovery"
306
+ echo "[you.md] if this Mac was just registered, run this on the source Mac: youmd env vault share"
307
+ fi
308
+ fi
309
+ if [ "$SECRET_VAULT_RESTORED" != "1" ] && [ -z "\${YOUMD_ENV_VAULT:-}" ]; then
310
+ 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
311
+ if [ -d "$DEFAULT_ENV_VAULT_DIR" ]; then
312
+ 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)"
313
+ if [ -n "$DETECTED_ENV_VAULT" ]; then
314
+ export YOUMD_ENV_VAULT="$DETECTED_ENV_VAULT"
315
+ echo "[you.md] using detected env vault: $YOUMD_ENV_VAULT"
316
+ break
317
+ fi
318
+ fi
319
+ done
320
+ fi
321
+ if [ "$SECRET_VAULT_RESTORED" = "1" ]; then
322
+ :
323
+ elif [ -n "\${YOUMD_ENV_VAULT:-}" ]; then
324
+ if [ ! -f "$YOUMD_ENV_VAULT" ]; then
325
+ echo "[you.md] env vault path does not exist: $YOUMD_ENV_VAULT" >&2
326
+ exit 1
327
+ fi
328
+ if [ -z "\${ENV_VAULT_PASS:-}" ] && command_exists security; then
329
+ KEYCHAIN_SERVICE="\${YOUMD_ENV_VAULT_KEYCHAIN_SERVICE:-youmd-env-vault}"
330
+ if ENV_VAULT_PASS_FROM_KEYCHAIN="$(security find-generic-password -a "\${USER:-\${LOGNAME:-houston}}" -s "$KEYCHAIN_SERVICE" -w 2>/dev/null)"; then
331
+ export ENV_VAULT_PASS="$ENV_VAULT_PASS_FROM_KEYCHAIN"
332
+ unset ENV_VAULT_PASS_FROM_KEYCHAIN
333
+ echo "[you.md] loaded env-vault passphrase from macOS Keychain service: $KEYCHAIN_SERVICE"
334
+ else
335
+ echo "[you.md] no env-vault Keychain item found; restore will prompt for the passphrase"
336
+ fi
337
+ fi
338
+ echo "[you.md] listing encrypted .env.local vault before restore"
339
+ youmd env restore "$YOUMD_ENV_VAULT" --root "$ROOT" --list --map-existing --existing-only --skip-agent-auth
340
+ echo "[you.md] restoring encrypted .env.local vault into existing cloned project dirs"
341
+ youmd env restore "$YOUMD_ENV_VAULT" --root "$ROOT" --map-existing --existing-only --skip-agent-auth
342
+ youmd agent send --channel machine-sync --kind status "fresh machine \$(hostname) restored encrypted env vault into existing project dirs" || true
343
+ else
344
+ echo "[you.md] env vault not restored yet"
345
+ echo "[you.md] On the old/source Mac, create the encrypted vault first:"
346
+ echo "youmd env vault push --root ~/Desktop/CODE_2025 --out ~/Desktop/youmd-env-vault"
347
+ echo "[you.md] Then share local decrypt access to registered trusted Macs:"
348
+ echo "youmd env vault share"
349
+ echo "[you.md] Or create a transferable local copy without account sync:"
350
+ echo "youmd env backup --root ~/Desktop/CODE_2025 --out ~/Desktop/youmd-env-vault"
351
+ echo "[you.md] The setup command also auto-detects vaults in local Desktop and iCloud Desktop: ~/Library/Mobile Documents/com~apple~CloudDocs/Desktop/youmd-env-vault"
352
+ echo "[you.md] Move the generated env-vault-*.tar.enc file to this Mac, then rerun this command with:"
353
+ echo "YOUMD_ENV_VAULT=/path/to/env-vault-YYYYMMDDTHHMMZ.tar.enc YOUMD_REQUIRE_ENV_VAULT=1 <same command>"
354
+ echo "[you.md] Or restore manually after clone:"
355
+ echo "youmd env restore <vault> --root \\"$ROOT\\" --map-existing --existing-only --skip-agent-auth"
356
+ if [ "\${YOUMD_REQUIRE_ENV_VAULT:-}" = "1" ]; then
357
+ echo "[you.md] strict proof requires Secret Vault restore or YOUMD_ENV_VAULT; stopping before readiness is marked complete" >&2
358
+ youmd agent send --channel machine-sync --kind status "fresh machine \$(hostname) stopped: strict env vault restore still required; source Mac may need youmd env vault share" || true
359
+ exit 1
360
+ fi
361
+ fi
362
+ echo "[you.md] rehydrating portfolio graph with local README/project-context/env-key evidence"
363
+ run_with_timeout "$HYDRATE_TIMEOUT" youmd project portfolio-hydrate --root "$ROOT" --days "$DAYS" --limit "$LIMIT" || true
364
+ echo "[you.md] auditing cloned project readiness"
365
+ youmd machine verify --root "$ROOT" --max-projects "$LIMIT" --write-report --sync-report || true
366
+ youmd agent send --channel machine-sync --kind status "fresh machine \$(hostname) synced machine readiness proof for $ROOT" || true
367
+ FULL_PROJECT_SET_COMPLETE=0
368
+ EXPAND_TO_90="\${YOUMD_EXPAND_TO_90_DAYS:-}"
369
+ if [ -z "$EXPAND_TO_90" ] && [ "\${YOUMD_SKIP_90_DAY_EXPANSION_PROMPT:-}" != "1" ] && [ -t 0 ]; then
370
+ printf "\\n[you.md] expand to all active projects from the last \${EXPAND_DAYS} days before calling setup complete? [y/N] "
371
+ read -r EXPAND_TO_90
372
+ fi
373
+ case "$EXPAND_TO_90" in
374
+ y|Y|yes|YES|1|true|TRUE)
375
+ echo "[you.md] expanding workspace to active \${EXPAND_DAYS}-day project set"
376
+ run_with_timeout "$HYDRATE_TIMEOUT" youmd project portfolio-hydrate --root "$ROOT" --days "$EXPAND_DAYS" --limit "$LIMIT" || true
377
+ EXPAND_PROJECT_ARGS=(--root "$ROOT" --days "$EXPAND_DAYS" "\${RECENT_ONLY_ARGS[@]}")
378
+ if [ -n "\${YOUMD_MAX_CLONE_PROJECTS:-}" ]; then
379
+ EXPAND_PROJECT_ARGS+=(--max-clone-projects "$YOUMD_MAX_CLONE_PROJECTS")
380
+ fi
381
+ run_machine_projects_recent_only "\${EXPAND_PROJECT_ARGS[@]}" --dry-run || true
382
+ run_machine_projects_recent_only "\${EXPAND_PROJECT_ARGS[@]}"
383
+ run_with_timeout "$HYDRATE_TIMEOUT" youmd project portfolio-hydrate --root "$ROOT" --days "$EXPAND_DAYS" --limit "$LIMIT" || true
384
+ youmd machine verify --root "$ROOT" --max-projects "$LIMIT" --write-report --sync-report || true
385
+ youmd agent send --channel machine-sync --kind status "fresh machine \$(hostname) expanded to active/focused \${EXPAND_DAYS}-day project set and synced proof" || true
386
+ FULL_PROJECT_SET_COMPLETE=1
387
+ ;;
388
+ *)
389
+ echo "[you.md] stopped after the \${DAYS}-day active project setup; \${EXPAND_DAYS}-day expansion remains intentionally open."
390
+ ;;
391
+ esac
392
+ if [ "\${YOUMD_RUN_CHECKS:-}" = "1" ]; then
393
+ echo "[you.md] running bounded package checks"
394
+ youmd machine verify --root "$ROOT" --max-projects "$LIMIT" --run-checks --max-check-projects "\${YOUMD_MAX_CHECK_PROJECTS:-8}" --check-timeout-ms "\${YOUMD_CHECK_TIMEOUT_MS:-120000}" --write-report --sync-report || true
395
+ else
396
+ echo "[you.md] bounded package checks skipped; set YOUMD_RUN_CHECKS=1 to run lint/typecheck/test/build caps"
397
+ fi
398
+ if [ "\${YOUMD_INSTALL_DEPS:-}" = "1" ] || [ "\${YOUMD_PROBE_SERVERS:-}" = "1" ]; then
399
+ echo "[you.md] running bounded clean-host install/server proof"
400
+ VERIFY_ARGS=(--root "$ROOT" --max-projects "$LIMIT")
401
+ if [ "\${YOUMD_INSTALL_DEPS:-}" = "1" ]; then
402
+ VERIFY_ARGS+=(--install-deps --max-install-projects "\${YOUMD_MAX_INSTALL_PROJECTS:-4}" --install-timeout-ms "\${YOUMD_INSTALL_TIMEOUT_MS:-180000}")
403
+ fi
404
+ if [ "\${YOUMD_PROBE_SERVERS:-}" = "1" ]; then
405
+ VERIFY_ARGS+=(--probe-servers --max-server-projects "\${YOUMD_MAX_SERVER_PROJECTS:-3}" --server-timeout-ms "\${YOUMD_SERVER_TIMEOUT_MS:-45000}" --server-start-port "\${YOUMD_SERVER_START_PORT:-4310}")
406
+ fi
407
+ youmd machine verify "\${VERIFY_ARGS[@]}" --write-report --sync-report || true
408
+ else
409
+ echo "[you.md] clean-host install/server proof skipped; set YOUMD_INSTALL_DEPS=1 and YOUMD_PROBE_SERVERS=1 to install deps and smoke-probe local dev servers"
410
+ fi
411
+ echo "[you.md] confirming resident realtime/identity/skillstack/project-context daemons"
412
+ youmd stack daemon install || true
413
+ youmd stack daemon status || true
414
+ youmd status
415
+ if [ "$FULL_PROJECT_SET_COMPLETE" = "1" ]; then
416
+ echo "[you.md] fresh-machine full \${EXPAND_DAYS}-day project setup complete: $ROOT"
417
+ youmd agent send --channel machine-sync --kind status "fresh machine \$(hostname) complete: full \${EXPAND_DAYS}-day active/focused setup at $ROOT" || true
418
+ else
419
+ echo "[you.md] fresh-machine \${DAYS}-day setup pass complete; \${EXPAND_DAYS}-day expansion is still open: $ROOT"
420
+ 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
421
+ fi`;
242
422
  }
243
423
  function buildFreshMachineBootstrapCommand(options = {}) {
244
424
  const assignments = [
245
425
  envAssignment("YOUMD_API_KEY", options.apiKey),
246
- envAssignment("YOUMD_CODE_ROOT", portableHomePath(options.root)),
426
+ envAssignment("YOUMD_CODE_ROOT", portableHomePath(options.root), { expandHome: true }),
247
427
  envAssignment("YOUMD_ACTIVE_DAYS", options.days ?? exports.DEFAULT_FRESH_MACHINE_DAYS),
248
428
  envAssignment("YOUMD_PROJECT_LIMIT", options.limit ?? exports.DEFAULT_FRESH_MACHINE_LIMIT),
249
429
  envAssignment("YOUMD_MAX_CLONE_PROJECTS", options.maxCloneProjects),
250
- envAssignment("YOUMD_ENV_VAULT", portableHomePath(options.envVaultPath)),
430
+ envAssignment("YOUMD_ENV_VAULT", portableHomePath(options.envVaultPath), { expandHome: true }),
251
431
  envAssignment("YOUMD_REQUIRE_ENV_VAULT", options.requireEnvVault ? "1" : undefined),
252
432
  ].filter((value) => Boolean(value));
253
- return `${assignments.join(" ")} bash -lc ${shellQuote(buildFreshMachineBootstrapScript())}`;
433
+ const pathPrefix = `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"`;
434
+ return `${[pathPrefix, ...assignments].join(" ")} bash -lc ${shellQuote(buildFreshMachineBootstrapScript())}`;
254
435
  }
255
436
  function buildFreshMachineBootstrapPrompt(options = {}) {
256
437
  const root = portableHomePath(options.root) ?? exports.DEFAULT_FRESH_MACHINE_ROOT;
@@ -270,6 +451,8 @@ function buildFreshMachineBootstrapPrompt(options = {}) {
270
451
  "",
271
452
  authLine,
272
453
  "",
454
+ "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 vault sharing/passphrase entry if the trusted-device envelope has not been created yet, npm OTP, OS permissions, or an explicit choice such as the 90-day expansion.",
455
+ "",
273
456
  "Exact setup command:",
274
457
  "",
275
458
  "```bash",
@@ -277,19 +460,24 @@ function buildFreshMachineBootstrapPrompt(options = {}) {
277
460
  "```",
278
461
  "",
279
462
  "What it will do:",
280
- "- install You.md from the curl runtime",
463
+ "- check/install the local prerequisites first: Homebrew, Node 22/npm, git, GitHub CLI, bun, and pnpm/corepack",
464
+ "- install You.md from the curl runtime and force the You.md/Homebrew/Node 22 paths into this setup shell",
281
465
  "- authenticate and pull/sync your identity bundle",
466
+ "- install resident realtime sync daemons early so identity/skill/project-context sync is not deferred until the end",
467
+ "- require GitHub CLI auth before private shared-skill/project repos clone; if browser auth fails inside Claude/Codex, it prints the exact Terminal command to run and stops cleanly",
282
468
  "- install/configure MCP for Claude Code and Codex",
283
- "- restore shared agent skills, stack config, Claude/Codex links, and resident sync daemons",
469
+ "- restore shared agent skills, stack config, Claude/Codex links, and agent host config",
470
+ "- 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",
471
+ "- 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",
284
472
  "- hydrate the portfolio graph from You.md + authenticated GitHub before cloning",
285
473
  `- preview the graph-backed plan, create ${root}, and clone only projects marked ACTIVE plus Top Priority/Focusing from the last ${days} days first`,
286
474
  `- 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`,
287
- "- check env-vault tooling, auto-detect the newest `~/Desktop/youmd-env-vault/env-vault-*` file if `YOUMD_ENV_VAULT` is not set, list the encrypted vault, try macOS Keychain service `youmd-env-vault` for the passphrase, restore only after the list passes, then rehydrate local project/env evidence",
475
+ "- 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`, otherwise auto-detect the newest local Desktop or iCloud Desktop `youmd-env-vault/env-vault-*` file if `YOUMD_ENV_VAULT` is not set, then rehydrate local project/env evidence",
288
476
  "- write and sync a secret-safe machine proof report, with optional bounded install/check/server proof flags",
289
477
  "- bound portfolio hydration with `YOUMD_PORTFOLIO_HYDRATE_TIMEOUT_SECONDS` so large restored roots do not wedge setup",
290
478
  "",
291
479
  `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.`,
292
- "Secret rule: .env.local values are never embedded here. On the old/source Mac, create a vault with `youmd env backup --root ~/Desktop/CODE_2025 --out ~/Desktop/youmd-env-vault`, move the generated `env-vault-*.tar.enc` file to `~/Desktop/youmd-env-vault/` on the new machine, then run this command. The command auto-detects the newest vault there; you can also override with `YOUMD_ENV_VAULT=/path/to/env-vault-*.tar.enc`. If macOS Keychain contains service `youmd-env-vault` for the current user, restore uses it automatically; otherwise it prompts. The restore path lists variable names/counts and target paths only, never values.",
480
+ "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. Local fallback: run `youmd env backup --root ~/Desktop/CODE_2025 --out ~/Desktop/youmd-env-vault`, move the generated `env-vault-*.tar.enc` file to `~/Desktop/youmd-env-vault/` or the iCloud Desktop `youmd-env-vault/` on the new machine, then run this command. The command checks Secret Vault first, then auto-detects the newest local vault; you can also override with `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.",
293
481
  "",
294
482
  "After the command finishes, report:",
295
483
  "- the `youmd status` sync state",