@uluops/setup 0.2.0 → 0.6.0

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 (253) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +109 -89
  3. package/assets/auto-tracker-save.mjs +142 -0
  4. package/assets/claude-code/agents/anxiety-reader-agent.md +464 -0
  5. package/assets/{agents → claude-code/agents}/api-contract-validator-agent.md +9 -228
  6. package/assets/{agents → claude-code/agents}/aristotle-analyst-agent.md +51 -4
  7. package/assets/{agents → claude-code/agents}/aristotle-explorer-agent.md +6 -2
  8. package/assets/{agents → claude-code/agents}/aristotle-forecaster-agent.md +15 -230
  9. package/assets/{agents → claude-code/agents}/aristotle-validator-agent.md +12 -252
  10. package/assets/{agents → claude-code/agents}/assumption-excavator-agent.md +21 -247
  11. package/assets/{agents → claude-code/agents}/code-auditor-agent.md +12 -255
  12. package/assets/{agents → claude-code/agents}/code-optimizer-agent.md +15 -236
  13. package/assets/{agents → claude-code/agents}/code-validator-agent.md +31 -300
  14. package/assets/claude-code/agents/docs-validator-agent.md +472 -0
  15. package/assets/{agents → claude-code/agents}/frontend-validator-agent.md +15 -258
  16. package/assets/{agents → claude-code/agents}/mcp-validator-agent.md +8 -252
  17. package/assets/{agents → claude-code/agents}/pre-implementation-architect-agent.md +8 -224
  18. package/assets/{agents → claude-code/agents}/prompt-engineer-agent.md +57 -290
  19. package/assets/{agents → claude-code/agents}/prompt-pattern-analyzer-agent.md +10 -225
  20. package/assets/{agents → claude-code/agents}/prompt-quality-validator-agent.md +11 -249
  21. package/assets/{agents → claude-code/agents}/public-interface-validator-agent.md +15 -268
  22. package/assets/claude-code/agents/release-readiness-agent.md +495 -0
  23. package/assets/{agents → claude-code/agents}/security-analyst-agent.md +236 -480
  24. package/assets/{agents → claude-code/agents}/test-architect-agent.md +16 -259
  25. package/assets/{agents → claude-code/agents}/type-safety-validator-agent.md +23 -266
  26. package/assets/{agents → claude-code/agents}/workflow-synthesis-agent.md +23 -226
  27. package/assets/claude-code/commands/agents/anxiety-reader.md +157 -0
  28. package/assets/{commands → claude-code/commands}/agents/api-contract.md +156 -135
  29. package/assets/{commands → claude-code/commands}/agents/architect.md +156 -135
  30. package/assets/claude-code/commands/agents/aristotle-analyst.md +157 -0
  31. package/assets/claude-code/commands/agents/aristotle-explorer.md +157 -0
  32. package/assets/claude-code/commands/agents/aristotle-forecaster.md +157 -0
  33. package/assets/claude-code/commands/agents/aristotle-validator.md +157 -0
  34. package/assets/{commands → claude-code/commands}/agents/assumption-excavator.md +49 -6
  35. package/assets/{commands → claude-code/commands}/agents/audit.md +156 -136
  36. package/assets/{commands → claude-code/commands}/agents/docs-validate.md +156 -133
  37. package/assets/{commands → claude-code/commands}/agents/frontend.md +156 -135
  38. package/assets/{commands → claude-code/commands}/agents/mcp-validate.md +156 -136
  39. package/assets/{commands → claude-code/commands}/agents/optimize.md +156 -133
  40. package/assets/{commands → claude-code/commands}/agents/pattern-analyzer.md +150 -126
  41. package/assets/{commands → claude-code/commands}/agents/prompt-quality.md +155 -134
  42. package/assets/claude-code/commands/agents/prompt-validate.md +155 -0
  43. package/assets/{commands → claude-code/commands}/agents/public-interface.md +156 -134
  44. package/assets/{commands → claude-code/commands}/agents/release.md +156 -135
  45. package/assets/{commands → claude-code/commands}/agents/security.md +156 -137
  46. package/assets/{commands → claude-code/commands}/agents/test-review.md +156 -136
  47. package/assets/{commands → claude-code/commands}/agents/type-safety.md +156 -135
  48. package/assets/{commands → claude-code/commands}/agents/validate.md +156 -134
  49. package/assets/claude-code/commands/agents/workflow-synthesis.md +157 -0
  50. package/assets/claude-code/commands/pipelines/aristotle.md +143 -0
  51. package/assets/claude-code/commands/pipelines/ship.md +188 -0
  52. package/assets/claude-code/commands/workflows/post-implementation.md +60 -0
  53. package/assets/claude-code/commands/workflows/pre-implementation.md +46 -0
  54. package/assets/claude-code/commands/workflows/prompt-audit.md +44 -0
  55. package/assets/codex/agents/anxiety-reader-agent.toml +462 -0
  56. package/assets/codex/agents/api-contract-validator-agent.toml +738 -0
  57. package/assets/codex/agents/aristotle-analyst-agent.toml +750 -0
  58. package/assets/codex/agents/aristotle-explorer-agent.toml +155 -0
  59. package/assets/codex/agents/aristotle-forecaster-agent.toml +449 -0
  60. package/assets/codex/agents/aristotle-validator-agent.toml +424 -0
  61. package/assets/codex/agents/assumption-excavator-agent.toml +1126 -0
  62. package/assets/codex/agents/code-auditor-agent.toml +815 -0
  63. package/assets/codex/agents/code-optimizer-agent.toml +652 -0
  64. package/assets/codex/agents/code-validator-agent.toml +573 -0
  65. package/assets/codex/agents/docs-validator-agent.toml +468 -0
  66. package/assets/codex/agents/frontend-validator-agent.toml +598 -0
  67. package/assets/codex/agents/mcp-validator-agent.toml +580 -0
  68. package/assets/codex/agents/pre-implementation-architect-agent.toml +817 -0
  69. package/assets/codex/agents/prompt-engineer-agent.toml +922 -0
  70. package/assets/codex/agents/prompt-pattern-analyzer-agent.toml +689 -0
  71. package/assets/codex/agents/prompt-quality-validator-agent.toml +777 -0
  72. package/assets/codex/agents/public-interface-validator-agent.toml +695 -0
  73. package/assets/codex/agents/release-readiness-agent.toml +491 -0
  74. package/assets/codex/agents/security-analyst-agent.toml +847 -0
  75. package/assets/codex/agents/test-architect-agent.toml +615 -0
  76. package/assets/codex/agents/type-safety-validator-agent.toml +686 -0
  77. package/assets/codex/agents/workflow-synthesis-agent.toml +631 -0
  78. package/assets/gemini-cli/agents/anxiety-reader-agent.md +470 -0
  79. package/assets/gemini-cli/agents/api-contract-validator-agent.md +747 -0
  80. package/assets/gemini-cli/agents/aristotle-analyst-agent.md +758 -0
  81. package/assets/gemini-cli/agents/aristotle-explorer-agent.md +163 -0
  82. package/assets/gemini-cli/agents/aristotle-forecaster-agent.md +457 -0
  83. package/assets/gemini-cli/agents/aristotle-validator-agent.md +432 -0
  84. package/assets/gemini-cli/agents/assumption-excavator-agent.md +1134 -0
  85. package/assets/gemini-cli/agents/code-auditor-agent.md +827 -0
  86. package/assets/gemini-cli/agents/code-optimizer-agent.md +661 -0
  87. package/assets/gemini-cli/agents/code-validator-agent.md +582 -0
  88. package/assets/gemini-cli/agents/docs-validator-agent.md +477 -0
  89. package/assets/gemini-cli/agents/frontend-validator-agent.md +610 -0
  90. package/assets/gemini-cli/agents/mcp-validator-agent.md +589 -0
  91. package/assets/gemini-cli/agents/pre-implementation-architect-agent.md +826 -0
  92. package/assets/gemini-cli/agents/prompt-engineer-agent.md +931 -0
  93. package/assets/gemini-cli/agents/prompt-pattern-analyzer-agent.md +698 -0
  94. package/assets/gemini-cli/agents/prompt-quality-validator-agent.md +786 -0
  95. package/assets/gemini-cli/agents/public-interface-validator-agent.md +707 -0
  96. package/assets/gemini-cli/agents/release-readiness-agent.md +500 -0
  97. package/assets/gemini-cli/agents/security-analyst-agent.md +859 -0
  98. package/assets/gemini-cli/agents/test-architect-agent.md +624 -0
  99. package/assets/gemini-cli/agents/type-safety-validator-agent.md +695 -0
  100. package/assets/gemini-cli/agents/workflow-synthesis-agent.md +639 -0
  101. package/assets/gemini-cli/commands/agents/anxiety-reader.toml +155 -0
  102. package/assets/gemini-cli/commands/agents/api-contract.toml +154 -0
  103. package/assets/gemini-cli/commands/agents/architect.toml +154 -0
  104. package/assets/gemini-cli/commands/agents/aristotle-analyst.toml +155 -0
  105. package/assets/gemini-cli/commands/agents/aristotle-explorer.toml +155 -0
  106. package/assets/gemini-cli/commands/agents/aristotle-forecaster.toml +155 -0
  107. package/assets/gemini-cli/commands/agents/aristotle-validator.toml +155 -0
  108. package/assets/gemini-cli/commands/agents/assumption-excavator.toml +155 -0
  109. package/assets/gemini-cli/commands/agents/audit.toml +154 -0
  110. package/assets/gemini-cli/commands/agents/docs-validate.toml +154 -0
  111. package/assets/gemini-cli/commands/agents/frontend.toml +154 -0
  112. package/assets/gemini-cli/commands/agents/mcp-validate.toml +154 -0
  113. package/assets/gemini-cli/commands/agents/optimize.toml +154 -0
  114. package/assets/gemini-cli/commands/agents/pattern-analyzer.toml +148 -0
  115. package/assets/gemini-cli/commands/agents/prompt-quality.toml +153 -0
  116. package/assets/gemini-cli/commands/agents/prompt-validate.toml +153 -0
  117. package/assets/gemini-cli/commands/agents/public-interface.toml +154 -0
  118. package/assets/gemini-cli/commands/agents/release.toml +154 -0
  119. package/assets/gemini-cli/commands/agents/security.toml +154 -0
  120. package/assets/gemini-cli/commands/agents/test-review.toml +154 -0
  121. package/assets/gemini-cli/commands/agents/type-safety.toml +154 -0
  122. package/assets/gemini-cli/commands/agents/validate.toml +154 -0
  123. package/assets/gemini-cli/commands/agents/workflow-synthesis.toml +155 -0
  124. package/assets/gemini-cli/commands/pipelines/aristotle.toml +139 -0
  125. package/assets/gemini-cli/commands/pipelines/ship.toml +184 -0
  126. package/assets/gemini-cli/commands/workflows/post-implementation.toml +56 -0
  127. package/assets/gemini-cli/commands/workflows/pre-implementation.toml +42 -0
  128. package/assets/gemini-cli/commands/workflows/prompt-audit.toml +40 -0
  129. package/assets/opencode/agents/anxiety-reader-agent.md +472 -0
  130. package/assets/opencode/agents/api-contract-validator-agent.md +749 -0
  131. package/assets/opencode/agents/aristotle-analyst-agent.md +760 -0
  132. package/assets/opencode/agents/aristotle-explorer-agent.md +164 -0
  133. package/assets/opencode/agents/aristotle-forecaster-agent.md +459 -0
  134. package/assets/opencode/agents/aristotle-validator-agent.md +434 -0
  135. package/assets/opencode/agents/assumption-excavator-agent.md +1136 -0
  136. package/assets/opencode/agents/code-auditor-agent.md +826 -0
  137. package/assets/opencode/agents/code-optimizer-agent.md +663 -0
  138. package/assets/opencode/agents/code-validator-agent.md +584 -0
  139. package/assets/opencode/agents/docs-validator-agent.md +479 -0
  140. package/assets/opencode/agents/frontend-validator-agent.md +609 -0
  141. package/assets/opencode/agents/mcp-validator-agent.md +591 -0
  142. package/assets/opencode/agents/pre-implementation-architect-agent.md +828 -0
  143. package/assets/opencode/agents/prompt-engineer-agent.md +933 -0
  144. package/assets/opencode/agents/prompt-pattern-analyzer-agent.md +700 -0
  145. package/assets/opencode/agents/prompt-quality-validator-agent.md +788 -0
  146. package/assets/opencode/agents/public-interface-validator-agent.md +706 -0
  147. package/assets/opencode/agents/release-readiness-agent.md +502 -0
  148. package/assets/opencode/agents/security-analyst-agent.md +858 -0
  149. package/assets/opencode/agents/test-architect-agent.md +626 -0
  150. package/assets/opencode/agents/type-safety-validator-agent.md +697 -0
  151. package/assets/opencode/agents/workflow-synthesis-agent.md +641 -0
  152. package/dist/cli.js +22 -380
  153. package/dist/commands/helpers.d.ts +73 -0
  154. package/dist/commands/helpers.js +274 -0
  155. package/dist/commands/setup.d.ts +13 -0
  156. package/dist/commands/setup.js +93 -0
  157. package/dist/commands/uninstall.d.ts +3 -0
  158. package/dist/commands/uninstall.js +126 -0
  159. package/dist/commands/verify.d.ts +1 -0
  160. package/dist/commands/verify.js +28 -0
  161. package/dist/harnesses/claude-code.d.ts +8 -0
  162. package/dist/harnesses/claude-code.js +74 -0
  163. package/dist/harnesses/codex.d.ts +15 -0
  164. package/dist/harnesses/codex.js +54 -0
  165. package/dist/harnesses/gemini-cli.d.ts +12 -0
  166. package/dist/harnesses/gemini-cli.js +80 -0
  167. package/dist/harnesses/index.d.ts +27 -0
  168. package/dist/harnesses/index.js +54 -0
  169. package/dist/harnesses/opencode.d.ts +14 -0
  170. package/dist/harnesses/opencode.js +139 -0
  171. package/dist/harnesses/types.d.ts +106 -0
  172. package/dist/harnesses/types.js +26 -0
  173. package/dist/lib/agent-transform.d.ts +12 -0
  174. package/dist/lib/agent-transform.js +129 -0
  175. package/dist/lib/asset-catalog.d.ts +9 -0
  176. package/dist/lib/asset-catalog.js +56 -0
  177. package/dist/lib/atomic-write.d.ts +11 -0
  178. package/dist/lib/atomic-write.js +28 -0
  179. package/dist/lib/config-merger.d.ts +9 -2
  180. package/dist/lib/config-merger.js +44 -7
  181. package/dist/lib/display.d.ts +14 -0
  182. package/dist/lib/display.js +66 -0
  183. package/dist/lib/file-ops.d.ts +11 -0
  184. package/dist/lib/file-ops.js +40 -4
  185. package/dist/lib/hash.d.ts +1 -0
  186. package/dist/lib/hash.js +2 -1
  187. package/dist/lib/health.d.ts +2 -0
  188. package/dist/lib/health.js +10 -0
  189. package/dist/lib/manifest.d.ts +51 -5
  190. package/dist/lib/manifest.js +146 -13
  191. package/dist/lib/paths.d.ts +30 -3
  192. package/dist/lib/paths.js +98 -12
  193. package/dist/lib/settings-merger.d.ts +31 -8
  194. package/dist/lib/settings-merger.js +87 -24
  195. package/dist/lib/version.d.ts +2 -0
  196. package/dist/lib/version.js +10 -0
  197. package/dist/steps/agents.d.ts +4 -1
  198. package/dist/steps/agents.js +48 -9
  199. package/dist/steps/auth.js +26 -10
  200. package/dist/steps/cli.d.ts +53 -0
  201. package/dist/steps/cli.js +90 -0
  202. package/dist/steps/commands.d.ts +6 -1
  203. package/dist/steps/commands.js +36 -9
  204. package/dist/steps/detect.d.ts +3 -0
  205. package/dist/steps/detect.js +11 -0
  206. package/dist/steps/mcp.d.ts +6 -2
  207. package/dist/steps/mcp.js +39 -22
  208. package/dist/steps/metrics.d.ts +26 -10
  209. package/dist/steps/metrics.js +108 -108
  210. package/dist/steps/shell.d.ts +2 -0
  211. package/dist/steps/shell.js +26 -9
  212. package/dist/steps/signup.d.ts +7 -4
  213. package/dist/steps/signup.js +29 -20
  214. package/dist/steps/verify.d.ts +2 -2
  215. package/dist/steps/verify.js +118 -112
  216. package/package.json +40 -14
  217. package/assets/agents/docs-validator-agent.md +0 -490
  218. package/assets/agents/release-readiness-agent.md +0 -482
  219. package/assets/commands/agents/aristotle-analyst.md +0 -115
  220. package/assets/commands/agents/aristotle-explorer.md +0 -92
  221. package/assets/commands/agents/aristotle-forecaster.md +0 -114
  222. package/assets/commands/agents/aristotle-validator.md +0 -114
  223. package/assets/commands/agents/prompt-validate.md +0 -135
  224. package/assets/commands/agents/workflow-synthesis.md +0 -101
  225. package/assets/commands/workflows/aristotle.md +0 -543
  226. package/assets/commands/workflows/post-implementation.md +0 -577
  227. package/assets/commands/workflows/pre-implementation.md +0 -670
  228. package/assets/commands/workflows/prompt-audit.md +0 -754
  229. package/assets/commands/workflows/ship.md +0 -721
  230. package/dist/test/auth.test.d.ts +0 -1
  231. package/dist/test/auth.test.js +0 -43
  232. package/dist/test/config-io.test.d.ts +0 -1
  233. package/dist/test/config-io.test.js +0 -56
  234. package/dist/test/config-merger.test.d.ts +0 -1
  235. package/dist/test/config-merger.test.js +0 -94
  236. package/dist/test/detect.test.d.ts +0 -1
  237. package/dist/test/detect.test.js +0 -25
  238. package/dist/test/file-ops.test.d.ts +0 -1
  239. package/dist/test/file-ops.test.js +0 -100
  240. package/dist/test/hash.test.d.ts +0 -1
  241. package/dist/test/hash.test.js +0 -14
  242. package/dist/test/manifest.test.d.ts +0 -1
  243. package/dist/test/manifest.test.js +0 -78
  244. package/dist/test/paths.test.d.ts +0 -1
  245. package/dist/test/paths.test.js +0 -30
  246. package/dist/test/settings-merger.test.d.ts +0 -1
  247. package/dist/test/settings-merger.test.js +0 -167
  248. package/dist/test/shell-profile.test.d.ts +0 -1
  249. package/dist/test/shell-profile.test.js +0 -40
  250. package/dist/test/shell.test.d.ts +0 -1
  251. package/dist/test/shell.test.js +0 -71
  252. package/dist/test/signup.test.d.ts +0 -1
  253. package/dist/test/signup.test.js +0 -83
