create-quiver 0.7.0 → 0.9.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 (89) hide show
  1. package/.claude/settings.local.json +52 -0
  2. package/.github/workflows/ci.yml +2 -2
  3. package/BACKLOG.md +139 -0
  4. package/CHANGELOG.md +20 -1
  5. package/README.md +31 -1
  6. package/README_FOR_AI.md +25 -13
  7. package/ROADMAP.md +28 -6
  8. package/docs/AI_ONBOARDING_PROMPT.md.template +4 -0
  9. package/docs/COMMANDS.md.template +25 -0
  10. package/docs/INDEX.md.template +2 -0
  11. package/docs/SUPPORT_MATRIX.md.template +9 -0
  12. package/docs/WORKFLOW.md.template +4 -0
  13. package/docs/examples/graph.md.template +62 -0
  14. package/docs/examples/next.md.template +27 -0
  15. package/docs/examples/plan.md.template +28 -0
  16. package/package.json +5 -2
  17. package/package.template.json +8 -3
  18. package/scripts/check-slice-readiness.sh +6 -4
  19. package/scripts/init-docs.sh +57 -9
  20. package/specs/[project-name]/HANDOFF.md.template +37 -0
  21. package/specs/[project-name]/slices/slice-template/slice.json +5 -0
  22. package/specs/quiver-v08-agent-onboarding-analysis/slices/slice-01-project-scan-command/slice.json +1 -1
  23. package/specs/quiver-v08-agent-onboarding-analysis/slices/slice-02-ai-onboarding-prompt/slice.json +1 -1
  24. package/specs/quiver-v08-agent-onboarding-analysis/slices/slice-03-doctor-readme-adoption-flow/slice.json +1 -1
  25. package/specs/quiver-v12-cross-platform-native-runtime/slices/slice-01-cross-platform-support-contract/slice.json +1 -1
  26. package/specs/quiver-v12-cross-platform-native-runtime/slices/slice-02-node-init-docs-runtime/slice.json +1 -1
  27. package/specs/quiver-v12-cross-platform-native-runtime/slices/slice-03-node-migrate-analyze-doctor-flow/slice.json +1 -1
  28. package/specs/quiver-v12-cross-platform-native-runtime/slices/slice-04-node-slice-lifecycle-commands/slice.json +1 -1
  29. package/specs/quiver-v12-cross-platform-native-runtime/slices/slice-05-generated-project-scripts-and-migration/slice.json +1 -1
  30. package/specs/quiver-v13-token-efficient-ai-context/EVIDENCE_REPORT.md +1 -1
  31. package/specs/quiver-v13-token-efficient-ai-context/SPEC.md +1 -1
  32. package/specs/quiver-v15-init-required-before-migrate/EVIDENCE_REPORT.md +26 -0
  33. package/specs/quiver-v15-init-required-before-migrate/SPEC.md +66 -0
  34. package/specs/quiver-v15-init-required-before-migrate/STATUS.md +26 -0
  35. package/specs/quiver-v15-init-required-before-migrate/slices/slice-01-migrate-initialization-precondition/slice.json +65 -0
  36. package/specs/quiver-v15-init-required-before-migrate/slices/slice-02-doctor-not-initialized-guidance/slice.json +61 -0
  37. package/specs/quiver-v15-init-required-before-migrate/slices/slice-03-docs-smokes-init-before-migrate/slice.json +64 -0
  38. package/specs/quiver-v16-handoff-contract/EVIDENCE_REPORT.md +26 -0
  39. package/specs/quiver-v16-handoff-contract/SPEC.md +68 -0
  40. package/specs/quiver-v16-handoff-contract/STATUS.md +26 -0
  41. package/specs/quiver-v16-handoff-contract/slices/slice-01-handoff-template-and-contract/slice.json +66 -0
  42. package/specs/quiver-v16-handoff-contract/slices/slice-02-check-handoff-command/slice.json +70 -0
  43. package/specs/quiver-v16-handoff-contract/slices/slice-03-handoff-scaffold-optional/slice.json +67 -0
  44. package/specs/quiver-v17-orchestration-foundation/EVIDENCE_REPORT.md +32 -0
  45. package/specs/quiver-v17-orchestration-foundation/SPEC.md +79 -0
  46. package/specs/quiver-v17-orchestration-foundation/STATUS.md +31 -0
  47. package/specs/quiver-v17-orchestration-foundation/slices/slice-01-ci-matrix-verified/slice.json +68 -0
  48. package/specs/quiver-v17-orchestration-foundation/slices/slice-02-slice-graph-library/slice.json +65 -0
  49. package/specs/quiver-v17-orchestration-foundation/slices/slice-03-depends-on-validation/slice.json +72 -0
  50. package/specs/quiver-v18-slice-orchestration/EVIDENCE_REPORT.md +38 -0
  51. package/specs/quiver-v18-slice-orchestration/SPEC.md +91 -0
  52. package/specs/quiver-v18-slice-orchestration/STATUS.md +33 -0
  53. package/specs/quiver-v18-slice-orchestration/slices/slice-01-plan-command/slice.json +79 -0
  54. package/specs/quiver-v18-slice-orchestration/slices/slice-02-graph-mvp-tree/slice.json +75 -0
  55. package/specs/quiver-v18-slice-orchestration/slices/slice-03-graph-extended-formats/slice.json +70 -0
  56. package/specs/quiver-v18-slice-orchestration/slices/slice-04-next-command/slice.json +73 -0
  57. package/specs/quiver-v18-stabilization/EVIDENCE_REPORT.md +26 -0
  58. package/specs/quiver-v18-stabilization/SPEC.md +62 -0
  59. package/specs/quiver-v18-stabilization/STATUS.md +30 -0
  60. package/specs/quiver-v18-stabilization/slices/slice-01-fix-legacy-dependency-resolution/CLOSURE_BRIEF.md +29 -0
  61. package/specs/quiver-v18-stabilization/slices/slice-01-fix-legacy-dependency-resolution/EXECUTION_BRIEF.md +134 -0
  62. package/specs/quiver-v18-stabilization/slices/slice-01-fix-legacy-dependency-resolution/slice.json +56 -0
  63. package/specs/quiver-v18-stabilization/slices/slice-02-roadmap-and-branch-cleanup/CLOSURE_BRIEF.md +29 -0
  64. package/specs/quiver-v18-stabilization/slices/slice-02-roadmap-and-branch-cleanup/EXECUTION_BRIEF.md +118 -0
  65. package/specs/quiver-v18-stabilization/slices/slice-02-roadmap-and-branch-cleanup/slice.json +57 -0
  66. package/specs/quiver-v18-stabilization/slices/slice-03-publish-drafts-branch/CLOSURE_BRIEF.md +23 -0
  67. package/specs/quiver-v18-stabilization/slices/slice-03-publish-drafts-branch/EXECUTION_BRIEF.md +73 -0
  68. package/specs/quiver-v18-stabilization/slices/slice-03-publish-drafts-branch/slice.json +49 -0
  69. package/specs/quiver-v19-self-install-dev-dep/EVIDENCE_REPORT.md +19 -0
  70. package/specs/quiver-v19-self-install-dev-dep/SPEC.md +51 -0
  71. package/specs/quiver-v19-self-install-dev-dep/STATUS.md +20 -0
  72. package/specs/quiver-v19-self-install-dev-dep/slices/slice-01-auto-install-dev-dep/CLOSURE_BRIEF.md +29 -0
  73. package/specs/quiver-v19-self-install-dev-dep/slices/slice-01-auto-install-dev-dep/EXECUTION_BRIEF.md +287 -0
  74. package/specs/quiver-v19-self-install-dev-dep/slices/slice-01-auto-install-dev-dep/slice.json +56 -0
  75. package/src/create-quiver/commands/graph.js +97 -0
  76. package/src/create-quiver/commands/next.js +134 -0
  77. package/src/create-quiver/commands/plan.js +205 -0
  78. package/src/create-quiver/index.js +203 -3
  79. package/src/create-quiver/lib/handoff.js +104 -0
  80. package/src/create-quiver/lib/init-docs.js +108 -13
  81. package/src/create-quiver/lib/json.js +14 -0
  82. package/src/create-quiver/lib/lifecycle.js +3 -2
  83. package/src/create-quiver/lib/readiness.js +55 -1
  84. package/src/create-quiver/lib/renderers/dot.js +129 -0
  85. package/src/create-quiver/lib/renderers/mermaid.js +119 -0
  86. package/src/create-quiver/lib/renderers/tree.js +116 -0
  87. package/src/create-quiver/lib/slice-graph.js +453 -0
  88. package/src/create-quiver/lib/slice.js +2 -1
  89. package/src/create-quiver/lib/state.js +50 -0
