@cydm/pie 1.0.6 → 1.0.8

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 (59) hide show
  1. package/README.md +156 -9
  2. package/dist/builtin/extensions/ask-user/index.js +2 -3
  3. package/dist/builtin/extensions/init/index.js +70 -68
  4. package/dist/builtin/extensions/kimi-attachments/index.js +3 -3
  5. package/dist/builtin/extensions/plan-mode/index.js +85 -87
  6. package/dist/builtin/extensions/subagent/index.js +17 -7
  7. package/dist/builtin/extensions/todo/index.js +51 -22
  8. package/dist/builtin/skills/browser-tools/CHANGELOG.md +2 -44
  9. package/dist/builtin/skills/browser-tools/README.md +10 -99
  10. package/dist/builtin/skills/browser-tools/SKILL.md +21 -174
  11. package/dist/builtin/skills/browser-tools/package.json +6 -13
  12. package/dist/builtin/skills/browser-tools/playwright-cli.js +24 -0
  13. package/dist/builtin/skills/skill-creator/SKILL.md +17 -17
  14. package/dist/builtin/skills/skill-creator/eval-viewer/generate_review.mjs +285 -0
  15. package/dist/builtin/skills/skill-creator/eval-viewer/viewer.html +1 -1
  16. package/dist/builtin/skills/skill-creator/scripts/aggregate_benchmark.mjs +271 -0
  17. package/dist/builtin/skills/skill-creator/scripts/claude_cli.mjs +115 -0
  18. package/dist/builtin/skills/skill-creator/scripts/generate_report.mjs +224 -0
  19. package/dist/builtin/skills/skill-creator/scripts/improve_description.mjs +198 -0
  20. package/dist/builtin/skills/skill-creator/scripts/package_skill.mjs +132 -0
  21. package/dist/builtin/skills/skill-creator/scripts/pie_runner.mjs +115 -0
  22. package/dist/builtin/skills/skill-creator/scripts/quick_validate.mjs +44 -0
  23. package/dist/builtin/skills/skill-creator/scripts/run_eval.mjs +169 -0
  24. package/dist/builtin/skills/skill-creator/scripts/run_loop.mjs +297 -0
  25. package/dist/builtin/skills/skill-creator/scripts/skill_metadata.mjs +134 -0
  26. package/dist/chunks/chunk-6WD2NFIC.js +8383 -0
  27. package/dist/chunks/{chunk-MWFBYJOI.js → chunk-A5JSJAPK.js} +3973 -1313
  28. package/dist/chunks/chunk-NTYHFBUA.js +36 -0
  29. package/dist/chunks/chunk-ZRONUKTW.js +989 -0
  30. package/dist/chunks/{src-EGWRDMLB.js → src-3X3HBT2G.js} +1 -2
  31. package/dist/chunks/typescript-GSKWJIO4.js +210747 -0
  32. package/dist/cli.js +15261 -12502
  33. package/models.schema.json +238 -0
  34. package/package.json +34 -8
  35. package/dist/builtin/skills/browser-tools/browser-content.js +0 -103
  36. package/dist/builtin/skills/browser-tools/browser-cookies.js +0 -35
  37. package/dist/builtin/skills/browser-tools/browser-eval.js +0 -49
  38. package/dist/builtin/skills/browser-tools/browser-hn-scraper.js +0 -108
  39. package/dist/builtin/skills/browser-tools/browser-nav.js +0 -44
  40. package/dist/builtin/skills/browser-tools/browser-pick.js +0 -162
  41. package/dist/builtin/skills/browser-tools/browser-screenshot.js +0 -34
  42. package/dist/builtin/skills/browser-tools/browser-start.js +0 -86
  43. package/dist/builtin/skills/skill-creator/eval-viewer/generate_review.py +0 -471
  44. package/dist/builtin/skills/skill-creator/scripts/__init__.py +0 -0
  45. package/dist/builtin/skills/skill-creator/scripts/aggregate_benchmark.py +0 -401
  46. package/dist/builtin/skills/skill-creator/scripts/generate_report.py +0 -326
  47. package/dist/builtin/skills/skill-creator/scripts/improve_description.py +0 -247
  48. package/dist/builtin/skills/skill-creator/scripts/package_skill.py +0 -136
  49. package/dist/builtin/skills/skill-creator/scripts/quick_validate.py +0 -103
  50. package/dist/builtin/skills/skill-creator/scripts/run_eval.py +0 -310
  51. package/dist/builtin/skills/skill-creator/scripts/run_loop.py +0 -328
  52. package/dist/builtin/skills/skill-creator/scripts/utils.py +0 -47
  53. package/dist/chunks/capabilities-FENCOHVA.js +0 -9
  54. package/dist/chunks/chunk-JYBXCEJJ.js +0 -315
  55. package/dist/chunks/chunk-RID3574D.js +0 -2718
  56. package/dist/chunks/chunk-TBJ25UWB.js +0 -3657
  57. package/dist/chunks/chunk-XZXLO7YB.js +0 -322
  58. package/dist/chunks/file-logger-AL5VVZHH.js +0 -22
  59. package/dist/chunks/src-WRUACRN2.js +0 -132
