@mjasnikovs/pi-task 0.18.9 → 0.18.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.
@@ -201,8 +201,18 @@ export function runBootCheck(cwd, [bin, args], graceMs = 10_000) {
201
201
  };
202
202
  const killGroup = (sig) => {
203
203
  try {
204
- if (child.pid)
204
+ if (!child.pid)
205
+ return;
206
+ if (process.platform === 'win32') {
207
+ // Windows has no process groups / negative-pid kill. taskkill
208
+ // /T tears down the whole tree (the detached child plus any
209
+ // grandchildren it spawned); /F forces it, so the SIGTERM→
210
+ // SIGKILL escalation collapses to one idempotent call.
211
+ spawnSync('taskkill', ['/pid', String(child.pid), '/T', '/F']);
212
+ }
213
+ else {
205
214
  process.kill(-child.pid, sig);
215
+ }
206
216
  }
207
217
  catch {
208
218
  // group already gone
@@ -2,6 +2,7 @@
2
2
  * Phase pipeline — the five phase functions (refine, research, grill, compose,
3
3
  * critique) plus the config table that drives the orchestrator loop.
4
4
  */
5
+ import { fileURLToPath } from 'node:url';
5
6
  import { docsFocused } from '../workers/docs-core.js';
6
7
  import { fetchFocused } from '../workers/fetch-core.js';
7
8
  import { formatNpmVersionSection } from '../workers/npm-version.js';
@@ -159,13 +160,13 @@ export async function phaseVerifyTooling(deps, research) {
159
160
  await setTaskSection(deps.cwd, deps.taskId, 'verified tooling', verifiedSection);
160
161
  return replaceToolingWithVerified(research, parsed.verified);
161
162
  }
162
- const DOCS_EXTENSION_PATH = new URL('../workers/docs-extension.js', import.meta.url).pathname;
163
+ const DOCS_EXTENSION_PATH = fileURLToPath(new URL('../workers/docs-extension.js', import.meta.url));
163
164
  /** pi-worker-search + pi-worker-fetch, loaded into the APIS research worker only
164
165
  * when a Brave key is configured (the tool without a key just errors, and a weak
165
166
  * model burns calls on it). Search being absent from the research toolset was
166
167
  * STRUCTURAL: three consecutive audited runs made 0 search calls because the
167
168
  * child literally did not have the tool. */
168
- const SEARCH_EXTENSION_PATH = new URL('../workers/search-extension.js', import.meta.url).pathname;
169
+ const SEARCH_EXTENSION_PATH = fileURLToPath(new URL('../workers/search-extension.js', import.meta.url));
169
170
  /**
170
171
  * Is live web search configured for this process? The keyless providers (exa,
171
172
  * ddg) always are; only brave needs its API key — mirrors search-core's lookup.
@@ -191,8 +192,7 @@ export const RESEARCH_SEARCH_HINT = '\n\nLIVE WEB — use pi-worker-search for e
191
192
  * healthy recorded run, so neither rule has a legitimate false positive here.
192
193
  * See single-read-guard.ts.
193
194
  */
194
- const SINGLE_READ_EXTENSION_PATH = new URL('../workers/single-read-extension.js', import.meta.url)
195
- .pathname;
195
+ const SINGLE_READ_EXTENSION_PATH = fileURLToPath(new URL('../workers/single-read-extension.js', import.meta.url));
196
196
  /**
197
197
  * Task-file heading under which a research worker's validated output is cached.
198
198
  * A resumed research phase reads these to skip workers that already succeeded,
@@ -145,7 +145,10 @@ function ingestBody(cache, pkg, contentHash) {
145
145
  let filesIngested = 0;
146
146
  const insertChunk = cache.db.prepare('INSERT INTO chunks (name, version, file_path, kind, content) VALUES (?, ?, ?, ?, ?)');
147
147
  for (const abs of files.dts) {
148
- const rel = path.relative(pkg.root, abs);
148
+ // Store the file identifier POSIX-style so indexed docs are identical
149
+ // across platforms (this value is a model-facing label, never re-joined
150
+ // to the filesystem — node reads forward slashes fine on Windows too).
151
+ const rel = path.relative(pkg.root, abs).replace(/\\/g, '/');
149
152
  let raw;
150
153
  try {
151
154
  raw = fs.readFileSync(abs, 'utf8');
@@ -163,7 +166,7 @@ function ingestBody(cache, pkg, contentHash) {
163
166
  }
164
167
  }
165
168
  if (files.readme) {
166
- const rel = path.relative(pkg.root, files.readme);
169
+ const rel = path.relative(pkg.root, files.readme).replace(/\\/g, '/');
167
170
  const raw = fs.readFileSync(files.readme, 'utf8');
168
171
  const chunks = chunkReadme(raw);
169
172
  if (chunks.length) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mjasnikovs/pi-task",
3
- "version": "0.18.9",
3
+ "version": "0.18.10",
4
4
  "description": "Deterministic task planning and spec-orchestration for local models — crash-safe /task pipelines with verify/enforce gates, a real-time remote web view, and web/docs/fetch/worker subagent tools.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -14,7 +14,7 @@
14
14
  "scripts": {
15
15
  "build": "tsc -p tsconfig.build.json",
16
16
  "lint": "prettier --log-level warn --write 'src/**/*.ts' && eslint --fix . && tsc --noEmit",
17
- "test": "AGENT=1 bun test src/",
17
+ "test": "cross-env AGENT=1 bun test --isolate src/",
18
18
  "prepublishOnly": "bun run build"
19
19
  },
20
20
  "peerDependencies": {
@@ -36,12 +36,12 @@
36
36
  "@earendil-works/pi-coding-agent": "0.80.2",
37
37
  "@earendil-works/pi-tui": "0.80.2",
38
38
  "@eslint/js": "10.0.1",
39
- "@sinclair/typebox": "0.34.49",
40
39
  "@types/bun": "1.3.12",
41
40
  "@types/qrcode": "1.5.6",
42
41
  "@types/turndown": "5.0.6",
43
42
  "@types/web-push": "3.6.4",
44
43
  "@types/ws": "8.18.1",
44
+ "cross-env": "^10.1.0",
45
45
  "eslint": "10.2.1",
46
46
  "globals": "17.5.0",
47
47
  "prettier": "3.8.3",