@abarcenas/ai-workflow-template 1.48.0 → 2.0.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 (37) hide show
  1. package/.agents/instructions/knowledgebase.instructions.md +2 -2
  2. package/.agents/instructions/learned-knowledge.instructions.md +47 -2
  3. package/.agents/instructions/memory-schema.instructions.md +1 -1
  4. package/.github/workflows/npm-publish.yml +69 -1
  5. package/.opencode/agents/implementer.md +3 -1
  6. package/.opencode/agents/unit-tester.md +21 -2
  7. package/.opencode/plugins/graphify.js +22 -0
  8. package/LICENSE +15 -0
  9. package/README.md +56 -22
  10. package/memory-bank/.vocabulary.json +3 -0
  11. package/opencode.mcp.example.json +13 -0
  12. package/package.json +20 -10
  13. package/scripts/bump-version.js +18 -2
  14. package/scripts/mcp/playwright-mcp-launcher.js +45 -2
  15. package/scripts/bump-version.test.js +0 -238
  16. package/scripts/knowledgebase-cli.test.js +0 -576
  17. package/scripts/knowledgebase-index.test.js +0 -759
  18. package/scripts/mcp/playwright-mcp-launcher.test.js +0 -217
  19. package/scripts/mcp-knowledgebase-server.test.js +0 -745
  20. package/scripts/mcp-memory-server.test.js +0 -398
  21. package/scripts/memory-cli.test.js +0 -297
  22. package/scripts/memory-index.test.js +0 -1173
  23. package/scripts/normalize-memory.test.js +0 -753
  24. package/scripts/setup/discover.test.js +0 -530
  25. package/scripts/setup/hooks.test.js +0 -722
  26. package/scripts/setup/husky-init.test.js +0 -311
  27. package/scripts/setup/index.test.js +0 -1021
  28. package/scripts/setup/knowledgebase.test.js +0 -352
  29. package/scripts/setup/prepare.test.js +0 -718
  30. package/scripts/setup/skills-phase.test.js +0 -1274
  31. package/scripts/setup/sync-phase.test.js +0 -373
  32. package/scripts/setup/ui.test.js +0 -579
  33. package/scripts/setup/utils.test.js +0 -586
  34. package/scripts/sync-unit.test.js +0 -1881
  35. package/scripts/sync.test.js +0 -472
  36. package/scripts/validate-memory-schema.test.js +0 -328
  37. package/scripts/vocab-sync.test.js +0 -902
