@dsalazardev/ai-hub-cli 0.2.0 → 0.3.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 (78) hide show
  1. package/README.md +63 -4
  2. package/dist/backup/snapshots.js +12 -0
  3. package/dist/catalog.d.ts +8 -1
  4. package/dist/catalog.js +38 -9
  5. package/dist/cli/args.js +1 -0
  6. package/dist/cli/doctor.js +20 -11
  7. package/dist/cli/maintenance.js +21 -39
  8. package/dist/cli/memory.js +4 -0
  9. package/dist/cli/onboarding.d.ts +13 -0
  10. package/dist/cli/onboarding.js +128 -14
  11. package/dist/cli/run.d.ts +3 -1
  12. package/dist/cli/run.js +5 -4
  13. package/dist/cli/types.d.ts +3 -0
  14. package/dist/engine/engine.d.ts +19 -1
  15. package/dist/engine/engine.js +52 -0
  16. package/dist/engine/gates.d.ts +16 -0
  17. package/dist/engine/gates.js +102 -1
  18. package/dist/harness/memory/ledger.d.ts +6 -0
  19. package/dist/harness/memory/ledger.js +44 -2
  20. package/dist/manifest/manifest.d.ts +3 -1
  21. package/dist/manifest/manifest.js +16 -10
  22. package/dist/presets/materialize.d.ts +5 -0
  23. package/dist/presets/materialize.js +30 -0
  24. package/dist/speckit/binding.d.ts +15 -0
  25. package/dist/speckit/binding.js +66 -0
  26. package/dist/speckit/commands.d.ts +46 -0
  27. package/dist/speckit/commands.js +131 -0
  28. package/dist/speckit/doctor.d.ts +14 -0
  29. package/dist/speckit/doctor.js +103 -0
  30. package/dist/speckit/runner.d.ts +19 -0
  31. package/dist/speckit/runner.js +22 -0
  32. package/dist/speckit/seal.d.ts +12 -0
  33. package/dist/speckit/seal.js +47 -0
  34. package/dist/speckit/settings.d.ts +36 -0
  35. package/dist/speckit/settings.js +75 -0
  36. package/dist/speckit/state.d.ts +59 -0
  37. package/dist/speckit/state.js +279 -0
  38. package/dist/speckit/version.d.ts +8 -0
  39. package/dist/speckit/version.js +53 -0
  40. package/dist/sync/config.js +3 -2
  41. package/dist/sync/render.js +30 -0
  42. package/dist/sync/sync.d.ts +4 -0
  43. package/dist/sync/sync.js +48 -5
  44. package/dist/sync/targets.d.ts +13 -0
  45. package/dist/sync/targets.js +5 -0
  46. package/engine/engine.yaml +65 -31
  47. package/manifest.json +20 -48
  48. package/package.json +1 -1
  49. package/schema/engine.schema.json +22 -3
  50. package/schema/manifest.schema.json +10 -0
  51. package/skills/shared/analyze/SKILL.md +2 -1
  52. package/skills/shared/clarify/SKILL.md +2 -1
  53. package/skills/shared/implement/SKILL.md +2 -1
  54. package/skills/shared/plan/SKILL.md +2 -1
  55. package/skills/shared/review/SKILL.md +2 -1
  56. package/skills/shared/sdd/SKILL.md +2 -1
  57. package/skills/shared/sdd-init/SKILL.md +2 -1
  58. package/skills/shared/ship/SKILL.md +2 -1
  59. package/skills/shared/specify/SKILL.md +2 -1
  60. package/skills/shared/tasks/SKILL.md +2 -1
  61. package/skills/shared/verify/SKILL.md +2 -1
  62. package/skills/shared/speckit-analyze/SKILL.md +0 -35
  63. package/skills/shared/speckit-assess-decide/SKILL.md +0 -36
  64. package/skills/shared/speckit-assess-define/SKILL.md +0 -36
  65. package/skills/shared/speckit-assess-intake/SKILL.md +0 -38
  66. package/skills/shared/speckit-assess-research/SKILL.md +0 -36
  67. package/skills/shared/speckit-assess-shape/SKILL.md +0 -36
  68. package/skills/shared/speckit-bug-assess/SKILL.md +0 -38
  69. package/skills/shared/speckit-bug-fix/SKILL.md +0 -37
  70. package/skills/shared/speckit-bug-test/SKILL.md +0 -37
  71. package/skills/shared/speckit-checklist/SKILL.md +0 -35
  72. package/skills/shared/speckit-clarify/SKILL.md +0 -32
  73. package/skills/shared/speckit-constitution/SKILL.md +0 -35
  74. package/skills/shared/speckit-converge/SKILL.md +0 -36
  75. package/skills/shared/speckit-implement/SKILL.md +0 -32
  76. package/skills/shared/speckit-plan/SKILL.md +0 -37
  77. package/skills/shared/speckit-specify/SKILL.md +0 -36
  78. package/skills/shared/speckit-tasks/SKILL.md +0 -34
