@docyrus/docyrus 0.0.33 → 0.0.35
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 +25 -0
- package/agent-loader.js +3 -2
- package/agent-loader.js.map +2 -2
- package/main.js +82252 -46058
- package/main.js.map +4 -4
- package/package.json +12 -3
- package/resources/chrome-tools/browser-content.js +46 -46
- package/resources/chrome-tools/browser-cookies.js +16 -16
- package/resources/chrome-tools/browser-eval.js +27 -27
- package/resources/chrome-tools/browser-hn-scraper.js +1 -1
- package/resources/chrome-tools/browser-nav.js +23 -23
- package/resources/chrome-tools/browser-pick.js +127 -127
- package/resources/chrome-tools/browser-screenshot.js +10 -10
- package/resources/chrome-tools/browser-start.js +38 -38
- package/resources/pi-agent/extensions/answer.ts +392 -384
- package/resources/pi-agent/extensions/context.ts +415 -415
- package/resources/pi-agent/extensions/control.ts +1287 -1287
- package/resources/pi-agent/extensions/diff.ts +171 -171
- package/resources/pi-agent/extensions/files.ts +155 -155
- package/resources/pi-agent/extensions/knowledge.ts +664 -0
- package/resources/pi-agent/extensions/loop.ts +375 -375
- package/resources/pi-agent/extensions/pi-bash-live-view/index.ts +1 -1
- package/resources/pi-agent/extensions/pi-bash-live-view/package.json +22 -22
- package/resources/pi-agent/extensions/pi-bash-live-view/pty-execute.ts +2 -2
- package/resources/pi-agent/extensions/pi-bash-live-view/pty-session.ts +2 -2
- package/resources/pi-agent/extensions/pi-bash-live-view/spawn-helper.ts +2 -2
- package/resources/pi-agent/extensions/pi-bash-live-view/terminal-emulator.ts +18 -18
- package/resources/pi-agent/extensions/pi-bash-live-view/truncate.ts +1 -1
- package/resources/pi-agent/extensions/pi-bash-live-view/widget.ts +4 -4
- package/resources/pi-agent/extensions/pi-custom-compaction/package.json +4 -4
- package/resources/pi-agent/extensions/pi-mcp-adapter/app-bridge.bundle.js +14 -14
- package/resources/pi-agent/extensions/pi-mcp-adapter/commands.ts +6 -6
- package/resources/pi-agent/extensions/pi-mcp-adapter/config.ts +9 -9
- package/resources/pi-agent/extensions/pi-mcp-adapter/consent-manager.ts +4 -4
- package/resources/pi-agent/extensions/pi-mcp-adapter/direct-tools.ts +13 -13
- package/resources/pi-agent/extensions/pi-mcp-adapter/glimpse-ui.ts +5 -5
- package/resources/pi-agent/extensions/pi-mcp-adapter/host-html-template.ts +13 -13
- package/resources/pi-agent/extensions/pi-mcp-adapter/index.ts +14 -14
- package/resources/pi-agent/extensions/pi-mcp-adapter/init.ts +17 -17
- package/resources/pi-agent/extensions/pi-mcp-adapter/lifecycle.ts +2 -2
- package/resources/pi-agent/extensions/pi-mcp-adapter/logger.ts +2 -2
- package/resources/pi-agent/extensions/pi-mcp-adapter/mcp-panel.ts +17 -17
- package/resources/pi-agent/extensions/pi-mcp-adapter/metadata-cache.ts +9 -9
- package/resources/pi-agent/extensions/pi-mcp-adapter/npx-resolver.ts +35 -35
- package/resources/pi-agent/extensions/pi-mcp-adapter/oauth-handler.ts +1 -1
- package/resources/pi-agent/extensions/pi-mcp-adapter/proxy-modes.ts +12 -12
- package/resources/pi-agent/extensions/pi-mcp-adapter/server-manager.ts +6 -6
- package/resources/pi-agent/extensions/pi-mcp-adapter/tool-metadata.ts +4 -4
- package/resources/pi-agent/extensions/pi-mcp-adapter/types.ts +2 -2
- package/resources/pi-agent/extensions/pi-mcp-adapter/ui-resource-handler.ts +6 -6
- package/resources/pi-agent/extensions/pi-mcp-adapter/ui-server.ts +17 -17
- package/resources/pi-agent/extensions/pi-mcp-adapter/ui-session.ts +22 -22
- package/resources/pi-agent/extensions/pi-mcp-adapter/utils.ts +2 -2
- package/resources/pi-agent/extensions/prompt-editor.ts +900 -900
- package/resources/pi-agent/extensions/prompt-url-widget.ts +122 -122
- package/resources/pi-agent/extensions/redraws.ts +14 -14
- package/resources/pi-agent/extensions/review.ts +1533 -1533
- package/resources/pi-agent/extensions/todos.ts +1735 -1735
- package/resources/pi-agent/extensions/tps.ts +40 -40
- package/resources/pi-agent/extensions/whimsical.ts +3 -3
- package/resources/pi-agent/prompts/agent-system.md +2 -0
- package/resources/pi-agent/prompts/coder-system.md +2 -0
- package/resources/pi-agent/skills/officecli/SKILL.md +113 -0
- package/server-loader.js +82 -1
- package/server-loader.js.map +3 -3
- package/tui.mjs +2 -0
- package/tui.mjs.map +1 -1
|
@@ -15,204 +15,204 @@ interface FileInfo {
|
|
|
15
15
|
file: string;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
export default function
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
18
|
+
export default function(pi: ExtensionAPI) {
|
|
19
|
+
pi.registerCommand("diff", {
|
|
20
|
+
description: "Show git changes and open in VS Code diff view",
|
|
21
|
+
handler: async(_args, ctx) => {
|
|
22
|
+
if (!ctx.hasUI) {
|
|
23
|
+
ctx.ui.notify("No UI available", "error");
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
26
|
|
|
27
27
|
// Get changed files from git status
|
|
28
|
-
|
|
28
|
+
const result = await pi.exec("git", ["status", "--porcelain"], { cwd: ctx.cwd });
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
if (result.code !== 0) {
|
|
31
|
+
ctx.ui.notify(`git status failed: ${result.stderr}`, "error");
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
if (!result.stdout || !result.stdout.trim()) {
|
|
36
|
+
ctx.ui.notify("No changes in working tree", "info");
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
39
|
|
|
40
40
|
// Parse git status output
|
|
41
41
|
// Format: XY filename (where XY is two-letter status, then space, then filename)
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
const lines = result.stdout.split("\n");
|
|
43
|
+
const files: FileInfo[] = [];
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
for (const line of lines) {
|
|
46
|
+
if (line.length < 4) {continue;} // Need at least "XY f"
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
const status = line.slice(0, 2);
|
|
49
|
+
const file = line.slice(2).trimStart();
|
|
50
50
|
|
|
51
51
|
// Translate status codes to short labels
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
52
|
+
let statusLabel: string;
|
|
53
|
+
if (status.includes("M")) {statusLabel = "M";}
|
|
54
|
+
else if (status.includes("A")) {statusLabel = "A";}
|
|
55
|
+
else if (status.includes("D")) {statusLabel = "D";}
|
|
56
|
+
else if (status.includes("?")) {statusLabel = "?";}
|
|
57
|
+
else if (status.includes("R")) {statusLabel = "R";}
|
|
58
|
+
else if (status.includes("C")) {statusLabel = "C";}
|
|
59
|
+
else {statusLabel = status.trim() || "~";}
|
|
60
|
+
|
|
61
|
+
files.push({ status: statusLabel, statusLabel, file });
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (files.length === 0) {
|
|
65
|
+
ctx.ui.notify("No changes found", "info");
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const WINDOWS_UNSAFE_CMD_CHARS_RE = /[&|<>^%\r\n]/;
|
|
70
|
+
const quoteCmdArg = (value: string) => `"${value.replace(/"/g, '""')}"`;
|
|
71
|
+
|
|
72
|
+
const openWithCode = async(file: string) => {
|
|
73
|
+
if (process.platform === "win32") {
|
|
74
|
+
if (WINDOWS_UNSAFE_CMD_CHARS_RE.test(file)) {
|
|
75
|
+
ctx.ui.notify(
|
|
76
|
+
`Refusing to open ${file}: path contains Windows cmd metacharacters (& | < > ^ % or newline).`,
|
|
77
|
+
"error",
|
|
78
|
+
);
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
const commandLine = `code -g ${quoteCmdArg(file)}`;
|
|
82
|
+
return pi.exec("cmd", ["/d", "/s", "/c", commandLine], { cwd: ctx.cwd });
|
|
83
|
+
}
|
|
84
|
+
return pi.exec("code", ["-g", file], { cwd: ctx.cwd });
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const openSelected = async(fileInfo: FileInfo): Promise<void> => {
|
|
88
|
+
try {
|
|
89
89
|
// Open in VS Code diff view.
|
|
90
90
|
// For untracked files, git difftool won't work, so fall back to just opening the file.
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
91
|
+
if (fileInfo.status === "?") {
|
|
92
|
+
const openResult = await openWithCode(fileInfo.file);
|
|
93
|
+
if (!openResult) {return;}
|
|
94
|
+
if (openResult.code !== 0) {
|
|
95
|
+
const openStderr = openResult.stderr.trim();
|
|
96
|
+
ctx.ui.notify(
|
|
97
|
+
`Failed to open ${fileInfo.file} (exit ${openResult.code})${openStderr ? `: ${openStderr}` : ""}`,
|
|
98
|
+
"error",
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const diffResult = await pi.exec("git", ["difftool", "-y", "--tool=vscode", fileInfo.file], {
|
|
105
|
+
cwd: ctx.cwd,
|
|
106
|
+
});
|
|
107
|
+
if (diffResult.code !== 0) {
|
|
108
|
+
const diffStderr = diffResult.stderr.trim();
|
|
109
|
+
ctx.ui.notify(
|
|
110
|
+
`Failed to show diff with vscode for ${fileInfo.file} (exit ${diffResult.code})${diffStderr ? `: ${diffStderr}` : ""}`,
|
|
111
|
+
"error",
|
|
112
|
+
);
|
|
113
|
+
ctx.ui.notify(
|
|
114
|
+
"Troubleshooting: check git difftool config (e.g. `git config --get difftool.vscode.cmd`).",
|
|
115
|
+
"info",
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
const openResult = await openWithCode(fileInfo.file);
|
|
119
|
+
if (!openResult) {return;}
|
|
120
|
+
if (openResult.code !== 0) {
|
|
121
|
+
const openStderr = openResult.stderr.trim();
|
|
122
|
+
ctx.ui.notify(
|
|
123
|
+
`Failed to open ${fileInfo.file} (exit ${openResult.code})${openStderr ? `: ${openStderr}` : ""}`,
|
|
124
|
+
"error",
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
} catch (error) {
|
|
129
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
130
|
+
ctx.ui.notify(`Failed to open ${fileInfo.file}: ${message}`, "error");
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
133
|
|
|
134
134
|
// Show file picker with SelectList
|
|
135
|
-
|
|
136
|
-
|
|
135
|
+
await ctx.ui.custom<void>((tui, theme, _kb, done) => {
|
|
136
|
+
const container = new Container();
|
|
137
137
|
|
|
138
138
|
// Top border
|
|
139
|
-
|
|
139
|
+
container.addChild(new DynamicBorder((s: string) => theme.fg("accent", s)));
|
|
140
140
|
|
|
141
141
|
// Title
|
|
142
|
-
|
|
142
|
+
container.addChild(new Text(theme.fg("accent", theme.bold(" Select file to diff")), 0, 0));
|
|
143
143
|
|
|
144
144
|
// Build select items with colored status
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
145
|
+
const items: SelectItem[] = files.map((f) => {
|
|
146
|
+
let statusColor: string;
|
|
147
|
+
switch (f.status) {
|
|
148
|
+
case "M":
|
|
149
|
+
statusColor = theme.fg("warning", f.status);
|
|
150
|
+
break;
|
|
151
|
+
case "A":
|
|
152
|
+
statusColor = theme.fg("success", f.status);
|
|
153
|
+
break;
|
|
154
|
+
case "D":
|
|
155
|
+
statusColor = theme.fg("error", f.status);
|
|
156
|
+
break;
|
|
157
|
+
case "?":
|
|
158
|
+
statusColor = theme.fg("muted", f.status);
|
|
159
|
+
break;
|
|
160
|
+
default:
|
|
161
|
+
statusColor = theme.fg("dim", f.status);
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
value: f,
|
|
165
|
+
label: `${statusColor} ${f.file}`,
|
|
166
|
+
};
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
const visibleRows = Math.min(files.length, 15);
|
|
170
|
+
let currentIndex = 0;
|
|
171
|
+
|
|
172
|
+
const selectList = new SelectList(items, visibleRows, {
|
|
173
|
+
selectedPrefix: (t) => theme.fg("accent", t),
|
|
174
|
+
selectedText: (t) => t, // Keep existing colors
|
|
175
|
+
description: (t) => theme.fg("muted", t),
|
|
176
|
+
scrollInfo: (t) => theme.fg("dim", t),
|
|
177
|
+
noMatch: (t) => theme.fg("warning", t),
|
|
178
|
+
});
|
|
179
|
+
selectList.onSelect = (item) => {
|
|
180
|
+
void openSelected(item.value as FileInfo);
|
|
181
|
+
};
|
|
182
|
+
selectList.onCancel = () => done();
|
|
183
|
+
selectList.onSelectionChange = (item) => {
|
|
184
|
+
currentIndex = items.indexOf(item);
|
|
185
|
+
};
|
|
186
|
+
container.addChild(selectList);
|
|
187
187
|
|
|
188
188
|
// Help text
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
189
|
+
container.addChild(
|
|
190
|
+
new Text(theme.fg("dim", " ↑↓ navigate • ←→ page • enter open • esc close"), 0, 0),
|
|
191
|
+
);
|
|
192
192
|
|
|
193
193
|
// Bottom border
|
|
194
|
-
|
|
194
|
+
container.addChild(new DynamicBorder((s: string) => theme.fg("accent", s)));
|
|
195
195
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
196
|
+
return {
|
|
197
|
+
render: (w) => container.render(w),
|
|
198
|
+
invalidate: () => container.invalidate(),
|
|
199
|
+
handleInput: (data) => {
|
|
200
200
|
// Add paging with left/right
|
|
201
|
-
|
|
201
|
+
if (matchesKey(data, Key.left)) {
|
|
202
202
|
// Page up - clamp to 0
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
203
|
+
currentIndex = Math.max(0, currentIndex - visibleRows);
|
|
204
|
+
selectList.setSelectedIndex(currentIndex);
|
|
205
|
+
} else if (matchesKey(data, Key.right)) {
|
|
206
206
|
// Page down - clamp to last
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
207
|
+
currentIndex = Math.min(items.length - 1, currentIndex + visibleRows);
|
|
208
|
+
selectList.setSelectedIndex(currentIndex);
|
|
209
|
+
} else {
|
|
210
|
+
selectList.handleInput(data);
|
|
211
|
+
}
|
|
212
|
+
tui.requestRender();
|
|
213
|
+
},
|
|
214
|
+
};
|
|
215
|
+
});
|
|
216
|
+
},
|
|
217
|
+
});
|
|
218
218
|
}
|