universal-dev-standards 6.8.0 → 6.10.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/bin/uds.js +12 -2
- package/bundled/ai/standards/acceptance-criteria-traceability.ai.yaml +14 -2
- package/bundled/ai/standards/adr-standards.ai.yaml +14 -2
- package/bundled/ai/standards/code-review.ai.yaml +13 -3
- package/bundled/ai/standards/commit-message.ai.yaml +8 -4
- package/bundled/ai/standards/deferred-item-exit.ai.yaml +225 -0
- package/bundled/ai/standards/feature-discovery-standards.ai.yaml +14 -2
- package/bundled/ai/standards/governance-layer.ai.yaml +128 -2
- package/bundled/ai/standards/logging.ai.yaml +2 -2
- package/bundled/ai/standards/retrospective-standards.ai.yaml +14 -2
- package/bundled/ai/standards/reverse-engineering-standards.ai.yaml +73 -2
- package/bundled/ai/standards/security-standards.ai.yaml +2 -2
- package/bundled/ai/standards/spec-driven-development.ai.yaml +14 -2
- package/bundled/ai/standards/tech-debt-standards.ai.yaml +87 -3
- package/bundled/ai/standards/turn-completion-integrity.ai.yaml +131 -0
- package/bundled/core/acceptance-criteria-traceability.md +5 -2
- package/bundled/core/adr-standards.md +26 -2
- package/bundled/core/agent-communication-protocol.md +8 -0
- package/bundled/core/branch-completion.md +8 -0
- package/bundled/core/change-batching-standards.md +8 -0
- package/bundled/core/code-review-checklist.md +5 -2
- package/bundled/core/context-aware-loading.md +1 -1
- package/bundled/core/deferred-item-exit.md +254 -0
- package/bundled/core/execution-history.md +8 -0
- package/bundled/core/feature-discovery-standards.md +5 -1
- package/bundled/core/governance-layer.md +114 -2
- package/bundled/core/pipeline-integration-standards.md +8 -0
- package/bundled/core/retrospective-standards.md +4 -2
- package/bundled/core/reverse-engineering-standards.md +81 -2
- package/bundled/core/spec-driven-development.md +8 -2
- package/bundled/core/tech-debt-standards.md +67 -8
- package/bundled/core/turn-completion-integrity.md +196 -0
- package/bundled/core/workflow-enforcement.md +8 -0
- package/bundled/core/workflow-state-protocol.md +8 -0
- package/bundled/hooks/check-dangerous-cmd.mjs +60 -0
- package/bundled/hooks/check-logging-standard.mjs +59 -0
- package/bundled/hooks/check-turn-completion.mjs +233 -0
- package/bundled/hooks/inject-standards.mjs +183 -0
- package/bundled/hooks/telemetry-wrapper.mjs +77 -0
- package/bundled/hooks/turn-completion/detect.mjs +99 -0
- package/bundled/hooks/turn-completion/locales/en.mjs +159 -0
- package/bundled/hooks/turn-completion/locales/zh-TW.mjs +166 -0
- package/bundled/hooks/validate-commit-msg.mjs +104 -0
- package/bundled/locales/zh-CN/CHANGELOG.md +73 -3
- package/bundled/locales/zh-CN/CLAUDE.md +1 -1
- package/bundled/locales/zh-CN/README.md +2 -2
- package/bundled/locales/zh-CN/SECURITY.md +1 -1
- package/bundled/locales/zh-CN/core/adr-standards.md +1 -1
- package/bundled/locales/zh-CN/core/agent-communication-protocol.md +7 -0
- package/bundled/locales/zh-CN/core/branch-completion.md +7 -0
- package/bundled/locales/zh-CN/core/change-batching-standards.md +7 -0
- package/bundled/locales/zh-CN/core/execution-history.md +7 -0
- package/bundled/locales/zh-CN/core/governance-layer.md +118 -6
- package/bundled/locales/zh-CN/core/pipeline-integration-standards.md +7 -0
- package/bundled/locales/zh-CN/core/retrospective-standards.md +1 -1
- package/bundled/locales/zh-CN/core/tech-debt-standards.md +71 -4
- package/bundled/locales/zh-CN/core/turn-completion-integrity.md +190 -0
- package/bundled/locales/zh-CN/core/workflow-enforcement.md +7 -0
- package/bundled/locales/zh-CN/core/workflow-state-protocol.md +7 -0
- package/bundled/locales/zh-CN/docs/CHEATSHEET.md +8 -1
- package/bundled/locales/zh-CN/docs/CLI-INIT-OPTIONS.md +29 -68
- package/bundled/locales/zh-CN/docs/FEATURE-REFERENCE.md +25 -15
- package/bundled/locales/zh-CN/docs/MIGRATION-v6.md +8 -4
- package/bundled/locales/zh-CN/docs/USAGE-MODES-COMPARISON.md +1 -2
- package/bundled/locales/zh-CN/integrations/google-antigravity/{INSTRUCTIONS.md → AGENTS.md} +1 -1
- package/bundled/locales/zh-CN/integrations/google-antigravity/README.md +3 -3
- package/bundled/locales/zh-CN/skills/atdd-assistant/SKILL.md +2 -0
- package/bundled/locales/zh-CN/skills/bdd-assistant/SKILL.md +2 -0
- package/bundled/locales/zh-CN/skills/brainstorm-assistant/SKILL.md +22 -12
- package/bundled/locales/zh-CN/skills/brainstorm-assistant/guide.md +12 -9
- package/bundled/locales/zh-CN/skills/code-review-assistant/SKILL.md +1 -0
- package/bundled/locales/zh-CN/skills/commands/brainstorm.md +17 -13
- package/bundled/locales/zh-CN/skills/commands/config.md +0 -1
- package/bundled/locales/zh-CN/skills/commands/init.md +1 -2
- package/bundled/locales/zh-CN/skills/commit-standards/SKILL.md +2 -0
- package/bundled/locales/zh-CN/skills/contract-test-assistant/SKILL.md +1 -0
- package/bundled/locales/zh-CN/skills/dev-methodology/SKILL.md +2 -0
- package/bundled/locales/zh-CN/skills/observability-assistant/SKILL.md +1 -0
- package/bundled/locales/zh-CN/skills/project-structure-guide/SKILL.md +1 -0
- package/bundled/locales/zh-CN/skills/release-standards/SKILL.md +3 -0
- package/bundled/locales/zh-CN/skills/requirement-assistant/SKILL.md +2 -0
- package/bundled/locales/zh-CN/skills/reverse-engineer/SKILL.md +3 -0
- package/bundled/locales/zh-CN/skills/runbook-assistant/SKILL.md +1 -0
- package/bundled/locales/zh-CN/skills/slo-assistant/SKILL.md +1 -0
- package/bundled/locales/zh-CN/skills/tdd-assistant/SKILL.md +2 -0
- package/bundled/locales/zh-TW/CHANGELOG.md +74 -3
- package/bundled/locales/zh-TW/CLAUDE.md +1 -1
- package/bundled/locales/zh-TW/README.md +2 -2
- package/bundled/locales/zh-TW/SECURITY.md +1 -1
- package/bundled/locales/zh-TW/core/acceptance-criteria-traceability.md +2 -0
- package/bundled/locales/zh-TW/core/adr-standards.md +26 -5
- package/bundled/locales/zh-TW/core/agent-communication-protocol.md +7 -0
- package/bundled/locales/zh-TW/core/branch-completion.md +7 -0
- package/bundled/locales/zh-TW/core/change-batching-standards.md +7 -0
- package/bundled/locales/zh-TW/core/code-review-checklist.md +2 -0
- package/bundled/locales/zh-TW/core/container-image-standards.md +2 -2
- package/bundled/locales/zh-TW/core/contract-testing-standards.md +2 -2
- package/bundled/locales/zh-TW/core/cross-flow-regression.md +8 -7
- package/bundled/locales/zh-TW/core/data-contract.md +2 -2
- package/bundled/locales/zh-TW/core/data-migration-testing.md +2 -2
- package/bundled/locales/zh-TW/core/data-pipeline.md +2 -2
- package/bundled/locales/zh-TW/core/deferred-item-exit.md +251 -0
- package/bundled/locales/zh-TW/core/documentation-writing-standards.md +228 -3
- package/bundled/locales/zh-TW/core/execution-history.md +7 -0
- package/bundled/locales/zh-TW/core/full-coverage-testing.md +15 -2
- package/bundled/locales/zh-TW/core/governance-layer.md +118 -5
- package/bundled/locales/zh-TW/core/iac-design-principles.md +2 -2
- package/bundled/locales/zh-TW/core/incident-response.md +2 -2
- package/bundled/locales/zh-TW/core/model-provenance.md +4 -2
- package/bundled/locales/zh-TW/core/pii-classification.md +42 -6
- package/bundled/locales/zh-TW/core/pipeline-integration-standards.md +7 -0
- package/bundled/locales/zh-TW/core/prd-standards.md +4 -2
- package/bundled/locales/zh-TW/core/product-metrics-standards.md +4 -2
- package/bundled/locales/zh-TW/core/release-readiness-gate.md +2 -2
- package/bundled/locales/zh-TW/core/resource-cost-boundary.md +2 -2
- package/bundled/locales/zh-TW/core/retrospective-standards.md +5 -3
- package/bundled/locales/zh-TW/core/reverse-engineering-standards.md +83 -5
- package/bundled/locales/zh-TW/core/runbook.md +2 -2
- package/bundled/locales/zh-TW/core/schema-evolution.md +2 -2
- package/bundled/locales/zh-TW/core/secret-management-standards.md +2 -2
- package/bundled/locales/zh-TW/core/slo-sli.md +2 -2
- package/bundled/locales/zh-TW/core/spec-driven-development.md +2 -0
- package/bundled/locales/zh-TW/core/tech-debt-standards.md +71 -4
- package/bundled/locales/zh-TW/core/turn-completion-integrity.md +190 -0
- package/bundled/locales/zh-TW/core/user-journey-testing.md +2 -2
- package/bundled/locales/zh-TW/core/user-story-mapping.md +2 -2
- package/bundled/locales/zh-TW/core/verification-oracle.md +2 -2
- package/bundled/locales/zh-TW/core/workflow-enforcement.md +7 -0
- package/bundled/locales/zh-TW/core/workflow-state-protocol.md +7 -0
- package/bundled/locales/zh-TW/docs/CHEATSHEET.md +8 -1
- package/bundled/locales/zh-TW/docs/CLI-INIT-OPTIONS.md +29 -68
- package/bundled/locales/zh-TW/docs/FEATURE-REFERENCE.md +25 -15
- package/bundled/locales/zh-TW/docs/MIGRATION-v6.md +8 -4
- package/bundled/locales/zh-TW/docs/USAGE-MODES-COMPARISON.md +1 -2
- package/bundled/locales/zh-TW/integrations/google-antigravity/{INSTRUCTIONS.md → AGENTS.md} +1 -1
- package/bundled/locales/zh-TW/integrations/google-antigravity/README.md +3 -3
- package/bundled/locales/zh-TW/skills/adr-assistant/SKILL.md +1 -1
- package/bundled/locales/zh-TW/skills/atdd-assistant/SKILL.md +2 -0
- package/bundled/locales/zh-TW/skills/bdd-assistant/SKILL.md +2 -0
- package/bundled/locales/zh-TW/skills/brainstorm-assistant/SKILL.md +22 -12
- package/bundled/locales/zh-TW/skills/brainstorm-assistant/guide.md +12 -9
- package/bundled/locales/zh-TW/skills/code-review-assistant/SKILL.md +1 -0
- package/bundled/locales/zh-TW/skills/commands/brainstorm.md +17 -13
- package/bundled/locales/zh-TW/skills/commands/config.md +0 -1
- package/bundled/locales/zh-TW/skills/commands/init.md +1 -2
- package/bundled/locales/zh-TW/skills/commit-standards/SKILL.md +2 -0
- package/bundled/locales/zh-TW/skills/contract-test-assistant/SKILL.md +2 -1
- package/bundled/locales/zh-TW/skills/dev-methodology/SKILL.md +2 -0
- package/bundled/locales/zh-TW/skills/dev-workflow-guide/SKILL.md +1 -1
- package/bundled/locales/zh-TW/skills/knowledge-graph/guide.md +2 -2
- package/bundled/locales/zh-TW/skills/migration-assistant/SKILL.md +1 -1
- package/bundled/locales/zh-TW/skills/observability-assistant/SKILL.md +1 -0
- package/bundled/locales/zh-TW/skills/project-discovery/SKILL.md +1 -0
- package/bundled/locales/zh-TW/skills/project-structure-guide/SKILL.md +1 -0
- package/bundled/locales/zh-TW/skills/release-standards/SKILL.md +3 -0
- package/bundled/locales/zh-TW/skills/requirement-assistant/SKILL.md +2 -0
- package/bundled/locales/zh-TW/skills/reverse-engineer/SKILL.md +3 -0
- package/bundled/locales/zh-TW/skills/runbook-assistant/SKILL.md +1 -0
- package/bundled/locales/zh-TW/skills/slo-assistant/SKILL.md +1 -0
- package/bundled/locales/zh-TW/skills/tdd-assistant/SKILL.md +2 -0
- package/bundled/skills/atdd-assistant/SKILL.md +2 -0
- package/bundled/skills/bdd-assistant/SKILL.md +2 -0
- package/bundled/skills/brainstorm-assistant/SKILL.md +31 -13
- package/bundled/skills/brainstorm-assistant/guide.md +9 -6
- package/bundled/skills/code-review-assistant/SKILL.md +1 -0
- package/bundled/skills/commands/brainstorm.md +12 -9
- package/bundled/skills/commands/config.md +0 -1
- package/bundled/skills/commands/init.md +2 -3
- package/bundled/skills/commit-standards/SKILL.md +2 -0
- package/bundled/skills/contract-test-assistant/SKILL.md +1 -0
- package/bundled/skills/dev-methodology/SKILL.md +4 -0
- package/bundled/skills/observability-assistant/SKILL.md +1 -0
- package/bundled/skills/project-discovery/SKILL.md +1 -0
- package/bundled/skills/project-structure-guide/SKILL.md +1 -0
- package/bundled/skills/release-standards/SKILL.md +3 -0
- package/bundled/skills/requirement-assistant/SKILL.md +2 -0
- package/bundled/skills/reverse-engineer/SKILL.md +3 -0
- package/bundled/skills/runbook-assistant/SKILL.md +1 -0
- package/bundled/skills/slo-assistant/SKILL.md +1 -0
- package/bundled/skills/tdd-assistant/SKILL.md +2 -0
- package/bundled/templates/.ai-context.yaml.template +194 -0
- package/bundled/templates/CLAUDE.md.template +145 -0
- package/bundled/templates/DESIGN.md +237 -0
- package/bundled/templates/SKILL-BRIEF-TEMPLATE.md +57 -0
- package/bundled/templates/SKILL-CANDIDATES.md +39 -0
- package/bundled/templates/gates/check-error-exit.mjs +309 -0
- package/bundled/templates/mcp-config.json +10 -0
- package/bundled/templates/methodology-template.yaml +209 -0
- package/bundled/templates/migration-template.md +408 -0
- package/bundled/templates/requirement-checklist.md +410 -0
- package/bundled/templates/requirement-document-template.md +591 -0
- package/bundled/templates/requirement-template.md +881 -0
- package/bundled/templates/reverse-spec-template.md +409 -0
- package/bundled/templates/test-case-template.md +74 -0
- package/bundled/templates/test-plan-template.md +74 -0
- package/package.json +12 -9
- package/src/commands/audit.js +82 -0
- package/src/commands/check.js +227 -34
- package/src/commands/config.js +19 -19
- package/src/commands/init.js +174 -20
- package/src/commands/spec.js +2 -2
- package/src/commands/update.js +537 -43
- package/src/compilers/claude-code-compiler.js +4 -1
- package/src/config/ai-agent-paths.js +62 -17
- package/src/core/constants.js +42 -11
- package/src/core/manifest.js +201 -3
- package/src/core/paths.js +2 -2
- package/src/i18n/messages.js +42 -29
- package/src/installers/hooks-installer.js +167 -75
- package/src/installers/integration-installer.js +13 -9
- package/src/installers/skills-installer.js +4 -4
- package/src/installers/standards-installer.js +3 -3
- package/src/prompts/init.js +47 -18
- package/src/reconciler/diff-engine.js +57 -2
- package/src/reconciler/plan-executor.js +31 -11
- package/src/utils/detector.js +21 -1
- package/src/utils/effect-boundary.js +1093 -0
- package/src/utils/hasher.js +166 -1
- package/src/utils/hook-stats.js +1 -1
- package/src/utils/integration-generator.js +288 -82
- package/src/utils/reference-sync.js +107 -8
- package/src/utils/registry.js +57 -0
- package/src/utils/spinner.js +31 -0
- package/src/utils/yaml-generator.js +51 -9
- package/standards-registry.json +32 -9
package/src/commands/init.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
import
|
|
2
|
+
import { createSpinner } from '../utils/spinner.js';
|
|
3
3
|
import { execSync } from 'child_process';
|
|
4
4
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
5
|
-
import {
|
|
5
|
+
import { join } from 'path';
|
|
6
6
|
import {
|
|
7
|
-
manifestExists as isInitialized
|
|
7
|
+
manifestExists as isInitialized,
|
|
8
|
+
normalizeContentMode,
|
|
9
|
+
SUPPORTED_CONTENT_MODES
|
|
8
10
|
} from '../core/manifest.js';
|
|
9
11
|
import { t, detectLanguage } from '../i18n/messages.js';
|
|
10
12
|
import { detectAll } from '../utils/detector.js';
|
|
@@ -53,7 +55,7 @@ export async function initCommand(options) {
|
|
|
53
55
|
}
|
|
54
56
|
|
|
55
57
|
// STEP 2: Detect project characteristics
|
|
56
|
-
const spinner =
|
|
58
|
+
const spinner = createSpinner(msg.detectingProject).start();
|
|
57
59
|
const detected = detectAll(projectPath);
|
|
58
60
|
spinner.succeed(msg.analysisComplete);
|
|
59
61
|
|
|
@@ -121,7 +123,16 @@ export async function initCommand(options) {
|
|
|
121
123
|
apply: async () => {
|
|
122
124
|
// 1. Install Standards
|
|
123
125
|
const standardsResults = await installStandards(config, projectPath);
|
|
124
|
-
|
|
126
|
+
// Paths, not basenames. Everything downstream classifies an option
|
|
127
|
+
// by an `/options/` segment, so reducing to basenames here is not a
|
|
128
|
+
// simplification — it deletes the only signal that distinguishes the
|
|
129
|
+
// two, and `contentLayout: flat` installs option files with no
|
|
130
|
+
// directory to recover it from. The index block consequently said
|
|
131
|
+
// "options 0" on every project for two releases, while the manifest
|
|
132
|
+
// right beside it listed seven. `buildToolIntegrationConfig` (the
|
|
133
|
+
// update path's equivalent) has carried a comment warning against
|
|
134
|
+
// exactly this reduction the whole time; only this call site did it.
|
|
135
|
+
config.installedStandards = standardsResults.standards;
|
|
125
136
|
|
|
126
137
|
// 1.5. Generate release-config.yaml if non-default mode selected
|
|
127
138
|
if (config.releaseMode && config.releaseMode !== 'ci-cd') {
|
|
@@ -156,9 +167,29 @@ export async function initCommand(options) {
|
|
|
156
167
|
skillHashes: {},
|
|
157
168
|
commandHashes: {}
|
|
158
169
|
};
|
|
170
|
+
// A detected tool that can take skills and has no verified path gets
|
|
171
|
+
// nothing — and must be told so. Silence was the actual defect measured
|
|
172
|
+
// on 2026-09-08: `--mode skills` installed nothing, printed no skills
|
|
173
|
+
// line, and exited 0. An adopter cannot know to go looking.
|
|
174
|
+
for (const tool of config.skillsConfig.skillsPathUnknownTools || []) {
|
|
175
|
+
console.log(chalk.yellow(
|
|
176
|
+
`⚠ ${getAgentDisplayName(tool) || tool}: ` +
|
|
177
|
+
`${msg.skillsPathUnknown || 'no verified skills path — nothing was installed for this tool'}`
|
|
178
|
+
));
|
|
179
|
+
}
|
|
159
180
|
await installSkills(config.skillsConfig, projectPath, msg, skillsResults);
|
|
160
181
|
await installCommands(config.skillsConfig, projectPath, msg, skillsResults);
|
|
161
182
|
|
|
183
|
+
// A tool may need something from the adopter before it will read what
|
|
184
|
+
// we just wrote. Driven by an `installNote` on the path table, so a new
|
|
185
|
+
// precondition is a field and not a branch here.
|
|
186
|
+
for (const { agent } of config.skillsConfig.skillsInstallations || []) {
|
|
187
|
+
const note = getAgentConfig(agent)?.installNote;
|
|
188
|
+
if (note) {
|
|
189
|
+
console.log(chalk.yellow(` ⚠ ${getAgentDisplayName(agent) || agent}: ${note}`));
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
162
193
|
// Combine results
|
|
163
194
|
installErrors = [
|
|
164
195
|
...standardsResults.errors,
|
|
@@ -225,7 +256,25 @@ export async function initCommand(options) {
|
|
|
225
256
|
const { installHooks } = await import('../installers/hooks-installer.js');
|
|
226
257
|
const hookResult = installHooks(projectPath);
|
|
227
258
|
if (hookResult.installed) {
|
|
228
|
-
console.log(chalk.green(
|
|
259
|
+
console.log(chalk.green(
|
|
260
|
+
` ✓ Enforcement hooks installed (${hookResult.scriptsCount} scripts, `
|
|
261
|
+
+ `${hookResult.events.join(', ')})`));
|
|
262
|
+
} else {
|
|
263
|
+
// Silence here is how three broken installs reported success.
|
|
264
|
+
console.log(chalk.yellow(' ⚠ No enforcement hooks installed — no standard produced a usable hook.'));
|
|
265
|
+
}
|
|
266
|
+
for (const s of hookResult.skipped ?? []) {
|
|
267
|
+
console.log(chalk.yellow(` · skipped ${s.id}: ${s.why}`));
|
|
268
|
+
}
|
|
269
|
+
// turn-completion-integrity R8: a prose-reading hook in a language it does
|
|
270
|
+
// not ship is installed, running, and unable to fire — and that looks
|
|
271
|
+
// exactly like a turn with nothing wrong. Say so at install time; there is
|
|
272
|
+
// no later moment where the adopter could find out.
|
|
273
|
+
for (const l of hookResult.languageLimits ?? []) {
|
|
274
|
+
console.log(chalk.yellow(` · ${l.script} reads prose, and ships:`));
|
|
275
|
+
for (const line of l.languages.split('\n')) {
|
|
276
|
+
console.log(chalk.gray(` ${line}`));
|
|
277
|
+
}
|
|
229
278
|
}
|
|
230
279
|
}
|
|
231
280
|
|
|
@@ -433,16 +482,95 @@ function buildNonInteractiveConfig(options, detected, projectPath) {
|
|
|
433
482
|
});
|
|
434
483
|
|
|
435
484
|
// Skills Configuration Logic
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
485
|
+
//
|
|
486
|
+
// 🔴 Which tools can take skills is asked of the path table, never listed here.
|
|
487
|
+
// This used to read `t === 'claude-code' || t === 'opencode'`, and the two
|
|
488
|
+
// consequences were both measured on 2026-09-08 (XSPEC-408 §18.3):
|
|
489
|
+
//
|
|
490
|
+
// - A repo detected as codex ran `uds init --mode skills -y` and got **zero
|
|
491
|
+
// skills, in any directory, with no message saying so.**
|
|
492
|
+
// - When a location was passed explicitly, the install went to `.claude/skills/`
|
|
493
|
+
// for every tool, because the branch below never built `skillsInstallations`
|
|
494
|
+
// and `installSkills()` then fell through to the legacy path, whose target is
|
|
495
|
+
// the hardcoded `getProjectSkillsDir()`. Codex does not read that directory:
|
|
496
|
+
// two arms differing only in path gave 15,235 vs 18,096 input tokens, and only
|
|
497
|
+
// the `.agents/skills` arm made Codex say it could see the skills at all.
|
|
498
|
+
//
|
|
499
|
+
// 🔴 This is the second time in the same shape. `ai-agent-paths.js` records the
|
|
500
|
+
// first: `.codex/skills/` was "a directory UDS invented", skills there were
|
|
501
|
+
// invisible, and a behavioural probe failed while Codex behaved correctly. That
|
|
502
|
+
// fix corrected the path table. This one broke in the code that never asked it.
|
|
503
|
+
// The predicate below is the same one `promptSkillsInstallLocation` already used —
|
|
504
|
+
// the interactive flow was never wrong.
|
|
505
|
+
const skillsCapableTools = aiToolsNormalized.filter(tool => {
|
|
506
|
+
const config = getAgentConfig(tool);
|
|
507
|
+
return Boolean(config?.supportsSkills && config?.skills);
|
|
508
|
+
});
|
|
509
|
+
const hasSkillsCompatibleTool = skillsCapableTools.length > 0;
|
|
510
|
+
// Marketplace is Claude Code's. A tool reaches it either by having one
|
|
511
|
+
// (`supportsMarketplace`) or by reading Claude's directory (`fallbackSkillsPath`).
|
|
512
|
+
// ⚠️ Those fallback claims are NOT all verified — `opencode`'s carries the bare
|
|
513
|
+
// comment "Can read Claude skills" and no evidence. It is preserved here rather
|
|
514
|
+
// than flipped, because changing behaviour on an unverified field in either
|
|
515
|
+
// direction is a guess. Codex's identical claim WAS measured, and falsified, so
|
|
516
|
+
// its field is now null (see `ai-agent-paths.js`) and it drops out here by data.
|
|
517
|
+
// 🔴 The marketplace is all-or-nothing for a repo: it installs into Claude's
|
|
518
|
+
// directory, so it serves a tool only if that tool has a marketplace of its own or
|
|
519
|
+
// declares Claude's directory as its fallback. If ANY detected tool is not served
|
|
520
|
+
// by it, file installs are used instead — every tool then gets its own path, and
|
|
521
|
+
// nobody is left with a successful init and an empty directory.
|
|
522
|
+
const reachesMarketplace = t => {
|
|
523
|
+
const c = getAgentConfig(t);
|
|
524
|
+
return Boolean(c?.supportsMarketplace || c?.fallbackSkillsPath);
|
|
525
|
+
};
|
|
526
|
+
const onlySkillsCompatibleTools =
|
|
527
|
+
hasSkillsCompatibleTool && aiToolsNormalized.every(reachesMarketplace);
|
|
528
|
+
|
|
439
529
|
let skillsLocationFlag = options.skillsLocation;
|
|
440
530
|
if (!skillsLocationFlag) {
|
|
441
|
-
skillsLocationFlag =
|
|
531
|
+
skillsLocationFlag = hasSkillsCompatibleTool
|
|
532
|
+
? (onlySkillsCompatibleTools ? 'marketplace' : 'project')
|
|
533
|
+
: 'none';
|
|
442
534
|
}
|
|
443
535
|
|
|
444
|
-
|
|
536
|
+
// A detected tool that can take skills and is getting none must SAY SO. The worst
|
|
537
|
+
// property of the old default was not the wrong directory, it was the silence:
|
|
538
|
+
// `--mode skills` printed no skills line at all and exited 0.
|
|
539
|
+
const skippedSkillsTools = aiToolsNormalized.filter(tool => {
|
|
540
|
+
const config = getAgentConfig(tool);
|
|
541
|
+
return Boolean(config?.supportsSkills) && !config?.skills;
|
|
542
|
+
});
|
|
543
|
+
// Carried on the config and printed by the caller — this function builds config
|
|
544
|
+
// and has no message bundle in scope. (First version called `msg` here and every
|
|
545
|
+
// init that detected a pathless tool crashed with `ReferenceError: msg is not
|
|
546
|
+
// defined`; the gate's own control arm missed it, because the string it looked for
|
|
547
|
+
// appeared in the stack trace.)
|
|
548
|
+
|
|
549
|
+
// `auto` is resolved later per tool by resolveContentModeForTool, so it is
|
|
550
|
+
// not a content mode and must not go through the normalizer.
|
|
551
|
+
let contentModeFlag = options.contentMode || 'auto';
|
|
552
|
+
if (contentModeFlag !== 'auto') {
|
|
553
|
+
// An unrecognised value is never substituted quietly: a typo that still
|
|
554
|
+
// produces a normal-looking run is how `--content-mode` would lie about
|
|
555
|
+
// what it generated. (XSPEC-357 R7) In 6.x it warns and keeps 6.8.0's
|
|
556
|
+
// result (`index`); it becomes an error in 7.0.0 — see normalizeContentMode.
|
|
557
|
+
const normalized = normalizeContentMode(contentModeFlag);
|
|
558
|
+
if (normalized.unrecognized) {
|
|
559
|
+
console.log(chalk.yellow(
|
|
560
|
+
`⚠ Unknown content mode '${normalized.unrecognized}'; using '${normalized.mode}'. ` +
|
|
561
|
+
`Supported: ${SUPPORTED_CONTENT_MODES.join(', ')}. This will be an error in 7.0.0.`
|
|
562
|
+
));
|
|
563
|
+
}
|
|
564
|
+
if (normalized.migratedFrom) {
|
|
565
|
+
console.log(chalk.yellow(
|
|
566
|
+
`⚠ --content-mode ${normalized.migratedFrom} is retired; using '${normalized.mode}'. ` +
|
|
567
|
+
'The two produced identical files, so nothing about your output changes.'
|
|
568
|
+
));
|
|
569
|
+
}
|
|
570
|
+
contentModeFlag = normalized.mode;
|
|
571
|
+
}
|
|
445
572
|
let skillsConfig = {};
|
|
573
|
+
let skillsInstallationsForYes = [];
|
|
446
574
|
|
|
447
575
|
if (skillsLocationFlag === 'marketplace') {
|
|
448
576
|
skillsConfig = {
|
|
@@ -472,14 +600,39 @@ function buildNonInteractiveConfig(options, detected, projectPath) {
|
|
|
472
600
|
location = 'project';
|
|
473
601
|
}
|
|
474
602
|
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
603
|
+
// 🔴 One installation per skills-capable detected tool, each at that tool's own
|
|
604
|
+
// path from the table. Without this the config carries only `updateTargets`,
|
|
605
|
+
// `installSkills()` takes its legacy branch, and every tool's skills land in
|
|
606
|
+
// `.claude/skills/` — see the block above for what that measured.
|
|
607
|
+
skillsInstallationsForYes = skillsCapableTools.map(agent => ({ agent, level: location }));
|
|
608
|
+
|
|
609
|
+
// 🔴 Detected tools, none of which can take skills, is NOT the same as "no tools
|
|
610
|
+
// detected". The first is knowledge — install nothing and say why. The second is
|
|
611
|
+
// ignorance, and there the historical `.claude/skills/` fallback is the least-bad
|
|
612
|
+
// guess and is kept. Without this split, `--skills-location project` in an
|
|
613
|
+
// Antigravity-only repo wrote 55 skills into `.claude/skills/`, a directory
|
|
614
|
+
// nothing in that repo reads. Caught by `check:install-paths`, not by me.
|
|
615
|
+
const knowinglyUnsupported = skillsCapableTools.length === 0 && aiToolsNormalized.length > 0;
|
|
616
|
+
|
|
617
|
+
skillsConfig = knowinglyUnsupported
|
|
618
|
+
? {
|
|
619
|
+
installed: false,
|
|
620
|
+
location: null,
|
|
621
|
+
needsInstall: false,
|
|
622
|
+
updateTargets: [],
|
|
623
|
+
skillsInstallations: [],
|
|
624
|
+
standardsScope: 'full',
|
|
625
|
+
contentMode: contentModeFlag
|
|
626
|
+
}
|
|
627
|
+
: {
|
|
628
|
+
installed: true,
|
|
629
|
+
location,
|
|
630
|
+
skillsInstallations: skillsInstallationsForYes,
|
|
631
|
+
needsInstall: skillsLocationFlag === 'project' || skillsLocationFlag === 'user' || (!userSkillsInfo?.installed && !projectSkillsInfo?.installed),
|
|
632
|
+
updateTargets: [location],
|
|
633
|
+
standardsScope: 'minimal',
|
|
634
|
+
contentMode: contentModeFlag
|
|
635
|
+
};
|
|
483
636
|
}
|
|
484
637
|
|
|
485
638
|
// Auto-install commands
|
|
@@ -496,6 +649,7 @@ function buildNonInteractiveConfig(options, detected, projectPath) {
|
|
|
496
649
|
}
|
|
497
650
|
|
|
498
651
|
skillsConfig.locale = displayLanguageToLocale(displayLanguage);
|
|
652
|
+
skillsConfig.skillsPathUnknownTools = skippedSkillsTools;
|
|
499
653
|
|
|
500
654
|
// AGENTS.md: default to true in --yes mode unless codex/opencode selected or --no-agents-md
|
|
501
655
|
// When codex/opencode is selected, they already generate AGENTS.md — no need for universal output
|
|
@@ -639,7 +793,7 @@ function displaySummary(config, msg, common) {
|
|
|
639
793
|
}
|
|
640
794
|
|
|
641
795
|
// 9. Content Mode (STEP 11)
|
|
642
|
-
const contentModeLabels = t().contentMode?.labels || { index: 'Standard',
|
|
796
|
+
const contentModeLabels = t().contentMode?.labels || { index: 'Standard', minimal: 'Minimal' };
|
|
643
797
|
console.log(chalk.gray(` ${msg.contentModeLabel}: ${contentModeLabels[config.contentMode] || config.contentMode}`));
|
|
644
798
|
|
|
645
799
|
// 10. Methodology (STEP 12, experimental)
|
package/src/commands/spec.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import chalk from 'chalk';
|
|
12
|
-
import
|
|
12
|
+
import { createSpinner } from '../utils/spinner.js';
|
|
13
13
|
import { select, confirm as inquirerConfirm } from '@inquirer/prompts';
|
|
14
14
|
import { existsSync, readFileSync } from 'node:fs';
|
|
15
15
|
import { join } from 'node:path';
|
|
@@ -48,7 +48,7 @@ export async function specCreateCommand(intent, options = {}) {
|
|
|
48
48
|
output: options.output
|
|
49
49
|
});
|
|
50
50
|
|
|
51
|
-
const spinner =
|
|
51
|
+
const spinner = createSpinner({
|
|
52
52
|
text: t('spec.generating', 'Generating micro-spec...'),
|
|
53
53
|
color: 'cyan'
|
|
54
54
|
}).start();
|