@@ -1,73 +1,74 @@
1
1
  import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
2
2
  import {
3
- PLAN_MODE_TOOL_NAMES,
3
+ buildExecutionReminder,
4
+ createExecutionStateFromPlan,
4
5
  createPlanCapability,
5
6
  extractPlanTodoItems,
6
7
  isPlanModeSafeCommand,
7
- markCompletedPlanSteps
8
- } from "../../../chunks/chunk-TBJ25UWB.js";
9
- import "../../../chunks/chunk-MWFBYJOI.js";
10
- import "../../../chunks/chunk-RID3574D.js";
8
+ markCompletedPlanSteps,
9
+ restoreExecutionState
10
+ } from "../../../chunks/chunk-6WD2NFIC.js";
11
+ import "../../../chunks/chunk-A5JSJAPK.js";
11
12
  import "../../../chunks/chunk-TG2EQLX2.js";
12
13
 
13
14
  // builtin/extensions/plan-mode/index.ts
14
15
  var SESSION_METADATA_KEY = "planModeEnabled";
16
+ var EXECUTION_METADATA_KEY = "executionState";
15
17
  var planModeEnabled = false;
16
18
  var executionMode = false;
17
- var todoItems = [];
19
+ function toPlanTodoItems(state) {
20
+ return state.steps.map((step) => ({
21
+ step: step.id,
22
+ text: step.title,
23
+ completed: step.status === "completed"
24
+ }));
25
+ }
18
26
  function planModeExtension(ctx) {
19
- ctx.log("Plan mode extension loaded");
20
27
  const capability = createPlanCapability();
21
28
  function readPersistedPlanMode() {
22
29
  return ctx.getSessionMetadata()?.[SESSION_METADATA_KEY] === true;
23
30
  }
31
+ function readExecutionState() {
32
+ return restoreExecutionState(ctx.getSessionMetadata()?.[EXECUTION_METADATA_KEY] ?? ctx.getExecutionState());
33
+ }
34
+ function writeExecutionState(state) {
35
+ const next = state ?? restoreExecutionState(null);
36
+ ctx.setSessionMetadata(EXECUTION_METADATA_KEY, next);
37
+ ctx.setExecutionState(next);
38
+ ctx.setExecutionReminder(buildExecutionReminder(next) ?? void 0);
39
+ return next;
40
+ }
24
41
  function updateStatus() {
25
- if (executionMode && todoItems.length > 0) {
26
- const completed = todoItems.filter((t) => t.completed).length;
27
- ctx.ui.notify(`\u{1F4CB} Plan: ${completed}/${todoItems.length} completed`, "info");
42
+ const state = readExecutionState();
43
+ if (executionMode && state.steps.length > 0) {
44
+ const completed = state.steps.filter((step) => step.status === "completed").length;
45
+ ctx.ui.notify(`\u{1F4CB} Plan: ${completed}/${state.steps.length} completed`, "info");
28
46
  } else if (planModeEnabled) {
29
47
  ctx.ui.notify("\u23F8\uFE0F Plan mode active (read-only)", "info");
30
48
  }
31
49
  }
32
- function getNormalModeTools() {
33
- const allToolNames = ctx.getAllTools?.()?.map((tool) => tool?.name).filter((name) => typeof name === "string" && name.length > 0);
34
- if (allToolNames && allToolNames.length > 0) {
35
- return allToolNames;
50
+ function applyPlanModeState(enabled, forcePromptInjection = false) {
51
+ planModeEnabled = enabled;
52
+ if (!enabled) {
53
+ executionMode = false;
36
54
  }
37
- return ["read", "bash", "edit", "write", "grep", "find", "ls", "ask_user_multi", "manage_todo_list"];
55
+ ctx.setPlanMode(enabled, { forcePromptInjection });
38
56
  }
39
57
  function togglePlanMode() {
40
58
  planModeEnabled = !planModeEnabled;
41
59
  executionMode = false;
42
- todoItems = [];
60
+ writeExecutionState(null);
43
61
  ctx.setSessionMetadata(SESSION_METADATA_KEY, planModeEnabled);
44
- ctx.setPlanMode(planModeEnabled);
45
- if (planModeEnabled) {
46
- ctx.setActiveTools([...PLAN_MODE_TOOL_NAMES]);
47
- ctx.ui.notify(`Plan mode enabled. Available tools: ${PLAN_MODE_TOOL_NAMES.join(", ")}`);
48
- } else {
49
- ctx.setActiveTools(getNormalModeTools());
50
- ctx.ui.notify("Plan mode disabled. Full access restored.");
51
- }
52
- updateStatus();
53
- }
54
- function applyPlanModeState(enabled, options = {}) {
55
- planModeEnabled = enabled;
56
- executionMode = false;
57
- todoItems = [];
58
- ctx.setPlanMode(enabled, { forcePromptInjection: options.forcePromptInjection });
59
- ctx.setActiveTools(enabled ? [...PLAN_MODE_TOOL_NAMES] : getNormalModeTools());
60
- if (options.notify) {
61
- ctx.ui.notify(
62
- enabled ? `Plan mode enabled. Available tools: ${PLAN_MODE_TOOL_NAMES.join(", ")}` : "Plan mode disabled. Full access restored."
63
- );
64
- }
62
+ applyPlanModeState(planModeEnabled, true);
63
+ ctx.ui.notify(
64
+ planModeEnabled ? `Plan mode enabled. Available tools: ${ctx.getActiveTools().join(", ")}` : "Plan mode disabled. Full access restored."
65
+ );
65
66
  updateStatus();
66
67
  }
67
68
  ctx.registerCommand({
68
69
  path: capability.commands?.[0]?.path ?? ["tools", "plan"],
69
70
  description: capability.commands?.[0]?.description ?? "Toggle plan mode (read-only exploration)",
70
- handler: async (_ctx) => {
71
+ handler: async () => {
71
72
  togglePlanMode();
72
73
  }
73
74
  });
@@ -91,78 +92,75 @@ Command: ${command}`,
91
92
  });
92
93
  ctx.on("agent:start", async () => {
93
94
  const persisted = readPersistedPlanMode();
94
- if (persisted !== planModeEnabled) {
95
- applyPlanModeState(persisted);
96
- }
97
- if (planModeEnabled) {
98
- ctx.log("[plan-mode] Injecting plan mode context");
99
- }
95
+ applyPlanModeState(persisted);
96
+ writeExecutionState(readExecutionState());
100
97
  });
101
98
  ctx.on("session:changed", async () => {
102
99
  const enabled = readPersistedPlanMode();
103
- applyPlanModeState(enabled, { forcePromptInjection: enabled });
100
+ applyPlanModeState(enabled, enabled);
101
+ writeExecutionState(readExecutionState());
104
102
  });
105
103
  ctx.on("turn:end", async (event) => {
106
- if (!executionMode || todoItems.length === 0) return;
104
+ const state = readExecutionState();
105
+ if (!executionMode || state.steps.length === 0) return;
107
106
  const message = event.message;
108
- if (message?.role === "assistant" && Array.isArray(message.content)) {
109
- const text = message.content.filter((c) => c.type === "text").map((c) => c.text).join("\n");
110
- if (markCompletedPlanSteps(text, todoItems) > 0) {
111
- updateStatus();
112
- }
113
- }
107
+ if (message?.role !== "assistant" || !Array.isArray(message.content)) return;
108
+ const text = message.content.filter((item) => item.type === "text").map((item) => item.text).join("\n");
109
+ const todoItems = toPlanTodoItems(state);
110
+ if (markCompletedPlanSteps(text, todoItems) <= 0) return;
111
+ const nextState = createExecutionStateFromPlan(todoItems);
112
+ writeExecutionState(nextState);
113
+ updateStatus();
114
114
  });
115
115
  ctx.on("agent:end", async (event) => {
116
- if (executionMode && todoItems.length > 0) {
117
- if (todoItems.every((t) => t.completed)) {
118
- const completedList = todoItems.map((t) => `\u2713 ${t.text}`).join("\n");
116
+ const state = readExecutionState();
117
+ if (executionMode && state.steps.length > 0) {
118
+ if (state.steps.every((step) => step.status === "completed")) {
119
+ const completedList = state.steps.map((step) => `\u2713 ${step.title}`).join("\n");
119
120
  ctx.ui.notify(`**Plan Complete!** \u2713
120
121
 
121
122
  ${completedList}`, "info");
122
123
  executionMode = false;
123
- todoItems = [];
124
- ctx.setActiveTools(getNormalModeTools());
124
+ writeExecutionState(null);
125
125
  }
126
126
  return;
127
127
  }
128
128
  if (!planModeEnabled || !ctx.hasUI) return;
129
129
  const messages = event.messages || [];
130
130
  const lastAssistant = [...messages].reverse().find(
131
- (m) => m.role === "assistant" && Array.isArray(m.content)
131
+ (message) => message.role === "assistant" && Array.isArray(message.content)
132
132
  );
133
- if (lastAssistant) {
134
- const text = lastAssistant.content.filter((c) => c.type === "text").map((c) => c.text).join("\n");
135
- const extracted = extractPlanTodoItems(text);
136
- if (extracted.length > 0) {
137
- todoItems = extracted;
138
- }
139
- }
140
- if (todoItems.length > 0) {
141
- const todoListText = todoItems.map((t) => `${t.step}. \u2610 ${t.text}`).join("\n");
142
- ctx.ui.notify(`**Plan Steps (${todoItems.length}):**
133
+ if (!lastAssistant) return;
134
+ const text = lastAssistant.content.filter((item) => item.type === "text").map((item) => item.text).join("\n");
135
+ const extracted = extractPlanTodoItems(text);
136
+ if (extracted.length === 0) return;
137
+ const extractedState = writeExecutionState(createExecutionStateFromPlan(extracted));
138
+ const todoListText = extractedState.steps.map((step) => `${step.id}. \u2610 ${step.title}`).join("\n");
139
+ ctx.ui.notify(`**Plan Steps (${extractedState.steps.length}):**
143
140
  ${todoListText}`, "info");
144
- const choice = await ctx.ui.select("Plan mode - what next?", [
145
- todoItems.length > 0 ? "Execute the plan (track progress)" : "Execute the plan",
146
- "Stay in plan mode",
147
- "Refine the plan"
148
- ]);
149
- if (choice?.startsWith("Execute")) {
150
- planModeEnabled = false;
151
- executionMode = todoItems.length > 0;
152
- ctx.setSessionMetadata(SESSION_METADATA_KEY, false);
153
- ctx.setPlanMode(false);
154
- ctx.setActiveTools(getNormalModeTools());
155
- updateStatus();
156
- const execMessage = todoItems.length > 0 ? `Execute the plan. Start with: ${todoItems[0].text}. Mark completed steps with [DONE:n] in your response.` : "Execute the plan you just created.";
157
- ctx.sendUserMessage(execMessage);
158
- } else if (choice === "Refine the plan") {
159
- const refinement = await ctx.ui.editor("Refine the plan:", "");
160
- if (refinement?.trim()) {
161
- ctx.sendUserMessage(refinement.trim());
162
- }
141
+ const choice = await ctx.ui.select("Plan mode - what next?", [
142
+ "Execute the plan (track progress)",
143
+ "Stay in plan mode",
144
+ "Refine the plan"
145
+ ]);
146
+ if (choice?.startsWith("Execute")) {
147
+ planModeEnabled = false;
148
+ executionMode = extractedState.steps.length > 0;
149
+ ctx.setSessionMetadata(SESSION_METADATA_KEY, false);
150
+ ctx.setPlanMode(false);
151
+ updateStatus();
152
+ const execMessage = extractedState.steps.length > 0 ? `Execute the plan. Start with: ${extractedState.steps[0].title}. Mark completed steps with [DONE:n] in your response.` : "Execute the plan you just created.";
153
+ ctx.sendUserMessage(execMessage);
154
+ return;
155
+ }
156
+ if (choice === "Refine the plan") {
157
+ const refinement = await ctx.ui.editor("Refine the plan:", "");
158
+ if (refinement?.trim()) {
159
+ ctx.sendUserMessage(refinement.trim());
163
160
  }
164
161
  }
165
162
  });
163
+ ctx.log("Plan mode extension loaded");
166
164
  }
167
165
  export {
168
166
  planModeExtension as default
@@ -1,13 +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-JYBXCEJJ.js";
4
+ } from "../../../chunks/chunk-ZRONUKTW.js";
5
5
  import {
6
6
  createSharedFileSystemTools,
7
7
  createSubagentCapability
8
- } from "../../../chunks/chunk-TBJ25UWB.js";
9
- import "../../../chunks/chunk-MWFBYJOI.js";
10
- import "../../../chunks/chunk-RID3574D.js";
8
+ } from "../../../chunks/chunk-6WD2NFIC.js";
9
+ import "../../../chunks/chunk-A5JSJAPK.js";
11
10
  import "../../../chunks/chunk-TG2EQLX2.js";
12
11
 
13
12
  // builtin/extensions/subagent/index.ts
@@ -34,7 +33,7 @@ function subagentExtension(ctx) {
34
33
  let model = ctx.model;
35
34
  if (!model) {
36
35
  model = {
37
- id: process.env.PIE_MODEL_ID || "kimi-cn/kimi-k2.5",
36
+ id: process.env.PIE_MODEL_ID || "kimi-api/kimi-k2.5",
38
37
  name: "Default Model",
39
38
  reasoning: false,
40
39
  input: ["text"],
@@ -56,9 +55,20 @@ function subagentExtension(ctx) {
56
55
  log: (message) => ctx.log(message),
57
56
  notify: ctx.hasUI ? (message, type) => ctx.ui.notify(message, type) : void 0,
58
57
  debugLog,
58
+ resolveModelClass: (modelClass) => ctx.resolveModelClass?.(modelClass),
59
59
  createRuntimeTools: () => {
60
- const skillsDir = path.join(os.homedir(), ".pie", "skills");
61
- const fsOptions = ctx.yoloMode ? { allowlistedDirs: ["/"] } : { allowlistedDirs: [skillsDir] };
60
+ const parentRuntimeTools = ctx.getRuntimeTools?.();
61
+ if (Array.isArray(parentRuntimeTools) && parentRuntimeTools.length > 0) {
62
+ return parentRuntimeTools.filter((tool) => tool?.name !== "spawn_subagents_parallel");
63
+ }
64
+ const configDir = path.join(os.homedir(), ".pie");
65
+ const fsOptions = ctx.yoloMode ? { allowlistedDirs: ["/"] } : {
66
+ accessRoots: [
67
+ ctx.cwd,
68
+ configDir,
69
+ ...skills.map((skill) => skill.baseDir).filter((entry) => entry && entry.length > 0)
70
+ ]
71
+ };
62
72
  const fsTools = createSharedFileSystemTools(ctx.cwd, fsOptions);
63
73
  const cliHostCapabilities = createCliHostCapabilities(ctx.cwd);
64
74
  return [...fsTools, ...cliHostCapabilities.tools];
@@ -1,30 +1,37 @@
1
1
  import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
2
2
  import {
3
3
  ManageTodoListParamsSchema,
4
+ buildExecutionReminder,
5
+ createExecutionStateFromTodos,
6
+ createTodoWidgetView,
4
7
  executeManageTodoList,
5
- restoreTodosFromMessages
6
- } from "../../../chunks/chunk-TBJ25UWB.js";
7
- import "../../../chunks/chunk-MWFBYJOI.js";
8
- import "../../../chunks/chunk-RID3574D.js";
8
+ executionStateToTodos,
9
+ restoreExecutionState
10
+ } from "../../../chunks/chunk-6WD2NFIC.js";
11
+ import "../../../chunks/chunk-A5JSJAPK.js";
9
12
  import "../../../chunks/chunk-TG2EQLX2.js";
10
13
 
11
14
  // builtin/extensions/todo/index.ts
12
- var TOOL_DESCRIPTION = `Manage a structured todo list to track progress and plan tasks throughout your coding session.
13
-
14
- Use this tool for complex multi-step work, especially when:
15
- - The task needs planning or progress tracking
16
- - The user provided multiple requests
17
- - You need to break a larger change into actionable steps
18
- - You are about to start or finish a tracked step
19
-
20
- Workflow:
21
- 1. Write the full todo list with clear action items
22
- 2. Mark the current item as in-progress before starting it
23
- 3. Complete the work for that item
24
- 4. Mark it completed immediately
25
- 5. Continue until all items are done
26
-
27
- Always send the full list on write. Partial updates are not supported.`;
15
+ var EXECUTION_METADATA_KEY = "executionState";
16
+ var TOOL_DESCRIPTION = `Manage a session-local todo list. Use when the user explicitly asks to use the todo tool, create/manage todos, track tasks, follow a todo list, show tasks, or mark a task done.
17
+ NEVER use for: internal planning, tracking your own progress, remembering subtasks, or creating checklists for yourself.
18
+ Use action=create with items to create a list; the tool starts item 1 automatically. Use action=complete_current after finishing the current item; the tool advances to the next item or clears the list after the final item.
19
+ When a todo list exists, keep executing from the current in-progress item until it is cleared. If the work cannot continue, explain the failure and use action=clear with a reason.
20
+ Actions: create, read, complete_current, clear.`;
21
+ function persistExecutionState(ctx, state) {
22
+ const nextState = state ?? restoreExecutionState(null);
23
+ ctx.setSessionMetadata(EXECUTION_METADATA_KEY, nextState);
24
+ ctx.setExecutionState(nextState);
25
+ ctx.setExecutionReminder(buildExecutionReminder(nextState) ?? void 0);
26
+ return nextState;
27
+ }
28
+ function notifyWidget(ctx, state) {
29
+ if (!ctx.hasUI || !ctx.ui) return;
30
+ const steps = createTodoWidgetView(state);
31
+ if (steps.length === 0) return;
32
+ const completed = steps.filter((step) => step.status === "completed").length;
33
+ ctx.ui.notify(`Todo tracking: ${completed}/${steps.length} completed`, "info");
34
+ }
28
35
  function todoExtension(ctx) {
29
36
  ctx.registerTool({
30
37
  name: "manage_todo_list",
@@ -32,8 +39,30 @@ function todoExtension(ctx) {
32
39
  description: TOOL_DESCRIPTION,
33
40
  parameters: ManageTodoListParamsSchema,
34
41
  async execute(args) {
35
- const currentTodos = restoreTodosFromMessages(ctx.getMessages());
36
- return executeManageTodoList(args, currentTodos).result;
42
+ const currentTodos = executionStateToTodos(ctx.getExecutionState());
43
+ const execution = executeManageTodoList(args, currentTodos);
44
+ const nextState = createExecutionStateFromTodos(execution.nextTodos, "todo", "user_todo");
45
+ persistExecutionState(ctx, nextState);
46
+ notifyWidget(ctx, nextState);
47
+ return execution.result;
48
+ }
49
+ });
50
+ ctx.on("session:changed", async () => {
51
+ const state = restoreExecutionState(ctx.getSessionMetadata()?.[EXECUTION_METADATA_KEY]);
52
+ persistExecutionState(ctx, state);
53
+ });
54
+ ctx.on("tool:execution:end", async (event) => {
55
+ if (event.toolName !== "manage_todo_list") return;
56
+ const details = event.result?.details;
57
+ if (!details?.todos) return;
58
+ const state = createExecutionStateFromTodos(details.todos, "todo", "user_todo");
59
+ persistExecutionState(ctx, state);
60
+ });
61
+ ctx.on("agent:end", async () => {
62
+ const state = ctx.getExecutionState();
63
+ if (state.mode !== "todo") return;
64
+ if (state.lifecycle === "completed") {
65
+ persistExecutionState(ctx, null);
37
66
  }
38
67
  });
39
68
  ctx.log("Builtin todo extension ready");
@@ -1,47 +1,5 @@
1
1
  # Changelog
2
2
 
3
- All notable changes to this project will be documented in this file.
3
+ ## 2.0.0
4
4
 
5
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
-
8
- ## [1.1.0] - 2025-03-10
9
-
10
- ### Fixed
11
-
12
- - **browser-eval.js**: Fixed complex JavaScript code execution
13
- - Support for "const", "let", "var" keywords
14
- - Support for multi-line code and conditionals (if/else, for, while)
15
- - Support for function declarations and calls
16
- - Automatic expression return value handling
17
- - Fixed AsyncFunction wrapping syntax errors
18
-
19
- ### Improved
20
-
21
- - Improved code execution logic using eval() instead of complex AsyncFunction wrapping
22
- - Support for more complex browser automation scenarios (e.g., MagicShell 10-round dialog testing)
23
-
24
- ## [1.0.0] - 2025-03-09
25
-
26
- ### Initial Release
27
-
28
- - Basic browser automation toolset
29
- - Chrome DevTools Protocol support
30
- - Included tools:
31
- - browser-start.js: Start Chrome
32
- - browser-nav.js: Page navigation
33
- - browser-eval.js: JavaScript execution (basic)
34
- - browser-screenshot.js: Screenshots
35
- - browser-cookies.js: Cookie management
36
- - browser-content.js: Content extraction
37
- - browser-hn-scraper.js: HN scraper example
38
- - browser-pick.js: Interactive element picker
39
-
40
- ### Dependencies
41
-
42
- - puppeteer: ^24.31.0
43
- - puppeteer-core: ^23.11.1
44
- - @mozilla/readability: ^0.6.0
45
- - cheerio: ^1.1.2
46
- - jsdom: ^27.0.1
47
- - turndown: ^7.2.2
5
+ - Replaced Pie's custom Chrome DevTools Protocol scripts with the packaged Microsoft Playwright CLI wrapper.
@@ -1,106 +1,17 @@
1
1
  # Browser Tools
2
2
 
3
- Browser automation tools based on Chrome DevTools Protocol (CDP) for collaborative site exploration and testing.
3
+ Pie's browser-tools skill is backed by Microsoft Playwright CLI through `playwright-cli.js`.
4
4
 
5
- ## Tools
6
-
7
- | Tool | Function | Usage |
8
- |------|----------|-------|
9
- | browser-start.js | Start Chrome with remote debugging | node browser-start.js |
10
- | browser-nav.js | Navigate to URL | node browser-nav.js https://example.com |
11
- | browser-eval.js | Execute JavaScript in browser | node browser-eval.js "document.title" |
12
- | browser-screenshot.js | Take screenshot | node browser-screenshot.js |
13
- | browser-cookies.js | Manage cookies | node browser-cookies.js |
14
- | browser-content.js | Extract page content | node browser-content.js |
15
- | browser-hn-scraper.js | HN scraper example | node browser-hn-scraper.js |
16
- | browser-pick.js | Interactive element picker | node browser-pick.js |
17
-
18
- ## Quick Start
19
-
20
- ### 1. Install dependencies
21
-
22
- ```bash
23
- npm install
24
- ```
25
-
26
- ### 2. Start Chrome
27
-
28
- ```bash
29
- node browser-start.js
30
- ```
31
-
32
- This starts Chrome with remote debugging port (default: 9222).
33
-
34
- ### 3. Use tools
5
+ Use:
35
6
 
36
7
  ```bash
37
- # Navigate to website
38
- node browser-nav.js https://www.baidu.com
39
-
40
- # Execute JavaScript
41
- node browser-eval.js "document.title"
42
-
43
- # Complex code execution (supports const/let/var/if)
44
- node browser-eval.js "
45
- const links = document.querySelectorAll("a");
46
- const count = links.length;
47
- count;
48
- "
49
-
50
- # Take screenshot
51
- node browser-screenshot.js
8
+ node playwright-cli.js --help
9
+ node playwright-cli.js open https://example.com
10
+ node playwright-cli.js snapshot
11
+ node playwright-cli.js screenshot
12
+ node playwright-cli.js console
13
+ node playwright-cli.js network
14
+ node playwright-cli.js close
52
15
  ```
53
16
 
54
- ## browser-eval.js Advanced Usage
55
-
56
- ### Simple expressions
57
-
58
- ```bash
59
- node browser-eval.js "1 + 1" # Output: 2
60
- node browser-eval.js "document.title" # Output: Page title
61
- ```
62
-
63
- ### Complex code
64
-
65
- Supports multi-line code, const/let/var, conditionals:
66
-
67
- ```bash
68
- node browser-eval.js "
69
- const buttons = document.querySelectorAll("button");
70
- const count = buttons.length;
71
- count;
72
- "
73
-
74
- node browser-eval.js "
75
- let sum = 0;
76
- for (let i = 1; i <= 5; i++) {
77
- sum += i;
78
- }
79
- sum;
80
- "
81
- ```
82
-
83
- ## Tech Stack
84
-
85
- - **Puppeteer Core**: Connect and control Chrome browser
86
- - **Chrome DevTools Protocol**: Browser remote debugging protocol
87
- - **ES Modules**: Native ES module system
88
-
89
- ## Dependencies
90
-
91
- - puppeteer: ^24.31.0
92
- - puppeteer-core: ^23.11.1
93
-
94
- ## Notes
95
-
96
- 1. Must run browser-start.js first to start Chrome
97
- 2. Chrome must be started in remote debugging mode (default port 9222)
98
- 3. browser-eval.js uses eval() to execute code, ensure input is trusted
99
-
100
- ## Author
101
-
102
- Mario Zechner
103
-
104
- ## License
105
-
106
- MIT
17
+ Dependencies are provided by `@cydm/pie`; do not run `npm install` inside this skill directory.