@@ -1,149 +1,165 @@
1
- import { readdir, access } from "node:fs/promises";
1
+ import { readdir, access, stat } from "node:fs/promises";
2
2
  import { join } from "node:path";
3
3
  import { loadManifest } from "../lib/manifest.js";
4
- import { readConfig } from "../lib/config-merger.js";
5
- import { readSettings, hasUluopsHook } from "../lib/settings-merger.js";
6
- import { getMetricsToolDir, getSettingsPath } from "./metrics.js";
7
- export async function verify() {
8
- const checks = [];
4
+ import { getHealthTimeout } from "../lib/health.js";
5
+ import { getProfile } from "../harnesses/index.js";
6
+ import { readInstalledMetricsVersion } from "./metrics.js";
7
+ /** Verify a single harness entry, appending results to checks. Returns false if any check fails. */
8
+ async function verifyHarness(harnessName, hm, checks) {
9
9
  let allOk = true;
10
- // 1. Manifest
11
- const manifest = await loadManifest();
12
- if (!manifest) {
13
- checks.push({
14
- label: "Manifest found",
15
- passed: false,
16
- detail: "No manifest — run npx @uluops/setup first",
17
- });
18
- return { ok: false, checks };
10
+ let profile;
11
+ try {
12
+ profile = getProfile(harnessName);
19
13
  }
20
- checks.push({
21
- label: `Manifest found (v${manifest.version}, installed ${manifest.installedAt.split("T")[0]})`,
22
- passed: true,
23
- });
24
- // 2. MCP config
25
- const config = await readConfig(manifest.mcpConfigPath);
26
- const hasTracker = !!config.mcpServers?.["uluops-tracker"];
27
- const hasRegistry = !!config.mcpServers?.["uluops-registry"];
28
- if (hasTracker && hasRegistry) {
14
+ catch {
15
+ checks.push({ label: `Harness: ${harnessName}`, passed: false, detail: "Unknown harness in manifest" });
16
+ return false;
17
+ }
18
+ // 1. Readiness Check (Harness Restart)
19
+ try {
20
+ const configStat = await stat(hm.mcpConfigPath);
21
+ const installedTime = new Date(hm.installedAt).getTime();
22
+ const configTime = configStat.mtimeMs;
23
+ // If config was modified AFTER install, it's a proxy for the harness having read it.
24
+ // We add a 100ms buffer to handle near-simultaneous writes.
25
+ const isReady = configTime > (installedTime + 100);
29
26
  checks.push({
30
- label: `MCP config present in ${manifest.mcpConfigPath} (2 servers)`,
27
+ label: `[${profile.displayName}] Readiness`,
31
28
  passed: true,
29
+ detail: isReady ? "Active (loaded)" : "Waiting for restart",
32
30
  });
33
31
  }
34
- else {
35
- checks.push({
36
- label: "MCP config",
37
- passed: false,
38
- detail: `Missing: ${[!hasTracker && "tracker", !hasRegistry && "registry"].filter(Boolean).join(", ")}`,
39
- });
40
- allOk = false;
32
+ catch {
33
+ // If we can't stat it, we'll catch the error in the MCP config check below.
41
34
  }
42
- // 3. Agent files
43
- const agentsDir = join(manifest.defsPath, "agents");
35
+ // 2. MCP config
44
36
  try {
45
- const agentFiles = await readdir(agentsDir);
46
- const found = manifest.agents.filter((a) => agentFiles.includes(a)).length;
47
- if (found === manifest.agents.length) {
48
- checks.push({
49
- label: `${found}/${manifest.agents.length} agents in ${agentsDir}`,
50
- passed: true,
51
- });
37
+ const config = await profile.mcpConfig.read(hm.mcpConfigPath);
38
+ if (profile.mcpConfig.check(config)) {
39
+ checks.push({ label: `[${profile.displayName}] MCP config present in ${hm.mcpConfigPath} (2 servers)`, passed: true });
52
40
  }
53
41
  else {
54
- checks.push({
55
- label: `${found}/${manifest.agents.length} agents in ${agentsDir}`,
56
- passed: false,
57
- detail: `Missing ${manifest.agents.length - found} agent(s)`,
58
- });
42
+ checks.push({ label: `[${profile.displayName}] MCP config`, passed: false, detail: "UluOps servers not found in config" });
59
43
  allOk = false;
60
44
  }
61
45
  }
62
46
  catch {
47
+ checks.push({ label: `[${profile.displayName}] MCP config`, passed: false, detail: `Cannot read ${hm.mcpConfigPath}` });
48
+ allOk = false;
49
+ }
50
+ // Agent files
51
+ const agentsDir = join(hm.defsPath, "agents");
52
+ try {
53
+ const agentFiles = await readdir(agentsDir);
54
+ const found = hm.agents.filter((a) => agentFiles.includes(a)).length;
63
55
  checks.push({
64
- label: "Agent files",
65
- passed: false,
66
- detail: `Directory not found: ${agentsDir}`,
56
+ label: `[${profile.displayName}] ${found}/${hm.agents.length} agents in ${agentsDir}`,
57
+ passed: found === hm.agents.length,
58
+ detail: found < hm.agents.length ? `Missing ${hm.agents.length - found} agent(s)` : undefined,
67
59
  });
60
+ if (found < hm.agents.length)
61
+ allOk = false;
62
+ }
63
+ catch {
64
+ checks.push({ label: `[${profile.displayName}] Agent files`, passed: false, detail: `Directory not found: ${agentsDir}` });
68
65
  allOk = false;
69
66
  }
70
- // 4. Command files
71
- const commandsDir = join(manifest.defsPath, "commands");
72
- try {
73
- let found = 0;
74
- for (const cmd of manifest.commands) {
67
+ // Command files
68
+ if (hm.commands.length > 0) {
69
+ const commandsDir = join(hm.defsPath, "commands");
70
+ const cmdResults = await Promise.all(hm.commands.map(async (cmd) => {
75
71
  try {
76
72
  await access(join(commandsDir, cmd));
77
- found++;
73
+ return true;
78
74
  }
79
75
  catch {
80
- // Missing
76
+ return false;
81
77
  }
82
- }
83
- if (found === manifest.commands.length) {
84
- checks.push({
85
- label: `${found}/${manifest.commands.length} commands in ${commandsDir}`,
86
- passed: true,
87
- });
88
- }
89
- else {
90
- checks.push({
91
- label: `${found}/${manifest.commands.length} commands in ${commandsDir}`,
92
- passed: false,
93
- detail: `Missing ${manifest.commands.length - found} command(s)`,
94
- });
95
- allOk = false;
96
- }
97
- }
98
- catch {
78
+ }));
79
+ const found = cmdResults.filter(Boolean).length;
99
80
  checks.push({
100
- label: "Command files",
101
- passed: false,
102
- detail: `Directory not found: ${commandsDir}`,
81
+ label: `[${profile.displayName}] ${found}/${hm.commands.length} commands`,
82
+ passed: found === hm.commands.length,
83
+ detail: found < hm.commands.length ? `Missing ${hm.commands.length - found} command(s)` : undefined,
103
84
  });
104
- allOk = false;
85
+ if (found < hm.commands.length)
86
+ allOk = false;
105
87
  }
106
- // 5. Agent metrics hook
107
- if (manifest.metricsHookInstalled) {
108
- const settings = await readSettings(getSettingsPath());
109
- const hookPresent = hasUluopsHook(settings);
110
- const toolDir = getMetricsToolDir();
88
+ // Hooks
89
+ if (hm.hooksInstalled && profile.hooks && profile.paths.settingsPath) {
90
+ const hookPresent = await profile.hooks.check(profile.paths.settingsPath);
111
91
  let hookFilePresent = false;
112
- try {
113
- await access(join(toolDir, "dist", "hook.js"));
114
- hookFilePresent = true;
115
- }
116
- catch {
117
- // Missing
92
+ if (profile.paths.toolsDir) {
93
+ try {
94
+ await access(join(profile.paths.toolsDir, "dist", "hook.js"));
95
+ hookFilePresent = true;
96
+ }
97
+ catch { /* Missing */ }
118
98
  }
119
99
  if (hookPresent && hookFilePresent) {
100
+ // Existence is necessary but not sufficient — check version drift against the
101
+ // currently-resolvable agent-metrics. Without this, verify cannot detect that
102
+ // a fresh setup release is shipping while the installed hook is stale.
103
+ const installedVersion = profile.paths.toolsDir
104
+ ? await readInstalledMetricsVersion(profile.paths.toolsDir)
105
+ : null;
106
+ const recordedVersion = hm.hooksInstalledVersion ?? null;
107
+ const detail = installedVersion
108
+ ? `v${installedVersion}${recordedVersion && recordedVersion !== installedVersion ? ` (manifest records v${recordedVersion} — out of sync)` : ""}`
109
+ : "version unknown";
120
110
  checks.push({
121
- label: "Agent metrics hook configured and tool files present",
111
+ label: `[${profile.displayName}] Agent metrics hook configured`,
122
112
  passed: true,
113
+ detail,
123
114
  });
115
+ if (recordedVersion && installedVersion && recordedVersion !== installedVersion) {
116
+ // Drift between manifest record and on-disk hook copy — not a hard failure
117
+ // because verify is read-only, but surface it so the user re-runs setup.
118
+ allOk = false;
119
+ }
124
120
  }
125
121
  else {
126
122
  const missing = [
127
- !hookPresent && "hook not in settings.json",
128
- !hookFilePresent && "hook.js not found",
129
- ]
130
- .filter(Boolean)
131
- .join(", ");
132
- checks.push({
133
- label: "Agent metrics",
134
- passed: false,
135
- detail: missing,
136
- });
123
+ ...(!hookPresent ? ["hook not in settings"] : []),
124
+ ...(!hookFilePresent ? ["hook.js not found"] : []),
125
+ ].join(", ");
126
+ checks.push({ label: `[${profile.displayName}] Agent metrics`, passed: false, detail: missing });
137
127
  allOk = false;
138
128
  }
139
129
  }
140
- // 6. API connectivity
141
- const apiKey = extractApiKey(config);
130
+ return allOk;
131
+ }
132
+ /** Run all verification checks against the current installation and return structured results. */
133
+ export async function verify() {
134
+ const checks = [];
135
+ let allOk = true;
136
+ // 1. Manifest
137
+ const manifest = await loadManifest();
138
+ if (!manifest) {
139
+ checks.push({
140
+ label: "Manifest found",
141
+ passed: false,
142
+ detail: "No manifest — run npx @uluops/setup first",
143
+ });
144
+ return { ok: false, checks };
145
+ }
146
+ checks.push({
147
+ label: `Manifest found (v${manifest.version}, installed ${manifest.installedAt.split("T")[0]})`,
148
+ passed: true,
149
+ });
150
+ // 2. Per-harness checks
151
+ for (const [harnessName, hm] of Object.entries(manifest.harnesses)) {
152
+ const ok = await verifyHarness(harnessName, hm, checks);
153
+ if (!ok)
154
+ allOk = false;
155
+ }
156
+ // 3. API connectivity (harness-agnostic)
157
+ const apiKey = process.env["ULUOPS_API_KEY"];
142
158
  if (apiKey) {
143
159
  try {
144
160
  const res = await fetch("https://api.uluops.ai/api/v1/registry/users/me", {
145
161
  headers: { Authorization: `Bearer ${apiKey}` },
146
- signal: AbortSignal.timeout(5000),
162
+ signal: AbortSignal.timeout(getHealthTimeout()),
147
163
  });
148
164
  if (res.ok) {
149
165
  const data = (await res.json());
@@ -172,13 +188,3 @@ export async function verify() {
172
188
  }
173
189
  return { ok: allOk, checks };
174
190
  }
175
- function extractApiKey(config) {
176
- const raw = config.mcpServers;
177
- if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
178
- return process.env["ULUOPS_API_KEY"];
179
- }
180
- const servers = raw;
181
- return (servers["uluops-registry"]?.env?.["ULUOPS_API_KEY"] ??
182
- servers["uluops-tracker"]?.env?.["ULUOPS_TRACKER_API_KEY"] ??
183
- process.env["ULUOPS_API_KEY"]);
184
- }
package/package.json CHANGED
@@ -1,36 +1,62 @@
1
1
  {
2
2
  "name": "@uluops/setup",
3
- "version": "0.2.0",
4
- "description": "Zero-friction installer for UluOps + Claude Code",
3
+ "version": "0.6.0",
4
+ "description": "Zero-friction installer for UluOps agentic harnesses",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/Uluops/-uluops-setup.git"
9
+ },
10
+ "homepage": "https://uluops.ai",
11
+ "keywords": [
12
+ "uluops",
13
+ "mcp",
14
+ "agents",
15
+ "claude",
16
+ "opencode",
17
+ "agentic",
18
+ "harness",
19
+ "setup",
20
+ "installer"
21
+ ],
5
22
  "type": "module",
6
23
  "bin": {
7
24
  "uluops-setup": "./dist/cli.js"
8
25
  },
26
+ "exports": {
27
+ "./cli": "./dist/cli.js"
28
+ },
9
29
  "files": [
10
- "dist",
30
+ "dist/cli.js",
31
+ "dist/cli.d.ts",
32
+ "dist/lib/**",
33
+ "dist/steps/**",
34
+ "dist/harnesses/**",
35
+ "dist/commands/**",
11
36
  "assets"
12
37
  ],
13
38
  "engines": {
14
- "node": ">=18.0.0"
39
+ "node": ">=20.0.0"
15
40
  },
16
41
  "scripts": {
17
- "build": "tsc",
42
+ "build": "tsc -p tsconfig.build.json",
18
43
  "dev": "tsx src/cli.ts",
19
- "typecheck": "tsc --noEmit",
44
+ "typecheck": "tsc -p tsconfig.build.json --noEmit && tsc -p tsconfig.test.json --noEmit",
20
45
  "test": "vitest run",
21
46
  "test:watch": "vitest watch",
22
47
  "prepublishOnly": "npm run build"
23
48
  },
24
49
  "dependencies": {
25
- "@inquirer/prompts": "^7.0.0",
26
- "@uluops/agent-metrics": "^0.2.0",
27
- "chalk": "^5.0.0",
28
- "commander": "^12.0.0"
50
+ "@inquirer/prompts": "7.10.1",
51
+ "@uluops/agent-metrics": "0.4.0",
52
+ "chalk": "5.6.2",
53
+ "commander": "12.1.0",
54
+ "jsonc-parser": "3.3.1"
29
55
  },
30
56
  "devDependencies": {
31
- "@types/node": "^22.0.0",
32
- "tsx": "^4.0.0",
33
- "typescript": "^5.7.0",
34
- "vitest": "^3.0.0"
57
+ "@types/node": "22.19.15",
58
+ "tsx": "4.21.0",
59
+ "typescript": "5.9.3",
60
+ "vitest": "3.2.4"
35
61
  }
36
62
  }