@@ -0,0 +1,73 @@
1
+ # EXECUTION BRIEF — slice-03: Publicar rama de drafts
2
+
3
+ **Spec:** quiver-v18-stabilization
4
+ **Slice:** slice-03-publish-drafts-branch
5
+ **Estimated time:** 5 min
6
+ **Sin PR** — es un `git push` directo de una rama de referencia.
7
+
8
+ ---
9
+
10
+ ## ⛔ Gate obligatoria — leer antes de ejecutar cualquier cosa
11
+
12
+ Este slice está **bloqueado** hasta que el mantenedor confirme explícitamente:
13
+
14
+ 1. Usé `quiver:plan`, `quiver:graph`, y `quiver:next` en al menos un ciclo real de trabajo.
15
+ 2. Registré una observación en `specs/quiver-v18-slice-orchestration/EVIDENCE_REPORT.md`.
16
+ 3. Confirmo que el checkpoint de v18 pasó.
17
+
18
+ **Si esa confirmación no está en el prompt que te delega este slice, abortá y pedila.**
19
+
20
+ ---
21
+
22
+ ## Contexto
23
+
24
+ La rama `drafts/v19-v22-orchestration-followups` existe solo localmente. Contiene 23 archivos (4 specs: v19–v22) en un único commit. ROADMAP.md y BACKLOG.md ya hacen referencia a esta rama por nombre. Publicarla en origin completa la cadena de trazabilidad y protege el trabajo ante pérdida local.
25
+
26
+ No es una rama candidata a merge. Es una rama de referencia que vive indefinidamente hasta que alguna de las specs se promueva formalmente.
27
+
28
+ ---
29
+
30
+ ## Verificación previa
31
+
32
+ ```bash
33
+ # 1. Confirmar que la rama existe y tiene el commit correcto
34
+ git log drafts/v19-v22-orchestration-followups --oneline -1
35
+ # Esperás: 13eab96 docs(drafts): park v19-v22 spec drafts pending v18 checkpoint
36
+
37
+ # 2. Confirmar que NO existe ya en origin
38
+ git ls-remote origin drafts/v19-v22-orchestration-followups
39
+ # Esperás: salida vacía (si retorna algo, la rama ya fue publicada — slice completado)
40
+ ```
41
+
42
+ ---
43
+
44
+ ## Ejecución
45
+
46
+ ```bash
47
+ GIT_SSH_COMMAND="ssh -i ~/ssh/github-personal" \
48
+ git push origin drafts/v19-v22-orchestration-followups
49
+ ```
50
+
51
+ ---
52
+
53
+ ## Verificación post-push
54
+
55
+ ```bash
56
+ # Confirmar que el SHA remoto coincide con el local
57
+ LOCAL_SHA=$(git rev-parse drafts/v19-v22-orchestration-followups)
58
+ REMOTE_SHA=$(git ls-remote origin drafts/v19-v22-orchestration-followups | awk '{print $1}')
59
+
60
+ echo "Local: $LOCAL_SHA"
61
+ echo "Remote: $REMOTE_SHA"
62
+
63
+ [ "$LOCAL_SHA" = "$REMOTE_SHA" ] && echo "OK" || echo "MISMATCH — investigar"
64
+ ```
65
+
66
+ ---
67
+
68
+ ## Restricciones
69
+
70
+ - **No** abras un PR para esta rama.
71
+ - **No** hagas `--force` en ninguna circunstancia.
72
+ - **No** edites ningún archivo en la rama antes de publicarla.
73
+ - **No** ejecutes este slice si el gate no fue confirmado explícitamente.
@@ -0,0 +1,49 @@
1
+ {
2
+ "slice_id": "slice-03-publish-drafts-branch",
3
+ "ticket": "QUIVER-03",
4
+ "type": "chore",
5
+ "title": "Publish `drafts/v19-v22-orchestration-followups` to origin",
6
+ "objective": "Push the locally-parked v19–v22 draft specs to origin so they are preserved in the remote in case of local machine loss and are accessible for future promotion.",
7
+ "description": "The branch `drafts/v19-v22-orchestration-followups` exists only locally. It contains 23 files across 4 spec directories (v19 Project Visibility, v20 Context Diagnostics, v21 Slice Archaeology, v22 Deferred Tooling) committed in a single commit. ROADMAP.md and BACKLOG.md already reference this branch by name. Pushing it to origin completes the traceability chain. This slice has no PR — it is a single `git push` operation. It is gated by the human checkpoint for v18: the maintainer must confirm that `plan`, `graph`, and `next` were used in real work before this slice is executed.",
8
+ "git": {
9
+ "branch_type": "chore",
10
+ "base_branch": null,
11
+ "branch_slug": "publish-drafts-v19-v22",
12
+ "branch_name": "drafts/v19-v22-orchestration-followups"
13
+ },
14
+ "must": [
15
+ "Confirm the human checkpoint for v18 was explicitly declared by the maintainer before executing",
16
+ "Run `git log drafts/v19-v22-orchestration-followups --oneline -1` and confirm the expected SHA is present",
17
+ "Push with: `GIT_SSH_COMMAND=\"ssh -i ~/ssh/github-personal\" git push origin drafts/v19-v22-orchestration-followups`",
18
+ "Verify with: `git ls-remote origin drafts/v19-v22-orchestration-followups` and confirm the SHA matches local"
19
+ ],
20
+ "not_included": [
21
+ "Opening a PR for the drafts branch — it is a reference branch, not a merge candidate",
22
+ "Promoting any of v19–v22 to active spec — that is a separate decision after the checkpoint",
23
+ "Modifying any file in the drafts branch",
24
+ "Any other git push"
25
+ ],
26
+ "acceptance": [
27
+ "Maintainer has explicitly confirmed the v18 human checkpoint",
28
+ "`git ls-remote origin drafts/v19-v22-orchestration-followups` returns a non-empty SHA",
29
+ "The returned SHA matches `git rev-parse drafts/v19-v22-orchestration-followups`"
30
+ ],
31
+ "files": [],
32
+ "tests": [
33
+ "git ls-remote origin drafts/v19-v22-orchestration-followups",
34
+ "git rev-parse drafts/v19-v22-orchestration-followups"
35
+ ],
36
+ "documentation": [],
37
+ "depends_on": [],
38
+ "assumptions": [
39
+ "The SSH key at `~/ssh/github-personal` has push access to `FabriJuncal/quiver`",
40
+ "The local branch `drafts/v19-v22-orchestration-followups` has not been rebased or force-reset since creation"
41
+ ],
42
+ "estimated_hours": 0.1,
43
+ "actual_hours": 0.1,
44
+ "status": "completed",
45
+ "blocked_reason": null,
46
+ "ready_at": "2026-05-12T00:00:00Z",
47
+ "started_at": "2026-05-12T00:00:00Z",
48
+ "completed_at": "2026-05-12T00:00:00Z"
49
+ }
@@ -0,0 +1,19 @@
1
+ # Quiver v19 — Evidence Report
2
+
3
+ **Spec:** quiver-v19-self-install-dev-dep
4
+ **Date:** 2026-05-14
5
+ **Status:** In Progress
6
+
7
+ ## Slice Evidence
8
+
9
+ | Slice | Status | Evidence |
10
+ |-------|--------|----------|
11
+ | slice-01 | Ready | — |
12
+
13
+ ## Required Final Evidence
14
+
15
+ - `npx create-quiver --name "test-project" --dir /tmp/test-project` → `cat /tmp/test-project/package.json | grep create-quiver` returns a devDependency entry
16
+ - `ls /tmp/test-project/node_modules/create-quiver` → directory exists
17
+ - `npx create-quiver plan` inside `/tmp/test-project` → exits 0 without `@version`
18
+ - `npx create-quiver --skip-install --name "ci-project" --dir /tmp/ci-project` → no `node_modules/create-quiver`
19
+ - `node --test tests/**/*.test.js` → all pass
@@ -0,0 +1,51 @@
1
+ # Quiver v19 — Self-Install as Dev Dependency
2
+
3
+ **Date:** 2026-05-14
4
+ **Status:** Active
5
+
6
+ Slice numbering resets here. This spec starts at `slice-01`.
7
+
8
+ ## Problem
9
+
10
+ `npx create-quiver` uses the global npx cache. After init, commands like `quiver:plan`, `quiver:graph`, and `quiver:next` in the target project may silently run the cached version instead of the latest — or fail entirely if the version in cache predates those commands. The user has no `create-quiver` in their `node_modules` unless they install it manually.
11
+
12
+ ## Objective
13
+
14
+ After `npx create-quiver --name "foo"` (init) or `npx create-quiver migrate`, the target project's `package.json` has `create-quiver` in `devDependencies` and it is installed in `node_modules`. Subsequent `npx create-quiver` invocations in that project resolve to the local version — no cache issues, reproducible across machines.
15
+
16
+ ## Scope
17
+
18
+ ### Included
19
+
20
+ - Detect the package manager in use (yarn, pnpm, bun, npm) by checking lockfiles
21
+ - Run the appropriate install command (`npm install -D`, `yarn add -D`, `pnpm add -D`, `bun add -d`) with the exact running version
22
+ - Skip if `create-quiver` is already present in `devDependencies`
23
+ - Skip gracefully if no `package.json` exists in the target project
24
+ - Add `--skip-install` flag to the CLI for CI environments
25
+ - Apply to both `init` and `migrate` flows
26
+ - Tests for `detectPackageManager` and `installSelfAsDevDep`
27
+
28
+ ### Excluded
29
+
30
+ - Changing any other part of the init/migrate scaffold output
31
+ - Supporting non-standard registries or private npm configurations
32
+ - Auto-updating an existing create-quiver devDependency to a newer version
33
+
34
+ ## Acceptance Criteria
35
+
36
+ 1. After init, `cat package.json | jq .devDependencies` shows `"create-quiver": "^X.Y.Z"`
37
+ 2. `node_modules/create-quiver` exists in the target project after init
38
+ 3. `npx create-quiver plan` (no `@version`) works immediately after init
39
+ 4. If target project has no `package.json` → no crash, warning printed, init continues
40
+ 5. If `create-quiver` already in `devDependencies` → step skipped, no duplicate install
41
+ 6. `npx create-quiver --skip-install --name "foo"` → installs Quiver docs but skips npm install
42
+ 7. `npx create-quiver migrate --skip-install` → same skip behavior
43
+ 8. yarn/pnpm/bun projects get the right install command
44
+ 9. If install fails (no network, etc.) → warning printed, init completes without crashing
45
+ 10. `node --test tests/**/*.test.js` passes
46
+
47
+ ## Slices
48
+
49
+ | Slice | Title | Status |
50
+ |-------|-------|--------|
51
+ | slice-01 | Auto-install create-quiver as dev dependency | Ready |
@@ -0,0 +1,20 @@
1
+ # Quiver v19 — Status
2
+
3
+ **Spec:** quiver-v19-self-install-dev-dep
4
+ **Last updated:** 2026-05-14
5
+
6
+ ## Status
7
+
8
+ | Slice | Title | Status | PR | Estimated hours | Actual hours |
9
+ |-------|-------|--------|----|-----------------|--------------|
10
+ | slice-01 | Auto-install create-quiver as dev dependency | Ready | — | 1.5 | — |
11
+
12
+ ## Progress
13
+
14
+ - Completed slices: 0 / 1
15
+ - Estimated hours: 1.5
16
+ - Actual hours: —
17
+
18
+ ## Blockers
19
+
20
+ None.
@@ -0,0 +1,29 @@
1
+ # CLOSURE BRIEF — slice-01: Auto-install create-quiver as dev dependency
2
+
3
+ **Spec:** quiver-v19-self-install-dev-dep
4
+ **Slice:** slice-01-auto-install-dev-dep
5
+
6
+ ---
7
+
8
+ ## Checklist antes de abrir el PR
9
+
10
+ - [ ] `node --test tests/**/*.test.js` → exit 0, todos los tests pasan incluyendo los 7 nuevos en `init-docs.test.js`
11
+ - [ ] Smoke con `--skip-install` → `node_modules/create-quiver` NO existe en el proyecto destino
12
+ - [ ] Smoke sin `--skip-install` → `node_modules/create-quiver` SÍ existe y `npx create-quiver plan` funciona sin `@version`
13
+ - [ ] Smoke con `devDependencies` preexistente → el step se saltea, no hay doble install
14
+ - [ ] `git diff --stat HEAD` muestra exactamente 3 archivos: `src/create-quiver/lib/init-docs.js`, `src/create-quiver/index.js`, `tests/lib/init-docs.test.js`
15
+
16
+ ## Checklist del PR
17
+
18
+ - [ ] Branch: `feature/QUIVER-01-auto-install-dev-dep` → `main`
19
+ - [ ] Título: `feat(QUIVER-01): auto-install create-quiver as dev dependency after init`
20
+ - [ ] Body sigue las secciones del `docs/GITFLOW_PR_GUIDE.md.template`
21
+ - [ ] En "Evidence": output del smoke test mostrando `node_modules/create-quiver` creado y `npx create-quiver plan` funcionando
22
+ - [ ] En "Risks / Notes": mencionar que en entornos sin red el install falla silenciosamente (expected behavior) y documentar el `--skip-install` flag
23
+
24
+ ## Post-merge
25
+
26
+ - [ ] Actualizar `specs/quiver-v19-self-install-dev-dep/STATUS.md`: slice-01 → `Completed`, agregar PR y `actual_hours`
27
+ - [ ] Actualizar `specs/quiver-v19-self-install-dev-dep/EVIDENCE_REPORT.md`: registrar evidencia
28
+ - [ ] Actualizar `slice.json`: `status: completed`, `actual_hours`, timestamps
29
+ - [ ] Evaluar si se publica `0.9.0` o si se acumula con otros cambios
@@ -0,0 +1,287 @@
1
+ # EXECUTION BRIEF — slice-01: Auto-install create-quiver as dev dependency
2
+
3
+ **Spec:** quiver-v19-self-install-dev-dep
4
+ **Slice:** slice-01-auto-install-dev-dep
5
+ **Branch:** `feature/QUIVER-01-auto-install-dev-dep` from `main`
6
+ **Estimated time:** 1.5h
7
+
8
+ ---
9
+
10
+ ## Contexto
11
+
12
+ `npx create-quiver` no instala el paquete en `node_modules` del proyecto destino. Después del init, comandos como `quiver:plan` fallan o usan la versión cacheada globalmente. La solución es correr el package manager del proyecto destino para instalar `create-quiver` como dev dependency inmediatamente después del init/migrate.
13
+
14
+ ---
15
+
16
+ ## Archivos a modificar
17
+
18
+ 1. `src/create-quiver/lib/init-docs.js` — agregar `detectPackageManager` e `installSelfAsDevDep`
19
+ 2. `src/create-quiver/index.js` — agregar `--skip-install` al parser, llamar a `installSelfAsDevDep` en init y migrate
20
+ 3. `tests/lib/init-docs.test.js` — nuevo archivo de tests
21
+
22
+ No toques ningún otro archivo.
23
+
24
+ ---
25
+
26
+ ## Parte A — `src/create-quiver/lib/init-docs.js`
27
+
28
+ ### Paso 1: Agregar import de `execSync`
29
+
30
+ Al inicio del archivo, después de los requires existentes (`fs`, `path`, `writeState`), agregar:
31
+
32
+ ```js
33
+ const { execSync } = require('child_process');
34
+ ```
35
+
36
+ ### Paso 2: Agregar las dos funciones nuevas
37
+
38
+ Agregar antes del `module.exports` al final del archivo:
39
+
40
+ ```js
41
+ function detectPackageManager(projectRoot) {
42
+ if (fs.existsSync(path.join(projectRoot, 'bun.lockb'))) return 'bun';
43
+ if (fs.existsSync(path.join(projectRoot, 'pnpm-lock.yaml'))) return 'pnpm';
44
+ if (fs.existsSync(path.join(projectRoot, 'yarn.lock'))) return 'yarn';
45
+ return 'npm';
46
+ }
47
+
48
+ function installSelfAsDevDep(projectRoot, version) {
49
+ const packageJsonPath = path.join(projectRoot, 'package.json');
50
+ if (!fs.existsSync(packageJsonPath)) {
51
+ return 'skipped-no-package-json';
52
+ }
53
+
54
+ const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
55
+ if (pkg.devDependencies && pkg.devDependencies['create-quiver']) {
56
+ return 'skipped-already-present';
57
+ }
58
+
59
+ const pm = detectPackageManager(projectRoot);
60
+ const commands = {
61
+ npm: `npm install -D create-quiver@${version}`,
62
+ yarn: `yarn add -D create-quiver@${version}`,
63
+ pnpm: `pnpm add -D create-quiver@${version}`,
64
+ bun: `bun add -d create-quiver@${version}`,
65
+ };
66
+
67
+ try {
68
+ execSync(commands[pm], { cwd: projectRoot, stdio: 'inherit' });
69
+ return 'installed';
70
+ } catch {
71
+ return 'failed';
72
+ }
73
+ }
74
+ ```
75
+
76
+ ### Paso 3: Exportar las funciones nuevas
77
+
78
+ Encontrá el `module.exports` actual y agregá las dos funciones nuevas:
79
+
80
+ ```js
81
+ module.exports = {
82
+ // ... exports existentes ...
83
+ detectPackageManager,
84
+ installSelfAsDevDep,
85
+ };
86
+ ```
87
+
88
+ ---
89
+
90
+ ## Parte B — `src/create-quiver/index.js`
91
+
92
+ ### Paso 1: Importar `installSelfAsDevDep`
93
+
94
+ En la línea 10 donde se importa `runInitDocs`, extender el destructuring para incluir la función nueva:
95
+
96
+ ```js
97
+ // Antes (aproximado):
98
+ const { runInitDocs } = require('./lib/init-docs');
99
+
100
+ // Después:
101
+ const { runInitDocs, installSelfAsDevDep } = require('./lib/init-docs');
102
+ ```
103
+
104
+ ### Paso 2: Agregar `--skip-install` al parser de args
105
+
106
+ Dentro de la función `parseArgs`, en el bloque donde se manejan los flags (el loop que analiza `arg`), agregar el caso nuevo junto a los otros flags booleanos (`--yes`, etc.):
107
+
108
+ ```js
109
+ if (arg === '--skip-install') {
110
+ result.skipInstall = true;
111
+ continue;
112
+ }
113
+ ```
114
+
115
+ ### Paso 3: Llamar a `installSelfAsDevDep` en el flujo de init
116
+
117
+ El flujo init en index.js (cerca de la línea 1416) actualmente es:
118
+
119
+ ```js
120
+ runInitDocs(targetDir, projectName);
121
+ console.log(`Installed Quiver into ${targetDir}`);
122
+ printInitNextSteps(targetDir, projectName);
123
+ ```
124
+
125
+ Reemplazarlo por:
126
+
127
+ ```js
128
+ runInitDocs(targetDir, projectName);
129
+
130
+ if (!args.skipInstall) {
131
+ const installResult = installSelfAsDevDep(targetDir, CLI_VERSION);
132
+ if (installResult === 'installed') {
133
+ console.log(`Added create-quiver@${CLI_VERSION} as dev dependency`);
134
+ } else if (installResult === 'failed') {
135
+ console.warn(`Warning: could not install create-quiver automatically. Run: npm install -D create-quiver@${CLI_VERSION}`);
136
+ }
137
+ }
138
+
139
+ console.log(`Installed Quiver into ${targetDir}`);
140
+ printInitNextSteps(targetDir, projectName);
141
+ ```
142
+
143
+ Nota: `CLI_VERSION` ya existe en `index.js` — no lo reimportes.
144
+
145
+ ### Paso 4: Llamar a `installSelfAsDevDep` en el flujo de migrate
146
+
147
+ Buscá el flujo de migrate en index.js (buscar `runInitDocs` con `migrateMode: true` o similar). Aplicar el mismo patrón después del call de init/migrate.
148
+
149
+ ---
150
+
151
+ ## Parte C — `tests/lib/init-docs.test.js` (archivo nuevo)
152
+
153
+ Crear este archivo con el patrón del repo (`node:test`, `node:assert/strict`):
154
+
155
+ ```js
156
+ const assert = require('node:assert/strict');
157
+ const fs = require('node:fs');
158
+ const os = require('node:os');
159
+ const path = require('node:path');
160
+ const test = require('node:test');
161
+
162
+ const { detectPackageManager, installSelfAsDevDep } = require('../../src/create-quiver/lib/init-docs');
163
+
164
+ function makeTmpDir() {
165
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'quiver-init-test-'));
166
+ return { dir, cleanup: () => fs.rmSync(dir, { recursive: true, force: true }) };
167
+ }
168
+
169
+ test('detectPackageManager returns npm when no lockfile exists', () => {
170
+ const { dir, cleanup } = makeTmpDir();
171
+ try {
172
+ assert.equal(detectPackageManager(dir), 'npm');
173
+ } finally {
174
+ cleanup();
175
+ }
176
+ });
177
+
178
+ test('detectPackageManager returns yarn when yarn.lock exists', () => {
179
+ const { dir, cleanup } = makeTmpDir();
180
+ try {
181
+ fs.writeFileSync(path.join(dir, 'yarn.lock'), '');
182
+ assert.equal(detectPackageManager(dir), 'yarn');
183
+ } finally {
184
+ cleanup();
185
+ }
186
+ });
187
+
188
+ test('detectPackageManager returns pnpm when pnpm-lock.yaml exists', () => {
189
+ const { dir, cleanup } = makeTmpDir();
190
+ try {
191
+ fs.writeFileSync(path.join(dir, 'pnpm-lock.yaml'), '');
192
+ assert.equal(detectPackageManager(dir), 'pnpm');
193
+ } finally {
194
+ cleanup();
195
+ }
196
+ });
197
+
198
+ test('detectPackageManager returns bun when bun.lockb exists', () => {
199
+ const { dir, cleanup } = makeTmpDir();
200
+ try {
201
+ fs.writeFileSync(path.join(dir, 'bun.lockb'), '');
202
+ assert.equal(detectPackageManager(dir), 'bun');
203
+ } finally {
204
+ cleanup();
205
+ }
206
+ });
207
+
208
+ test('installSelfAsDevDep returns skipped-no-package-json when no package.json', () => {
209
+ const { dir, cleanup } = makeTmpDir();
210
+ try {
211
+ const result = installSelfAsDevDep(dir, '0.8.0');
212
+ assert.equal(result, 'skipped-no-package-json');
213
+ } finally {
214
+ cleanup();
215
+ }
216
+ });
217
+
218
+ test('installSelfAsDevDep returns skipped-already-present when create-quiver in devDeps', () => {
219
+ const { dir, cleanup } = makeTmpDir();
220
+ try {
221
+ fs.writeFileSync(path.join(dir, 'package.json'), JSON.stringify({
222
+ name: 'test',
223
+ devDependencies: { 'create-quiver': '^0.7.0' },
224
+ }));
225
+ const result = installSelfAsDevDep(dir, '0.8.0');
226
+ assert.equal(result, 'skipped-already-present');
227
+ } finally {
228
+ cleanup();
229
+ }
230
+ });
231
+
232
+ test('installSelfAsDevDep returns failed when install command fails', () => {
233
+ const { dir, cleanup } = makeTmpDir();
234
+ try {
235
+ fs.writeFileSync(path.join(dir, 'package.json'), JSON.stringify({ name: 'test' }));
236
+ // Force failure: set PATH to empty so no package manager can be found
237
+ const original = process.env.PATH;
238
+ process.env.PATH = '';
239
+ const result = installSelfAsDevDep(dir, '0.8.0');
240
+ process.env.PATH = original;
241
+ assert.equal(result, 'failed');
242
+ } finally {
243
+ cleanup();
244
+ }
245
+ });
246
+ ```
247
+
248
+ ---
249
+
250
+ ## Verificaciones
251
+
252
+ ```bash
253
+ # Tests
254
+ node --test tests/**/*.test.js
255
+
256
+ # Smoke: --skip-install no instala
257
+ mkdir -p /tmp/quiver-skip-test && echo '{"name":"test","scripts":{}}' > /tmp/quiver-skip-test/package.json
258
+ node bin/create-quiver.js --skip-install --name test --dir /tmp/quiver-skip-test
259
+ ls /tmp/quiver-skip-test/node_modules/create-quiver 2>/dev/null && echo "FAIL: se instaló igual" || echo "OK: no instaló"
260
+
261
+ # Smoke: sin --skip-install sí instala (requiere red)
262
+ mkdir -p /tmp/quiver-install-test && echo '{"name":"test","scripts":{}}' > /tmp/quiver-install-test/package.json
263
+ node bin/create-quiver.js --name test --dir /tmp/quiver-install-test
264
+ ls /tmp/quiver-install-test/node_modules/create-quiver && echo "OK: instalado" || echo "FAIL"
265
+ ```
266
+
267
+ ---
268
+
269
+ ## Restricciones
270
+
271
+ - No toques `mergePackageJson` — la lógica de install va en `installSelfAsDevDep`, no en el merge de package.json
272
+ - No hagas `npm install` general — solo `npm install -D create-quiver@VERSION`
273
+ - No elimines ni renombres ningún export existente de `init-docs.js`
274
+ - No agregues dependencias externas — solo `child_process` (built-in de Node)
275
+ - Un solo commit con los tres archivos
276
+
277
+ ## Mensaje de commit sugerido
278
+
279
+ ```
280
+ feat(QUIVER-01): auto-install create-quiver as dev dependency after init
281
+
282
+ After init or migrate, detect the target project's package manager
283
+ (yarn/pnpm/bun/npm) and install create-quiver as a dev dependency.
284
+ Skippable with --skip-install for CI environments.
285
+ Resolves the npx cache issue: subsequent quiver commands in the project
286
+ resolve to the local version without requiring @version suffix.
287
+ ```
@@ -0,0 +1,56 @@
1
+ {
2
+ "slice_id": "slice-01-auto-install-dev-dep",
3
+ "ticket": "QUIVER-01",
4
+ "type": "feature",
5
+ "title": "Auto-install create-quiver as dev dependency after init/migrate",
6
+ "objective": "After `npx create-quiver` init or migrate, the target project has create-quiver in devDependencies and installed in node_modules. Uses the correct package manager. Skippable via --skip-install.",
7
+ "description": "Add two functions to init-docs.js: detectPackageManager (checks lockfiles) and installSelfAsDevDep (runs the appropriate install command). Call installSelfAsDevDep from the init and migrate flows in index.js after runInitDocs. Add --skip-install flag to the CLI arg parser.",
8
+ "git": {
9
+ "branch_type": "feature",
10
+ "base_branch": "main",
11
+ "branch_slug": "auto-install-dev-dep",
12
+ "branch_name": "feature/QUIVER-01-auto-install-dev-dep"
13
+ },
14
+ "files": [
15
+ "src/create-quiver/lib/init-docs.js",
16
+ "src/create-quiver/index.js",
17
+ "tests/lib/init-docs.test.js"
18
+ ],
19
+ "depends_on": [],
20
+ "must": [
21
+ "detectPackageManager(projectRoot) returns 'bun'|'pnpm'|'yarn'|'npm' based on lockfile presence",
22
+ "installSelfAsDevDep(projectRoot, version) runs the correct install command for the detected pm",
23
+ "installSelfAsDevDep skips if no package.json exists (returns 'skipped-no-package-json')",
24
+ "installSelfAsDevDep skips if create-quiver already in devDependencies (returns 'skipped-already-present')",
25
+ "installSelfAsDevDep catches install errors and returns 'failed' without throwing",
26
+ "--skip-install flag parsed in index.js and passed through to suppress the install step",
27
+ "Both init and migrate flows call installSelfAsDevDep unless --skip-install is set",
28
+ "Init output prints 'Added create-quiver@X.Y.Z as dev dependency' on success or a warning on skip/fail",
29
+ "node --test tests/**/*.test.js passes"
30
+ ],
31
+ "not_included": [
32
+ "Auto-updating an existing create-quiver version in devDependencies",
33
+ "Supporting private registries or custom npm configs",
34
+ "Changing the scaffold output beyond the install step message"
35
+ ],
36
+ "acceptance": [
37
+ "After init: package.json has create-quiver in devDependencies",
38
+ "After init: node_modules/create-quiver exists",
39
+ "npx create-quiver plan works without @version in a freshly initialized project",
40
+ "--skip-install suppresses the install in both init and migrate",
41
+ "yarn/pnpm/bun projects use the right install command",
42
+ "Install failure prints a warning but does not crash the init",
43
+ "node --test tests/**/*.test.js exits 0"
44
+ ],
45
+ "tests": [
46
+ "node --test tests/**/*.test.js",
47
+ "npx create-quiver --skip-install --name test --dir /tmp/quiver-test-skip && ls /tmp/quiver-test-skip/node_modules/create-quiver 2>/dev/null && echo FAIL || echo OK"
48
+ ],
49
+ "estimated_hours": 1.5,
50
+ "actual_hours": null,
51
+ "status": "ready",
52
+ "blocked_reason": null,
53
+ "ready_at": "2026-05-14T00:00:00Z",
54
+ "started_at": null,
55
+ "completed_at": null
56
+ }