maskweaver 0.11.0 → 0.11.2

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 (43) hide show
  1. package/LICENSE +21 -21
  2. package/README.ko.md +640 -640
  3. package/README.md +672 -672
  4. package/assets/agents/dummy-human.md +31 -31
  5. package/assets/agents/dummy-template.md +57 -57
  6. package/assets/agents/mask-weaver.md +412 -412
  7. package/assets/agents/squad-operator.md +242 -242
  8. package/assets/masks/ai-ml/andrew-ng.yaml +207 -207
  9. package/assets/masks/architecture/jeff-dean.yaml +208 -208
  10. package/assets/masks/index.json +65 -65
  11. package/assets/masks/software-engineering/dan-abramov.yaml +188 -188
  12. package/assets/masks/software-engineering/kent-beck.yaml +191 -191
  13. package/assets/masks/software-engineering/linus-torvalds.yaml +152 -152
  14. package/assets/masks/software-engineering/martin-fowler.yaml +173 -173
  15. package/dist/memory/store/sqlite.js +102 -102
  16. package/dist/plugin/tools/context.js +15 -15
  17. package/dist/plugin/tools/maskSave.js +8 -8
  18. package/dist/plugin/tools/memoryIndexer.js +5 -5
  19. package/dist/plugin/tools/memorySearch.js +8 -8
  20. package/dist/plugin/tools/memoryWrite.js +3 -3
  21. package/dist/plugin/tools/retrospect.js +3 -3
  22. package/dist/plugin/tools/squad.js +39 -39
  23. package/dist/retrospect/mask-save.js +21 -21
  24. package/dist/retrospect/retrospect.js +9 -9
  25. package/dist/shared/generate-agents.d.ts +3 -15
  26. package/dist/shared/generate-agents.js +13 -172
  27. package/dist/shared/subscription-detection.d.ts +20 -0
  28. package/dist/shared/subscription-detection.js +162 -0
  29. package/dist/verify/prompts.js +114 -114
  30. package/dist/version.d.ts +1 -1
  31. package/dist/version.js +1 -1
  32. package/dist/weave/knowledge/global.js +86 -86
  33. package/dist/weave/verification/playwright.js +127 -127
  34. package/masks/ai-ml/andrew-ng.yaml +207 -207
  35. package/masks/architecture/jeff-dean.yaml +208 -208
  36. package/masks/index.json +65 -65
  37. package/masks/orchestration/squad-operator.yaml +205 -205
  38. package/masks/software-engineering/dan-abramov.yaml +188 -188
  39. package/masks/software-engineering/kent-beck.yaml +191 -191
  40. package/masks/software-engineering/linus-torvalds.yaml +152 -152
  41. package/masks/software-engineering/martin-fowler.yaml +173 -173
  42. package/package.json +1 -1
  43. package/postinstall.mjs +22 -112
