pi-soly 0.5.10 → 0.7.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/agents/soly-manager.md +124 -0
- package/agents-install.ts +113 -36
- package/commands.ts +1 -1
- package/config.ts +5 -4
- package/index.ts +15 -14
- package/package.json +2 -1
- package/skills/soly-framework/SKILL.md +320 -0
- package/switch/README.md +21 -24
- package/switch/core.ts +4 -11
- package/switch/index.ts +2 -2
- package/switch/prompt.ts +24 -27
- package/switch/tests/core.test.ts +1 -1
- package/switch/tests/index.test.ts +3 -2
- package/switch/tests/prompt.test.ts +26 -24
- package/agents/soly-debugger.md +0 -60
- package/agents/soly-documenter.md +0 -82
- package/agents/soly-oracle.md +0 -69
- package/agents/soly-refactor.md +0 -65
- package/agents/soly-reviewer.md +0 -107
- package/agents/soly-tester.md +0 -56
- package/agents/soly-worker.md +0 -84
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: soly-manager
|
|
3
|
+
description: Soly workflow executor. Handles any soly task end-to-end — plan, execute, debug, test, review, refactor, document. Reads the workflow brief passed by the parent and picks the right role for the task. The single writer/reviewer for soly projects.
|
|
4
|
+
thinking: high
|
|
5
|
+
systemPromptMode: replace
|
|
6
|
+
inheritProjectContext: true
|
|
7
|
+
inheritSkills: false
|
|
8
|
+
tools: read, grep, find, ls, bash, edit, write
|
|
9
|
+
defaultContext: fork
|
|
10
|
+
defaultReads: context.md, plan.md
|
|
11
|
+
defaultProgress: true
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
You are `soly-manager`: the workflow executor for the **soly** project-management extension.
|
|
15
|
+
|
|
16
|
+
The parent agent passes you a task with one of these roles. **Pick the right one based on the task brief, not on your name:**
|
|
17
|
+
|
|
18
|
+
| Task brief mentions | You are in mode | Your job |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| implement, build, write code, add feature, create | **worker** | Write the code, run verification, commit |
|
|
21
|
+
| debug, bug, fix, crash, error, repro, broken | **debugger** | Repro → isolate → fix → regression test |
|
|
22
|
+
| test, coverage, spec, assert, only modify tests | **tester** | Write tests, run full suite, never touch prod |
|
|
23
|
+
| review, audit, adversarial, find bugs, qa | **reviewer** | Read-only review with file:line evidence |
|
|
24
|
+
| refactor, simplify, extract, rename, no behavior change | **refactor** | Behavior-preserving structural change |
|
|
25
|
+
| document, readme, jsdoc, comment, intent doc | **documenter** | Update docs, never change product behavior |
|
|
26
|
+
| validate, scope, drift, decision, before committing | **oracle** | Read-only consistency check, no edits |
|
|
27
|
+
| plan, design, outline, structure, decompose | **planner** | Ordered steps with risks; not code |
|
|
28
|
+
|
|
29
|
+
**You are one agent that switches modes. You are not seven agents.** The system prompt above is your only persona — the task brief tells you which hat to wear.
|
|
30
|
+
|
|
31
|
+
## Soly-aware defaults (apply in every mode)
|
|
32
|
+
|
|
33
|
+
**Path discipline — NON-NEGOTIABLE.** All soly-managed files live under `.soly/`:
|
|
34
|
+
- `PLAN.md`, `CONTEXT.md`, `RESEARCH.md`, `SUMMARY.md` → `.soly/phases/<NN>-<slug>/`
|
|
35
|
+
- iteration files → `.soly/iterations/`
|
|
36
|
+
- handoffs → `.soly/HANDOFF.json`, `.soly/.continue-here.md`
|
|
37
|
+
- rules → `.soly/rules/` (NEVER edit — version-controlled)
|
|
38
|
+
- All other files (source code, tests) → normal project dirs
|
|
39
|
+
|
|
40
|
+
**Close-out order** (when working a plan): production-code commit(s) → SUMMARY commit → `STATUS: done` update.
|
|
41
|
+
Once production commits exist, returning without a committed SUMMARY is an **illegal partial-plan state**.
|
|
42
|
+
|
|
43
|
+
**Frontmatter contract** for `PLAN.md`: `id`, `title`, `status: pending|in_progress|done`, `phase`, `depends-on`, `parallelizable`. Read frontmatter first.
|
|
44
|
+
|
|
45
|
+
**pi-todo integration** (auto-tracks plan sub-tasks if `todo_update` tool is available):
|
|
46
|
+
1. At task start: call `todo_update` with all `status: "pending"`
|
|
47
|
+
2. Set first to `in_progress` before starting
|
|
48
|
+
3. Update as you go: `pending` → `in_progress` → `completed`
|
|
49
|
+
4. Clear list (`todo_update({todos: []})`) after SUMMARY committed
|
|
50
|
+
Skip silently if `todo_update` is not available.
|
|
51
|
+
|
|
52
|
+
## Read first (soly-aware order)
|
|
53
|
+
|
|
54
|
+
1. `.soly/STATE.md` — milestone, current position, recent decisions
|
|
55
|
+
2. `.soly/ROADMAP.md` — overall phase plan
|
|
56
|
+
3. The target `PLAN.md` (the contract) if a plan is in scope
|
|
57
|
+
4. `<phase>-CONTEXT.md` if it exists (honor user decisions)
|
|
58
|
+
5. `<phase>-RESEARCH.md` if it exists (use chosen libs/patterns)
|
|
59
|
+
|
|
60
|
+
**Iteration context file** (if the parent references one) is a pre-aggregated bundle. If given, read that INSTEAD of the individual files.
|
|
61
|
+
|
|
62
|
+
## Mode-specific discipline
|
|
63
|
+
|
|
64
|
+
These are the few hard rules per mode. Follow them or fail loudly.
|
|
65
|
+
|
|
66
|
+
### As worker (implement)
|
|
67
|
+
- Atomic edits only — no speculative scaffolding, no TODO comments
|
|
68
|
+
- Per task: read `<read_first>` → minimal correct change → verify `<acceptance_criteria>` (HARD GATE; log deviation after 2 failed fix attempts) → run `<verification>` → commit with `<type>(${PHASE}-${PLAN}): <summary>`
|
|
69
|
+
- Do NOT edit `.soly/rules/`
|
|
70
|
+
|
|
71
|
+
### As debugger (fix)
|
|
72
|
+
- **Reproduce first.** No fix without a repro. If the user gave a stack trace, build a minimal test that triggers it. If they said "X is broken", find one test case that demonstrates it.
|
|
73
|
+
- **Isolate.** Git blame, grep, bisect. State the root cause in one sentence before fixing.
|
|
74
|
+
- **Fix the cause, not the symptom.** Extra null checks, swallowed errors, type casts mask the bug.
|
|
75
|
+
- **Regression test.** If a test would have caught this, write it. Run the full suite.
|
|
76
|
+
|
|
77
|
+
### As tester
|
|
78
|
+
- **Hard rule:** you can edit `*.test.*`, `*.spec.*`, `tests/`, `__tests__/`, `test/`. You CANNOT edit anything else. If a test fails because of a prod bug, STOP and report — don't "fix" the prod code.
|
|
79
|
+
- Match the project's existing test style. Don't introduce a new style.
|
|
80
|
+
- Test behavior, not implementation. Black-box > white-box.
|
|
81
|
+
|
|
82
|
+
### As reviewer (adversarial)
|
|
83
|
+
- **Read-only.** Do NOT edit files. Do NOT fix bugs. Do NOT commit. You produce a review with file:line evidence; the parent decides what to do.
|
|
84
|
+
- Read spec → read test → read impl → diff them. Where do they disagree?
|
|
85
|
+
- Pick 3-4 relevant review angles (correctness, security, performance, maintainability, soly-style).
|
|
86
|
+
- Specific over vague: "Line 47: SQL injection. Use parameterized query." not "the code is buggy".
|
|
87
|
+
|
|
88
|
+
### As refactor
|
|
89
|
+
- **Behavior preservation is the entire point.** If a test starts failing, you've changed behavior — that's a bug, not a refactor.
|
|
90
|
+
- Smallest possible diff. Run tests after EVERY change.
|
|
91
|
+
- Don't refactor AND fix a bug. Two concerns = unreviewable.
|
|
92
|
+
- If you find a bug, stop, log it, finish the refactor without touching it.
|
|
93
|
+
|
|
94
|
+
### As documenter
|
|
95
|
+
- **You do NOT change product code.** You write READMEs, JSDoc, `.soly/docs/`, ADRs.
|
|
96
|
+
- Update, don't append. If the README has an "Architecture" section, edit in place.
|
|
97
|
+
- Link, don't repeat. 5 lines + a link > 50 lines of pasted explanation.
|
|
98
|
+
- Don't add marketing fluff ("this powerful, elegant framework...").
|
|
99
|
+
|
|
100
|
+
### As oracle (validate)
|
|
101
|
+
- **Read-only.** No edits, no code, no new workflow trees.
|
|
102
|
+
- Check: drift, hidden assumptions, scope creep, missing prerequisites, repeated mistakes, unresolved `depends-on`.
|
|
103
|
+
- Sometimes the answer is "this shouldn't be a soly plan at all" — say so.
|
|
104
|
+
- Output: inherited decisions → drift check → hidden assumptions → missing prereqs → scope check → recommendation → confidence.
|
|
105
|
+
|
|
106
|
+
### As planner
|
|
107
|
+
- Output ordered steps with explicit risks. No code. No "let me also...".
|
|
108
|
+
- Each step: description, depends-on, verification (test or command), acceptance criteria.
|
|
109
|
+
- If the parent asks for a plan, give a plan. Don't drift into implementation.
|
|
110
|
+
|
|
111
|
+
## Returning
|
|
112
|
+
|
|
113
|
+
Your final response should follow this shape:
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
Mode: <worker | debugger | tester | reviewer | refactor | documenter | oracle | planner>
|
|
117
|
+
Did: <one-sentence summary of what you did or found>
|
|
118
|
+
Changed files: <list, or "none" for read-only modes>
|
|
119
|
+
Validation: <test/typecheck/build output, or "n/a" for read-only modes>
|
|
120
|
+
Open risks / decisions needing approval: <list, or "none">
|
|
121
|
+
Recommended next step: <one line>
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Be concise. The parent synthesizes, not you.
|
package/agents-install.ts
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
// =============================================================================
|
|
2
|
-
//
|
|
2
|
+
// assets-install.ts — Idempotent install of soly-managed user assets
|
|
3
3
|
// =============================================================================
|
|
4
4
|
//
|
|
5
|
-
// Soly ships
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
5
|
+
// Soly ships two kinds of user-scope assets:
|
|
6
|
+
//
|
|
7
|
+
// 1. Subagent configs → `~/.pi/agent/agents/`
|
|
8
|
+
// The single `soly-manager` subagent (mode-switching executor).
|
|
9
|
+
//
|
|
10
|
+
// 2. Skills → `~/.pi/agent/skills/<name>/`
|
|
11
|
+
// The `soly-framework` skill — framework documentation the LLM
|
|
12
|
+
// loads on demand via the read tool.
|
|
13
|
+
//
|
|
14
|
+
// pi discovers both from `~/.pi/agent/`, so on first session_start we
|
|
15
|
+
// copy our shipped files there.
|
|
10
16
|
//
|
|
11
17
|
// IDEMPOTENT: if the target file already exists (user may have customized
|
|
12
18
|
// it), we do NOT overwrite. This is one-way "first install wins".
|
|
@@ -18,43 +24,76 @@ import * as path from "node:path";
|
|
|
18
24
|
|
|
19
25
|
/** soly agent files bundled with the extension. */
|
|
20
26
|
const SHIPPED_AGENTS = [
|
|
21
|
-
"soly-
|
|
22
|
-
"soly-debugger.md",
|
|
23
|
-
"soly-tester.md",
|
|
24
|
-
"soly-refactor.md",
|
|
25
|
-
"soly-oracle.md",
|
|
26
|
-
"soly-reviewer.md",
|
|
27
|
-
"soly-documenter.md",
|
|
27
|
+
"soly-manager.md",
|
|
28
28
|
] as const;
|
|
29
29
|
|
|
30
|
-
/**
|
|
31
|
-
*
|
|
30
|
+
/** soly skills bundled with the extension. Each entry is a directory
|
|
31
|
+
* under `skills/` containing a SKILL.md. */
|
|
32
|
+
const SHIPPED_SKILLS = [
|
|
33
|
+
"soly-framework",
|
|
34
|
+
] as const;
|
|
35
|
+
|
|
36
|
+
/** Where pi looks for user agents. Respects HOME/USERPROFILE for
|
|
37
|
+
* testability (otherwise we'd always write to the real user home). */
|
|
32
38
|
function userAgentsDir(): string {
|
|
33
39
|
const home = process.env.HOME || process.env.USERPROFILE || os.homedir();
|
|
34
40
|
return path.join(home, ".pi", "agent", "agents");
|
|
35
41
|
}
|
|
36
42
|
|
|
43
|
+
/** Where pi looks for user skills. */
|
|
44
|
+
function userSkillsDir(): string {
|
|
45
|
+
const home = process.env.HOME || process.env.USERPROFILE || os.homedir();
|
|
46
|
+
return path.join(home, ".pi", "agent", "skills");
|
|
47
|
+
}
|
|
48
|
+
|
|
37
49
|
/** Where this soly extension's `agents/` directory lives. */
|
|
38
|
-
function
|
|
50
|
+
function shippedAgentsDir(extensionRoot: string): string {
|
|
39
51
|
return path.join(extensionRoot, "agents");
|
|
40
52
|
}
|
|
41
53
|
|
|
54
|
+
/** Where this soly extension's `skills/` directory lives. */
|
|
55
|
+
function shippedSkillsDir(extensionRoot: string): string {
|
|
56
|
+
return path.join(extensionRoot, "skills");
|
|
57
|
+
}
|
|
58
|
+
|
|
42
59
|
export interface InstallResult {
|
|
43
60
|
installed: string[];
|
|
44
61
|
skipped: string[];
|
|
45
62
|
errors: string[];
|
|
46
63
|
}
|
|
47
64
|
|
|
65
|
+
/** Copy a single file if destination doesn't exist. Idempotent. */
|
|
66
|
+
function copyIfMissing(from: string, to: string): "installed" | "skipped" | "error" {
|
|
67
|
+
if (!fs.existsSync(from)) return "error";
|
|
68
|
+
if (fs.existsSync(to)) return "skipped";
|
|
69
|
+
try {
|
|
70
|
+
fs.copyFileSync(from, to);
|
|
71
|
+
return "installed";
|
|
72
|
+
} catch {
|
|
73
|
+
return "error";
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Recursively copy a directory tree if destination doesn't exist. Idempotent. */
|
|
78
|
+
function copyDirIfMissing(from: string, to: string): "installed" | "skipped" | "error" {
|
|
79
|
+
if (!fs.existsSync(from)) return "error";
|
|
80
|
+
if (fs.existsSync(to)) return "skipped";
|
|
81
|
+
try {
|
|
82
|
+
fs.mkdirSync(path.dirname(to), { recursive: true });
|
|
83
|
+
fs.cpSync(from, to, { recursive: true });
|
|
84
|
+
return "installed";
|
|
85
|
+
} catch {
|
|
86
|
+
return "error";
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
48
90
|
/** Install shipped soly agents to `~/.pi/agent/agents/`. Idempotent. */
|
|
49
91
|
export function installSolyAgents(extensionRoot: string): InstallResult {
|
|
50
92
|
const result: InstallResult = { installed: [], skipped: [], errors: [] };
|
|
51
|
-
const src =
|
|
93
|
+
const src = shippedAgentsDir(extensionRoot);
|
|
52
94
|
const dst = userAgentsDir();
|
|
53
95
|
|
|
54
|
-
if (!fs.existsSync(src))
|
|
55
|
-
// Development mode or partial install — silently no-op
|
|
56
|
-
return result;
|
|
57
|
-
}
|
|
96
|
+
if (!fs.existsSync(src)) return result; // dev mode no-op
|
|
58
97
|
|
|
59
98
|
try {
|
|
60
99
|
fs.mkdirSync(dst, { recursive: true });
|
|
@@ -66,26 +105,46 @@ export function installSolyAgents(extensionRoot: string): InstallResult {
|
|
|
66
105
|
for (const name of SHIPPED_AGENTS) {
|
|
67
106
|
const from = path.join(src, name);
|
|
68
107
|
const to = path.join(dst, name);
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
if (fs.existsSync(to)) {
|
|
74
|
-
// User already has this file (possibly customized) — respect it
|
|
75
|
-
result.skipped.push(name);
|
|
76
|
-
continue;
|
|
77
|
-
}
|
|
78
|
-
try {
|
|
79
|
-
fs.copyFileSync(from, to);
|
|
80
|
-
result.installed.push(name);
|
|
81
|
-
} catch (err) {
|
|
82
|
-
result.errors.push(`copy ${name}: ${(err as Error).message}`);
|
|
83
|
-
}
|
|
108
|
+
const r = copyIfMissing(from, to);
|
|
109
|
+
if (r === "installed") result.installed.push(name);
|
|
110
|
+
else if (r === "skipped") result.skipped.push(name);
|
|
111
|
+
else result.errors.push(`missing source: ${from}`);
|
|
84
112
|
}
|
|
85
113
|
|
|
86
114
|
return result;
|
|
87
115
|
}
|
|
88
116
|
|
|
117
|
+
/** Install shipped soly skills to `~/.pi/agent/skills/`. Idempotent. */
|
|
118
|
+
export function installSolySkills(extensionRoot: string): InstallResult {
|
|
119
|
+
const result: InstallResult = { installed: [], skipped: [], errors: [] };
|
|
120
|
+
const src = shippedSkillsDir(extensionRoot);
|
|
121
|
+
const dst = userSkillsDir();
|
|
122
|
+
|
|
123
|
+
if (!fs.existsSync(src)) return result; // dev mode no-op
|
|
124
|
+
|
|
125
|
+
for (const name of SHIPPED_SKILLS) {
|
|
126
|
+
const from = path.join(src, name);
|
|
127
|
+
const to = path.join(dst, name);
|
|
128
|
+
const r = copyDirIfMissing(from, to);
|
|
129
|
+
if (r === "installed") result.installed.push(name);
|
|
130
|
+
else if (r === "skipped") result.skipped.push(name);
|
|
131
|
+
else result.errors.push(`missing source: ${from}`);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return result;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** Install all soly assets (agents + skills). Combined for convenience. */
|
|
138
|
+
export function installSolyAssets(extensionRoot: string): {
|
|
139
|
+
agents: InstallResult;
|
|
140
|
+
skills: InstallResult;
|
|
141
|
+
} {
|
|
142
|
+
return {
|
|
143
|
+
agents: installSolyAgents(extensionRoot),
|
|
144
|
+
skills: installSolySkills(extensionRoot),
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
89
148
|
/** Check which shipped soly agents are present in the user dir. Used by doctor. */
|
|
90
149
|
export function checkSolyAgentsInstalled(extensionRoot: string): {
|
|
91
150
|
installed: string[];
|
|
@@ -103,3 +162,21 @@ export function checkSolyAgentsInstalled(extensionRoot: string): {
|
|
|
103
162
|
}
|
|
104
163
|
return { installed, missing };
|
|
105
164
|
}
|
|
165
|
+
|
|
166
|
+
/** Check which shipped soly skills are present in the user dir. */
|
|
167
|
+
export function checkSolySkillsInstalled(extensionRoot: string): {
|
|
168
|
+
installed: string[];
|
|
169
|
+
missing: string[];
|
|
170
|
+
} {
|
|
171
|
+
const dst = userSkillsDir();
|
|
172
|
+
const installed: string[] = [];
|
|
173
|
+
const missing: string[] = [];
|
|
174
|
+
for (const name of SHIPPED_SKILLS) {
|
|
175
|
+
if (fs.existsSync(path.join(dst, name, "SKILL.md"))) {
|
|
176
|
+
installed.push(name);
|
|
177
|
+
} else {
|
|
178
|
+
missing.push(name);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return { installed, missing };
|
|
182
|
+
}
|
package/commands.ts
CHANGED
|
@@ -371,7 +371,7 @@ What must the LLM do?
|
|
|
371
371
|
};
|
|
372
372
|
const subcommands: Record<string, SolySub> = {
|
|
373
373
|
// `agent` subcommand REMOVED — moved to the separate `pi-switch`
|
|
374
|
-
// extension as the `/agent` slash command (
|
|
374
|
+
// extension as the `/agent` slash command (footer pill + Ctrl+Tab).
|
|
375
375
|
// Soly no longer owns the agent switcher UI.
|
|
376
376
|
config: {
|
|
377
377
|
description: "show merged config (per-project + global + defaults); edit .soly/config.json or ~/.soly/config.json",
|
package/config.ts
CHANGED
|
@@ -35,10 +35,11 @@ export interface SolyConfig {
|
|
|
35
35
|
preferAskPro: boolean;
|
|
36
36
|
/** When soly pause is invoked, also auto-save HANDOFF.json (currently always true; knob for future). */
|
|
37
37
|
autoCheckpointOnPause: boolean;
|
|
38
|
-
/** Opt-in: install soly-
|
|
39
|
-
* ~/.pi/agent/agents/ on session_start
|
|
40
|
-
*
|
|
41
|
-
*
|
|
38
|
+
/** Opt-in: install soly-manager agent config to
|
|
39
|
+
* ~/.pi/agent/agents/ on session_start. The single soly subagent
|
|
40
|
+
* is mode-switching (worker/debugger/tester/reviewer/etc. based on
|
|
41
|
+
* the task brief). Off by default — most users don't need a soly-
|
|
42
|
+
* specialized subagent since the workflow template already
|
|
42
43
|
* contains soly instructions. */
|
|
43
44
|
useSolyWorkerSubagents: boolean;
|
|
44
45
|
};
|
package/index.ts
CHANGED
|
@@ -45,7 +45,7 @@ import {
|
|
|
45
45
|
type SourceSpec,
|
|
46
46
|
} from "./core.ts";
|
|
47
47
|
import { buildIntegrationsSection } from "./integrations.ts";
|
|
48
|
-
import {
|
|
48
|
+
import { installSolyAssets } from "./agents-install.ts";
|
|
49
49
|
import {
|
|
50
50
|
DEFAULT_CONFIG,
|
|
51
51
|
loadConfig,
|
|
@@ -85,9 +85,9 @@ export default function solyExtension(pi: ExtensionAPI) {
|
|
|
85
85
|
|
|
86
86
|
// ============================================================================
|
|
87
87
|
// Agent switcher: REMOVED. The agent cycler is now owned by the
|
|
88
|
-
// separate `pi-switch` extension (
|
|
89
|
-
// Soly
|
|
90
|
-
//
|
|
88
|
+
// separate `pi-switch` extension (footer pill + Ctrl+Tab + /agent slash).
|
|
89
|
+
// Soly owns a single subagent (soly-manager.md) and the auto-install on
|
|
90
|
+
// opt-in. Workflows read the current agent from
|
|
91
91
|
// globalThis.__PI_SWITCH_AGENT__ (set by pi-switch).
|
|
92
92
|
// ============================================================================
|
|
93
93
|
|
|
@@ -328,7 +328,7 @@ export default function solyExtension(pi: ExtensionAPI) {
|
|
|
328
328
|
// and mnemonic for "A"gent.)
|
|
329
329
|
// ============================================================================
|
|
330
330
|
// Agent switcher REMOVED — moved to the separate `pi-switch` extension.
|
|
331
|
-
// Soly no longer owns Ctrl+
|
|
331
|
+
// Soly no longer owns Ctrl+Tab, the footer pill, or /agent slash.
|
|
332
332
|
// The current agent is read by soly workflows from
|
|
333
333
|
// globalThis.__PI_SWITCH_AGENT__ (set by pi-switch), with a fallback
|
|
334
334
|
// to "worker" if pi-switch isn't installed.
|
|
@@ -388,21 +388,22 @@ export default function solyExtension(pi: ExtensionAPI) {
|
|
|
388
388
|
}
|
|
389
389
|
}
|
|
390
390
|
|
|
391
|
-
// Auto-install soly-
|
|
392
|
-
// to ~/.pi/agent/
|
|
393
|
-
//
|
|
394
|
-
//
|
|
391
|
+
// Auto-install soly user-scope assets (soly-manager agent + soly-framework
|
|
392
|
+
// skill) to ~/.pi/agent/ on first run. Opt-in via config
|
|
393
|
+
// `agent.useSolyWorkerSubagents` (default false). Idempotent — respects
|
|
394
|
+
// any existing user-customized copies.
|
|
395
395
|
if (activeConfig.agent.useSolyWorkerSubagents) {
|
|
396
396
|
const extRoot = path.dirname(new URL(import.meta.url).pathname.replace(/^\/([A-Z]:)/, "$1"));
|
|
397
|
-
const
|
|
398
|
-
|
|
397
|
+
const assets = installSolyAssets(extRoot);
|
|
398
|
+
const installed = [...assets.agents.installed, ...assets.skills.installed.map((s) => `skill:${s}`)];
|
|
399
|
+
if (installed.length > 0) {
|
|
399
400
|
ctx.ui.notify(
|
|
400
|
-
`soly: installed
|
|
401
|
+
`soly: installed (${installed.join(", ")}) — run \`/subagents-doctor\` to verify`,
|
|
401
402
|
"info",
|
|
402
403
|
);
|
|
403
404
|
}
|
|
404
|
-
for (const e of
|
|
405
|
-
ctx.ui.notify(`soly:
|
|
405
|
+
for (const e of [...assets.agents.errors, ...assets.skills.errors]) {
|
|
406
|
+
ctx.ui.notify(`soly: install error — ${e}`, "warning");
|
|
406
407
|
}
|
|
407
408
|
}
|
|
408
409
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-soly",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Project management framework for pi-coding-agent. Workflows, planning, multi-question picker, agent switcher, live task list — one npm install, zero config.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
"agents-install.ts",
|
|
41
41
|
"agents",
|
|
42
42
|
"ask",
|
|
43
|
+
"skills",
|
|
43
44
|
"switch",
|
|
44
45
|
"workflows",
|
|
45
46
|
"workflows-data"
|