@cydm/pie 1.0.23 → 1.0.24
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.
- package/README.md +30 -2
- package/dist/builtin/extensions/ask-user/index.js +4 -3
- package/dist/builtin/extensions/changelog/index.js +65 -65
- package/dist/builtin/extensions/init/index.js +33 -33
- package/dist/builtin/extensions/kimi-attachments/index.js +1 -1
- package/dist/builtin/extensions/plan-mode/index.js +34 -5
- package/dist/builtin/extensions/subagent/index.js +5 -4
- package/dist/builtin/extensions/todo/index.js +4 -3
- package/dist/builtin/skills/browser-tools/README.md +1 -1
- package/dist/builtin/skills/browser-tools/SKILL.md +3 -3
- package/dist/builtin/skills/browser-tools/playwright-cli.js +22 -1
- package/dist/chunks/{chunk-7ABSJC2D.js → chunk-HAAYC2N5.js} +41 -25
- package/dist/chunks/chunk-J4P2LP7K.js +3846 -0
- package/dist/chunks/chunk-QMIIW75M.js +95 -0
- package/dist/chunks/{chunk-4WU5VAX4.js → chunk-QYYRJ7JW.js} +53 -19
- package/dist/chunks/{chunk-PUZP2Q3F.js → chunk-X44YTB6R.js} +1 -1
- package/dist/chunks/{chunk-AFTBFF6J.js → chunk-XWNIIJ3X.js} +6239 -4060
- package/dist/chunks/{src-UCXJ4C6P.js → src-PENSDHBM.js} +2 -2
- package/dist/chunks/{test-stream-UKULOPZB.js → test-stream-PRUYMLXQ.js} +1 -1
- package/dist/cli.js +2310 -1303
- package/dist/session-preview-worker.js +159 -0
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ Pie is developed by [cydream](https://cydream.tech).
|
|
|
20
20
|
npm install -g @cydm/pie
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
Pie
|
|
23
|
+
Pie requires Node.js 20.19 or newer. Release builds are validated with npm's lockfile workflow (`npm ci`) so dependency resolution is reproducible.
|
|
24
24
|
|
|
25
25
|
## Quick Start
|
|
26
26
|
|
|
@@ -199,6 +199,7 @@ Pie uses a hierarchical slash-command menu. The current built-in commands includ
|
|
|
199
199
|
| `/skills/list` | List available skills |
|
|
200
200
|
| `/skills/use` | Use a skill |
|
|
201
201
|
| `/skills/reload` | Reload skills from disk |
|
|
202
|
+
| `/extensions` | List extensions and toggle enable/disable |
|
|
202
203
|
| `/tools/subagent` | Spawn a subagent for a task |
|
|
203
204
|
| `/debugs/cache-test` | Run provider cache diagnostics with a dedicated 2-request probe |
|
|
204
205
|
| `/debugs/context` | Append a context summary to `~/.pie/logs/pie-cli.log` |
|
|
@@ -228,6 +229,33 @@ Pie supports Markdown-based skills and built-in extensions.
|
|
|
228
229
|
|
|
229
230
|
That is part of what makes Pie embeddable: the CLI is only one interface on top of a broader agent toolkit.
|
|
230
231
|
|
|
232
|
+
## Extension Sources, Priority, And Toggles
|
|
233
|
+
|
|
234
|
+
Extensions are discovered from four sources in ascending priority (later sources shadow earlier ones by stable extension identity):
|
|
235
|
+
|
|
236
|
+
1. `builtin` — shipped with the CLI (`ask-user`, `todo`, `plan-mode`, `subagent`, `init`, `changelog`, `deploy`, `files`, attachment handlers)
|
|
237
|
+
2. `global` — `~/.pie/extensions/`
|
|
238
|
+
3. `project` — `./.pie/extensions/`
|
|
239
|
+
4. `configured` — repeated `--extension-path <dir>` flags
|
|
240
|
+
|
|
241
|
+
Every extension is enabled by default. Toggles are sparse overrides stored in settings and applied by extension identity across all sources:
|
|
242
|
+
|
|
243
|
+
- Interactive: `/extensions` opens the user-default toggle menu; `/extensions --project` edits project overrides. `/extensions list|enable|disable ...` remains available for command-driven use.
|
|
244
|
+
- Scripts and third-party UIs: `pie extensions list [--json]`, `pie extensions enable|disable <name> [--project|--user]`
|
|
245
|
+
- Process flags: `--no-builtin-extensions` (skip built-ins) and `--no-extensions` (skip all discovered sources; `--extension-path` still loads)
|
|
246
|
+
|
|
247
|
+
Example override in `~/.pie/settings.json` (or `./.pie/settings.json` for project scope, which wins per identity):
|
|
248
|
+
|
|
249
|
+
```jsonc
|
|
250
|
+
{
|
|
251
|
+
"extensions": {
|
|
252
|
+
"plan-mode": { "enabled": false }
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
The full contract (identity rules, schema, host integration) lives in [`docs/extensions-enablement.md`](../../docs/extensions-enablement.md).
|
|
258
|
+
|
|
231
259
|
## Browser Tools
|
|
232
260
|
|
|
233
261
|
The built-in `browser-tools` skill uses Microsoft's Playwright CLI for visible browser automation. Its runtime dependencies ship with the CLI; do not run `npm install` inside the skill directory.
|
|
@@ -239,7 +267,7 @@ node <resolvedPath for browser-tools/playwright-cli.js> open https://example.com
|
|
|
239
267
|
node <resolvedPath for browser-tools/playwright-cli.js> snapshot
|
|
240
268
|
node <resolvedPath for browser-tools/playwright-cli.js> screenshot
|
|
241
269
|
node <resolvedPath for browser-tools/playwright-cli.js> console
|
|
242
|
-
node <resolvedPath for browser-tools/playwright-cli.js>
|
|
270
|
+
node <resolvedPath for browser-tools/playwright-cli.js> requests
|
|
243
271
|
```
|
|
244
272
|
|
|
245
273
|
If Playwright's Chromium browser is not installed, run:
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
createAskUserCapability
|
|
4
|
-
} from "../../../chunks/chunk-
|
|
5
|
-
import "../../../chunks/chunk-
|
|
6
|
-
import "../../../chunks/chunk-
|
|
4
|
+
} from "../../../chunks/chunk-XWNIIJ3X.js";
|
|
5
|
+
import "../../../chunks/chunk-X44YTB6R.js";
|
|
6
|
+
import "../../../chunks/chunk-J4P2LP7K.js";
|
|
7
|
+
import "../../../chunks/chunk-HAAYC2N5.js";
|
|
7
8
|
import "../../../chunks/chunk-TG2EQLX2.js";
|
|
8
9
|
|
|
9
10
|
// builtin/extensions/ask-user/index.ts
|
|
@@ -65,54 +65,54 @@ function changelogExtension(ctx) {
|
|
|
65
65
|
if (!commits2) {
|
|
66
66
|
return "No git history found. Cannot check for missing entries.";
|
|
67
67
|
}
|
|
68
|
-
return `\u{1F50D} CHANGELOG
|
|
68
|
+
return `\u{1F50D} Check for CHANGELOG gaps
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
Analyze the following information for missing CHANGELOG entries:
|
|
71
71
|
|
|
72
|
-
##
|
|
73
|
-
${commits2 || "(
|
|
72
|
+
## Recent Git commits
|
|
73
|
+
${commits2 || "(unavailable)"}
|
|
74
74
|
|
|
75
|
-
##
|
|
76
|
-
${changedFiles2 || "(
|
|
75
|
+
## Changed files
|
|
76
|
+
${changedFiles2 || "(unavailable)"}
|
|
77
77
|
|
|
78
|
-
##
|
|
79
|
-
${changelog2 ? changelog2.slice(0, 1500) + "\n..." : "(
|
|
78
|
+
## Current CHANGELOG
|
|
79
|
+
${changelog2 ? changelog2.slice(0, 1500) + "\n..." : "(file does not exist)"}
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
1.
|
|
83
|
-
2.
|
|
84
|
-
3.
|
|
81
|
+
Compare the sources and report:
|
|
82
|
+
1. Which important committed changes are not recorded in the CHANGELOG?
|
|
83
|
+
2. Does the current [Unreleased] section accurately cover recent work?
|
|
84
|
+
3. Which missing entries should be added under Added, Changed, or Fixed?
|
|
85
85
|
|
|
86
|
-
|
|
86
|
+
Return the analysis report only. Do not modify files.`;
|
|
87
87
|
}
|
|
88
88
|
if (args?.startsWith("add ")) {
|
|
89
89
|
const description = args.slice(4).trim();
|
|
90
90
|
const existingChangelog = await readChangelog(ctx2.cwd);
|
|
91
|
-
ctx2.ui.notify(
|
|
92
|
-
return
|
|
91
|
+
ctx2.ui.notify("\u{1F4DD} Generating a changelog entry...", "info");
|
|
92
|
+
return `Convert the following description into a professional CHANGELOG entry:
|
|
93
93
|
|
|
94
|
-
|
|
94
|
+
Description: "${description}"
|
|
95
95
|
|
|
96
96
|
${existingChangelog ? `
|
|
97
|
-
|
|
97
|
+
Follow the existing format:
|
|
98
98
|
\`\`\`
|
|
99
99
|
${existingChangelog.slice(0, 800)}
|
|
100
100
|
...
|
|
101
101
|
\`\`\`` : ""}
|
|
102
102
|
|
|
103
|
-
|
|
104
|
-
1.
|
|
105
|
-
2.
|
|
106
|
-
3.
|
|
103
|
+
Requirements:
|
|
104
|
+
1. Choose the appropriate category: **Added** / **Changed** / **Fixed** / **Removed** / **Deprecated** / **Security**.
|
|
105
|
+
2. Use present tense and concise wording while preserving important technical details.
|
|
106
|
+
3. Include relevant file paths when useful.
|
|
107
107
|
|
|
108
|
-
|
|
109
|
-
- **Added**:
|
|
110
|
-
- **Fixed**:
|
|
108
|
+
Examples:
|
|
109
|
+
- **Added**: Add JWT token validation to the authentication module (src/auth/).
|
|
110
|
+
- **Fixed**: Prevent a memory leak during large-file processing.
|
|
111
111
|
|
|
112
|
-
|
|
113
|
-
-
|
|
114
|
-
-
|
|
115
|
-
-
|
|
112
|
+
Use the write tool to update CHANGELOG.md:
|
|
113
|
+
- Create a standard file with an ## [Unreleased] section if it does not exist.
|
|
114
|
+
- Add the new entry to the appropriate subsection under [Unreleased].
|
|
115
|
+
- Preserve existing entries.`;
|
|
116
116
|
}
|
|
117
117
|
if (args?.startsWith("release")) {
|
|
118
118
|
const versionHint = args.slice(7).trim();
|
|
@@ -121,30 +121,30 @@ ${existingChangelog.slice(0, 800)}
|
|
|
121
121
|
return "No CHANGELOG.md found. Create one first with /changelog";
|
|
122
122
|
}
|
|
123
123
|
ctx2.ui.notify(`\u{1F4DD} Preparing release ${versionHint || "..."}`, "info");
|
|
124
|
-
return
|
|
124
|
+
return `Turn the [Unreleased] section into a new version release.
|
|
125
125
|
|
|
126
|
-
|
|
126
|
+
Current CHANGELOG:
|
|
127
127
|
\`\`\`
|
|
128
128
|
${existingChangelog.slice(0, 1500)}
|
|
129
129
|
...
|
|
130
130
|
\`\`\`
|
|
131
131
|
|
|
132
|
-
|
|
132
|
+
Version hint: ${versionHint || "infer patch, minor, or major from the changes"}
|
|
133
133
|
|
|
134
|
-
Semantic Versioning
|
|
134
|
+
Semantic Versioning rules:
|
|
135
135
|
- **patch** (0.0.x): Bug fixes only
|
|
136
136
|
- **minor** (0.x.0): New features, backward compatible
|
|
137
137
|
- **major** (x.0.0): Breaking changes
|
|
138
138
|
|
|
139
|
-
|
|
140
|
-
1.
|
|
141
|
-
2.
|
|
142
|
-
3.
|
|
143
|
-
4.
|
|
144
|
-
5.
|
|
145
|
-
6.
|
|
139
|
+
Tasks:
|
|
140
|
+
1. Analyze the change types in [Unreleased].
|
|
141
|
+
2. Choose the appropriate version when the user did not specify one.
|
|
142
|
+
3. Create a version section such as ## [1.2.0] - 2024-03-06.
|
|
143
|
+
4. Move the [Unreleased] entries into the new version section.
|
|
144
|
+
5. Leave an empty [Unreleased] section.
|
|
145
|
+
6. Update version comparison links at the bottom when needed.
|
|
146
146
|
|
|
147
|
-
|
|
147
|
+
Use the write tool to update CHANGELOG.md.`;
|
|
148
148
|
}
|
|
149
149
|
const commits = getRecentCommits(ctx2.cwd, 15);
|
|
150
150
|
const changelog = await readChangelog(ctx2.cwd);
|
|
@@ -152,40 +152,40 @@ Semantic Versioning \u89C4\u5219\uFF1A
|
|
|
152
152
|
if (!commits && !changelog) {
|
|
153
153
|
return "No git history or CHANGELOG.md found. Initialize with: /changelog add <description>";
|
|
154
154
|
}
|
|
155
|
-
ctx2.ui.notify("\u{1F50D}
|
|
156
|
-
return `\u{1F4DD}
|
|
155
|
+
ctx2.ui.notify("\u{1F50D} Analyzing changes and checking for gaps...", "info");
|
|
156
|
+
return `\u{1F4DD} Smart CHANGELOG update
|
|
157
157
|
|
|
158
|
-
|
|
158
|
+
Analyze the following information, identify missing CHANGELOG entries, and add them when appropriate:
|
|
159
159
|
|
|
160
|
-
##
|
|
161
|
-
${commits || "(
|
|
160
|
+
## Recent Git commits
|
|
161
|
+
${commits || "(git history unavailable)"}
|
|
162
162
|
|
|
163
|
-
##
|
|
164
|
-
${changedFiles || "(
|
|
163
|
+
## Recently changed files
|
|
164
|
+
${changedFiles || "(unavailable)"}
|
|
165
165
|
|
|
166
|
-
##
|
|
167
|
-
${changelog ? "\n```\n" + changelog.slice(0, 2e3) + "\n...\n```" : "(
|
|
166
|
+
## Current CHANGELOG.md
|
|
167
|
+
${changelog ? "\n```\n" + changelog.slice(0, 2e3) + "\n...\n```" : "(file does not exist and must be created)"}
|
|
168
168
|
|
|
169
|
-
##
|
|
169
|
+
## Tasks
|
|
170
170
|
|
|
171
|
-
1.
|
|
172
|
-
-
|
|
173
|
-
-
|
|
174
|
-
-
|
|
171
|
+
1. **Compare sources**:
|
|
172
|
+
- Identify important changes in Git commits.
|
|
173
|
+
- Compare them with the CHANGELOG [Unreleased] section.
|
|
174
|
+
- Identify missing entries.
|
|
175
175
|
|
|
176
|
-
2.
|
|
177
|
-
-
|
|
178
|
-
-
|
|
179
|
-
-
|
|
176
|
+
2. **Add missing entries when needed**:
|
|
177
|
+
- Write a professional entry for each missing change.
|
|
178
|
+
- Classify it under **Added**, **Changed**, **Fixed**, or **Removed**.
|
|
179
|
+
- Include useful technical details and file paths.
|
|
180
180
|
|
|
181
|
-
3.
|
|
182
|
-
-
|
|
183
|
-
-
|
|
184
|
-
-
|
|
181
|
+
3. **Update the file**:
|
|
182
|
+
- Use the write tool to update CHANGELOG.md.
|
|
183
|
+
- Create a standard CHANGELOG if it does not exist.
|
|
184
|
+
- Add only missing entries and preserve existing content.
|
|
185
185
|
|
|
186
|
-
4.
|
|
187
|
-
-
|
|
188
|
-
-
|
|
186
|
+
4. **Report the result**:
|
|
187
|
+
- List the entries that were added.
|
|
188
|
+
- Note any changes whose inclusion is uncertain.`;
|
|
189
189
|
}
|
|
190
190
|
});
|
|
191
191
|
ctx.log("Changelog extension ready");
|
|
@@ -28,48 +28,48 @@ function buildResearchPrompt(params) {
|
|
|
28
28
|
const { isUpdate, existingContent, userIntent, cwd, projectRoot, agentsPath } = params;
|
|
29
29
|
if (isUpdate && existingContent) {
|
|
30
30
|
const truncatedContent = existingContent.length > 4e3 ? existingContent.slice(0, 4e3) + "\n... (truncated)" : existingContent;
|
|
31
|
-
return `\u{1F4DD}
|
|
31
|
+
return `\u{1F4DD} Update the root AGENTS.md project context
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
Target file: ${agentsPath}
|
|
34
|
+
Project root: ${projectRoot}
|
|
35
|
+
Current working directory: ${cwd}
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
Current root AGENTS.md content:
|
|
38
38
|
\`\`\`
|
|
39
39
|
${truncatedContent}
|
|
40
40
|
\`\`\`
|
|
41
41
|
|
|
42
|
-
${userIntent ? `\u{1F4CC}
|
|
42
|
+
${userIntent ? `\u{1F4CC} User update intent: ${userIntent}
|
|
43
43
|
|
|
44
|
-
` : ""}
|
|
44
|
+
` : ""}Research the project again and update the root AGENTS.md:
|
|
45
45
|
|
|
46
|
-
1.
|
|
47
|
-
2.
|
|
48
|
-
3. Repo Map
|
|
49
|
-
4.
|
|
50
|
-
5.
|
|
46
|
+
1. Keep AGENTS.md as a progressive-disclosure index, not a long project encyclopedia.
|
|
47
|
+
2. Preserve concise root instructions and maintain the Repo Map.
|
|
48
|
+
3. Give every important Repo Map directory a desc explaining when to read it or its related documentation.
|
|
49
|
+
4. Include only stable rules, directory routing, verification gates, and generated-artifact rules.
|
|
50
|
+
5. Remove obsolete content and large sections that duplicate README or ARCHITECTURE.
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
CLI
|
|
52
|
+
Use the write_file tool to update: ${agentsPath}
|
|
53
|
+
CLI file tools already use the project root as their access boundary; do not pass an additional root argument.`;
|
|
54
54
|
}
|
|
55
|
-
return `\u{1F50D}
|
|
55
|
+
return `\u{1F50D} Initialize the root AGENTS.md project context
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
Target file: ${agentsPath}
|
|
58
|
+
Project root: ${projectRoot}
|
|
59
|
+
Current working directory: ${cwd}
|
|
60
60
|
|
|
61
|
-
${userIntent ? `\u{1F4CC}
|
|
61
|
+
${userIntent ? `\u{1F4CC} User research intent: ${userIntent}
|
|
62
62
|
|
|
63
|
-
` : ""}
|
|
63
|
+
` : ""}Research the current project and create the root \`AGENTS.md\`. It should be a progressive disclosure index that tells future agents which documentation to read on demand, rather than a one-time summary of the entire repository.
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
1.
|
|
67
|
-
2.
|
|
68
|
-
3.
|
|
69
|
-
4.
|
|
70
|
-
5.
|
|
65
|
+
Research tasks:
|
|
66
|
+
1. Identify the project type and technology stack by checking package.json, Cargo.toml, go.mod, requirements.txt, pyproject.toml, and similar files.
|
|
67
|
+
2. Explore the top-level directory structure and important package/product boundaries.
|
|
68
|
+
3. Read existing README, ARCHITECTURE, and docs/public-api material without duplicating it.
|
|
69
|
+
4. Identify generated-artifact rules, verification gates, code-layer boundaries, and high-risk change boundaries.
|
|
70
|
+
5. Produce concise, stable, maintainable directory-routing guidance.
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
Create an AGENTS.md with these sections:
|
|
73
73
|
|
|
74
74
|
\`\`\`
|
|
75
75
|
# AGENTS.md
|
|
@@ -91,8 +91,8 @@ Rules for AGENTS.md, generated bundles, and source-of-truth files.
|
|
|
91
91
|
Which focused tests/checks to run by touched area.
|
|
92
92
|
\`\`\`
|
|
93
93
|
|
|
94
|
-
|
|
95
|
-
CLI
|
|
94
|
+
Use the write_file tool to create: ${agentsPath}
|
|
95
|
+
CLI file tools already use the project root as their access boundary; do not pass an additional root argument.`;
|
|
96
96
|
}
|
|
97
97
|
async function initExtension(ctx) {
|
|
98
98
|
ctx.log("Init extension loaded");
|
|
@@ -110,7 +110,7 @@ async function initExtension(ctx) {
|
|
|
110
110
|
}
|
|
111
111
|
ctx.registerCommand({
|
|
112
112
|
path: ["tools", "init"],
|
|
113
|
-
description: "
|
|
113
|
+
description: "Research the project and create or update the root AGENTS.md context index",
|
|
114
114
|
handler: async (ctx2, args) => {
|
|
115
115
|
const existing = await loadExistingKnowledge(ctx2.cwd);
|
|
116
116
|
const existingContent = existing.content;
|
|
@@ -119,12 +119,12 @@ async function initExtension(ctx) {
|
|
|
119
119
|
cachedKnowledge = existingContent;
|
|
120
120
|
if (isUpdate) {
|
|
121
121
|
if (userIntent) {
|
|
122
|
-
ctx2.ui.notify(`\u{1F4DD}
|
|
122
|
+
ctx2.ui.notify(`\u{1F4DD} Updating project context (${userIntent})...`, "info");
|
|
123
123
|
} else {
|
|
124
|
-
ctx2.ui.notify("\u{1F4DD}
|
|
124
|
+
ctx2.ui.notify("\u{1F4DD} Updating root AGENTS.md...", "info");
|
|
125
125
|
}
|
|
126
126
|
} else {
|
|
127
|
-
ctx2.ui.notify("\u{1F50D}
|
|
127
|
+
ctx2.ui.notify("\u{1F50D} Initializing root AGENTS.md...", "info");
|
|
128
128
|
}
|
|
129
129
|
const researchPrompt = buildResearchPrompt({
|
|
130
130
|
isUpdate,
|
|
@@ -23,7 +23,7 @@ function kimiAttachmentsExtension(ctx) {
|
|
|
23
23
|
if (!fileId) {
|
|
24
24
|
return {
|
|
25
25
|
items: [{ type: "text", text: `[${attachment.id}]` }],
|
|
26
|
-
warnings: ["
|
|
26
|
+
warnings: ["The attachment has no fileId, so Kimi native references are unavailable."]
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
29
|
const modality = getModality(attachment.mimeType);
|
|
@@ -1,20 +1,26 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
|
+
BUILTIN_TOOL_CAPABILITY_METADATA,
|
|
4
|
+
DEFAULT_PLAN_MODE_TOOL_NAMES,
|
|
3
5
|
buildExecutionReminder,
|
|
4
6
|
createExecutionStateFromPlan,
|
|
5
7
|
createPlanCapability,
|
|
6
8
|
extractPlanTodoItems,
|
|
9
|
+
getToolCapabilityMetadata,
|
|
7
10
|
isPlanModeSafeCommand,
|
|
11
|
+
isToolAllowedInPlanMode,
|
|
8
12
|
markCompletedPlanSteps,
|
|
9
13
|
restoreExecutionState
|
|
10
|
-
} from "../../../chunks/chunk-
|
|
11
|
-
import "../../../chunks/chunk-
|
|
12
|
-
import "../../../chunks/chunk-
|
|
14
|
+
} from "../../../chunks/chunk-XWNIIJ3X.js";
|
|
15
|
+
import "../../../chunks/chunk-X44YTB6R.js";
|
|
16
|
+
import "../../../chunks/chunk-J4P2LP7K.js";
|
|
17
|
+
import "../../../chunks/chunk-HAAYC2N5.js";
|
|
13
18
|
import "../../../chunks/chunk-TG2EQLX2.js";
|
|
14
19
|
|
|
15
20
|
// builtin/extensions/plan-mode/index.ts
|
|
16
21
|
var SESSION_METADATA_KEY = "planModeEnabled";
|
|
17
22
|
var EXECUTION_METADATA_KEY = "executionState";
|
|
23
|
+
var PLAN_ALLOWED_BUILTIN_TOOLS = new Set(DEFAULT_PLAN_MODE_TOOL_NAMES);
|
|
18
24
|
var planModeEnabled = false;
|
|
19
25
|
var executionMode = false;
|
|
20
26
|
function toPlanTodoItems(state) {
|
|
@@ -80,9 +86,32 @@ function planModeExtension(ctx) {
|
|
|
80
86
|
}
|
|
81
87
|
});
|
|
82
88
|
ctx.on("tool:call", async (event) => {
|
|
83
|
-
if (!planModeEnabled
|
|
89
|
+
if (!planModeEnabled) return;
|
|
90
|
+
if (event.runtimeTool && event.runtimeTool.name !== event.toolName) {
|
|
91
|
+
ctx.ui.notify(`Plan mode: Tool blocked (runtime instance mismatch).
|
|
92
|
+
Tool: ${event.toolName}`, "error");
|
|
93
|
+
return { block: true, reason: `Plan mode: runtime tool instance does not match "${event.toolName}".` };
|
|
94
|
+
}
|
|
95
|
+
const runtimeTool = event.runtimeTool;
|
|
96
|
+
const builtinMetadata = BUILTIN_TOOL_CAPABILITY_METADATA[event.toolName];
|
|
97
|
+
const metadata = runtimeTool ? getToolCapabilityMetadata(runtimeTool) : builtinMetadata;
|
|
98
|
+
const allowed = runtimeTool ? isToolAllowedInPlanMode(runtimeTool) : builtinMetadata ? PLAN_ALLOWED_BUILTIN_TOOLS.has(event.toolName) : true;
|
|
99
|
+
if (!allowed) {
|
|
100
|
+
ctx.ui.notify(
|
|
101
|
+
`Plan mode: Tool blocked (read-only). Use /plan to disable plan mode first.
|
|
102
|
+
Tool: ${event.toolName}`,
|
|
103
|
+
"error"
|
|
104
|
+
);
|
|
105
|
+
return { block: true, reason: `Plan mode: tool "${event.toolName}" is not available in plan mode (read-only). Disable plan mode with /plan to use it.` };
|
|
106
|
+
}
|
|
107
|
+
if (!metadata?.executesShell) return;
|
|
84
108
|
const command = event.args?.command;
|
|
85
|
-
if (command
|
|
109
|
+
if (typeof command !== "string" || command.trim().length === 0) {
|
|
110
|
+
ctx.ui.notify(`Plan mode: Shell tool blocked (missing command).
|
|
111
|
+
Tool: ${event.toolName}`, "error");
|
|
112
|
+
return { block: true, reason: `Plan mode: shell tool "${event.toolName}" requires a non-empty string command.` };
|
|
113
|
+
}
|
|
114
|
+
if (!isPlanModeSafeCommand(command)) {
|
|
86
115
|
ctx.ui.notify(
|
|
87
116
|
`Plan mode: Command blocked (not allowlisted). Use /plan to disable plan mode first.
|
|
88
117
|
Command: ${command}`,
|
|
@@ -1,13 +1,14 @@
|
|
|
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-
|
|
4
|
+
} from "../../../chunks/chunk-QYYRJ7JW.js";
|
|
5
5
|
import {
|
|
6
6
|
createSharedFileSystemTools,
|
|
7
7
|
createSubagentCapability
|
|
8
|
-
} from "../../../chunks/chunk-
|
|
9
|
-
import "../../../chunks/chunk-
|
|
10
|
-
import "../../../chunks/chunk-
|
|
8
|
+
} from "../../../chunks/chunk-XWNIIJ3X.js";
|
|
9
|
+
import "../../../chunks/chunk-X44YTB6R.js";
|
|
10
|
+
import "../../../chunks/chunk-J4P2LP7K.js";
|
|
11
|
+
import "../../../chunks/chunk-HAAYC2N5.js";
|
|
11
12
|
import "../../../chunks/chunk-TG2EQLX2.js";
|
|
12
13
|
|
|
13
14
|
// builtin/extensions/subagent/index.ts
|
|
@@ -7,9 +7,10 @@ import {
|
|
|
7
7
|
executeManageTodoList,
|
|
8
8
|
executionStateToTodos,
|
|
9
9
|
restoreExecutionState
|
|
10
|
-
} from "../../../chunks/chunk-
|
|
11
|
-
import "../../../chunks/chunk-
|
|
12
|
-
import "../../../chunks/chunk-
|
|
10
|
+
} from "../../../chunks/chunk-XWNIIJ3X.js";
|
|
11
|
+
import "../../../chunks/chunk-X44YTB6R.js";
|
|
12
|
+
import "../../../chunks/chunk-J4P2LP7K.js";
|
|
13
|
+
import "../../../chunks/chunk-HAAYC2N5.js";
|
|
13
14
|
import "../../../chunks/chunk-TG2EQLX2.js";
|
|
14
15
|
|
|
15
16
|
// builtin/extensions/todo/index.ts
|
|
@@ -10,7 +10,7 @@ node playwright-cli.js open https://example.com
|
|
|
10
10
|
node playwright-cli.js snapshot
|
|
11
11
|
node playwright-cli.js screenshot
|
|
12
12
|
node playwright-cli.js console
|
|
13
|
-
node playwright-cli.js
|
|
13
|
+
node playwright-cli.js requests
|
|
14
14
|
node playwright-cli.js close
|
|
15
15
|
```
|
|
16
16
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: browser-tools
|
|
3
|
-
description: Interactive browser automation via Microsoft Playwright CLI. Use when you need to open pages, inspect DOM snapshots, click/type, capture screenshots, inspect console/
|
|
3
|
+
description: Interactive browser automation via Microsoft Playwright CLI. Use when you need to open pages, inspect DOM snapshots, click/type, capture screenshots, inspect console/request output, or test frontend flows in a real browser.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Browser Tools
|
|
@@ -19,7 +19,7 @@ node <baseDir>/playwright-cli.js click "Submit"
|
|
|
19
19
|
node <baseDir>/playwright-cli.js type "hello"
|
|
20
20
|
node <baseDir>/playwright-cli.js screenshot
|
|
21
21
|
node <baseDir>/playwright-cli.js console
|
|
22
|
-
node <baseDir>/playwright-cli.js
|
|
22
|
+
node <baseDir>/playwright-cli.js requests
|
|
23
23
|
node <baseDir>/playwright-cli.js close
|
|
24
24
|
```
|
|
25
25
|
|
|
@@ -27,7 +27,7 @@ Use `node <baseDir>/playwright-cli.js --help` for the full command list.
|
|
|
27
27
|
|
|
28
28
|
## Workflow
|
|
29
29
|
|
|
30
|
-
Start with `open` or `goto`, then use `snapshot` before interacting. Prefer snapshot, console, and
|
|
30
|
+
Start with `open` or `goto`, then use `snapshot` before interacting. Prefer snapshot, console, and request output for diagnosis; use screenshots when visual layout matters. Use named sessions with `-s=<session>` when you need to keep multiple browser flows separate.
|
|
31
31
|
|
|
32
32
|
If the browser is not installed, run:
|
|
33
33
|
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { spawnSync } from "node:child_process";
|
|
4
|
+
import fs from "node:fs";
|
|
4
5
|
import { createRequire } from "node:module";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
5
8
|
|
|
6
9
|
const require = createRequire(import.meta.url);
|
|
7
10
|
|
|
@@ -18,7 +21,25 @@ export function runPlaywrightCli(args = process.argv.slice(2), options = {}) {
|
|
|
18
21
|
});
|
|
19
22
|
}
|
|
20
23
|
|
|
21
|
-
|
|
24
|
+
function normalizeDirectEntryPath(candidate) {
|
|
25
|
+
const resolved = path.resolve(candidate);
|
|
26
|
+
const real = fs.realpathSync.native(resolved);
|
|
27
|
+
const normalized = path.normalize(real);
|
|
28
|
+
return process.platform === "win32" ? normalized.toLowerCase() : normalized;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function isDirectEntry(moduleUrl = import.meta.url, argvPath = process.argv[1]) {
|
|
32
|
+
if (!argvPath) return false;
|
|
33
|
+
try {
|
|
34
|
+
const modulePath = normalizeDirectEntryPath(fileURLToPath(moduleUrl));
|
|
35
|
+
const entryPath = normalizeDirectEntryPath(argvPath);
|
|
36
|
+
return modulePath === entryPath;
|
|
37
|
+
} catch {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (isDirectEntry()) {
|
|
22
43
|
const result = runPlaywrightCli();
|
|
23
44
|
process.exitCode = result.status ?? 1;
|
|
24
45
|
}
|