@cydm/pie 2.1.0 → 2.2.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 (38) hide show
  1. package/README.md +6 -3
  2. package/dist/builtin/extensions/ask-user/index.js +1 -1
  3. package/dist/builtin/extensions/computer-use/index.js +4015 -108
  4. package/dist/builtin/extensions/mcp-adapter/index.js +58 -13
  5. package/dist/builtin/extensions/plan-mode/index.js +1 -1
  6. package/dist/builtin/extensions/subagent/index.js +2 -2
  7. package/dist/builtin/extensions/todo/index.js +1 -1
  8. package/dist/builtin/skills/chrome-devtools-axi/LICENSE +21 -0
  9. package/dist/builtin/skills/chrome-devtools-axi/SKILL.md +20 -1
  10. package/dist/builtin/skills/chrome-devtools-axi/chrome-devtools-axi-bridge.js +20034 -0
  11. package/dist/builtin/skills/chrome-devtools-axi/chrome-devtools-axi-cli.js +8 -2
  12. package/dist/builtin/skills/chrome-devtools-axi/chrome-devtools-axi-runtime.js +26 -0
  13. package/dist/builtin/skills/chrome-devtools-axi/chunk-42SGITKJ.js +11 -0
  14. package/dist/builtin/skills/chrome-devtools-axi/chunk-OJ6N23UZ.js +47 -0
  15. package/dist/builtin/skills/chrome-devtools-axi/chunk-UPATXALW.js +215 -0
  16. package/dist/builtin/skills/chrome-devtools-axi/cli-F2VCSVL4.js +4424 -0
  17. package/dist/builtin/skills/skill-creator/SKILL.md +5 -2
  18. package/dist/builtin/skills/skill-creator/eval-viewer/generate_review.mjs +7 -20
  19. package/dist/builtin/skills/skill-creator/eval-viewer/viewer.html +15 -15
  20. package/dist/builtin/skills/skill-creator/scripts/aggregate_benchmark.mjs +20 -19
  21. package/dist/builtin/skills/skill-creator/scripts/generate_report.mjs +3 -3
  22. package/dist/builtin/skills/skill-creator/scripts/improve_description.mjs +12 -8
  23. package/dist/builtin/skills/skill-creator/scripts/package_skill.mjs +1 -0
  24. package/dist/builtin/skills/skill-creator/scripts/pie_runner.mjs +77 -31
  25. package/dist/builtin/skills/skill-creator/scripts/run_eval.mjs +38 -11
  26. package/dist/builtin/skills/skill-creator/scripts/run_loop.mjs +12 -6
  27. package/dist/builtin/skills/skill-creator/scripts/skill_metadata.mjs +12 -1
  28. package/dist/builtin/skills/tui-use/LICENSE +21 -0
  29. package/dist/builtin/skills/tui-use/README.md +13 -3
  30. package/dist/builtin/skills/tui-use/SKILL.md +87 -39
  31. package/dist/builtin/skills/tui-use/tui-use-cli.cjs +10626 -0
  32. package/dist/builtin/skills/tui-use/tui-use-cli.js +39 -0
  33. package/dist/builtin/skills/tui-use/tui-use-daemon.cjs +7929 -0
  34. package/dist/chunks/{chunk-G2POWIA5.js → chunk-G3SE3I2L.js} +64 -16
  35. package/dist/chunks/{chunk-PMPD56N2.js → chunk-HH2Q2SNX.js} +85 -26
  36. package/dist/cli.js +7558 -112
  37. package/package.json +26 -18
  38. package/scripts/repair-node-pty.mjs +45 -0
