pi-task-tracker 0.2.2 → 0.2.4
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 +1 -1
- package/index.ts +19 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -76,7 +76,7 @@ Optional `taskTracker` key in `~/.pi/agent/settings.json` (all default to `true`
|
|
|
76
76
|
- `readme` — maintain the `README.md` project-structure section
|
|
77
77
|
- `autoCommit` — per-task commits; these are the `/rollback` checkpoints, so disabling this also disables rollback targets
|
|
78
78
|
- `guard` — master switch for the built-in permission layer (default `true`). Set `false` to defer permission decisions entirely to another extension (e.g. `pi-permission-system`): no external-write checks, no git-ask prompts, no cd sandbox.
|
|
79
|
-
- `externalWrite` — policy for tool calls that would create/modify files OUTSIDE the session directory: `"block"` (default, hard deny — external changes cannot be tracked or rolled back), `"ask"` (per-attempt confirmation), `"off"` (no enforcement; `pi-permission-system` rules still apply). Reads stay free. Copying files FROM outside INTO the session is allowed (`cp` checks only its destination); moving/deleting external paths is blocked. Everything INSIDE the session directory passes by default — the only sandbox-internal intervention is the `cd` disable. Git history protection is **inherited**: history-rewriting git (rebase/reset/amend/force-push/clean/...) prompts for confirmation right here, so `pi-permission-system` can be uninstalled without losing that layer; routine git passes untouched, an external `git init`/`clone` is allowed with a heads-up that the new repo is not tracked. Shell commands are analyzed statically (redirects, `rm/mv/cp/touch/...`, `cd` tracking, PowerShell equivalents); git protection is inherited from `pi-permission-system` — routine git passes untouched and history-rewriting git still prompts there; only redirect targets and `-C` destinations on git segments are checked. **`cd
|
|
79
|
+
- `externalWrite` — policy for tool calls that would create/modify files OUTSIDE the session directory: `"block"` (default, hard deny — external changes cannot be tracked or rolled back), `"ask"` (per-attempt confirmation), `"off"` (no enforcement; `pi-permission-system` rules still apply). Reads stay free. Copying files FROM outside INTO the session is allowed (`cp` checks only its destination); moving/deleting external paths is blocked. Everything INSIDE the session directory passes by default — the only sandbox-internal intervention is the `cd` disable. Git history protection is **inherited**: history-rewriting git (rebase/reset/amend/force-push/clean/...) prompts for confirmation right here, so `pi-permission-system` can be uninstalled without losing that layer; routine git passes untouched, an external `git init`/`clone` is allowed with a heads-up that the new repo is not tracked. Shell commands are analyzed statically (redirects, `rm/mv/cp/touch/...`, `cd` tracking, PowerShell equivalents); git protection is inherited from `pi-permission-system` — routine git passes untouched and history-rewriting git still prompts there; only redirect targets and `-C` destinations on git segments are checked. **`cd` is free inside the session directory; a `cd` that would move the working directory outside it is blocked** (that is the one operation that changes pi's effective scope). No cd-tracking is performed — resolution baseline stays the session root, so a deep in-session `cd` followed by enough `../` levels to escape may over-block, which is the fail-safe direction.
|
|
80
80
|
|
|
81
81
|
## Requirements
|
|
82
82
|
|
package/index.ts
CHANGED
|
@@ -110,7 +110,7 @@ function findEnclosingRepo(dir: string): string | null {
|
|
|
110
110
|
// ---- External-write guard ----
|
|
111
111
|
// Enforces the tracking boundary as a write boundary: pi-task-tracker can
|
|
112
112
|
// only track (and therefore only roll back) the session directory, so by
|
|
113
|
-
// default (config taskTracker.externalWrite="
|
|
113
|
+
// default (config taskTracker.externalWrite="ask") tool calls that would
|
|
114
114
|
// create/modify files OUTSIDE it are denied. Reads stay free. Git command
|
|
115
115
|
// protection is inherited from pi-permission-system's bash rules (rebase/
|
|
116
116
|
// reset/amend/force-push/... ask there): this guard never inspects git
|
|
@@ -184,8 +184,20 @@ function guardShellExternalWrite(cmd: string, sessionCwd: string): { block?: str
|
|
|
184
184
|
const out: { block?: string; ask?: string; notify?: string } = {};
|
|
185
185
|
for (const seg of segments) {
|
|
186
186
|
if (/^(cd|sl|set-location)\s/i.test(seg)) {
|
|
187
|
-
|
|
188
|
-
|
|
187
|
+
// only a cd that would move the working directory OUTSIDE the session
|
|
188
|
+
// is stopped; in-session cd is free. Resolution baseline stays
|
|
189
|
+
// sessionCwd (no cd tracking) - documented limitation: a deep in-session
|
|
190
|
+
// cd followed by enough ../ levels to escape the session may over-block,
|
|
191
|
+
// which is the fail-safe direction.
|
|
192
|
+
const arg = seg.replace(/^(cd|sl|set-location)\s+/i, "").trim();
|
|
193
|
+
if (arg) {
|
|
194
|
+
const r = guardResolve(sessionCwd, arg);
|
|
195
|
+
if (r.external) {
|
|
196
|
+
out.block = r.abs;
|
|
197
|
+
return out;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
continue;
|
|
189
201
|
}
|
|
190
202
|
// 2. redirects: > >> 2> 2>> &> &>> >| (not heredocs, not fd dups like 2>&1)
|
|
191
203
|
for (const m of seg.matchAll(/(?:^|[^<>&=(])(?:\d?>{1,2}|&>>?|>\|)\s*([^\s;&|]+)/g)) {
|
|
@@ -296,7 +308,7 @@ async function guardExternalWriteHit(
|
|
|
296
308
|
if (ok) return null;
|
|
297
309
|
return `pi-task-tracker scope guard: user denied external write to '${hit.block}'. Do not retry or bypass.`;
|
|
298
310
|
}
|
|
299
|
-
return `pi-task-tracker scope guard (externalWrite
|
|
311
|
+
return `pi-task-tracker scope guard (externalWrite=${mode}): this command writes to '${hit.block}' outside the session directory. ${why} Stay inside the session directory, or have the user adjust taskTracker.externalWrite / run it manually.`;
|
|
300
312
|
}
|
|
301
313
|
return null;
|
|
302
314
|
}
|
|
@@ -318,7 +330,7 @@ async function guardExternalWriteHit(
|
|
|
318
330
|
if (ok) return "__ask__";
|
|
319
331
|
return `pi-task-tracker scope guard: user denied external write to '${p}'. Do not retry or bypass.`;
|
|
320
332
|
}
|
|
321
|
-
return `pi-task-tracker scope guard (externalWrite
|
|
333
|
+
return `pi-task-tracker scope guard (externalWrite=${mode}): tool '${toolName}' targets '${p}' outside the session directory. ${why} Ask the user to adjust taskTracker.externalWrite or perform the change manually.`;
|
|
322
334
|
}
|
|
323
335
|
|
|
324
336
|
function isExternalAbs2(base: string, p: string): boolean {
|
|
@@ -577,7 +589,7 @@ interface TrackerConfig {
|
|
|
577
589
|
}
|
|
578
590
|
|
|
579
591
|
function readConfig(): TrackerConfig {
|
|
580
|
-
const fallback: TrackerConfig = { todo: true, readme: true, autoCommit: true, externalWrite: "
|
|
592
|
+
const fallback: TrackerConfig = { todo: true, readme: true, autoCommit: true, externalWrite: "ask", guard: true };
|
|
581
593
|
try {
|
|
582
594
|
const dir = process.env.PI_CODING_AGENT_DIR || path.join(os.homedir(), ".pi", "agent");
|
|
583
595
|
const file = process.env.PI_TRACKER_SETTINGS || path.join(dir, "settings.json");
|
|
@@ -588,7 +600,7 @@ function readConfig(): TrackerConfig {
|
|
|
588
600
|
readme: t.readme !== false,
|
|
589
601
|
autoCommit: t.autoCommit !== false,
|
|
590
602
|
guard: t.guard !== false,
|
|
591
|
-
externalWrite: t.externalWrite === "
|
|
603
|
+
externalWrite: t.externalWrite === "block" || t.externalWrite === "off" ? t.externalWrite : "ask",
|
|
592
604
|
};
|
|
593
605
|
} catch {
|
|
594
606
|
return fallback;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-task-tracker",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "Task workflow tracking for the pi coding agent: TODO/README maintenance, per-task git auto-commits as checkpoints, and an interactive /rollback. Hashline-aware, nested-repo aware, subagent-artifact-safe.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|