@stfade/pi-read-delegator 1.0.12 → 1.0.13
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 +178 -69
- package/{bash-filter.d.ts → dist/bash-filter.d.ts} +16 -6
- package/dist/bash-filter.js +420 -0
- package/{config.d.ts → dist/config.d.ts} +0 -1
- package/{config.js → dist/config.js} +34 -59
- package/{index.js → dist/index.js} +111 -149
- package/{reader-manager.d.ts → dist/reader-manager.d.ts} +26 -1
- package/{reader-manager.js → dist/reader-manager.js} +127 -72
- package/{tool-blocker.js → dist/tool-blocker.js} +13 -21
- package/{ui.js → dist/ui.js} +15 -62
- package/package.json +20 -17
- package/bash-filter.js +0 -242
- package/templates/reader.md +0 -8
- /package/{index.d.ts → dist/index.d.ts} +0 -0
- /package/{tool-blocker.d.ts → dist/tool-blocker.d.ts} +0 -0
- /package/{ui.d.ts → dist/ui.d.ts} +0 -0
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* reader-manager.ts — Reader subagent lifecycle and error handling
|
|
4
3
|
*
|
|
@@ -8,53 +7,86 @@
|
|
|
8
7
|
* - Call the Reader subagent with a task
|
|
9
8
|
* - Handle errors with a [R]etry / [A]llow once / [C]ancel prompt
|
|
10
9
|
*/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
import * as fs from "fs";
|
|
11
|
+
import * as path from "path";
|
|
12
|
+
import * as os from "os";
|
|
13
|
+
import { exec } from "child_process";
|
|
14
|
+
import { rawLog, rawWarn, rawError } from "./ui";
|
|
15
|
+
export class SessionFileCache {
|
|
16
|
+
files = new Map();
|
|
17
|
+
readRanges = new Map();
|
|
18
|
+
/** Cache a file's content with a hash for change detection. */
|
|
19
|
+
set(path, content) {
|
|
20
|
+
this.files.set(path, {
|
|
21
|
+
content,
|
|
22
|
+
hash: simpleHash(content),
|
|
23
|
+
timestamp: Date.now(),
|
|
24
|
+
sizeBytes: Buffer.byteLength(content, "utf-8"),
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
get(path) {
|
|
28
|
+
return this.files.get(path)?.content;
|
|
29
|
+
}
|
|
30
|
+
has(path) {
|
|
31
|
+
return this.files.has(path);
|
|
32
|
+
}
|
|
33
|
+
getHash(path) {
|
|
34
|
+
return this.files.get(path)?.hash;
|
|
35
|
+
}
|
|
36
|
+
/** Record that a specific line range of a path has been read. */
|
|
37
|
+
markReadRange(path, from, to) {
|
|
38
|
+
const existing = this.readRanges.get(path) ?? [];
|
|
39
|
+
existing.push([from, to]);
|
|
40
|
+
this.readRanges.set(path, existing);
|
|
16
41
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
42
|
+
getReadRanges(path) {
|
|
43
|
+
return this.readRanges.get(path) ?? [];
|
|
44
|
+
}
|
|
45
|
+
/** Compute gaps (unread line ranges) given total line count. */
|
|
46
|
+
getUnreadRanges(path, totalLines) {
|
|
47
|
+
const read = this.readRanges.get(path);
|
|
48
|
+
if (!read || read.length === 0)
|
|
49
|
+
return [[1, totalLines]];
|
|
50
|
+
const sorted = [...read].sort((a, b) => a[0] - b[0]);
|
|
51
|
+
const gaps = [];
|
|
52
|
+
let pos = 1;
|
|
53
|
+
for (const [from, to] of sorted) {
|
|
54
|
+
if (from > pos)
|
|
55
|
+
gaps.push([pos, from - 1]);
|
|
56
|
+
pos = Math.max(pos, to + 1);
|
|
57
|
+
}
|
|
58
|
+
if (pos <= totalLines)
|
|
59
|
+
gaps.push([pos, totalLines]);
|
|
60
|
+
return gaps;
|
|
61
|
+
}
|
|
62
|
+
/** Return cache statistics for the status command. */
|
|
63
|
+
stats() {
|
|
64
|
+
let totalSize = 0;
|
|
65
|
+
for (const entry of this.files.values())
|
|
66
|
+
totalSize += entry.sizeBytes;
|
|
67
|
+
return {
|
|
68
|
+
files: this.files.size,
|
|
69
|
+
sizeKB: Math.round(totalSize / 1024),
|
|
70
|
+
ranges: this.readRanges.size,
|
|
33
71
|
};
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
exports.handleReaderError = handleReaderError;
|
|
51
|
-
const fs = __importStar(require("fs"));
|
|
52
|
-
const path = __importStar(require("path"));
|
|
53
|
-
const os = __importStar(require("os"));
|
|
54
|
-
const child_process_1 = require("child_process");
|
|
55
|
-
const ui_1 = require("./ui");
|
|
72
|
+
}
|
|
73
|
+
clear() {
|
|
74
|
+
this.files.clear();
|
|
75
|
+
this.readRanges.clear();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/** Singleton cache instance shared across the extension session. */
|
|
79
|
+
export const sessionCache = new SessionFileCache();
|
|
80
|
+
/** Simple non-cryptographic hash for cache invalidation. */
|
|
81
|
+
function simpleHash(str) {
|
|
82
|
+
let h = 0;
|
|
83
|
+
for (let i = 0; i < str.length; i++) {
|
|
84
|
+
h = (Math.imul(31, h) + str.charCodeAt(i)) | 0;
|
|
85
|
+
}
|
|
86
|
+
return h.toString(36);
|
|
87
|
+
}
|
|
56
88
|
/** Error thrown when the Reader subagent fails. */
|
|
57
|
-
class ReaderError extends Error {
|
|
89
|
+
export class ReaderError extends Error {
|
|
58
90
|
originalError;
|
|
59
91
|
constructor(message, originalError) {
|
|
60
92
|
super(message);
|
|
@@ -62,7 +94,6 @@ class ReaderError extends Error {
|
|
|
62
94
|
this.name = "ReaderError";
|
|
63
95
|
}
|
|
64
96
|
}
|
|
65
|
-
exports.ReaderError = ReaderError;
|
|
66
97
|
// ---------------------------------------------------------------------------
|
|
67
98
|
// Paths
|
|
68
99
|
// ---------------------------------------------------------------------------
|
|
@@ -116,53 +147,77 @@ function registerPiSubagentsPackage() {
|
|
|
116
147
|
if (!packages.includes(pkgName)) {
|
|
117
148
|
packages.push(pkgName);
|
|
118
149
|
settings.packages = packages;
|
|
119
|
-
|
|
120
|
-
|
|
150
|
+
// Atomic write: write to temp file then rename to avoid
|
|
151
|
+
// corruption from concurrent writes by other extensions.
|
|
152
|
+
const tmpPath = settingsPath + ".tmp";
|
|
153
|
+
fs.writeFileSync(tmpPath, JSON.stringify(settings, null, 2) + "\n", "utf-8");
|
|
154
|
+
fs.renameSync(tmpPath, settingsPath);
|
|
155
|
+
rawLog("✅ Registered pi-subagents in settings.json package list.");
|
|
121
156
|
}
|
|
122
157
|
}
|
|
123
158
|
catch (err) {
|
|
124
|
-
|
|
159
|
+
rawWarn("⚠️ Failed to register pi-subagents in settings.json: " + String(err));
|
|
125
160
|
}
|
|
126
161
|
}
|
|
127
|
-
|
|
162
|
+
/**
|
|
163
|
+
* Async wrapper around child_process.exec.
|
|
164
|
+
* Returns stdout/stderr and rejects on non-zero exit or timeout.
|
|
165
|
+
*/
|
|
166
|
+
function execAsync(command, options = {}) {
|
|
167
|
+
return new Promise((resolve, reject) => {
|
|
168
|
+
const child = exec(command, { cwd: options.cwd, encoding: "utf-8", maxBuffer: 10 * 1024 * 1024 }, (err, stdout, stderr) => {
|
|
169
|
+
if (err) {
|
|
170
|
+
reject(Object.assign(err, { stdout, stderr }));
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
resolve({ stdout, stderr });
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
if (options.timeout && options.timeout > 0) {
|
|
177
|
+
setTimeout(() => {
|
|
178
|
+
child.kill();
|
|
179
|
+
reject(new Error(`Command timed out after ${options.timeout}ms`));
|
|
180
|
+
}, options.timeout);
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
export async function checkDependencies(prompt, onProgress) {
|
|
128
185
|
// Already installed — nothing to do
|
|
129
186
|
if (fs.existsSync(piSubagentsPackageJson())) {
|
|
130
187
|
registerPiSubagentsPackage();
|
|
131
188
|
return true;
|
|
132
189
|
}
|
|
133
|
-
|
|
190
|
+
rawWarn("⚠️ pi-subagents is not installed.");
|
|
134
191
|
const answer = await prompt("pi-subagents is not installed. Install it now? [Y/n]");
|
|
135
192
|
const normalized = answer.trim().toLowerCase();
|
|
136
193
|
if (normalized !== "" && normalized !== "y" && normalized !== "yes") {
|
|
137
|
-
|
|
194
|
+
rawError("❌ Cannot proceed without pi-subagents. Extension disabled.");
|
|
138
195
|
return false;
|
|
139
196
|
}
|
|
140
197
|
// Attempt installation
|
|
141
198
|
const piNpmDir = path.join(os.homedir(), ".pi", "agent", "npm");
|
|
142
|
-
|
|
199
|
+
rawLog("📦 Installing pi-subagents to " + piNpmDir + "…");
|
|
143
200
|
onProgress?.("installing");
|
|
144
201
|
try {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
timeout: 60_000,
|
|
148
|
-
encoding: "utf-8",
|
|
202
|
+
await execAsync(`npm install --prefix "${piNpmDir}" pi-subagents`, {
|
|
203
|
+
timeout: 120_000,
|
|
149
204
|
});
|
|
150
|
-
|
|
205
|
+
rawLog("✅ pi-subagents installed via npm.");
|
|
151
206
|
registerPiSubagentsPackage();
|
|
152
207
|
onProgress?.("done");
|
|
153
208
|
}
|
|
154
209
|
catch (firstErr) {
|
|
155
210
|
onProgress?.("failed");
|
|
156
|
-
|
|
211
|
+
rawError("⚠️ npm install failed: " +
|
|
157
212
|
(firstErr instanceof Error ? firstErr.message : String(firstErr)));
|
|
158
|
-
|
|
213
|
+
rawError("❌ Cannot proceed without pi-subagents. Extension disabled.");
|
|
159
214
|
return false;
|
|
160
215
|
}
|
|
161
216
|
// Verify installation took effect
|
|
162
217
|
if (fs.existsSync(piSubagentsPackageJson())) {
|
|
163
218
|
return true;
|
|
164
219
|
}
|
|
165
|
-
|
|
220
|
+
rawError("❌ pi-subagents installed but cannot be found at " +
|
|
166
221
|
piSubagentsDir() +
|
|
167
222
|
". Restart Pi and try again.");
|
|
168
223
|
return false;
|
|
@@ -170,7 +225,7 @@ async function checkDependencies(prompt, onProgress) {
|
|
|
170
225
|
/**
|
|
171
226
|
* Quick synchronous check: does pi-subagents exist on disk?
|
|
172
227
|
*/
|
|
173
|
-
function isSubagentsInstalled() {
|
|
228
|
+
export function isSubagentsInstalled() {
|
|
174
229
|
return fs.existsSync(piSubagentsPackageJson());
|
|
175
230
|
}
|
|
176
231
|
// ---------------------------------------------------------------------------
|
|
@@ -182,26 +237,26 @@ function isSubagentsInstalled() {
|
|
|
182
237
|
*
|
|
183
238
|
* @returns true if the template exists after this call
|
|
184
239
|
*/
|
|
185
|
-
function ensureReaderTemplate() {
|
|
240
|
+
export function ensureReaderTemplate() {
|
|
186
241
|
if (fs.existsSync(READER_TEMPLATE_PATH)) {
|
|
187
242
|
return true;
|
|
188
243
|
}
|
|
189
244
|
// Path to the bundled template (sibling to the compiled JS)
|
|
190
245
|
const bundledPath = path.join(__dirname, "templates", "reader.md");
|
|
191
246
|
if (!fs.existsSync(bundledPath)) {
|
|
192
|
-
|
|
193
|
-
|
|
247
|
+
rawWarn("⚠️ Bundled reader template not found at: " + bundledPath);
|
|
248
|
+
rawWarn("Please create ~/.pi/agent/agents/reader.md manually.");
|
|
194
249
|
return false;
|
|
195
250
|
}
|
|
196
251
|
try {
|
|
197
252
|
const content = fs.readFileSync(bundledPath, "utf-8");
|
|
198
253
|
ensureDir(path.dirname(READER_TEMPLATE_PATH));
|
|
199
254
|
fs.writeFileSync(READER_TEMPLATE_PATH, content, "utf-8");
|
|
200
|
-
|
|
255
|
+
rawLog(`✅ Created reader subagent template: ${READER_TEMPLATE_PATH}`);
|
|
201
256
|
return true;
|
|
202
257
|
}
|
|
203
258
|
catch (err) {
|
|
204
|
-
|
|
259
|
+
rawError("⚠️ Failed to create reader template: " + String(err));
|
|
205
260
|
return false;
|
|
206
261
|
}
|
|
207
262
|
}
|
|
@@ -218,7 +273,7 @@ function ensureReaderTemplate() {
|
|
|
218
273
|
* @returns The Reader's response text
|
|
219
274
|
* @throws ReaderError on timeout, failure, or empty response
|
|
220
275
|
*/
|
|
221
|
-
async function callReader(agent, config, task, timeoutMs = 30_000) {
|
|
276
|
+
export async function callReader(agent, config, task, timeoutMs = 30_000) {
|
|
222
277
|
const result = await withTimeout(agent.callSubagent({
|
|
223
278
|
name: config.reader_subagent_name,
|
|
224
279
|
task,
|
|
@@ -248,21 +303,21 @@ async function callReader(agent, config, task, timeoutMs = 30_000) {
|
|
|
248
303
|
* @returns Reader response on Retry/Allow; never returns on Cancel
|
|
249
304
|
* @throws ReaderError on Cancel or repeated failure
|
|
250
305
|
*/
|
|
251
|
-
async function handleReaderError(agent, config, blockedTools, error, task, prompt) {
|
|
306
|
+
export async function handleReaderError(agent, config, blockedTools, error, task, prompt) {
|
|
252
307
|
const errMsg = error instanceof Error ? error.message : String(error);
|
|
253
|
-
|
|
308
|
+
rawError(`❌ Reader failed: ${errMsg}`);
|
|
254
309
|
const answer = await prompt(`\n❌ Reader subagent failed: ${errMsg}\n` +
|
|
255
310
|
`[R]etry [A]llow once (let main model do it) [C]ancel\n`);
|
|
256
311
|
const choice = answer.trim().toLowerCase();
|
|
257
312
|
if (choice === "r" || choice === "retry") {
|
|
258
313
|
// Retry the same task
|
|
259
|
-
|
|
314
|
+
rawLog("🔄 Retrying Reader…");
|
|
260
315
|
return callReader(agent, config, task);
|
|
261
316
|
}
|
|
262
317
|
if (choice === "a" || choice === "allow" || choice === "allow once") {
|
|
263
318
|
// Temporarily unblock tools, let main model execute the task,
|
|
264
319
|
// then re-block.
|
|
265
|
-
|
|
320
|
+
rawLog("🔓 Allowing main model to read once…");
|
|
266
321
|
// NOTE: For "Allow once", we need the main model to perform the task.
|
|
267
322
|
// However, we are inside a tool call — the main model can't run code
|
|
268
323
|
// inline. We return a specially formatted string that instructs the
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* tool-blocker.ts — Tool removal and restoration for pi-read-delegator
|
|
4
3
|
*
|
|
@@ -9,14 +8,7 @@
|
|
|
9
8
|
*
|
|
10
9
|
* We store removed tool definitions in a Map so they can be restored later.
|
|
11
10
|
*/
|
|
12
|
-
|
|
13
|
-
exports.blockTools = blockTools;
|
|
14
|
-
exports.restoreTools = restoreTools;
|
|
15
|
-
exports.tempAllowOnce = tempAllowOnce;
|
|
16
|
-
exports.isBlocked = isBlocked;
|
|
17
|
-
exports.getBlockedTools = getBlockedTools;
|
|
18
|
-
exports.reset = reset;
|
|
19
|
-
const ui_1 = require("./ui");
|
|
11
|
+
import { rawLog, rawError } from "./ui";
|
|
20
12
|
// ---------------------------------------------------------------------------
|
|
21
13
|
// Tool blocker state
|
|
22
14
|
// ---------------------------------------------------------------------------
|
|
@@ -30,7 +22,7 @@ const removedTools = new Map();
|
|
|
30
22
|
* Saves their definitions so they can be restored later.
|
|
31
23
|
* If a tool is already removed, it is silently skipped.
|
|
32
24
|
*/
|
|
33
|
-
function blockTools(agent, tools) {
|
|
25
|
+
export function blockTools(agent, tools) {
|
|
34
26
|
const currentTools = agent.getTools();
|
|
35
27
|
for (const toolName of tools) {
|
|
36
28
|
// Skip if already removed
|
|
@@ -41,10 +33,10 @@ function blockTools(agent, tools) {
|
|
|
41
33
|
removedTools.set(toolName, definition);
|
|
42
34
|
try {
|
|
43
35
|
agent.removeTool(toolName);
|
|
44
|
-
|
|
36
|
+
rawLog(`Blocked tool: ${toolName}`);
|
|
45
37
|
}
|
|
46
38
|
catch (err) {
|
|
47
|
-
|
|
39
|
+
rawError(`Failed to block tool "${toolName}": ${err}`);
|
|
48
40
|
}
|
|
49
41
|
}
|
|
50
42
|
}
|
|
@@ -53,14 +45,14 @@ function blockTools(agent, tools) {
|
|
|
53
45
|
* Restore all previously blocked tools to the agent.
|
|
54
46
|
* If a tool was never removed, it is skipped.
|
|
55
47
|
*/
|
|
56
|
-
function restoreTools(agent) {
|
|
48
|
+
export function restoreTools(agent) {
|
|
57
49
|
for (const [toolName, definition] of removedTools.entries()) {
|
|
58
50
|
try {
|
|
59
51
|
agent.addTool(definition);
|
|
60
|
-
|
|
52
|
+
rawLog(`Restored tool: ${toolName}`);
|
|
61
53
|
}
|
|
62
54
|
catch (err) {
|
|
63
|
-
|
|
55
|
+
rawError(`Failed to restore tool "${toolName}": ${err}`);
|
|
64
56
|
}
|
|
65
57
|
}
|
|
66
58
|
removedTools.clear();
|
|
@@ -77,7 +69,7 @@ function restoreTools(agent) {
|
|
|
77
69
|
* @param callback Async function to run while tools are available
|
|
78
70
|
* @returns The callback's return value
|
|
79
71
|
*/
|
|
80
|
-
async function tempAllowOnce(agent, blockedTools, callback) {
|
|
72
|
+
export async function tempAllowOnce(agent, blockedTools, callback) {
|
|
81
73
|
// Restore temporarily
|
|
82
74
|
const restoredNow = [];
|
|
83
75
|
// We need to get the definitions from our map, but they might not be there
|
|
@@ -93,7 +85,7 @@ async function tempAllowOnce(agent, blockedTools, callback) {
|
|
|
93
85
|
restoredNow.push(toolName);
|
|
94
86
|
}
|
|
95
87
|
catch (err) {
|
|
96
|
-
|
|
88
|
+
rawError(`Failed to temporarily restore "${toolName}": ${err}`);
|
|
97
89
|
}
|
|
98
90
|
}
|
|
99
91
|
}
|
|
@@ -114,7 +106,7 @@ async function tempAllowOnce(agent, blockedTools, callback) {
|
|
|
114
106
|
agent.removeTool(toolName);
|
|
115
107
|
}
|
|
116
108
|
catch (err) {
|
|
117
|
-
|
|
109
|
+
rawError(`Failed to re-block "${toolName}": ${err}`);
|
|
118
110
|
}
|
|
119
111
|
}
|
|
120
112
|
}
|
|
@@ -123,19 +115,19 @@ async function tempAllowOnce(agent, blockedTools, callback) {
|
|
|
123
115
|
/**
|
|
124
116
|
* Check whether a given tool is currently blocked.
|
|
125
117
|
*/
|
|
126
|
-
function isBlocked(toolName) {
|
|
118
|
+
export function isBlocked(toolName) {
|
|
127
119
|
return removedTools.has(toolName);
|
|
128
120
|
}
|
|
129
121
|
/**
|
|
130
122
|
* Get the list of currently blocked tool names.
|
|
131
123
|
*/
|
|
132
|
-
function getBlockedTools() {
|
|
124
|
+
export function getBlockedTools() {
|
|
133
125
|
return Array.from(removedTools.keys());
|
|
134
126
|
}
|
|
135
127
|
/**
|
|
136
128
|
* Clear all blocked tool state (useful for testing / full reset).
|
|
137
129
|
*/
|
|
138
|
-
function reset() {
|
|
130
|
+
export function reset() {
|
|
139
131
|
removedTools.clear();
|
|
140
132
|
}
|
|
141
133
|
//# sourceMappingURL=tool-blocker.js.map
|
package/{ui.js → dist/ui.js}
RENAMED
|
@@ -1,59 +1,12 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* ui.ts — Localization, status bar, and logging for pi-read-delegator
|
|
4
3
|
*
|
|
5
4
|
* Detects the user's language preference (config → Pi settings → OS → "en")
|
|
6
5
|
* and provides localized messages. Manages a status bar indicator.
|
|
7
6
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
-
}
|
|
14
|
-
Object.defineProperty(o, k2, desc);
|
|
15
|
-
}) : (function(o, m, k, k2) {
|
|
16
|
-
if (k2 === undefined) k2 = k;
|
|
17
|
-
o[k2] = m[k];
|
|
18
|
-
}));
|
|
19
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
-
}) : function(o, v) {
|
|
22
|
-
o["default"] = v;
|
|
23
|
-
});
|
|
24
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
-
var ownKeys = function(o) {
|
|
26
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
-
var ar = [];
|
|
28
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
-
return ar;
|
|
30
|
-
};
|
|
31
|
-
return ownKeys(o);
|
|
32
|
-
};
|
|
33
|
-
return function (mod) {
|
|
34
|
-
if (mod && mod.__esModule) return mod;
|
|
35
|
-
var result = {};
|
|
36
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
-
__setModuleDefault(result, mod);
|
|
38
|
-
return result;
|
|
39
|
-
};
|
|
40
|
-
})();
|
|
41
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
-
exports.getLanguage = getLanguage;
|
|
43
|
-
exports.msg = msg;
|
|
44
|
-
exports.setLanguage = setLanguage;
|
|
45
|
-
exports.initStatusBar = initStatusBar;
|
|
46
|
-
exports.updateStatusBar = updateStatusBar;
|
|
47
|
-
exports.getStatus = getStatus;
|
|
48
|
-
exports.log = log;
|
|
49
|
-
exports.logError = logError;
|
|
50
|
-
exports.logWarn = logWarn;
|
|
51
|
-
exports.rawLog = rawLog;
|
|
52
|
-
exports.rawWarn = rawWarn;
|
|
53
|
-
exports.rawError = rawError;
|
|
54
|
-
const fs = __importStar(require("fs"));
|
|
55
|
-
const os = __importStar(require("os"));
|
|
56
|
-
const path = __importStar(require("path"));
|
|
7
|
+
import * as fs from "fs";
|
|
8
|
+
import * as os from "os";
|
|
9
|
+
import * as path from "path";
|
|
57
10
|
// ---------------------------------------------------------------------------
|
|
58
11
|
// Language detection
|
|
59
12
|
// ---------------------------------------------------------------------------
|
|
@@ -146,7 +99,7 @@ let currentLang = "en";
|
|
|
146
99
|
* 3. Operating system locale (first two chars)
|
|
147
100
|
* 4. Fallback "en"
|
|
148
101
|
*/
|
|
149
|
-
function getLanguage(configLang) {
|
|
102
|
+
export function getLanguage(configLang) {
|
|
150
103
|
// 1. Explicit config override
|
|
151
104
|
if (configLang && configLang !== "auto") {
|
|
152
105
|
currentLang = configLang;
|
|
@@ -188,7 +141,7 @@ function getLanguage(configLang) {
|
|
|
188
141
|
*
|
|
189
142
|
* Falls back to English if the current language doesn't have the key.
|
|
190
143
|
*/
|
|
191
|
-
function msg(key, lang) {
|
|
144
|
+
export function msg(key, lang) {
|
|
192
145
|
const langCode = lang ?? currentLang;
|
|
193
146
|
const entry = messages[key];
|
|
194
147
|
if (!entry)
|
|
@@ -198,7 +151,7 @@ function msg(key, lang) {
|
|
|
198
151
|
/**
|
|
199
152
|
* Explicitly set the current language (for /read-delegator lang <code>).
|
|
200
153
|
*/
|
|
201
|
-
function setLanguage(lang) {
|
|
154
|
+
export function setLanguage(lang) {
|
|
202
155
|
currentLang = lang;
|
|
203
156
|
}
|
|
204
157
|
// ---------------------------------------------------------------------------
|
|
@@ -209,14 +162,14 @@ let currentStatus = "idle";
|
|
|
209
162
|
/**
|
|
210
163
|
* Initialize the status bar with the given agent.
|
|
211
164
|
*/
|
|
212
|
-
function initStatusBar(agent) {
|
|
165
|
+
export function initStatusBar(agent) {
|
|
213
166
|
statusBarAgent = agent;
|
|
214
167
|
updateStatusBar("idle");
|
|
215
168
|
}
|
|
216
169
|
/**
|
|
217
170
|
* Update the status bar indicator.
|
|
218
171
|
*/
|
|
219
|
-
function updateStatusBar(status) {
|
|
172
|
+
export function updateStatusBar(status) {
|
|
220
173
|
currentStatus = status;
|
|
221
174
|
if (!statusBarAgent)
|
|
222
175
|
return;
|
|
@@ -245,7 +198,7 @@ function updateStatusBar(status) {
|
|
|
245
198
|
/**
|
|
246
199
|
* Get the current status.
|
|
247
200
|
*/
|
|
248
|
-
function getStatus() {
|
|
201
|
+
export function getStatus() {
|
|
249
202
|
return currentStatus;
|
|
250
203
|
}
|
|
251
204
|
// ---------------------------------------------------------------------------
|
|
@@ -256,7 +209,7 @@ function getStatus() {
|
|
|
256
209
|
*
|
|
257
210
|
* Prepend "[pi-read-delegator]" for easy filtering.
|
|
258
211
|
*/
|
|
259
|
-
function log(key, detail) {
|
|
212
|
+
export function log(key, detail) {
|
|
260
213
|
const prefix = "[pi-read-delegator]";
|
|
261
214
|
const message = msg(key);
|
|
262
215
|
if (detail) {
|
|
@@ -269,7 +222,7 @@ function log(key, detail) {
|
|
|
269
222
|
/**
|
|
270
223
|
* Log an error with the standard prefix.
|
|
271
224
|
*/
|
|
272
|
-
function logError(key, detail) {
|
|
225
|
+
export function logError(key, detail) {
|
|
273
226
|
const prefix = "[pi-read-delegator]";
|
|
274
227
|
const message = msg(key);
|
|
275
228
|
const full = detail ? `${message}${detail}` : message;
|
|
@@ -278,7 +231,7 @@ function logError(key, detail) {
|
|
|
278
231
|
/**
|
|
279
232
|
* Log a warning with the standard prefix.
|
|
280
233
|
*/
|
|
281
|
-
function logWarn(key, detail) {
|
|
234
|
+
export function logWarn(key, detail) {
|
|
282
235
|
const prefix = "[pi-read-delegator]";
|
|
283
236
|
const message = msg(key);
|
|
284
237
|
const full = detail ? `${message}${detail}` : message;
|
|
@@ -287,13 +240,13 @@ function logWarn(key, detail) {
|
|
|
287
240
|
// Raw logging — bypass i18n lookup for extension-internal messages.
|
|
288
241
|
// These are the single source of console.* calls; everywhere else routes
|
|
289
242
|
// through these helpers so pi-lens console-statement checks pass cleanly.
|
|
290
|
-
function rawLog(message) {
|
|
243
|
+
export function rawLog(message) {
|
|
291
244
|
console.log(`[pi-read-delegator] ${message}`);
|
|
292
245
|
}
|
|
293
|
-
function rawWarn(message) {
|
|
246
|
+
export function rawWarn(message) {
|
|
294
247
|
console.warn(`[pi-read-delegator] ${message}`);
|
|
295
248
|
}
|
|
296
|
-
function rawError(message) {
|
|
249
|
+
export function rawError(message) {
|
|
297
250
|
console.error(`[pi-read-delegator] ${message}`);
|
|
298
251
|
}
|
|
299
252
|
//# sourceMappingURL=ui.js.map
|
package/package.json
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stfade/pi-read-delegator",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.13",
|
|
4
4
|
"description": "Pi extension that delegates all read operations to a Reader subagent, blocking read tools from the main model",
|
|
5
|
-
"main": "index.js",
|
|
6
|
-
"types": "index.d.ts",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
7
|
"pi-extension": true,
|
|
8
8
|
"files": [
|
|
9
|
-
"index.js",
|
|
10
|
-
"index.d.ts",
|
|
11
|
-
"config.js",
|
|
12
|
-
"config.d.ts",
|
|
13
|
-
"tool-blocker.js",
|
|
14
|
-
"tool-blocker.d.ts",
|
|
15
|
-
"bash-filter.js",
|
|
16
|
-
"bash-filter.d.ts",
|
|
17
|
-
"reader-manager.js",
|
|
18
|
-
"reader-manager.d.ts",
|
|
19
|
-
"ui.js",
|
|
20
|
-
"ui.d.ts",
|
|
21
|
-
"templates/reader.md"
|
|
9
|
+
"dist/index.js",
|
|
10
|
+
"dist/index.d.ts",
|
|
11
|
+
"dist/config.js",
|
|
12
|
+
"dist/config.d.ts",
|
|
13
|
+
"dist/tool-blocker.js",
|
|
14
|
+
"dist/tool-blocker.d.ts",
|
|
15
|
+
"dist/bash-filter.js",
|
|
16
|
+
"dist/bash-filter.d.ts",
|
|
17
|
+
"dist/reader-manager.js",
|
|
18
|
+
"dist/reader-manager.d.ts",
|
|
19
|
+
"dist/ui.js",
|
|
20
|
+
"dist/ui.d.ts",
|
|
21
|
+
"dist/templates/reader.md"
|
|
22
22
|
],
|
|
23
23
|
"scripts": {
|
|
24
24
|
"build": "tsc",
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
"author": "",
|
|
35
35
|
"license": "MIT",
|
|
36
36
|
"devDependencies": {
|
|
37
|
+
"@earendil-works/pi-coding-agent": "^0.79.3",
|
|
37
38
|
"@types/node": "^20.0.0",
|
|
38
39
|
"typescript": "^5.4.0"
|
|
39
40
|
},
|
|
@@ -44,6 +45,8 @@
|
|
|
44
45
|
"node": ">=18"
|
|
45
46
|
},
|
|
46
47
|
"pi": {
|
|
47
|
-
"extensions": [
|
|
48
|
+
"extensions": [
|
|
49
|
+
"dist/index.js"
|
|
50
|
+
]
|
|
48
51
|
}
|
|
49
52
|
}
|