@abarcenas/ai-workflow-template 1.29.0 → 1.33.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.
@@ -20,3 +20,49 @@
20
20
  - unit-tester: Must be told to look in `scripts/` for source and test files, not `src/`
21
21
  - coder: Must be told the project uses ES module syntax (import/export, not require/module.exports)
22
22
  - implementer: Plans should target `scripts/` for production code and tests
23
+
24
+ ## Session: 2026-07-24
25
+
26
+ **Pipeline:** researcher → architect → implementer → coder (6 parallel batches) → unit-tester → tracker
27
+ **Coverage:** 88/88 tests passing across 4 test files (discover 21, hooks 16, prepare 27, index 24)
28
+ **TDD Iterations:** 0 (feature pipeline, not TDD)
29
+
30
+ **New knowledge:**
31
+ - **npm v12 blocks postinstall scripts from dependencies** — this is a critical ecosystem shift that affects ALL npm library distribution. Postinstall auto-sync is no longer viable; explicit setup commands are required
32
+ - **npx-based setup command pattern** (following Playwright, Prisma, Cypress convention) is the future-proof distribution mechanism for CLI tools that need to configure consumer projects
33
+ - **Husky v9 programmatic API** is dead simple: `import husky from 'husky'; husky(consumerRoot)` — no need to shell out or manually manage shim files
34
+ - **`child_process.spawn` for scripts with `process.exit()`** — importing sync.js (which calls `process.exit()`) directly into the setup process would kill the parent. Spawn as a child process to isolate exit behavior
35
+ - **Marker comment idempotency** — a first-line comment (`# Managed by @abarcenas/ai-workflow-template setup`) on hook files enables content-based detection for safe re-runs. This pattern should be used for any managed file that needs idempotent installation
36
+ - **6-batch parallel execution worked well**: Batch A (3 foundation: constants, utils, ui) → Batch B (5 core: discover, hooks, prepare, husky-init, sync-phase) → Batch C (2 orchestrator: index.js, bin/setup.js) → Batches D+E (3 config: pre-commit marker, post-merge marker, package.json) → Batch F (4 tests). Clear interface definitions were essential for parallelism
37
+ - **Duplicate-marker trap** — constants.js `TEMPLATE_HOOKS.content` must stay in sync with actual `.husky/` hook files. During T12 (post-merge marker), a mismatch was discovered between the template content in constants.js (which already had the marker via `buildHookContent()`) and the actual disk file. Solution: update constants.js template content whenever hook files are modified
38
+
39
+ **Agent tuning notes:**
40
+ - **researcher**: Should explicitly investigate npm ecosystem changes (version-specific behavior, deprecations) — the npm v12 postinstall discovery was the single most important finding that drove the architecture
41
+ - **architect**: Modular design with clear interface contracts (Context object shape, return types) paid off — all 5 Batch B modules could be implemented in parallel without coordination issues
42
+ - **implementer**: The parallel batch plan with explicit dependency edges (Batch A → B → C, D+E → F) was critical for the 6 sub-agent coder execution. Without this structure, 6 concurrent coders would have had race conditions on shared files
43
+ - **coder (parallel batches)**: Batch ordering discipline worked — foundation first, then core, then orchestrator. The truly independent batches (D: markers, F: tests) could run alongside later batches. Key lesson: define interfaces (Context shape, return types) before splitting work across parallel coders
44
+ - **unit-tester**: Using real temp directories (`mkdtempSync`) over mocking filesystem operations catches path resolution and permission issues that mocks would miss. Mock only environment-dependent utilities (CI detection, Node version), not filesystem
45
+ - **tracker**: Should capture ecosystem discoveries alongside implementation details — the npm v12 finding and marker idempotency pattern are valuable knowledge for future pipeline sessions
46
+
47
+ ## Session: 2026-07-24 — Verbose Logging for ai-workflow-setup
48
+
49
+ **Pipeline:** implementer (bootstrap) → researcher → implementer (planning) → coder (4 parallel batches) → tracker
50
+ **Coverage:** 96/96 tests passing across 5 test files (discover 23, hooks 16, prepare 27, index 25, sync-phase 5)
51
+ **TDD Iterations:** 0 (feature pipeline, not TDD)
52
+
53
+ **New knowledge:**
54
+ - **Dead code infrastructure is a valuable find** — the `--verbose` flag already existed in `constants.js` and was correctly parsed by `parseCliArgs()`, but was never checked anywhere. Always check for existing-but-unused infrastructure before building new mechanisms
55
+ - **`spawnScript()` in `sync-phase.js` was the root cause of silent hangs** — child process stdout/stderr was captured into a string but that string was never displayed or logged. The fix: use `stdio: 'inherit'` when verbose, `'pipe'` for normal mode
56
+ - **Child process communication requires env vars** — parent and child processes share no context object. `sync.js` reads `AI_WORKFLOW_VERBOSE` from `process.env` set by `sync-phase.js` before spawning
57
+ - **`console.error` (stderr) is correct for verbose output in child processes** — stdout is captured by the parent for result parsing, but stderr streams to terminal in `stdio: 'inherit'` mode. Diagnostic messages go to stderr
58
+ - **`index.js` needed ZERO changes** — the Context `verbose` field flows from `discover(flags)` through all phase modules automatically via the existing orchestration pattern. This validates the Context enrichment architecture
59
+ - **Parallel batching with 4 batches and 10 tasks worked cleanly**: Batch A (T1–T2 foundation) → Batch B (T3–T6 core fixes) → Batch C (T7 single) → Batch D (T8–T10 tests). 0 collisions, clean interface boundaries. The explicit dependency graph (Batch A → B → C, B → D) prevented race conditions
60
+ - **`normalize-memory.js` already has good internal logging** — when verbose mode streams child stdout in real-time, this existing logging becomes visible to the user for free, with no code changes needed
61
+ - **Dim ANSI style (` … prefix`) for verbose output** — visually distinguishes verbose progress from normal output. Uses existing color infrastructure with TTY guard
62
+
63
+ **Agent tuning notes:**
64
+ - **researcher**: Should examine existing flag/configuration infrastructure for dead code — the `--verbose` flag was fully defined and parsed but never checked. This was the single most impactful finding because it revealed both the root cause (spawnScript capture) and the solution path (activate existing flag)
65
+ - **implementer (planning)**: The "index.js needs zero changes" insight should be explicitly validated before including in plans — it's easy to miss that context flows automatically. Read the orchestrator code to verify before committing to "no changes" claims
66
+ - **coder**: When fixing child process output capture, consider both stdout and stderr channels independently — they serve different purposes (results vs diagnostics). `stdio: 'inherit'` is clean for real-time streaming but means stdout is no longer capturable programmatically
67
+ - **unit-tester**: When testing child process spawn behavior, mock `child_process` spawn module rather than using real subprocesses — this avoids side effects and keeps tests fast. Use `vi.mock` with factory functions to control `stdio` arg and `env` values
68
+ - **tracker**: Record dead-code discoveries alongside implementation details — the "existing but unused infrastructure" finding is a recurring pattern worth tracking across sessions
@@ -19,6 +19,9 @@ jobs:
19
19
  - name: Install dependencies
