alanbox 0.1.3 → 0.1.4

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 (56) hide show
  1. package/0boxer/AGENTS.md +3 -2
  2. package/0boxer/src/commands/AGENTS.md +2 -1
  3. package/0boxer/src/commands/install.js +47 -0
  4. package/1swarmer/AGENTS.md +5 -2
  5. package/1swarmer/src/AGENTS.md +4 -3
  6. package/1swarmer/src/args.js +7 -0
  7. package/1swarmer/src/cli.js +26 -0
  8. package/1swarmer/src/commands/AGENTS.md +3 -0
  9. package/1swarmer/src/commands/review-file.js +997 -0
  10. package/1swarmer/src/runner/AGENTS.md +1 -0
  11. package/1swarmer/src/runner/codex-runner.js +23 -3
  12. package/2designer/README.md +3 -0
  13. package/2designer/dist/{cdp-engine-JK2XVDHK.js → cdp-engine-4AIWSWXO.js} +2 -2
  14. package/2designer/dist/{cdp-engine-A5WTMTVF.js → cdp-engine-SG4K2BCX.js} +2 -2
  15. package/2designer/dist/{chunk-NQ3ASZUE.js → chunk-7X7PTLZH.js} +2 -2
  16. package/2designer/dist/{chunk-JVF26NXD.js → chunk-DPOWNFOH.js} +2 -2
  17. package/2designer/dist/{chunk-SKEIVBOU.js → chunk-ISUUIOO7.js} +1 -1
  18. package/2designer/dist/chunk-ISUUIOO7.js.map +1 -0
  19. package/2designer/dist/cli.js +494 -244
  20. package/2designer/dist/cli.js.map +1 -1
  21. package/2designer/dist/index.d.ts +7 -18
  22. package/2designer/dist/index.js +5 -198
  23. package/2designer/dist/index.js.map +1 -1
  24. package/2designer/dist/{playwright-engine-YBRDIUHF.js → playwright-engine-YXBY3KEN.js} +2 -2
  25. package/2designer/dist/{playwright-engine-3YKJOUNU.js → playwright-engine-YXGDTSZ5.js} +2 -2
  26. package/2designer/dist/tint-UD4CJ7S2.js +7 -0
  27. package/2designer/dist/{tint-I3FTT23O.js → tint-YN63MLVN.js} +1 -1
  28. package/2designer/dist/tint-YN63MLVN.js.map +1 -0
  29. package/4reporter/README.md +24 -0
  30. package/4reporter/dist/cli.js +464 -0
  31. package/4reporter/dist/cli.js.map +1 -0
  32. package/4reporter/dist/index.d.ts +108 -0
  33. package/4reporter/dist/index.js +445 -0
  34. package/4reporter/dist/index.js.map +1 -0
  35. package/4reporter/package.json +39 -0
  36. package/README.md +13 -5
  37. package/bin/reporter.js +11 -0
  38. package/cli.js +31 -6
  39. package/mcp/README.md +7 -1
  40. package/mcp/config.toml +4 -0
  41. package/package.json +8 -4
  42. package/skills/AGENTS.md +3 -3
  43. package/skills/aitool/SKILL.md +1 -1
  44. package/skills/desginer/SKILL.md +65 -45
  45. package/skills/swarmer/SKILL.md +37 -0
  46. package/2designer/LICENSE +0 -21
  47. package/2designer/dist/chunk-SKEIVBOU.js.map +0 -1
  48. package/2designer/dist/tint-I3FTT23O.js.map +0 -1
  49. package/2designer/dist/tint-RUSSUAWA.js +0 -7
  50. /package/2designer/dist/{cdp-engine-JK2XVDHK.js.map → cdp-engine-4AIWSWXO.js.map} +0 -0
  51. /package/2designer/dist/{cdp-engine-A5WTMTVF.js.map → cdp-engine-SG4K2BCX.js.map} +0 -0
  52. /package/2designer/dist/{chunk-NQ3ASZUE.js.map → chunk-7X7PTLZH.js.map} +0 -0
  53. /package/2designer/dist/{chunk-JVF26NXD.js.map → chunk-DPOWNFOH.js.map} +0 -0
  54. /package/2designer/dist/{playwright-engine-YBRDIUHF.js.map → playwright-engine-YXBY3KEN.js.map} +0 -0
  55. /package/2designer/dist/{playwright-engine-3YKJOUNU.js.map → playwright-engine-YXGDTSZ5.js.map} +0 -0
  56. /package/2designer/dist/{tint-RUSSUAWA.js.map → tint-UD4CJ7S2.js.map} +0 -0
