youmd 0.6.21 → 0.6.27

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 (218) hide show
  1. package/dist/commands/build.d.ts.map +1 -1
  2. package/dist/commands/build.js +0 -1
  3. package/dist/commands/build.js.map +1 -1
  4. package/dist/commands/chat.d.ts.map +1 -1
  5. package/dist/commands/chat.js +283 -184
  6. package/dist/commands/chat.js.map +1 -1
  7. package/dist/commands/export.d.ts +1 -0
  8. package/dist/commands/export.d.ts.map +1 -1
  9. package/dist/commands/export.js +5 -0
  10. package/dist/commands/export.js.map +1 -1
  11. package/dist/commands/init.d.ts.map +1 -1
  12. package/dist/commands/init.js +21 -1
  13. package/dist/commands/init.js.map +1 -1
  14. package/dist/commands/keys.d.ts.map +1 -1
  15. package/dist/commands/keys.js +3 -3
  16. package/dist/commands/keys.js.map +1 -1
  17. package/dist/commands/link.d.ts.map +1 -1
  18. package/dist/commands/link.js +3 -3
  19. package/dist/commands/link.js.map +1 -1
  20. package/dist/commands/login.d.ts +29 -0
  21. package/dist/commands/login.d.ts.map +1 -1
  22. package/dist/commands/login.js +256 -127
  23. package/dist/commands/login.js.map +1 -1
  24. package/dist/commands/logs.js +0 -1
  25. package/dist/commands/logs.js.map +1 -1
  26. package/dist/commands/mcp.d.ts +14 -0
  27. package/dist/commands/mcp.d.ts.map +1 -1
  28. package/dist/commands/mcp.js +284 -28
  29. package/dist/commands/mcp.js.map +1 -1
  30. package/dist/commands/okf.d.ts +12 -0
  31. package/dist/commands/okf.d.ts.map +1 -0
  32. package/dist/commands/okf.js +411 -0
  33. package/dist/commands/okf.js.map +1 -0
  34. package/dist/commands/private.d.ts.map +1 -1
  35. package/dist/commands/private.js +6 -5
  36. package/dist/commands/private.js.map +1 -1
  37. package/dist/commands/project.d.ts.map +1 -1
  38. package/dist/commands/project.js +9 -5
  39. package/dist/commands/project.js.map +1 -1
  40. package/dist/commands/publish.d.ts.map +1 -1
  41. package/dist/commands/publish.js +0 -1
  42. package/dist/commands/publish.js.map +1 -1
  43. package/dist/commands/pull.d.ts +24 -1
  44. package/dist/commands/pull.d.ts.map +1 -1
  45. package/dist/commands/pull.js +114 -14
  46. package/dist/commands/pull.js.map +1 -1
  47. package/dist/commands/push.d.ts +1 -0
  48. package/dist/commands/push.d.ts.map +1 -1
  49. package/dist/commands/push.js +33 -13
  50. package/dist/commands/push.js.map +1 -1
  51. package/dist/commands/register.d.ts +6 -0
  52. package/dist/commands/register.d.ts.map +1 -1
  53. package/dist/commands/register.js +179 -79
  54. package/dist/commands/register.js.map +1 -1
  55. package/dist/commands/skill.d.ts.map +1 -1
  56. package/dist/commands/skill.js +121 -50
  57. package/dist/commands/skill.js.map +1 -1
  58. package/dist/commands/stack.d.ts +16 -0
  59. package/dist/commands/stack.d.ts.map +1 -0
  60. package/dist/commands/stack.js +863 -0
  61. package/dist/commands/stack.js.map +1 -0
  62. package/dist/commands/status.d.ts.map +1 -1
  63. package/dist/commands/status.js +25 -5
  64. package/dist/commands/status.js.map +1 -1
  65. package/dist/commands/sync.d.ts +23 -0
  66. package/dist/commands/sync.d.ts.map +1 -1
  67. package/dist/commands/sync.js +193 -12
  68. package/dist/commands/sync.js.map +1 -1
  69. package/dist/commands/whoami.d.ts.map +1 -1
  70. package/dist/commands/whoami.js +21 -16
  71. package/dist/commands/whoami.js.map +1 -1
  72. package/dist/create.js +0 -0
  73. package/dist/index.js +64 -7
  74. package/dist/index.js.map +1 -1
  75. package/dist/lib/api.d.ts +127 -5
  76. package/dist/lib/api.d.ts.map +1 -1
  77. package/dist/lib/api.js +142 -5
  78. package/dist/lib/api.js.map +1 -1
  79. package/dist/lib/ascii.d.ts +1 -0
  80. package/dist/lib/ascii.d.ts.map +1 -1
  81. package/dist/lib/ascii.js +9 -26
  82. package/dist/lib/ascii.js.map +1 -1
  83. package/dist/lib/canonical-json.d.ts +8 -0
  84. package/dist/lib/canonical-json.d.ts.map +1 -0
  85. package/dist/lib/canonical-json.js +29 -0
  86. package/dist/lib/canonical-json.js.map +1 -0
  87. package/dist/lib/capability-router.d.ts +58 -0
  88. package/dist/lib/capability-router.d.ts.map +1 -0
  89. package/dist/lib/capability-router.js +54 -0
  90. package/dist/lib/capability-router.js.map +1 -0
  91. package/dist/lib/compiler.d.ts +32 -0
  92. package/dist/lib/compiler.d.ts.map +1 -1
  93. package/dist/lib/compiler.js +150 -0
  94. package/dist/lib/compiler.js.map +1 -1
  95. package/dist/lib/config.d.ts +71 -35
  96. package/dist/lib/config.d.ts.map +1 -1
  97. package/dist/lib/config.js +334 -124
  98. package/dist/lib/config.js.map +1 -1
  99. package/dist/lib/decompile.d.ts +6 -1
  100. package/dist/lib/decompile.d.ts.map +1 -1
  101. package/dist/lib/decompile.js +120 -11
  102. package/dist/lib/decompile.js.map +1 -1
  103. package/dist/lib/hash.d.ts.map +1 -1
  104. package/dist/lib/hash.js +2 -19
  105. package/dist/lib/hash.js.map +1 -1
  106. package/dist/lib/heartbeat.d.ts +38 -0
  107. package/dist/lib/heartbeat.d.ts.map +1 -0
  108. package/dist/lib/heartbeat.js +70 -0
  109. package/dist/lib/heartbeat.js.map +1 -0
  110. package/dist/lib/host-link.d.ts +123 -0
  111. package/dist/lib/host-link.d.ts.map +1 -0
  112. package/dist/lib/host-link.js +350 -0
  113. package/dist/lib/host-link.js.map +1 -0
  114. package/dist/lib/merge.d.ts +50 -0
  115. package/dist/lib/merge.d.ts.map +1 -0
  116. package/dist/lib/merge.js +167 -0
  117. package/dist/lib/merge.js.map +1 -0
  118. package/dist/lib/okf-bundle.d.ts +104 -0
  119. package/dist/lib/okf-bundle.d.ts.map +1 -0
  120. package/dist/lib/okf-bundle.js +473 -0
  121. package/dist/lib/okf-bundle.js.map +1 -0
  122. package/dist/lib/okf-health.d.ts +40 -0
  123. package/dist/lib/okf-health.d.ts.map +1 -0
  124. package/dist/lib/okf-health.js +152 -0
  125. package/dist/lib/okf-health.js.map +1 -0
  126. package/dist/lib/okf-stack.d.ts +47 -0
  127. package/dist/lib/okf-stack.d.ts.map +1 -0
  128. package/dist/lib/okf-stack.js +331 -0
  129. package/dist/lib/okf-stack.js.map +1 -0
  130. package/dist/lib/okf-view.d.ts +49 -0
  131. package/dist/lib/okf-view.d.ts.map +1 -0
  132. package/dist/lib/okf-view.js +197 -0
  133. package/dist/lib/okf-view.js.map +1 -0
  134. package/dist/lib/okf.d.ts +130 -0
  135. package/dist/lib/okf.d.ts.map +1 -0
  136. package/dist/lib/okf.js +263 -0
  137. package/dist/lib/okf.js.map +1 -0
  138. package/dist/lib/onboarding.d.ts +17 -0
  139. package/dist/lib/onboarding.d.ts.map +1 -1
  140. package/dist/lib/onboarding.js +224 -207
  141. package/dist/lib/onboarding.js.map +1 -1
  142. package/dist/lib/project.d.ts +5 -0
  143. package/dist/lib/project.d.ts.map +1 -1
  144. package/dist/lib/project.js +8 -0
  145. package/dist/lib/project.js.map +1 -1
  146. package/dist/lib/projectContext.d.ts +201 -0
  147. package/dist/lib/projectContext.d.ts.map +1 -0
  148. package/dist/lib/projectContext.js +597 -0
  149. package/dist/lib/projectContext.js.map +1 -0
  150. package/dist/lib/render.d.ts +38 -1
  151. package/dist/lib/render.d.ts.map +1 -1
  152. package/dist/lib/render.js +83 -18
  153. package/dist/lib/render.js.map +1 -1
  154. package/dist/lib/skill-catalog.d.ts.map +1 -1
  155. package/dist/lib/skill-catalog.js +22 -2
  156. package/dist/lib/skill-catalog.js.map +1 -1
  157. package/dist/lib/skills.d.ts +20 -5
  158. package/dist/lib/skills.d.ts.map +1 -1
  159. package/dist/lib/skills.js +116 -58
  160. package/dist/lib/skills.js.map +1 -1
  161. package/dist/lib/stackEval.d.ts +87 -0
  162. package/dist/lib/stackEval.d.ts.map +1 -0
  163. package/dist/lib/stackEval.js +233 -0
  164. package/dist/lib/stackEval.js.map +1 -0
  165. package/dist/lib/stackImprove.d.ts +49 -0
  166. package/dist/lib/stackImprove.d.ts.map +1 -0
  167. package/dist/lib/stackImprove.js +313 -0
  168. package/dist/lib/stackImprove.js.map +1 -0
  169. package/dist/lib/stackInstall.d.ts +59 -0
  170. package/dist/lib/stackInstall.d.ts.map +1 -0
  171. package/dist/lib/stackInstall.js +162 -0
  172. package/dist/lib/stackInstall.js.map +1 -0
  173. package/dist/lib/stackSafety.d.ts +126 -0
  174. package/dist/lib/stackSafety.d.ts.map +1 -0
  175. package/dist/lib/stackSafety.js +486 -0
  176. package/dist/lib/stackSafety.js.map +1 -0
  177. package/dist/lib/stackUpdate.d.ts +44 -0
  178. package/dist/lib/stackUpdate.d.ts.map +1 -0
  179. package/dist/lib/stackUpdate.js +256 -0
  180. package/dist/lib/stackUpdate.js.map +1 -0
  181. package/dist/lib/stream.d.ts +116 -0
  182. package/dist/lib/stream.d.ts.map +1 -0
  183. package/dist/lib/stream.js +368 -0
  184. package/dist/lib/stream.js.map +1 -0
  185. package/dist/lib/youstack.d.ts +219 -0
  186. package/dist/lib/youstack.d.ts.map +1 -0
  187. package/dist/lib/youstack.js +1049 -0
  188. package/dist/lib/youstack.js.map +1 -0
  189. package/dist/mcp/registry.d.ts +133 -0
  190. package/dist/mcp/registry.d.ts.map +1 -0
  191. package/dist/mcp/registry.js +833 -0
  192. package/dist/mcp/registry.js.map +1 -0
  193. package/dist/mcp/server.d.ts +106 -5
  194. package/dist/mcp/server.d.ts.map +1 -1
  195. package/dist/mcp/server.js +851 -498
  196. package/dist/mcp/server.js.map +1 -1
  197. package/dist/postinstall.js +11 -2
  198. package/dist/postinstall.js.map +1 -1
  199. package/dist/you.d.ts +1 -0
  200. package/dist/you.js +40 -4
  201. package/dist/you.js.map +1 -1
  202. package/examples/youstack-bamfstack-public/docs/quickstart.md +34 -0
  203. package/examples/youstack-bamfstack-public/prompts/creator-draft-starter.md +15 -0
  204. package/examples/youstack-bamfstack-public/skills/bamfstack-start/SKILL.md +36 -0
  205. package/examples/youstack-bamfstack-public/tests/smoke.md +19 -0
  206. package/examples/youstack-bamfstack-public/workflows/creator-growth-workflow.md +22 -0
  207. package/examples/youstack-bamfstack-public/youstack.json +172 -0
  208. package/examples/youstack-personal/docs/quickstart.md +10 -0
  209. package/examples/youstack-personal/skills/youstack-start/SKILL.md +9 -0
  210. package/examples/youstack-personal/tests/smoke.md +9 -0
  211. package/examples/youstack-personal/workflows/startup.md +7 -0
  212. package/examples/youstack-personal/youstack.json +123 -0
  213. package/package.json +3 -3
  214. package/skills/claude-md-generator.md +1 -1
  215. package/skills/meta-improve.md +8 -3
  216. package/skills/proactive-context-fill.md +1 -1
  217. package/skills/youstack-maintainer.md +128 -0
  218. package/skills/youstack-start.md +78 -0
@@ -0,0 +1,863 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.stackCommand = stackCommand;
40
+ const chalk_1 = __importDefault(require("chalk"));
41
+ const api_1 = require("../lib/api");
42
+ const projectContext_1 = require("../lib/projectContext");
43
+ const host_link_1 = require("../lib/host-link");
44
+ const youstack_1 = require("../lib/youstack");
45
+ const capability_router_1 = require("../lib/capability-router");
46
+ const stackEval_1 = require("../lib/stackEval");
47
+ const stackImprove_1 = require("../lib/stackImprove");
48
+ const stackUpdate_1 = require("../lib/stackUpdate");
49
+ const stackInstall_1 = require("../lib/stackInstall");
50
+ const heartbeat_1 = require("../lib/heartbeat");
51
+ const ACCENT = chalk_1.default.hex("#C46A3A");
52
+ const DIM = chalk_1.default.dim;
53
+ function printHelp() {
54
+ console.log("");
55
+ console.log(" " + chalk_1.default.bold("youmd stack") + DIM(" -- local YouStack manifest tools"));
56
+ console.log("");
57
+ console.log(" " + ACCENT("Commands"));
58
+ console.log(" " + chalk_1.default.cyan("inspect") + DIM(" Show the local stack manifest summary"));
59
+ console.log(" " + chalk_1.default.cyan("doctor") + DIM(" Run read-only stack health diagnostics"));
60
+ console.log(" " + chalk_1.default.cyan("smoke") + DIM(" Run read-only local manifest/file checks"));
61
+ console.log(" " + chalk_1.default.cyan("capabilities") + DIM(" List declared local capabilities"));
62
+ console.log(" " + chalk_1.default.cyan("route \"...\"") + DIM(" Pick the best local capability for a request"));
63
+ console.log(" " + chalk_1.default.cyan("link") + DIM(" Generate host adapter files from the manifest"));
64
+ console.log(" " + chalk_1.default.cyan("guard") + DIM(" Check safety contract (T0-T3) and capability consistency"));
65
+ console.log(" " + chalk_1.default.cyan("eval") + DIM(" Run golden-prompt eval suite (--init to scaffold)"));
66
+ console.log(" " + chalk_1.default.cyan("improve") + DIM(" Gather signals + write proposals to journal/ (--mode propose|auto_pr)"));
67
+ console.log(" " + chalk_1.default.cyan("update") + DIM(" Check for a newer upstream version (--apply to write it)"));
68
+ console.log(" " + chalk_1.default.cyan("install <user>/<slug>") + DIM(" Install a public stack from the registry"));
69
+ console.log(" " + chalk_1.default.cyan("proposals") + DIM(" List open maintainer proposals for your stacks"));
70
+ console.log(" " + chalk_1.default.cyan("proposals approve <id>") + DIM(" Approve a maintainer proposal"));
71
+ console.log(" " + chalk_1.default.cyan("proposals reject <id>") + DIM(" Reject a maintainer proposal"));
72
+ console.log(" " + chalk_1.default.cyan("consent") + DIM(" Show your brainScope consent settings"));
73
+ console.log(" " + chalk_1.default.cyan("consent grant <scope>") + DIM(" Grant a brainScope (consolidate|fleet_aggregate|journal_mine)"));
74
+ console.log(" " + chalk_1.default.cyan("consent revoke <scope>") + DIM(" Revoke a brainScope"));
75
+ console.log("");
76
+ console.log(" " + DIM("Options: ") + chalk_1.default.cyan("--path <manifest-or-dir>") + DIM(", ") + chalk_1.default.cyan("--hosts claude-code,codex,cursor") + DIM(", ") + chalk_1.default.cyan("--target <dir>") + DIM(", ") + chalk_1.default.cyan("--dry-run") + DIM(", ") + chalk_1.default.cyan("--verify") + DIM(", ") + chalk_1.default.cyan("--json") + DIM(", ") + chalk_1.default.cyan("--init") + DIM(", ") + chalk_1.default.cyan("--mode propose|auto_pr") + DIM(", ") + chalk_1.default.cyan("--apply") + DIM(", ") + chalk_1.default.cyan("--force") + DIM(", ") + chalk_1.default.cyan("--dir <path>"));
77
+ console.log("");
78
+ console.log(" " + DIM("Canonical layout: ") + chalk_1.default.cyan("stacks/<slug>/youstack.json") + DIM(" (legacy youstack.json, .you/, and youstacks/ still load)"));
79
+ console.log("");
80
+ }
81
+ function printValidation(validation) {
82
+ for (const warning of validation.warnings) {
83
+ console.log(" " + chalk_1.default.yellow("WARN") + " " + warning);
84
+ }
85
+ for (const error of validation.errors) {
86
+ console.log(" " + chalk_1.default.red("FAIL") + " " + error);
87
+ }
88
+ }
89
+ function capabilityLabel(capability) {
90
+ const mode = capability.localOnly ? "local" : capability.mcpTool || capability.apiEndpoint ? "api/mcp" : "mixed";
91
+ const policy = capability.mutationPolicy || "unspecified";
92
+ return `${capability.id} ${DIM(`[${mode}; ${policy}]`)}`;
93
+ }
94
+ async function stackCommand(subcommand, args = [], options = {}) {
95
+ const cmd = subcommand || "help";
96
+ if (cmd === "help" || cmd === "--help" || cmd === "-h") {
97
+ printHelp();
98
+ return;
99
+ }
100
+ // ── P9: stack install ────────────────────────────────────────────────────────
101
+ if (cmd === "install") {
102
+ const ref = args[0] ?? "";
103
+ const slash = ref.indexOf("/");
104
+ if (!ref || slash <= 0 || slash === ref.length - 1) {
105
+ console.log("");
106
+ console.log(chalk_1.default.yellow(" usage: youmd stack install <user>/<slug>"));
107
+ console.log(" " + DIM("example: youmd stack install houston/coding-stack"));
108
+ console.log("");
109
+ process.exitCode = 1;
110
+ return;
111
+ }
112
+ const user = ref.slice(0, slash);
113
+ const slug = ref.slice(slash + 1);
114
+ const { BrailleSpinner } = await Promise.resolve().then(() => __importStar(require("../lib/render")));
115
+ const spinner = new BrailleSpinner(`fetching ${ACCENT(ref)} from registry`);
116
+ spinner.start();
117
+ try {
118
+ const result = await (0, stackInstall_1.installStack)(user, slug, {
119
+ dir: options.dir,
120
+ force: options.force,
121
+ });
122
+ spinner.stop();
123
+ if (options.json) {
124
+ console.log(JSON.stringify({
125
+ slug: result.slug,
126
+ targetDir: result.targetDir,
127
+ filesWritten: result.filesWritten,
128
+ hostLinks: result.hostLinks,
129
+ }, null, 2));
130
+ return;
131
+ }
132
+ console.log("");
133
+ console.log(" " + ACCENT("youstack install") + " " + chalk_1.default.bold(ref));
134
+ console.log(" " + DIM("slug: ") + chalk_1.default.cyan(result.slug));
135
+ console.log(" " + DIM("dir: ") + result.targetDir);
136
+ console.log("");
137
+ for (const f of result.filesWritten) {
138
+ console.log(" " + chalk_1.default.green("WROTE") + " " + f);
139
+ }
140
+ if (result.hostLinks.length > 0) {
141
+ console.log("");
142
+ for (const link of result.hostLinks) {
143
+ console.log(" " + chalk_1.default.green("LINKED") + " " + link);
144
+ }
145
+ }
146
+ console.log("");
147
+ console.log(" " + chalk_1.default.green("installed.") + " " + DIM(`run \`youmd stack doctor --path ${result.targetDir}\` to validate.`));
148
+ console.log("");
149
+ }
150
+ catch (err) {
151
+ spinner.fail("install failed");
152
+ const e = err;
153
+ console.log("");
154
+ if (e.code === "not_found") {
155
+ console.log(chalk_1.default.red(" not found: ") + e.message);
156
+ }
157
+ else if (e.code === "conflict") {
158
+ console.log(chalk_1.default.red(" conflict: ") + e.message);
159
+ }
160
+ else if (e.code === "invalid_manifest") {
161
+ console.log(chalk_1.default.red(" invalid manifest: ") + e.message);
162
+ if (e.validationErrors) {
163
+ for (const ve of e.validationErrors) {
164
+ console.log(" " + DIM(ve));
165
+ }
166
+ }
167
+ }
168
+ else {
169
+ console.log(chalk_1.default.red(" error: ") + e.message);
170
+ }
171
+ console.log("");
172
+ process.exitCode = 1;
173
+ }
174
+ return;
175
+ }
176
+ // ── L26: stack proposals ─────────────────────────────────────────────────────
177
+ if (cmd === "proposals") {
178
+ const sub = args[0]; // "approve" | "reject" | undefined
179
+ const { BrailleSpinner } = await Promise.resolve().then(() => __importStar(require("../lib/render")));
180
+ if (sub === "approve" || sub === "reject") {
181
+ const id = args[1];
182
+ if (!id) {
183
+ console.log("");
184
+ console.log(chalk_1.default.yellow(` usage: youmd stack proposals ${sub} <id>`));
185
+ console.log("");
186
+ process.exitCode = 1;
187
+ return;
188
+ }
189
+ const decision = sub === "approve" ? "approved" : "rejected";
190
+ const spinner = new BrailleSpinner(`submitting ${sub} decision`);
191
+ spinner.start();
192
+ try {
193
+ const res = await (0, api_1.setProposalDecision)(id, decision);
194
+ spinner.stop();
195
+ if (!res.ok) {
196
+ const msg = (0, api_1.apiErrorMessage)(res.data) ?? `request failed (${res.status})`;
197
+ console.log("");
198
+ console.log(chalk_1.default.red(` proposals ${sub}: `) + msg);
199
+ console.log("");
200
+ process.exitCode = 1;
201
+ return;
202
+ }
203
+ console.log("");
204
+ console.log(" " + chalk_1.default.green(sub === "approve" ? "approved" : "rejected") + " proposal " + ACCENT(id));
205
+ console.log("");
206
+ }
207
+ catch (err) {
208
+ spinner.fail(`proposals ${sub} failed`);
209
+ console.log("");
210
+ console.log(chalk_1.default.red(" error: ") + (err instanceof Error ? err.message : String(err)));
211
+ console.log("");
212
+ process.exitCode = 1;
213
+ }
214
+ return;
215
+ }
216
+ // list
217
+ const spinner = new BrailleSpinner("fetching maintainer proposals");
218
+ spinner.start();
219
+ try {
220
+ const res = await (0, api_1.listMaintainerProposals)();
221
+ spinner.stop();
222
+ if (!res.ok) {
223
+ const msg = (0, api_1.apiErrorMessage)(res.data) ?? `request failed (${res.status})`;
224
+ console.log("");
225
+ console.log(chalk_1.default.red(" proposals: ") + msg);
226
+ console.log("");
227
+ process.exitCode = 1;
228
+ return;
229
+ }
230
+ const { proposals } = res.data;
231
+ console.log("");
232
+ if (!proposals || proposals.length === 0) {
233
+ console.log(" " + chalk_1.default.dim("no proposals — your stacks are clean"));
234
+ console.log("");
235
+ return;
236
+ }
237
+ console.log(" " + ACCENT("maintainer proposals") + DIM(` (${proposals.length})`));
238
+ console.log("");
239
+ const idW = 20, stackW = 16, skillW = 24, evW = 5, stateW = 10;
240
+ console.log(" " +
241
+ chalk_1.default.bold("id".padEnd(idW)) +
242
+ chalk_1.default.bold("stack".padEnd(stackW)) +
243
+ chalk_1.default.bold("skill".padEnd(skillW)) +
244
+ chalk_1.default.bold("ev".padEnd(evW)) +
245
+ chalk_1.default.bold("state".padEnd(stateW)));
246
+ console.log(" " + DIM("-".repeat(idW + stackW + skillW + evW + stateW)));
247
+ for (const p of proposals) {
248
+ const shortId = String(p.proposalId).slice(-12);
249
+ const stateColor = p.humanApprovalState === "approved" ? chalk_1.default.green :
250
+ p.humanApprovalState === "rejected" ? chalk_1.default.red :
251
+ chalk_1.default.dim;
252
+ console.log(" " +
253
+ chalk_1.default.cyan(shortId.padEnd(idW)) +
254
+ String(p.stackSlug).slice(0, stackW - 1).padEnd(stackW) +
255
+ String(p.skillName).slice(0, skillW - 1).padEnd(skillW) +
256
+ String(p.evidenceCount).padEnd(evW) +
257
+ stateColor(String(p.humanApprovalState).padEnd(stateW)));
258
+ }
259
+ console.log("");
260
+ console.log(" " + DIM("use `youmd stack proposals approve <id>` or `youmd stack proposals reject <id>`"));
261
+ console.log("");
262
+ }
263
+ catch (err) {
264
+ spinner.fail("proposals fetch failed");
265
+ console.log("");
266
+ console.log(chalk_1.default.red(" error: ") + (err instanceof Error ? err.message : String(err)));
267
+ console.log("");
268
+ process.exitCode = 1;
269
+ }
270
+ return;
271
+ }
272
+ // ── L26: stack consent ───────────────────────────────────────────────────────
273
+ if (cmd === "consent") {
274
+ const sub = args[0]; // "grant" | "revoke" | undefined
275
+ const { BrailleSpinner } = await Promise.resolve().then(() => __importStar(require("../lib/render")));
276
+ if (sub === "grant" || sub === "revoke") {
277
+ const scope = args[1];
278
+ if (!scope) {
279
+ console.log("");
280
+ console.log(chalk_1.default.yellow(` usage: youmd stack consent ${sub} <scope>`));
281
+ console.log(" " + DIM("scopes: consolidate, fleet_aggregate, journal_mine"));
282
+ console.log("");
283
+ process.exitCode = 1;
284
+ return;
285
+ }
286
+ const granted = sub === "grant";
287
+ const spinner = new BrailleSpinner(`${granted ? "granting" : "revoking"} ${scope}`);
288
+ spinner.start();
289
+ try {
290
+ const res = await (0, api_1.setBrainConsent)(scope, granted);
291
+ spinner.stop();
292
+ if (!res.ok) {
293
+ const msg = (0, api_1.apiErrorMessage)(res.data) ?? `request failed (${res.status})`;
294
+ console.log("");
295
+ console.log(chalk_1.default.red(` consent ${sub}: `) + msg);
296
+ console.log("");
297
+ process.exitCode = 1;
298
+ return;
299
+ }
300
+ console.log("");
301
+ console.log(" " +
302
+ (granted ? chalk_1.default.green("granted") : chalk_1.default.red("revoked")) +
303
+ " " + ACCENT(scope));
304
+ console.log("");
305
+ }
306
+ catch (err) {
307
+ spinner.fail(`consent ${sub} failed`);
308
+ console.log("");
309
+ console.log(chalk_1.default.red(" error: ") + (err instanceof Error ? err.message : String(err)));
310
+ console.log("");
311
+ process.exitCode = 1;
312
+ }
313
+ return;
314
+ }
315
+ // list
316
+ const spinner = new BrailleSpinner("fetching brain consent settings");
317
+ spinner.start();
318
+ try {
319
+ const res = await (0, api_1.listBrainConsent)();
320
+ spinner.stop();
321
+ if (!res.ok) {
322
+ const msg = (0, api_1.apiErrorMessage)(res.data) ?? `request failed (${res.status})`;
323
+ console.log("");
324
+ console.log(chalk_1.default.red(" consent: ") + msg);
325
+ console.log("");
326
+ process.exitCode = 1;
327
+ return;
328
+ }
329
+ const { consents } = res.data;
330
+ console.log("");
331
+ console.log(" " + ACCENT("brain consent settings"));
332
+ console.log("");
333
+ const scopeW = 22, grantedW = 10, explicitW = 12;
334
+ console.log(" " +
335
+ chalk_1.default.bold("scope".padEnd(scopeW)) +
336
+ chalk_1.default.bold("granted".padEnd(grantedW)) +
337
+ chalk_1.default.bold("explicit".padEnd(explicitW)));
338
+ console.log(" " + DIM("-".repeat(scopeW + grantedW + explicitW)));
339
+ for (const c of consents) {
340
+ const grantedStr = c.granted ? chalk_1.default.green("yes") : chalk_1.default.red("no");
341
+ const explicitStr = c.explicit ? chalk_1.default.cyan("yes") : chalk_1.default.dim("no (default)");
342
+ console.log(" " +
343
+ String(c.scope).padEnd(scopeW) +
344
+ (c.granted ? chalk_1.default.green("yes".padEnd(grantedW)) : chalk_1.default.red("no".padEnd(grantedW))) +
345
+ (c.explicit ? chalk_1.default.cyan("yes") : chalk_1.default.dim("no (default)")));
346
+ void grantedStr;
347
+ void explicitStr;
348
+ }
349
+ console.log("");
350
+ console.log(" " + DIM("use `youmd stack consent revoke <scope>` or `youmd stack consent grant <scope>`"));
351
+ console.log("");
352
+ }
353
+ catch (err) {
354
+ spinner.fail("consent fetch failed");
355
+ console.log("");
356
+ console.log(chalk_1.default.red(" error: ") + (err instanceof Error ? err.message : String(err)));
357
+ console.log("");
358
+ process.exitCode = 1;
359
+ }
360
+ return;
361
+ }
362
+ let loaded;
363
+ try {
364
+ loaded = (0, youstack_1.loadYouStackManifest)(options.path);
365
+ }
366
+ catch (error) {
367
+ console.log("");
368
+ console.log(chalk_1.default.red(" youmd stack: ") + (error instanceof Error ? error.message : String(error)));
369
+ console.log("");
370
+ process.exitCode = 1;
371
+ return;
372
+ }
373
+ if (cmd === "inspect") {
374
+ if (options.json) {
375
+ console.log(JSON.stringify(loaded, null, 2));
376
+ return;
377
+ }
378
+ const manifest = loaded.manifest;
379
+ console.log("");
380
+ console.log(" " + ACCENT("youstack") + " " + chalk_1.default.bold(manifest.name));
381
+ console.log(" " + DIM("slug: ") + chalk_1.default.cyan(manifest.slug));
382
+ if (manifest.domain)
383
+ console.log(" " + DIM("domain: ") + manifest.domain);
384
+ if (manifest.aliases?.length)
385
+ console.log(" " + DIM("aliases: ") + manifest.aliases.join(", "));
386
+ if (manifest.tags?.length)
387
+ console.log(" " + DIM("tags: ") + manifest.tags.join(", "));
388
+ console.log(" " + DIM("version: ") + manifest.version);
389
+ console.log(" " + DIM("visibility: ") + manifest.visibility);
390
+ console.log(" " + DIM("manifest: ") + loaded.manifestPath);
391
+ const readiness = (0, youstack_1.getYouStackReadiness)(loaded);
392
+ console.log(" " + DIM("readiness: ") + `${readiness.status} (${readiness.reason})`);
393
+ console.log("");
394
+ console.log(" " + DIM("files: ") + String(manifest.files?.length || 0));
395
+ console.log(" " + DIM("brain scopes: ") + String(manifest.brainScopes?.length || 0));
396
+ console.log(" " + DIM("capabilities: ") + String((0, youstack_1.getYouStackCapabilities)(manifest).length));
397
+ console.log(" " + DIM("adapters: ") + Object.keys(manifest.adapters || {}).join(", "));
398
+ console.log(" " + DIM("improvement: ") + (manifest.improvement?.mode || "not declared"));
399
+ console.log(" " + DIM("update: ") + (manifest.update?.channel || "not declared"));
400
+ console.log("");
401
+ printValidation(loaded.validation);
402
+ if (loaded.validation.ok) {
403
+ console.log(" " + chalk_1.default.green("OK") + " manifest schema is valid");
404
+ }
405
+ console.log("");
406
+ return;
407
+ }
408
+ if (cmd === "capabilities") {
409
+ const capabilities = (0, youstack_1.getYouStackCapabilities)(loaded.manifest);
410
+ const readiness = (0, youstack_1.getYouStackReadiness)(loaded);
411
+ if (options.json) {
412
+ console.log(JSON.stringify({ readiness, capabilities }, null, 2));
413
+ return;
414
+ }
415
+ console.log("");
416
+ console.log(" " + ACCENT("youstack capabilities") + DIM(` (${capabilities.length})`));
417
+ console.log(" " + DIM("readiness: ") + `${readiness.status} (${readiness.reason})`);
418
+ console.log("");
419
+ for (const capability of capabilities) {
420
+ console.log(" " + chalk_1.default.cyan(capabilityLabel(capability)));
421
+ if (capability.intent)
422
+ console.log(" " + DIM(capability.intent));
423
+ if (capability.requiredScopes?.length) {
424
+ console.log(" " + DIM("scopes: ") + capability.requiredScopes.join(", "));
425
+ }
426
+ }
427
+ console.log("");
428
+ return;
429
+ }
430
+ if (cmd === "doctor") {
431
+ const result = (0, youstack_1.runYouStackDoctor)(loaded);
432
+ if (options.json) {
433
+ console.log(JSON.stringify(result, null, 2));
434
+ if (!result.ok)
435
+ process.exitCode = 1;
436
+ return;
437
+ }
438
+ console.log("");
439
+ console.log(" " + ACCENT("youstack doctor") + DIM(" -- read-only diagnostics"));
440
+ console.log("");
441
+ for (const diagnostic of result.diagnostics) {
442
+ console.log(" " + chalk_1.default.cyan("INFO") + " " + diagnostic);
443
+ }
444
+ // P20: one dim line per actually-active shadowing (env over session,
445
+ // canonical stack over legacy, repo project-context over global overlay).
446
+ for (const shadow of (0, projectContext_1.detectShadowing)()) {
447
+ console.log(" " + DIM(`shadowed: ${shadow.message}`));
448
+ }
449
+ console.log("");
450
+ // P11: empirical Claude Code discovery gate — per-skill pass/fail for
451
+ // the SKILL.md files `youmd stack link` would emit for claude-code.
452
+ if (result.discovery.length > 0) {
453
+ for (const check of result.discovery) {
454
+ if (check.ok) {
455
+ console.log(" " + chalk_1.default.green("PASS") + " claude discovery: " + check.path);
456
+ }
457
+ else {
458
+ console.log(" " + chalk_1.default.red("FAIL") + " claude discovery: " + check.path);
459
+ for (const problem of check.problems) {
460
+ console.log(" " + DIM(problem));
461
+ }
462
+ }
463
+ }
464
+ console.log("");
465
+ }
466
+ for (const recommendation of result.recommendations) {
467
+ console.log(" " + ACCENT("NEXT") + " " + recommendation);
468
+ }
469
+ printValidation(result);
470
+ console.log("");
471
+ if (result.ok) {
472
+ console.log(" " + chalk_1.default.green("Doctor passed.") + " " + DIM("No brain data was modified, no connected tools were invoked, and no files were changed."));
473
+ }
474
+ else {
475
+ console.log(" " + chalk_1.default.red("Doctor failed.") + " " + DIM("Fix the manifest errors above and rerun."));
476
+ process.exitCode = 1;
477
+ }
478
+ // Heartbeat: append NEXT dim line when stack wants to improve.
479
+ try {
480
+ const signal = await (0, heartbeat_1.getHeartbeatSignal)();
481
+ if (signal.active) {
482
+ console.log(" " + DIM("NEXT: " + signal.message));
483
+ }
484
+ }
485
+ catch { /* advisory only — never break doctor */ }
486
+ console.log("");
487
+ return;
488
+ }
489
+ if (cmd === "route") {
490
+ const request = args.join(" ").trim();
491
+ if (!request) {
492
+ console.log("");
493
+ console.log(chalk_1.default.yellow(" usage: youmd stack route \"start this repo with my preferences\""));
494
+ console.log("");
495
+ process.exitCode = 1;
496
+ return;
497
+ }
498
+ const route = (0, youstack_1.routeYouStackRequest)(loaded.manifest, request);
499
+ // Resolve transport availability for the matched capability via the canonical router.
500
+ const transport = (0, capability_router_1.resolveCapability)(loaded.manifest, { capability: route.capability.id });
501
+ const readiness = (0, youstack_1.getYouStackReadiness)(loaded);
502
+ if (options.json) {
503
+ console.log(JSON.stringify({ readiness, ...route, transports: transport.transports }, null, 2));
504
+ return;
505
+ }
506
+ console.log("");
507
+ console.log(" " + ACCENT("route") + " " + chalk_1.default.cyan(route.capability.id));
508
+ console.log(" " + DIM("readiness: ") + `${readiness.status} (${readiness.reason})`);
509
+ console.log(" " + DIM("request: ") + request);
510
+ if (route.capability.intent) {
511
+ console.log(" " + DIM("intent: ") + route.capability.intent);
512
+ }
513
+ console.log(" " + DIM("policy: ") + (route.capability.mutationPolicy || "unspecified"));
514
+ const http = transport.transports.http ? chalk_1.default.green("yes") : chalk_1.default.dim("no");
515
+ const mcp = transport.transports.mcp ? chalk_1.default.green("yes") : chalk_1.default.dim("no");
516
+ console.log(" " + DIM("transports: ") + `http=${http} mcp=${mcp}`);
517
+ if (route.capability.skill)
518
+ console.log(" " + DIM("skill: ") + route.capability.skill);
519
+ if (route.capability.mcpTool)
520
+ console.log(" " + DIM("mcp: ") + route.capability.mcpTool);
521
+ if (route.capability.apiEndpoint)
522
+ console.log(" " + DIM("api: ") + route.capability.apiEndpoint);
523
+ console.log("");
524
+ return;
525
+ }
526
+ if (cmd === "smoke") {
527
+ const result = (0, youstack_1.runYouStackSmoke)(loaded);
528
+ const readiness = (0, youstack_1.getYouStackReadiness)(loaded);
529
+ if (options.json) {
530
+ console.log(JSON.stringify({ readiness, ...result }, null, 2));
531
+ if (!result.ok)
532
+ process.exitCode = 1;
533
+ return;
534
+ }
535
+ console.log("");
536
+ console.log(" " + ACCENT("youstack smoke") + DIM(" -- read-only"));
537
+ console.log(" " + DIM("readiness: ") + `${readiness.status} (${readiness.reason})`);
538
+ console.log("");
539
+ for (const check of result.checks) {
540
+ console.log(" " + chalk_1.default.green("OK") + " " + check);
541
+ }
542
+ printValidation(result);
543
+ console.log("");
544
+ if (result.ok) {
545
+ console.log(" " + chalk_1.default.green("Smoke passed.") + " " + DIM("No brain data was modified, no connected tools were invoked, and no files were changed."));
546
+ }
547
+ else {
548
+ console.log(" " + chalk_1.default.red("Smoke failed.") + " " + DIM("Fix the manifest errors above and rerun."));
549
+ process.exitCode = 1;
550
+ }
551
+ console.log("");
552
+ return;
553
+ }
554
+ if (cmd === "link") {
555
+ const hosts = options.hosts
556
+ ? options.hosts.split(",").map((host) => host.trim()).filter(Boolean)
557
+ : undefined;
558
+ let results;
559
+ try {
560
+ results = (0, youstack_1.linkYouStackAdapters)(loaded, {
561
+ hosts,
562
+ targetDir: options.target,
563
+ dryRun: options.dryRun,
564
+ });
565
+ }
566
+ catch (error) {
567
+ console.log("");
568
+ console.log(chalk_1.default.red(" link failed: ") + (error instanceof Error ? error.message : String(error)));
569
+ console.log("");
570
+ process.exitCode = 1;
571
+ return;
572
+ }
573
+ // P11 release gate: --verify checks every emitted SKILL.md against the
574
+ // Claude Code discovery contract and exits non-zero on failures.
575
+ let verification;
576
+ if (options.verify) {
577
+ verification = (0, host_link_1.verifySkillDiscovery)(results);
578
+ if (!verification.ok)
579
+ process.exitCode = 1;
580
+ }
581
+ if (options.json) {
582
+ console.log(JSON.stringify({ results, verification }, null, 2));
583
+ return;
584
+ }
585
+ console.log("");
586
+ console.log(" " + ACCENT("youstack link") + (options.dryRun ? DIM(" -- dry run") : ""));
587
+ console.log("");
588
+ for (const result of results) {
589
+ const status = result.wrote ? chalk_1.default.green("WROTE") : chalk_1.default.yellow("WOULD WRITE");
590
+ console.log(" " + status + " " + chalk_1.default.cyan(result.host) + DIM(" -> ") + result.targetPath);
591
+ }
592
+ console.log("");
593
+ if (verification) {
594
+ for (const check of verification.checks) {
595
+ if (check.ok) {
596
+ console.log(" " + chalk_1.default.green("PASS") + " skill discovery: " + check.path);
597
+ }
598
+ else {
599
+ console.log(" " + chalk_1.default.red("FAIL") + " skill discovery: " + check.path);
600
+ for (const problem of check.problems) {
601
+ console.log(" " + DIM(problem));
602
+ }
603
+ }
604
+ }
605
+ console.log("");
606
+ if (!verification.ok) {
607
+ console.log(" " + chalk_1.default.red("Verification failed.") + " " + DIM("Fix the SKILL.md issues above and rerun."));
608
+ console.log("");
609
+ return;
610
+ }
611
+ }
612
+ if (!options.dryRun) {
613
+ console.log(" " + chalk_1.default.green("Adapter files generated.") + " " + DIM("No brain data or connected tools were touched."));
614
+ console.log("");
615
+ }
616
+ return;
617
+ }
618
+ if (cmd === "guard") {
619
+ const guardResult = (0, youstack_1.runStackGuard)(loaded.manifest, loaded.manifestPath);
620
+ if (options.json) {
621
+ console.log(JSON.stringify(guardResult, null, 2));
622
+ if (!guardResult.ok)
623
+ process.exitCode = 1;
624
+ return;
625
+ }
626
+ console.log("");
627
+ console.log(" " + ACCENT("youstack guard") + DIM(` -- T0-T3 safety contract (${guardResult.tier})`));
628
+ console.log(" " + DIM("manifest: ") + loaded.manifestPath);
629
+ console.log("");
630
+ for (const check of guardResult.checks) {
631
+ if (check.status === "PASS") {
632
+ const inferNote = check.inferred
633
+ ? DIM(` (inferred from: ${check.inferredFrom.join(", ")})`)
634
+ : "";
635
+ console.log(" " + chalk_1.default.green("PASS") + " " + chalk_1.default.cyan(check.capability) + " — " + check.message + inferNote);
636
+ }
637
+ else {
638
+ const inferNote = check.inferred
639
+ ? DIM(` (inferred from: ${check.inferredFrom.join(", ")})`)
640
+ : "";
641
+ console.log(" " + chalk_1.default.red("VIOLATION") + " " + chalk_1.default.cyan(check.capability) + " — " + check.message + inferNote);
642
+ console.log(" " + DIM(`tier rule: ${check.tierRule}`));
643
+ }
644
+ }
645
+ if (guardResult.contractViolations.length > 0) {
646
+ console.log("");
647
+ console.log(" " + ACCENT("contract violations:"));
648
+ for (const violation of guardResult.contractViolations) {
649
+ console.log(" " + chalk_1.default.red("FAIL") + " " + violation.reason);
650
+ console.log(" " + DIM(`tier rule: ${violation.tierRule}`));
651
+ }
652
+ }
653
+ if (guardResult.warnings.length > 0) {
654
+ console.log("");
655
+ for (const warning of guardResult.warnings) {
656
+ console.log(" " + chalk_1.default.yellow("WARN") + " " + warning);
657
+ }
658
+ }
659
+ console.log("");
660
+ if (guardResult.ok) {
661
+ console.log(" " + chalk_1.default.green("Guard passed.") + " " +
662
+ DIM(`${guardResult.tier} contract is self-consistent and no inferred capabilities exceed the declared tier.`));
663
+ }
664
+ else {
665
+ console.log(" " + chalk_1.default.red("Guard failed.") + " " +
666
+ DIM("Fix the violations above and rerun `youmd stack guard`."));
667
+ process.exitCode = 1;
668
+ }
669
+ console.log("");
670
+ return;
671
+ }
672
+ if (cmd === "eval") {
673
+ if (options.init) {
674
+ // Write example golden.json
675
+ const golden = (0, stackEval_1.buildInitGoldenFile)(loaded.manifest);
676
+ const filePath = (0, stackEval_1.writeGoldenFile)(loaded.rootDir, golden);
677
+ if (options.json) {
678
+ console.log(JSON.stringify({ wrote: filePath, entries: golden.entries.length }, null, 2));
679
+ return;
680
+ }
681
+ console.log("");
682
+ console.log(" " + ACCENT("youstack eval --init"));
683
+ console.log(" " + chalk_1.default.green("WROTE") + " " + filePath);
684
+ console.log(" " + DIM(`${golden.entries.length} example entries. Edit to add real assertions, then run \`youmd stack eval\`.`));
685
+ console.log("");
686
+ return;
687
+ }
688
+ // Run the eval suite
689
+ let goldenFile;
690
+ try {
691
+ goldenFile = (0, stackEval_1.readGoldenFile)(loaded.rootDir);
692
+ }
693
+ catch (error) {
694
+ console.log("");
695
+ console.log(chalk_1.default.red(" eval: ") + (error instanceof Error ? error.message : String(error)));
696
+ console.log("");
697
+ process.exitCode = 1;
698
+ return;
699
+ }
700
+ const evalResults = (0, stackEval_1.runEval)(loaded.manifest, goldenFile);
701
+ const resultsPath = (0, stackEval_1.writeEvalResults)(loaded.rootDir, evalResults);
702
+ if (options.json) {
703
+ console.log(JSON.stringify(evalResults, null, 2));
704
+ if (evalResults.failures.length > 0)
705
+ process.exitCode = 1;
706
+ return;
707
+ }
708
+ console.log("");
709
+ console.log(" " + ACCENT("youstack eval") + DIM(` -- ${evalResults.total} prompts`));
710
+ console.log(" " + DIM("golden: ") + (0, stackEval_1.goldenFilePath)(loaded.rootDir));
711
+ console.log(" " + DIM("results: ") + resultsPath);
712
+ console.log("");
713
+ for (const entry of goldenFile.entries) {
714
+ const failure = evalResults.failures.find((f) => f.label === entry.label);
715
+ if (!failure) {
716
+ console.log(" " + chalk_1.default.green("PASS") + " " + entry.label);
717
+ }
718
+ else {
719
+ console.log(" " + ACCENT("FAIL") + " " + entry.label);
720
+ for (const diff of failure.diff) {
721
+ console.log(" " + DIM(diff));
722
+ }
723
+ console.log(" " + DIM(`routed to: ${failure.actual.routedTo}`));
724
+ }
725
+ }
726
+ console.log("");
727
+ const passCount = chalk_1.default.green(`${evalResults.passed} passed`);
728
+ const failCount = evalResults.failures.length > 0
729
+ ? ACCENT(`${evalResults.failures.length} failed`)
730
+ : chalk_1.default.dim("0 failed");
731
+ console.log(" " + passCount + DIM(" / ") + failCount + DIM(` of ${evalResults.total} total`));
732
+ console.log("");
733
+ if (evalResults.failures.length > 0) {
734
+ console.log(" " + chalk_1.default.red("Eval failed.") + " " + DIM("Fix routing assertions or update golden.json."));
735
+ console.log("");
736
+ process.exitCode = 1;
737
+ }
738
+ else {
739
+ console.log(" " + chalk_1.default.green("Eval passed.") + " " + DIM("All prompts routed as expected."));
740
+ console.log("");
741
+ }
742
+ return;
743
+ }
744
+ if (cmd === "improve") {
745
+ const rawMode = options.mode ?? "propose";
746
+ if (rawMode !== "propose" && rawMode !== "auto_pr") {
747
+ console.log("");
748
+ console.log(chalk_1.default.red(" stack improve: ") + `--mode must be "propose" or "auto_pr" (got: ${rawMode})`);
749
+ console.log("");
750
+ process.exitCode = 1;
751
+ return;
752
+ }
753
+ const improveMode = rawMode;
754
+ const result = (0, stackImprove_1.runStackImprove)(loaded.manifest, loaded.rootDir, improveMode);
755
+ if (options.json) {
756
+ console.log(JSON.stringify(result, null, 2));
757
+ if (result.refused)
758
+ process.exitCode = 1;
759
+ return;
760
+ }
761
+ console.log("");
762
+ console.log(" " + ACCENT("youstack improve") + DIM(` -- mode: ${result.mode}`));
763
+ console.log(" " + DIM("manifest: ") + loaded.manifestPath);
764
+ console.log("");
765
+ if (result.refused) {
766
+ console.log(" " + chalk_1.default.red("REFUSED") + " " + result.refused);
767
+ console.log("");
768
+ process.exitCode = 1;
769
+ return;
770
+ }
771
+ console.log(" " + DIM("journal: ") + result.journalPath);
772
+ if (result.appended) {
773
+ console.log(" " + DIM("(appended to existing entry — idempotent re-run)"));
774
+ }
775
+ else {
776
+ console.log(" " + chalk_1.default.green("WROTE") + " " + result.journalPath);
777
+ }
778
+ console.log("");
779
+ if (result.summary.signals.length > 0) {
780
+ console.log(" " + ACCENT("signals:"));
781
+ for (const sig of result.summary.signals) {
782
+ console.log(" " + chalk_1.default.cyan(sig.name) + DIM(" = ") + sig.value);
783
+ }
784
+ console.log("");
785
+ }
786
+ if (result.summary.proposals.length === 0) {
787
+ console.log(" " + chalk_1.default.green("no proposals") + DIM(" — stack looks healthy"));
788
+ }
789
+ else {
790
+ console.log(" " + ACCENT("proposals:"));
791
+ for (const p of result.summary.proposals) {
792
+ console.log(" " + chalk_1.default.cyan(p.id));
793
+ console.log(" " + p.description);
794
+ console.log(" " + DIM(p.rationale));
795
+ }
796
+ }
797
+ if (result.prUrl) {
798
+ console.log("");
799
+ if (result.prUrl === "no-gh") {
800
+ console.log(" " + chalk_1.default.yellow("gh CLI not found") + DIM(" — patch printed to journal only"));
801
+ }
802
+ else if (result.prUrl.startsWith("pr-failed:")) {
803
+ console.log(" " + chalk_1.default.yellow("PR creation failed:") + " " + result.prUrl.replace("pr-failed: ", ""));
804
+ }
805
+ else {
806
+ console.log(" " + chalk_1.default.green("PR opened:") + " " + chalk_1.default.cyan(result.prUrl));
807
+ }
808
+ }
809
+ console.log("");
810
+ return;
811
+ }
812
+ // ── L17: stack update ───────────────────────────────────────────────────────
813
+ if (cmd === "update") {
814
+ const info = await (0, stackUpdate_1.checkStackUpdate)(loaded);
815
+ if (options.json) {
816
+ console.log(JSON.stringify(info, null, 2));
817
+ return;
818
+ }
819
+ console.log("");
820
+ console.log(" " + ACCENT("youstack update"));
821
+ console.log(" " + DIM("manifest: ") + loaded.manifestPath);
822
+ console.log("");
823
+ console.log(" " + DIM("current: ") + info.currentVersion);
824
+ console.log(" " + DIM("latest: ") + (info.latestVersion ?? DIM("unknown")));
825
+ console.log(" " + DIM("source: ") + info.source);
826
+ console.log("");
827
+ console.log(" " + (info.updateAvailable ? chalk_1.default.green("update available") : chalk_1.default.dim("up to date")));
828
+ if (info.changelogHint) {
829
+ console.log(" " + DIM("hint: ") + info.changelogHint);
830
+ }
831
+ console.log("");
832
+ if (options.apply) {
833
+ if (!info.updateAvailable) {
834
+ console.log(" " + DIM("nothing to apply — already at latest"));
835
+ console.log("");
836
+ return;
837
+ }
838
+ const applyResult = await (0, stackUpdate_1.applyStackUpdate)(loaded);
839
+ if (applyResult.error) {
840
+ console.log(" " + chalk_1.default.red("apply failed: ") + applyResult.error);
841
+ console.log("");
842
+ process.exitCode = 1;
843
+ return;
844
+ }
845
+ for (const wrote of applyResult.wrote) {
846
+ console.log(" " + chalk_1.default.green("WROTE") + " " + wrote);
847
+ }
848
+ console.log("");
849
+ console.log(" " + chalk_1.default.green("applied.") + " " + DIM("re-run `youmd stack doctor` to validate the new manifest."));
850
+ console.log("");
851
+ }
852
+ else if (info.updateAvailable) {
853
+ console.log(" " + DIM("run `youmd stack update --apply` to write the new manifest."));
854
+ console.log("");
855
+ }
856
+ return;
857
+ }
858
+ console.log("");
859
+ console.log(chalk_1.default.yellow(` unknown stack command: ${cmd}`));
860
+ printHelp();
861
+ process.exitCode = 1;
862
+ }
863
+ //# sourceMappingURL=stack.js.map