@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/bash-filter.js DELETED
@@ -1,242 +0,0 @@
1
- "use strict";
2
- /**
3
- * bash-filter.ts — Bash command classification and Reader forwarding
4
- *
5
- * Classifies shell commands as read-only (delegate to Reader subagent),
6
- * write (execute directly), or ambiguous (prompt user).
7
- */
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.isReadCommand = isReadCommand;
10
- exports.isWriteCommand = isWriteCommand;
11
- exports.wrapForReader = wrapForReader;
12
- exports.wrapTaskForReader = wrapTaskForReader;
13
- // ---------------------------------------------------------------------------
14
- // Command lists
15
- // ---------------------------------------------------------------------------
16
- /**
17
- * Commands that ONLY read and should be forwarded to the Reader subagent.
18
- * - sed without -i is read-only (stream editor writing to stdout).
19
- * - awk is read-only (pattern scanning and processing language).
20
- */
21
- const READ_COMMANDS = new Set([
22
- "cat",
23
- "grep",
24
- "find",
25
- "ls",
26
- "head",
27
- "tail",
28
- "less",
29
- "wc",
30
- "nl",
31
- "more",
32
- "bat",
33
- "rg",
34
- "fd",
35
- "awk",
36
- "du",
37
- "df",
38
- "stat",
39
- "file",
40
- "which",
41
- "where",
42
- "type",
43
- "dir",
44
- ]);
45
- /**
46
- * Commands that write to the filesystem and should execute directly.
47
- * sed and tee are context-dependent — handled specially in isWriteCommand.
48
- */
49
- const WRITE_COMMANDS = new Set([
50
- "mkdir",
51
- "touch",
52
- "echo",
53
- "rm",
54
- "mv",
55
- "cp",
56
- "chmod",
57
- "chown",
58
- "ln",
59
- "rmdir",
60
- "npm",
61
- "pnpm",
62
- "yarn",
63
- "pip",
64
- "cargo",
65
- "go",
66
- "npx",
67
- "node",
68
- "python",
69
- "python3",
70
- "git",
71
- "docker",
72
- "kubectl",
73
- "tsc",
74
- "make",
75
- "cmake",
76
- "dotnet",
77
- "rustc",
78
- "gcc",
79
- "g++",
80
- ]);
81
- // ---------------------------------------------------------------------------
82
- // Public API
83
- // ---------------------------------------------------------------------------
84
- /**
85
- * Determine if a bash command is read-only and should be forwarded to Reader.
86
- *
87
- * Rules:
88
- * - If the first word is in READ_COMMANDS → true
89
- * - sed without -i flag → true (read-only stream edit)
90
- * - sed with -i → false (in-place edit = write)
91
- */
92
- function isReadCommand(command) {
93
- const argv = parseArgv(command);
94
- if (argv.length === 0)
95
- return false;
96
- const cmd = argv[0].toLowerCase();
97
- // sed is special: if -i is present, it's a write; otherwise read-only
98
- if (cmd === "sed" || cmd === "sed.exe") {
99
- return !hasInlineFlag(argv);
100
- }
101
- return READ_COMMANDS.has(cmd);
102
- }
103
- /**
104
- * Determine if a bash command modifies the filesystem and should run directly.
105
- *
106
- * Rules:
107
- * - If the first word is in WRITE_COMMANDS → true
108
- * - sed with -i flag → true (in-place edit)
109
- * - Command contains > or >> redirect → true (writes to file)
110
- * - Command contains tee without -a flag → true (writes to file)
111
- */
112
- function isWriteCommand(command) {
113
- const argv = parseArgv(command);
114
- if (argv.length === 0)
115
- return false;
116
- const cmd = argv[0].toLowerCase();
117
- // sed with -i = write
118
- if (cmd === "sed" || cmd === "sed.exe") {
119
- return hasInlineFlag(argv);
120
- }
121
- if (WRITE_COMMANDS.has(cmd))
122
- return true;
123
- // Check for output redirection markers (> or >>)
124
- // We do a simple string match outside the parsed argv because parseArgv
125
- // might stop at the redirect operator.
126
- if (/\b>>?\b/.test(command))
127
- return true;
128
- // tee is ambiguous: if -a (append) it's write, otherwise also write
129
- if (cmd === "tee" || cmd === "tee.exe")
130
- return true;
131
- return false;
132
- }
133
- /**
134
- * Wrap a shell command into a Reader subagent task.
135
- *
136
- * Returns a formatted string instructing the Reader to execute and report
137
- * minimal results.
138
- */
139
- function wrapForReader(command) {
140
- return [
141
- "Execute this shell command and return ONLY the essential result.",
142
- "Max 5 lines or a single number. Never dump full file contents.",
143
- `Command: ${command}`,
144
- ].join("\n");
145
- }
146
- /**
147
- * Wrap a generic task (non-bash) into a Reader subagent task.
148
- */
149
- function wrapTaskForReader(task) {
150
- return [
151
- "Execute this task and return ONLY the essential result.",
152
- "Max 5 lines or a single number. Never dump full file contents.",
153
- `Task: ${task}`,
154
- ].join("\n");
155
- }
156
- // ---------------------------------------------------------------------------
157
- // Internals
158
- // ---------------------------------------------------------------------------
159
- /**
160
- * Parse a command string into argv tokens, respecting single/double quotes.
161
- *
162
- * This is a simplified parser — edge cases like escaped quotes inside
163
- * opposite-quoted strings are handled on a best-effort basis.
164
- */
165
- function parseArgv(command) {
166
- const tokens = [];
167
- let current = "";
168
- let inSingle = false;
169
- let inDouble = false;
170
- for (let i = 0; i < command.length; i++) {
171
- const ch = command[i];
172
- if (inSingle) {
173
- if (ch === "'") {
174
- inSingle = false;
175
- }
176
- else {
177
- current += ch;
178
- }
179
- }
180
- else if (inDouble) {
181
- if (ch === '"') {
182
- inDouble = false;
183
- }
184
- else if (ch === "\\" && i + 1 < command.length) {
185
- // Simple escape handling inside double quotes
186
- const next = command[i + 1];
187
- if (next === '"' || next === "\\" || next === "$" || next === "`") {
188
- current += next;
189
- i++;
190
- }
191
- else {
192
- current += ch;
193
- }
194
- }
195
- else {
196
- current += ch;
197
- }
198
- }
199
- else {
200
- if (ch === "'") {
201
- inSingle = true;
202
- }
203
- else if (ch === '"') {
204
- inDouble = true;
205
- }
206
- else if (ch === " " || ch === "\t") {
207
- if (current.length > 0) {
208
- tokens.push(current);
209
- current = "";
210
- }
211
- }
212
- else {
213
- current += ch;
214
- }
215
- }
216
- }
217
- // Flush remaining token
218
- if (current.length > 0) {
219
- tokens.push(current);
220
- }
221
- return tokens;
222
- }
223
- /**
224
- * Check whether `sed` has the -i (in-place) flag.
225
- */
226
- function hasInlineFlag(argv) {
227
- for (let i = 1; i < argv.length; i++) {
228
- const arg = argv[i];
229
- // -i, -i.bak, --in-place, --in-place=.bak
230
- if (arg === "-i" || arg.startsWith("-i.") || arg === "--in-place") {
231
- return true;
232
- }
233
- if (arg.startsWith("--in-place=")) {
234
- return true;
235
- }
236
- // Stop at the expression (s/.../.../ or -e '...') — flags after that
237
- // might apply to the expression, not sed itself. In practice, -i always
238
- // comes before the expression.
239
- }
240
- return false;
241
- }
242
- //# sourceMappingURL=bash-filter.js.map
@@ -1,8 +0,0 @@
1
- ---
2
- name: reader
3
- description: Read-only file agent that returns minimal results
4
- tools: read, grep, find, ls
5
- model: lmstudio/nemotron-mini
6
- ---
7
-
8
- You are a token-efficient assistant. Execute read/search tasks and return ONLY the essential result. Max 5 lines or a single number. Never dump files. If running a shell command, return only the output, nothing else.
File without changes
File without changes
File without changes