@workweave/router 0.2.10 → 0.2.12
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 +40 -14
- package/cc-statusline.sh +274 -23
- package/codex-skills/fm/SKILL.md +15 -0
- package/codex-skills/fm/scripts/emit.sh +8 -0
- package/codex-skills/force-model/SKILL.md +15 -0
- package/codex-skills/force-model/scripts/emit.sh +9 -0
- package/codex-skills/rf/SKILL.md +15 -0
- package/codex-skills/rf/scripts/emit.sh +7 -0
- package/codex-skills/router-feedback/SKILL.md +15 -0
- package/codex-skills/router-feedback/scripts/emit.sh +9 -0
- package/codex-skills/router-models/SKILL.md +51 -0
- package/codex-skills/router-off/SKILL.md +22 -0
- package/codex-skills/router-on/SKILL.md +22 -0
- package/codex-skills/router-status/SKILL.md +19 -0
- package/codex-skills/ufm/SKILL.md +14 -0
- package/codex-skills/ufm/scripts/emit.sh +3 -0
- package/codex-skills/unforce-model/SKILL.md +14 -0
- package/codex-skills/unforce-model/scripts/emit.sh +4 -0
- package/codex-status.sh +312 -0
- package/commands/beta.md +5 -0
- package/commands/models.md +46 -0
- package/commands/router-models.md +46 -0
- package/directives.tsv +13 -0
- package/install.sh +1849 -263
- package/package.json +7 -1
- package/pi-router/README.md +39 -7
- package/pi-router/skills/install-lsps/SKILL.md +75 -0
- package/pi-router/skills/lsp-guide/SKILL.md +63 -0
- package/pi-router/src/beta.ts +21 -0
- package/pi-router/src/compaction.ts +46 -8
- package/pi-router/src/config.ts +34 -5
- package/pi-router/src/context-window.ts +12 -0
- package/pi-router/src/dispatch.ts +35 -2
- package/pi-router/src/index.ts +12 -1
- package/pi-router/src/lsp-broker.ts +255 -0
- package/pi-router/src/lsp-client.ts +435 -0
- package/pi-router/src/lsp-format.ts +230 -0
- package/pi-router/src/lsp-install.ts +215 -0
- package/pi-router/src/lsp-protocol.ts +128 -0
- package/pi-router/src/lsp-servers.ts +361 -0
- package/pi-router/src/lsp.ts +529 -0
- package/pi-router/src/pricing.generated.ts +77 -70
- package/pi-router/src/provider.ts +15 -2
- package/pi-router/src/routed-model.ts +17 -0
- package/pi-router/src/savings.ts +1 -1
- package/registry.sh +102 -0
- package/uninstall.sh +210 -31
package/uninstall.sh
CHANGED
|
@@ -27,6 +27,119 @@ set -euo pipefail
|
|
|
27
27
|
scope="user"
|
|
28
28
|
scope_explicit="false"
|
|
29
29
|
install_dir=""
|
|
30
|
+
script_dir="$(cd "$(dirname "$0")" 2>/dev/null && pwd || true)"
|
|
31
|
+
|
|
32
|
+
# ---------- directive registry (embedded) ----------
|
|
33
|
+
#
|
|
34
|
+
# uninstall.sh is served standalone too (the npm bin runs it directly, and it
|
|
35
|
+
# can be piped), so it cannot rely on a sibling registry.sh. The data and
|
|
36
|
+
# helpers are embedded verbatim; install/tests/registry_test.sh asserts they
|
|
37
|
+
# never drift from the canonical files. Regenerate with `make embed-registry`.
|
|
38
|
+
WEAVE_REGISTRY_DATA=$(cat <<'WEAVE_REGISTRY_EOF'
|
|
39
|
+
# Weave Router directive registry
|
|
40
|
+
# canonical|aliases|capability|claude|codex|opencode|pi|cursor|adapter
|
|
41
|
+
# aliases are comma-separated; client columns are yes/no. adapter is the native asset kind.
|
|
42
|
+
force-model|fm|prompt|yes|yes|yes|yes|manual|command,skill
|
|
43
|
+
unforce-model|ufm|prompt|yes|yes|yes|yes|manual|command,skill
|
|
44
|
+
router-feedback|rf|prompt|yes|yes|yes|no|manual|command,skill
|
|
45
|
+
router-off||local-toggle|yes|yes|no|no|manual|command,skill
|
|
46
|
+
router-on||local-toggle|yes|yes|no|no|manual|command,skill
|
|
47
|
+
router-status||local-toggle|yes|yes|no|no|manual|command,skill
|
|
48
|
+
router-session||prompt|yes|no|no|no|manual|command
|
|
49
|
+
router-models|models|local-toggle|yes|yes|no|no|manual|command,skill
|
|
50
|
+
disable-routing||local-toggle|no|yes|no|no|manual|skill
|
|
51
|
+
beta||prompt|yes|no|no|yes|manual|command
|
|
52
|
+
WEAVE_REGISTRY_EOF
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
# >>> weave-router registry lib >>>
|
|
56
|
+
weave_registry_rows() {
|
|
57
|
+
if [ -n "${WEAVE_REGISTRY_DATA:-}" ]; then
|
|
58
|
+
printf '%s\n' "$WEAVE_REGISTRY_DATA" | awk -F '|' '!/^([[:space:]]*#|[[:space:]]*$)/ { print }'
|
|
59
|
+
return 0
|
|
60
|
+
fi
|
|
61
|
+
local registry="${WEAVE_REGISTRY_FILE:-}"
|
|
62
|
+
if [ -z "$registry" ]; then
|
|
63
|
+
local dir
|
|
64
|
+
dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd -P)" || return 1
|
|
65
|
+
registry="$dir/directives.tsv"
|
|
66
|
+
fi
|
|
67
|
+
[ -f "$registry" ] || return 1
|
|
68
|
+
awk -F '|' '!/^([[:space:]]*#|[[:space:]]*$)/ { print }' "$registry"
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
# weave_registry_names lists every canonical name and alias a client installs.
|
|
72
|
+
weave_registry_names() {
|
|
73
|
+
local target="$1" canonical aliases capability claude codex opencode pi cursor adapter
|
|
74
|
+
while IFS='|' read -r canonical aliases capability claude codex opencode pi cursor adapter; do
|
|
75
|
+
case "$target" in
|
|
76
|
+
claude) [ "$claude" = yes ] || continue ;; codex) [ "$codex" = yes ] || continue ;;
|
|
77
|
+
opencode) [ "$opencode" = yes ] || continue ;; pi) [ "$pi" = yes ] || continue ;;
|
|
78
|
+
cursor) [ "$cursor" = yes ] || continue ;;
|
|
79
|
+
esac
|
|
80
|
+
printf '%s\n' "$canonical"
|
|
81
|
+
[ -n "$aliases" ] && printf '%s\n' "$aliases" | tr ',' '\n'
|
|
82
|
+
done <<EOF
|
|
83
|
+
$(weave_registry_rows)
|
|
84
|
+
EOF
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
# weave_registry_skill_names lists the prompt directives a client exposes as a
|
|
88
|
+
# native skill. Local-config toggles are excluded: they mutate config this
|
|
89
|
+
# installer owns and are handled per target, not as a generic prompt.
|
|
90
|
+
weave_registry_skill_names() {
|
|
91
|
+
local target="$1" canonical aliases capability claude codex opencode pi cursor adapter
|
|
92
|
+
while IFS='|' read -r canonical aliases capability claude codex opencode pi cursor adapter; do
|
|
93
|
+
[ "$capability" = prompt ] || continue
|
|
94
|
+
case "$target" in
|
|
95
|
+
claude) [ "$claude" = yes ] || continue ;; codex) [ "$codex" = yes ] || continue ;;
|
|
96
|
+
opencode) [ "$opencode" = yes ] || continue ;; pi) [ "$pi" = yes ] || continue ;;
|
|
97
|
+
cursor) [ "$cursor" = yes ] || continue ;;
|
|
98
|
+
esac
|
|
99
|
+
printf '%s\n' "$canonical"
|
|
100
|
+
[ -n "$aliases" ] && printf '%s\n' "$aliases" | tr ',' '\n'
|
|
101
|
+
done <<EOF
|
|
102
|
+
$(weave_registry_rows)
|
|
103
|
+
EOF
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
# weave_registry_skill_assets lists every directive a client ships as a skill
|
|
107
|
+
# file, including local-config toggles such as Codex's disable-routing. Install
|
|
108
|
+
# and uninstall use this for file management; weave_registry_skill_names is the
|
|
109
|
+
# narrower prompt-only set used when generating prompt adapters.
|
|
110
|
+
weave_registry_skill_assets() {
|
|
111
|
+
local target="$1" canonical aliases capability claude codex opencode pi cursor adapter
|
|
112
|
+
while IFS='|' read -r canonical aliases capability claude codex opencode pi cursor adapter; do
|
|
113
|
+
case ",$adapter," in *,skill,*) ;; *) continue ;; esac
|
|
114
|
+
case "$target" in
|
|
115
|
+
claude) [ "$claude" = yes ] || continue ;; codex) [ "$codex" = yes ] || continue ;;
|
|
116
|
+
opencode) [ "$opencode" = yes ] || continue ;; pi) [ "$pi" = yes ] || continue ;;
|
|
117
|
+
cursor) [ "$cursor" = yes ] || continue ;;
|
|
118
|
+
esac
|
|
119
|
+
printf '%s\n' "$canonical"
|
|
120
|
+
[ -n "$aliases" ] && printf '%s\n' "$aliases" | tr ',' '\n'
|
|
121
|
+
done <<EOF
|
|
122
|
+
$(weave_registry_rows)
|
|
123
|
+
EOF
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
# weave_registry_canonical_for resolves a name or alias to its canonical
|
|
127
|
+
# directive, and fails when the name is not in the registry at all.
|
|
128
|
+
weave_registry_canonical_for() {
|
|
129
|
+
local wanted="$1" canonical aliases capability claude codex opencode pi cursor adapter alias
|
|
130
|
+
while IFS='|' read -r canonical aliases capability claude codex opencode pi cursor adapter; do
|
|
131
|
+
[ "$wanted" = "$canonical" ] && { printf '%s' "$canonical"; return 0; }
|
|
132
|
+
IFS=',' read -ra _aliases <<< "$aliases"
|
|
133
|
+
for alias in ${_aliases[@]+"${_aliases[@]}"}; do
|
|
134
|
+
[ "$wanted" = "$alias" ] && { printf '%s' "$canonical"; return 0; }
|
|
135
|
+
done
|
|
136
|
+
done <<EOF
|
|
137
|
+
$(weave_registry_rows)
|
|
138
|
+
EOF
|
|
139
|
+
return 1
|
|
140
|
+
}
|
|
141
|
+
# <<< weave-router registry lib <<<
|
|
142
|
+
|
|
30
143
|
target="claude"
|
|
31
144
|
|
|
32
145
|
err() { printf "\033[31merror:\033[0m %s\n" "$*" >&2; }
|
|
@@ -92,7 +205,6 @@ fi
|
|
|
92
205
|
# Markers must stay in sync with install.sh. Keep verbatim.
|
|
93
206
|
WEAVE_CODEX_BEGIN_MARKER="# >>> weave-router managed (do not edit between markers) >>>"
|
|
94
207
|
WEAVE_CODEX_END_MARKER="# <<< weave-router managed <<<"
|
|
95
|
-
WEAVE_CODEX_SKILL_MARKER="<!-- weave-router managed disable-routing skill -->"
|
|
96
208
|
|
|
97
209
|
# strip_codex_block rewrites config.toml without the managed block and any
|
|
98
210
|
# top-level `model_provider = "weave"` that lived outside the markers (which
|
|
@@ -223,14 +335,20 @@ if [ "$target" = "opencode" ]; then
|
|
|
223
335
|
local opencode_cmds_dir="$1" cmd cmd_file
|
|
224
336
|
if [ -d "$opencode_cmds_dir" ]; then
|
|
225
337
|
refuse_if_symlink "$opencode_cmds_dir"
|
|
226
|
-
|
|
338
|
+
while IFS= read -r cmd; do
|
|
227
339
|
cmd_file="$opencode_cmds_dir/$cmd.md"
|
|
228
340
|
if [ -f "$cmd_file" ]; then
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
341
|
+
if grep -Fq "<!-- weave-router managed command: $cmd -->" "$cmd_file"; then
|
|
342
|
+
refuse_if_symlink "$cmd_file"
|
|
343
|
+
rm -f "$cmd_file"
|
|
344
|
+
ok "Removed $cmd_file"
|
|
345
|
+
else
|
|
346
|
+
warn "Leaving user-owned opencode command at $cmd_file untouched."
|
|
347
|
+
fi
|
|
232
348
|
fi
|
|
233
|
-
done
|
|
349
|
+
done <<EOF
|
|
350
|
+
$(weave_registry_names opencode)
|
|
351
|
+
EOF
|
|
234
352
|
rmdir "$opencode_cmds_dir" 2>/dev/null || true
|
|
235
353
|
fi
|
|
236
354
|
}
|
|
@@ -405,7 +523,15 @@ if [ "$target" = "codex" ]; then
|
|
|
405
523
|
refuse_if_symlink "$codex_dir"
|
|
406
524
|
fi
|
|
407
525
|
codex_config_file="$codex_dir/config.toml"
|
|
526
|
+
if [ "$scope" = "user" ] && [ -z "$install_dir" ]; then
|
|
527
|
+
codex_status_file="$HOME/.weave/codex-status.sh"
|
|
528
|
+
else
|
|
529
|
+
codex_status_file="$codex_dir/weave-status.sh"
|
|
530
|
+
fi
|
|
531
|
+
codex_status_disabled_marker="$(dirname "$codex_status_file")/.weave-router-disabled"
|
|
408
532
|
refuse_if_symlink "$codex_config_file"
|
|
533
|
+
refuse_if_symlink "$codex_status_file"
|
|
534
|
+
refuse_if_symlink "$codex_status_disabled_marker"
|
|
409
535
|
|
|
410
536
|
if [ -f "$codex_config_file" ]; then
|
|
411
537
|
strip_codex_block "$codex_config_file"
|
|
@@ -422,39 +548,85 @@ if [ "$target" = "codex" ]; then
|
|
|
422
548
|
info "No Codex config at $codex_config_file (already uninstalled?)"
|
|
423
549
|
fi
|
|
424
550
|
|
|
551
|
+
# A user config with an existing [features] table receives the installer
|
|
552
|
+
# hook setting outside the managed block; remove only our tagged line.
|
|
553
|
+
if [ -f "$codex_config_file" ]; then
|
|
554
|
+
tmp="$(mktemp -t weave-codex-features-uninstall.XXXXXX)"
|
|
555
|
+
awk '$0 != "hooks = true # weave-router managed codex hooks" { print }' "$codex_config_file" >"$tmp"
|
|
556
|
+
mv "$tmp" "$codex_config_file"
|
|
557
|
+
fi
|
|
558
|
+
|
|
559
|
+
if [ -f "$codex_status_file" ]; then
|
|
560
|
+
if grep -Fq '<!-- weave-router managed codex status -->' "$codex_status_file"; then
|
|
561
|
+
rm -f "$codex_status_file"
|
|
562
|
+
rm -f "$codex_status_disabled_marker"
|
|
563
|
+
ok "Removed $codex_status_file"
|
|
564
|
+
rmdir "$(dirname "$codex_status_file")" 2>/dev/null || true
|
|
565
|
+
else
|
|
566
|
+
warn "Leaving user-owned Codex status helper at $codex_status_file untouched."
|
|
567
|
+
fi
|
|
568
|
+
fi
|
|
569
|
+
|
|
425
570
|
# Remove only the prompt files this installer owns; leave any user-authored
|
|
426
571
|
# entries in prompts/ alone. The dir itself is dropped only if empty after.
|
|
427
572
|
codex_prompts_dir="$codex_dir/prompts"
|
|
428
573
|
if [ -d "$codex_prompts_dir" ]; then
|
|
429
574
|
refuse_if_symlink "$codex_prompts_dir"
|
|
430
|
-
|
|
575
|
+
while IFS= read -r cmd; do
|
|
431
576
|
cmd_file="$codex_prompts_dir/$cmd.md"
|
|
432
577
|
if [ -f "$cmd_file" ]; then
|
|
433
578
|
refuse_if_symlink "$cmd_file"
|
|
434
579
|
rm -f "$cmd_file"
|
|
435
580
|
ok "Removed $cmd_file"
|
|
436
581
|
fi
|
|
437
|
-
done
|
|
582
|
+
done <<EOF
|
|
583
|
+
$(weave_registry_names codex)
|
|
584
|
+
EOF
|
|
438
585
|
rmdir "$codex_prompts_dir" 2>/dev/null || true
|
|
439
586
|
fi
|
|
440
587
|
|
|
441
|
-
#
|
|
442
|
-
#
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
warn "
|
|
588
|
+
# disable-routing is handled by the registry-driven loop below, alongside
|
|
589
|
+
# every other installer-owned skill.
|
|
590
|
+
|
|
591
|
+
# A symlinked skills/ or per-skill directory would let the marker check and
|
|
592
|
+
# the rm below reach a file outside the Codex tree entirely, so refuse the
|
|
593
|
+
# parents before touching anything beneath them — not just SKILL.md itself.
|
|
594
|
+
if [ -L "$codex_dir/skills" ]; then
|
|
595
|
+
warn "$codex_dir/skills is a symlink; leaving Codex skills untouched."
|
|
596
|
+
else
|
|
597
|
+
while IFS= read -r canonical; do
|
|
598
|
+
skill_dir="$codex_dir/skills/$canonical"
|
|
599
|
+
skill_file="$skill_dir/SKILL.md"
|
|
600
|
+
if [ -L "$skill_dir" ]; then
|
|
601
|
+
warn "$skill_dir is a symlink; leaving it untouched."
|
|
602
|
+
continue
|
|
455
603
|
fi
|
|
456
|
-
|
|
457
|
-
|
|
604
|
+
if [ -L "$skill_file" ]; then
|
|
605
|
+
warn "$skill_file is a symlink; leaving it untouched."
|
|
606
|
+
continue
|
|
607
|
+
fi
|
|
608
|
+
if [ -f "$skill_file" ]; then
|
|
609
|
+
if grep -Fq "<!-- weave-router managed $canonical skill -->" "$skill_file"; then
|
|
610
|
+
rm -f "$skill_file"
|
|
611
|
+
ok "Removed $skill_file"
|
|
612
|
+
# The prompt skills also ship scripts/emit.sh; leaving it behind
|
|
613
|
+
# strands a directory Codex still advertises as a skill.
|
|
614
|
+
emit_file="$skill_dir/scripts/emit.sh"
|
|
615
|
+
if [ ! -L "$skill_dir/scripts" ] && [ ! -L "$emit_file" ] && [ -f "$emit_file" ]; then
|
|
616
|
+
rm -f "$emit_file"
|
|
617
|
+
rmdir "$skill_dir/scripts" 2>/dev/null || true
|
|
618
|
+
fi
|
|
619
|
+
else
|
|
620
|
+
warn "Leaving user-owned Codex skill at $skill_file untouched."
|
|
621
|
+
fi
|
|
622
|
+
rmdir "$skill_dir" 2>/dev/null || true
|
|
623
|
+
fi
|
|
624
|
+
done <<EOF
|
|
625
|
+
$(weave_registry_skill_assets codex)
|
|
626
|
+
EOF
|
|
627
|
+
# Drop skills/ when nothing is left in it, matching how the prompts and
|
|
628
|
+
# Claude command paths clean up their now-empty directories. rmdir refuses
|
|
629
|
+
# a non-empty dir, so an unrelated user skill keeps it.
|
|
458
630
|
rmdir "$codex_dir/skills" 2>/dev/null || true
|
|
459
631
|
fi
|
|
460
632
|
|
|
@@ -558,11 +730,12 @@ fi
|
|
|
558
730
|
|
|
559
731
|
if [ -n "$local_settings_file" ] && [ -f "$local_settings_file" ]; then
|
|
560
732
|
# ANTHROPIC_BASE_URL only lives here when a project install was toggled off
|
|
561
|
-
# (the off path overrides it to Anthropic in the local file)
|
|
562
|
-
#
|
|
733
|
+
# (the off path overrides it to Anthropic in the local file). Project installs
|
|
734
|
+
# also keep WEAVE_ROUTER_BASE_URL here as a private endpoint marker beside the
|
|
735
|
+
# router key; scrub both so uninstall fully reverts the local config.
|
|
563
736
|
cleaned="$(jq '
|
|
564
737
|
if .env then
|
|
565
|
-
.env |= (del(.ANTHROPIC_BASE_URL, .ANTHROPIC_AUTH_TOKEN, .ANTHROPIC_CUSTOM_HEADERS, .ENABLE_TOOL_SEARCH))
|
|
738
|
+
.env |= (del(.ANTHROPIC_BASE_URL, .ANTHROPIC_AUTH_TOKEN, .ANTHROPIC_CUSTOM_HEADERS, .ENABLE_TOOL_SEARCH, .WEAVE_ROUTER_BASE_URL))
|
|
566
739
|
| (if (.env | length) == 0 then del(.env) else . end)
|
|
567
740
|
else . end
|
|
568
741
|
| del(.apiKeyHelper)
|
|
@@ -592,14 +765,20 @@ done
|
|
|
592
765
|
commands_dir="$(dirname "$settings_file")/commands"
|
|
593
766
|
if [ -d "$commands_dir" ]; then
|
|
594
767
|
refuse_if_symlink "$commands_dir"
|
|
595
|
-
|
|
768
|
+
while IFS= read -r cmd; do
|
|
596
769
|
cmd_file="$commands_dir/$cmd.md"
|
|
597
770
|
if [ -f "$cmd_file" ]; then
|
|
598
771
|
refuse_if_symlink "$cmd_file"
|
|
599
|
-
|
|
600
|
-
|
|
772
|
+
if grep -Fq "<!-- weave-router managed command: $cmd -->" "$cmd_file"; then
|
|
773
|
+
rm -f "$cmd_file"
|
|
774
|
+
ok "Removed $cmd_file"
|
|
775
|
+
else
|
|
776
|
+
warn "Leaving user-owned Claude command at $cmd_file untouched."
|
|
777
|
+
fi
|
|
601
778
|
fi
|
|
602
|
-
done
|
|
779
|
+
done <<EOF
|
|
780
|
+
$(weave_registry_names claude)
|
|
781
|
+
EOF
|
|
603
782
|
# Clean up the dir only if we left nothing behind.
|
|
604
783
|
rmdir "$commands_dir" 2>/dev/null || true
|
|
605
784
|
fi
|