ultra-builder-pro-cli 0.5.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.
- package/.ultra-template/delivery-report.json +9 -0
- package/.ultra-template/docs/research/README.md +53 -0
- package/.ultra-template/specs/architecture.md +250 -0
- package/.ultra-template/specs/discovery.md +248 -0
- package/.ultra-template/specs/product.md +223 -0
- package/.ultra-template/tasks/contexts/TEMPLATE.md +57 -0
- package/.ultra-template/tasks/tasks.json +33 -0
- package/.ultra-template/test-report.json +8 -0
- package/CHANGELOG.md +194 -0
- package/LICENSE +21 -0
- package/README.md +187 -0
- package/adapters/_shared/codex-assets.cjs +1128 -0
- package/adapters/_shared/codex-ultra-tools-entry.cjs +11 -0
- package/adapters/_shared/file-ops.cjs +115 -0
- package/adapters/_shared/frontmatter.cjs +52 -0
- package/adapters/_shared/handbook.cjs +144 -0
- package/adapters/_shared/md-to-toml.cjs +54 -0
- package/adapters/_shared/path-rewrite.cjs +79 -0
- package/adapters/_shared/rtk-detect.cjs +86 -0
- package/adapters/_shared/runtime-assets.cjs +70 -0
- package/adapters/_shared/settings-merge.cjs +76 -0
- package/adapters/_shared/tests/file-ops.test.cjs +54 -0
- package/adapters/_shared/tests/frontmatter.test.cjs +47 -0
- package/adapters/_shared/tests/handbook.test.cjs +86 -0
- package/adapters/_shared/tests/md-to-toml.test.cjs +48 -0
- package/adapters/_shared/tests/path-rewrite.test.cjs +60 -0
- package/adapters/_shared/tests/resolve-target.test.cjs +85 -0
- package/adapters/_shared/tests/rtk-detect.test.cjs +116 -0
- package/adapters/_shared/tests/runtime-assets.test.cjs +107 -0
- package/adapters/_shared/tests/settings-merge.test.cjs +85 -0
- package/adapters/_shared/tests/validate.test.cjs +30 -0
- package/adapters/_shared/validate.cjs +24 -0
- package/adapters/claude.js +182 -0
- package/adapters/codex.js +385 -0
- package/adapters/gemini.js +204 -0
- package/adapters/opencode.js +506 -0
- package/adapters/tests/claude.test.cjs +117 -0
- package/adapters/tests/codex-hook.test.cjs +90 -0
- package/adapters/tests/codex.test.cjs +356 -0
- package/adapters/tests/gemini.test.cjs +112 -0
- package/adapters/tests/opencode.test.cjs +246 -0
- package/agents/code-reviewer.md +102 -0
- package/agents/debugger.md +127 -0
- package/agents/review-code.md +125 -0
- package/agents/review-comments.md +98 -0
- package/agents/review-coordinator.md +146 -0
- package/agents/review-design.md +133 -0
- package/agents/review-errors.md +87 -0
- package/agents/review-tests.md +93 -0
- package/agents/tdd-runner.md +92 -0
- package/bin/handbook.js +54 -0
- package/bin/install.js +254 -0
- package/bin/orchestrator.js +214 -0
- package/commands/learn.md +41 -0
- package/commands/ultra-deliver.md +45 -0
- package/commands/ultra-dev.md +50 -0
- package/commands/ultra-init.md +51 -0
- package/commands/ultra-plan.md +49 -0
- package/commands/ultra-research.md +59 -0
- package/commands/ultra-status.md +46 -0
- package/commands/ultra-test.md +48 -0
- package/commands/ultra-think.md +45 -0
- package/docs/AGENT-CONTEXT.md +143 -0
- package/docs/ARCHITECTURE.md +197 -0
- package/docs/COMMIT-HASH-BACKFILL.md +101 -0
- package/docs/LEGACY-HERMES.md +1175 -0
- package/docs/PLAN.zh-CN.md +1683 -0
- package/docs/ROADMAP.md +102 -0
- package/docs/RUNTIME-COMPAT-MATRIX.md +98 -0
- package/docs/STATE-DB-ACCESS-POLICY.md +109 -0
- package/docs/USER-HANDBOOK-CONTRACT.md +61 -0
- package/hooks/README.md +24 -0
- package/hooks/active_task_context.py +44 -0
- package/hooks/adapters/codex.py +302 -0
- package/hooks/health_check.py +61 -0
- package/hooks/pre_stop_check.py +56 -0
- package/hooks/subagent_tracker.py +116 -0
- package/hooks/workflow_checkpoint.py +56 -0
- package/hooks/workflow_context.py +63 -0
- package/hooks/workflow_resume.py +50 -0
- package/mcp-server/lib/init-project.cjs +162 -0
- package/mcp-server/lib/llm-client.cjs +157 -0
- package/mcp-server/lib/llm-client.test.cjs +156 -0
- package/mcp-server/lib/plan-store.cjs +96 -0
- package/mcp-server/lib/plan-store.test.cjs +132 -0
- package/mcp-server/lib/prd-parser.cjs +110 -0
- package/mcp-server/lib/prd-parser.test.cjs +171 -0
- package/mcp-server/lib/pricing.cjs +53 -0
- package/mcp-server/lib/projector.cjs +158 -0
- package/mcp-server/lib/state-db.cjs +113 -0
- package/mcp-server/lib/state-db.test.cjs +116 -0
- package/mcp-server/lib/state-ops.cjs +725 -0
- package/mcp-server/lib/task-expander.cjs +123 -0
- package/mcp-server/lib/task-expander.test.cjs +253 -0
- package/mcp-server/lib/telemetry.cjs +72 -0
- package/mcp-server/lib/topo.cjs +131 -0
- package/mcp-server/lib/topo.test.cjs +158 -0
- package/mcp-server/server.cjs +482 -0
- package/mcp-server/tests/circuit-breaker.test.cjs +125 -0
- package/mcp-server/tests/commit-hash-flow.test.cjs +117 -0
- package/mcp-server/tests/concurrency-update.test.cjs +96 -0
- package/mcp-server/tests/concurrency.test.cjs +112 -0
- package/mcp-server/tests/db-ops.test.cjs +117 -0
- package/mcp-server/tests/init-project.test.cjs +141 -0
- package/mcp-server/tests/migrate.test.cjs +144 -0
- package/mcp-server/tests/projector.test.cjs +130 -0
- package/mcp-server/tests/server-contract.test.cjs +750 -0
- package/mcp-server/tests/staleness.test.cjs +190 -0
- package/mcp-server/tests/state-ops.test.cjs +286 -0
- package/mcp-server/tests/tagged-tasks.test.cjs +163 -0
- package/mcp-server/tests/telemetry.test.cjs +205 -0
- package/orchestrator/auto-merge.cjs +109 -0
- package/orchestrator/code-graph-watcher.cjs +121 -0
- package/orchestrator/daemon.cjs +112 -0
- package/orchestrator/dispatch-rules.cjs +93 -0
- package/orchestrator/parallel-orchestrator.cjs +195 -0
- package/orchestrator/planner/expand-prompt.cjs +62 -0
- package/orchestrator/planner/expand-prompt.test.cjs +52 -0
- package/orchestrator/planner/plan-builder.cjs +116 -0
- package/orchestrator/planner/plan-builder.test.cjs +165 -0
- package/orchestrator/planner/prd-prompt.cjs +44 -0
- package/orchestrator/planner/prd-prompt.test.cjs +30 -0
- package/orchestrator/recovery.cjs +70 -0
- package/orchestrator/session-runner.cjs +224 -0
- package/orchestrator/skill-miner.cjs +133 -0
- package/orchestrator/tests/auto-merge.test.cjs +216 -0
- package/orchestrator/tests/code-graph-watcher.test.cjs +183 -0
- package/orchestrator/tests/daemon.test.cjs +260 -0
- package/orchestrator/tests/dispatch-rules.test.cjs +122 -0
- package/orchestrator/tests/parallel-orchestrator.test.cjs +233 -0
- package/orchestrator/tests/phase-8b-gate.test.cjs +183 -0
- package/orchestrator/tests/recovery.test.cjs +190 -0
- package/orchestrator/tests/session-runner.test.cjs +314 -0
- package/orchestrator/tests/skill-miner.test.cjs +147 -0
- package/orchestrator/tests/worktree-manager.test.cjs +148 -0
- package/orchestrator/worktree-manager.cjs +131 -0
- package/output-styles/coding-vibes.md +67 -0
- package/output-styles/structural-thinking.md +61 -0
- package/package.json +109 -0
- package/settings.json +8 -0
- package/skills/cc-collab/SKILL.md +41 -0
- package/skills/code-review-expert/SKILL.md +118 -0
- package/skills/code-review-expert/references/code-quality-checklist.md +112 -0
- package/skills/code-review-expert/references/integration-checklist.md +46 -0
- package/skills/code-review-expert/references/removal-plan.md +52 -0
- package/skills/code-review-expert/references/security-checklist.md +100 -0
- package/skills/code-review-expert/references/solid-checklist.md +65 -0
- package/skills/codex-collab/SKILL.md +52 -0
- package/skills/codex-collab/evals/evals.json +40 -0
- package/skills/gemini-collab/SKILL.md +51 -0
- package/skills/gemini-collab/evals/evals.json +42 -0
- package/skills/integration-rules/SKILL.md +71 -0
- package/skills/learn/SKILL.md +117 -0
- package/skills/security-rules/SKILL.md +60 -0
- package/skills/testing-rules/SKILL.md +56 -0
- package/skills/ultra-deliver/SKILL.md +171 -0
- package/skills/ultra-dev/SKILL.md +324 -0
- package/skills/ultra-init/SKILL.md +148 -0
- package/skills/ultra-plan/SKILL.md +314 -0
- package/skills/ultra-research/SKILL.md +156 -0
- package/skills/ultra-research/steps/step-00-problem-validation.md +154 -0
- package/skills/ultra-research/steps/step-01-opportunity-discovery.md +172 -0
- package/skills/ultra-research/steps/step-02-market-assessment.md +195 -0
- package/skills/ultra-research/steps/step-03-competitive-landscape.md +197 -0
- package/skills/ultra-research/steps/step-04-product-strategy.md +196 -0
- package/skills/ultra-research/steps/step-05-assumptions-validation.md +234 -0
- package/skills/ultra-research/steps/step-10-user-personas.md +169 -0
- package/skills/ultra-research/steps/step-11-user-scenarios.md +181 -0
- package/skills/ultra-research/steps/step-20-user-stories.md +156 -0
- package/skills/ultra-research/steps/step-21-features-scope.md +157 -0
- package/skills/ultra-research/steps/step-22-success-metrics.md +195 -0
- package/skills/ultra-research/steps/step-30-architecture-context.md +154 -0
- package/skills/ultra-research/steps/step-31-solution-strategy.md +172 -0
- package/skills/ultra-research/steps/step-32-building-blocks.md +188 -0
- package/skills/ultra-research/steps/step-40-deployment.md +123 -0
- package/skills/ultra-research/steps/step-41-quality-risks.md +135 -0
- package/skills/ultra-research/steps/step-99-synthesis.md +188 -0
- package/skills/ultra-review/SKILL.md +437 -0
- package/skills/ultra-review/references/unified-schema.md +127 -0
- package/skills/ultra-review/scripts/review_verdict_update.py +99 -0
- package/skills/ultra-review/scripts/review_wait.py +120 -0
- package/skills/ultra-status/SKILL.md +162 -0
- package/skills/ultra-test/SKILL.md +195 -0
- package/skills/ultra-think/SKILL.md +109 -0
- package/skills/ultra-verify/SKILL.md +111 -0
- package/skills/ultra-verify/evals/evals.json +51 -0
- package/skills/ultra-verify/references/confidence-system.md +38 -0
- package/skills/ultra-verify/references/cross-verify-modes.md +73 -0
- package/skills/ultra-verify/scripts/verify_wait.py +131 -0
- package/spec/cli-protocol.md +118 -0
- package/spec/mcp-tools.yaml +658 -0
- package/spec/schemas/command-manifest.schema.json +47 -0
- package/spec/schemas/context-file.v4.5.schema.json +54 -0
- package/spec/schemas/mcp-tools.schema.json +136 -0
- package/spec/schemas/skill-manifest.schema.json +94 -0
- package/spec/schemas/state-db.sql +154 -0
- package/spec/schemas/tasks.v4.5.schema.json +66 -0
- package/ultra-tools/cli.cjs +121 -0
- package/ultra-tools/commands/db.cjs +175 -0
- package/ultra-tools/commands/legacy-memory.cjs +159 -0
- package/ultra-tools/commands/migrate.cjs +354 -0
- package/ultra-tools/commands/session.cjs +180 -0
- package/ultra-tools/commands/status.cjs +158 -0
- package/ultra-tools/commands/task.cjs +95 -0
- package/ultra-tools/legacy-memory.test.cjs +80 -0
- package/ultra-tools/status-command.test.cjs +132 -0
|
@@ -0,0 +1,658 @@
|
|
|
1
|
+
# Ultra Builder Pro — MCP tool contracts
|
|
2
|
+
# Single source for tool name, schema, errors, and CLI mapping.
|
|
3
|
+
# Validated by spec/schemas/mcp-tools.schema.json (run `npm run test:spec`).
|
|
4
|
+
# Trace: PLAN §7.3, decisions D12 / D29 / D31-D34.
|
|
5
|
+
|
|
6
|
+
version: '1.0'
|
|
7
|
+
|
|
8
|
+
info:
|
|
9
|
+
title: Ultra Builder Pro MCP tool contracts
|
|
10
|
+
phase: '1.1'
|
|
11
|
+
trace_to: 'PLAN docs/PLAN.zh-CN.md §7.3'
|
|
12
|
+
notes: |
|
|
13
|
+
This published contract contains only tools registered by the MCP server.
|
|
14
|
+
Host-native review, impact, skill discovery, and human-interaction capabilities
|
|
15
|
+
are documented by each adapter's capability map rather than advertised as MCP.
|
|
16
|
+
Generators consume this YAML to derive types, validators, and CLI parsers (R19).
|
|
17
|
+
Adding a tool requires: (a) update this file, (b) add valid+invalid
|
|
18
|
+
fixture to spec/fixtures/{valid,invalid}/, (c) `npm run test:spec` green.
|
|
19
|
+
|
|
20
|
+
families:
|
|
21
|
+
- { name: task, description: 'authoritative task lifecycle on state.db', phase: '2' }
|
|
22
|
+
- { name: session, description: 'execution-unit lifecycle with single-active-lease admission (D33)', phase: '4.5' }
|
|
23
|
+
- { name: plan, description: 'execution-plan artifact export and query (D34)', phase: '8a' }
|
|
24
|
+
|
|
25
|
+
tools:
|
|
26
|
+
|
|
27
|
+
# ─────────────────────────── task family ────────────────────────────────
|
|
28
|
+
- name: task.create
|
|
29
|
+
family: task
|
|
30
|
+
description: Create a new task in state.db. Emits task_created event. If `id` is omitted the server mints a uuid.
|
|
31
|
+
phase: '2'
|
|
32
|
+
writer_role: mcp
|
|
33
|
+
input_schema:
|
|
34
|
+
type: object
|
|
35
|
+
required: [title, type, priority]
|
|
36
|
+
additionalProperties: false
|
|
37
|
+
properties:
|
|
38
|
+
id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$', description: 'optional caller-supplied id; otherwise server mints a uuid' }
|
|
39
|
+
title: { type: string, minLength: 3 }
|
|
40
|
+
type: { type: string, enum: [architecture, feature, bugfix] }
|
|
41
|
+
priority: { type: string, enum: [P0, P1, P2, P3] }
|
|
42
|
+
complexity: { type: integer, minimum: 1, maximum: 10 }
|
|
43
|
+
deps: { type: array, items: { type: string } }
|
|
44
|
+
files_modified: { type: array, items: { type: string }, description: 'Phase 8A conflict detection' }
|
|
45
|
+
parent_id: { type: string, description: 'Phase 8A.3 parent reference for task.expand children' }
|
|
46
|
+
tag: { type: string, description: 'git branch tag (Phase 7.2)' }
|
|
47
|
+
trace_to: { type: string, description: 'spec anchor (e.g. spec/mcp-tools.yaml#task.create)' }
|
|
48
|
+
output_schema:
|
|
49
|
+
type: object
|
|
50
|
+
required: [id, status, created_at]
|
|
51
|
+
additionalProperties: false
|
|
52
|
+
properties:
|
|
53
|
+
id: { type: string, pattern: '^[a-zA-Z0-9_\-]+$' }
|
|
54
|
+
status: { type: string, enum: [pending] }
|
|
55
|
+
created_at: { type: string, format: date-time }
|
|
56
|
+
errors:
|
|
57
|
+
- { code: VALIDATION_ERROR, description: 'input failed schema validation' }
|
|
58
|
+
- { code: DUPLICATE_TASK_ID, description: 'task id already exists' }
|
|
59
|
+
- { code: STATE_DB_LOCKED, description: 'database is locked', retriable: true }
|
|
60
|
+
cli_subcommand: task create
|
|
61
|
+
emits_events: [task_created]
|
|
62
|
+
trace_to: '§7.3, §7.1'
|
|
63
|
+
|
|
64
|
+
- name: task.update
|
|
65
|
+
family: task
|
|
66
|
+
description: Patch a task's mutable fields. status transitions enforced server-side.
|
|
67
|
+
phase: '2'
|
|
68
|
+
writer_role: mcp
|
|
69
|
+
input_schema:
|
|
70
|
+
type: object
|
|
71
|
+
required: [id, patch]
|
|
72
|
+
additionalProperties: false
|
|
73
|
+
properties:
|
|
74
|
+
id: { type: string }
|
|
75
|
+
patch:
|
|
76
|
+
type: object
|
|
77
|
+
additionalProperties: false
|
|
78
|
+
properties:
|
|
79
|
+
status: { type: string, enum: [pending, in_progress, completed, blocked, expanded] }
|
|
80
|
+
priority: { type: string, enum: [P0, P1, P2, P3] }
|
|
81
|
+
complexity: { type: integer, minimum: 1, maximum: 10 }
|
|
82
|
+
deps: { type: array, items: { type: string } }
|
|
83
|
+
files_modified: { type: array, items: { type: string } }
|
|
84
|
+
session_id: { type: string }
|
|
85
|
+
stale: { type: boolean }
|
|
86
|
+
tag: { type: string }
|
|
87
|
+
completion_commit: { type: string, pattern: '^[0-9a-f]{7,40}$' }
|
|
88
|
+
output_schema:
|
|
89
|
+
type: object
|
|
90
|
+
required: [ok, task]
|
|
91
|
+
additionalProperties: false
|
|
92
|
+
properties:
|
|
93
|
+
ok: { type: boolean }
|
|
94
|
+
task: { type: object }
|
|
95
|
+
errors:
|
|
96
|
+
- { code: TASK_NOT_FOUND, description: 'no task with given id' }
|
|
97
|
+
- { code: ILLEGAL_STATUS_TRANSITION, description: 'transition rejected by state machine' }
|
|
98
|
+
- { code: VALIDATION_ERROR, description: 'patch failed schema validation' }
|
|
99
|
+
cli_subcommand: task update
|
|
100
|
+
emits_events: [task_started, task_completed, task_blocked, task_stale_marked]
|
|
101
|
+
trace_to: '§7.3, §7.2'
|
|
102
|
+
|
|
103
|
+
- name: task.list
|
|
104
|
+
family: task
|
|
105
|
+
description: List tasks filtered by status / tag / time window.
|
|
106
|
+
phase: '2'
|
|
107
|
+
readonly: true
|
|
108
|
+
writer_role: any
|
|
109
|
+
input_schema:
|
|
110
|
+
type: object
|
|
111
|
+
additionalProperties: false
|
|
112
|
+
properties:
|
|
113
|
+
status: { type: string, enum: [pending, in_progress, completed, blocked, expanded, any] }
|
|
114
|
+
tag: { type: string }
|
|
115
|
+
since: { type: string, format: date-time }
|
|
116
|
+
limit: { type: integer, minimum: 1, maximum: 1000 }
|
|
117
|
+
output_schema:
|
|
118
|
+
type: object
|
|
119
|
+
required: [tasks, count]
|
|
120
|
+
additionalProperties: false
|
|
121
|
+
properties:
|
|
122
|
+
tasks: { type: array, items: { type: object } }
|
|
123
|
+
count: { type: integer, minimum: 0 }
|
|
124
|
+
errors:
|
|
125
|
+
- { code: VALIDATION_ERROR, description: 'filter failed schema validation' }
|
|
126
|
+
cli_subcommand: task list
|
|
127
|
+
emits_events: []
|
|
128
|
+
trace_to: '§7.3'
|
|
129
|
+
|
|
130
|
+
- name: task.get
|
|
131
|
+
family: task
|
|
132
|
+
description: Fetch one task with its full row.
|
|
133
|
+
phase: '2'
|
|
134
|
+
readonly: true
|
|
135
|
+
writer_role: any
|
|
136
|
+
input_schema:
|
|
137
|
+
type: object
|
|
138
|
+
required: [id]
|
|
139
|
+
additionalProperties: false
|
|
140
|
+
properties:
|
|
141
|
+
id: { type: string }
|
|
142
|
+
output_schema:
|
|
143
|
+
type: object
|
|
144
|
+
required: [task]
|
|
145
|
+
additionalProperties: false
|
|
146
|
+
properties:
|
|
147
|
+
task: { type: object }
|
|
148
|
+
errors:
|
|
149
|
+
- { code: TASK_NOT_FOUND, description: 'no task with given id' }
|
|
150
|
+
cli_subcommand: task get
|
|
151
|
+
emits_events: []
|
|
152
|
+
trace_to: '§7.3'
|
|
153
|
+
|
|
154
|
+
- name: task.switch_tag
|
|
155
|
+
family: task
|
|
156
|
+
description: Change a task's tag (branch-scoped context partition, Phase 7.2). Emits task_tag_changed.
|
|
157
|
+
phase: '7.2'
|
|
158
|
+
writer_role: mcp
|
|
159
|
+
input_schema:
|
|
160
|
+
type: object
|
|
161
|
+
required: [id, tag]
|
|
162
|
+
additionalProperties: false
|
|
163
|
+
properties:
|
|
164
|
+
id: { type: string }
|
|
165
|
+
tag: { type: ['string', 'null'] }
|
|
166
|
+
output_schema:
|
|
167
|
+
type: object
|
|
168
|
+
required: [task_id, tag]
|
|
169
|
+
additionalProperties: false
|
|
170
|
+
properties:
|
|
171
|
+
task_id: { type: string }
|
|
172
|
+
tag: { type: ['string', 'null'] }
|
|
173
|
+
from: { type: ['string', 'null'] }
|
|
174
|
+
errors:
|
|
175
|
+
- { code: TASK_NOT_FOUND, description: 'no task with given id' }
|
|
176
|
+
- { code: VALIDATION_ERROR, description: 'task_id missing' }
|
|
177
|
+
cli_subcommand: task switch-tag
|
|
178
|
+
emits_events: [task_tag_changed]
|
|
179
|
+
trace_to: '§6, D26'
|
|
180
|
+
|
|
181
|
+
- name: task.delete
|
|
182
|
+
family: task
|
|
183
|
+
description: Hard-delete a task. Refuses if any in_progress session is bound.
|
|
184
|
+
phase: '2'
|
|
185
|
+
writer_role: mcp
|
|
186
|
+
input_schema:
|
|
187
|
+
type: object
|
|
188
|
+
required: [id]
|
|
189
|
+
additionalProperties: false
|
|
190
|
+
properties:
|
|
191
|
+
id: { type: string }
|
|
192
|
+
force: { type: boolean, default: false }
|
|
193
|
+
output_schema:
|
|
194
|
+
type: object
|
|
195
|
+
required: [ok]
|
|
196
|
+
additionalProperties: false
|
|
197
|
+
properties:
|
|
198
|
+
ok: { type: boolean }
|
|
199
|
+
errors:
|
|
200
|
+
- { code: TASK_NOT_FOUND, description: 'no task with given id' }
|
|
201
|
+
- { code: SESSION_ACTIVE, description: 'task has an active session; pass force=true to override' }
|
|
202
|
+
cli_subcommand: task delete
|
|
203
|
+
emits_events: []
|
|
204
|
+
trace_to: '§7.3'
|
|
205
|
+
|
|
206
|
+
- name: task.init_project
|
|
207
|
+
family: task
|
|
208
|
+
description: |
|
|
209
|
+
Bootstrap a fresh `.ultra/` skeleton in target_dir from the bundled
|
|
210
|
+
templates/.ultra/ source. Copies spec templates, tasks.json, context
|
|
211
|
+
template, and report stubs. Phase 3.1 entry point for /ultra-init.
|
|
212
|
+
phase: '3'
|
|
213
|
+
writer_role: mcp
|
|
214
|
+
input_schema:
|
|
215
|
+
type: object
|
|
216
|
+
required: [target_dir, project_name]
|
|
217
|
+
additionalProperties: false
|
|
218
|
+
properties:
|
|
219
|
+
target_dir:
|
|
220
|
+
type: string
|
|
221
|
+
description: absolute or repo-relative path of the project root where `.ultra/` will be created
|
|
222
|
+
project_name:
|
|
223
|
+
type: string
|
|
224
|
+
minLength: 1
|
|
225
|
+
project_type:
|
|
226
|
+
type: string
|
|
227
|
+
enum: [web, api, cli, fullstack, other]
|
|
228
|
+
description: optional; skill will pass detected value when available
|
|
229
|
+
stack:
|
|
230
|
+
type: string
|
|
231
|
+
description: optional tech stack descriptor (comma-separated for fullstack)
|
|
232
|
+
overwrite:
|
|
233
|
+
type: boolean
|
|
234
|
+
default: false
|
|
235
|
+
description: when true, back up an existing `.ultra/` to `.ultra.backup.<ts>` then re-create
|
|
236
|
+
source_template:
|
|
237
|
+
type: string
|
|
238
|
+
description: override path to the template root (defaults to bundled templates/.ultra/)
|
|
239
|
+
output_schema:
|
|
240
|
+
type: object
|
|
241
|
+
required: [created_path, status, copied_files]
|
|
242
|
+
additionalProperties: false
|
|
243
|
+
properties:
|
|
244
|
+
created_path:
|
|
245
|
+
type: string
|
|
246
|
+
description: absolute path to the created `.ultra/` directory
|
|
247
|
+
status:
|
|
248
|
+
type: string
|
|
249
|
+
enum: [created, overwritten]
|
|
250
|
+
copied_files:
|
|
251
|
+
type: array
|
|
252
|
+
items: { type: string }
|
|
253
|
+
description: paths relative to created_path
|
|
254
|
+
backup_path:
|
|
255
|
+
type: string
|
|
256
|
+
description: set only when status=overwritten
|
|
257
|
+
errors:
|
|
258
|
+
- { code: ULTRA_DIR_EXISTS, description: '.ultra/ already exists and overwrite=false' }
|
|
259
|
+
- { code: TEMPLATE_MISSING, description: 'source_template path does not exist' }
|
|
260
|
+
- { code: TARGET_NOT_DIR, description: 'target_dir is not a directory' }
|
|
261
|
+
- { code: IO_ERROR, description: 'filesystem write failed', retriable: true }
|
|
262
|
+
cli_subcommand: task init-project
|
|
263
|
+
emits_events: [project_initialized]
|
|
264
|
+
trace_to: 'PLAN §6 Phase 3.1'
|
|
265
|
+
|
|
266
|
+
- name: task.expand
|
|
267
|
+
family: task
|
|
268
|
+
description: Expand a parent task into N child sub-tasks (Phase 8A).
|
|
269
|
+
phase: '8a'
|
|
270
|
+
writer_role: mcp
|
|
271
|
+
input_schema:
|
|
272
|
+
type: object
|
|
273
|
+
required: [id]
|
|
274
|
+
additionalProperties: false
|
|
275
|
+
properties:
|
|
276
|
+
id: { type: string }
|
|
277
|
+
sub_count: { type: integer, minimum: 1, maximum: 16 }
|
|
278
|
+
strategy: { type: string, enum: [llm], default: llm }
|
|
279
|
+
output_schema:
|
|
280
|
+
type: object
|
|
281
|
+
required: [parent_id, children]
|
|
282
|
+
additionalProperties: false
|
|
283
|
+
properties:
|
|
284
|
+
parent_id: { type: string }
|
|
285
|
+
children: { type: array, items: { type: object } }
|
|
286
|
+
errors:
|
|
287
|
+
- { code: TASK_NOT_FOUND, description: 'parent id missing' }
|
|
288
|
+
- { code: ALREADY_EXPANDED, description: 'task is already expanded' }
|
|
289
|
+
cli_subcommand: task expand
|
|
290
|
+
emits_events: [task_expanded]
|
|
291
|
+
trace_to: '§7.3, D34'
|
|
292
|
+
|
|
293
|
+
- name: task.parse_prd
|
|
294
|
+
family: task
|
|
295
|
+
description: Parse a PRD document into a task graph (Phase 8A). When dry_run=true the tasks are returned without writing to state.db (supports ultra-plan human gate workflow).
|
|
296
|
+
phase: '8a'
|
|
297
|
+
writer_role: mcp
|
|
298
|
+
input_schema:
|
|
299
|
+
type: object
|
|
300
|
+
additionalProperties: false
|
|
301
|
+
properties:
|
|
302
|
+
prd_path: { type: string }
|
|
303
|
+
prd_text: { type: string }
|
|
304
|
+
tag: { type: string }
|
|
305
|
+
dry_run: { type: boolean, default: false, description: 'when true, do not persist to state.db — used by ultra-plan gate to preview before approve' }
|
|
306
|
+
output_schema:
|
|
307
|
+
type: object
|
|
308
|
+
required: [tasks, topo]
|
|
309
|
+
additionalProperties: false
|
|
310
|
+
properties:
|
|
311
|
+
tasks: { type: array, items: { type: object } }
|
|
312
|
+
topo: { type: array, items: { type: array, items: { type: string } } }
|
|
313
|
+
errors:
|
|
314
|
+
- { code: NO_INPUT, description: 'one of prd_path or prd_text required' }
|
|
315
|
+
- { code: PARSE_FAILED, description: 'PRD could not be parsed into tasks' }
|
|
316
|
+
cli_subcommand: task parse-prd
|
|
317
|
+
emits_events: [task_created]
|
|
318
|
+
trace_to: '§7.3, D34'
|
|
319
|
+
|
|
320
|
+
- name: task.dependency_topo
|
|
321
|
+
family: task
|
|
322
|
+
description: Compute topological waves for a set of tasks; consumed by execution-plan.
|
|
323
|
+
phase: '8a'
|
|
324
|
+
readonly: true
|
|
325
|
+
input_schema:
|
|
326
|
+
type: object
|
|
327
|
+
additionalProperties: false
|
|
328
|
+
properties:
|
|
329
|
+
task_ids: { type: array, items: { type: string } }
|
|
330
|
+
output_schema:
|
|
331
|
+
type: object
|
|
332
|
+
required: [waves]
|
|
333
|
+
additionalProperties: false
|
|
334
|
+
properties:
|
|
335
|
+
waves: { type: array, items: { type: array, items: { type: string } } }
|
|
336
|
+
cycles: { type: array, items: { type: array, items: { type: string } } }
|
|
337
|
+
errors:
|
|
338
|
+
- { code: CYCLE_DETECTED, description: 'dependency graph has cycles' }
|
|
339
|
+
cli_subcommand: task topo
|
|
340
|
+
emits_events: []
|
|
341
|
+
trace_to: '§7.3, D34'
|
|
342
|
+
|
|
343
|
+
- name: task.append_event
|
|
344
|
+
family: task
|
|
345
|
+
description: Append a row to events table. Returns assigned id (subscribe cursor).
|
|
346
|
+
phase: '2'
|
|
347
|
+
writer_role: any
|
|
348
|
+
input_schema:
|
|
349
|
+
type: object
|
|
350
|
+
required: [type]
|
|
351
|
+
additionalProperties: false
|
|
352
|
+
properties:
|
|
353
|
+
task_id: { type: string }
|
|
354
|
+
session_id: { type: string }
|
|
355
|
+
runtime: { type: string, enum: [claude, opencode, codex, gemini] }
|
|
356
|
+
type:
|
|
357
|
+
type: string
|
|
358
|
+
enum:
|
|
359
|
+
- task_created
|
|
360
|
+
- task_started
|
|
361
|
+
- task_completed
|
|
362
|
+
- task_failed
|
|
363
|
+
- task_blocked
|
|
364
|
+
- task_expanded
|
|
365
|
+
- task_stale_marked
|
|
366
|
+
- session_spawned
|
|
367
|
+
- session_closed
|
|
368
|
+
- session_crashed
|
|
369
|
+
- session_orphaned
|
|
370
|
+
- session_heartbeat_lost
|
|
371
|
+
- spec_changed
|
|
372
|
+
- context_updated
|
|
373
|
+
- plan_approved
|
|
374
|
+
- commit_pushed
|
|
375
|
+
- review_verdict
|
|
376
|
+
- merge_conflict
|
|
377
|
+
- auto_merged
|
|
378
|
+
- cost_alert
|
|
379
|
+
- token_alert
|
|
380
|
+
- circuit_open
|
|
381
|
+
payload: { type: object }
|
|
382
|
+
output_schema:
|
|
383
|
+
type: object
|
|
384
|
+
required: [event_id, ts]
|
|
385
|
+
additionalProperties: false
|
|
386
|
+
properties:
|
|
387
|
+
event_id: { type: integer, minimum: 1 }
|
|
388
|
+
ts: { type: string, format: date-time }
|
|
389
|
+
errors:
|
|
390
|
+
- { code: VALIDATION_ERROR, description: 'event payload failed validation' }
|
|
391
|
+
- { code: STATE_DB_LOCKED, description: 'database is locked', retriable: true }
|
|
392
|
+
cli_subcommand: task append-event
|
|
393
|
+
emits_events: []
|
|
394
|
+
trace_to: '§7.2, D31'
|
|
395
|
+
|
|
396
|
+
- name: task.subscribe_events
|
|
397
|
+
family: task
|
|
398
|
+
description: Pull events with id > since_id. Cursor is monotonic (D31, R26).
|
|
399
|
+
phase: '2'
|
|
400
|
+
readonly: true
|
|
401
|
+
input_schema:
|
|
402
|
+
type: object
|
|
403
|
+
required: [since_id]
|
|
404
|
+
additionalProperties: false
|
|
405
|
+
properties:
|
|
406
|
+
since_id: { type: integer, minimum: 0 }
|
|
407
|
+
types: { type: array, items: { type: string } }
|
|
408
|
+
task_id: { type: string }
|
|
409
|
+
limit: { type: integer, minimum: 1, maximum: 500, default: 100 }
|
|
410
|
+
output_schema:
|
|
411
|
+
type: object
|
|
412
|
+
required: [events, next_since_id]
|
|
413
|
+
additionalProperties: false
|
|
414
|
+
properties:
|
|
415
|
+
events: { type: array, items: { type: object } }
|
|
416
|
+
next_since_id: { type: integer, minimum: 0 }
|
|
417
|
+
errors:
|
|
418
|
+
- { code: VALIDATION_ERROR, description: 'cursor or filter invalid' }
|
|
419
|
+
cli_subcommand: task subscribe
|
|
420
|
+
emits_events: []
|
|
421
|
+
trace_to: '§7.2, D31'
|
|
422
|
+
|
|
423
|
+
# ────────────────────────── session family ──────────────────────────────
|
|
424
|
+
- name: session.spawn
|
|
425
|
+
family: session
|
|
426
|
+
description: Register execution-session intent, lease, and proposed worktree/artifact paths. The orchestrator creates the process and worktree after this admission step.
|
|
427
|
+
phase: '4.5'
|
|
428
|
+
writer_role: mcp
|
|
429
|
+
input_schema:
|
|
430
|
+
type: object
|
|
431
|
+
required: [task_id, runtime]
|
|
432
|
+
additionalProperties: false
|
|
433
|
+
properties:
|
|
434
|
+
task_id: { type: string }
|
|
435
|
+
runtime: { type: string, enum: [claude, opencode, codex, gemini] }
|
|
436
|
+
takeover: { type: boolean, default: false, description: 'override active lease (D33 takeover strategy)' }
|
|
437
|
+
worktree_base: { type: string }
|
|
438
|
+
output_schema:
|
|
439
|
+
type: object
|
|
440
|
+
required: [sid, worktree_path, artifact_dir, lease_expires_at]
|
|
441
|
+
additionalProperties: false
|
|
442
|
+
properties:
|
|
443
|
+
sid: { type: string }
|
|
444
|
+
worktree_path: { type: string }
|
|
445
|
+
artifact_dir: { type: string }
|
|
446
|
+
lease_expires_at: { type: string, format: date-time }
|
|
447
|
+
errors:
|
|
448
|
+
- { code: TASK_NOT_FOUND, description: 'task id missing' }
|
|
449
|
+
- { code: ADMISSION_DENIED, description: 'active lease exists; choose takeover/resume/abandon' }
|
|
450
|
+
cli_subcommand: session spawn
|
|
451
|
+
emits_events: [session_spawned]
|
|
452
|
+
trace_to: '§7.3, D20, D33'
|
|
453
|
+
|
|
454
|
+
- name: session.close
|
|
455
|
+
family: session
|
|
456
|
+
description: Close a session and release its lease.
|
|
457
|
+
phase: '4.5'
|
|
458
|
+
writer_role: mcp
|
|
459
|
+
input_schema:
|
|
460
|
+
type: object
|
|
461
|
+
required: [sid, status]
|
|
462
|
+
additionalProperties: false
|
|
463
|
+
properties:
|
|
464
|
+
sid: { type: string }
|
|
465
|
+
status: { type: string, enum: [completed, crashed, orphan] }
|
|
466
|
+
output_schema:
|
|
467
|
+
type: object
|
|
468
|
+
required: [ok]
|
|
469
|
+
additionalProperties: false
|
|
470
|
+
properties:
|
|
471
|
+
ok: { type: boolean }
|
|
472
|
+
errors:
|
|
473
|
+
- { code: SESSION_NOT_FOUND, description: 'sid unknown' }
|
|
474
|
+
cli_subcommand: session close
|
|
475
|
+
emits_events: [session_closed, session_crashed, session_orphaned]
|
|
476
|
+
trace_to: '§7.3, D32'
|
|
477
|
+
|
|
478
|
+
- name: session.get
|
|
479
|
+
family: session
|
|
480
|
+
description: Fetch a session row.
|
|
481
|
+
phase: '4.5'
|
|
482
|
+
readonly: true
|
|
483
|
+
input_schema:
|
|
484
|
+
type: object
|
|
485
|
+
required: [sid]
|
|
486
|
+
additionalProperties: false
|
|
487
|
+
properties:
|
|
488
|
+
sid: { type: string }
|
|
489
|
+
output_schema:
|
|
490
|
+
type: object
|
|
491
|
+
required: [session]
|
|
492
|
+
additionalProperties: false
|
|
493
|
+
properties:
|
|
494
|
+
session: { type: object }
|
|
495
|
+
errors:
|
|
496
|
+
- { code: SESSION_NOT_FOUND, description: 'sid unknown' }
|
|
497
|
+
cli_subcommand: session get
|
|
498
|
+
emits_events: []
|
|
499
|
+
trace_to: '§7.3'
|
|
500
|
+
|
|
501
|
+
- name: session.list
|
|
502
|
+
family: session
|
|
503
|
+
description: List sessions filtered by status (default 'running') and optional task_id. Read-only snapshot for /ultra-status + orchestrator dashboards.
|
|
504
|
+
phase: '4.5'
|
|
505
|
+
readonly: true
|
|
506
|
+
input_schema:
|
|
507
|
+
type: object
|
|
508
|
+
additionalProperties: false
|
|
509
|
+
properties:
|
|
510
|
+
status: { type: string, enum: [running, completed, crashed, orphan] }
|
|
511
|
+
task_id: { type: string }
|
|
512
|
+
limit: { type: integer, minimum: 1, maximum: 500, default: 100 }
|
|
513
|
+
output_schema:
|
|
514
|
+
type: object
|
|
515
|
+
required: [sessions, count]
|
|
516
|
+
additionalProperties: false
|
|
517
|
+
properties:
|
|
518
|
+
sessions: { type: array, items: { type: object } }
|
|
519
|
+
count: { type: integer, minimum: 0 }
|
|
520
|
+
errors:
|
|
521
|
+
- { code: STATE_DB_ERROR, description: 'database unavailable', retriable: true }
|
|
522
|
+
cli_subcommand: session list
|
|
523
|
+
emits_events: []
|
|
524
|
+
trace_to: '§7.3, Phase 4.5.4'
|
|
525
|
+
|
|
526
|
+
- name: session.admission_check
|
|
527
|
+
family: session
|
|
528
|
+
description: Check whether spawning a new session for task_id is allowed (D33). Returns recommended action.
|
|
529
|
+
phase: '4.5'
|
|
530
|
+
readonly: true
|
|
531
|
+
input_schema:
|
|
532
|
+
type: object
|
|
533
|
+
required: [task_id]
|
|
534
|
+
additionalProperties: false
|
|
535
|
+
properties:
|
|
536
|
+
task_id: { type: string }
|
|
537
|
+
runtime: { type: string, enum: [claude, opencode, codex, gemini] }
|
|
538
|
+
output_schema:
|
|
539
|
+
type: object
|
|
540
|
+
required: [can_spawn, recommended_action]
|
|
541
|
+
additionalProperties: false
|
|
542
|
+
properties:
|
|
543
|
+
can_spawn: { type: boolean }
|
|
544
|
+
conflict:
|
|
545
|
+
type: object
|
|
546
|
+
properties:
|
|
547
|
+
sid: { type: string }
|
|
548
|
+
status: { type: string }
|
|
549
|
+
heartbeat_age_ms: { type: integer, minimum: 0 }
|
|
550
|
+
recommended_action:
|
|
551
|
+
type: string
|
|
552
|
+
enum: [spawn, takeover, resume, abandon, blocked_by_breaker]
|
|
553
|
+
errors:
|
|
554
|
+
- { code: TASK_NOT_FOUND, description: 'task id missing' }
|
|
555
|
+
cli_subcommand: session admission
|
|
556
|
+
emits_events: []
|
|
557
|
+
trace_to: '§7.3, D33'
|
|
558
|
+
|
|
559
|
+
- name: session.heartbeat
|
|
560
|
+
family: session
|
|
561
|
+
description: Refresh lease for a running session. Lease expires after grace period without heartbeat.
|
|
562
|
+
phase: '4.5'
|
|
563
|
+
writer_role: mcp
|
|
564
|
+
input_schema:
|
|
565
|
+
type: object
|
|
566
|
+
required: [sid]
|
|
567
|
+
additionalProperties: false
|
|
568
|
+
properties:
|
|
569
|
+
sid: { type: string }
|
|
570
|
+
output_schema:
|
|
571
|
+
type: object
|
|
572
|
+
required: [ok, lease_expires_at]
|
|
573
|
+
additionalProperties: false
|
|
574
|
+
properties:
|
|
575
|
+
ok: { type: boolean }
|
|
576
|
+
lease_expires_at: { type: string, format: date-time }
|
|
577
|
+
errors:
|
|
578
|
+
- { code: SESSION_NOT_FOUND, description: 'sid unknown' }
|
|
579
|
+
- { code: LEASE_EXPIRED, description: 'lease already expired; need takeover/resume' }
|
|
580
|
+
cli_subcommand: session heartbeat
|
|
581
|
+
emits_events: [session_heartbeat_lost]
|
|
582
|
+
trace_to: '§7.3, D32'
|
|
583
|
+
|
|
584
|
+
- name: session.subscribe_events
|
|
585
|
+
family: session
|
|
586
|
+
description: Pull session-related events with cursor.
|
|
587
|
+
phase: '4.5'
|
|
588
|
+
readonly: true
|
|
589
|
+
input_schema:
|
|
590
|
+
type: object
|
|
591
|
+
required: [since_id]
|
|
592
|
+
additionalProperties: false
|
|
593
|
+
properties:
|
|
594
|
+
since_id: { type: integer, minimum: 0 }
|
|
595
|
+
sid: { type: string }
|
|
596
|
+
limit: { type: integer, minimum: 1, maximum: 500, default: 100 }
|
|
597
|
+
output_schema:
|
|
598
|
+
type: object
|
|
599
|
+
required: [events, next_since_id]
|
|
600
|
+
additionalProperties: false
|
|
601
|
+
properties:
|
|
602
|
+
events: { type: array, items: { type: object } }
|
|
603
|
+
next_since_id: { type: integer, minimum: 0 }
|
|
604
|
+
errors:
|
|
605
|
+
- { code: VALIDATION_ERROR, description: 'cursor invalid' }
|
|
606
|
+
cli_subcommand: session subscribe
|
|
607
|
+
emits_events: []
|
|
608
|
+
trace_to: '§7.3, D31'
|
|
609
|
+
|
|
610
|
+
# ────────────────────────── plan family (D34) ───────────────────────────
|
|
611
|
+
- name: plan.export
|
|
612
|
+
family: plan
|
|
613
|
+
description: Render the current execution-plan artifact to disk (waves + ownership + conflict surface).
|
|
614
|
+
phase: '8a'
|
|
615
|
+
writer_role: mcp
|
|
616
|
+
input_schema:
|
|
617
|
+
type: object
|
|
618
|
+
required: [out_path]
|
|
619
|
+
additionalProperties: false
|
|
620
|
+
properties:
|
|
621
|
+
format: { type: string, enum: [json, md], default: json }
|
|
622
|
+
out_path: { type: string }
|
|
623
|
+
tag: { type: string }
|
|
624
|
+
output_schema:
|
|
625
|
+
type: object
|
|
626
|
+
required: [plan_path, wave_count]
|
|
627
|
+
additionalProperties: false
|
|
628
|
+
properties:
|
|
629
|
+
plan_path: { type: string }
|
|
630
|
+
wave_count: { type: integer, minimum: 0 }
|
|
631
|
+
errors:
|
|
632
|
+
- { code: NO_TASKS, description: 'no tasks to plan' }
|
|
633
|
+
- { code: WRITE_FAILED, description: 'cannot write plan file' }
|
|
634
|
+
cli_subcommand: plan export
|
|
635
|
+
emits_events: [plan_approved]
|
|
636
|
+
trace_to: '§7.3, D34'
|
|
637
|
+
|
|
638
|
+
- name: plan.get
|
|
639
|
+
family: plan
|
|
640
|
+
description: Read a section of the current project's persisted .ultra/execution-plan.json artifact.
|
|
641
|
+
phase: '8a'
|
|
642
|
+
readonly: true
|
|
643
|
+
input_schema:
|
|
644
|
+
type: object
|
|
645
|
+
additionalProperties: false
|
|
646
|
+
properties:
|
|
647
|
+
section: { type: string, enum: [tasks, topo, conflicts, all], default: all }
|
|
648
|
+
output_schema:
|
|
649
|
+
type: object
|
|
650
|
+
required: [plan]
|
|
651
|
+
additionalProperties: false
|
|
652
|
+
properties:
|
|
653
|
+
plan: { type: object }
|
|
654
|
+
errors:
|
|
655
|
+
- { code: NO_PLAN, description: 'no plan has been computed yet' }
|
|
656
|
+
cli_subcommand: plan get
|
|
657
|
+
emits_events: []
|
|
658
|
+
trace_to: '§7.3, D34'
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://ultra-builder-pro.dev/spec/command-manifest.schema.json",
|
|
4
|
+
"title": "Command manifest (frontmatter)",
|
|
5
|
+
"description": "YAML frontmatter contract for commands/ultra-*.md thin-shell files. Phase 3 薄壳化: 命令文件 ≤ 80 行正文,真实 workflow 放 skills/<name>/SKILL.md。additionalProperties=false (PLAN R19).",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["description"],
|
|
8
|
+
"additionalProperties": false,
|
|
9
|
+
"properties": {
|
|
10
|
+
"description": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"minLength": 10,
|
|
13
|
+
"description": "一句话触发描述; 给 runtime 的 skill router / 用户命令列表使用"
|
|
14
|
+
},
|
|
15
|
+
"argument-hint": {
|
|
16
|
+
"oneOf": [
|
|
17
|
+
{ "type": "string" },
|
|
18
|
+
{ "type": "array", "items": { "type": "string" }, "minItems": 1 }
|
|
19
|
+
],
|
|
20
|
+
"description": "Claude Code convention: hint shown after slash-command name. Both `argument-hint: [foo]` (YAML array form) and `argument-hint: \"[foo]\"` (string form) are accepted."
|
|
21
|
+
},
|
|
22
|
+
"allowed-tools": {
|
|
23
|
+
"type": "string",
|
|
24
|
+
"description": "Claude Code convention: comma-separated tool allowlist"
|
|
25
|
+
},
|
|
26
|
+
"model": {
|
|
27
|
+
"type": "string",
|
|
28
|
+
"enum": ["haiku", "sonnet", "opus"],
|
|
29
|
+
"description": "Claude Code convention: model routing hint"
|
|
30
|
+
},
|
|
31
|
+
"workflow-ref": {
|
|
32
|
+
"type": "string",
|
|
33
|
+
"pattern": "^@skills/[a-z][a-z0-9\\-]*/SKILL\\.md$",
|
|
34
|
+
"description": "Phase 3 薄壳关键字段: 指向 skills/<name>/SKILL.md; 存在即表示该命令已迁为薄壳"
|
|
35
|
+
},
|
|
36
|
+
"mcp_tools_required": {
|
|
37
|
+
"type": "array",
|
|
38
|
+
"items": { "type": "string", "pattern": "^[a-z]+\\.[a-z_]+$" },
|
|
39
|
+
"uniqueItems": true,
|
|
40
|
+
"description": "Phase 3+: 命令运行时会调用的 MCP tool 名单; 无 MCP 时走 cli_fallback"
|
|
41
|
+
},
|
|
42
|
+
"cli_fallback": {
|
|
43
|
+
"type": "string",
|
|
44
|
+
"description": "Phase 3+: MCP 不可达时回退的 ultra-tools 子命令 (e.g. 'init' -> 'ultra-tools init')"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|