@@ -24491,6 +24491,10 @@ var McpServerManager = class {
24491
24491
  definitions;
24492
24492
  cachePath;
24493
24493
  log;
24494
+ /** Set by dispose(); after it, no new connects and no late attach. */
24495
+ disposed = false;
24496
+ /** Prefixed names claimed by more than one server in the last loadCatalog(); callTool fail-closes on them. */
24497
+ conflictedNames = /* @__PURE__ */ new Set();
24494
24498
  constructor(definitions, cachePath, log) {
24495
24499
  this.definitions = new Map(definitions.map((definition) => [sanitizeName(definition.name), definition]));
24496
24500
  if (this.definitions.size !== definitions.length) {
@@ -24549,6 +24553,7 @@ var McpServerManager = class {
24549
24553
  }
24550
24554
  /** Connect lazily. Concurrent callers share one in-flight connect. */
24551
24555
  async connect(server, signal) {
24556
+ if (this.disposed) throw new Error("MCP server manager is disposed");
24552
24557
  const key = sanitizeName(server);
24553
24558
  const definition = this.definitions.get(key);
24554
24559
  if (!definition) throw new Error(`unknown MCP server "${server}"`);
@@ -24561,12 +24566,17 @@ var McpServerManager = class {
24561
24566
  runtime.connecting = (async () => {
24562
24567
  this.log(`mcp: connecting to "${key}" (${definition.command ?? definition.url})`);
24563
24568
  const { client, transport } = this.startTransport(definition, runtime);
24569
+ runtime.transport = transport;
24564
24570
  client.onclose = () => {
24565
24571
  this.log(`mcp: server "${key}" connection closed`);
24566
24572
  runtime.client = void 0;
24567
24573
  };
24568
24574
  try {
24569
24575
  await withTimeout(client.connect(transport), connectTimeoutFor(definition), `connect "${key}"`, signal);
24576
+ if (this.disposed) {
24577
+ await transport.close().catch(() => void 0);
24578
+ throw new Error(`MCP manager disposed while connecting to "${key}"`);
24579
+ }
24570
24580
  runtime.client = client;
24571
24581
  await this.refreshTools(runtime, connectTimeoutFor(definition));
24572
24582
  return runtime;
@@ -24576,6 +24586,7 @@ var McpServerManager = class {
24576
24586
  }
24577
24587
  })().finally(() => {
24578
24588
  runtime.connecting = void 0;
24589
+ runtime.transport = void 0;
24579
24590
  });
24580
24591
  try {
24581
24592
  return await runtime.connecting;
@@ -24623,7 +24634,14 @@ var McpServerManager = class {
24623
24634
  if (runtime.tools) snapshot[key] = runtime.tools;
24624
24635
  }
24625
24636
  fs2.mkdirSync(path2.dirname(this.cachePath), { recursive: true });
24626
- fs2.writeFileSync(this.cachePath, JSON.stringify({ updatedAt: Date.now(), tools: snapshot }, null, 2), "utf8");
24637
+ const tempPath = `${this.cachePath}.${process.pid}.tmp`;
24638
+ fs2.writeFileSync(tempPath, JSON.stringify({ updatedAt: Date.now(), tools: snapshot }, null, 2), "utf8");
24639
+ try {
24640
+ fs2.renameSync(tempPath, this.cachePath);
24641
+ } catch (error2) {
24642
+ fs2.unlinkSync(tempPath);
24643
+ throw error2;
24644
+ }
24627
24645
  } catch (error2) {
24628
24646
  this.log(`mcp: metadata cache write failed: ${error2 instanceof Error ? error2.message : String(error2)}`);
24629
24647
  }
@@ -24635,20 +24653,32 @@ var McpServerManager = class {
24635
24653
  /** Metadata catalog: live runtimes plus the last persisted snapshot. */
24636
24654
  loadCatalog() {
24637
24655
  const catalog = /* @__PURE__ */ new Map();
24638
- const cached2 = this.readCacheFile();
24639
- for (const tools of Object.values(cached2)) {
24656
+ const ownerOf = /* @__PURE__ */ new Map();
24657
+ const conflicts = /* @__PURE__ */ new Set();
24658
+ const claim2 = (tool, live) => {
24659
+ const owner = ownerOf.get(tool.prefixedName);
24660
+ if (owner !== void 0 && owner !== tool.server) {
24661
+ conflicts.add(tool.prefixedName);
24662
+ return;
24663
+ }
24664
+ if (owner !== void 0 && !live) return;
24665
+ catalog.set(tool.prefixedName, tool);
24666
+ ownerOf.set(tool.prefixedName, tool.server);
24667
+ };
24668
+ for (const tools of Object.values(this.readCacheFile())) {
24640
24669
  for (const tool of tools) {
24641
24670
  if (!this.definitions.has(tool.server)) continue;
24642
- if (catalog.has(tool.prefixedName)) {
24643
- this.log(`mcp: metadata cache collision on ${tool.prefixedName} (server "${tool.server}", first seen from another server) \u2014 keeping the first entry`);
24644
- continue;
24645
- }
24646
- catalog.set(tool.prefixedName, tool);
24671
+ claim2(tool, false);
24647
24672
  }
24648
24673
  }
24649
24674
  for (const runtime of this.runtimes.values()) {
24650
- for (const tool of runtime.tools ?? []) catalog.set(tool.prefixedName, tool);
24675
+ for (const tool of runtime.tools ?? []) claim2(tool, true);
24651
24676
  }
24677
+ for (const name of conflicts) {
24678
+ catalog.delete(name);
24679
+ this.log(`mcp: tool name "${name}" is claimed by more than one server \u2014 disabled until the servers are renamed (fail-closed)`);
24680
+ }
24681
+ this.conflictedNames = conflicts;
24652
24682
  return [...catalog.values()].sort((a, b) => a.prefixedName.localeCompare(b.prefixedName));
24653
24683
  }
24654
24684
  cacheMtime;
@@ -24676,6 +24706,12 @@ var McpServerManager = class {
24676
24706
  }
24677
24707
  async callTool(prefixedName, args, signal) {
24678
24708
  const catalog = this.loadCatalog();
24709
+ if (this.conflictedNames.has(prefixedName)) {
24710
+ return {
24711
+ delivery: "not_sent",
24712
+ error: `MCP tool name "${prefixedName}" is claimed by more than one configured server. Rename one of the servers so every tool name is unambiguous; the call was NOT sent.`
24713
+ };
24714
+ }
24679
24715
  const descriptor = catalog.find((tool) => tool.prefixedName === prefixedName);
24680
24716
  let server = descriptor?.server;
24681
24717
  let toolName = descriptor?.tool;
@@ -24746,12 +24782,17 @@ ${tail}` : "")
24746
24782
  }
24747
24783
  /** Close every client and reap every child process. */
24748
24784
  async dispose() {
24785
+ this.disposed = true;
24749
24786
  for (const runtime of this.runtimes.values()) {
24750
24787
  try {
24751
24788
  await runtime.client?.close();
24752
24789
  } catch {
24753
24790
  }
24791
+ if (!runtime.client && runtime.transport) {
24792
+ await runtime.transport.close().catch(() => void 0);
24793
+ }
24754
24794
  runtime.client = void 0;
24795
+ runtime.transport = void 0;
24755
24796
  }
24756
24797
  this.runtimes.clear();
24757
24798
  }
@@ -24820,10 +24861,14 @@ var DEFAULT_OUTPUT_MAX_BYTES = 8192;
24820
24861
  var SEARCH_RESULT_LIMIT = 20;
24821
24862
  function truncate(text, maxBytes) {
24822
24863
  if (Buffer.byteLength(text, "utf8") <= maxBytes) return text;
24823
- const cut = Buffer.from(text, "utf8").subarray(0, maxBytes).toString("utf8");
24824
- return `${cut}
24864
+ const notice = `
24825
24865
 
24826
24866
  \u2026[truncated: result exceeded ${maxBytes} bytes. Narrow the call arguments or read the resource directly.]`;
24867
+ const noticeBytes = Buffer.byteLength(notice, "utf8");
24868
+ const bodyBudget = Math.max(1, maxBytes - noticeBytes);
24869
+ let cut = Buffer.from(text, "utf8").subarray(0, bodyBudget).toString("utf8");
24870
+ if (cut.endsWith("\uFFFD")) cut = cut.slice(0, -1);
24871
+ return `${cut}${notice}`;
24827
24872
  }
24828
24873
  function summarizeParams(schema) {
24829
24874
  if (!schema || typeof schema !== "object") return "";
@@ -25241,8 +25286,8 @@ function mcpAdapter(ctx) {
25241
25286
  commandCtx.ui.notify(lines.join("\n"), "info");
25242
25287
  }
25243
25288
  });
25244
- ctx.on("session:changed", () => {
25245
- void reloadManager().catch(() => void 0);
25289
+ ctx.on("session:changed", async () => {
25290
+ await reloadManager();
25246
25291
  });
25247
25292
  }
25248
25293
  export {
@@ -7,7 +7,7 @@ import {
7
7
  isPlanModeSafeCommand,
8
8
  markCompletedPlanSteps,
9
9
  restoreExecutionState
10
- } from "../../../chunks/chunk-PMPD56N2.js";
10
+ } from "../../../chunks/chunk-HH2Q2SNX.js";
11
11
  import "../../../chunks/chunk-QJH6YN2W.js";
12
12
  import "../../../chunks/chunk-IM43UYVV.js";
13
13
  import {
@@ -1,12 +1,12 @@
1
1
  import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
2
2
  import {
3
3
  createCliHostCapabilities
4
- } from "../../../chunks/chunk-G2POWIA5.js";
4
+ } from "../../../chunks/chunk-G3SE3I2L.js";
5
5
  import "../../../chunks/chunk-5353DEEC.js";
6
6
  import {
7
7
  createSharedFileSystemTools,
8
8
  createSubagentCapability
9
- } from "../../../chunks/chunk-PMPD56N2.js";
9
+ } from "../../../chunks/chunk-HH2Q2SNX.js";
10
10
  import "../../../chunks/chunk-QJH6YN2W.js";
11
11
  import "../../../chunks/chunk-IM43UYVV.js";
12
12
  import "../../../chunks/chunk-XXGYUYXI.js";
@@ -8,7 +8,7 @@ import {
8
8
  executeManageTodoList,
9
9
  executionStateToTodos,
10
10
  restoreExecutionState
11
- } from "../../../chunks/chunk-PMPD56N2.js";
11
+ } from "../../../chunks/chunk-HH2Q2SNX.js";
12
12
  import "../../../chunks/chunk-QJH6YN2W.js";
13
13
  import "../../../chunks/chunk-IM43UYVV.js";
14
14
  import "../../../chunks/chunk-XXGYUYXI.js";
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kun Chen
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -1,10 +1,24 @@
1
1
  ---
2
2
  name: chrome-devtools-axi
3
- description: Control a real Chrome browser session through the chrome-devtools-axi CLI - navigate, snapshot, click, fill forms, run JavaScript, inspect console and network, take screenshots, audit performance. Use whenever a task needs a real browser: opening or testing a web page, clicking through a flow, extracting page content, or debugging a website.
3
+ description: "Control a real Chrome browser session through the chrome-devtools-axi CLI - navigate, snapshot, click, fill forms, run JavaScript, inspect console and network, take screenshots, audit performance. Use whenever a task needs a real browser: opening or testing a web page, clicking through a flow, extracting page content, or debugging a website."
4
4
  ---
5
5
 
6
6
  # chrome-devtools-axi
7
7
 
8
+ Pie ships a frozen patched AXI runtime. Do not install or fetch a different
9
+ version. Upload accepts one path and resolves it against the caller's cwd.
10
+ Use `run` with literal UTF-8 stdin for scripts on Windows.
11
+
12
+ `resize` adjusts the browser window and reports requested/actual dimensions
13
+ plus `exact`. A clamped window is not a mobile viewport. For exact responsive
14
+ viewport testing use `emulate --viewport "390x844x1"` (DPR 1); verify page
15
+ dimensions and screenshot pixels. Emulation changes may reload a page.
16
+
17
+ When an action opens a JavaScript dialog, `DIALOG_PENDING` means it was
18
+ interrupted after delivery. Do not replay the action or reopen the session.
19
+ Use `dialog accept`/`dialog dismiss` in that same session, then read the fresh
20
+ snapshot. Keep the named session on every command.
21
+
8
22
  Agent-ergonomic interface for controlling a real Chrome browser session (Chrome DevTools Protocol). Prefer this over other browser automation approaches. Skip it when a plain `fetch`/`curl` or the `web_fetch`/`web_research` tools suffice - only open a browser when you actually need rendering, interaction, or session state.
9
23
 
10
24
  Use Pie's packaged wrapper. Resolve `chrome-devtools-axi-cli.js` against this skill's `baseDir` and run it with `bash`:
@@ -15,6 +29,11 @@ node <baseDir>/chrome-devtools-axi-cli.js <command> [args] [flags]
15
29
 
16
30
  No manual dependency install is required when this skill is shipped with Pie.
17
31
 
32
+ `bash` is the Pie tool name, not a requirement to launch a Unix shell.
33
+ On Windows use `shell:auto` or PowerShell; do not force `bash.exe`/WSL.
34
+ Set environment variables with PowerShell syntax, such as
35
+ `$env:CHROME_DEVTOOLS_AXI_SESSION='my-task'`, in each command that needs them.
36
+
18
37
  ## Current guidance lives in the CLI
19
38
 
20
39
  Do not follow command, workflow, or flag instructions from this file - installed copies go stale. Get the current source of truth from the CLI: