ultra-builder-pro-cli 0.25.0 → 0.26.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 (241) hide show
  1. package/.ultra-template/contexts/TEMPLATE.md +87 -0
  2. package/.ultra-template/decisions/.gitkeep +1 -0
  3. package/.ultra-template/evidence/.gitkeep +1 -0
  4. package/.ultra-template/north-star.md +46 -0
  5. package/.ultra-template/research/.gitkeep +1 -0
  6. package/.ultra-template/specs/discovery.md +2 -2
  7. package/.ultra-template/tasks.json +3 -0
  8. package/.ultra-template/test-report.json +27 -0
  9. package/CHANGELOG.md +49 -0
  10. package/README.md +217 -579
  11. package/adapters/_shared/delegate-profiles/kimi-read-only.md +15 -0
  12. package/adapters/_shared/delegate-profiles/kimi-write.md +17 -0
  13. package/adapters/_shared/file-ops.cjs +76 -2
  14. package/adapters/_shared/host-profile.cjs +97 -0
  15. package/adapters/_shared/plugin-core.cjs +204 -0
  16. package/adapters/_shared/runtime-assets.cjs +31 -96
  17. package/adapters/claude.js +92 -291
  18. package/adapters/codex.js +309 -842
  19. package/adapters/grok.js +143 -1469
  20. package/adapters/kimi.js +124 -1053
  21. package/adapters/opencode.js +230 -742
  22. package/bin/delegate-worker.cjs +323 -0
  23. package/bin/delegate.cjs +456 -0
  24. package/bin/install.js +38 -11
  25. package/docs/ARCHITECTURE.md +122 -216
  26. package/docs/ARTIFACT-AUTHORITY.md +90 -268
  27. package/docs/DECISIONS.md +75 -87
  28. package/docs/PHILOSOPHY.md +177 -0
  29. package/docs/PLUGIN-ISOLATION-CONTRACT.md +62 -39
  30. package/docs/RUNTIME-COMPAT-MATRIX.md +99 -156
  31. package/docs/SKILL-AUTHORING.md +94 -73
  32. package/docs/WORKFLOW-LIFECYCLE.md +93 -189
  33. package/hooks/README.md +17 -37
  34. package/hooks/_common.py +113 -0
  35. package/hooks/adapters/codex.py +9 -16
  36. package/hooks/adapters/grok.py +5 -5
  37. package/hooks/adapters/kimi.py +8 -14
  38. package/hooks/block_dangerous_commands.py +95 -0
  39. package/hooks/compact_context.py +65 -0
  40. package/hooks/mid_workflow_recall.py +25 -0
  41. package/hooks/post_edit_guard.py +105 -0
  42. package/hooks/session_context.py +30 -0
  43. package/package.json +17 -52
  44. package/skills/ultra-change/SKILL.md +97 -50
  45. package/skills/ultra-change/references/change-contract.md +40 -1
  46. package/skills/ultra-delegate/SKILL.md +82 -0
  47. package/skills/ultra-delegate/references/delegation-contract.md +51 -0
  48. package/skills/ultra-delegate/scripts/delegate_wait.py +86 -0
  49. package/skills/ultra-deliver/SKILL.md +61 -42
  50. package/skills/ultra-deliver/references/baseline-reconciliation.md +39 -20
  51. package/skills/ultra-dev/SKILL.md +96 -62
  52. package/skills/ultra-dev/references/debugging.md +22 -0
  53. package/skills/ultra-domain-modeling/SKILL.md +79 -0
  54. package/skills/ultra-grilling/SKILL.md +79 -0
  55. package/skills/ultra-init/SKILL.md +94 -37
  56. package/skills/ultra-init/references/brownfield-adoption.md +33 -83
  57. package/skills/ultra-init/scripts/init_project.cjs +84 -0
  58. package/skills/ultra-plan/SKILL.md +88 -68
  59. package/skills/ultra-research/SKILL.md +62 -48
  60. package/skills/ultra-research/references/00-problem-validation.md +5 -5
  61. package/skills/ultra-research/references/01-opportunity-discovery.md +3 -3
  62. package/skills/ultra-research/references/02-market-assessment.md +5 -4
  63. package/skills/ultra-research/references/03-competitive-landscape.md +3 -3
  64. package/skills/ultra-research/references/04-product-strategy.md +3 -3
  65. package/skills/ultra-research/references/05-assumptions-validation.md +5 -5
  66. package/skills/ultra-research/references/10-user-personas.md +3 -2
  67. package/skills/ultra-research/references/11-user-scenarios.md +3 -3
  68. package/skills/ultra-research/references/20-user-stories.md +4 -3
  69. package/skills/ultra-research/references/21-features-scope.md +3 -2
  70. package/skills/ultra-research/references/22-success-metrics.md +3 -3
  71. package/skills/ultra-research/references/30-architecture-context.md +3 -3
  72. package/skills/ultra-research/references/31-solution-strategy.md +3 -3
  73. package/skills/ultra-research/references/32-building-blocks.md +3 -3
  74. package/skills/ultra-research/references/40-deployment.md +3 -3
  75. package/skills/ultra-research/references/41-quality-risks.md +3 -3
  76. package/skills/ultra-research/references/99-synthesis.md +7 -7
  77. package/skills/ultra-review/SKILL.md +59 -32
  78. package/skills/ultra-review/references/code.md +17 -0
  79. package/skills/ultra-review/references/comments.md +12 -0
  80. package/skills/ultra-review/references/design.md +12 -0
  81. package/skills/ultra-review/references/errors.md +13 -0
  82. package/skills/ultra-review/references/spec.md +13 -0
  83. package/skills/ultra-review/references/tests.md +12 -0
  84. package/skills/ultra-review/references/worker-packet.md +40 -0
  85. package/skills/ultra-review/scripts/review_wait.py +26 -15
  86. package/skills/ultra-status/SKILL.md +61 -36
  87. package/skills/ultra-tdd/SKILL.md +81 -0
  88. package/skills/ultra-tdd/references/templates/README.md +20 -0
  89. package/skills/ultra-tdd/references/templates/feature-flag-default-audit.sh +79 -0
  90. package/skills/ultra-tdd/references/templates/persistence-real.ts +78 -0
  91. package/skills/ultra-tdd/references/templates/testcontainer-postgres.py +78 -0
  92. package/skills/ultra-tdd/references/templates/testcontainer-postgres.ts +73 -0
  93. package/skills/ultra-tdd/references/templates/vertical-slice.ts +66 -0
  94. package/skills/ultra-tdd/references/test-execution.md +18 -0
  95. package/skills/ultra-test/SKILL.md +70 -30
  96. package/skills/ultra-test/references/export-syntax.md +18 -0
  97. package/skills/ultra-test/scripts/worktree_digest.cjs +54 -0
  98. package/skills/ultra-think/SKILL.md +49 -27
  99. package/skills/ultra-think/references/autonomy-boundary.md +48 -0
  100. package/skills/ultra-think/references/interaction-boundary.md +18 -33
  101. package/.ultra-template/docs/research/README.md +0 -55
  102. package/.ultra-template/reports/templates/delivery-report.json +0 -17
  103. package/.ultra-template/reports/templates/test-report.json +0 -18
  104. package/.ultra-template/tasks/tasks.json +0 -15
  105. package/.ultra-template/templates/task-context.md +0 -19
  106. package/adapters/_shared/codex-assets.cjs +0 -725
  107. package/adapters/_shared/codex-ultra-tools-entry.cjs +0 -11
  108. package/adapters/_shared/interaction-contract.cjs +0 -129
  109. package/adapters/_shared/path-rewrite.cjs +0 -79
  110. package/adapters/_shared/runtime-native.cjs +0 -132
  111. package/adapters/_shared/settings-merge.cjs +0 -76
  112. package/agents/code-reviewer.md +0 -42
  113. package/agents/debugger.md +0 -40
  114. package/agents/review-code.md +0 -49
  115. package/agents/review-comments.md +0 -38
  116. package/agents/review-coordinator.md +0 -56
  117. package/agents/review-design.md +0 -40
  118. package/agents/review-errors.md +0 -43
  119. package/agents/review-spec.md +0 -39
  120. package/agents/review-tests.md +0 -40
  121. package/agents/tdd-runner.md +0 -38
  122. package/bin/orchestrator.js +0 -383
  123. package/commands/ultra-change.md +0 -10
  124. package/commands/ultra-deliver.md +0 -10
  125. package/commands/ultra-dev.md +0 -10
  126. package/commands/ultra-doctor.md +0 -10
  127. package/commands/ultra-init.md +0 -10
  128. package/commands/ultra-plan.md +0 -10
  129. package/commands/ultra-research.md +0 -10
  130. package/commands/ultra-review.md +0 -10
  131. package/commands/ultra-status.md +0 -10
  132. package/commands/ultra-test.md +0 -10
  133. package/commands/ultra-think.md +0 -10
  134. package/docs/AGENT-CONTEXT.md +0 -191
  135. package/docs/COMMIT-HASH-BACKFILL.md +0 -51
  136. package/docs/LEGACY-CLI-CROSSWALK.md +0 -175
  137. package/docs/ROADMAP.md +0 -101
  138. package/docs/STATE-DB-ACCESS-POLICY.md +0 -161
  139. package/hooks/active_task_context.py +0 -152
  140. package/hooks/context_envelope.py +0 -100
  141. package/hooks/health_check.py +0 -196
  142. package/hooks/pre_stop_check.py +0 -66
  143. package/hooks/runtime_paths.py +0 -396
  144. package/hooks/subagent_tracker.py +0 -88
  145. package/hooks/workflow_checkpoint.py +0 -76
  146. package/hooks/workflow_context.py +0 -48
  147. package/hooks/workflow_resume.py +0 -84
  148. package/mcp-server/hook-context.cjs +0 -38
  149. package/mcp-server/hook-event.cjs +0 -34
  150. package/mcp-server/lib/archive-journal.cjs +0 -1119
  151. package/mcp-server/lib/archive-mutation-worker.py +0 -365
  152. package/mcp-server/lib/artifact-registry.cjs +0 -1232
  153. package/mcp-server/lib/baseline-workflow.cjs +0 -1193
  154. package/mcp-server/lib/canonical-json.cjs +0 -19
  155. package/mcp-server/lib/change-authority.cjs +0 -26
  156. package/mcp-server/lib/change-packet.cjs +0 -790
  157. package/mcp-server/lib/change-workflow.cjs +0 -65
  158. package/mcp-server/lib/context-envelope.cjs +0 -581
  159. package/mcp-server/lib/context-paths.cjs +0 -142
  160. package/mcp-server/lib/decision-records.cjs +0 -423
  161. package/mcp-server/lib/delivery-transaction.cjs +0 -471
  162. package/mcp-server/lib/doctor-backup-worker.cjs +0 -328
  163. package/mcp-server/lib/doctor.cjs +0 -627
  164. package/mcp-server/lib/git-bootstrap.cjs +0 -651
  165. package/mcp-server/lib/init-project.cjs +0 -1021
  166. package/mcp-server/lib/kernel-change-workflow.cjs +0 -2029
  167. package/mcp-server/lib/legacy-change-workflow.cjs +0 -3032
  168. package/mcp-server/lib/managed-file-write.cjs +0 -172
  169. package/mcp-server/lib/plan-checkpoint.cjs +0 -177
  170. package/mcp-server/lib/plan-publication-worker.cjs +0 -830
  171. package/mcp-server/lib/plan-store.cjs +0 -794
  172. package/mcp-server/lib/prd-parser.cjs +0 -83
  173. package/mcp-server/lib/pricing.cjs +0 -44
  174. package/mcp-server/lib/project-context.cjs +0 -178
  175. package/mcp-server/lib/projector.cjs +0 -386
  176. package/mcp-server/lib/provider-refs.cjs +0 -42
  177. package/mcp-server/lib/runtime-paths.cjs +0 -1687
  178. package/mcp-server/lib/runtime-state.cjs +0 -222
  179. package/mcp-server/lib/safe-project-file.cjs +0 -385
  180. package/mcp-server/lib/stage-checkpoints.cjs +0 -463
  181. package/mcp-server/lib/state-authority.cjs +0 -95
  182. package/mcp-server/lib/state-db.cjs +0 -1580
  183. package/mcp-server/lib/state-ops.cjs +0 -1428
  184. package/mcp-server/lib/task-contract.cjs +0 -404
  185. package/mcp-server/lib/task-expander.cjs +0 -105
  186. package/mcp-server/lib/task-ledger.cjs +0 -1964
  187. package/mcp-server/lib/telemetry.cjs +0 -85
  188. package/mcp-server/lib/topo.cjs +0 -131
  189. package/mcp-server/lib/ultra-facade.cjs +0 -2684
  190. package/mcp-server/lib/worker-packet.cjs +0 -358
  191. package/mcp-server/server.cjs +0 -437
  192. package/orchestrator/auto-merge.cjs +0 -128
  193. package/orchestrator/daemon.cjs +0 -264
  194. package/orchestrator/dispatch-rules.cjs +0 -78
  195. package/orchestrator/parallel-orchestrator.cjs +0 -903
  196. package/orchestrator/planner/plan-builder.cjs +0 -125
  197. package/orchestrator/recovery.cjs +0 -188
  198. package/orchestrator/session-close-journal-worker.cjs +0 -5
  199. package/orchestrator/session-close-journal.cjs +0 -1014
  200. package/orchestrator/session-runner.cjs +0 -1153
  201. package/orchestrator/worktree-manager.cjs +0 -282
  202. package/settings.json +0 -7
  203. package/skills/cc-collab/SKILL.md +0 -42
  204. package/skills/code-review-expert/SKILL.md +0 -43
  205. package/skills/code-review-expert/references/correctness-reliability.md +0 -30
  206. package/skills/code-review-expert/references/design-boundaries.md +0 -26
  207. package/skills/code-review-expert/references/removal-plan.md +0 -24
  208. package/skills/codex-collab/SKILL.md +0 -49
  209. package/skills/codex-collab/evals/evals.json +0 -35
  210. package/skills/integration-rules/SKILL.md +0 -32
  211. package/skills/security-rules/SKILL.md +0 -38
  212. package/skills/testing-rules/SKILL.md +0 -32
  213. package/skills/ultra-doctor/SKILL.md +0 -41
  214. package/skills/ultra-plan/references/semantic-preflight.md +0 -20
  215. package/skills/ultra-verify/SKILL.md +0 -46
  216. package/skills/ultra-verify/evals/evals.json +0 -46
  217. package/skills/ultra-verify/references/cross-verify-modes.md +0 -28
  218. package/skills/ultra-verify/references/evidence-status.md +0 -21
  219. package/skills/ultra-verify/scripts/verify_wait.py +0 -94
  220. package/spec/cli-protocol.md +0 -102
  221. package/spec/mcp-tools.yaml +0 -312
  222. package/spec/schemas/baseline-reconciliation.v1.schema.json +0 -73
  223. package/spec/schemas/change-delta.v1.schema.json +0 -153
  224. package/spec/schemas/command-manifest.schema.json +0 -29
  225. package/spec/schemas/context-file.v4.5.schema.json +0 -54
  226. package/spec/schemas/delivery-report.v1.schema.json +0 -66
  227. package/spec/schemas/documentation-reconciliation.v1.schema.json +0 -106
  228. package/spec/schemas/mcp-tools.schema.json +0 -136
  229. package/spec/schemas/skill-manifest.schema.json +0 -24
  230. package/spec/schemas/state-db.sql +0 -641
  231. package/spec/schemas/task-ledger.v2.schema.json +0 -296
  232. package/spec/schemas/tasks.v4.5.schema.json +0 -96
  233. package/spec/schemas/test-report.v1.schema.json +0 -225
  234. package/ultra-tools/cli.cjs +0 -129
  235. package/ultra-tools/commands/db.cjs +0 -226
  236. package/ultra-tools/commands/legacy-memory.cjs +0 -159
  237. package/ultra-tools/commands/migrate.cjs +0 -1386
  238. package/ultra-tools/commands/session.cjs +0 -213
  239. package/ultra-tools/commands/status.cjs +0 -559
  240. package/ultra-tools/commands/system.cjs +0 -498
  241. package/ultra-tools/commands/task.cjs +0 -105