@@ -16,6 +16,7 @@
16
16
  - 不要把个人 Antigravity cockpit 路径、全局 npm 安装路径或本机私有 home 写成通用默认配置。
17
17
  - `info` 输出可以展示 `<native>`、`<not inherited>`、command、commandArgs 这类排查信息,但不要打印 secret。
18
18
  - Windows `.cmd`、`.bat`、`.ps1`、PowerShell 路径和 Node `spawn` 参数需要实际考虑;provider 裸命令应通过 PATH/PATHEXT 解析后再启动,不要把用户本机 npm shim 绝对路径写进默认配置。
19
+ - Windows 超时清理必须结束完整 provider 进程树;`codex.CMD` 可能继续派生 `node` 和 `codex.exe`,只杀父进程会导致 review-file 或 swarm 卡住。
19
20
 
20
21
  ### Verification
21
22
 
@@ -213,6 +213,9 @@ function summarizePromptTransport(invocation) {
213
213
 
214
214
  function buildClaudePrintArgs(config, options) {
215
215
  const args = ['-p'];
216
+ if (Array.isArray(options.claudeArgs) && options.claudeArgs.length > 0) {
217
+ args.push(...options.claudeArgs);
218
+ }
216
219
  const model = options.model || config.defaultModel;
217
220
  if (model) {
218
221
  args.push('--model', model);
@@ -277,7 +280,7 @@ function runCodex(args, options = {}) {
277
280
  const timer = timeoutMs > 0
278
281
  ? setTimeout(() => {
279
282
  timedOut = true;
280
- child.kill('SIGTERM');
283
+ killProcessTree(child.pid);
281
284
  }, timeoutMs)
282
285
  : null;
283
286
 
@@ -332,6 +335,24 @@ function writeStreamChunk(stream, text, prefix = '') {
332
335
  }
333
336
  }
334
337
 
338
+ function killProcessTree(pid) {
339
+ if (!pid) return;
340
+ if (process.platform === 'win32') {
341
+ const killer = spawn('taskkill.exe', ['/pid', String(pid), '/t', '/f'], {
342
+ stdio: 'ignore',
343
+ windowsHide: true,
344
+ });
345
+ killer.on('error', () => {});
346
+ return;
347
+ }
348
+
349
+ try {
350
+ process.kill(pid, 'SIGTERM');
351
+ } catch {
352
+ // Process may already be gone.
353
+ }
354
+ }
355
+
335
356
  async function execPrompt(prompt, options = {}) {
336
357
  if (!prompt || !prompt.trim()) {
337
358
  throw new Error('prompt is required');
@@ -513,7 +534,6 @@ module.exports = {
513
534
  buildLaunch,
514
535
  resolveCommandArgs,
515
536
  writeStreamChunk,
537
+ killProcessTree,
516
538
  };
517
539
 
518
-
519
-
@@ -5,6 +5,7 @@ Runtime UI measurement CLI for AI agents. The active command surface is intentio
5
5
  - `measure` — read element bbox, computed CSS, and optional child layout as JSON.
6
6
  - `screenshot` — capture a full page or selected element as PNG.
7
7
  - `overlay` — tint a design screenshot magenta and composite it over the runtime page.
8
+ - `changelist` — output changed-region JSON and side-by-side comparison PNGs from design/runtime screenshots.
8
9
 
9
10
  The CLI is bundled through `alanbox` as both `designer` and `alanbox designer ...`.
10
11
 
@@ -14,6 +15,7 @@ The CLI is bundled through `alanbox` as both `designer` and `alanbox designer ..
14
15
  designer measure --url "http://localhost:3000" --selector ".dialog"
15
16
  designer screenshot --url "http://localhost:3000" --selector ".dialog" --output runtime.png
16
17
  designer overlay --design design.png --url "http://localhost:3000" --selector ".dialog" --output overlay.png
18
+ designer changelist --design design.png --runtime runtime.png --output changes.json --annotated changes.png --regions-dir regions
17
19
  ```
18
20
 
19
21
  For Axure or iframe-based designs:
@@ -26,6 +28,7 @@ designer measure --url "http://127.0.0.1:32767/start.html" --frame "#mainFrame"
26
28
 
27
29
  - `src/` — active implementation.
28
30
  - `dist/` — built runtime shipped by `alanbox`.
31
+ - `res/overlay/` — archived interactive overlay UI, not part of the active CLI.
29
32
  - `res/designer-main-legacy/` — archived old commands and references, not part of the active CLI.
30
33
 
31
34
  ## Development
@@ -271,7 +271,7 @@ var CdpEngine = class _CdpEngine {
271
271
  return result.value;
272
272
  }
273
273
  async injectOverlay(params) {
274
- const { tintDesignImage } = await import("./tint-I3FTT23O.js");
274
+ const { tintDesignImage } = await import("./tint-YN63MLVN.js");
275
275
  const tintedBuf = await tintDesignImage(params.designImagePath);
276
276
  const base64 = tintedBuf.toString("base64");
277
277
  const js = `
@@ -311,4 +311,4 @@ export {
311
311
  CdpEngine,
312
312
  buildClip
313
313
  };
314
- //# sourceMappingURL=cdp-engine-JK2XVDHK.js.map
314
+ //# sourceMappingURL=cdp-engine-4AIWSWXO.js.map
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  CdpEngine,
3
3
  buildClip
4
- } from "./chunk-JVF26NXD.js";
4
+ } from "./chunk-DPOWNFOH.js";
5
5
  import "./chunk-UVKSRKXR.js";
6
6
  export {
7
7
  CdpEngine,
8
8
  buildClip
9
9
  };
10
- //# sourceMappingURL=cdp-engine-A5WTMTVF.js.map
10
+ //# sourceMappingURL=cdp-engine-SG4K2BCX.js.map
@@ -143,7 +143,7 @@ var PlaywrightEngine = class _PlaywrightEngine {
143
143
  return this.page.evaluate(expression);
144
144
  }
145
145
  async injectOverlay(params) {
146
- const { tintDesignImage } = await import("./tint-RUSSUAWA.js");
146
+ const { tintDesignImage } = await import("./tint-UD4CJ7S2.js");
147
147
  const tintedBuf = await tintDesignImage(params.designImagePath);
148
148
  const base64 = tintedBuf.toString("base64");
149
149
  await this.page.evaluate(
@@ -182,4 +182,4 @@ var PlaywrightEngine = class _PlaywrightEngine {
182
182
  export {
183
183
  PlaywrightEngine
184
184
  };
185
- //# sourceMappingURL=chunk-NQ3ASZUE.js.map
185
+ //# sourceMappingURL=chunk-7X7PTLZH.js.map
@@ -269,7 +269,7 @@ var CdpEngine = class _CdpEngine {
269
269
  return result.value;
270
270
  }
271
271
  async injectOverlay(params) {
272
- const { tintDesignImage } = await import("./tint-RUSSUAWA.js");
272
+ const { tintDesignImage } = await import("./tint-UD4CJ7S2.js");
273
273
  const tintedBuf = await tintDesignImage(params.designImagePath);
274
274
  const base64 = tintedBuf.toString("base64");
275
275
  const js = `
@@ -310,4 +310,4 @@ export {
310
310
  buildClip,
311
311
  CdpEngine
312
312
  };
313
- //# sourceMappingURL=chunk-JVF26NXD.js.map
313
+ //# sourceMappingURL=chunk-DPOWNFOH.js.map
@@ -55,4 +55,4 @@ function tintGhost(pixels, info, opacity) {
55
55
  export {
56
56
  tintDesignImage
57
57
  };
58
- //# sourceMappingURL=chunk-SKEIVBOU.js.map
58
+ //# sourceMappingURL=chunk-ISUUIOO7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/overlay/tint.ts"],"sourcesContent":["import sharp from 'sharp'\r\n\r\nexport type TintMode = 'magenta' | 'ghost' | 'difference'\r\n\r\n/**\n * 处理设计稿截图,生成适合叠到运行页上的 PNG 重影。\n *\n * 模式说明:\n * - 'magenta': 把非白色像素染成品红,适合白底或浅色背景的设计稿。\n * - 'ghost': 只统一降低透明度,适合背景不是纯白的截图。\n * - 'difference': 不预处理,由调用方使用 difference 混合模式。\n *\n * 返回带 alpha 通道的 PNG buffer。\n */\nexport async function tintDesignImage(\n imagePath: string,\r\n mode: TintMode = 'auto' as any,\r\n): Promise<Buffer> {\r\n const { data, info } = await sharp(imagePath)\r\n .ensureAlpha()\r\n .raw()\r\n .toBuffer({ resolveWithObject: true })\r\n\r\n const pixels = new Uint8Array(data.buffer)\r\n\r\n // 自动模式只粗略判断背景亮度:白底走品红染色,深色/复杂背景走 ghost。\n const resolvedMode = mode === ('auto' as any) ? detectMode(pixels) : mode\n\r\n if (resolvedMode === 'magenta') {\r\n return tintMagenta(pixels, info)\r\n }\n\n if (resolvedMode === 'difference') {\n // difference 模式需要保留原图颜色,混合策略交给调用方处理。\n return sharp(imagePath).ensureAlpha().png().toBuffer()\n }\n\n // ghost 模式不改颜色,只统一压低 alpha,避免覆盖运行页细节。\n return tintGhost(pixels, info, 0.4)\n}\n\nfunction detectMode(pixels: Uint8Array): TintMode {\n // 采样前若干像素估算背景亮度;当前目标是快速区分浅底和非浅底,不做精确抠图。\n let brightCount = 0\n const sampleSize = Math.min(pixels.length / 4, 1000)\r\n const step = Math.floor(pixels.length / 4 / sampleSize)\r\n\r\n for (let i = 0; i < sampleSize; i++) {\r\n const idx = i * step * 4\r\n const brightness = (pixels[idx] + pixels[idx + 1] + pixels[idx + 2]) / 3\r\n if (brightness > 220) brightCount++\r\n }\r\n\r\n return (brightCount / sampleSize) > 0.5 ? 'magenta' : 'ghost'\r\n}\r\n\r\nconst LIGHT_THRESHOLD = 230\nconst MAGENTA: [number, number, number] = [220, 40, 160]\n\r\nfunction tintMagenta(\r\n pixels: Uint8Array,\r\n info: { width: number; height: number },\r\n): Promise<Buffer> {\r\n for (let i = 0; i < pixels.length; i += 4) {\n const r = pixels[i], g = pixels[i + 1], b = pixels[i + 2]\n const brightness = (r + g + b) / 3\n\n if (brightness > LIGHT_THRESHOLD) {\n // 浅色背景直接透明化,避免白底盖住运行页。\n pixels[i + 3] = 0\n } else {\n // 像素越暗说明设计内容越明显,叠层 alpha 越高,便于观察 1-2px 偏差。\n const darkness = 1 - brightness / 255\n pixels[i] = MAGENTA[0]\n pixels[i + 1] = MAGENTA[1]\r\n pixels[i + 2] = MAGENTA[2]\r\n pixels[i + 3] = Math.round(darkness * 200)\r\n }\r\n }\r\n\r\n return sharp(Buffer.from(pixels.buffer), {\r\n raw: { width: info.width, height: info.height, channels: 4 },\r\n })\r\n .png()\r\n .toBuffer()\r\n}\r\n\r\nfunction tintGhost(\r\n pixels: Uint8Array,\r\n info: { width: number; height: number },\r\n opacity: number,\r\n): Promise<Buffer> {\n for (let i = 0; i < pixels.length; i += 4) {\n // 仅缩放 alpha,保留原图色相,用于非白底设计稿的低侵入叠加。\n pixels[i + 3] = Math.round(pixels[i + 3] * opacity)\n }\n\r\n return sharp(Buffer.from(pixels.buffer), {\r\n raw: { width: info.width, height: info.height, channels: 4 },\r\n })\r\n .png()\r\n .toBuffer()\r\n}\r\n"],"mappings":";AAAA,OAAO,WAAW;AAclB,eAAsB,gBACpB,WACA,OAAiB,QACA;AACjB,QAAM,EAAE,MAAM,KAAK,IAAI,MAAM,MAAM,SAAS,EACzC,YAAY,EACZ,IAAI,EACJ,SAAS,EAAE,mBAAmB,KAAK,CAAC;AAEvC,QAAM,SAAS,IAAI,WAAW,KAAK,MAAM;AAGzC,QAAM,eAAe,SAAU,SAAiB,WAAW,MAAM,IAAI;AAErE,MAAI,iBAAiB,WAAW;AAC9B,WAAO,YAAY,QAAQ,IAAI;AAAA,EACjC;AAEA,MAAI,iBAAiB,cAAc;AAEjC,WAAO,MAAM,SAAS,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS;AAAA,EACvD;AAGA,SAAO,UAAU,QAAQ,MAAM,GAAG;AACpC;AAEA,SAAS,WAAW,QAA8B;AAEhD,MAAI,cAAc;AAClB,QAAM,aAAa,KAAK,IAAI,OAAO,SAAS,GAAG,GAAI;AACnD,QAAM,OAAO,KAAK,MAAM,OAAO,SAAS,IAAI,UAAU;AAEtD,WAAS,IAAI,GAAG,IAAI,YAAY,KAAK;AACnC,UAAM,MAAM,IAAI,OAAO;AACvB,UAAM,cAAc,OAAO,GAAG,IAAI,OAAO,MAAM,CAAC,IAAI,OAAO,MAAM,CAAC,KAAK;AACvE,QAAI,aAAa,IAAK;AAAA,EACxB;AAEA,SAAQ,cAAc,aAAc,MAAM,YAAY;AACxD;AAEA,IAAM,kBAAkB;AACxB,IAAM,UAAoC,CAAC,KAAK,IAAI,GAAG;AAEvD,SAAS,YACP,QACA,MACiB;AACjB,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK,GAAG;AACzC,UAAM,IAAI,OAAO,CAAC,GAAG,IAAI,OAAO,IAAI,CAAC,GAAG,IAAI,OAAO,IAAI,CAAC;AACxD,UAAM,cAAc,IAAI,IAAI,KAAK;AAEjC,QAAI,aAAa,iBAAiB;AAEhC,aAAO,IAAI,CAAC,IAAI;AAAA,IAClB,OAAO;AAEL,YAAM,WAAW,IAAI,aAAa;AAClC,aAAO,CAAC,IAAI,QAAQ,CAAC;AACrB,aAAO,IAAI,CAAC,IAAI,QAAQ,CAAC;AACzB,aAAO,IAAI,CAAC,IAAI,QAAQ,CAAC;AACzB,aAAO,IAAI,CAAC,IAAI,KAAK,MAAM,WAAW,GAAG;AAAA,IAC3C;AAAA,EACF;AAEA,SAAO,MAAM,OAAO,KAAK,OAAO,MAAM,GAAG;AAAA,IACvC,KAAK,EAAE,OAAO,KAAK,OAAO,QAAQ,KAAK,QAAQ,UAAU,EAAE;AAAA,EAC7D,CAAC,EACE,IAAI,EACJ,SAAS;AACd;AAEA,SAAS,UACP,QACA,MACA,SACiB;AACjB,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK,GAAG;AAEzC,WAAO,IAAI,CAAC,IAAI,KAAK,MAAM,OAAO,IAAI,CAAC,IAAI,OAAO;AAAA,EACpD;AAEA,SAAO,MAAM,OAAO,KAAK,OAAO,MAAM,GAAG;AAAA,IACvC,KAAK,EAAE,OAAO,KAAK,OAAO,QAAQ,KAAK,QAAQ,UAAU,EAAE;AAAA,EAC7D,CAAC,EACE,IAAI,EACJ,SAAS;AACd;","names":[]}