@cydm/pie 1.0.7 → 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.
- package/README.md +10 -5
- package/dist/builtin/extensions/ask-user/index.js +1 -1
- package/dist/builtin/extensions/init/index.js +70 -68
- package/dist/builtin/extensions/plan-mode/index.js +1 -1
- package/dist/builtin/extensions/subagent/index.js +10 -65
- package/dist/builtin/extensions/todo/index.js +1 -1
- package/dist/builtin/skills/browser-tools/SKILL.md +14 -14
- package/dist/chunks/{chunk-BHNULR7U.js → chunk-6WD2NFIC.js} +822 -430
- package/dist/chunks/chunk-NTYHFBUA.js +36 -0
- package/dist/chunks/{chunk-GDTN4UPJ.js → chunk-ZRONUKTW.js} +297 -9
- package/dist/cli.js +554 -486
- package/package.json +2 -2
- package/dist/builtin/skills/pie-unity-rpc/SKILL.md +0 -121
- package/dist/builtin/skills/pie-unity-rpc/pie-unity-rpc.js +0 -417
package/README.md
CHANGED
|
@@ -92,6 +92,7 @@ Validate the file explicitly:
|
|
|
92
92
|
```bash
|
|
93
93
|
pie models validate
|
|
94
94
|
pie models validate --path /abs/path/to/models.json
|
|
95
|
+
pie models validate --probe web_search
|
|
95
96
|
```
|
|
96
97
|
|
|
97
98
|
Generate a starter template:
|
|
@@ -249,13 +250,15 @@ node <resolvedPath for browser-tools/playwright-cli.js> install-browser chromium
|
|
|
249
250
|
|
|
250
251
|
Run `pie doctor` to check whether Playwright CLI and its browser runtime are discoverable.
|
|
251
252
|
|
|
252
|
-
## Web
|
|
253
|
+
## Web Research
|
|
253
254
|
|
|
254
|
-
Pie exposes a canonical `
|
|
255
|
+
Pie exposes a canonical `web_research` tool for public web research, current information, online documentation, and internet inspiration. It plans search variants, uses provider-native search, fetches credible sources, and returns citations. Workspace search remains separate: use `grep_text`, `find_files`, and `list_dir` for local repository content.
|
|
255
256
|
|
|
256
|
-
`web_search`
|
|
257
|
+
`web_search` remains available as the lower-level provider-native search tool. It does not scrape DuckDuckGo or fall back to `bash` with `curl` or Python HTTP scripts. If the configured provider/model cannot perform native web search, the tool returns a clear unavailable result with provider/configuration details.
|
|
257
258
|
|
|
258
|
-
Use `web_fetch`
|
|
259
|
+
Use `web_fetch` directly when the agent needs to read a specific URL, documentation page, changelog, issue, or PDF. `web_fetch` follows redirects, extracts readable text/markdown, returns citation anchors and extraction diagnostics, and reports `requires_browser` for JavaScript-heavy pages instead of pretending the content was read. In the CLI, `web_research` can use browser-tools for browser-rendered sources when the Playwright runtime is available; Unity reports those pages as `requires_browser`.
|
|
260
|
+
|
|
261
|
+
`web_research` records route health and latency in Pie's state directory so later runs can prefer providers with better source quality, fewer timeouts, and lower rate-limit pressure. `pie doctor --json` reports the recorded provider health, and `verify:web` writes web metrics including p50/p95 latency, failure categories, and citation quality artifacts.
|
|
259
262
|
|
|
260
263
|
## Permissions
|
|
261
264
|
|
|
@@ -305,8 +308,10 @@ npm run verify:terminal:matrix
|
|
|
305
308
|
```
|
|
306
309
|
|
|
307
310
|
Use `npm run verify:agent` when model credentials are available and you want the real daily agent gate.
|
|
308
|
-
Use `npm run verify:agent:nightly`
|
|
311
|
+
Use `npm run verify:agent:nightly` before release candidates that claim real-provider reliability.
|
|
312
|
+
Use `UNITY_EDITOR="/path/to/Unity" npm run verify:unity:reliability` before Unity release candidates. For live Unity Dev RPC coverage, run `PIE_UNITY_REAL_RPC=1 UNITY_EDITOR="/path/to/Unity" npm run verify:unity:reliability`.
|
|
309
313
|
Set `PIE_REAL_BROWSER=1` when you want `verify:browser` to open a real browser session instead of only checking the Playwright CLI contract.
|
|
314
|
+
Set `PIE_REAL_WEB=1` when you want `verify:web` to run real provider web research smoke with fetched or browser-read citations.
|
|
310
315
|
|
|
311
316
|
## Publishing
|
|
312
317
|
|
|
@@ -1,7 +1,7 @@
|
|
|
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-
|
|
4
|
+
} from "../../../chunks/chunk-6WD2NFIC.js";
|
|
5
5
|
import "../../../chunks/chunk-A5JSJAPK.js";
|
|
6
6
|
import "../../../chunks/chunk-TG2EQLX2.js";
|
|
7
7
|
|
|
@@ -1,136 +1,138 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
resolveCliProjectRoot
|
|
4
|
+
} from "../../../chunks/chunk-NTYHFBUA.js";
|
|
2
5
|
import "../../../chunks/chunk-TG2EQLX2.js";
|
|
3
6
|
|
|
4
7
|
// builtin/extensions/init/index.ts
|
|
8
|
+
import fs from "node:fs";
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
function resolveProjectAgentsTarget(cwd) {
|
|
11
|
+
const projectRoot = resolveCliProjectRoot(cwd);
|
|
12
|
+
return {
|
|
13
|
+
projectRoot,
|
|
14
|
+
agentsPath: path.join(projectRoot, "AGENTS.md")
|
|
15
|
+
};
|
|
16
|
+
}
|
|
5
17
|
async function loadExistingKnowledge(cwd) {
|
|
18
|
+
const target = resolveProjectAgentsTarget(cwd);
|
|
6
19
|
try {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const agentsPath = path.join(cwd, ".pie", "agents.md");
|
|
10
|
-
if (fs.existsSync(agentsPath)) {
|
|
11
|
-
return fs.readFileSync(agentsPath, "utf-8");
|
|
20
|
+
if (fs.existsSync(target.agentsPath)) {
|
|
21
|
+
return { target, content: fs.readFileSync(target.agentsPath, "utf-8") };
|
|
12
22
|
}
|
|
13
23
|
} catch {
|
|
14
24
|
}
|
|
15
|
-
return null;
|
|
16
|
-
}
|
|
17
|
-
async function ensurePieDir(cwd) {
|
|
18
|
-
const fs = await import("fs");
|
|
19
|
-
const path = await import("path");
|
|
20
|
-
const pieDir = path.join(cwd, ".pie");
|
|
21
|
-
if (!fs.existsSync(pieDir)) {
|
|
22
|
-
fs.mkdirSync(pieDir, { recursive: true });
|
|
23
|
-
}
|
|
25
|
+
return { target, content: null };
|
|
24
26
|
}
|
|
25
27
|
function buildResearchPrompt(params) {
|
|
26
|
-
const { isUpdate, existingContent, userIntent, cwd } = params;
|
|
28
|
+
const { isUpdate, existingContent, userIntent, cwd, projectRoot, agentsPath } = params;
|
|
27
29
|
if (isUpdate && existingContent) {
|
|
28
30
|
const truncatedContent = existingContent.length > 4e3 ? existingContent.slice(0, 4e3) + "\n... (truncated)" : existingContent;
|
|
29
|
-
return `\u{1F4DD} \u66F4\u65B0\u9879\u76EE\
|
|
31
|
+
return `\u{1F4DD} \u66F4\u65B0 root AGENTS.md \u9879\u76EE\u4E0A\u4E0B\u6587
|
|
32
|
+
|
|
33
|
+
\u76EE\u6807\u6587\u4EF6\uFF1A${agentsPath}
|
|
34
|
+
\u9879\u76EE\u6839\u76EE\u5F55\uFF1A${projectRoot}
|
|
35
|
+
\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\uFF1A${cwd}
|
|
30
36
|
|
|
31
|
-
\u5F53\u524D .
|
|
37
|
+
\u5F53\u524D root AGENTS.md \u5185\u5BB9\uFF1A
|
|
32
38
|
\`\`\`
|
|
33
39
|
${truncatedContent}
|
|
34
40
|
\`\`\`
|
|
35
41
|
|
|
36
42
|
${userIntent ? `\u{1F4CC} \u7528\u6237\u66F4\u65B0\u610F\u56FE\uFF1A${userIntent}
|
|
37
43
|
|
|
38
|
-
` : ""}\u8BF7\u91CD\u65B0\u7814\u7A76\u9879\u76EE\u5E76\u66F4\u65B0\
|
|
44
|
+
` : ""}\u8BF7\u91CD\u65B0\u7814\u7A76\u9879\u76EE\u5E76\u66F4\u65B0 root AGENTS.md\uFF1A
|
|
39
45
|
|
|
40
|
-
1. \
|
|
41
|
-
2. \
|
|
42
|
-
3.
|
|
43
|
-
4. \
|
|
44
|
-
5. \
|
|
46
|
+
1. \u4FDD\u6301 AGENTS.md \u662F progressive disclosure index\uFF0C\u4E0D\u8981\u5199\u6210\u957F\u7BC7\u9879\u76EE\u767E\u79D1
|
|
47
|
+
2. \u4FDD\u7559\u7B80\u77ED root instructions\uFF0C\u7136\u540E\u7EF4\u62A4 Repo Map
|
|
48
|
+
3. Repo Map \u91CC\u7684\u6BCF\u4E2A\u91CD\u8981\u76EE\u5F55\u90FD\u8981\u6709 desc\uFF0C\u8BF4\u660E\u4EC0\u4E48\u65F6\u5019\u9700\u8981\u8BFB\u8BE5\u76EE\u5F55\u6216\u76F8\u5173\u6587\u6863
|
|
49
|
+
4. \u53EA\u8865\u5145\u7A33\u5B9A\u89C4\u5219\u3001\u76EE\u5F55\u8DEF\u7531\u3001\u9A8C\u8BC1\u95E8\u7981\u548C\u751F\u6210\u7269\u89C4\u5219
|
|
50
|
+
5. \u5220\u9664\u8FC7\u65F6\u6216\u91CD\u590D README/ARCHITECTURE \u7684\u5927\u6BB5\u5185\u5BB9
|
|
45
51
|
|
|
46
|
-
\u8BF7\u4F7F\u7528
|
|
47
|
-
|
|
48
|
-
\u5DE5\u4F5C\u76EE\u5F55\uFF1A${cwd}`;
|
|
52
|
+
\u8BF7\u4F7F\u7528 write_file \u5DE5\u5177\u66F4\u65B0\u76EE\u6807\u6587\u4EF6\uFF1A${agentsPath}
|
|
53
|
+
CLI \u6587\u4EF6\u5DE5\u5177\u4F1A\u4EE5\u9879\u76EE\u6839\u76EE\u5F55\u4F5C\u4E3A\u8BBF\u95EE\u8FB9\u754C\uFF1B\u4E0D\u8981\u4F7F\u7528\u989D\u5916\u7684 root \u53C2\u6570\u3002`;
|
|
49
54
|
}
|
|
50
|
-
return `\u{1F50D} \u521D\u59CB\u5316\u9879\u76EE\
|
|
55
|
+
return `\u{1F50D} \u521D\u59CB\u5316 root AGENTS.md \u9879\u76EE\u4E0A\u4E0B\u6587
|
|
56
|
+
|
|
57
|
+
\u76EE\u6807\u6587\u4EF6\uFF1A${agentsPath}
|
|
58
|
+
\u9879\u76EE\u6839\u76EE\u5F55\uFF1A${projectRoot}
|
|
59
|
+
\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\uFF1A${cwd}
|
|
51
60
|
|
|
52
61
|
${userIntent ? `\u{1F4CC} \u7528\u6237\u7814\u7A76\u610F\u56FE\uFF1A${userIntent}
|
|
53
62
|
|
|
54
|
-
` : ""}\u8BF7\
|
|
63
|
+
` : ""}\u8BF7\u7814\u7A76\u5F53\u524D\u9879\u76EE\u5E76\u521B\u5EFA root \`AGENTS.md\`\u3002\u8FD9\u4E2A\u6587\u4EF6\u5E94\u8BE5\u662F progressive disclosure index\uFF0C\u7528\u6765\u6307\u5BFC\u540E\u7EED agent \u6309\u9700\u8BFB\u53D6\u76F8\u5173\u6587\u6863\uFF0C\u800C\u4E0D\u662F\u4E00\u6B21\u6027\u603B\u7ED3\u6574\u4E2A\u4ED3\u5E93\u3002
|
|
55
64
|
|
|
56
65
|
\u7814\u7A76\u4EFB\u52A1\uFF1A
|
|
57
66
|
1. \u8BC6\u522B\u9879\u76EE\u7C7B\u578B\u548C\u6280\u672F\u6808\uFF08\u67E5\u770B package.json, Cargo.toml, go.mod, requirements.txt, pyproject.toml \u7B49\uFF09
|
|
58
|
-
2. \u63A2\u7D22\
|
|
59
|
-
3. \u8BFB\u53D6\
|
|
60
|
-
4. \u8BC6\u522B\
|
|
61
|
-
5. \
|
|
62
|
-
6. \u63A8\u65AD\u5F00\u53D1\u89C4\u8303\uFF08\u4EE3\u7801\u98CE\u683C\u3001\u6D4B\u8BD5\u3001\u6784\u5EFA\u6D41\u7A0B\uFF09
|
|
67
|
+
2. \u63A2\u7D22\u9876\u5C42\u76EE\u5F55\u7ED3\u6784\u548C\u5173\u952E package/product \u8FB9\u754C
|
|
68
|
+
3. \u8BFB\u53D6 README\u3001ARCHITECTURE\u3001docs/public-api \u7B49\u5DF2\u6709\u6587\u6863\uFF0C\u907F\u514D\u91CD\u590D\u7C98\u8D34
|
|
69
|
+
4. \u8BC6\u522B\u751F\u6210\u7269\u89C4\u5219\u3001\u6D4B\u8BD5\u95E8\u7981\u3001\u4EE3\u7801\u5206\u5C42\u548C\u9AD8\u98CE\u9669\u6539\u52A8\u8FB9\u754C
|
|
70
|
+
5. \u751F\u6210\u7B80\u77ED\u3001\u7A33\u5B9A\u3001\u53EF\u7EF4\u62A4\u7684\u76EE\u5F55\u8DEF\u7531\u8BF4\u660E
|
|
63
71
|
|
|
64
|
-
\u8BF7\u751F\u6210\u5305\u542B\u4EE5\u4E0B\u7AE0\u8282\u7684
|
|
72
|
+
\u8BF7\u751F\u6210\u5305\u542B\u4EE5\u4E0B\u7AE0\u8282\u7684 AGENTS.md\uFF1A
|
|
65
73
|
|
|
66
74
|
\`\`\`
|
|
67
|
-
#
|
|
75
|
+
# AGENTS.md
|
|
68
76
|
|
|
69
|
-
##
|
|
70
|
-
|
|
71
|
-
- \u6280\u672F\u6808\uFF1A<\u4E3B\u8981\u6280\u672F>
|
|
72
|
-
- \u4E00\u53E5\u8BDD\u63CF\u8FF0\uFF1A<\u9879\u76EE\u7528\u9014>
|
|
77
|
+
## How To Use This File
|
|
78
|
+
Briefly explain that this file is an index/router. Agents should read linked docs on demand.
|
|
73
79
|
|
|
74
|
-
##
|
|
75
|
-
-
|
|
76
|
-
|
|
77
|
-
- \u4F9D\u8D56\u5173\u7CFB
|
|
80
|
+
## Repo Map
|
|
81
|
+
- \`path\`
|
|
82
|
+
desc: When to read this directory and what it owns.
|
|
78
83
|
|
|
79
|
-
##
|
|
80
|
-
|
|
81
|
-
|------|------|------|
|
|
84
|
+
## Architecture Rules
|
|
85
|
+
Stable cross-package boundaries only.
|
|
82
86
|
|
|
83
|
-
##
|
|
84
|
-
-
|
|
85
|
-
- \u6D4B\u8BD5\u6A21\u5F0F
|
|
86
|
-
- \u6784\u5EFA/\u8FD0\u884C\u65B9\u5F0F
|
|
87
|
+
## Context And Generated Artifacts
|
|
88
|
+
Rules for AGENTS.md, generated bundles, and source-of-truth files.
|
|
87
89
|
|
|
88
|
-
##
|
|
89
|
-
|
|
90
|
+
## Verification Map
|
|
91
|
+
Which focused tests/checks to run by touched area.
|
|
90
92
|
\`\`\`
|
|
91
93
|
|
|
92
|
-
\u8BF7\u4F7F\u7528
|
|
93
|
-
|
|
94
|
-
\u5DE5\u4F5C\u76EE\u5F55\uFF1A${cwd}`;
|
|
94
|
+
\u8BF7\u4F7F\u7528 write_file \u5DE5\u5177\u521B\u5EFA\u76EE\u6807\u6587\u4EF6\uFF1A${agentsPath}
|
|
95
|
+
CLI \u6587\u4EF6\u5DE5\u5177\u4F1A\u4EE5\u9879\u76EE\u6839\u76EE\u5F55\u4F5C\u4E3A\u8BBF\u95EE\u8FB9\u754C\uFF1B\u4E0D\u8981\u4F7F\u7528\u989D\u5916\u7684 root \u53C2\u6570\u3002`;
|
|
95
96
|
}
|
|
96
97
|
async function initExtension(ctx) {
|
|
97
98
|
ctx.log("Init extension loaded");
|
|
98
99
|
let cachedKnowledge = null;
|
|
99
100
|
try {
|
|
100
|
-
|
|
101
|
+
const existing = await loadExistingKnowledge(ctx.cwd);
|
|
102
|
+
cachedKnowledge = existing.content;
|
|
101
103
|
if (cachedKnowledge) {
|
|
102
|
-
|
|
103
|
-
const projectName = firstLine.replace(/^#\s*/, "").trim() || "\u9879\u76EE";
|
|
104
|
-
ctx.log(`Pre-loaded agents.md (${cachedKnowledge.length} chars)`);
|
|
104
|
+
ctx.log(`Pre-loaded root AGENTS.md (${cachedKnowledge.length} chars) from ${existing.target.agentsPath}`);
|
|
105
105
|
} else {
|
|
106
|
-
ctx.log(
|
|
106
|
+
ctx.log(`No existing root AGENTS.md found at ${existing.target.agentsPath}`);
|
|
107
107
|
}
|
|
108
108
|
} catch (err) {
|
|
109
|
-
ctx.log(`Failed to pre-load
|
|
109
|
+
ctx.log(`Failed to pre-load root AGENTS.md: ${err}`);
|
|
110
110
|
}
|
|
111
111
|
ctx.registerCommand({
|
|
112
112
|
path: ["tools", "init"],
|
|
113
|
-
description: "\u7814\u7A76\u9879\u76EE\u5E76\u751F\u6210/\u66F4\u65B0
|
|
113
|
+
description: "\u7814\u7A76\u9879\u76EE\u5E76\u751F\u6210/\u66F4\u65B0 root AGENTS.md \u9879\u76EE\u4E0A\u4E0B\u6587\u7D22\u5F15",
|
|
114
114
|
handler: async (ctx2, args) => {
|
|
115
|
-
await
|
|
116
|
-
const existingContent =
|
|
117
|
-
const isUpdate = !!
|
|
115
|
+
const existing = await loadExistingKnowledge(ctx2.cwd);
|
|
116
|
+
const existingContent = existing.content;
|
|
117
|
+
const isUpdate = !!existing.content;
|
|
118
118
|
const userIntent = args?.trim();
|
|
119
119
|
cachedKnowledge = existingContent;
|
|
120
120
|
if (isUpdate) {
|
|
121
121
|
if (userIntent) {
|
|
122
122
|
ctx2.ui.notify(`\u{1F4DD} \u6B63\u5728\u66F4\u65B0\u9879\u76EE\u77E5\u8BC6\uFF08${userIntent}\uFF09...`, "info");
|
|
123
123
|
} else {
|
|
124
|
-
ctx2.ui.notify("\u{1F4DD} \u6B63\u5728\u66F4\u65B0
|
|
124
|
+
ctx2.ui.notify("\u{1F4DD} \u6B63\u5728\u66F4\u65B0 root AGENTS.md...", "info");
|
|
125
125
|
}
|
|
126
126
|
} else {
|
|
127
|
-
ctx2.ui.notify("\u{1F50D} \u6B63\u5728\u521D\u59CB\u5316
|
|
127
|
+
ctx2.ui.notify("\u{1F50D} \u6B63\u5728\u521D\u59CB\u5316 root AGENTS.md...", "info");
|
|
128
128
|
}
|
|
129
129
|
const researchPrompt = buildResearchPrompt({
|
|
130
130
|
isUpdate,
|
|
131
131
|
existingContent,
|
|
132
132
|
userIntent,
|
|
133
|
-
cwd: ctx2.cwd
|
|
133
|
+
cwd: ctx2.cwd,
|
|
134
|
+
projectRoot: existing.target.projectRoot,
|
|
135
|
+
agentsPath: existing.target.agentsPath
|
|
134
136
|
});
|
|
135
137
|
return researchPrompt;
|
|
136
138
|
}
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
isPlanModeSafeCommand,
|
|
8
8
|
markCompletedPlanSteps,
|
|
9
9
|
restoreExecutionState
|
|
10
|
-
} from "../../../chunks/chunk-
|
|
10
|
+
} from "../../../chunks/chunk-6WD2NFIC.js";
|
|
11
11
|
import "../../../chunks/chunk-A5JSJAPK.js";
|
|
12
12
|
import "../../../chunks/chunk-TG2EQLX2.js";
|
|
13
13
|
|
|
@@ -1,14 +1,11 @@
|
|
|
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-ZRONUKTW.js";
|
|
5
5
|
import {
|
|
6
|
-
createReadResourceCapability,
|
|
7
|
-
createReadSkillCapability,
|
|
8
|
-
createResolveResourceCapability,
|
|
9
6
|
createSharedFileSystemTools,
|
|
10
7
|
createSubagentCapability
|
|
11
|
-
} from "../../../chunks/chunk-
|
|
8
|
+
} from "../../../chunks/chunk-6WD2NFIC.js";
|
|
12
9
|
import "../../../chunks/chunk-A5JSJAPK.js";
|
|
13
10
|
import "../../../chunks/chunk-TG2EQLX2.js";
|
|
14
11
|
|
|
@@ -65,68 +62,16 @@ function subagentExtension(ctx) {
|
|
|
65
62
|
return parentRuntimeTools.filter((tool) => tool?.name !== "spawn_subagents_parallel");
|
|
66
63
|
}
|
|
67
64
|
const configDir = path.join(os.homedir(), ".pie");
|
|
68
|
-
const fsOptions = ctx.yoloMode ? { allowlistedDirs: ["/"] } : {
|
|
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
|
+
};
|
|
69
72
|
const fsTools = createSharedFileSystemTools(ctx.cwd, fsOptions);
|
|
70
|
-
const readSkillTool = createReadSkillCapability({
|
|
71
|
-
resolveSkill(name) {
|
|
72
|
-
const skill = skills.find((entry) => entry.name === name);
|
|
73
|
-
if (!skill || !skill.filePath) {
|
|
74
|
-
return null;
|
|
75
|
-
}
|
|
76
|
-
const content = skill.content ?? fs.readFileSync(skill.filePath, "utf8");
|
|
77
|
-
return {
|
|
78
|
-
name: skill.name,
|
|
79
|
-
content,
|
|
80
|
-
resources: skill.resourceRefs
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
}).tool;
|
|
84
|
-
const readResourceTool = createReadResourceCapability({
|
|
85
|
-
resolveResource(owner, resourcePath) {
|
|
86
|
-
const skill = skills.find((entry) => entry.name === owner);
|
|
87
|
-
if (!skill) {
|
|
88
|
-
return null;
|
|
89
|
-
}
|
|
90
|
-
const trimmed = String(resourcePath || "").trim().replace(/\\/g, "/");
|
|
91
|
-
if (!trimmed || trimmed.startsWith("/") || /^[A-Za-z]:\//.test(trimmed)) {
|
|
92
|
-
return null;
|
|
93
|
-
}
|
|
94
|
-
const segments = trimmed.split("/").filter(Boolean);
|
|
95
|
-
if (segments.some((segment) => segment === "..")) {
|
|
96
|
-
return null;
|
|
97
|
-
}
|
|
98
|
-
const absolutePath = path.resolve(skill.baseDir, ...segments);
|
|
99
|
-
const relativePath = path.relative(skill.baseDir, absolutePath).replace(/\\/g, "/");
|
|
100
|
-
if (relativePath.startsWith("../") || relativePath === ".." || !fs.existsSync(absolutePath)) {
|
|
101
|
-
return null;
|
|
102
|
-
}
|
|
103
|
-
return {
|
|
104
|
-
owner: skill.name,
|
|
105
|
-
path: trimmed.replace(/^\.\/+/, ""),
|
|
106
|
-
content: fs.readFileSync(absolutePath, "utf8")
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
}).tool;
|
|
110
|
-
const resolveResourceTool = createResolveResourceCapability({
|
|
111
|
-
resolveResource(owner, resourcePath) {
|
|
112
|
-
const skill = skills.find((entry) => entry.name === owner);
|
|
113
|
-
if (!skill) return null;
|
|
114
|
-
const trimmed = String(resourcePath || "").trim().replace(/\\/g, "/");
|
|
115
|
-
if (!trimmed || trimmed.startsWith("/") || /^[A-Za-z]:\//.test(trimmed)) return null;
|
|
116
|
-
const segments = trimmed.split("/").filter(Boolean);
|
|
117
|
-
if (segments.some((segment) => segment === "..")) return null;
|
|
118
|
-
const absolutePath = path.resolve(skill.baseDir, ...segments);
|
|
119
|
-
const relativePath = path.relative(skill.baseDir, absolutePath).replace(/\\/g, "/");
|
|
120
|
-
if (relativePath.startsWith("../") || relativePath === ".." || !fs.existsSync(absolutePath)) return null;
|
|
121
|
-
return {
|
|
122
|
-
owner: skill.name,
|
|
123
|
-
path: trimmed.replace(/^\.\/+/, ""),
|
|
124
|
-
resolvedPath: absolutePath
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
}).tool;
|
|
128
73
|
const cliHostCapabilities = createCliHostCapabilities(ctx.cwd);
|
|
129
|
-
return [...fsTools,
|
|
74
|
+
return [...fsTools, ...cliHostCapabilities.tools];
|
|
130
75
|
}
|
|
131
76
|
});
|
|
132
77
|
for (const tool of capability.tools) {
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
executeManageTodoList,
|
|
8
8
|
executionStateToTodos,
|
|
9
9
|
restoreExecutionState
|
|
10
|
-
} from "../../../chunks/chunk-
|
|
10
|
+
} from "../../../chunks/chunk-6WD2NFIC.js";
|
|
11
11
|
import "../../../chunks/chunk-A5JSJAPK.js";
|
|
12
12
|
import "../../../chunks/chunk-TG2EQLX2.js";
|
|
13
13
|
|
|
@@ -5,25 +5,25 @@ description: Interactive browser automation via Microsoft Playwright CLI. Use wh
|
|
|
5
5
|
|
|
6
6
|
# Browser Tools
|
|
7
7
|
|
|
8
|
-
Use Pie's packaged Microsoft Playwright CLI wrapper. Scripts live next to this skill;
|
|
8
|
+
Use Pie's packaged Microsoft Playwright CLI wrapper. Scripts live next to this skill; resolve `playwright-cli.js` against this skill's `baseDir` and use the resulting ordinary path with `bash`.
|
|
9
9
|
|
|
10
10
|
No manual dependency install is required when this skill is shipped with Pie.
|
|
11
11
|
|
|
12
12
|
## Common Commands
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
node <
|
|
16
|
-
node <
|
|
17
|
-
node <
|
|
18
|
-
node <
|
|
19
|
-
node <
|
|
20
|
-
node <
|
|
21
|
-
node <
|
|
22
|
-
node <
|
|
23
|
-
node <
|
|
15
|
+
node <baseDir>/playwright-cli.js open https://example.com
|
|
16
|
+
node <baseDir>/playwright-cli.js goto https://example.com
|
|
17
|
+
node <baseDir>/playwright-cli.js snapshot
|
|
18
|
+
node <baseDir>/playwright-cli.js click "Submit"
|
|
19
|
+
node <baseDir>/playwright-cli.js type "hello"
|
|
20
|
+
node <baseDir>/playwright-cli.js screenshot
|
|
21
|
+
node <baseDir>/playwright-cli.js console
|
|
22
|
+
node <baseDir>/playwright-cli.js network
|
|
23
|
+
node <baseDir>/playwright-cli.js close
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
Use `node <
|
|
26
|
+
Use `node <baseDir>/playwright-cli.js --help` for the full command list.
|
|
27
27
|
|
|
28
28
|
## Workflow
|
|
29
29
|
|
|
@@ -32,12 +32,12 @@ Start with `open` or `goto`, then use `snapshot` before interacting. Prefer snap
|
|
|
32
32
|
If the browser is not installed, run:
|
|
33
33
|
|
|
34
34
|
```bash
|
|
35
|
-
node <
|
|
35
|
+
node <baseDir>/playwright-cli.js install-browser chromium
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
If a session gets stuck, use:
|
|
39
39
|
|
|
40
40
|
```bash
|
|
41
|
-
node <
|
|
42
|
-
node <
|
|
41
|
+
node <baseDir>/playwright-cli.js close
|
|
42
|
+
node <baseDir>/playwright-cli.js kill-all
|
|
43
43
|
```
|