@mjasnikovs/pi-task 0.13.28 → 0.13.29

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.
@@ -4,6 +4,16 @@
4
4
  * read/grep on known paths. Returns '' on failure (non-git repo, git missing,
5
5
  * timeout) so callers can fall back to the pre-inventory behavior.
6
6
  */
7
+ /**
8
+ * Drop the committed task directory from the inventory. `git ls-files` lists
9
+ * tracked files regardless of `.ignore`, so once tasks are committed they would
10
+ * otherwise be handed to every research worker (and feed orientation). The user
11
+ * wants tasks committable but invisible to workers and the local model, so we
12
+ * strip `.pi-tasks/` here — the inventory's single chokepoint. (`git ls-files`
13
+ * always emits posix-style paths, so the forward-slash prefix is correct on all
14
+ * platforms.)
15
+ */
16
+ export declare function stripTasksDir(raw: string): string;
7
17
  /** Cap output to maxLines real (non-blank) paths; tag truncation when cut. */
8
18
  export declare function capInventory(raw: string, maxLines?: number): string;
9
19
  export declare function getFileInventory(cwd: string, signal?: AbortSignal, maxLines?: number): Promise<string>;
@@ -5,7 +5,24 @@
5
5
  * timeout) so callers can fall back to the pre-inventory behavior.
6
6
  */
7
7
  import { spawn } from 'node:child_process';
8
+ import { TASKS_DIR_NAME } from './task-types.js';
8
9
  const DEFAULT_MAX_LINES = 2000;
10
+ /**
11
+ * Drop the committed task directory from the inventory. `git ls-files` lists
12
+ * tracked files regardless of `.ignore`, so once tasks are committed they would
13
+ * otherwise be handed to every research worker (and feed orientation). The user
14
+ * wants tasks committable but invisible to workers and the local model, so we
15
+ * strip `.pi-tasks/` here — the inventory's single chokepoint. (`git ls-files`
16
+ * always emits posix-style paths, so the forward-slash prefix is correct on all
17
+ * platforms.)
18
+ */
19
+ export function stripTasksDir(raw) {
20
+ const prefix = `${TASKS_DIR_NAME}/`;
21
+ return raw
22
+ .split('\n')
23
+ .filter(l => !l.startsWith(prefix))
24
+ .join('\n');
25
+ }
9
26
  function runGitLsFiles(cwd, signal) {
10
27
  return new Promise(resolve => {
11
28
  let stdout = '';
@@ -40,5 +57,5 @@ export async function getFileInventory(cwd, signal, maxLines = DEFAULT_MAX_LINES
40
57
  const raw = await runGitLsFiles(cwd, signal);
41
58
  if (!raw)
42
59
  return '';
43
- return capInventory(raw, maxLines);
60
+ return capInventory(stripTasksDir(raw), maxLines);
44
61
  }
@@ -7,6 +7,10 @@
7
7
  import { type TaskFrontMatter } from './task-types.js';
8
8
  export declare function tasksDir(cwd: string): string;
9
9
  export declare function taskFilePath(cwd: string, id: string): string;
10
+ /**
11
+ * Create .pi-tasks/ and, if absent, its `.ignore`. The ignore file is written
12
+ * only when missing so a hand-edited one is never clobbered.
13
+ */
10
14
  export declare function ensureTasksDir(cwd: string): Promise<void>;
11
15
  export declare function allocateTaskId(cwd: string): Promise<string>;
12
16
  export declare function readTaskFile(cwd: string, id: string): Promise<{
@@ -15,8 +15,32 @@ export function tasksDir(cwd) {
15
15
  export function taskFilePath(cwd, id) {
16
16
  return path.join(tasksDir(cwd), `${id}.md`);
17
17
  }
18
+ /**
19
+ * `.ignore` body written into .pi-tasks/ so pi's discovery tools skip it. fd and
20
+ * ripgrep (the find/grep tools the host model AND the research workers use) honor
21
+ * `.ignore`, but git does NOT — so task files stay committable while no worker or
22
+ * the local model ever surfaces them via search. `*` hides the whole directory's
23
+ * contents; the leading comment explains the file to anyone who opens it. This
24
+ * only affects discovery: pi-task reads task files by direct path (see
25
+ * readTaskFile), which no ignore mechanism intercepts.
26
+ */
27
+ const TASKS_IGNORE_BODY = '# Keep committed task files out of pi find/grep discovery (host model + '
28
+ + 'research\n# workers) while git still tracks them. .ignore is read by '
29
+ + 'fd/ripgrep, not by\n# git, so tasks stay committable. Managed by pi-task.\n*\n';
30
+ /**
31
+ * Create .pi-tasks/ and, if absent, its `.ignore`. The ignore file is written
32
+ * only when missing so a hand-edited one is never clobbered.
33
+ */
18
34
  export async function ensureTasksDir(cwd) {
19
- await fsp.mkdir(tasksDir(cwd), { recursive: true });
35
+ const dir = tasksDir(cwd);
36
+ await fsp.mkdir(dir, { recursive: true });
37
+ const ignorePath = path.join(dir, '.ignore');
38
+ try {
39
+ await fsp.access(ignorePath);
40
+ }
41
+ catch {
42
+ await fsp.writeFile(ignorePath, TASKS_IGNORE_BODY, 'utf8');
43
+ }
20
44
  }
21
45
  export async function allocateTaskId(cwd) {
22
46
  await ensureTasksDir(cwd);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mjasnikovs/pi-task",
3
- "version": "0.13.28",
3
+ "version": "0.13.29",
4
4
  "description": "Deterministic spec-orchestration for local models, with a bundled real-time remote web view and web/docs/fetch/worker subagent tools.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",