@@ -1,217 +0,0 @@
1
- // ═════════════════════════════════════════════════════════════════════════════
2
- // playwright-mcp-launcher.test.js — Unit tests for the MCP launcher
3
- // ═════════════════════════════════════════════════════════════════════════════
4
- //
5
- // `spawn` is mocked so no MCP server is ever launched. Signal handling and
6
- // exit-code propagation are exercised through injected fakes (an EventEmitter
7
- // double for the process and a fake child), plus a direct-run import that
8
- // verifies the CLI bootstrap branch.
9
- //
10
- // Covered scenarios:
11
- // 1. default args (no env flags)
12
- // 2. HEADLESS=true adds --headless
13
- // 3. HEADLESS=false does not
14
- // 4. VIEWPORT adds --viewport <size>
15
- // 5. HEADLESS + VIEWPORT together
16
- // 6. spawn is called as `npx <args>` with inherited stdio + shell
17
- // 7. exit code 0 is forwarded
18
- // 8. non-zero exit code is forwarded
19
- // 9. missing exit code falls back to 0
20
- // 10. SIGINT / SIGTERM are forwarded to the child
21
- // 11. launch returns the child
22
- // 12. direct run auto-launches; imported elsewhere it does not
23
- // ═════════════════════════════════════════════════════════════════════════════
24
-
25
- import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest'
26
- import { EventEmitter } from 'node:events'
27
- import { fileURLToPath } from 'node:url'
28
-
29
- const cp = vi.hoisted(() => ({ spawn: vi.fn() }))
30
-
31
- vi.mock('node:child_process', () => ({
32
- spawn: cp.spawn,
33
- }))
34
-
35
- import { spawn } from 'node:child_process'
36
- import { buildArgs, launch } from './playwright-mcp-launcher.js'
37
-
38
- /**
39
- * Creates a fake ChildProcess.
40
- *
41
- * @returns {object} Fake child with kill/on and a helper to emit 'exit'.
42
- */
43
- function makeChild() {
44
- const handlers = {}
45
- return {
46
- kill: vi.fn(),
47
- on: vi.fn((event, handler) => {
48
- handlers[event] = handler
49
- }),
50
- emitExit(code) {
51
- handlers.exit?.(code)
52
- },
53
- }
54
- }
55
-
56
- describe('playwright-mcp-launcher', () => {
57
- let child
58
-
59
- beforeEach(() => {
60
- vi.clearAllMocks()
61
- child = makeChild()
62
- spawn.mockReturnValue(child)
63
- })
64
-
65
- afterEach(() => {
66
- vi.restoreAllMocks()
67
- })
68
-
69
- // ── buildArgs ────────────────────────────────────────────────────────────
70
-
71
- it('buildArgs: returns only the package when no env flags are set', () => {
72
- expect(buildArgs({})).toEqual(['@playwright/mcp@latest'])
73
- })
74
-
75
- it('buildArgs: HEADLESS=true adds --headless', () => {
76
- expect(buildArgs({ HEADLESS: 'true' })).toEqual([
77
- '@playwright/mcp@latest',
78
- '--headless',
79
- ])
80
- })
81
-
82
- it('buildArgs: HEADLESS=false does not add --headless', () => {
83
- expect(buildArgs({ HEADLESS: 'false' })).toEqual(['@playwright/mcp@latest'])
84
- })
85
-
86
- it('buildArgs: VIEWPORT adds a two-token viewport flag', () => {
87
- expect(buildArgs({ VIEWPORT: '1280x720' })).toEqual([
88
- '@playwright/mcp@latest',
89
- '--viewport',
90
- '1280x720',
91
- ])
92
- })
93
-
94
- it('buildArgs: combines headless and viewport flags', () => {
95
- expect(buildArgs({ HEADLESS: 'true', VIEWPORT: '800x600' })).toEqual([
96
- '@playwright/mcp@latest',
97
- '--headless',
98
- '--viewport',
99
- '800x600',
100
- ])
101
- })
102
-
103
- // ── launch ───────────────────────────────────────────────────────────────
104
-
105
- it('launch: spawns npx with inherited stdio and shell', () => {
106
- launch({ env: {}, proc: new EventEmitter(), exit: vi.fn() })
107
-
108
- expect(spawn).toHaveBeenCalledWith('npx', ['@playwright/mcp@latest'], {
109
- stdio: 'inherit',
110
- shell: true,
111
- })
112
- })
113
-
114
- it('launch: returns the spawned child', () => {
115
- const returned = launch({
116
- env: {},
117
- proc: new EventEmitter(),
118
- exit: vi.fn(),
119
- })
120
-
121
- expect(returned).toBe(child)
122
- })
123
-
124
- it('launch: forwards exit code 0', () => {
125
- const exit = vi.fn()
126
- launch({ env: {}, proc: new EventEmitter(), exit })
127
-
128
- child.emitExit(0)
129
-
130
- expect(exit).toHaveBeenCalledWith(0)
131
- })
132
-
133
- it('launch: forwards a non-zero exit code', () => {
134
- const exit = vi.fn()
135
- launch({ env: {}, proc: new EventEmitter(), exit })
136
-
137
- child.emitExit(5)
138
-
139
- expect(exit).toHaveBeenCalledWith(5)
140
- })
141
-
142
- it('launch: falls back to 0 when no exit code is provided', () => {
143
- const exit = vi.fn()
144
- launch({ env: {}, proc: new EventEmitter(), exit })
145
-
146
- child.emitExit(undefined)
147
-
148
- expect(exit).toHaveBeenCalledWith(0)
149
- })
150
-
151
- it('launch: forwards SIGINT to the child', () => {
152
- const proc = new EventEmitter()
153
- launch({ env: {}, proc, exit: vi.fn() })
154
-
155
- proc.emit('SIGINT')
156
-
157
- expect(child.kill).toHaveBeenCalledWith('SIGINT')
158
- })
159
-
160
- it('launch: forwards SIGTERM to the child', () => {
161
- const proc = new EventEmitter()
162
- launch({ env: {}, proc, exit: vi.fn() })
163
-
164
- proc.emit('SIGTERM')
165
-
166
- expect(child.kill).toHaveBeenCalledWith('SIGTERM')
167
- })
168
-
169
- // ── Direct-run guard ─────────────────────────────────────────────────────
170
-
171
- it('direct run: auto-launches when argv[1] is this module', async () => {
172
- const modulePath = fileURLToPath(
173
- new URL('./playwright-mcp-launcher.js', import.meta.url),
174
- )
175
- const originalArgv1 = process.argv[1]
176
- const intListeners = process.listeners('SIGINT')
177
- const termListeners = process.listeners('SIGTERM')
178
- process.argv[1] = modulePath
179
-
180
- try {
181
- vi.resetModules()
182
- await import('./playwright-mcp-launcher.js')
183
-
184
- expect(spawn).toHaveBeenCalledWith(
185
- 'npx',
186
- expect.arrayContaining(['@playwright/mcp@latest']),
187
- { stdio: 'inherit', shell: true },
188
- )
189
- } finally {
190
- process.argv[1] = originalArgv1
191
- for (const listener of process.listeners('SIGINT')) {
192
- if (!intListeners.includes(listener)) {
193
- process.removeListener('SIGINT', listener)
194
- }
195
- }
196
- for (const listener of process.listeners('SIGTERM')) {
197
- if (!termListeners.includes(listener)) {
198
- process.removeListener('SIGTERM', listener)
199
- }
200
- }
201
- }
202
- })
203
-
204
- it('imported with an empty argv[1]: does not launch', async () => {
205
- const originalArgv1 = process.argv[1]
206
- process.argv[1] = ''
207
-
208
- try {
209
- vi.resetModules()
210
- await import('./playwright-mcp-launcher.js')
211
-
212
- expect(spawn).not.toHaveBeenCalled()
213
- } finally {
214
- process.argv[1] = originalArgv1
215
- }
216
- })
217
- })