@abarcenas/ai-workflow-template 1.49.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 (35) 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/plugins/graphify.js +22 -0
  6. package/LICENSE +15 -0
  7. package/README.md +56 -22
  8. package/memory-bank/.vocabulary.json +3 -0
  9. package/opencode.mcp.example.json +13 -0
  10. package/package.json +20 -10
  11. package/scripts/bump-version.js +18 -2
  12. package/scripts/mcp/playwright-mcp-launcher.js +45 -2
  13. package/scripts/bump-version.test.js +0 -238
  14. package/scripts/knowledgebase-cli.test.js +0 -576
  15. package/scripts/knowledgebase-index.test.js +0 -759
  16. package/scripts/mcp/playwright-mcp-launcher.test.js +0 -217
  17. package/scripts/mcp-knowledgebase-server.test.js +0 -745
  18. package/scripts/mcp-memory-server.test.js +0 -398
  19. package/scripts/memory-cli.test.js +0 -297
  20. package/scripts/memory-index.test.js +0 -1173
  21. package/scripts/normalize-memory.test.js +0 -753
  22. package/scripts/setup/discover.test.js +0 -530
  23. package/scripts/setup/hooks.test.js +0 -722
  24. package/scripts/setup/husky-init.test.js +0 -311
  25. package/scripts/setup/index.test.js +0 -1021
  26. package/scripts/setup/knowledgebase.test.js +0 -352
  27. package/scripts/setup/prepare.test.js +0 -718
  28. package/scripts/setup/skills-phase.test.js +0 -1274
  29. package/scripts/setup/sync-phase.test.js +0 -373
  30. package/scripts/setup/ui.test.js +0 -579
  31. package/scripts/setup/utils.test.js +0 -586
  32. package/scripts/sync-unit.test.js +0 -1881
  33. package/scripts/sync.test.js +0 -472
  34. package/scripts/validate-memory-schema.test.js +0 -328
  35. 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
- })