pi-rolecast 0.2.1 → 0.2.2
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/package.json +1 -1
- package/scripts/install.sh +5 -18
- package/scripts/sync_settings.py +1 -20
- package/scripts/uninstall.sh +150 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-rolecast",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Multi-agent role framework for Pi. Groups of specialist agents (coding, video, etc.) bound to per-role models, dispatched via pi-subagents. Profile-driven, gate-verified, language-agnostic.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
package/scripts/install.sh
CHANGED
|
@@ -31,11 +31,9 @@ if [[ -n "$DRY_RUN" ]]; then
|
|
|
31
31
|
fi
|
|
32
32
|
mkdir -p "$PREFIX"
|
|
33
33
|
|
|
34
|
-
#
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
echo "linked $PREFIX/pi-rolecast to $FRAMEWORK_ROOT"
|
|
38
|
-
fi
|
|
34
|
+
# Remove legacy pi-agent-workflow framework symlink if it exists.
|
|
35
|
+
# v0.2.3: no longer creates ~/.pi/agent/pi-rolecast symlink — npm install
|
|
36
|
+
# path (~/.pi/agent/npm/node_modules/pi-rolecast) is canonical.
|
|
39
37
|
if [[ -e "$PREFIX/pi-agent-workflow" ]]; then
|
|
40
38
|
echo "removing legacy $PREFIX/pi-agent-workflow symlink"
|
|
41
39
|
rm -f "$PREFIX/pi-agent-workflow"
|
|
@@ -70,26 +68,15 @@ if [[ -d "$agents_dir" ]]; then
|
|
|
70
68
|
fi
|
|
71
69
|
linked=0
|
|
72
70
|
while IFS= read -r md; do
|
|
73
|
-
role=$(basename "$md" .md) # e.g. "coding-architect"
|
|
74
|
-
bare="${role#coding-}" # legacy compat name e.g. "architect" (for coding group)
|
|
71
|
+
role=$(basename "$md" .md) # e.g. "coding-architect" (full prefixed name)
|
|
75
72
|
link_path="$agents_dir/$role.md"
|
|
76
73
|
if [[ -L "$link_path" ]]; then
|
|
77
74
|
rm -f "$link_path"
|
|
78
75
|
fi
|
|
79
76
|
ln -s "$md" "$link_path"
|
|
80
77
|
linked=$((linked + 1))
|
|
81
|
-
# Legacy shim: create <bare-role>.md symlink for extensions that key
|
|
82
|
-
# off filename (e.g. bundled pi-cc-extensions). Removed in v0.3.0.
|
|
83
|
-
if [[ "$role" == "$bare" ]]; then
|
|
84
|
-
continue # safety: if role had no group prefix, skip
|
|
85
|
-
fi
|
|
86
|
-
legacy_link="$agents_dir/$bare.md"
|
|
87
|
-
if [[ ! -L "$legacy_link" && ! -e "$legacy_link" ]]; then
|
|
88
|
-
ln -s "$md" "$legacy_link"
|
|
89
|
-
linked=$((linked + 1))
|
|
90
|
-
fi
|
|
91
78
|
done < <(find "$FRAMEWORK_ROOT/role-packs" -type f -name '*.md' 2>/dev/null | sort)
|
|
92
|
-
echo "linked $linked role agents from role-packs/
|
|
79
|
+
echo "linked $linked role agents from role-packs/"
|
|
93
80
|
|
|
94
81
|
# Warn if pi-subagents is missing — required for actual role dispatch.
|
|
95
82
|
SETTINGS_JSON="$PREFIX/settings.json"
|
package/scripts/sync_settings.py
CHANGED
|
@@ -253,11 +253,6 @@ def _write_agents(agents_dir: Path, framework_root: Path,
|
|
|
253
253
|
"""Write project-local copies of role-packs/<group>/<role>.md for every
|
|
254
254
|
bound role. Uses full role name (`<group>-<role>`) as the filename so
|
|
255
255
|
pi-subagents can find it via @<full-name> mention syntax.
|
|
256
|
-
|
|
257
|
-
Also writes a legacy `<bare-role>.md` shim for extensions that key off
|
|
258
|
-
filename (e.g. the bundled pi-cc-extensions subagent reference provider).
|
|
259
|
-
Both files contain the same body, just different filenames. The legacy
|
|
260
|
-
shim is removed in v0.3.0.
|
|
261
256
|
"""
|
|
262
257
|
roles = available_roles(framework_root, groups=enabled_groups or None)
|
|
263
258
|
if dry_run:
|
|
@@ -269,10 +264,6 @@ def _write_agents(agents_dir: Path, framework_root: Path,
|
|
|
269
264
|
full = (provider + "/" + model_id) if provider else model_id
|
|
270
265
|
print("would write " + str(agents_dir / (role_full_name + ".md")) +
|
|
271
266
|
" model=" + full)
|
|
272
|
-
legacy = rd.role
|
|
273
|
-
if legacy and legacy != role_full_name:
|
|
274
|
-
print("would write " + str(agents_dir / (legacy + ".md")) +
|
|
275
|
-
" model=" + full + " (legacy shim)")
|
|
276
267
|
return 0
|
|
277
268
|
agents_dir.mkdir(parents=True, exist_ok=True)
|
|
278
269
|
written = 0
|
|
@@ -293,17 +284,7 @@ def _write_agents(agents_dir: Path, framework_root: Path,
|
|
|
293
284
|
dst = agents_dir / (role_full_name + ".md")
|
|
294
285
|
dst.write_text(updated)
|
|
295
286
|
written += 1
|
|
296
|
-
|
|
297
|
-
# Only created for the coding group; other groups have no legacy.
|
|
298
|
-
legacy = rd.role
|
|
299
|
-
if legacy and legacy != role_full_name and rd.group == "coding":
|
|
300
|
-
legacy_dst = agents_dir / (legacy + ".md")
|
|
301
|
-
if legacy_dst.exists() or legacy_dst.is_symlink():
|
|
302
|
-
legacy_dst.unlink()
|
|
303
|
-
legacy_dst.write_text(updated)
|
|
304
|
-
written += 1
|
|
305
|
-
print("wrote " + str(written) + " project-local agent files to " + str(agents_dir) +
|
|
306
|
-
" (incl. legacy compat shims)")
|
|
287
|
+
print("wrote " + str(written) + " project-local agent files to " + str(agents_dir))
|
|
307
288
|
return 0
|
|
308
289
|
|
|
309
290
|
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# pi-rolecast uninstaller. Removes all framework artifacts created by
|
|
3
|
+
# install.sh and sync_settings.py. Safe to run multiple times (idempotent).
|
|
4
|
+
#
|
|
5
|
+
# Removes:
|
|
6
|
+
# - ~/.pi/agent/pi-rolecast framework symlink
|
|
7
|
+
# - ~/.pi/agent/agents/*.md symlinks whose target is inside a pi-rolecast
|
|
8
|
+
# framework
|
|
9
|
+
# - .pi/agents/<framework-role>.md files matching framework role names
|
|
10
|
+
# (in cwd)
|
|
11
|
+
# - subagents.agentOverrides entries for framework roles in settings.json
|
|
12
|
+
# - empty agent directories if nothing else remains
|
|
13
|
+
#
|
|
14
|
+
# Does NOT remove:
|
|
15
|
+
# - ~/.pi/agent/npm/node_modules/pi-rolecast/ (run `pi uninstall npm:pi-rolecast` first)
|
|
16
|
+
# - user-created agent files in .pi/agents/ (e.g. custom-role.md)
|
|
17
|
+
# - user-created symlinks in ~/.pi/agent/agents/ (e.g. targeting other frameworks)
|
|
18
|
+
# - settings.json entries for non-framework roles
|
|
19
|
+
set -euo pipefail
|
|
20
|
+
|
|
21
|
+
PREFIX="${HOME}/.pi/agent"
|
|
22
|
+
DRY_RUN=""
|
|
23
|
+
KEEP_PROJECT_AGENTS=""
|
|
24
|
+
SETTINGS_JSON=""
|
|
25
|
+
GLOBAL_AGENTS_DIR=""
|
|
26
|
+
PROJECT_AGENTS_DIR=""
|
|
27
|
+
FRAMEWORK_ROOT=""
|
|
28
|
+
|
|
29
|
+
while [[ $# -gt 0 ]]; do
|
|
30
|
+
case "$1" in
|
|
31
|
+
--prefix) PREFIX="$2"; shift 2 ;;
|
|
32
|
+
--framework-root) FRAMEWORK_ROOT="$2"; shift 2 ;;
|
|
33
|
+
--dry-run) DRY_RUN="1"; shift ;;
|
|
34
|
+
--settings) SETTINGS_JSON="$2"; shift 2 ;;
|
|
35
|
+
--global-agents-dir) GLOBAL_AGENTS_DIR="$2"; shift 2 ;;
|
|
36
|
+
--project-agents-dir) PROJECT_AGENTS_DIR="$2"; shift 2 ;;
|
|
37
|
+
--keep-project-agents) KEEP_PROJECT_AGENTS="1"; shift ;;
|
|
38
|
+
*) echo "unknown argument: $1" >&2; exit 1 ;;
|
|
39
|
+
esac
|
|
40
|
+
done
|
|
41
|
+
|
|
42
|
+
[[ -z "$SETTINGS_JSON" ]] && SETTINGS_JSON="$PREFIX/settings.json"
|
|
43
|
+
[[ -z "$GLOBAL_AGENTS_DIR" ]] && GLOBAL_AGENTS_DIR="$PREFIX/agents"
|
|
44
|
+
[[ -z "$PROJECT_AGENTS_DIR" ]] && PROJECT_AGENTS_DIR="$(pwd)/.pi/agents"
|
|
45
|
+
|
|
46
|
+
# Find framework root to enumerate framework role names. Without this we
|
|
47
|
+
# cannot tell framework-written project-local files from user customizations.
|
|
48
|
+
if [[ -z "$FRAMEWORK_ROOT" ]]; then
|
|
49
|
+
if [[ -d "./role-packs" ]]; then
|
|
50
|
+
FRAMEWORK_ROOT="$(cd . && pwd)"
|
|
51
|
+
elif [[ -d "$PREFIX/npm/node_modules/pi-rolecast/role-packs" ]]; then
|
|
52
|
+
FRAMEWORK_ROOT="$PREFIX/npm/node_modules/pi-rolecast"
|
|
53
|
+
fi
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
framework_roles=()
|
|
57
|
+
if [[ -n "$FRAMEWORK_ROOT" ]]; then
|
|
58
|
+
while IFS= read -r role; do
|
|
59
|
+
framework_roles+=("$role")
|
|
60
|
+
done < <(find "$FRAMEWORK_ROOT/role-packs" -type f -name '*.md' \
|
|
61
|
+
-exec basename {} .md \; 2>/dev/null | sort -u)
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
removed=0
|
|
65
|
+
_action() {
|
|
66
|
+
# $1 = action (rm), $2 = path, $3 = reason
|
|
67
|
+
if [[ -n "$DRY_RUN" ]]; then
|
|
68
|
+
echo "would $1 $2 ($3)"
|
|
69
|
+
else
|
|
70
|
+
if "$1" "$2" 2>/dev/null; then
|
|
71
|
+
echo "$1 $2 ($3)"
|
|
72
|
+
removed=$((removed + 1))
|
|
73
|
+
fi
|
|
74
|
+
fi
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
# 1. Framework symlink ~/.pi/agent/pi-rolecast
|
|
78
|
+
link="$PREFIX/pi-rolecast"
|
|
79
|
+
if [[ -L "$link" ]]; then
|
|
80
|
+
target="$(readlink "$link")"
|
|
81
|
+
case "$target" in
|
|
82
|
+
*pi-rolecast*) _action rm "$link" "framework symlink" ;;
|
|
83
|
+
esac
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
# 2. Global agent symlinks ~/.pi/agent/agents/*.md
|
|
87
|
+
# Only remove symlinks whose target is inside a pi-rolecast framework.
|
|
88
|
+
if [[ -d "$GLOBAL_AGENTS_DIR" ]]; then
|
|
89
|
+
while IFS= read -r l; do
|
|
90
|
+
target="$(readlink "$l")"
|
|
91
|
+
case "$target" in
|
|
92
|
+
*pi-rolecast*) _action rm "$l" "global agent symlink" ;;
|
|
93
|
+
esac
|
|
94
|
+
done < <(find "$GLOBAL_AGENTS_DIR" -maxdepth 1 -type l -name '*.md' 2>/dev/null)
|
|
95
|
+
fi
|
|
96
|
+
|
|
97
|
+
# 3. Project-local agent files .pi/agents/<role>.md
|
|
98
|
+
# Only remove files matching framework role names. Skip symlinks (user-created).
|
|
99
|
+
if [[ -z "$KEEP_PROJECT_AGENTS" && -d "$PROJECT_AGENTS_DIR" && ${#framework_roles[@]} -gt 0 ]]; then
|
|
100
|
+
for role in "${framework_roles[@]}"; do
|
|
101
|
+
f="$PROJECT_AGENTS_DIR/$role.md"
|
|
102
|
+
[[ -e "$f" || -L "$f" ]] || continue
|
|
103
|
+
[[ -L "$f" ]] && continue
|
|
104
|
+
_action rm "$f" "project-local agent file"
|
|
105
|
+
done
|
|
106
|
+
elif [[ -z "$KEEP_PROJECT_AGENTS" && -d "$PROJECT_AGENTS_DIR" ]]; then
|
|
107
|
+
echo "warning: framework root not found, skipping project-local agent cleanup" >&2
|
|
108
|
+
echo " hint: cd into a project with .pi/rolecast.yaml, or run from pi-rolecast repo" >&2
|
|
109
|
+
fi
|
|
110
|
+
|
|
111
|
+
# 4. Clean settings.json subagents.agentOverrides for framework roles
|
|
112
|
+
if [[ -f "$SETTINGS_JSON" && ${#framework_roles[@]} -gt 0 ]]; then
|
|
113
|
+
python3 - "$SETTINGS_JSON" "${framework_roles[@]}" <<'PYEOF'
|
|
114
|
+
import json, sys
|
|
115
|
+
path = sys.argv[1]
|
|
116
|
+
roles = set(sys.argv[2:])
|
|
117
|
+
try:
|
|
118
|
+
with open(path) as f:
|
|
119
|
+
s = json.load(f)
|
|
120
|
+
except (FileNotFoundError, json.JSONDecodeError):
|
|
121
|
+
sys.exit(0)
|
|
122
|
+
sub = s.setdefault("subagents", {})
|
|
123
|
+
ov = sub.get("agentOverrides", {}) or {}
|
|
124
|
+
cleared = [k for k in list(ov) if k in roles]
|
|
125
|
+
for k in cleared:
|
|
126
|
+
del ov[k]
|
|
127
|
+
sub["agentOverrides"] = ov
|
|
128
|
+
s["subagents"] = sub
|
|
129
|
+
with open(path, "w") as f:
|
|
130
|
+
json.dump(s, f, indent=2, sort_keys=True)
|
|
131
|
+
f.write("\n")
|
|
132
|
+
print(f"removed {len(cleared)} framework overrides from {path}")
|
|
133
|
+
PYEOF
|
|
134
|
+
fi
|
|
135
|
+
|
|
136
|
+
# 5. Remove empty agent directories (after all cleanup)
|
|
137
|
+
for d in "$GLOBAL_AGENTS_DIR" "$PROJECT_AGENTS_DIR"; do
|
|
138
|
+
if [[ -d "$d" && -z "$(ls -A "$d" 2>/dev/null)" ]]; then
|
|
139
|
+
if [[ -n "$DRY_RUN" ]]; then
|
|
140
|
+
echo "would remove empty dir $d"
|
|
141
|
+
else
|
|
142
|
+
if rmdir "$d" 2>/dev/null; then
|
|
143
|
+
echo "rmdir $d (empty dir)"
|
|
144
|
+
removed=$((removed + 1))
|
|
145
|
+
fi
|
|
146
|
+
fi
|
|
147
|
+
fi
|
|
148
|
+
done
|
|
149
|
+
|
|
150
|
+
echo "uninstall complete: removed $removed items"
|