pi-tool-discipline 0.1.9 → 0.1.10

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.
@@ -53,6 +53,7 @@ async function walk(dir: string, out: string[], state: WalkState, signal?: Abort
53
53
  try {
54
54
  entries = await readdir(dir);
55
55
  } catch (error: any) {
56
+ throwIfAborted(signal); // cancellation wins over the fs error
56
57
  if (depth === 0) state.rootError = error?.message ?? String(error);
57
58
  return;
58
59
  }
@@ -84,7 +85,7 @@ async function walk(dir: string, out: string[], state: WalkState, signal?: Abort
84
85
  */
85
86
  function truncate(text: string, maxBytes = MAX_OUTPUT_BYTES, extraMarkerBytes = 0): string {
86
87
  const buf = Buffer.from(text, "utf8");
87
- if (buf.length <= maxBytes) return text;
88
+ if (buf.length + extraMarkerBytes <= maxBytes) return text;
88
89
  const budget = maxBytes - Buffer.byteLength(TRUNCATE_MARKER) - extraMarkerBytes;
89
90
  if (budget <= 0) return TRUNCATE_MARKER.trim();
90
91
  const cut = buf.subarray(0, budget).toString("utf8");
@@ -93,12 +94,14 @@ function truncate(text: string, maxBytes = MAX_OUTPUT_BYTES, extraMarkerBytes =
93
94
  return `${cut.slice(0, lastNewline)}\n${TRUNCATE_MARKER}`;
94
95
  }
95
96
 
96
- async function resolveRoot(cwd: string, sub?: string): Promise<string | null> {
97
+ async function resolveRoot(cwd: string, sub?: string, signal?: AbortSignal): Promise<string | null> {
97
98
  const root = resolve(cwd, sub || ".");
98
99
  try {
99
100
  const st = await stat(root);
101
+ throwIfAborted(signal);
100
102
  return st.isDirectory() ? root : null;
101
- } catch {
103
+ } catch (error: any) {
104
+ throwIfAborted(signal);
102
105
  return null;
103
106
  }
104
107
  }
@@ -118,7 +121,7 @@ export async function grepFiles(opts: {
118
121
  signal?: AbortSignal;
119
122
  }): Promise<string> {
120
123
  throwIfAborted(opts.signal);
121
- const root = await resolveRoot(opts.cwd, opts.path);
124
+ const root = await resolveRoot(opts.cwd, opts.path, opts.signal);
122
125
  if (!root) return `Error: search path not found: ${resolve(opts.cwd, opts.path || ".")}`;
123
126
  const pattern = opts.caseSensitive ? opts.pattern : opts.pattern.toLowerCase();
124
127
  const limit = opts.maxResults ?? 100;
@@ -130,14 +133,16 @@ export async function grepFiles(opts: {
130
133
  if (matches.length >= limit) break;
131
134
  try {
132
135
  if ((await stat(file)).size > MAX_FILE_BYTES) continue; // cap only before reading content
133
- } catch {
136
+ } catch (error: any) {
137
+ throwIfAborted(opts.signal);
134
138
  continue;
135
139
  }
136
140
  throwIfAborted(opts.signal);
137
141
  let content: string;
138
142
  try {
139
143
  content = await readFile(file, "utf8");
140
- } catch {
144
+ } catch (error: any) {
145
+ throwIfAborted(opts.signal);
141
146
  continue;
142
147
  }
143
148
  throwIfAborted(opts.signal);
@@ -167,7 +172,7 @@ export async function findFiles(opts: {
167
172
  signal?: AbortSignal;
168
173
  }): Promise<string> {
169
174
  throwIfAborted(opts.signal);
170
- const root = await resolveRoot(opts.cwd, opts.path);
175
+ const root = await resolveRoot(opts.cwd, opts.path, opts.signal);
171
176
  if (!root) return `Error: search path not found: ${resolve(opts.cwd, opts.path || ".")}`;
172
177
  const { files, state } = await walkFiles(root, opts.signal);
173
178
  if (state.rootError) return `Error: cannot read search root ${root}: ${state.rootError}`;
@@ -193,7 +198,7 @@ export async function findFiles(opts: {
193
198
 
194
199
  export async function listDir(opts: { path?: string; cwd: string; signal?: AbortSignal }): Promise<string> {
195
200
  throwIfAborted(opts.signal);
196
- const root = await resolveRoot(opts.cwd, opts.path);
201
+ const root = await resolveRoot(opts.cwd, opts.path, opts.signal);
197
202
  if (!root) return `Error: directory not found: ${resolve(opts.cwd, opts.path || ".")}`;
198
203
  try {
199
204
  const entries = await readdir(root);
@@ -201,7 +206,7 @@ export async function listDir(opts: { path?: string; cwd: string; signal?: Abort
201
206
  if (entries.length === 0) return "(empty directory)";
202
207
  return truncate(entries.join("\n"));
203
208
  } catch (error: any) {
204
- if (error?.message === "Operation aborted") throw error;
209
+ throwIfAborted(opts.signal);
205
210
  return `Error listing ${root}: ${error.message}`;
206
211
  }
207
212
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-tool-discipline",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": "pi extension: enforce ffgrep/fffind-first search discipline and neutralize the default bash file-operation guideline",
5
5
  "type": "module",
6
6
  "license": "MIT",