@tekmidian/pai 0.59.0 → 0.60.1
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/.claude-plugin/plugin.json +8 -33
- package/PLUGIN-ARCHITECTURE.md +4 -6
- package/dist/{aibroker-client-B8Wtasez.mjs → aibroker-client-BYG-GtAg.mjs} +1 -1
- package/dist/{chain-Cltx0NjY.mjs → chain-CGyAIHo4.mjs} +4 -4
- package/dist/{chain-Cltx0NjY.mjs.map → chain-CGyAIHo4.mjs.map} +1 -1
- package/dist/cli/index.mjs +12 -12
- package/dist/cli/program.mjs +12 -12
- package/dist/{config-D1omG_UU.mjs → config-CQCmH_gV.mjs} +17 -4
- package/dist/{config-D1omG_UU.mjs.map → config-CQCmH_gV.mjs.map} +1 -1
- package/dist/{config-DCYWFaEi.mjs → config-DjXq_W42.mjs} +1 -1
- package/dist/{context-handover-cache-Dt4HW1Ro.mjs → context-handover-cache-BzM7Qudn.mjs} +4 -4
- package/dist/{context-handover-cache-Dt4HW1Ro.mjs.map → context-handover-cache-BzM7Qudn.mjs.map} +1 -1
- package/dist/daemon/index.mjs +12 -12
- package/dist/{daemon-CmqJfeb9.mjs → daemon-B_TodsIS.mjs} +97 -23
- package/dist/daemon-B_TodsIS.mjs.map +1 -0
- package/dist/daemon-jviL3VVJ.mjs +19 -0
- package/dist/daemon-mcp/index.mjs +9 -9
- package/dist/daemon-mcp/index.mjs.map +1 -1
- package/dist/{factory-C9wGUe30.mjs → factory-DW7BCJJT.mjs} +1 -1
- package/dist/{factory-DiuntvwG.mjs → factory-EUUhSSoq.mjs} +7 -8
- package/dist/factory-EUUhSSoq.mjs.map +1 -0
- package/dist/{fallback-B_2ozQHw.mjs → fallback-CjdakQVu.mjs} +80 -9
- package/dist/fallback-CjdakQVu.mjs.map +1 -0
- package/dist/hooks/block-sleep-poll.mjs +7590 -0
- package/dist/hooks/block-sleep-poll.mjs.map +7 -0
- package/dist/hooks/capture-all-events.mjs +8 -4
- package/dist/hooks/capture-all-events.mjs.map +2 -2
- package/dist/hooks/capture-session-summary.mjs.map +1 -1
- package/dist/hooks/capture-tool-output.mjs.map +1 -1
- package/dist/hooks/cleanup-session-files.mjs.map +1 -1
- package/dist/hooks/context-compression-hook.mjs +6 -6
- package/dist/hooks/context-compression-hook.mjs.map +3 -3
- package/dist/hooks/initialize-session.mjs.map +1 -1
- package/dist/hooks/load-core-context.mjs.map +1 -1
- package/dist/hooks/load-project-context.mjs.map +2 -2
- package/dist/hooks/post-compact-inject.mjs +1 -1
- package/dist/hooks/post-compact-inject.mjs.map +2 -2
- package/dist/hooks/route-agents-to-worker.mjs +5 -4
- package/dist/hooks/route-agents-to-worker.mjs.map +3 -3
- package/dist/hooks/security-validator.mjs +5 -4
- package/dist/hooks/security-validator.mjs.map +3 -3
- package/dist/hooks/stop-hook.mjs.map +1 -1
- package/dist/hooks/sync-todo-to-md.mjs.map +1 -1
- package/dist/hooks/whisper-rules.mjs +5 -4
- package/dist/hooks/whisper-rules.mjs.map +3 -3
- package/dist/hooks/worker-proxy.mjs +5 -4
- package/dist/hooks/worker-proxy.mjs.map +3 -3
- package/dist/hooks/worker-status-line.mjs +10 -7
- package/dist/hooks/worker-status-line.mjs.map +3 -3
- package/dist/hooks/worker-supervision.mjs +5 -4
- package/dist/hooks/worker-supervision.mjs.map +3 -3
- package/dist/{main-resolver-DYNxxNwJ.mjs → main-resolver-BFQfU5xo.mjs} +100 -21
- package/dist/main-resolver-BFQfU5xo.mjs.map +1 -0
- package/dist/main-resolver-VMBENifT.mjs +7 -0
- package/dist/{planner-DsZZEZCA.mjs → planner-DN967Lvm.mjs} +83 -30
- package/dist/planner-DN967Lvm.mjs.map +1 -0
- package/dist/{program-B5miXqQa.mjs → program-BnsjB57Q.mjs} +278 -92
- package/dist/program-BnsjB57Q.mjs.map +1 -0
- package/dist/router-C5hPk9YP.mjs +3 -0
- package/dist/{router-BdxdsAvs.mjs → router-DjFZIoDl.mjs} +2 -1
- package/dist/router-DjFZIoDl.mjs.map +1 -0
- package/dist/{run-XaA-UPdW.mjs → run-FeM1_UVa.mjs} +102 -18
- package/dist/run-FeM1_UVa.mjs.map +1 -0
- package/dist/{run-env-DyTWgZC9.mjs → run-env-CEHTeIUM.mjs} +2 -2
- package/dist/{run-env-DyTWgZC9.mjs.map → run-env-CEHTeIUM.mjs.map} +1 -1
- package/dist/{server-CzqHGbKt.mjs → server-CekGOJcp.mjs} +2 -2
- package/dist/{server-CzqHGbKt.mjs.map → server-CekGOJcp.mjs.map} +1 -1
- package/dist/{session-keepalive-DDsEo81Q.mjs → session-keepalive-Bc9aT678.mjs} +5 -5
- package/dist/{session-keepalive-DDsEo81Q.mjs.map → session-keepalive-Bc9aT678.mjs.map} +1 -1
- package/dist/{tools-Diro2s8J.mjs → tools-qXyHFwNj.mjs} +2 -2
- package/dist/{tools-Diro2s8J.mjs.map → tools-qXyHFwNj.mjs.map} +1 -1
- package/dist/{tools-KgL1rkPD.mjs → tools-r-7ZG8B5.mjs} +3 -3
- package/dist/{wakeup-D0uvqLsE.mjs → wakeup-C48hcN6O.mjs} +2 -2
- package/dist/wakeup-C48hcN6O.mjs.map +1 -0
- package/dist/{work-queue-worker-DL9lu8sN.mjs → work-queue-worker-BL4dq5P7.mjs} +2 -2
- package/dist/{work-queue-worker-DL9lu8sN.mjs.map → work-queue-worker-BL4dq5P7.mjs.map} +1 -1
- package/dist/work-queue-worker-DVOVcEnO.mjs +11 -0
- package/docker/init.sql +1 -1
- package/docs/commands/README.md +4 -4
- package/docs/commands/daemon.md +6 -6
- package/docs/commands/session.md +2 -2
- package/docs/commands/worker.md +5 -2
- package/docs/workers-config.md +5 -1
- package/package.json +1 -1
- package/plugins/context-preservation/hooks/hooks.json +38 -31
- package/plugins/context-preservation/plugin.json +1 -4
- package/plugins/core/hooks/hooks.json +51 -46
- package/plugins/core/plugin.json +1 -4
- package/plugins/creative/plugin.json +1 -5
- package/plugins/observability/hooks/hooks.json +87 -72
- package/plugins/observability/plugin.json +1 -5
- package/plugins/productivity/hooks/hooks.json +22 -19
- package/plugins/productivity/plugin.json +2 -5
- package/plugins/semantic-search/plugin.json +1 -16
- package/plugins/ui/hooks/hooks.json +17 -14
- package/plugins/ui/plugin.json +1 -5
- package/plugins/zettelkasten/plugin.json +1 -14
- package/src/hooks/session-autosave.sh +4 -2
- package/src/hooks/session-stop.sh +2 -2
- package/src/hooks/ts/capture-all-events.ts +3 -3
- package/src/hooks/ts/lib/metadata-extraction.ts +3 -2
- package/src/hooks/ts/lib/pai-paths.test.ts +1 -1
- package/src/hooks/ts/lib/sleep-poll-gate.test.ts +62 -0
- package/src/hooks/ts/lib/sleep-poll-gate.ts +77 -0
- package/src/hooks/ts/post-tool-use/capture-tool-output.ts +1 -1
- package/src/hooks/ts/post-tool-use/sync-todo-to-md.ts +1 -1
- package/src/hooks/ts/pre-compact/context-compression-hook.ts +1 -1
- package/src/hooks/ts/pre-tool-use/block-sleep-poll.test.ts +44 -0
- package/src/hooks/ts/pre-tool-use/block-sleep-poll.ts +50 -0
- package/src/hooks/ts/session-end/capture-session-summary.ts +1 -1
- package/src/hooks/ts/session-start/initialize-session.ts +2 -2
- package/src/hooks/ts/session-start/load-core-context.ts +2 -2
- package/src/hooks/ts/session-start/load-project-context.ts +1 -1
- package/src/hooks/ts/stop/stop-hook.ts +1 -1
- package/src/hooks/ts/user-prompt/cleanup-session-files.ts +1 -1
- package/statusline-command.sh +26 -11
- package/dist/daemon-B6hx1Ysz.mjs +0 -19
- package/dist/daemon-CmqJfeb9.mjs.map +0 -1
- package/dist/factory-DiuntvwG.mjs.map +0 -1
- package/dist/fallback-B_2ozQHw.mjs.map +0 -1
- package/dist/main-resolver-DYNxxNwJ.mjs.map +0 -1
- package/dist/main-resolver-Df65bPAi.mjs +0 -7
- package/dist/planner-DsZZEZCA.mjs.map +0 -1
- package/dist/program-B5miXqQa.mjs.map +0 -1
- package/dist/router-BXOf_e9e.mjs +0 -3
- package/dist/router-BdxdsAvs.mjs.map +0 -1
- package/dist/run-XaA-UPdW.mjs.map +0 -1
- package/dist/wakeup-D0uvqLsE.mjs.map +0 -1
- package/dist/work-queue-worker-BY7xn4pw.mjs +0 -11
|
@@ -1,49 +1,54 @@
|
|
|
1
1
|
{
|
|
2
|
-
"module": "core",
|
|
3
2
|
"description": "Essential lifecycle hooks for session management, context loading, and security",
|
|
4
|
-
"hooks":
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
3
|
+
"hooks": {
|
|
4
|
+
"SessionStart": [
|
|
5
|
+
{
|
|
6
|
+
"hooks": [
|
|
7
|
+
{ "type": "command", "command": "${PAI_DIR}/Hooks/load-core-context.mjs" }
|
|
8
|
+
]
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"hooks": [
|
|
12
|
+
{ "type": "command", "command": "${PAI_DIR}/Hooks/load-project-context.mjs" }
|
|
13
|
+
]
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"hooks": [
|
|
17
|
+
{ "type": "command", "command": "${PAI_DIR}/Hooks/initialize-session.mjs" }
|
|
18
|
+
]
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"matcher": "resume|compact",
|
|
22
|
+
"hooks": [
|
|
23
|
+
{ "type": "command", "command": "${PAI_DIR}/Hooks/mcp-deferred-reminder.mjs" }
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
"PreToolUse": [
|
|
28
|
+
{
|
|
29
|
+
"matcher": "Bash",
|
|
30
|
+
"hooks": [
|
|
31
|
+
{ "type": "command", "command": "${PAI_DIR}/Hooks/security-validator.mjs" }
|
|
32
|
+
]
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"matcher": "mcp__",
|
|
36
|
+
"hooks": [
|
|
37
|
+
{ "type": "command", "command": "${PAI_DIR}/Hooks/mcp-deferred-gate.mjs" }
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"Stop": [
|
|
42
|
+
{
|
|
43
|
+
"hooks": [
|
|
44
|
+
{ "type": "command", "command": "${PAI_DIR}/Hooks/stop-hook.mjs" }
|
|
45
|
+
]
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"hooks": [
|
|
49
|
+
{ "type": "command", "command": "${PAI_DIR}/Hooks/pai-session-stop.sh" }
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
}
|
|
49
54
|
}
|
package/plugins/core/plugin.json
CHANGED
|
@@ -3,8 +3,5 @@
|
|
|
3
3
|
"displayName": "PAI Core",
|
|
4
4
|
"description": "Core memory engine, session management, and project registry",
|
|
5
5
|
"version": "0.7.0",
|
|
6
|
-
"
|
|
7
|
-
"required": true,
|
|
8
|
-
"hooks": "hooks/hooks.json",
|
|
9
|
-
"skills": ["Sessions", "Route", "Name"]
|
|
6
|
+
"hooks": "./hooks/hooks.json"
|
|
10
7
|
}
|
|
@@ -2,9 +2,5 @@
|
|
|
2
2
|
"name": "pai-creative",
|
|
3
3
|
"displayName": "PAI Creative Studio",
|
|
4
4
|
"description": "Art direction, story explanation, voice/prosody configuration",
|
|
5
|
-
"version": "0.7.0"
|
|
6
|
-
"tier": "enterprise",
|
|
7
|
-
"required": false,
|
|
8
|
-
"depends": ["core"],
|
|
9
|
-
"skills": ["Art", "StoryExplanation"]
|
|
5
|
+
"version": "0.7.0"
|
|
10
6
|
}
|
|
@@ -1,75 +1,90 @@
|
|
|
1
1
|
{
|
|
2
|
-
"module": "observability",
|
|
3
2
|
"description": "Automatic observation capture, event logging, tool output recording, and session summaries",
|
|
4
|
-
"hooks":
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
3
|
+
"hooks": {
|
|
4
|
+
"SessionStart": [
|
|
5
|
+
{
|
|
6
|
+
"hooks": [
|
|
7
|
+
{ "type": "command", "command": "${PAI_DIR}/Hooks/capture-all-events.mjs --event-type SessionStart" }
|
|
8
|
+
]
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"hooks": [
|
|
12
|
+
{ "type": "command", "command": "${PAI_DIR}/Hooks/inject-observations.mjs" }
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"UserPromptSubmit": [
|
|
17
|
+
{
|
|
18
|
+
"hooks": [
|
|
19
|
+
{ "type": "command", "command": "${PAI_DIR}/Hooks/capture-all-events.mjs --event-type UserPromptSubmit" }
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"PreToolUse": [
|
|
24
|
+
{
|
|
25
|
+
"matcher": "*",
|
|
26
|
+
"hooks": [
|
|
27
|
+
{ "type": "command", "command": "${PAI_DIR}/Hooks/capture-all-events.mjs --event-type PreToolUse" }
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
"PostToolUse": [
|
|
32
|
+
{
|
|
33
|
+
"matcher": "*",
|
|
34
|
+
"hooks": [
|
|
35
|
+
{ "type": "command", "command": "${PAI_DIR}/Hooks/capture-all-events.mjs --event-type PostToolUse" }
|
|
36
|
+
]
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"matcher": "*",
|
|
40
|
+
"hooks": [
|
|
41
|
+
{ "type": "command", "command": "${PAI_DIR}/Hooks/observe.mjs" }
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"matcher": "*",
|
|
46
|
+
"hooks": [
|
|
47
|
+
{ "type": "command", "command": "${PAI_DIR}/Hooks/capture-tool-output.mjs" }
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
],
|
|
51
|
+
"Stop": [
|
|
52
|
+
{
|
|
53
|
+
"hooks": [
|
|
54
|
+
{ "type": "command", "command": "${PAI_DIR}/Hooks/capture-all-events.mjs --event-type Stop" }
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
],
|
|
58
|
+
"SubagentStop": [
|
|
59
|
+
{
|
|
60
|
+
"hooks": [
|
|
61
|
+
{ "type": "command", "command": "${PAI_DIR}/Hooks/subagent-stop-hook.mjs" }
|
|
62
|
+
]
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"hooks": [
|
|
66
|
+
{ "type": "command", "command": "${PAI_DIR}/Hooks/capture-all-events.mjs --event-type SubagentStop" }
|
|
67
|
+
]
|
|
68
|
+
}
|
|
69
|
+
],
|
|
70
|
+
"SessionEnd": [
|
|
71
|
+
{
|
|
72
|
+
"hooks": [
|
|
73
|
+
{ "type": "command", "command": "${PAI_DIR}/Hooks/capture-session-summary.mjs" }
|
|
74
|
+
]
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"hooks": [
|
|
78
|
+
{ "type": "command", "command": "${PAI_DIR}/Hooks/capture-all-events.mjs --event-type SessionEnd" }
|
|
79
|
+
]
|
|
80
|
+
}
|
|
81
|
+
],
|
|
82
|
+
"PreCompact": [
|
|
83
|
+
{
|
|
84
|
+
"hooks": [
|
|
85
|
+
{ "type": "command", "command": "${PAI_DIR}/Hooks/capture-all-events.mjs --event-type PreCompact" }
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
]
|
|
89
|
+
}
|
|
75
90
|
}
|
|
@@ -3,9 +3,5 @@
|
|
|
3
3
|
"displayName": "PAI Observability Suite",
|
|
4
4
|
"description": "Automatic observation capture, classification, session summaries, and search history",
|
|
5
5
|
"version": "0.7.0",
|
|
6
|
-
"
|
|
7
|
-
"required": false,
|
|
8
|
-
"depends": ["core"],
|
|
9
|
-
"hooks": "hooks/hooks.json",
|
|
10
|
-
"skills": ["Observability", "SearchHistory"]
|
|
6
|
+
"hooks": "./hooks/hooks.json"
|
|
11
7
|
}
|
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
{
|
|
2
|
-
"module": "productivity",
|
|
3
2
|
"description": "Hooks for TODO sync, session cleanup, and productivity workflows",
|
|
4
|
-
"hooks":
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
3
|
+
"hooks": {
|
|
4
|
+
"PostToolUse": [
|
|
5
|
+
{
|
|
6
|
+
"matcher": "TodoWrite",
|
|
7
|
+
"hooks": [
|
|
8
|
+
{ "type": "command", "command": "${PAI_DIR}/Hooks/sync-todo-to-md.mjs" }
|
|
9
|
+
]
|
|
10
|
+
}
|
|
11
|
+
],
|
|
12
|
+
"UserPromptSubmit": [
|
|
13
|
+
{
|
|
14
|
+
"hooks": [
|
|
15
|
+
{ "type": "command", "command": "${PAI_DIR}/Hooks/cleanup-session-files.mjs" }
|
|
16
|
+
]
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"hooks": [
|
|
20
|
+
{ "type": "command", "command": "${PAI_DIR}/Hooks/worker-supervision.mjs" }
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
}
|
|
22
25
|
}
|
|
@@ -3,9 +3,6 @@
|
|
|
3
3
|
"displayName": "PAI Productivity",
|
|
4
4
|
"description": "Planning, journaling, reviewing, research, sharing, and cross-session task routing",
|
|
5
5
|
"version": "0.7.0",
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"depends": ["core"],
|
|
9
|
-
"hooks": "hooks/hooks.json",
|
|
10
|
-
"skills": ["Plan", "Review", "Journal", "Research", "Share", "Createskill", "Reconstruct", "Tasks"]
|
|
6
|
+
"hooks": "./hooks/hooks.json",
|
|
7
|
+
"skills": ["./skills/"]
|
|
11
8
|
}
|
|
@@ -2,20 +2,5 @@
|
|
|
2
2
|
"name": "pai-semantic-search",
|
|
3
3
|
"displayName": "PAI Semantic Search",
|
|
4
4
|
"description": "Vector search with pgvector, cross-encoder reranking, hybrid mode, recency boost",
|
|
5
|
-
"version": "0.7.0"
|
|
6
|
-
"tier": "pro",
|
|
7
|
-
"required": false,
|
|
8
|
-
"depends": ["core"],
|
|
9
|
-
"features": [
|
|
10
|
-
"semantic_search_mode",
|
|
11
|
-
"hybrid_search_mode",
|
|
12
|
-
"cross_encoder_reranking",
|
|
13
|
-
"recency_boost",
|
|
14
|
-
"pgvector_storage"
|
|
15
|
-
],
|
|
16
|
-
"requirements": {
|
|
17
|
-
"docker": true,
|
|
18
|
-
"postgresql": ">=15",
|
|
19
|
-
"pgvector": ">=0.5.0"
|
|
20
|
-
}
|
|
5
|
+
"version": "0.7.0"
|
|
21
6
|
}
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
{
|
|
2
|
-
"module": "ui",
|
|
3
2
|
"description": "Terminal tab titles, statusline updates, and visual feedback hooks",
|
|
4
|
-
"hooks":
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
3
|
+
"hooks": {
|
|
4
|
+
"UserPromptSubmit": [
|
|
5
|
+
{
|
|
6
|
+
"hooks": [
|
|
7
|
+
{ "type": "command", "command": "${PAI_DIR}/Hooks/update-tab-titles.mjs" }
|
|
8
|
+
]
|
|
9
|
+
}
|
|
10
|
+
],
|
|
11
|
+
"PostToolUse": [
|
|
12
|
+
{
|
|
13
|
+
"matcher": "*",
|
|
14
|
+
"hooks": [
|
|
15
|
+
{ "type": "command", "command": "${PAI_DIR}/Hooks/update-tab-on-action.mjs" }
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
}
|
|
17
20
|
}
|
package/plugins/ui/plugin.json
CHANGED
|
@@ -3,9 +3,5 @@
|
|
|
3
3
|
"displayName": "PAI UI Customization",
|
|
4
4
|
"description": "Terminal tab titles, statusline, tab coloring, and visual customization",
|
|
5
5
|
"version": "0.7.0",
|
|
6
|
-
"
|
|
7
|
-
"required": false,
|
|
8
|
-
"depends": ["core"],
|
|
9
|
-
"hooks": "hooks/hooks.json",
|
|
10
|
-
"scripts": ["statusline-command.sh", "tab-color-command.sh"]
|
|
6
|
+
"hooks": "./hooks/hooks.json"
|
|
11
7
|
}
|
|
@@ -2,18 +2,5 @@
|
|
|
2
2
|
"name": "pai-zettelkasten",
|
|
3
3
|
"displayName": "PAI Zettelkasten Intelligence",
|
|
4
4
|
"description": "Luhmann-inspired vault intelligence with graph operations and Obsidian integration",
|
|
5
|
-
"version": "0.7.0"
|
|
6
|
-
"tier": "enterprise",
|
|
7
|
-
"required": false,
|
|
8
|
-
"depends": ["core", "semantic-search"],
|
|
9
|
-
"skills": ["VaultConnect", "VaultContext", "VaultEmerge", "VaultOrphans", "VaultTrace"],
|
|
10
|
-
"features": [
|
|
11
|
-
"vault_indexer",
|
|
12
|
-
"zettel_explore",
|
|
13
|
-
"zettel_surprise",
|
|
14
|
-
"zettel_converse",
|
|
15
|
-
"zettel_themes",
|
|
16
|
-
"zettel_health",
|
|
17
|
-
"zettel_suggest"
|
|
18
|
-
]
|
|
5
|
+
"version": "0.7.0"
|
|
19
6
|
}
|
|
@@ -31,8 +31,10 @@ SENTINEL="${TMPDIR:-/tmp}/pai-autosave-hook-${SENTINEL_KEY}"
|
|
|
31
31
|
|
|
32
32
|
if [ -f "$SENTINEL" ]; then
|
|
33
33
|
NOW=$(date +%s)
|
|
34
|
-
# stat is not portable:
|
|
35
|
-
|
|
34
|
+
# stat is not portable: GNU/Linux uses -c %Y, BSD/macOS uses -f %m. GNU
|
|
35
|
+
# first — BSD's `-f %m` reads as "filesystem status" on GNU and silently
|
|
36
|
+
# succeeds on the wrong thing instead of failing over.
|
|
37
|
+
LAST=$(stat -c %Y "$SENTINEL" 2>/dev/null || stat -f %m "$SENTINEL" 2>/dev/null || echo 0)
|
|
36
38
|
if [ $((NOW - LAST)) -lt "$MIN_GAP_SECONDS" ]; then
|
|
37
39
|
exit 0
|
|
38
40
|
fi
|
|
@@ -68,7 +68,7 @@ OLD_LOCK_DIR="$HOME/.config/pai/.session-stop.lock"
|
|
|
68
68
|
mkdir -p "$(dirname "$LOCK_DIR")" 2>/dev/null || true
|
|
69
69
|
|
|
70
70
|
if [ -d "$OLD_LOCK_DIR" ] && [ ! -d "$LOCK_DIR" ]; then
|
|
71
|
-
OLD_LOCK_AGE=$(( $(date +%s) - $(stat -f %m "$OLD_LOCK_DIR" 2>/dev/null || echo 0) ))
|
|
71
|
+
OLD_LOCK_AGE=$(( $(date +%s) - $(stat -c %Y "$OLD_LOCK_DIR" 2>/dev/null || stat -f %m "$OLD_LOCK_DIR" 2>/dev/null || echo 0) ))
|
|
72
72
|
if [ "$OLD_LOCK_AGE" -le 600 ]; then
|
|
73
73
|
echo "pai: honoring in-flight lock at old location $OLD_LOCK_DIR" >&2
|
|
74
74
|
LOCK_DIR="$OLD_LOCK_DIR"
|
|
@@ -78,7 +78,7 @@ fi
|
|
|
78
78
|
# A crashed run must not wedge this forever: treat a lock older than 10 minutes
|
|
79
79
|
# as abandoned. Longer than any observed tail, shorter than a working session.
|
|
80
80
|
if [ -d "$LOCK_DIR" ]; then
|
|
81
|
-
LOCK_AGE=$(( $(date +%s) - $(stat -f %m "$LOCK_DIR" 2>/dev/null || echo 0) ))
|
|
81
|
+
LOCK_AGE=$(( $(date +%s) - $(stat -c %Y "$LOCK_DIR" 2>/dev/null || stat -f %m "$LOCK_DIR" 2>/dev/null || echo 0) ))
|
|
82
82
|
[ "$LOCK_AGE" -gt 600 ] && rmdir "$LOCK_DIR" 2>/dev/null
|
|
83
83
|
fi
|
|
84
84
|
|
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
|
|
9
9
|
import { readFileSync, appendFileSync, mkdirSync, existsSync } from 'fs';
|
|
10
10
|
import { join } from 'path';
|
|
11
|
-
import { historyDir, agentSessionsPath } from './lib/pai-paths';
|
|
12
|
-
import { enrichEventWithAgentMetadata, isAgentSpawningCall } from './lib/metadata-extraction';
|
|
13
|
-
import { isProbeSession } from './lib/project-utils';
|
|
11
|
+
import { historyDir, agentSessionsPath } from './lib/pai-paths.js';
|
|
12
|
+
import { enrichEventWithAgentMetadata, isAgentSpawningCall } from './lib/metadata-extraction.js';
|
|
13
|
+
import { isProbeSession } from './lib/project-utils.js';
|
|
14
14
|
import { writeJsonAtomic } from '../../config/json-store.js';
|
|
15
15
|
|
|
16
16
|
interface HookEvent {
|
|
@@ -52,10 +52,11 @@ export function extractAgentInstanceId(
|
|
|
52
52
|
if (!result.agent_instance_id && toolInput?.prompt && typeof toolInput.prompt === 'string') {
|
|
53
53
|
const promptMatch = toolInput.prompt.match(/\[AGENT_INSTANCE:\s*([^\]]+)\]/);
|
|
54
54
|
if (promptMatch) {
|
|
55
|
-
|
|
55
|
+
const agentInstanceId = promptMatch[1].trim();
|
|
56
|
+
result.agent_instance_id = agentInstanceId;
|
|
56
57
|
|
|
57
58
|
// Parse agent type and instance number from ID
|
|
58
|
-
const parts =
|
|
59
|
+
const parts = agentInstanceId.match(/^([a-z-]+)-(\d+)$/);
|
|
59
60
|
if (parts) {
|
|
60
61
|
result.agent_type = parts[1];
|
|
61
62
|
result.instance_number = parseInt(parts[2], 10);
|
|
@@ -28,7 +28,7 @@ function resetNoticeFlag(): void {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
function deprecationLines(writeSpy: ReturnType<typeof vi.spyOn>): string[] {
|
|
31
|
-
return writeSpy.mock.calls.map((c) => String(c[0])).filter((line) => line.includes("PAI_DIR is deprecated"));
|
|
31
|
+
return writeSpy.mock.calls.map((c: unknown[]) => String(c[0])).filter((line: string) => line.includes("PAI_DIR is deprecated"));
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
beforeEach(() => {
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { decideSleepPollGate, renderDecision, type SleepPollGateInput } from "./sleep-poll-gate.js";
|
|
3
|
+
|
|
4
|
+
function decisionOf(input: SleepPollGateInput, env: Record<string, string | undefined> = {}) {
|
|
5
|
+
return JSON.parse(renderDecision(decideSleepPollGate(input, env))).hookSpecificOutput;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function bash(command: string, run_in_background?: boolean): SleepPollGateInput {
|
|
9
|
+
return { tool_name: "Bash", tool_input: { command, ...(run_in_background !== undefined ? { run_in_background } : {}) } };
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
describe("sleep-poll gate", () => {
|
|
13
|
+
it("denies a long sleep, standalone or buried in a compound command", () => {
|
|
14
|
+
for (const cmd of [
|
|
15
|
+
"sleep 590",
|
|
16
|
+
"sleep 2m",
|
|
17
|
+
"cd x && sleep 300",
|
|
18
|
+
"sleep 120; tail -5 f",
|
|
19
|
+
"while true; do sleep 90; done",
|
|
20
|
+
"for i in 1 2; do sleep 61; done",
|
|
21
|
+
]) {
|
|
22
|
+
const out = decisionOf(bash(cmd));
|
|
23
|
+
expect(out.permissionDecision).toBe("deny");
|
|
24
|
+
expect(out.hookEventName).toBe("PreToolUse");
|
|
25
|
+
expect(out.permissionDecisionReason).toContain("do not sleep-poll");
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("allows a short sleep or a sleep lookalike", () => {
|
|
30
|
+
for (const cmd of ["sleep 30", "sleep 59; tail f", "echo sleep 500", "grep sleep file", "timeout 600 make"]) {
|
|
31
|
+
expect(decisionOf(bash(cmd)).permissionDecision).toBe("allow");
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("allows any command when run_in_background is true — a backgrounded sleep blocks nothing", () => {
|
|
36
|
+
expect(decisionOf(bash("sleep 590", true)).permissionDecision).toBe("allow");
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("lets a non-Bash tool through untouched", () => {
|
|
40
|
+
expect(
|
|
41
|
+
decisionOf({ tool_name: "Write", tool_input: { command: "sleep 590" } } as unknown as SleepPollGateInput)
|
|
42
|
+
.permissionDecision
|
|
43
|
+
).toBe("allow");
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("interactive session: deny reason points at run_in_background and a bounded loop", () => {
|
|
47
|
+
const out = decisionOf(bash("sleep 590"), {});
|
|
48
|
+
expect(out.permissionDecisionReason).toContain("run_in_background: true");
|
|
49
|
+
expect(out.permissionDecisionReason).toContain("bounded loop under 60s");
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("worker session (PAI_WORKER=1): deny reason points at a foreground timeout and a kill -0 loop instead", () => {
|
|
53
|
+
const out = decisionOf(bash("sleep 590"), { PAI_WORKER: "1" });
|
|
54
|
+
expect(out.permissionDecisionReason).toContain("FOREGROUND with a Bash timeout up to 600000 ms");
|
|
55
|
+
expect(out.permissionDecisionReason).toContain("while kill -0 <pid> 2>/dev/null; do sleep 15; done");
|
|
56
|
+
expect(out.permissionDecisionReason).not.toContain("run_in_background: true");
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it("names the exact offending duration in the reason", () => {
|
|
60
|
+
expect(decisionOf(bash("sleep 2m")).permissionDecisionReason).toContain("sleep 120s blocked");
|
|
61
|
+
});
|
|
62
|
+
});
|