@tekmidian/pai 0.60.1 → 0.62.0
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/dist/{async-CLvuY7b-.mjs → async-DNVWtQl2.mjs} +2 -2
- package/dist/{async-CLvuY7b-.mjs.map → async-DNVWtQl2.mjs.map} +1 -1
- package/dist/{chain-CGyAIHo4.mjs → chain-CuaDawK9.mjs} +4 -4
- package/dist/{chain-CGyAIHo4.mjs.map → chain-CuaDawK9.mjs.map} +1 -1
- package/dist/cli/index.mjs +13 -13
- package/dist/cli/program.mjs +13 -13
- package/dist/{context-handover-cache-BzM7Qudn.mjs → context-handover-cache-DFNnlWv2.mjs} +4 -4
- package/dist/{context-handover-cache-BzM7Qudn.mjs.map → context-handover-cache-DFNnlWv2.mjs.map} +1 -1
- package/dist/daemon/index.mjs +10 -10
- package/dist/{daemon-B_TodsIS.mjs → daemon-Bf7Eock4.mjs} +45 -24
- package/dist/{daemon-B_TodsIS.mjs.map → daemon-Bf7Eock4.mjs.map} +1 -1
- package/dist/daemon-bJi1gDkG.mjs +19 -0
- package/dist/daemon-mcp/index.mjs +8 -10
- package/dist/daemon-mcp/index.mjs.map +1 -1
- package/dist/{factory-EUUhSSoq.mjs → factory-BozZa81q.mjs} +3 -3
- package/dist/{factory-EUUhSSoq.mjs.map → factory-BozZa81q.mjs.map} +1 -1
- package/dist/{factory-DW7BCJJT.mjs → factory-UO9_DFMN.mjs} +1 -1
- package/dist/{fallback-CjdakQVu.mjs → fallback-F0TWGVM2.mjs} +11 -13
- package/dist/{fallback-CjdakQVu.mjs.map → fallback-F0TWGVM2.mjs.map} +1 -1
- package/dist/{helpers-D9WkIf9R.mjs → helpers-Dj-B314s.mjs} +3 -2
- package/dist/{helpers-D9WkIf9R.mjs.map → helpers-Dj-B314s.mjs.map} +1 -1
- package/dist/hooks/block-sleep-poll.mjs.map +2 -2
- package/dist/hooks/context-compression-hook.mjs.map +1 -1
- package/dist/hooks/load-project-context.mjs +8513 -133
- package/dist/hooks/load-project-context.mjs.map +4 -4
- package/dist/hooks/post-compact-inject.mjs.map +1 -1
- package/dist/hooks/route-agents-to-worker.mjs +3 -3
- package/dist/hooks/route-agents-to-worker.mjs.map +2 -2
- package/dist/hooks/security-validator.mjs +58 -58
- package/dist/hooks/security-validator.mjs.map +3 -3
- package/dist/hooks/stop-hook.mjs +15 -15
- package/dist/hooks/stop-hook.mjs.map +3 -3
- package/dist/hooks/update-tab-on-action.mjs +14 -12
- package/dist/hooks/update-tab-on-action.mjs.map +3 -3
- package/dist/hooks/update-tab-titles.mjs +13 -9
- package/dist/hooks/update-tab-titles.mjs.map +3 -3
- package/dist/hooks/worker-guard.mjs +7859 -0
- package/dist/hooks/worker-guard.mjs.map +7 -0
- package/dist/hooks/worker-proxy.mjs +3 -3
- package/dist/hooks/worker-proxy.mjs.map +2 -2
- package/dist/hooks/worker-status-line.mjs +104 -11
- package/dist/hooks/worker-status-line.mjs.map +4 -4
- package/dist/hooks/worker-supervision.mjs +3 -3
- package/dist/hooks/worker-supervision.mjs.map +2 -2
- package/dist/index.mjs +1 -1
- package/dist/{indexer-backend-DcDtin1O.mjs → indexer-backend-BN9rpp9O.mjs} +2 -2
- package/dist/{main-resolver-BFQfU5xo.mjs → main-resolver-BIft_FVF.mjs} +4 -4
- package/dist/{main-resolver-BFQfU5xo.mjs.map → main-resolver-BIft_FVF.mjs.map} +1 -1
- package/dist/{main-resolver-VMBENifT.mjs → main-resolver-C9-poMdi.mjs} +2 -2
- package/dist/{planner-DN967Lvm.mjs → planner-BG9ivPj0.mjs} +6 -6
- package/dist/{planner-DN967Lvm.mjs.map → planner-BG9ivPj0.mjs.map} +1 -1
- package/dist/{postgres-nvU5pShF.mjs → postgres-CxD6_Dca.mjs} +3 -3
- package/dist/{postgres-nvU5pShF.mjs.map → postgres-CxD6_Dca.mjs.map} +1 -1
- package/dist/{program-BnsjB57Q.mjs → program-BRvCzhjx.mjs} +249 -82
- package/dist/program-BRvCzhjx.mjs.map +1 -0
- package/dist/{run-FeM1_UVa.mjs → run-BVQZI79D.mjs} +610 -253
- package/dist/run-BVQZI79D.mjs.map +1 -0
- package/dist/{run-env-CEHTeIUM.mjs → run-env-BE5xyCwy.mjs} +25 -6
- package/dist/run-env-BE5xyCwy.mjs.map +1 -0
- package/dist/{server-CekGOJcp.mjs → server-BY6AedmC.mjs} +2 -2
- package/dist/{server-CekGOJcp.mjs.map → server-BY6AedmC.mjs.map} +1 -1
- package/dist/{session-keepalive-Bc9aT678.mjs → session-keepalive-DJA97K2X.mjs} +4 -4
- package/dist/{session-keepalive-Bc9aT678.mjs.map → session-keepalive-DJA97K2X.mjs.map} +1 -1
- package/dist/{sqlite-D9p5a4qe.mjs → sqlite-CfKfuggn.mjs} +2 -2
- package/dist/{sqlite-D9p5a4qe.mjs.map → sqlite-CfKfuggn.mjs.map} +1 -1
- package/dist/{tools-r-7ZG8B5.mjs → tools-B52IvaU6.mjs} +3 -3
- package/dist/{tools-qXyHFwNj.mjs → tools-DFdPbX-X.mjs} +2 -2
- package/dist/{tools-qXyHFwNj.mjs.map → tools-DFdPbX-X.mjs.map} +1 -1
- package/dist/{vault-indexer-DHYBpRZ5.mjs → vault-indexer-mCFus_AM.mjs} +2 -2
- package/dist/{vault-indexer-DHYBpRZ5.mjs.map → vault-indexer-mCFus_AM.mjs.map} +1 -1
- package/dist/{wakeup-C48hcN6O.mjs → wakeup-DO1O4udw.mjs} +2 -2
- package/dist/{wakeup-C48hcN6O.mjs.map → wakeup-DO1O4udw.mjs.map} +1 -1
- package/dist/{work-queue-worker-BL4dq5P7.mjs → work-queue-worker-BbrC3I_R.mjs} +2 -2
- package/dist/{work-queue-worker-BL4dq5P7.mjs.map → work-queue-worker-BbrC3I_R.mjs.map} +1 -1
- package/dist/work-queue-worker-z-AATZ2t.mjs +11 -0
- package/docs/commands/README.md +2 -0
- package/docs/commands/worker.md +28 -0
- package/package.json +2 -2
- package/scripts/build-hooks.mjs +6 -5
- package/scripts/build-skill-stubs.mjs +6 -5
- package/src/hooks/ts/lib/tab-title.ts +18 -0
- package/src/hooks/ts/lib/worker-guard.test.ts +188 -0
- package/src/hooks/ts/lib/worker-guard.ts +315 -0
- package/src/hooks/ts/post-tool-use/update-tab-on-action.ts +3 -20
- package/src/hooks/ts/pre-tool-use/worker-guard.ts +75 -0
- package/src/hooks/ts/session-start/load-project-context.ts +14 -0
- package/src/hooks/ts/stop/stop-hook.ts +4 -15
- package/src/hooks/ts/user-prompt/update-tab-titles.ts +2 -10
- package/dist/daemon-jviL3VVJ.mjs +0 -19
- package/dist/program-BnsjB57Q.mjs.map +0 -1
- package/dist/run-FeM1_UVa.mjs.map +0 -1
- package/dist/run-env-CEHTeIUM.mjs.map +0 -1
- package/dist/work-queue-worker-DVOVcEnO.mjs +0 -11
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { isWorkerSession } from "../lib/worker-session.js";
|
|
11
|
-
import {
|
|
11
|
+
import { setTabTitle } from "../lib/tab-title.js";
|
|
12
12
|
|
|
13
13
|
// Action tools that warrant a tab title update
|
|
14
14
|
const ACTION_TOOLS = new Set([
|
|
@@ -60,24 +60,6 @@ async function readStdinWithTimeout(timeout: number = 3000): Promise<string> {
|
|
|
60
60
|
});
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
/**
|
|
64
|
-
* Update Kitty tab title using escape codes
|
|
65
|
-
*/
|
|
66
|
-
function setTabTitle(title: string): void {
|
|
67
|
-
try {
|
|
68
|
-
// Truncate to reasonable length
|
|
69
|
-
const truncated = title.length > 50 ? title.slice(0, 47) + '...' : title;
|
|
70
|
-
const escaped = truncated.replace(/'/g, "'\\''");
|
|
71
|
-
|
|
72
|
-
// Multiple escape sequences for compatibility
|
|
73
|
-
execSync(`printf '\\033]0;${escaped}\\007' >&2`, { stdio: ['pipe', 'pipe', 'inherit'] });
|
|
74
|
-
execSync(`printf '\\033]2;${escaped}\\007' >&2`, { stdio: ['pipe', 'pipe', 'inherit'] });
|
|
75
|
-
execSync(`printf '\\033]30;${escaped}\\007' >&2`, { stdio: ['pipe', 'pipe', 'inherit'] });
|
|
76
|
-
} catch {
|
|
77
|
-
// Silently fail - don't interrupt Claude's work
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
63
|
/**
|
|
82
64
|
* Generate a human-readable title from tool input
|
|
83
65
|
*/
|
|
@@ -135,7 +117,8 @@ async function main() {
|
|
|
135
117
|
|
|
136
118
|
// Generate and set title
|
|
137
119
|
const title = generateTitle(data.tool_name, data.tool_input);
|
|
138
|
-
|
|
120
|
+
const truncated = title.length > 50 ? title.slice(0, 47) + '...' : title;
|
|
121
|
+
setTabTitle(truncated);
|
|
139
122
|
|
|
140
123
|
process.exit(0);
|
|
141
124
|
} catch {
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* worker-guard.ts — PreToolUse (Bash|Edit|Write|MultiEdit|NotebookEdit)
|
|
5
|
+
*
|
|
6
|
+
* Worker-only (PAI_WORKER=1) enforcement of the git/worktree rules every
|
|
7
|
+
* worker spec used to repeat in prose and workers still broke: no symlinks
|
|
8
|
+
* out of the worktree, no repo copies, no push/publish/tag/version, no
|
|
9
|
+
* tree-rewriting git in a shared checkout, no cd into the main checkout,
|
|
10
|
+
* no Notes/TODO.md or live config writes, no `bun test` on a vitest repo.
|
|
11
|
+
* A no-op in interactive sessions.
|
|
12
|
+
*
|
|
13
|
+
* This file is only I/O: read stdin, gather the git context, print the
|
|
14
|
+
* decision. The decision lives in lib/worker-guard.ts and is tested there
|
|
15
|
+
* and through this entry.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { execFileSync } from "node:child_process";
|
|
19
|
+
import { readFileSync } from "node:fs";
|
|
20
|
+
import { homedir } from "node:os";
|
|
21
|
+
import { dirname, join } from "node:path";
|
|
22
|
+
import { renderDecision } from "../lib/sleep-poll-gate.js";
|
|
23
|
+
import { decideWorkerGuard, type WorkerGuardContext, type WorkerGuardInput } from "../lib/worker-guard.js";
|
|
24
|
+
|
|
25
|
+
function git(cwd: string, args: string[]): string | null {
|
|
26
|
+
try {
|
|
27
|
+
return execFileSync("git", ["-C", cwd, ...args], { encoding: "utf8", timeout: 5_000, stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
28
|
+
} catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function buildContext(cwd: string): WorkerGuardContext {
|
|
34
|
+
const worktreeRoot = git(cwd, ["rev-parse", "--show-toplevel"]);
|
|
35
|
+
const gitDir = git(cwd, ["rev-parse", "--absolute-git-dir"]);
|
|
36
|
+
const common = git(cwd, ["rev-parse", "--path-format=absolute", "--git-common-dir"]);
|
|
37
|
+
const inWorktree = !!gitDir && !!common && gitDir !== common;
|
|
38
|
+
return {
|
|
39
|
+
cwd,
|
|
40
|
+
home: homedir(),
|
|
41
|
+
worktreeRoot,
|
|
42
|
+
inWorktree,
|
|
43
|
+
mainCheckout: inWorktree && common ? dirname(common) : null,
|
|
44
|
+
testScript: () => {
|
|
45
|
+
try {
|
|
46
|
+
const pkg = JSON.parse(readFileSync(join(worktreeRoot ?? cwd, "package.json"), "utf8"));
|
|
47
|
+
return typeof pkg?.scripts?.test === "string" ? pkg.scripts.test : null;
|
|
48
|
+
} catch {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async function main(): Promise<void> {
|
|
56
|
+
let text = "";
|
|
57
|
+
try {
|
|
58
|
+
for await (const chunk of process.stdin) text += chunk;
|
|
59
|
+
} catch {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (!text.trim()) return;
|
|
63
|
+
|
|
64
|
+
let input: WorkerGuardInput;
|
|
65
|
+
try {
|
|
66
|
+
input = JSON.parse(text) as WorkerGuardInput;
|
|
67
|
+
} catch {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const decision = decideWorkerGuard(input, process.env, () => buildContext(input.cwd || process.cwd()));
|
|
72
|
+
if (decision.decision === "deny") process.stdout.write(renderDecision(decision) + "\n");
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
main().catch(() => process.exit(0));
|
|
@@ -16,6 +16,9 @@
|
|
|
16
16
|
* - Sending ntfy.sh notifications
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
+
import { readWorkersSection } from '../../../workers/config.js';
|
|
20
|
+
import { workersLogDir } from '../../../workers/paths.js';
|
|
21
|
+
import { pendingResults } from '../../../workers/pending.js';
|
|
19
22
|
import { isWorkerSession } from "../lib/worker-session.js";
|
|
20
23
|
import { existsSync, readdirSync, readFileSync, statSync } from 'fs';
|
|
21
24
|
import { join, basename, dirname, resolve } from 'path';
|
|
@@ -492,6 +495,17 @@ ${paiProjectBlock ? `\n${paiProjectBlock}` : ''}
|
|
|
492
495
|
// Output to stdout for Claude to receive
|
|
493
496
|
console.log(reminder);
|
|
494
497
|
|
|
498
|
+
// Unmerged finished worker results in this repo: one line, none when zero
|
|
499
|
+
try {
|
|
500
|
+
const { workers } = readWorkersSection();
|
|
501
|
+
const pending = pendingResults(workersLogDir(workers), cwd);
|
|
502
|
+
if (pending.length) {
|
|
503
|
+
console.log(`${pending.length} finished worker result(s) not merged in this repo: ${pending.map((r) => r.id).join(', ')} — run \`pai worker pending\``);
|
|
504
|
+
}
|
|
505
|
+
} catch {
|
|
506
|
+
// no workers config or not a git repo: stay silent
|
|
507
|
+
}
|
|
508
|
+
|
|
495
509
|
// 8.5. INJECT THE PAUSE CHECKPOINT
|
|
496
510
|
//
|
|
497
511
|
// `pai pause` writes the handover to TODO.md under `## Continue`. Until now
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { isWorkerSession } from "../lib/worker-session.js";
|
|
4
|
+
import { setTabTitle } from "../lib/tab-title.js";
|
|
4
5
|
import { readFileSync, writeFileSync, mkdirSync, existsSync, unlinkSync } from 'fs';
|
|
5
6
|
import { join, basename, dirname } from 'path';
|
|
6
7
|
import { connect } from 'net';
|
|
@@ -599,11 +600,7 @@ async function executeDirectly(
|
|
|
599
600
|
|
|
600
601
|
if (tabTitle) {
|
|
601
602
|
try {
|
|
602
|
-
|
|
603
|
-
const { execSync } = await import('child_process');
|
|
604
|
-
execSync(`printf '\\033]0;${escapedTitle}\\007' >&2`);
|
|
605
|
-
execSync(`printf '\\033]2;${escapedTitle}\\007' >&2`);
|
|
606
|
-
execSync(`printf '\\033]30;${escapedTitle}\\007' >&2`);
|
|
603
|
+
setTabTitle(tabTitle);
|
|
607
604
|
console.error(`Tab title set to: "${tabTitle}"`);
|
|
608
605
|
} catch (e) {
|
|
609
606
|
console.error(`Failed to set tab title: ${e}`);
|
|
@@ -856,11 +853,7 @@ async function main() {
|
|
|
856
853
|
}
|
|
857
854
|
if (tabTitle) {
|
|
858
855
|
try {
|
|
859
|
-
|
|
860
|
-
const escapedTitle = tabTitle.replace(/'/g, "'\\''");
|
|
861
|
-
execSync(`printf '\\033]0;${escapedTitle}\\007' >&2`);
|
|
862
|
-
execSync(`printf '\\033]2;${escapedTitle}\\007' >&2`);
|
|
863
|
-
execSync(`printf '\\033]30;${escapedTitle}\\007' >&2`);
|
|
856
|
+
setTabTitle(tabTitle);
|
|
864
857
|
console.error(`Tab title set to: "${tabTitle}"`);
|
|
865
858
|
} catch (e) {
|
|
866
859
|
console.error(`Failed to set tab title: ${e}`);
|
|
@@ -876,11 +869,7 @@ async function main() {
|
|
|
876
869
|
const persistentName = await getPersistentTabName();
|
|
877
870
|
if (persistentName) {
|
|
878
871
|
try {
|
|
879
|
-
|
|
880
|
-
const escaped = persistentName.replace(/'/g, "'\\''");
|
|
881
|
-
execSync(`printf '\\033]0;${escaped}\\007' >&2`);
|
|
882
|
-
execSync(`printf '\\033]2;${escaped}\\007' >&2`);
|
|
883
|
-
execSync(`printf '\\033]30;${escaped}\\007' >&2`);
|
|
872
|
+
setTabTitle(persistentName);
|
|
884
873
|
process.stderr.write(`\x1b]2;${persistentName.slice(0, 50)}\x07`);
|
|
885
874
|
console.error(`Tab title re-asserted to persistent name: "${persistentName}"`);
|
|
886
875
|
} catch (e) {
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { isWorkerSession } from "../lib/worker-session.js";
|
|
10
|
-
import {
|
|
10
|
+
import { setTabTitle } from "../lib/tab-title.js";
|
|
11
11
|
|
|
12
12
|
interface HookInput {
|
|
13
13
|
session_id: string;
|
|
@@ -69,15 +69,7 @@ async function main() {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
// Set initial tab title with recycle emoji
|
|
72
|
-
|
|
73
|
-
const titleWithEmoji = '♻️ ' + tabTitle;
|
|
74
|
-
const escapedTitle = titleWithEmoji.replace(/'/g, "'\\''");
|
|
75
|
-
execSync(`printf '\\033]0;${escapedTitle}\\007' >&2`);
|
|
76
|
-
execSync(`printf '\\033]2;${escapedTitle}\\007' >&2`);
|
|
77
|
-
execSync(`printf '\\033]30;${escapedTitle}\\007' >&2`);
|
|
78
|
-
} catch (e) {
|
|
79
|
-
// Silently fail
|
|
80
|
-
}
|
|
72
|
+
setTabTitle('♻️ ' + tabTitle);
|
|
81
73
|
|
|
82
74
|
process.exit(0);
|
|
83
75
|
} catch (error) {
|
package/dist/daemon-jviL3VVJ.mjs
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import "./utils-C9HsYDpO.mjs";
|
|
2
|
-
import "./migrate-BD7D8EEh.mjs";
|
|
3
|
-
import "./factory-EUUhSSoq.mjs";
|
|
4
|
-
import "./wakeup-C48hcN6O.mjs";
|
|
5
|
-
import "./context-handover-cache-BzM7Qudn.mjs";
|
|
6
|
-
import "./config-CQCmH_gV.mjs";
|
|
7
|
-
import "./run-env-CEHTeIUM.mjs";
|
|
8
|
-
import "./run-FeM1_UVa.mjs";
|
|
9
|
-
import "./server-CekGOJcp.mjs";
|
|
10
|
-
import "./state-n13uPK5B.mjs";
|
|
11
|
-
import "./aibroker-client-BK1h--W_.mjs";
|
|
12
|
-
import "./session-keepalive-Bc9aT678.mjs";
|
|
13
|
-
import "./embeddings-DfrYNIng.mjs";
|
|
14
|
-
import { t as serve } from "./daemon-B_TodsIS.mjs";
|
|
15
|
-
import "./router-DjFZIoDl.mjs";
|
|
16
|
-
import "./tools-qXyHFwNj.mjs";
|
|
17
|
-
import "./work-queue-worker-BL4dq5P7.mjs";
|
|
18
|
-
|
|
19
|
-
export { serve };
|