@tekmidian/pai 0.40.1 → 0.41.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/README.md +1 -0
- package/dist/browser-mcp/index.d.mts +1 -0
- package/dist/browser-mcp/index.mjs +352 -0
- package/dist/browser-mcp/index.mjs.map +1 -0
- package/dist/{chain-DhVHVnmT.mjs → chain-zMjCDW-R.mjs} +40 -8
- package/dist/chain-zMjCDW-R.mjs.map +1 -0
- package/dist/cli/index.mjs +3 -3
- package/dist/cli/program.mjs +3 -3
- package/dist/daemon-mcp/index.mjs +12 -2
- package/dist/daemon-mcp/index.mjs.map +1 -1
- package/dist/{fallback-CdXv-Np0.mjs → fallback-CgQ_x4I7.mjs} +2 -2
- package/dist/{fallback-CdXv-Np0.mjs.map → fallback-CgQ_x4I7.mjs.map} +1 -1
- package/dist/hooks/worker-status-line.mjs.map +2 -2
- package/dist/{planner-Cm3g6fWH.mjs → planner-DsmMRIZR.mjs} +2 -2
- package/dist/{planner-Cm3g6fWH.mjs.map → planner-DsmMRIZR.mjs.map} +1 -1
- package/dist/{program-AR0qlYRg.mjs → program-Bed-Pd-8.mjs} +67 -55
- package/dist/program-Bed-Pd-8.mjs.map +1 -0
- package/dist/skills/Worker/SKILL.md +10 -0
- package/docs/commands/README.md +2 -2
- package/docs/commands/mcp.md +4 -4
- package/docs/commands/worker.md +3 -0
- package/package.json +1 -1
- package/statusline-command.sh +65 -73
- package/dist/chain-DhVHVnmT.mjs.map +0 -1
- package/dist/program-AR0qlYRg.mjs.map +0 -1
|
@@ -25,12 +25,22 @@ pai worker run --label "short task label" --class research \\
|
|
|
25
25
|
`pai worker run --chain draft,implement …` — the draft stage turns the brief
|
|
26
26
|
into a spec file, implement runs with it, `--chain draft,implement,review`
|
|
27
27
|
adds a review pass. `--class spotcheck` for verification runs.
|
|
28
|
+
- Grant MCP tools by naming mcp__server__tool in --allowedTools (the server loads automatically).
|
|
28
29
|
- The answer is in the `result` field of the JSON it prints. Review the diff yourself.
|
|
29
30
|
- `--no-pane` suppresses the iTerm follow pane; panes open automatically otherwise.
|
|
30
31
|
- `--agent <name>` runs a definition from ~/.claude/agents/<name>.md (the agent
|
|
31
32
|
library runs on workers: body becomes the system prompt, tools the allowlist,
|
|
32
33
|
model the class).
|
|
33
34
|
|
|
35
|
+
### Waiting
|
|
36
|
+
|
|
37
|
+
- NEVER busy-wait for a worker. No sleep loops, no `sleep N; pai worker ps`
|
|
38
|
+
polling, no manual retry loops. Two sanctioned waits: run workers as
|
|
39
|
+
background Bash tasks (the harness fires a completion notification), or
|
|
40
|
+
call `pai worker wait <id...>` which blocks until they finish and prints
|
|
41
|
+
each result as one JSON line. If you catch yourself sleeping to re-check a
|
|
42
|
+
worker, stop — you already get notified.
|
|
43
|
+
|
|
34
44
|
### Watching
|
|
35
45
|
|
|
36
46
|
- `worker_ps` — running + last finished workers (chains show as trees).
|
package/docs/commands/README.md
CHANGED
|
@@ -68,8 +68,8 @@ Generated man pages for every `pai` command area. Read any page in the terminal
|
|
|
68
68
|
| `pai kg query` | Query KG triples by subject, predicate, object, time, or project |
|
|
69
69
|
| `pai kg stats` | Show triple counts and contradiction count |
|
|
70
70
|
| `pai mcp` | MCP server management: install and status |
|
|
71
|
-
| `pai mcp install` | Register the PAI MCP server in ~/.claude.json (restart Claude Code to activate) |
|
|
72
|
-
| `pai mcp status` | Show whether the PAI MCP server is registered and the binary exists |
|
|
71
|
+
| `pai mcp install` | Register the PAI MCP server (pai) in ~/.claude.json (restart Claude Code to activate) |
|
|
72
|
+
| `pai mcp status` | Show whether the PAI MCP server (pai) is registered and the binary exists |
|
|
73
73
|
| `pai memory` | Memory engine: index, search, and status |
|
|
74
74
|
| `pai memory embed [project-slug]` | Generate embeddings for un-embedded chunks (Phase 2.5) |
|
|
75
75
|
| `pai memory index [project-slug]` | Index memory files for one project or all projects |
|
package/docs/commands/mcp.md
CHANGED
|
@@ -14,17 +14,17 @@ pai mcp <subcommand> [options]
|
|
|
14
14
|
|
|
15
15
|
| Command | Description |
|
|
16
16
|
|---------|-------------|
|
|
17
|
-
| [`pai mcp install`](#pai-mcp-install) | Register the PAI MCP server in ~/.claude.json (restart Claude Code to activate) |
|
|
18
|
-
| [`pai mcp status`](#pai-mcp-status) | Show whether the PAI MCP server is registered and the binary exists |
|
|
17
|
+
| [`pai mcp install`](#pai-mcp-install) | Register the PAI MCP server (pai) in ~/.claude.json (restart Claude Code to activate) |
|
|
18
|
+
| [`pai mcp status`](#pai-mcp-status) | Show whether the PAI MCP server (pai) is registered and the binary exists |
|
|
19
19
|
|
|
20
20
|
### pai mcp install
|
|
21
21
|
|
|
22
|
-
Register the PAI MCP server in ~/.claude.json (restart Claude Code to activate)
|
|
22
|
+
Register the PAI MCP server (pai) in ~/.claude.json (restart Claude Code to activate)
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
### pai mcp status
|
|
26
26
|
|
|
27
|
-
Show whether the PAI MCP server is registered and the binary exists
|
|
27
|
+
Show whether the PAI MCP server (pai) is registered and the binary exists
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
## See also
|
package/docs/commands/worker.md
CHANGED
|
@@ -47,6 +47,7 @@ Run one claude-code worker through the configured provider.
|
|
|
47
47
|
|
|
48
48
|
Unknown options are passed to claude verbatim (e.g. -p, --allowedTools);
|
|
49
49
|
--output-format/--verbose are handled here.
|
|
50
|
+
Grant MCP tools by naming mcp__server__tool in --allowedTools (the server loads automatically);
|
|
50
51
|
--chain draft,implement[,review] runs a spec-first pipeline;
|
|
51
52
|
--agent <name> runs an agent definition from ~/.claude/agents.
|
|
52
53
|
|
|
@@ -192,6 +193,8 @@ Merge a worker's worktree branch (worker/<id>) into the original checkout, then
|
|
|
192
193
|
|
|
193
194
|
Poll workers until they finish; prints each result as one JSON line, exit 1 on failure or timeout
|
|
194
195
|
|
|
196
|
+
Never busy-wait for a worker: no sleep loops, no sleep-then-`pai worker ps` polling, no manual retry loops. Two sanctioned waits: run workers as background Bash tasks (the harness notifies on completion), or call `pai worker wait`, which blocks until they finish and prints each result. If you catch yourself sleeping to re-check a worker, stop — you already get notified.
|
|
197
|
+
|
|
195
198
|
**Arguments**
|
|
196
199
|
|
|
197
200
|
| Argument | Kind |
|
package/package.json
CHANGED
package/statusline-command.sh
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
#
|
|
12
12
|
# LINES DISPLAYED:
|
|
13
13
|
# 1. Greeting: DA name, model, directory
|
|
14
|
-
# 2. MCPs:
|
|
14
|
+
# 2. MCPs: server count, then names that fit the width (rest shown as +N)
|
|
15
15
|
# 3. Context: Current session context window usage (K / 200K)
|
|
16
16
|
#
|
|
17
17
|
# ENVIRONMENT VARIABLES (set in settings.json env section):
|
|
@@ -86,27 +86,26 @@ fi
|
|
|
86
86
|
# Config directory
|
|
87
87
|
claude_dir="${PAI_DIR:-$HOME/.claude}"
|
|
88
88
|
|
|
89
|
-
#
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
# Collect MCP server names from all config sources (settings.json, .mcp.json,
|
|
90
|
+
# ~/.claude.json). Only entries that define a server (object with a command,
|
|
91
|
+
# type or url field) count: Claude Code also stores per-tool usage stats in
|
|
92
|
+
# mcpServers under tool-name keys ("Read", "mcp__pai__memory_search", …), and
|
|
93
|
+
# those must never reach the status line. Keys are newline-separated so names
|
|
94
|
+
# containing spaces survive.
|
|
95
|
+
mcp_names=""
|
|
92
96
|
|
|
93
|
-
# Helper: merge MCP names from a jq-compatible JSON file
|
|
94
97
|
_merge_mcps() {
|
|
95
98
|
local file="$1"
|
|
96
99
|
[ -f "$file" ] || return
|
|
97
|
-
local
|
|
98
|
-
|
|
99
|
-
[ -n "$data" ] && [ "$data" != "null" ] || return
|
|
100
|
-
local names count
|
|
101
|
-
names=$(echo "$data" | head -1)
|
|
102
|
-
count=$(echo "$data" | tail -1)
|
|
100
|
+
local names
|
|
101
|
+
names=$(jq -r '.mcpServers // {} | to_entries[] | select(((.value | type) == "object") and (.value | (has("command") or has("type") or has("url")))) | .key' "$file" 2>/dev/null)
|
|
103
102
|
[ -n "$names" ] || return
|
|
104
|
-
if [ -n "$
|
|
105
|
-
|
|
103
|
+
if [ -n "$mcp_names" ]; then
|
|
104
|
+
mcp_names="${mcp_names}
|
|
105
|
+
${names}"
|
|
106
106
|
else
|
|
107
|
-
|
|
107
|
+
mcp_names="$names"
|
|
108
108
|
fi
|
|
109
|
-
mcps_count=$((mcps_count + count))
|
|
110
109
|
}
|
|
111
110
|
|
|
112
111
|
# Read from all three MCP config locations
|
|
@@ -114,11 +113,12 @@ _merge_mcps "$claude_dir/settings.json" # legacy
|
|
|
114
113
|
_merge_mcps "$claude_dir/.mcp.json" # project-level
|
|
115
114
|
_merge_mcps "$HOME/.claude.json" # user-level (e.g. Coogle, DEVONthink)
|
|
116
115
|
|
|
117
|
-
# Deduplicate
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
116
|
+
# Deduplicate (case-insensitive — macOS config keys drift in case), first
|
|
117
|
+
# spelling wins, order preserved
|
|
118
|
+
mcp_list=()
|
|
119
|
+
while IFS= read -r mcp_line; do
|
|
120
|
+
mcp_list+=("$mcp_line")
|
|
121
|
+
done < <(printf '%s\n' "$mcp_names" | awk 'NF && !seen[tolower($0)]++')
|
|
122
122
|
|
|
123
123
|
# Extract context window usage from Claude Code's JSON input (no JSONL parsing needed)
|
|
124
124
|
context_pct=$(echo "$input" | jq -r '.context_window.used_percentage // 0' 2>/dev/null)
|
|
@@ -247,8 +247,7 @@ if [ "${PAI_SIMPLE_COLORS:-0}" = "1" ]; then
|
|
|
247
247
|
MCP_DEFAULT='\033[34m'
|
|
248
248
|
fi
|
|
249
249
|
|
|
250
|
-
# Format MCP
|
|
251
|
-
# Debug: log available width info (remove after testing)
|
|
250
|
+
# Format the MCP segment (see the render block below)
|
|
252
251
|
# Terminal width for line truncation
|
|
253
252
|
# Claude Code's statusline subprocess can't detect resize (stty returns stale values).
|
|
254
253
|
# To set your width: echo 105 > ~/.claude/.statusline_width
|
|
@@ -258,8 +257,7 @@ term_width=80
|
|
|
258
257
|
[ "$term_width" -gt 0 ] 2>/dev/null || term_width=80
|
|
259
258
|
mcp_prefix_width=10 # visual width of "🔌 MCPs: " (emoji=2 + space + "MCPs: " = 10)
|
|
260
259
|
|
|
261
|
-
#
|
|
262
|
-
# No width detection needed: if total display chars > 60, split at the midpoint.
|
|
260
|
+
# Display-name mapping for known servers
|
|
263
261
|
_mcp_display_name() {
|
|
264
262
|
case "$1" in
|
|
265
263
|
"daemon") echo "Daemon" ;;
|
|
@@ -275,7 +273,9 @@ _mcp_display_name() {
|
|
|
275
273
|
"macos_automator") echo "macOS" ;;
|
|
276
274
|
"claude_ai_Gmail") echo "Gmail" ;;
|
|
277
275
|
"claude_ai_Google_Calendar") echo "GCal" ;;
|
|
278
|
-
|
|
276
|
+
# capitalize without bash-4 ${n^} so /bin/bash 3.2 renders names too
|
|
277
|
+
*) local n="$1"
|
|
278
|
+
printf '%s%s' "$(printf '%s' "$n" | cut -c1 | tr '[:lower:]' '[:upper:]')" "$(printf '%s' "$n" | cut -c2-)" ;;
|
|
279
279
|
esac
|
|
280
280
|
}
|
|
281
281
|
|
|
@@ -288,57 +288,53 @@ _mcp_formatted() {
|
|
|
288
288
|
esac
|
|
289
289
|
}
|
|
290
290
|
|
|
291
|
-
#
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
for mcp in $mcp_names_raw; do
|
|
298
|
-
dn=$(_mcp_display_name "$mcp")
|
|
299
|
-
fm=$(_mcp_formatted "$dn")
|
|
300
|
-
mcp_display_names+=("$dn")
|
|
301
|
-
mcp_formatted_strs+=("$fm")
|
|
302
|
-
if [ $total_mcps -gt 0 ]; then
|
|
303
|
-
total_display_width=$((total_display_width + 2)) # ", "
|
|
304
|
-
fi
|
|
305
|
-
total_display_width=$((total_display_width + ${#dn}))
|
|
306
|
-
total_mcps=$((total_mcps + 1))
|
|
307
|
-
done
|
|
308
|
-
|
|
309
|
-
# Decide: one line or two lines?
|
|
310
|
-
# If total display width > 60 chars, split at the midpoint
|
|
291
|
+
# Build the MCP segment: "N: name1, name2, … +K" — total server count first,
|
|
292
|
+
# then as many display names as fit the width (hard cap regardless of width),
|
|
293
|
+
# the rest collapsed into "+K". Always a single line: what doesn't fit is
|
|
294
|
+
# counted, never printed.
|
|
295
|
+
mcp_total=${#mcp_list[@]}
|
|
311
296
|
mcp_line1=""
|
|
312
|
-
mcp_line2=""
|
|
313
297
|
|
|
314
|
-
if [ $
|
|
298
|
+
if [ "$mcp_total" -eq 0 ]; then
|
|
315
299
|
mcp_line1="none"
|
|
316
|
-
elif [ $total_display_width -le $term_width ]; then
|
|
317
|
-
# Single line — everything fits
|
|
318
|
-
for ((i=0; i<total_mcps; i++)); do
|
|
319
|
-
if [ $i -eq 0 ]; then
|
|
320
|
-
mcp_line1="${mcp_formatted_strs[$i]}"
|
|
321
|
-
else
|
|
322
|
-
mcp_line1="${mcp_line1}${SEPARATOR_COLOR}, ${mcp_formatted_strs[$i]}"
|
|
323
|
-
fi
|
|
324
|
-
done
|
|
325
300
|
else
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
for
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
301
|
+
mcp_max_names=6
|
|
302
|
+
# Width budget for the name list: terminal minus prefix, minus the leading
|
|
303
|
+
# "N: " and a reserve for the trailing " +K" overflow marker
|
|
304
|
+
mcp_budget=$(( term_width - mcp_prefix_width - ${#mcp_total} - 2 - 6 ))
|
|
305
|
+
[ "$mcp_budget" -lt 12 ] && mcp_budget=12
|
|
306
|
+
mcp_width=0
|
|
307
|
+
mcp_shown=0
|
|
308
|
+
mcp_overflow=0
|
|
309
|
+
for mcp in "${mcp_list[@]}"; do
|
|
310
|
+
dn=$(_mcp_display_name "$mcp")
|
|
311
|
+
w_add=${#dn}
|
|
312
|
+
[ "$mcp_shown" -gt 0 ] && w_add=$(( w_add + 2 )) # ", " separator
|
|
313
|
+
if [ "$mcp_shown" -ge "$mcp_max_names" ] || [ $(( mcp_width + w_add )) -gt "$mcp_budget" ]; then
|
|
314
|
+
mcp_overflow=$(( mcp_overflow + 1 ))
|
|
315
|
+
continue
|
|
333
316
|
fi
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
317
|
+
fm=$(_mcp_formatted "$dn")
|
|
318
|
+
if [ "$mcp_shown" -eq 0 ]; then
|
|
319
|
+
mcp_line1="${mcp_total}${SEPARATOR_COLOR}: ${RESET}${fm}"
|
|
320
|
+
mcp_width=${#mcp_total}
|
|
338
321
|
else
|
|
339
|
-
|
|
322
|
+
mcp_line1="${mcp_line1}${SEPARATOR_COLOR}, ${fm}"
|
|
323
|
+
mcp_width=$(( mcp_width + 2 ))
|
|
340
324
|
fi
|
|
325
|
+
mcp_width=$(( mcp_width + ${#dn} ))
|
|
326
|
+
mcp_shown=$(( mcp_shown + 1 ))
|
|
341
327
|
done
|
|
328
|
+
if [ "$mcp_shown" -eq 0 ]; then
|
|
329
|
+
# Even the first name exceeds the budget — truncate that one name
|
|
330
|
+
dn=$(_mcp_display_name "${mcp_list[0]}")
|
|
331
|
+
avail=$(( mcp_budget - 1 ))
|
|
332
|
+
[ "$avail" -lt 3 ] && avail=3
|
|
333
|
+
dn="${dn:0:$((avail - 1))}…"
|
|
334
|
+
mcp_line1="${mcp_total}${SEPARATOR_COLOR}: ${RESET}$(_mcp_formatted "$dn")"
|
|
335
|
+
mcp_overflow=$(( mcp_total - 1 ))
|
|
336
|
+
fi
|
|
337
|
+
[ "$mcp_overflow" -gt 0 ] && mcp_line1="${mcp_line1}${SEPARATOR_COLOR} +${RESET}${LINE2_ACCENT}${mcp_overflow}${RESET}"
|
|
342
338
|
fi
|
|
343
339
|
|
|
344
340
|
# Output the statusline
|
|
@@ -356,12 +352,8 @@ else
|
|
|
356
352
|
printf "${line1_short}\n"
|
|
357
353
|
fi
|
|
358
354
|
|
|
359
|
-
# LINE 2 - MCPs (
|
|
355
|
+
# LINE 2 - MCPs (single line, capped by width; overflow shown as +N)
|
|
360
356
|
printf "${LINE2_PRIMARY}${EMOJI_PLUG} MCPs${RESET}${LINE2_PRIMARY}${SEPARATOR_COLOR}: ${RESET}${mcp_line1}${RESET}\n"
|
|
361
|
-
if [ -n "$mcp_line2" ]; then
|
|
362
|
-
# Continuation line — indent to align with MCP names after "🔌 MCPs: "
|
|
363
|
-
printf "${LINE2_PRIMARY} ${RESET}${mcp_line2}${RESET}\n"
|
|
364
|
-
fi
|
|
365
357
|
|
|
366
358
|
|
|
367
359
|
# Usage suffix: provider-aware. glm sessions read the Z.ai plan quota
|