@@ -1,725 +0,0 @@
1
- 'use strict';
2
-
3
- const crypto = require('node:crypto');
4
- const fs = require('node:fs');
5
- const os = require('node:os');
6
- const path = require('node:path');
7
- const { spawnSync } = require('node:child_process');
8
- const yaml = require('js-yaml');
9
- const {
10
- CORE_PUBLIC_SKILLS,
11
- RUNTIME_SUPPORT_FILES,
12
- RUNTIME_WORKER_FILES,
13
- WORKFLOW_HOOK_FILES,
14
- skillPolicy,
15
- skillsForRuntime,
16
- } = require('./runtime-assets.cjs');
17
-
18
- const { parse: parseFrontmatter } = require('./frontmatter.cjs');
19
- const {
20
- copyTree,
21
- ensureDir,
22
- listRelative,
23
- removeTree,
24
- writeAtomic,
25
- } = require('./file-ops.cjs');
26
- const {
27
- adaptInteractionGuidance,
28
- interactionContract,
29
- } = require('./interaction-contract.cjs');
30
-
31
- const PLUGIN_NAME = 'ultra-builder-pro';
32
- const MANAGED_MARKER = 'Managed by Ultra Builder Pro Codex adapter.';
33
- const COMMAND_NAMES = Object.freeze(CORE_PUBLIC_SKILLS.filter((name) => name !== 'ultra-review'));
34
- const SKILL_REFERENCE_NAMES = Object.freeze([
35
- ...COMMAND_NAMES,
36
- 'cc-collab',
37
- 'ultra-review',
38
- 'ultra-verify',
39
- ]);
40
- const CODEX_PRIMARY_SKILLS = new Set([...COMMAND_NAMES, 'ultra-review']);
41
- const TEXT_EXTENSIONS = new Set(['.md', '.json', '.py', '.sh', '.txt', '.yaml', '.yml']);
42
- const NATIVE_PACKAGES = Object.freeze([
43
- 'better-sqlite3',
44
- 'bindings',
45
- 'file-uri-to-path',
46
- ]);
47
-
48
- function titleCase(name) {
49
- const special = { 'cc-collab': 'Claude Code Collaboration' };
50
- if (special[name]) return special[name];
51
- return name.split('-').map((part) => part ? part[0].toUpperCase() + part.slice(1) : part).join(' ');
52
- }
53
-
54
- function replaceSlashCommand(text, command, replacement) {
55
- const escaped = command.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
56
- return text.replace(
57
- new RegExp(`(^|[\\s\\x60(>])/${escaped}(?=$|[\\s\\x60,.;):])`, 'gm'),
58
- (_match, prefix) => `${prefix}${replacement}`,
59
- );
60
- }
61
-
62
- function adaptCodexPrimaryText(input, skillName) {
63
- let text = String(input);
64
- if (skillName === 'ultra-review') {
65
- text = text.replace(
66
- /(?:the current host's native|the host-native) bounded-worker\s+mechanism/g,
67
- 'native Codex custom agents installed for the selected review workers',
68
- );
69
- }
70
-
71
- return text;
72
- }
73
-
74
- function adaptSkillAsset(input, targetName, _rel) {
75
- return adaptHostText(input, targetName);
76
- }
77
-
78
- function adaptHostText(input, skillName = '') {
79
- let text = adaptInteractionGuidance(input, 'codex');
80
- text = text.replaceAll('codex-collab', 'cc-collab');
81
- text = text.replaceAll('CLAUDE.md', 'AGENTS.md');
82
- text = text.replaceAll('$CLAUDE_PLUGIN_ROOT/skills', '~/plugins/ultra-builder-pro/skills');
83
- text = text.replaceAll('~/.claude/skills', '~/plugins/ultra-builder-pro/skills');
84
- text = text.replaceAll('~/.codex/skills', '~/plugins/ultra-builder-pro/skills');
85
- text = text.replaceAll('~/.claude/hooks', '~/plugins/ultra-builder-pro/hooks');
86
- text = text.replaceAll('~/.claude', '~/.codex');
87
-
88
- for (const skill of SKILL_REFERENCE_NAMES) {
89
- text = replaceSlashCommand(text, skill, `$ultra-builder-pro:${skill}`);
90
- }
91
- text = replaceSlashCommand(text, 'clear', 'start a new Codex task');
92
-
93
- if (CODEX_PRIMARY_SKILLS.has(skillName)) {
94
- text = adaptCodexPrimaryText(text, skillName);
95
- }
96
-
97
- return text;
98
- }
99
-
100
- function adaptedDescription(sourceDescription, targetName) {
101
- const special = {
102
- 'cc-collab': 'Ask Claude Code for an independent read-only analysis while Codex owns verification and synthesis. Use only when the user explicitly requests CC or Claude Code collaboration.',
103
- 'ultra-verify': 'Run Codex-primary cross-model verification with a read-only Claude Code advisor. Use only when the user explicitly requests independent model verification.',
104
- 'ultra-dev': 'Execute one authoritative Ultra task with Codex-native implementation, verification, and review. Use when a dependency-ready slice is ready for development.',
105
- };
106
- return special[targetName] || adaptHostText(String(sourceDescription || `${titleCase(targetName)} workflow for Codex.`), targetName)
107
- .replace(/\s+/g, ' ')
108
- .trim();
109
- }
110
-
111
- function buildSkillMarkdown(sourceText, sourceName, targetName) {
112
- const { fm, body } = parseFrontmatter(sourceText);
113
- const adaptedBody = adaptHostText(body, targetName);
114
- return yaml.dump({
115
- name: targetName,
116
- description: adaptedDescription(fm && fm.description, targetName),
117
- }, { lineWidth: -1, noRefs: true }).trimEnd()
118
- .replace(/^/, '---\n') + `\n---\n\n${adaptedBody.trim()}\n`;
119
- }
120
-
121
- function shortDescription(description, name) {
122
- const value = String(description || `${titleCase(name)} for Codex`).replace(/\s+/g, ' ').trim();
123
- if (value.length <= 64) return value;
124
- const candidate = value.slice(0, 65);
125
- const boundary = candidate.lastIndexOf(' ');
126
- const short = (boundary >= 25 ? candidate.slice(0, boundary) : value.slice(0, 64))
127
- .replace(/[\s.,;:]+$/, '');
128
- return short || `${titleCase(name)} for Codex`;
129
- }
130
-
131
- function buildOpenAiYaml(name, description) {
132
- const policy = skillPolicy(name);
133
- const metadata = {
134
- interface: {
135
- display_name: titleCase(name),
136
- short_description: shortDescription(description, name),
137
- default_prompt: `Use $ultra-builder-pro:${name} for this task and follow its workflow.`,
138
- },
139
- policy: { allow_implicit_invocation: policy.allowImplicitInvocation },
140
- };
141
- if (policy.requiresUltraMcp) {
142
- metadata.dependencies = {
143
- tools: [{
144
- type: 'mcp',
145
- value: PLUGIN_NAME,
146
- description: 'Ultra Builder Pro authoritative task and change runtime',
147
- }],
148
- };
149
- }
150
- return yaml.dump(metadata, {
151
- lineWidth: -1,
152
- noRefs: true,
153
- forceQuotes: true,
154
- quotingType: "'",
155
- });
156
- }
157
-
158
- function isTextFile(rel) {
159
- return TEXT_EXTENSIONS.has(path.extname(rel).toLowerCase());
160
- }
161
-
162
- function copySkill(sourceDir, targetDir, sourceName, targetName) {
163
- if (targetName === 'cc-collab') {
164
- ensureDir(targetDir);
165
- const sourceText = fs.readFileSync(path.join(sourceDir, 'SKILL.md'), 'utf8');
166
- const skillText = buildSkillMarkdown(sourceText, sourceName, targetName);
167
- writeAtomic(path.join(targetDir, 'SKILL.md'), skillText);
168
- const description = parseFrontmatter(skillText).fm.description;
169
- writeAtomic(path.join(targetDir, 'agents', 'openai.yaml'), buildOpenAiYaml(targetName, description));
170
- return;
171
- }
172
-
173
- copyTree(sourceDir, targetDir, {
174
- transform(original, rel) {
175
- if (rel === path.join('agents', 'openai.yaml')) return original;
176
- if (rel === 'SKILL.md') {
177
- return Buffer.from(buildSkillMarkdown(original.toString('utf8'), sourceName, targetName));
178
- }
179
- if (!isTextFile(rel)) return original;
180
- return Buffer.from(adaptSkillAsset(original.toString('utf8'), targetName, rel));
181
- },
182
- });
183
- const skillText = fs.readFileSync(path.join(targetDir, 'SKILL.md'), 'utf8');
184
- const description = parseFrontmatter(skillText).fm.description;
185
- writeAtomic(path.join(targetDir, 'agents', 'openai.yaml'), buildOpenAiYaml(targetName, description));
186
- }
187
-
188
- function buildCommandMap() {
189
- return Object.fromEntries(COMMAND_NAMES.map((name) => [`/${name}`, `$ultra-builder-pro:${name}`]));
190
- }
191
-
192
- function shellQuote(value) {
193
- return `'${String(value).replaceAll("'", "'\"'\"'")}'`;
194
- }
195
-
196
- function hookCommand(pluginRoot, feature, ...args) {
197
- const adapter = path.join(path.resolve(pluginRoot), 'hooks', 'adapters', 'codex.py');
198
- return [
199
- `python3 ${shellQuote(adapter)}`,
200
- shellQuote(feature),
201
- ...args.map((arg) => shellQuote(arg)),
202
- ].join(' ');
203
- }
204
-
205
- function commandHook(pluginRoot, feature, timeout, statusMessage, ...args) {
206
- return {
207
- type: 'command',
208
- command: hookCommand(pluginRoot, feature, ...args),
209
- timeout,
210
- statusMessage,
211
- };
212
- }
213
-
214
- function buildHooksManifest(pluginRoot) {
215
- return {
216
- hooks: {
217
- SessionStart: [
218
- { hooks: [commandHook(pluginRoot, 'health_check.py', 5, 'Checking Ultra runtime')] },
219
- { hooks: [commandHook(pluginRoot, 'workflow_context.py', 10, 'Loading active Ultra workflow')] },
220
- ],
221
- PreToolUse: [
222
- { matcher: 'Edit|Write|apply_patch', hooks: [commandHook(pluginRoot, 'active_task_context.py', 3, 'Checking active Ultra task')] },
223
- ],
224
- PreCompact: [
225
- { matcher: 'manual|auto', hooks: [commandHook(pluginRoot, 'workflow_checkpoint.py', 10, 'Saving Ultra workflow checkpoint')] },
226
- ],
227
- PostCompact: [
228
- { hooks: [commandHook(pluginRoot, 'workflow_resume.py', 10, 'Restoring Ultra workflow checkpoint')] },
229
- ],
230
- Stop: [
231
- { hooks: [commandHook(pluginRoot, 'pre_stop_check.py', 5, 'Reporting Ultra workflow position')] },
232
- ],
233
- SubagentStart: [
234
- { hooks: [commandHook(pluginRoot, 'subagent_tracker.py', 5, 'Tracking Ultra subagent', 'start')] },
235
- ],
236
- SubagentStop: [
237
- { hooks: [commandHook(pluginRoot, 'subagent_tracker.py', 5, 'Tracking Ultra subagent', 'stop')] },
238
- ],
239
- },
240
- };
241
- }
242
-
243
- function copyHooks(repoRoot, pluginRoot, publishedRoot = pluginRoot) {
244
- const sourceRoot = path.join(repoRoot, 'hooks');
245
- const targetRoot = path.join(pluginRoot, 'hooks');
246
- ensureDir(targetRoot);
247
- for (const name of WORKFLOW_HOOK_FILES) {
248
- fs.copyFileSync(path.join(sourceRoot, name), path.join(targetRoot, name));
249
- }
250
- ensureDir(path.join(targetRoot, 'adapters'));
251
- fs.copyFileSync(
252
- path.join(sourceRoot, 'adapters', 'codex.py'),
253
- path.join(targetRoot, 'adapters', 'codex.py'),
254
- );
255
- writeAtomic(
256
- path.join(targetRoot, 'hooks.json'),
257
- JSON.stringify(buildHooksManifest(publishedRoot), null, 2) + '\n',
258
- );
259
- }
260
-
261
- function buildMcpRuntime(repoRoot, pluginRoot, { runtime = 'codex' } = {}) {
262
- const source = path.join(repoRoot, 'mcp-server', 'server.cjs');
263
- const cliSource = path.join(repoRoot, 'adapters', '_shared', 'codex-ultra-tools-entry.cjs');
264
- const runtimeWorkerSources = new Map([
265
- [
266
- 'session-close-journal-worker.cjs',
267
- path.join(repoRoot, 'orchestrator', 'session-close-journal-worker.cjs'),
268
- ],
269
- [
270
- 'doctor-backup-worker.cjs',
271
- path.join(repoRoot, 'mcp-server', 'lib', 'doctor-backup-worker.cjs'),
272
- ],
273
- ]);
274
- const runtimeRoot = path.join(pluginRoot, 'runtime');
275
- const buildRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'ubp-codex-mcp-build-'));
276
- let nccCli;
277
- try {
278
- nccCli = require.resolve('@vercel/ncc/dist/ncc/cli.js');
279
- } catch (error) {
280
- throw new Error(`Ultra MCP bundling requires @vercel/ncc: ${error.message}`);
281
- }
282
-
283
- try {
284
- const bundled = spawnSync(process.execPath, [
285
- nccCli,
286
- 'build',
287
- source,
288
- '-o',
289
- buildRoot,
290
- '--no-cache',
291
- '--quiet',
292
- '-e',
293
- 'better-sqlite3',
294
- ], {
295
- cwd: repoRoot,
296
- encoding: 'utf8',
297
- maxBuffer: 16 * 1024 * 1024,
298
- });
299
- if (bundled.error) throw bundled.error;
300
- if (bundled.status !== 0) {
301
- const detail = (bundled.stderr || bundled.stdout || '').trim();
302
- throw new Error(`ncc failed to bundle the Ultra MCP runtime${detail ? `: ${detail}` : ''}`);
303
- }
304
- copyTree(buildRoot, runtimeRoot);
305
- } finally {
306
- removeTree(buildRoot);
307
- }
308
-
309
- const cliBuildRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'ubp-codex-cli-build-'));
310
- try {
311
- const bundled = spawnSync(process.execPath, [
312
- nccCli,
313
- 'build',
314
- cliSource,
315
- '-o',
316
- cliBuildRoot,
317
- '--no-cache',
318
- '--quiet',
319
- '-e',
320
- 'better-sqlite3',
321
- ], {
322
- cwd: repoRoot,
323
- encoding: 'utf8',
324
- maxBuffer: 16 * 1024 * 1024,
325
- });
326
- if (bundled.error) throw bundled.error;
327
- if (bundled.status !== 0) {
328
- const detail = (bundled.stderr || bundled.stdout || '').trim();
329
- throw new Error(`ncc failed to bundle the Ultra fallback CLI${detail ? `: ${detail}` : ''}`);
330
- }
331
- for (const rel of listRelative(cliBuildRoot)) {
332
- const target = rel === 'index.cjs'
333
- ? path.join(runtimeRoot, 'ultra-tools.cjs')
334
- : path.join(runtimeRoot, rel);
335
- ensureDir(path.dirname(target));
336
- fs.copyFileSync(path.join(cliBuildRoot, rel), target);
337
- }
338
- } finally {
339
- removeTree(cliBuildRoot);
340
- }
341
-
342
- for (const workerFile of RUNTIME_WORKER_FILES) {
343
- const workerSource = runtimeWorkerSources.get(workerFile);
344
- if (!workerSource) {
345
- throw new Error(`Ultra runtime worker source is not registered: ${workerFile}`);
346
- }
347
- const workerBuildRoot = fs.mkdtempSync(path.join(
348
- os.tmpdir(),
349
- `ubp-${path.basename(workerFile, '.cjs')}-build-`,
350
- ));
351
- try {
352
- const bundled = spawnSync(process.execPath, [
353
- nccCli,
354
- 'build',
355
- workerSource,
356
- '-o',
357
- workerBuildRoot,
358
- '--no-cache',
359
- '--quiet',
360
- '-e',
361
- 'better-sqlite3',
362
- ], {
363
- cwd: repoRoot,
364
- encoding: 'utf8',
365
- maxBuffer: 16 * 1024 * 1024,
366
- });
367
- if (bundled.error) throw bundled.error;
368
- if (bundled.status !== 0) {
369
- const detail = (bundled.stderr || bundled.stdout || '').trim();
370
- throw new Error(
371
- `ncc failed to bundle Ultra runtime worker ${workerFile}${detail ? `: ${detail}` : ''}`,
372
- );
373
- }
374
- const workerOutput = path.join(workerBuildRoot, 'index.cjs');
375
- if (!fs.existsSync(workerOutput)) {
376
- throw new Error(`ncc did not emit Ultra runtime worker ${workerFile}`);
377
- }
378
- fs.copyFileSync(workerOutput, path.join(runtimeRoot, workerFile));
379
- } finally {
380
- removeTree(workerBuildRoot);
381
- }
382
- }
383
-
384
- for (const supportFile of RUNTIME_SUPPORT_FILES) {
385
- const sourceFile = path.join(repoRoot, 'mcp-server', 'lib', supportFile);
386
- if (!fs.existsSync(sourceFile) || !fs.statSync(sourceFile).isFile()) {
387
- throw new Error(`Ultra runtime support asset is missing: ${supportFile}`);
388
- }
389
- fs.copyFileSync(sourceFile, path.join(runtimeRoot, supportFile));
390
- }
391
-
392
- const nodeModulesRoot = path.join(runtimeRoot, 'node_modules');
393
- for (const packageName of NATIVE_PACKAGES) {
394
- let packageFile;
395
- try {
396
- packageFile = require.resolve(`${packageName}/package.json`, { paths: [repoRoot] });
397
- } catch (error) {
398
- throw new Error(`Ultra native runtime dependency ${packageName} is unavailable: ${error.message}`);
399
- }
400
- copyTree(
401
- path.dirname(packageFile),
402
- path.join(nodeModulesRoot, packageName),
403
- );
404
- }
405
- const nativeRelative = path.join(
406
- 'node_modules',
407
- 'better-sqlite3',
408
- 'build',
409
- 'Release',
410
- 'better_sqlite3.node',
411
- );
412
- const nativeFile = path.join(runtimeRoot, nativeRelative);
413
- if (!fs.existsSync(nativeFile) || !fs.statSync(nativeFile).isFile()) {
414
- throw new Error(`Ultra native SQLite driver is missing after staging: ${nativeFile}`);
415
- }
416
- const betterSqlitePackage = JSON.parse(fs.readFileSync(
417
- path.join(nodeModulesRoot, 'better-sqlite3', 'package.json'),
418
- 'utf8',
419
- ));
420
- writeAtomic(path.join(runtimeRoot, 'native-runtime.json'), JSON.stringify({
421
- schema_version: 1,
422
- platform: process.platform,
423
- arch: process.arch,
424
- modules: process.versions.modules,
425
- node_version: process.versions.node,
426
- package: {
427
- name: 'better-sqlite3',
428
- version: betterSqlitePackage.version,
429
- },
430
- native_module: nativeRelative.split(path.sep).join('/'),
431
- native_sha256: crypto.createHash('sha256').update(fs.readFileSync(nativeFile)).digest('hex'),
432
- }, null, 2) + '\n');
433
- fs.copyFileSync(
434
- path.join(repoRoot, 'adapters', '_shared', 'runtime-native.cjs'),
435
- path.join(runtimeRoot, 'runtime-native.cjs'),
436
- );
437
-
438
- const runtimeBootstrap = runtime === 'kimi' ? `
439
- const fs = require('node:fs');
440
- const pluginRoot = path.resolve(__dirname, '..');
441
-
442
- function usableProjectRoot(value) {
443
- if (typeof value !== 'string' || !value.trim()) return null;
444
- const candidate = path.resolve(value);
445
- if (candidate === pluginRoot || candidate.startsWith(pluginRoot + path.sep)) return null;
446
- try {
447
- return fs.statSync(candidate).isDirectory() ? candidate : null;
448
- } catch (_) {
449
- return null;
450
- }
451
- }
452
-
453
- if (!process.env.UBP_ROOT_DIR) {
454
- const rootDir = usableProjectRoot(process.cwd()) || usableProjectRoot(process.env.PWD);
455
- if (!rootDir) {
456
- throw new Error('Kimi Ultra MCP could not resolve the active project root; start Kimi from the project directory');
457
- }
458
- process.env.UBP_ROOT_DIR = rootDir;
459
- }
460
- ` : '';
461
-
462
- const launcher = `'use strict';
463
-
464
- const path = require('node:path');
465
- const { inspectRuntimeNative } = require('./runtime-native.cjs');
466
-
467
- process.env.UBP_RUNTIME_ROOT = path.resolve(__dirname, '..');
468
- ${runtimeBootstrap}
469
-
470
- inspectRuntimeNative(__dirname);
471
- const { main } = require('./index.cjs');
472
-
473
- main().catch((error) => {
474
- process.stderr.write(\`mcp-server fatal: \${error.message}\\n\`);
475
- process.exit(1);
476
- });
477
- `;
478
- writeAtomic(path.join(runtimeRoot, 'launch.cjs'), launcher);
479
- fs.copyFileSync(
480
- path.join(repoRoot, 'mcp-server', 'hook-context.cjs'),
481
- path.join(runtimeRoot, 'hook-context.cjs'),
482
- );
483
- fs.copyFileSync(
484
- path.join(repoRoot, 'mcp-server', 'hook-event.cjs'),
485
- path.join(runtimeRoot, 'hook-event.cjs'),
486
- );
487
- fs.copyFileSync(
488
- path.join(repoRoot, 'mcp-server', 'lib', 'plan-publication-worker.cjs'),
489
- path.join(runtimeRoot, 'plan-publication-worker.cjs'),
490
- );
491
-
492
- const sourceToolsFile = path.join(repoRoot, 'spec', 'mcp-tools.yaml');
493
- const upstreamManifest = yaml.load(fs.readFileSync(sourceToolsFile, 'utf8'));
494
- const { REGISTERED_TOOLS } = require(path.join(repoRoot, 'mcp-server', 'server.cjs'));
495
- const registered = new Set(REGISTERED_TOOLS);
496
- const liveFamilies = new Set(
497
- upstreamManifest.tools.filter((tool) => registered.has(tool.name)).map((tool) => tool.family),
498
- );
499
- const liveManifest = {
500
- ...upstreamManifest,
501
- info: {
502
- ...upstreamManifest.info,
503
- notes: `${upstreamManifest.info.notes.trim()}\n\n${runtime} bundled runtime: only tools registered by the MCP server are listed here.`,
504
- },
505
- families: upstreamManifest.families.filter((family) => liveFamilies.has(family.name)),
506
- tools: upstreamManifest.tools.filter((tool) => registered.has(tool.name)),
507
- };
508
- const specRoot = path.join(pluginRoot, 'spec');
509
- ensureDir(specRoot);
510
- writeAtomic(path.join(specRoot, 'mcp-tools.yaml'), yaml.dump(liveManifest, { lineWidth: -1, noRefs: true }));
511
- writeAtomic(
512
- path.join(specRoot, 'interaction-contract.json'),
513
- JSON.stringify(interactionContract(runtime), null, 2) + '\n',
514
- );
515
- const sourceSchema = path.join(repoRoot, 'spec', 'schemas', 'state-db.sql');
516
- const targetSchema = path.join(specRoot, 'schemas', 'state-db.sql');
517
- ensureDir(path.dirname(targetSchema));
518
- fs.copyFileSync(sourceSchema, targetSchema);
519
-
520
- const preferredTemplate = path.join(repoRoot, 'templates', '.ultra');
521
- const packagedTemplate = path.join(repoRoot, '.ultra-template');
522
- const templateRoot = fs.existsSync(preferredTemplate) ? preferredTemplate : packagedTemplate;
523
- if (!fs.existsSync(templateRoot)) {
524
- throw new Error(`Ultra project template missing from ${repoRoot}`);
525
- }
526
- copyTree(templateRoot, path.join(pluginRoot, 'templates', '.ultra'));
527
-
528
- return {
529
- launcher: path.join(runtimeRoot, 'launch.cjs'),
530
- bundle: path.join(runtimeRoot, 'index.cjs'),
531
- ultraTools: path.join(runtimeRoot, 'ultra-tools.cjs'),
532
- nativeManifest: path.join(runtimeRoot, 'native-runtime.json'),
533
- };
534
- }
535
-
536
- function mcpCommand(launcher) {
537
- if (process.platform === 'win32') {
538
- return { command: 'node.exe', args: [launcher] };
539
- }
540
- return { command: '/usr/bin/env', args: ['node', launcher] };
541
- }
542
-
543
- function inspectInstalledRuntime(runtimeRoot) {
544
- const report = {
545
- status: 'healthy',
546
- checks: {},
547
- issues: [],
548
- };
549
- try {
550
- const detail = require(path.join(runtimeRoot, 'runtime-native.cjs'))
551
- .inspectRuntimeNative(runtimeRoot);
552
- report.checks.native_runtime = { status: 'pass', ...detail };
553
- } catch (error) {
554
- report.status = 'degraded';
555
- report.checks.native_runtime = { status: 'fail' };
556
- report.issues.push({
557
- code: error.code || 'RUNTIME_NATIVE_MISSING',
558
- message: error.message,
559
- ...(error.details || {}),
560
- });
561
- }
562
- return report;
563
- }
564
-
565
- function applyNativeDoctor(report, runtimeRoot) {
566
- const native = inspectInstalledRuntime(runtimeRoot);
567
- report.checks = { ...(report.checks || {}), ...native.checks };
568
- report.issues = [...(report.issues || []), ...native.issues];
569
- if (report.status !== 'missing') {
570
- report.status = report.issues.length === 0 ? 'healthy' : 'degraded';
571
- }
572
- return report;
573
- }
574
-
575
- function pluginContentHash(pluginRoot, baseVersion) {
576
- const hash = crypto.createHash('sha256');
577
- hash.update(baseVersion);
578
- for (const rel of listRelative(pluginRoot)) {
579
- if (rel === path.join('.codex-plugin', 'plugin.json') || rel === '.ubp-managed') continue;
580
- hash.update(rel);
581
- hash.update(fs.readFileSync(path.join(pluginRoot, rel)));
582
- }
583
- return hash.digest('hex').slice(0, 12);
584
- }
585
-
586
- function buildPlugin({ repoRoot, pluginRoot, publishedRoot = pluginRoot }) {
587
- if (fs.existsSync(pluginRoot)) {
588
- const marker = path.join(pluginRoot, '.ubp-managed');
589
- const entries = fs.readdirSync(pluginRoot);
590
- if (entries.length > 0 && !fs.existsSync(marker)) {
591
- throw new Error(`refusing to replace unmanaged plugin directory: ${pluginRoot}`);
592
- }
593
- if (entries.length > 0) removeTree(pluginRoot);
594
- }
595
- ensureDir(pluginRoot);
596
-
597
- const installedSkills = [];
598
- for (const name of skillsForRuntime('codex')) {
599
- const sourceDir = path.join(repoRoot, 'skills', name);
600
- if (!fs.existsSync(path.join(sourceDir, 'SKILL.md'))) {
601
- throw new Error(`missing allowlisted Codex skill: ${name}`);
602
- }
603
- copySkill(sourceDir, path.join(pluginRoot, 'skills', name), name, name);
604
- installedSkills.push(name);
605
- }
606
-
607
- copyHooks(repoRoot, pluginRoot, publishedRoot);
608
- const mcpRuntime = buildMcpRuntime(repoRoot, pluginRoot);
609
- const command = mcpCommand(path.join(
610
- publishedRoot,
611
- path.relative(pluginRoot, mcpRuntime.launcher),
612
- ));
613
- writeAtomic(path.join(pluginRoot, '.mcp.json'), JSON.stringify({
614
- mcpServers: {
615
- [PLUGIN_NAME]: {
616
- type: 'stdio',
617
- command: command.command,
618
- args: command.args,
619
- },
620
- },
621
- }, null, 2) + '\n');
622
- writeAtomic(path.join(pluginRoot, 'command-map.json'), JSON.stringify(buildCommandMap(), null, 2) + '\n');
623
- if (fs.existsSync(path.join(repoRoot, 'LICENSE'))) {
624
- fs.copyFileSync(path.join(repoRoot, 'LICENSE'), path.join(pluginRoot, 'LICENSE'));
625
- }
626
-
627
- const pkg = JSON.parse(fs.readFileSync(path.join(repoRoot, 'package.json'), 'utf8'));
628
- const version = `${pkg.version}+codex.${pluginContentHash(pluginRoot, pkg.version)}`;
629
- const manifest = {
630
- name: PLUGIN_NAME,
631
- version,
632
- description: 'Codex-native Ultra Builder Pro workflows with a persistent safety kernel.',
633
- author: { name: typeof pkg.author === 'string' ? pkg.author : 'Ultra Builder Pro contributors' },
634
- homepage: pkg.homepage,
635
- repository: 'https://github.com/rocky2431/ultra-builder-pro-cli',
636
- license: pkg.license || 'MIT',
637
- keywords: ['codex', 'skills', 'agents', 'hooks', 'mcp', 'ultra-builder-pro'],
638
- skills: './skills/',
639
- mcpServers: './.mcp.json',
640
- interface: {
641
- displayName: 'Ultra Builder Pro',
642
- shortDescription: 'Codex-native engineering workflows and verification gates.',
643
- longDescription: 'Complete Codex adaptation of Ultra Builder Pro skills, command workflows, custom agents, lifecycle hooks, and a project-local persistence and safety kernel.',
644
- developerName: typeof pkg.author === 'string' ? pkg.author : 'Ultra Builder Pro contributors',
645
- category: 'Developer Tools',
646
- capabilities: ['Interactive', 'Write'],
647
- websiteURL: pkg.homepage,
648
- defaultPrompt: [
649
- 'Initialize this project with the Ultra Builder Pro workflow.',
650
- 'Run the Ultra review pipeline on my current changes.',
651
- 'Show the current Ultra project status, valid transitions, and host recommendation.',
652
- ],
653
- brandColor: '#111827',
654
- },
655
- };
656
- writeAtomic(path.join(pluginRoot, '.codex-plugin', 'plugin.json'), JSON.stringify(manifest, null, 2) + '\n');
657
- writeAtomic(path.join(pluginRoot, '.ubp-managed'), JSON.stringify({ source: 'ubp', adapter: 'codex', version }, null, 2) + '\n');
658
- return { root: publishedRoot, version, skills: installedSkills.sort() };
659
- }
660
-
661
- function tomlMultiline(value) {
662
- const escaped = String(value)
663
- .replace(/\\/g, '\\\\')
664
- .replace(/"""/g, '\\"\\"\\"')
665
- .replace(/\r/g, '')
666
- .replace(/\u0000/g, '');
667
- return `"""\\\n${escaped.trim()}\n"""`;
668
- }
669
-
670
- function buildAgentToml(sourceText) {
671
- const { fm, body } = parseFrontmatter(sourceText);
672
- const name = fm.name;
673
- const description = adaptHostText(String(fm.description || `${name} Ultra Builder Pro agent.`), name)
674
- .replace(/\s+/g, ' ')
675
- .trim();
676
- let instructions = adaptHostText(body, name);
677
- instructions = instructions.replace(
678
- /Consult your agent memory[^\n]*/g,
679
- 'Use the current checkout and parent-supplied context; do not assume persistent custom-agent memory.',
680
- );
681
- instructions = `You are a native Codex custom agent. Stay inside the delegated scope, preserve unrelated changes, and return concise evidence to the parent task.\n\n${instructions}`;
682
- return [
683
- `# ${MANAGED_MARKER}`,
684
- `name = ${JSON.stringify(name)}`,
685
- `description = ${JSON.stringify(description)}`,
686
- 'model_reasoning_effort = "high"',
687
- `developer_instructions = ${tomlMultiline(instructions)}`,
688
- '',
689
- ].join('\n');
690
- }
691
-
692
- function installAgents({ repoRoot, configDir }) {
693
- const sourceRoot = path.join(repoRoot, 'agents');
694
- const targetRoot = path.join(configDir, 'agents');
695
- ensureDir(targetRoot);
696
- const installed = [];
697
- for (const file of fs.readdirSync(sourceRoot).filter((name) => name.endsWith('.md')).sort()) {
698
- const targetFile = path.join(targetRoot, file.replace(/\.md$/, '.toml'));
699
- if (fs.existsSync(targetFile)) {
700
- const existing = fs.readFileSync(targetFile, 'utf8');
701
- if (!existing.startsWith(`# ${MANAGED_MARKER}`)) {
702
- throw new Error(`refusing to overwrite unmanaged Codex agent: ${targetFile}`);
703
- }
704
- }
705
- writeAtomic(targetFile, buildAgentToml(fs.readFileSync(path.join(sourceRoot, file), 'utf8')));
706
- installed.push(path.basename(targetFile));
707
- }
708
- return { root: targetRoot, installed };
709
- }
710
-
711
- module.exports = {
712
- PLUGIN_NAME,
713
- MANAGED_MARKER,
714
- COMMAND_NAMES,
715
- adaptHostText,
716
- buildCommandMap,
717
- buildHooksManifest,
718
- buildMcpRuntime,
719
- inspectInstalledRuntime,
720
- applyNativeDoctor,
721
- mcpCommand,
722
- buildPlugin,
723
- buildAgentToml,
724
- installAgents,
725
- };