20
20
  run: npm ci
21
21
 
22
+ - name: Run unit tests
23
+ run: npm run test:unit
24
+
22
25
  - name: Publish to npm
23
26
  run: npm publish --access public
24
27
  env:
@@ -0,0 +1,23 @@
1
+ name: PR Unit Tests
2
+
3
+ on:
4
+ pull_request:
5
+ branches:
6
+ - main
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+
14
+ - uses: actions/setup-node@v4
15
+ with:
16
+ node-version: '22'
17
+ cache: 'npm'
18
+
19
+ - name: Install dependencies
20
+ run: npm ci
21
+
22
+ - name: Run unit tests
23
+ run: npm run test:unit
package/.husky/post-merge CHANGED
@@ -1,3 +1,4 @@
1
+ # Managed by @abarcenas/ai-workflow-template setup
1
2
  #!/bin/sh
2
3
  . "$(dirname "$0")/_/husky.sh"
3
4
 
package/.husky/pre-commit CHANGED
@@ -1,2 +1,4 @@
1
+ # Managed by @abarcenas/ai-workflow-template setup
2
+
1
3
  node scripts/bump-version.js
2
4
  node scripts/validate-memory-schema.js
package/README.md CHANGED
@@ -35,7 +35,53 @@ Install directly into the project that needs AI workflow configuration:
35
35
  npm install @abarcenas/ai-workflow-template