@@ -153,60 +153,60 @@ export class GlobalKnowledge {
153
153
  createTables() {
154
154
  if (!this.db)
155
155
  return;
156
- this.db.exec(`
157
- CREATE TABLE IF NOT EXISTS troubleshooting (
158
- id INTEGER PRIMARY KEY AUTOINCREMENT,
159
- error_signature TEXT NOT NULL,
160
- error_message TEXT NOT NULL,
161
- context TEXT NOT NULL,
162
- solution TEXT NOT NULL,
163
- project_type TEXT,
164
- tech_stack TEXT,
165
- tags TEXT,
166
- effectiveness INTEGER DEFAULT 5,
167
- created_at TEXT NOT NULL,
168
- used_count INTEGER DEFAULT 0,
169
- last_used_at TEXT
170
- );
171
-
172
- CREATE INDEX IF NOT EXISTS idx_error_signature
173
- ON troubleshooting(error_signature);
174
-
175
- CREATE INDEX IF NOT EXISTS idx_project_type
176
- ON troubleshooting(project_type);
156
+ this.db.exec(`
157
+ CREATE TABLE IF NOT EXISTS troubleshooting (
158
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
159
+ error_signature TEXT NOT NULL,
160
+ error_message TEXT NOT NULL,
161
+ context TEXT NOT NULL,
162
+ solution TEXT NOT NULL,
163
+ project_type TEXT,
164
+ tech_stack TEXT,
165
+ tags TEXT,
166
+ effectiveness INTEGER DEFAULT 5,
167
+ created_at TEXT NOT NULL,
168
+ used_count INTEGER DEFAULT 0,
169
+ last_used_at TEXT
170
+ );
171
+
172
+ CREATE INDEX IF NOT EXISTS idx_error_signature
173
+ ON troubleshooting(error_signature);
174
+
175
+ CREATE INDEX IF NOT EXISTS idx_project_type
176
+ ON troubleshooting(project_type);
177
177
  `);
178
178
  if (this.usingSqlJs) {
179
179
  this.ftsAvailable = false;
180
180
  }
181
181
  else {
182
182
  try {
183
- this.db.exec(`
184
- CREATE VIRTUAL TABLE IF NOT EXISTS troubleshooting_fts USING fts5(
185
- error_message,
186
- context,
187
- solution,
188
- tags,
189
- content='troubleshooting',
190
- content_rowid='id'
191
- );
192
-
193
- -- Triggers to keep FTS in sync
194
- CREATE TRIGGER IF NOT EXISTS troubleshooting_ai AFTER INSERT ON troubleshooting BEGIN
195
- INSERT INTO troubleshooting_fts(rowid, error_message, context, solution, tags)
196
- VALUES (new.id, new.error_message, new.context, new.solution, new.tags);
197
- END;
198
-
199
- CREATE TRIGGER IF NOT EXISTS troubleshooting_ad AFTER DELETE ON troubleshooting BEGIN
200
- INSERT INTO troubleshooting_fts(troubleshooting_fts, rowid, error_message, context, solution, tags)
201
- VALUES ('delete', old.id, old.error_message, old.context, old.solution, old.tags);
202
- END;
203
-
204
- CREATE TRIGGER IF NOT EXISTS troubleshooting_au AFTER UPDATE ON troubleshooting BEGIN
205
- INSERT INTO troubleshooting_fts(troubleshooting_fts, rowid, error_message, context, solution, tags)
206
- VALUES ('delete', old.id, old.error_message, old.context, old.solution, old.tags);
207
- INSERT INTO troubleshooting_fts(rowid, error_message, context, solution, tags)
208
- VALUES (new.id, new.error_message, new.context, new.solution, new.tags);
209
- END;
183
+ this.db.exec(`
184
+ CREATE VIRTUAL TABLE IF NOT EXISTS troubleshooting_fts USING fts5(
185
+ error_message,
186
+ context,
187
+ solution,
188
+ tags,
189
+ content='troubleshooting',
190
+ content_rowid='id'
191
+ );
192
+
193
+ -- Triggers to keep FTS in sync
194
+ CREATE TRIGGER IF NOT EXISTS troubleshooting_ai AFTER INSERT ON troubleshooting BEGIN
195
+ INSERT INTO troubleshooting_fts(rowid, error_message, context, solution, tags)
196
+ VALUES (new.id, new.error_message, new.context, new.solution, new.tags);
197
+ END;
198
+
199
+ CREATE TRIGGER IF NOT EXISTS troubleshooting_ad AFTER DELETE ON troubleshooting BEGIN
200
+ INSERT INTO troubleshooting_fts(troubleshooting_fts, rowid, error_message, context, solution, tags)
201
+ VALUES ('delete', old.id, old.error_message, old.context, old.solution, old.tags);
202
+ END;
203
+
204
+ CREATE TRIGGER IF NOT EXISTS troubleshooting_au AFTER UPDATE ON troubleshooting BEGIN
205
+ INSERT INTO troubleshooting_fts(troubleshooting_fts, rowid, error_message, context, solution, tags)
206
+ VALUES ('delete', old.id, old.error_message, old.context, old.solution, old.tags);
207
+ INSERT INTO troubleshooting_fts(rowid, error_message, context, solution, tags)
208
+ VALUES (new.id, new.error_message, new.context, new.solution, new.tags);
209
+ END;
210
210
  `);
211
211
  this.ftsAvailable = true;
212
212
  }
@@ -223,12 +223,12 @@ export class GlobalKnowledge {
223
223
  }
224
224
  const signature = normalizeErrorSignature(entry.errorMessage);
225
225
  const now = new Date().toISOString();
226
- const stmt = this.db.prepare(`
227
- INSERT INTO troubleshooting (
228
- error_signature, error_message, context, solution,
229
- project_type, tech_stack, tags, effectiveness,
230
- created_at, used_count
231
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 0)
226
+ const stmt = this.db.prepare(`
227
+ INSERT INTO troubleshooting (
228
+ error_signature, error_message, context, solution,
229
+ project_type, tech_stack, tags, effectiveness,
230
+ created_at, used_count
231
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 0)
232
232
  `);
233
233
  const result = stmt.run(signature, entry.errorMessage, entry.context, entry.solution, entry.projectType || null, entry.techStack ? JSON.stringify(entry.techStack) : null, entry.tags ? JSON.stringify(entry.tags) : null, entry.effectiveness || 5, now);
234
234
  return result.lastInsertRowid;
@@ -240,12 +240,12 @@ export class GlobalKnowledge {
240
240
  const { projectType, limit = 5, minEffectiveness = 3 } = options;
241
241
  const signature = normalizeErrorSignature(errorMessage);
242
242
  const results = [];
243
- const exactStmt = this.db.prepare(`
244
- SELECT * FROM troubleshooting
245
- WHERE error_signature = ?
246
- AND effectiveness >= ?
247
- ORDER BY effectiveness DESC, used_count DESC
248
- LIMIT ?
243
+ const exactStmt = this.db.prepare(`
244
+ SELECT * FROM troubleshooting
245
+ WHERE error_signature = ?
246
+ AND effectiveness >= ?
247
+ ORDER BY effectiveness DESC, used_count DESC
248
+ LIMIT ?
249
249
  `);
250
250
  const exactMatches = exactStmt.all(signature, minEffectiveness, limit);
251
251
  for (const row of exactMatches) {
@@ -266,16 +266,16 @@ export class GlobalKnowledge {
266
266
  .join(' OR ');
267
267
  if (searchTerms) {
268
268
  try {
269
- const ftsStmt = this.db.prepare(`
270
- SELECT t.*, bm25(troubleshooting_fts) as rank
271
- FROM troubleshooting_fts f
272
- JOIN troubleshooting t ON f.rowid = t.id
273
- WHERE troubleshooting_fts MATCH ?
274
- AND t.effectiveness >= ?
275
- ${existingIds.length > 0 ? `AND t.id NOT IN (${existingIds.join(',')})` : ''}
276
- ${projectType ? 'AND t.project_type = ?' : ''}
277
- ORDER BY rank
278
- LIMIT ?
269
+ const ftsStmt = this.db.prepare(`
270
+ SELECT t.*, bm25(troubleshooting_fts) as rank
271
+ FROM troubleshooting_fts f
272
+ JOIN troubleshooting t ON f.rowid = t.id
273
+ WHERE troubleshooting_fts MATCH ?
274
+ AND t.effectiveness >= ?
275
+ ${existingIds.length > 0 ? `AND t.id NOT IN (${existingIds.join(',')})` : ''}
276
+ ${projectType ? 'AND t.project_type = ?' : ''}
277
+ ORDER BY rank
278
+ LIMIT ?
279
279
  `);
280
280
  const params = projectType
281
281
  ? [searchTerms, minEffectiveness, projectType, remaining]
@@ -299,11 +299,11 @@ export class GlobalKnowledge {
299
299
  await this.init();
300
300
  if (!this.db)
301
301
  return;
302
- const stmt = this.db.prepare(`
303
- UPDATE troubleshooting
304
- SET used_count = used_count + 1,
305
- last_used_at = ?
306
- WHERE id = ?
302
+ const stmt = this.db.prepare(`
303
+ UPDATE troubleshooting
304
+ SET used_count = used_count + 1,
305
+ last_used_at = ?
306
+ WHERE id = ?
307
307
  `);
308
308
  stmt.run(new Date().toISOString(), id);
309
309
  }
@@ -311,10 +311,10 @@ export class GlobalKnowledge {
311
311
  await this.init();
312
312
  if (!this.db)
313
313
  return;
314
- const stmt = this.db.prepare(`
315
- UPDATE troubleshooting
316
- SET effectiveness = ?
317
- WHERE id = ?
314
+ const stmt = this.db.prepare(`
315
+ UPDATE troubleshooting
316
+ SET effectiveness = ?
317
+ WHERE id = ?
318
318
  `);
319
319
  stmt.run(Math.max(1, Math.min(10, effectiveness)), id);
320
320
  }
@@ -330,13 +330,13 @@ export class GlobalKnowledge {
330
330
  }
331
331
  const totalStmt = this.db.prepare('SELECT COUNT(*) as count FROM troubleshooting');
332
332
  const total = totalStmt.get();
333
- const projectTypeStmt = this.db.prepare(`
334
- SELECT project_type as type, COUNT(*) as count
335
- FROM troubleshooting
336
- WHERE project_type IS NOT NULL
337
- GROUP BY project_type
338
- ORDER BY count DESC
339
- LIMIT 10
333
+ const projectTypeStmt = this.db.prepare(`
334
+ SELECT project_type as type, COUNT(*) as count
335
+ FROM troubleshooting
336
+ WHERE project_type IS NOT NULL
337
+ GROUP BY project_type
338
+ ORDER BY count DESC
339
+ LIMIT 10
340
340
  `);
341
341
  const projectTypes = projectTypeStmt.all();
342
342
  const avgStmt = this.db.prepare('SELECT AVG(effectiveness) as avg FROM troubleshooting');
@@ -141,16 +141,16 @@ export async function runVisualRegressionTests(projectPath, options) {
141
141
  export async function capturePageScreenshot(projectPath, url, outputPath) {
142
142
  const screenshotPath = outputPath || path.join(projectPath, '.weave', 'screenshots', `capture-${Date.now()}.png`);
143
143
  await fs.mkdir(path.dirname(screenshotPath), { recursive: true });
144
- const script = `
145
- const { chromium } = require('playwright');
146
- (async () => {
147
- const browser = await chromium.launch();
148
- const page = await browser.newPage();
149
- await page.goto('${url}');
150
- await page.screenshot({ path: '${screenshotPath.replace(/\\/g, '/')}', fullPage: true });
151
- await browser.close();
152
- console.log('Screenshot saved to: ${screenshotPath.replace(/\\/g, '/')}');
153
- })();
144
+ const script = `
145
+ const { chromium } = require('playwright');
146
+ (async () => {
147
+ const browser = await chromium.launch();
148
+ const page = await browser.newPage();
149
+ await page.goto('${url}');
150
+ await page.screenshot({ path: '${screenshotPath.replace(/\\/g, '/')}', fullPage: true });
151
+ await browser.close();
152
+ console.log('Screenshot saved to: ${screenshotPath.replace(/\\/g, '/')}');
153
+ })();
154
154
  `;
155
155
  const scriptPath = path.join(projectPath, '.weave', 'temp-screenshot.js');
156
156
  await fs.mkdir(path.dirname(scriptPath), { recursive: true });
@@ -334,126 +334,126 @@ export function analyzePlaywrightError(failure) {
334
334
  return analysis;
335
335
  }
336
336
  function generatePlaywrightConfig(projectPath) {
337
- return `import { defineConfig, devices } from '@playwright/test';
338
-
339
- /**
340
- * Playwright E2E Test Configuration
341
- * Generated by Maskweaver Weave
342
- *
343
- * @see https://playwright.dev/docs/test-configuration
344
- */
345
- export default defineConfig({
346
- // Test directory
347
- testDir: './e2e',
348
-
349
- // Run tests in parallel
350
- fullyParallel: true,
351
-
352
- // Fail the build on test.only in CI
353
- forbidOnly: !!process.env.CI,
354
-
355
- // Retry on CI only
356
- retries: process.env.CI ? 2 : 0,
357
-
358
- // Number of workers
359
- workers: process.env.CI ? 1 : undefined,
360
-
361
- // Reporter
362
- reporter: [
363
- ['html', { open: 'never' }],
364
- ['json', { outputFile: 'test-results/results.json' }],
365
- ],
366
-
367
- // Shared settings for all projects
368
- use: {
369
- // Base URL for navigation
370
- baseURL: 'http://localhost:3000',
371
-
372
- // Collect trace when retrying
373
- trace: 'on-first-retry',
374
-
375
- // Screenshot on failure
376
- screenshot: 'only-on-failure',
377
-
378
- // Record video on failure
379
- video: 'on-first-retry',
380
- },
381
-
382
- // Configure projects for browsers
383
- projects: [
384
- {
385
- name: 'chromium',
386
- use: { ...devices['Desktop Chrome'] },
387
- },
388
- // Uncomment for additional browsers
389
- // {
390
- // name: 'firefox',
391
- // use: { ...devices['Desktop Firefox'] },
392
- // },
393
- // {
394
- // name: 'webkit',
395
- // use: { ...devices['Desktop Safari'] },
396
- // },
397
- // Mobile testing
398
- // {
399
- // name: 'mobile-chrome',
400
- // use: { ...devices['Pixel 5'] },
401
- // },
402
- ],
403
-
404
- // Run local dev server before tests
405
- webServer: {
406
- command: 'npm run dev',
407
- url: 'http://localhost:3000',
408
- reuseExistingServer: !process.env.CI,
409
- timeout: 120 * 1000,
410
- },
411
- });
337
+ return `import { defineConfig, devices } from '@playwright/test';
338
+
339
+ /**
340
+ * Playwright E2E Test Configuration
341
+ * Generated by Maskweaver Weave
342
+ *
343
+ * @see https://playwright.dev/docs/test-configuration
344
+ */
345
+ export default defineConfig({
346
+ // Test directory
347
+ testDir: './e2e',
348
+
349
+ // Run tests in parallel
350
+ fullyParallel: true,
351
+
352
+ // Fail the build on test.only in CI
353
+ forbidOnly: !!process.env.CI,
354
+
355
+ // Retry on CI only
356
+ retries: process.env.CI ? 2 : 0,
357
+
358
+ // Number of workers
359
+ workers: process.env.CI ? 1 : undefined,
360
+
361
+ // Reporter
362
+ reporter: [
363
+ ['html', { open: 'never' }],
364
+ ['json', { outputFile: 'test-results/results.json' }],
365
+ ],
366
+
367
+ // Shared settings for all projects
368
+ use: {
369
+ // Base URL for navigation
370
+ baseURL: 'http://localhost:3000',
371
+
372
+ // Collect trace when retrying
373
+ trace: 'on-first-retry',
374
+
375
+ // Screenshot on failure
376
+ screenshot: 'only-on-failure',
377
+
378
+ // Record video on failure
379
+ video: 'on-first-retry',
380
+ },
381
+
382
+ // Configure projects for browsers
383
+ projects: [
384
+ {
385
+ name: 'chromium',
386
+ use: { ...devices['Desktop Chrome'] },
387
+ },
388
+ // Uncomment for additional browsers
389
+ // {
390
+ // name: 'firefox',
391
+ // use: { ...devices['Desktop Firefox'] },
392
+ // },
393
+ // {
394
+ // name: 'webkit',
395
+ // use: { ...devices['Desktop Safari'] },
396
+ // },
397
+ // Mobile testing
398
+ // {
399
+ // name: 'mobile-chrome',
400
+ // use: { ...devices['Pixel 5'] },
401
+ // },
402
+ ],
403
+
404
+ // Run local dev server before tests
405
+ webServer: {
406
+ command: 'npm run dev',
407
+ url: 'http://localhost:3000',
408
+ reuseExistingServer: !process.env.CI,
409
+ timeout: 120 * 1000,
410
+ },
411
+ });
412
412
  `;
413
413
  }
414
414
  function generateExampleTest() {
415
- return `import { test, expect } from '@playwright/test';
416
-
417
- /**
418
- * Example E2E Test
419
- * Generated by Maskweaver Weave
420
- *
421
- * Run with: npx playwright test
422
- */
423
-
424
- test.describe('Application', () => {
425
- test('should load home page', async ({ page }) => {
426
- // Navigate to home
427
- await page.goto('/');
428
-
429
- // Check if page loaded
430
- await expect(page).toHaveTitle(/.+/);
431
- });
432
-
433
- test('should have working navigation', async ({ page }) => {
434
- await page.goto('/');
435
-
436
- // Example: check for a navigation element
437
- const nav = page.locator('nav');
438
- // await expect(nav).toBeVisible();
439
- });
440
- });
441
-
442
- test.describe('Visual Regression', () => {
443
- test('home page screenshot', async ({ page }) => {
444
- await page.goto('/');
445
-
446
- // Wait for any animations to complete
447
- await page.waitForTimeout(1000);
448
-
449
- // Take a screenshot for visual comparison
450
- await expect(page).toHaveScreenshot('home.png', {
451
- fullPage: true,
452
- // Allow 0.2% pixel difference for anti-aliasing
453
- maxDiffPixelRatio: 0.002,
454
- });
455
- });
456
- });
415
+ return `import { test, expect } from '@playwright/test';
416
+
417
+ /**
418
+ * Example E2E Test
419
+ * Generated by Maskweaver Weave
420
+ *
421
+ * Run with: npx playwright test
422
+ */
423
+
424
+ test.describe('Application', () => {
425
+ test('should load home page', async ({ page }) => {
426
+ // Navigate to home
427
+ await page.goto('/');
428
+
429
+ // Check if page loaded
430
+ await expect(page).toHaveTitle(/.+/);
431
+ });
432
+
433
+ test('should have working navigation', async ({ page }) => {
434
+ await page.goto('/');
435
+
436
+ // Example: check for a navigation element
437
+ const nav = page.locator('nav');
438
+ // await expect(nav).toBeVisible();
439
+ });
440
+ });
441
+
442
+ test.describe('Visual Regression', () => {
443
+ test('home page screenshot', async ({ page }) => {
444
+ await page.goto('/');
445
+
446
+ // Wait for any animations to complete
447
+ await page.waitForTimeout(1000);
448
+
449
+ // Take a screenshot for visual comparison
450
+ await expect(page).toHaveScreenshot('home.png', {
451
+ fullPage: true,
452
+ // Allow 0.2% pixel difference for anti-aliasing
453
+ maxDiffPixelRatio: 0.002,
454
+ });
455
+ });
456
+ });
457
457
  `;
458
458
  }
459
459
  async function runCommand(command, args, cwd) {