package/dist/sync/sync.js CHANGED
@@ -3,6 +3,7 @@ import path from 'node:path';
3
3
  import { mapLimit } from '../concurrency.js';
4
4
  import { isEngineCheckout } from '../source-checkout.js';
5
5
  import { loadSyncConfig, resolveSourcePath } from './config.js';
6
+ import { ownedBySpeckit, readSpeckitState, speckitOwnedPaths } from '../speckit/state.js';
6
7
  import { normalize, renderAll } from './render.js';
7
8
  import { GENERATOR_VERSION, readLock, sha256, writeLock, } from './lock.js';
8
9
  export class SyncSourceError extends Error {
@@ -15,6 +16,16 @@ export class SyncSourceError extends Error {
15
16
  this.name = 'SyncSourceError';
16
17
  }
17
18
  }
19
+ export class SpeckitOwnershipError extends Error {
20
+ paths;
21
+ constructor(paths) {
22
+ super(`colisión de propiedad con Spec Kit: ${paths.join(', ')}\n` +
23
+ 'Esas rutas pertenecen a Spec Kit (sus manifiestos de integración, sus extensiones o el espacio speckit-*/speckit.*); ' +
24
+ 'ai-hub no las escribe. No se escribió ningún archivo ni el lock.');
25
+ this.paths = paths;
26
+ this.name = 'SpeckitOwnershipError';
27
+ }
28
+ }
18
29
  export class SyncSourceCheckoutError extends Error {
19
30
  root;
20
31
  constructor(root) {
@@ -34,16 +45,28 @@ export async function runSync(root, options) {
34
45
  const rendered = await renderAll(root, config);
35
46
  const previous = await readLock(root);
36
47
  const result = { written: [], removed: [], problems: [] };
48
+ // Un dueño por archivo: lo que reclama Spec Kit no se escribe ni se borra desde aquí.
49
+ const speckitPresent = (await readSpeckitState(root)).present;
50
+ const owned = await speckitOwnedPaths(root, config.tools);
51
+ const isSpeckit = (rel) => ownedBySpeckit(rel, owned, config.tools, speckitPresent);
52
+ const collisions = [...rendered.keys()].filter(isSpeckit).sort();
53
+ if (collisions.length > 0) {
54
+ if (options.check) {
55
+ result.problems.push(...collisions.map((rel) => `colisión con Spec Kit: ${rel}`));
56
+ return result;
57
+ }
58
+ throw new SpeckitOwnershipError(collisions);
59
+ }
37
60
  const symlinks = await findSymlinks(root, config, rendered);
38
- const obsolete = previous
39
- ? Object.keys(previous.files)
40
- .filter((rel) => !rendered.has(rel))
41
- .sort()
42
- : [];
61
+ const previousEntries = previous ? Object.keys(previous.files).filter((rel) => !rendered.has(rel)) : [];
62
+ // Entradas que pasaron a Spec Kit: se sueltan del lock sin tocar el archivo de su nuevo dueño.
63
+ const transferred = previousEntries.filter(isSpeckit).sort();
64
+ const obsolete = previousEntries.filter((rel) => !isSpeckit(rel)).sort();
43
65
  if (options.check) {
44
66
  result.problems.push(...(await checkCopies(root, rendered, previous)));
45
67
  result.problems.push(...symlinks.map((rel) => `enlace simbólico no permitido: ${rel}`));
46
68
  result.problems.push(...obsolete.map((rel) => `destino obsoleto: ${rel}`));
69
+ result.problems.push(...transferred.map((rel) => `propiedad transferida a Spec Kit (ejecuta ai-hub sync): ${rel}`));
47
70
  return result;
48
71
  }
49
72
  const nextLock = await buildLock(root, rendered);
@@ -55,6 +78,10 @@ export async function runSync(root, options) {
55
78
  await fs.rm(path.join(root, rel), { force: true });
56
79
  result.removed.push(rel);
57
80
  }
81
+ // Un destino obsoleto no deja su carpeta vacía (p. ej. `.github/skills/speckit-plan/` tras 0.2.x).
82
+ for (const dir of [...new Set(obsolete.map((rel) => path.posix.dirname(rel)))].sort((a, b) => b.length - a.length)) {
83
+ await pruneEmptyDirs(root, dir);
84
+ }
58
85
  const written = await mapLimit(sortedEntries(rendered), 24, async ([rel, file]) => {
59
86
  const abs = path.join(root, rel);
60
87
  const current = await readCopy(abs);
@@ -138,6 +165,9 @@ function categoryOf(source) {
138
165
  if (source === '@engine/engine/preflight.md' || source === 'engine/preflight.md') {
139
166
  return 'preflight';
140
167
  }
168
+ if (source === '@engine/engine/engine.yaml') {
169
+ return 'rules';
170
+ }
141
171
  if (source.startsWith('@engine/skills/') || source.includes('/skills/')) {
142
172
  return 'skills';
143
173
  }
@@ -276,6 +306,19 @@ async function collectSymlinks(root, relDir, found) {
276
306
  }
277
307
  }
278
308
  }
309
+ /** Borra `rel` y sus padres mientras estén vacíos, sin salir de `root`. */
310
+ async function pruneEmptyDirs(root, rel) {
311
+ let current = rel;
312
+ while (current !== '.' && current !== '' && !current.startsWith('..')) {
313
+ const abs = path.join(root, current);
314
+ const entries = await fs.readdir(abs).catch(() => null);
315
+ if (entries === null || entries.length > 0) {
316
+ return;
317
+ }
318
+ await fs.rmdir(abs).catch(() => undefined);
319
+ current = path.posix.dirname(current);
320
+ }
321
+ }
279
322
  async function readCopy(abs) {
280
323
  const text = await fs.readFile(abs, 'utf8').catch(() => null);
281
324
  return text === null ? null : normalize(text);
@@ -3,6 +3,17 @@ export type ToolId = (typeof TOOL_IDS)[number];
3
3
  export type SkillShape = 'dir' | 'file';
4
4
  export type RuleShape = 'md' | 'mdc' | 'instructions';
5
5
  export type HookKind = 'markdown' | 'cursor-mdc' | 'copilot-instructions';
6
+ /**
7
+ * Integración de Spec Kit que sirve a un destino. `commandsDir` es donde Spec Kit escribe
8
+ * sus comandos y delimita el espacio de nombres reservado `speckit-*` / `speckit.*`.
9
+ * `skill-dir` escribe `<dir>/speckit-plan/SKILL.md`; `command-file` escribe `<dir>/speckit.plan.md`.
10
+ */
11
+ export interface SpeckitTarget {
12
+ integration: string;
13
+ separator: '-' | '.';
14
+ commandsDir: string;
15
+ layout: 'skill-dir' | 'command-file';
16
+ }
6
17
  export interface ToolTargets {
7
18
  skills: string;
8
19
  agents: string | null;
@@ -11,6 +22,8 @@ export interface ToolTargets {
11
22
  skillShape: SkillShape;
12
23
  ruleShape: RuleShape;
13
24
  hookKind: HookKind;
25
+ /** `null`: el destino no recibe Spec Kit (Copilot). */
26
+ speckit: SpeckitTarget | null;
14
27
  }
15
28
  /**
16
29
  * Declarative destination table. Adding a tool means adding one row and one id
@@ -12,6 +12,7 @@ export const TARGETS = {
12
12
  skillShape: 'dir',
13
13
  ruleShape: 'md',
14
14
  hookKind: 'markdown',
15
+ speckit: { integration: 'claude', separator: '-', commandsDir: '.claude/skills', layout: 'skill-dir' },
15
16
  },
16
17
  opencode: {
17
18
  skills: '.opencode/skills',
@@ -21,6 +22,7 @@ export const TARGETS = {
21
22
  skillShape: 'dir',
22
23
  ruleShape: 'md',
23
24
  hookKind: 'markdown',
25
+ speckit: { integration: 'opencode', separator: '.', commandsDir: '.opencode/commands', layout: 'command-file' },
24
26
  },
25
27
  pi: {
26
28
  skills: '.pi/skills',
@@ -30,6 +32,7 @@ export const TARGETS = {
30
32
  skillShape: 'dir',
31
33
  ruleShape: 'md',
32
34
  hookKind: 'markdown',
35
+ speckit: { integration: 'pi', separator: '.', commandsDir: '.pi/prompts', layout: 'command-file' },
33
36
  },
34
37
  cursor: {
35
38
  skills: '.cursor/rules',
@@ -39,6 +42,7 @@ export const TARGETS = {
39
42
  skillShape: 'file',
40
43
  ruleShape: 'mdc',
41
44
  hookKind: 'cursor-mdc',
45
+ speckit: { integration: 'cursor-agent', separator: '-', commandsDir: '.cursor/skills', layout: 'skill-dir' },
42
46
  },
43
47
  copilot: {
44
48
  skills: '.github/skills',
@@ -48,6 +52,7 @@ export const TARGETS = {
48
52
  skillShape: 'dir',
49
53
  ruleShape: 'instructions',
50
54
  hookKind: 'copilot-instructions',
55
+ speckit: null,
51
56
  },
52
57
  };
53
58
  export function isToolId(value) {
@@ -113,87 +113,87 @@ commands:
113
113
  name: /speckit-assess-intake
114
114
  lane: assessment
115
115
  artifacts: [intake.md]
116
- exit: [GO, KILL, NEEDS_CLARIFICATION]
116
+ exit: [DONE, BLOCKED]
117
117
  role: spec-explorer
118
- skill: speckit-assess-intake
118
+ speckit: speckit.assess.intake
119
119
  - id: assess-research
120
120
  name: /speckit-assess-research
121
121
  lane: assessment
122
122
  artifacts: [research.md]
123
- exit: [GO, KILL, NEEDS_CLARIFICATION]
123
+ exit: [DONE, BLOCKED]
124
124
  role: spec-explorer
125
- skill: speckit-assess-research
125
+ speckit: speckit.assess.research
126
126
  - id: assess-define
127
127
  name: /speckit-assess-define
128
128
  lane: assessment
129
129
  artifacts: [problem.md]
130
- exit: [GO, KILL, NEEDS_CLARIFICATION]
130
+ exit: [DONE, BLOCKED]
131
131
  role: spec-explorer
132
- skill: speckit-assess-define
132
+ speckit: speckit.assess.define
133
133
  - id: assess-shape
134
134
  name: /speckit-assess-shape
135
135
  lane: assessment
136
136
  artifacts: [concept.md]
137
- exit: [GO, KILL, NEEDS_CLARIFICATION]
137
+ exit: [DONE, BLOCKED]
138
138
  role: spec-explorer
139
- skill: speckit-assess-shape
139
+ speckit: speckit.assess.shape
140
140
  - id: assess-decide
141
141
  name: /speckit-assess-decide
142
142
  lane: assessment
143
143
  artifacts: [decision.md]
144
- exit: [GO, KILL, NEEDS_CLARIFICATION]
144
+ exit: [GO, NEEDS_CLARIFICATION, KILL]
145
145
  role: spec-explorer
146
- skill: speckit-assess-decide
146
+ speckit: speckit.assess.decide
147
147
 
148
148
  - id: constitution
149
149
  name: /speckit.constitution
150
150
  lane: feature
151
151
  artifacts: [constitution.md]
152
- exit: [CREATED, UPDATED]
152
+ exit: [DONE, BLOCKED]
153
153
  role: spec-author
154
- skill: speckit-constitution
154
+ speckit: speckit.constitution
155
155
  - id: specify
156
156
  name: /speckit.specify
157
157
  lane: feature
158
158
  artifacts: [spec.md]
159
- exit: [DRAFT, READY]
159
+ exit: [DONE, BLOCKED]
160
160
  role: spec-author
161
- skill: speckit-specify
161
+ speckit: speckit.specify
162
162
  - id: clarify
163
163
  name: /speckit.clarify
164
164
  lane: feature
165
165
  artifacts: [spec.md]
166
- exit: [RESOLVED, OPEN]
166
+ exit: [DONE, BLOCKED]
167
167
  role: spec-author
168
- skill: speckit-clarify
168
+ speckit: speckit.clarify
169
169
  - id: plan
170
170
  name: /speckit.plan
171
171
  lane: feature
172
172
  artifacts: [plan.md]
173
- exit: [READY]
173
+ exit: [DONE, BLOCKED]
174
174
  role: spec-author
175
- skill: speckit-plan
175
+ speckit: speckit.plan
176
176
  - id: checklist
177
177
  name: /speckit.checklist
178
178
  lane: feature
179
179
  artifacts: [checklist.md]
180
- exit: [PASS, NEEDS_FIX]
180
+ exit: [DONE, BLOCKED]
181
181
  role: spec-author
182
- skill: speckit-checklist
182
+ speckit: speckit.checklist
183
183
  - id: tasks
184
184
  name: /speckit.tasks
185
185
  lane: feature
186
186
  artifacts: [tasks.md]
187
- exit: [READY]
187
+ exit: [DONE, BLOCKED]
188
188
  role: spec-author
189
- skill: speckit-tasks
189
+ speckit: speckit.tasks
190
190
  - id: analyze
191
191
  name: /speckit.analyze
192
192
  lane: feature
193
193
  artifacts: [analysis.md]
194
- exit: [PASS, NEEDS_FIX]
194
+ exit: [DONE, BLOCKED]
195
195
  role: spec-author
196
- skill: speckit-analyze
196
+ speckit: speckit.analyze
197
197
  - id: implement
198
198
  name: /speckit.implement
199
199
  lane: feature
@@ -201,37 +201,57 @@ commands:
201
201
  exit: [DONE, BLOCKED]
202
202
  role: implementer-frontend
203
203
  co_roles: [implementer-backend]
204
- skill: speckit-implement
204
+ speckit: speckit.implement
205
205
  - id: converge
206
206
  name: /speckit.converge
207
207
  lane: feature
208
208
  artifacts: [convergence.md]
209
209
  exit: [CONVERGED, NEEDS_WORK]
210
210
  role: reviewer-architecture
211
- skill: speckit-converge
211
+ speckit: speckit.converge
212
212
 
213
213
  - id: bug-assess
214
214
  name: /speckit-bug-assess
215
215
  lane: bug
216
216
  artifacts: [assessment.md]
217
- exit: [ROOT_CAUSE, NEEDS_DATA]
217
+ exit: [VALID, NEEDS_REPRODUCTION, INVALID]
218
218
  role: reviewer-architecture
219
- skill: speckit-bug-assess
219
+ speckit: speckit.bug.assess
220
220
  - id: bug-fix
221
221
  name: /speckit-bug-fix
222
222
  lane: bug
223
223
  artifacts: [fix.md]
224
- exit: [FIXED, BLOCKED]
224
+ exit: [APPLIED, PARTIAL, NOT_APPLIED]
225
225
  role: implementer-backend
226
226
  co_roles: [implementer-frontend]
227
- skill: speckit-bug-fix
227
+ speckit: speckit.bug.fix
228
228
  - id: bug-test
229
229
  name: /speckit-bug-test
230
230
  lane: bug
231
231
  artifacts: [test.md]
232
232
  exit: [VERIFIED, PARTIAL, FAILED]
233
233
  role: reviewer-tests
234
- skill: speckit-bug-test
234
+ speckit: speckit.bug.test
235
+
236
+ # Efecto de cada estado de salida sobre las etiquetas ai::* (tabla única, design D2.6).
237
+ # Ningún agente mueve una etiqueta: hermes-control aplica o propone el cambio y un humano confirma
238
+ # las propuestas de cierre (KILL, INVALID).
239
+ exit_effects:
240
+ GO: mantiene ai::in-spec; Spec-Author empieza la autoría de la feature
241
+ NEEDS_CLARIFICATION: mantiene ai::in-spec; se repite la etapa indicada
242
+ KILL: propone ai::done; hermes-control propone el cierre y un humano lo confirma
243
+ DONE: sin cambio de etiqueta; el artefacto declarado existe y el carril continúa
244
+ BLOCKED: ai::blocked con motivo y evidencia
245
+ CONVERGED: ai::in-review
246
+ NEEDS_WORK: mantiene ai::in-dev; las tareas pendientes se añaden a tasks.md
247
+ VALID: sin cambio de etiqueta; el bug pasa a bug-fix
248
+ NEEDS_REPRODUCTION: ai::blocked; faltan datos para reproducir
249
+ INVALID: propone ai::done; hermes-control propone el cierre y un humano lo confirma
250
+ APPLIED: ai::in-review
251
+ PARTIAL: mantiene ai::in-dev
252
+ NOT_APPLIED: ai::blocked con motivo y evidencia
253
+ VERIFIED: ai::done a través de la revisión
254
+ FAILED: ai::blocked con motivo y evidencia
235
255
 
236
256
  labels:
237
257
  - ai::todo
@@ -248,3 +268,17 @@ targets:
248
268
  - pi
249
269
  - cursor
250
270
  - copilot
271
+
272
+ # Spec Kit: dependencia de runtime fijada por el paquete. Un proyecto solo puede
273
+ # restringirla desde el bloque `speckit` de manifest.yaml, nunca ampliarla.
274
+ speckit:
275
+ package: specify-cli
276
+ pin: 1.2.3
277
+ supported: '>=1.2.3 <1.3.0'
278
+ # Fecha --exclude-newer de uvx: valor provisional; se fija el día de la publicación de 0.3.0.
279
+ # Moverla es una decisión de release, nunca automática. Es la única copia de esta fecha.
280
+ excludeNewer: '2026-10-27'
281
+ script: sh
282
+ extensions:
283
+ assess: 1.0.1
284
+ bug: 1.0.1
package/manifest.json CHANGED
@@ -29,103 +29,103 @@
29
29
  "id": "analyze",
30
30
  "lane": "feature",
31
31
  "role": "spec-author",
32
- "skill": "speckit-analyze"
32
+ "speckit": "speckit.analyze"
33
33
  },
34
34
  {
35
35
  "id": "assess-decide",
36
36
  "lane": "assessment",
37
37
  "role": "spec-explorer",
38
- "skill": "speckit-assess-decide"
38
+ "speckit": "speckit.assess.decide"
39
39
  },
40
40
  {
41
41
  "id": "assess-define",
42
42
  "lane": "assessment",
43
43
  "role": "spec-explorer",
44
- "skill": "speckit-assess-define"
44
+ "speckit": "speckit.assess.define"
45
45
  },
46
46
  {
47
47
  "id": "assess-intake",
48
48
  "lane": "assessment",
49
49
  "role": "spec-explorer",
50
- "skill": "speckit-assess-intake"
50
+ "speckit": "speckit.assess.intake"
51
51
  },
52
52
  {
53
53
  "id": "assess-research",
54
54
  "lane": "assessment",
55
55
  "role": "spec-explorer",
56
- "skill": "speckit-assess-research"
56
+ "speckit": "speckit.assess.research"
57
57
  },
58
58
  {
59
59
  "id": "assess-shape",
60
60
  "lane": "assessment",
61
61
  "role": "spec-explorer",
62
- "skill": "speckit-assess-shape"
62
+ "speckit": "speckit.assess.shape"
63
63
  },
64
64
  {
65
65
  "id": "bug-assess",
66
66
  "lane": "bug",
67
67
  "role": "reviewer-architecture",
68
- "skill": "speckit-bug-assess"
68
+ "speckit": "speckit.bug.assess"
69
69
  },
70
70
  {
71
71
  "id": "bug-fix",
72
72
  "lane": "bug",
73
73
  "role": "implementer-backend",
74
- "skill": "speckit-bug-fix"
74
+ "speckit": "speckit.bug.fix"
75
75
  },
76
76
  {
77
77
  "id": "bug-test",
78
78
  "lane": "bug",
79
79
  "role": "reviewer-tests",
80
- "skill": "speckit-bug-test"
80
+ "speckit": "speckit.bug.test"
81
81
  },
82
82
  {
83
83
  "id": "checklist",
84
84
  "lane": "feature",
85
85
  "role": "spec-author",
86
- "skill": "speckit-checklist"
86
+ "speckit": "speckit.checklist"
87
87
  },
88
88
  {
89
89
  "id": "clarify",
90
90
  "lane": "feature",
91
91
  "role": "spec-author",
92
- "skill": "speckit-clarify"
92
+ "speckit": "speckit.clarify"
93
93
  },
94
94
  {
95
95
  "id": "constitution",
96
96
  "lane": "feature",
97
97
  "role": "spec-author",
98
- "skill": "speckit-constitution"
98
+ "speckit": "speckit.constitution"
99
99
  },
100
100
  {
101
101
  "id": "converge",
102
102
  "lane": "feature",
103
103
  "role": "reviewer-architecture",
104
- "skill": "speckit-converge"
104
+ "speckit": "speckit.converge"
105
105
  },
106
106
  {
107
107
  "id": "implement",
108
108
  "lane": "feature",
109
109
  "role": "implementer-frontend",
110
- "skill": "speckit-implement"
110
+ "speckit": "speckit.implement"
111
111
  },
112
112
  {
113
113
  "id": "plan",
114
114
  "lane": "feature",
115
115
  "role": "spec-author",
116
- "skill": "speckit-plan"
116
+ "speckit": "speckit.plan"
117
117
  },
118
118
  {
119
119
  "id": "specify",
120
120
  "lane": "feature",
121
121
  "role": "spec-author",
122
- "skill": "speckit-specify"
122
+ "speckit": "speckit.specify"
123
123
  },
124
124
  {
125
125
  "id": "tasks",
126
126
  "lane": "feature",
127
127
  "role": "spec-author",
128
- "skill": "speckit-tasks"
128
+ "speckit": "speckit.tasks"
129
129
  }
130
130
  ],
131
131
  "labels": [
@@ -150,8 +150,8 @@
150
150
  "rules": "custom"
151
151
  },
152
152
  "catalog": {
153
- "version": "0.2.0",
154
- "hash": "f30e2590a4eb078ea520873661b5f10fb3cf9171d1422438c35aafd722abbb23"
153
+ "version": "0.3.0",
154
+ "hash": "9605441252114d0ccd1e03a433420d7645618f8956c71bd16634d35e8b427f66"
155
155
  },
156
156
  "agents": [
157
157
  "cpp-build-resolver",
@@ -195,7 +195,6 @@
195
195
  "accessibility",
196
196
  "agent-eval",
197
197
  "agent-safety",
198
- "analyze",
199
198
  "angular",
200
199
  "api-connector-builder",
201
200
  "api-design",
@@ -208,7 +207,6 @@
208
207
  "building-agents",
209
208
  "chatbot",
210
209
  "chrome-extension",
211
- "clarify",
212
210
  "clickhouse-analytics",
213
211
  "cloudflare",
214
212
  "code-review",
@@ -272,7 +270,6 @@
272
270
  "htmx",
273
271
  "huggingface",
274
272
  "idea-refinement",
275
- "implement",
276
273
  "init",
277
274
  "java",
278
275
  "knowledge-ops",
@@ -300,7 +297,6 @@
300
297
  "performance",
301
298
  "phoenix",
302
299
  "php",
303
- "plan",
304
300
  "planetscale",
305
301
  "planning-with-files",
306
302
  "postgresdb",
@@ -316,39 +312,17 @@
316
312
  "render",
317
313
  "replicate",
318
314
  "research-ops",
319
- "review",
320
315
  "ruby",
321
316
  "runpod",
322
317
  "rust",
323
318
  "scaling",
324
- "sdd",
325
- "sdd-init",
326
319
  "secure-coding",
327
320
  "security-scan",
328
- "ship",
329
321
  "shopify",
330
322
  "simplify-code",
331
323
  "skill-scout",
332
324
  "solid-js",
333
325
  "source-grounded-development",
334
- "specify",
335
- "speckit-analyze",
336
- "speckit-assess-decide",
337
- "speckit-assess-define",
338
- "speckit-assess-intake",
339
- "speckit-assess-research",
340
- "speckit-assess-shape",
341
- "speckit-bug-assess",
342
- "speckit-bug-fix",
343
- "speckit-bug-test",
344
- "speckit-checklist",
345
- "speckit-clarify",
346
- "speckit-constitution",
347
- "speckit-converge",
348
- "speckit-implement",
349
- "speckit-plan",
350
- "speckit-specify",
351
- "speckit-tasks",
352
326
  "spreadsheet-ops",
353
327
  "spring-boot",
354
328
  "sql",
@@ -358,7 +332,6 @@
358
332
  "supabase",
359
333
  "svelte",
360
334
  "swift-ios",
361
- "tasks",
362
335
  "tauri",
363
336
  "technical-writing",
364
337
  "testing-go",
@@ -376,7 +349,6 @@
376
349
  "variant-explorer",
377
350
  "vector-db",
378
351
  "vercel",
379
- "verify",
380
352
  "vllm",
381
353
  "vue-nuxt",
382
354
  "webhooks",
@@ -396,7 +368,7 @@
396
368
  "labels": 7,
397
369
  "targets": 5,
398
370
  "agents": 35,
399
- "skills": 191,
371
+ "skills": 163,
400
372
  "rules": 5
401
373
  }
402
374
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dsalazardev/ai-hub-cli",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "author": "Daner Alejandro Salazar Colorado",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -2,7 +2,7 @@
2
2
  "$schema": "http://json-schema.org/draft-07/schema#",
3
3
  "title": "AiHubEngineV2",
4
4
  "type": "object",
5
- "required": ["version", "roles", "commands", "labels", "targets"],
5
+ "required": ["version", "roles", "commands", "exit_effects", "labels", "targets", "speckit"],
6
6
  "additionalProperties": false,
7
7
  "properties": {
8
8
  "version": { "const": 2 },
@@ -32,7 +32,7 @@
32
32
  "maxItems": 17,
33
33
  "items": {
34
34
  "type": "object",
35
- "required": ["id", "name", "lane", "artifacts", "exit", "role", "skill"],
35
+ "required": ["id", "name", "lane", "artifacts", "exit", "role", "speckit"],
36
36
  "additionalProperties": false,
37
37
  "properties": {
38
38
  "id": { "type": "string", "pattern": "^[a-z][a-z0-9-]*$" },
@@ -42,10 +42,14 @@
42
42
  "exit": { "type": "array", "minItems": 1, "items": { "type": "string" } },
43
43
  "role": { "type": "string", "minLength": 1 },
44
44
  "co_roles": { "type": "array", "items": { "type": "string" }, "uniqueItems": true },
45
- "skill": { "type": "string", "pattern": "^speckit-" }
45
+ "speckit": { "type": "string", "pattern": "^speckit[.][a-z]+([.][a-z]+)?$" }
46
46
  }
47
47
  }
48
48
  },
49
+ "exit_effects": {
50
+ "type": "object",
51
+ "additionalProperties": { "type": "string", "minLength": 1 }
52
+ },
49
53
  "labels": {
50
54
  "type": "array",
51
55
  "minItems": 7,
@@ -68,6 +72,21 @@
68
72
  "minItems": 5,
69
73
  "uniqueItems": true,
70
74
  "items": { "enum": ["claude", "opencode", "pi", "cursor", "copilot"] }
75
+ },
76
+ "speckit": {
77
+ "type": "object",
78
+ "additionalProperties": false,
79
+ "properties": {
80
+ "package": { "type": "string", "minLength": 1 },
81
+ "pin": { "type": "string", "pattern": "^\\d+\\.\\d+\\.\\d+$" },
82
+ "supported": { "type": "string", "minLength": 1 },
83
+ "excludeNewer": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" },
84
+ "script": { "enum": ["sh", "ps"] },
85
+ "extensions": {
86
+ "type": "object",
87
+ "additionalProperties": { "type": "string", "pattern": "^\\d+\\.\\d+\\.\\d+$" }
88
+ }
89
+ }
71
90
  }
72
91
  }
73
92
  }
@@ -147,6 +147,16 @@
147
147
  "properties": {
148
148
  "source": { "type": "string", "minLength": 1 }
149
149
  }
150
+ },
151
+ "speckit": {
152
+ "type": "object",
153
+ "additionalProperties": false,
154
+ "properties": {
155
+ "managed": { "type": "boolean" },
156
+ "version": { "type": "string", "minLength": 1 },
157
+ "script": { "enum": ["sh", "ps"] },
158
+ "defaultTarget": { "type": "string", "minLength": 1 }
159
+ }
150
160
  }
151
161
  }
152
162
  }
@@ -3,7 +3,8 @@ name: analyze
3
3
  description: "Use when constitution, spec, plan and tasks all exist and you want them cross-read against each other before any code is written — the ai-hub Spec-Kit pre-implementation gate. Reports coverage gaps, contradictions, duplication, ambiguity and scope drift; edits nothing. NOT the task breakdown (that is `tasks`), NOT the coding (that is `implement`), NOT the post-code test gate (that is `verify`), NOT resolving ambiguity (that is `clarify`)."
4
4
  tags: [sdd, analyze, consistency]
5
5
  recommends: [implement]
6
- profiles: [core, full]
6
+ profiles: [full]
7
+ runtime: false
7
8
  origin: ai-hub
8
9
  ---
9
10