36
36
  ```
37
37
 
38
- The package runs `postinstall` automatically to sync configurations.
38
+ The package runs `postinstall` automatically to sync files. For full setup including git hooks, run the one-step setup command below.
39
+
40
+ ---
41
+
42
+ ## 🪝 Git Hook Setup
43
+
44
+ After installing the package, configure husky git hooks with one command:
45
+
46
+ ```bash
47
+ # One-step setup (fetches from npm registry automatically):
48
+ npx @abarcenas/ai-workflow-template
49
+
50
+ # Or if the package is already installed:
51
+ npx ai-workflow-setup
52
+ ```
53
+
54
+ ### What It Does
55
+
56
+ The setup command automatically:
57
+
58
+ | Phase | Action |
59
+ |-------|--------|
60
+ | 🔍 **Discover** | Detects git repo, existing hooks, CI mode |
61
+ | 🪝 **Hooks** | Installs `pre-commit` (version bump + validation) and `post-merge` (memory index update) |
62
+ | 📦 **Prepare** | Merges `"husky"` into your `package.json` prepare script |
63
+ | ⚙️ **Husky Init** | Initializes husky and sets `core.hooksPath` |
64
+ | 🔄 **Sync** | Copies agent configurations, skills, and memory bank scaffolding |
65
+
66
+ ### Options
67
+
68
+ ```bash
69
+ npx ai-workflow-setup --dry-run # Preview without changes
70
+ npx ai-workflow-setup --force # Overwrite existing hooks
71
+ npx ai-workflow-setup --skip-hooks # Skip hook installation
72
+ npx ai-workflow-setup --skip-sync # Skip file sync
73
+ npx ai-workflow-setup --help # Show all options
74
+ ```
75
+
76
+ ### Hook Merging
77
+
78
+ If you already have existing husky hooks, the setup command intelligently merges:
79
+ - **Your hooks are never overwritten** — new content is appended after a separator
80
+ - **Managed hooks are detected** via marker comments and updated idempotently
81
+ - **Complex hooks** trigger a warning with manual merge instructions
82
+ - **CI environments** auto-skip hook configuration
83
+
84
+ > **ℹ️ npm v12 note:** Future npm versions block automatic `postinstall` scripts. The explicit `npx setup` command is the recommended, future-proof approach.
39
85
 
40
86
  ---
41
87
 
@@ -416,6 +462,7 @@ npm run memory:normalize
416
462
  - 📖 `AGENTS.md` is the main instruction file agents should read
417
463
  - 🎯 Package assumes public npm registry
418
464
  - 🎭 Playwright MCP integration documented in `docs/` folder
465
+ - 🪝 Run `npx ai-workflow-setup` after install to configure git hooks (npm v12+ compatible)
419
466
 
420
467
  ---
421
468
 
package/bin/setup.js ADDED
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+
3
+ // ═════════════════════════════════════════════════════════════════════════════
4
+ // bin/setup.js — CLI entry point for `npx ai-workflow-setup`
5
+ // ═════════════════════════════════════════════════════════════════════════════
6
+ //
7
+ // Minimal shim that delegates to the orchestrator (scripts/setup/index.js).
8
+ // Uses top-level await via ESM (requires "type": "module" in package.json).
9
+ //
10
+ // Exit codes:
11
+ // 0 — All phases completed successfully
12
+ // 1 — One or more phases had warnings / were skipped
13
+ // 2 — Fatal error (discovery failure or unexpected exception)
14
+ // ═════════════════════════════════════════════════════════════════════════════
15
+
16
+ try {
17
+ const { main } = await import('../scripts/setup/index.js')
18
+ const exitCode = await main(process.argv.slice(2))
19
+ process.exit(exitCode)
20
+ } catch (err) {
21
+ console.error('Fatal error:', err.message)
22
+ process.exit(2)
23
+ }
package/package.json CHANGED
@@ -1,8 +1,11 @@
1
1
  {
2
2
  "name": "@abarcenas/ai-workflow-template",
3
- "version": "1.29.0",
3
+ "version": "1.33.0",
4
4
  "description": "A comprehensive template repository for AI-assisted development workflows using GitHub Copilot. This template provides a structured approach to leveraging AI assistance through pre-configured skills, prompts, agents, and coding standards.",
5
5
  "main": "index.js",
6
+ "bin": {
7
+ "ai-workflow-setup": "./bin/setup.js"
8
+ },
6
9
  "scripts": {
7
10
  "test": "playwright test",
8
11
  "test:headed": "playwright test --headed",
@@ -14,7 +17,7 @@
14
17
  "test:unit:watch": "vitest",
15
18
  "prepare": "husky",
16
19
  "sync": "node ./scripts/sync.js",
17
- "postinstall": "node ./scripts/sync.js && node ./scripts/normalize-memory.js",
20
+ "postinstall": "node ./scripts/sync.js && node ./scripts/normalize-memory.js && echo '' && echo '⚠️ IMPORTANT: Run npx ai-workflow-setup to configure git hooks' && echo ' (npm postinstall scripts will be blocked by npm v12+)'",
18
21
  "memory:search": "node ./scripts/memory-cli.js search",
19
22
  "memory:rebuild": "node ./scripts/memory-cli.js rebuild",
20
23
  "memory:update": "node ./scripts/memory-cli.js update",
@@ -33,9 +36,11 @@
33
36
  },
34
37
  "homepage": "https://github.com/abarcenas29/ai-workflow-template#readme",
35
38
  "files": [
39
+ "bin/",
36
40
  ".agents/",
37
41
  ".github/workflows/",
38
42
  "scripts/",
43
+ "scripts/setup/",
39
44
  ".opencode/agents/",
40
45
  ".opencode/commands/",
41
46
  ".husky/",
@@ -0,0 +1,226 @@
1
+ // ═════════════════════════════════════════════════════════════════════════════
2
+ // constants.js — Shared constants for the setup command pipeline
3
+ // ═════════════════════════════════════════════════════════════════════════════
4
+
5
+ // ── Package identity ──────────────────────────────────────────────────────────
6
+
7
+ /** npm package name */
8
+ export const PACKAGE_NAME = '@abarcenas/ai-workflow-template'
9
+
10
+ /** CLI binary name (npm "bin" entry) */
11
+ export const BIN_NAME = 'ai-workflow-setup'
12
+
13
+ // ── Idempotency markers ───────────────────────────────────────────────────────
14
+
15
+ /**
16
+ * First-line comment injected into every template hook file.
17
+ * Used to detect whether an existing consumer hook was installed by us
18
+ * (idempotency check in hooks.js, CASE C). Must be the first line of
19
+ * each template hook file.
20
+ */
21
+ export const HOOK_MARKER = '# Managed by @abarcenas/ai-workflow-template setup'
22
+
23
+ /**
24
+ * Separator inserted between a consumer's existing hook content and our
25
+ * appended content during hook merging (hooks.js, CASE D).
26
+ */
27
+ export const HOOK_MERGE_SEPARATOR = '# --- @abarcenas/ai-workflow-template ---'
28
+
29
+ // ── Template hook definitions ─────────────────────────────────────────────────
30
+
31
+ /**
32
+ * Map of hook names → metadata for every git hook the setup command manages.
33
+ *
34
+ * Each entry carries:
35
+ * `source` — Relative path from the package root to the template file.
36
+ * Resolved at runtime by hooks.js.
37
+ * `content` — Exact content that will be written (or appended) to the
38
+ * consumer's hook file. This mirrors the actual file on disk.
39
+ * `description` — Human-readable purpose, shown in output messages.
40
+ */
41
+ export const TEMPLATE_HOOKS = {
42
+ 'pre-commit': {
43
+ source: '.husky/pre-commit',
44
+ content:
45
+ '# Managed by @abarcenas/ai-workflow-template setup\n\nnode scripts/bump-version.js\nnode scripts/validate-memory-schema.js\n',
46
+ description:
47
+ 'Auto-bump version + validate memory-bank schema before commits',
48
+ },
49
+ 'post-merge': {
50
+ source: '.husky/post-merge',
51
+ content: [
52
+ '# Managed by @abarcenas/ai-workflow-template setup',
53
+ '#!/bin/sh',
54
+ '. "$(dirname "$0")/_/husky.sh"',
55
+ '',
56
+ '# After git pull/merge, check if memory-bank files changed',
57
+ '# and update the vector index incrementally',
58
+ '',
59
+ 'if git diff HEAD@{1} --name-only 2>/dev/null | grep -q "^memory-bank\\|^docs/"; then',
60
+ ' echo "[memory-bank] Memory bank files changed. Updating vector index..."',
61
+ ' node scripts/memory-cli.js update 2>/dev/null || echo "[memory-bank] Index update skipped (service not installed)"',
62
+ 'fi',
63
+ '',
64
+ ].join('\n'),
65
+ description:
66
+ 'Auto-update memory bank vector index after pull/merge',
67
+ },
68
+ }
69
+
70
+ // ── CI/CD environment detection ───────────────────────────────────────────────
71
+
72
+ /**
73
+ * Environment variable names checked to determine if the command is running
74
+ * inside a CI/CD pipeline.
75
+ *
76
+ * When `isCI()` from utils.js returns true, the setup command skips git hook
77
+ * installation entirely (REQ-07) and only performs file sync + memory-bank
78
+ * scaffolding.
79
+ *
80
+ * @note `NODE_ENV` is included here but is evaluated as
81
+ * `process.env.NODE_ENV === 'production'` (equality check), whereas
82
+ * all other entries are evaluated as simple truthiness checks.
83
+ */
84
+ export const CI_ENV_VARS = [
85
+ 'CI',
86
+ 'GITHUB_ACTIONS',
87
+ 'GITLAB_CI',
88
+ 'CIRCLECI',
89
+ 'TRAVIS',
90
+ 'JENKINS_URL',
91
+ 'BITBUCKET_BUILD_NUMBER',
92
+ 'APPVEYOR',
93
+ 'CODEBUILD_BUILD_ID',
94
+ 'AZURE_HTTP_USER_AGENT',
95
+ 'NODE_ENV',
96
+ ]
97
+
98
+ // ── CLI flags ─────────────────────────────────────────────────────────────────
99
+
100
+ /**
101
+ * Map of CLI argument strings (long and short forms) to their canonical
102
+ * camelCase property names on the flags object.
103
+ *
104
+ * Usage: `parseCliArgs()` in utils.js iterates over argv, looks up each
105
+ * element in this map, and sets the corresponding property to `true` on
106
+ * the returned flags object.
107
+ */
108
+ export const SUPPORTED_FLAGS = {
109
+ '--force': 'force',
110
+ '--dry-run': 'dryRun',
111
+ '--yes': 'yes',
112
+ '-y': 'yes',
113
+ '--skip-hooks': 'skipHooks',
114
+ '--skip-prepare': 'skipPrepare',
115
+ '--skip-sync': 'skipSync',
116
+ '--help': 'help',
117
+ '-h': 'help',
118
+ '--version': 'version',
119
+ '-v': 'version',
120
+ '--quiet': 'quiet',
121
+ '-q': 'quiet',
122
+ '--verbose': 'verbose',
123
+ '-V': 'verbose',
124
+ }
125
+
126
+ // ── Exit codes ────────────────────────────────────────────────────────────────
127
+
128
+ /**
129
+ * Numeric exit codes returned by the setup command.
130
+ *
131
+ * SUCCESS → All phases completed without errors or warnings
132
+ * WARNINGS → One or more phases had non-fatal warnings (exit code 1)
133
+ * FATAL → A required phase encountered an unrecoverable error (exit code 2)
134
+ */
135
+ export const EXIT_CODES = {
136
+ SUCCESS: 0,
137
+ WARNINGS: 1,
138
+ FATAL: 2,
139
+ }
140
+
141
+ // ── Required directories ──────────────────────────────────────────────────────
142
+
143
+ /**
144
+ * Relative paths (from the consumer project root) of directories that the
145
+ * setup command must ensure exist before running its pipeline.
146
+ */
147
+ export const REQUIRED_DIRS = [
148
+ '.husky',
149
+ 'memory-bank',
150
+ ]
151
+
152
+ // ── Output symbols ────────────────────────────────────────────────────────────
153
+
154
+ /**
155
+ * Unicode characters used as status indicators in the CLI output.
156
+ * Referenced by the ui.js module.
157
+ */
158
+ export const UNICODE_CHARS = {
159
+ CHECK: '\u2713', // ✓
160
+ WARN: '\u26A0', // ⚠
161
+ CROSS: '\u2717', // ✗
162
+ BULLET: '\u2022', // •
163
+ ARROW: '\u2192', // →
164
+ }
165
+
166
+ // ── Memory bank stubs ─────────────────────────────────────────────────────────
167
+
168
+ /**
169
+ * Template content for scaffolding a fresh memory-bank/ directory.
170
+ * Exact mirror of the `memoryBankStubs` object in `scripts/sync.js`
171
+ * (lines 204–254). Each key is a filename; each value is the file content.
172
+ *
173
+ * Used by the setup command's sync-phase when the consumer project lacks
174
+ * a memory-bank/ directory.
175
+ */
176
+ export const MEMORY_BANK_STUBS = {
177
+ 'projectbrief.md': `# projectbrief
178
+
179
+ > Foundation document — defines core requirements and goals.
180
+
181
+ - **Purpose**: {{describe project purpose}}
182
+ - **Goals**: {{list project goals}}
183
+ - **Scope**: {{define scope}}
184
+ `,
185
+ 'productContext.md': `# productContext
186
+
187
+ > Why this project exists and what problems it solves.
188
+
189
+ - **Problem**: {{describe the problem}}
190
+ - **Solution**: {{describe the solution}}
191
+ - **User Experience**: {{describe UX goals}}
192
+ `,
193
+ 'activeContext.md': `# activeContext
194
+
195
+ > Current work focus, recent changes, next steps.
196
+
197
+ - **Current Focus**: {{current task or goal}}
198
+ - **Recent Changes**: {{list of recent changes}}
199
+ - **Next Steps**: {{next actions}}
200
+ `,
201
+ 'systemPatterns.md': `# systemPatterns
202
+
203
+ > Architecture, key decisions, design patterns.
204
+
205
+ - **Architecture**: {{describe architecture}}
206
+ - **Key Decisions**: {{list key technical decisions}}
207
+ - **Patterns**: {{list design patterns in use}}
208
+ `,
209
+ 'techContext.md': `# techContext
210
+
211
+ > Technologies, setup, constraints, dependencies.
212
+
213
+ - **Stack**: {{list technologies}}
214
+ - **Setup**: {{describe dev setup}}
215
+ - **Constraints**: {{list technical constraints}}
216
+ `,
217
+ 'progress.md': `# progress
218
+
219
+ > What works, what's left, current status.
220
+
221
+ - **Working**: {{what's implemented and working}}
222
+ - **To Build**: {{what remains}}
223
+ - **Status**: {{overall project status}}
224
+ - **Known Issues**: {{list known issues}}
225
+ `,
226
+ }