@pi-unipi/workflow 0.1.17 → 2.0.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/commands.ts +1 -1
- package/index.ts +15 -7
- package/package.json +2 -2
- package/skills/brainstorm/SKILL.md +20 -6
- package/skills/debug/SKILL.md +4 -2
- package/skills/plan/SKILL.md +36 -13
- package/skills/review-work/SKILL.md +21 -1
- package/skills/work/SKILL.md +22 -1
package/commands.ts
CHANGED
|
@@ -388,7 +388,7 @@ export function registerWorkflowCommands(
|
|
|
388
388
|
// Apply sandbox — save current tools, set command's tools
|
|
389
389
|
const currentTools = options.getActiveTools();
|
|
390
390
|
options.saveTools(currentTools);
|
|
391
|
-
const sandboxTools = getToolsForCommand(cmd.name);
|
|
391
|
+
const sandboxTools = getToolsForCommand(cmd.name, currentTools);
|
|
392
392
|
const sandboxLevel = getSandboxLevel(cmd.name);
|
|
393
393
|
options.setActiveTools([...sandboxTools], sandboxLevel);
|
|
394
394
|
|
package/index.ts
CHANGED
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
getPackageVersion,
|
|
17
17
|
initUnipiDirs,
|
|
18
18
|
type SandboxLevel,
|
|
19
|
-
|
|
19
|
+
getBlockedToolsForLevel,
|
|
20
20
|
} from "@pi-unipi/core";
|
|
21
21
|
import { registerWorkflowCommands } from "./commands.js";
|
|
22
22
|
|
|
@@ -35,6 +35,9 @@ let sandboxActive = false;
|
|
|
35
35
|
/** Current sandbox level (null = no sandbox) */
|
|
36
36
|
let currentSandboxLevel: SandboxLevel | null = null;
|
|
37
37
|
|
|
38
|
+
/** Current active tools after sandbox filtering */
|
|
39
|
+
let currentSandboxTools: string[] | null = null;
|
|
40
|
+
|
|
38
41
|
export default function (pi: ExtensionAPI) {
|
|
39
42
|
// Register skills directory with pi's resource loader
|
|
40
43
|
const skillsDir = new URL("./skills", import.meta.url).pathname;
|
|
@@ -52,6 +55,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
52
55
|
pi.setActiveTools(tools);
|
|
53
56
|
sandboxActive = true;
|
|
54
57
|
currentSandboxLevel = level;
|
|
58
|
+
currentSandboxTools = tools;
|
|
55
59
|
},
|
|
56
60
|
saveTools: (tools: string[]) => {
|
|
57
61
|
savedTools = tools;
|
|
@@ -62,7 +66,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
62
66
|
pi.on("tool_call", async (event, _ctx) => {
|
|
63
67
|
if (!sandboxActive || !currentSandboxLevel) return;
|
|
64
68
|
|
|
65
|
-
const allowed =
|
|
69
|
+
const allowed = currentSandboxTools ?? [];
|
|
66
70
|
if (!allowed.includes(event.toolName)) {
|
|
67
71
|
return {
|
|
68
72
|
block: true,
|
|
@@ -75,11 +79,13 @@ export default function (pi: ExtensionAPI) {
|
|
|
75
79
|
pi.on("before_agent_start", async (event, _ctx) => {
|
|
76
80
|
if (!sandboxActive || !currentSandboxLevel) return;
|
|
77
81
|
|
|
78
|
-
const allowed =
|
|
79
|
-
const blocked =
|
|
80
|
-
.filter((t) => !allowed.includes(t));
|
|
82
|
+
const allowed = currentSandboxTools ?? pi.getActiveTools();
|
|
83
|
+
const blocked = getBlockedToolsForLevel(currentSandboxLevel);
|
|
81
84
|
|
|
82
|
-
const
|
|
85
|
+
const blockedLine = blocked.length > 0
|
|
86
|
+
? `\nBlocked tools: ${blocked.join(", ")} — removed from your tool list.`
|
|
87
|
+
: "\nNo tools were blocked by this sandbox.";
|
|
88
|
+
const base = `\n\n<sandbox>\nSandbox mode: ${currentSandboxLevel}.\nAvailable tools: ${allowed.join(", ")}.${blockedLine}`;
|
|
83
89
|
|
|
84
90
|
if (currentSandboxLevel === "brainstorm") {
|
|
85
91
|
return {
|
|
@@ -114,6 +120,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
114
120
|
savedTools = null;
|
|
115
121
|
sandboxActive = false;
|
|
116
122
|
currentSandboxLevel = null;
|
|
123
|
+
currentSandboxTools = null;
|
|
117
124
|
}
|
|
118
125
|
});
|
|
119
126
|
|
|
@@ -149,7 +156,8 @@ export default function (pi: ExtensionAPI) {
|
|
|
149
156
|
});
|
|
150
157
|
|
|
151
158
|
// Listen for ralph module ready event
|
|
152
|
-
pi.events.on(UNIPI_EVENTS.MODULE_READY, (
|
|
159
|
+
pi.events.on(UNIPI_EVENTS.MODULE_READY, (data) => {
|
|
160
|
+
const event = data as { name?: string };
|
|
153
161
|
if (event?.name === MODULES.RALPH) {
|
|
154
162
|
ralphDetected = true;
|
|
155
163
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/workflow",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "Structured development workflow commands for Pi coding agent",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"access": "public"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@pi-unipi/core": "^0.
|
|
36
|
+
"@pi-unipi/core": "^2.0.0"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"@mariozechner/pi-ai": "*",
|
|
@@ -177,13 +177,27 @@ Wait for user response. If changes requested, make them and re-run self-review.
|
|
|
177
177
|
|
|
178
178
|
## Phase 8: Handoff
|
|
179
179
|
|
|
180
|
-
Ask user what to do next:
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
180
|
+
Ask user what to do next. If `ask_user` is available, prefer structured options so the plan handoff can run automatically:
|
|
181
|
+
|
|
182
|
+
```ts
|
|
183
|
+
ask_user({
|
|
184
|
+
question: "What would you like to do next?",
|
|
185
|
+
options: [
|
|
186
|
+
{
|
|
187
|
+
label: "Proceed to /unipi:plan",
|
|
188
|
+
description: "Turn decisions into an implementation plan",
|
|
189
|
+
value: "plan",
|
|
190
|
+
action: "new_session",
|
|
191
|
+
prefill: "/unipi:plan specs:YYYY-MM-DD-<topic>-design",
|
|
192
|
+
},
|
|
193
|
+
{ label: "Keep exploring", description: "Refine questions or decisions", value: "explore" },
|
|
194
|
+
{ label: "Done for now", description: "Return later", value: "done", action: "end_turn" },
|
|
195
|
+
],
|
|
196
|
+
allowFreeform: false,
|
|
197
|
+
})
|
|
198
|
+
```
|
|
185
199
|
|
|
186
|
-
If
|
|
200
|
+
If `ask_user` is unavailable, ask conversationally with the same options. Keep this copyable fallback command visible:
|
|
187
201
|
```
|
|
188
202
|
/unipi:plan specs:YYYY-MM-DD-<topic>-design
|
|
189
203
|
```
|
package/skills/debug/SKILL.md
CHANGED
|
@@ -12,6 +12,8 @@ Active investigation to reproduce, diagnose, and root-cause bugs. Produces a str
|
|
|
12
12
|
**This skill MAY:** read codebase, run diagnostic commands, spawn subagents, write debug report to `.unipi/docs/debug/`.
|
|
13
13
|
**This skill MAY NOT:** edit code, fix issues, run tests that modify state, deploy.
|
|
14
14
|
|
|
15
|
+
**Write-permission clarification:** "Read-only" means source/project code is read-only for diagnosis. It does **not** prohibit creating or updating the debug report. The agent should use available file-writing tools to write exactly the report under `.unipi/docs/debug/`. If writing that report fails, report the write failure explicitly.
|
|
16
|
+
|
|
15
17
|
**This is diagnosis only — not fixing.**
|
|
16
18
|
|
|
17
19
|
## Command Format
|
|
@@ -21,7 +23,7 @@ Active investigation to reproduce, diagnose, and root-cause bugs. Produces a str
|
|
|
21
23
|
```
|
|
22
24
|
|
|
23
25
|
- `string(greedy)` — bug description, error message, or reproduction steps
|
|
24
|
-
-
|
|
26
|
+
- Source/code read-only sandbox, with explicit permission to write the debug report to `.unipi/docs/debug/`
|
|
25
27
|
- Spawns subagents if `@unipi/subagents` extension is installed
|
|
26
28
|
|
|
27
29
|
## Output Path
|
|
@@ -104,7 +106,7 @@ Deep dive into root cause:
|
|
|
104
106
|
|
|
105
107
|
### Phase 4: Document Findings
|
|
106
108
|
|
|
107
|
-
Write debug report to `.unipi/docs/debug/YYYY-MM-DD-<topic>-debug.md
|
|
109
|
+
Write debug report to `.unipi/docs/debug/YYYY-MM-DD-<topic>-debug.md` using the available file-writing tool. Do not skip this because the investigation is otherwise read-only:
|
|
108
110
|
|
|
109
111
|
```markdown
|
|
110
112
|
---
|
package/skills/plan/SKILL.md
CHANGED
|
@@ -179,22 +179,45 @@ Do NOT re-read or re-edit the spec checkboxes — Phase 4 already wrote them.
|
|
|
179
179
|
|
|
180
180
|
## Phase 6: Present & Handoff
|
|
181
181
|
|
|
182
|
-
Present plan summary to user. Then ask:
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
182
|
+
Present plan summary to user. Then ask what to do next. If `ask_user` is available, prefer structured handoff options using `action: "new_session"` so the selected workflow can be queued automatically:
|
|
183
|
+
|
|
184
|
+
```ts
|
|
185
|
+
ask_user({
|
|
186
|
+
question: "What would you like to do next?",
|
|
187
|
+
options: [
|
|
188
|
+
{
|
|
189
|
+
label: "Proceed to /unipi:work",
|
|
190
|
+
description: "Start implementing the plan",
|
|
191
|
+
value: "work",
|
|
192
|
+
action: "new_session",
|
|
193
|
+
prefill: "<work-command>",
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
label: "Proceed to /unipi:auto",
|
|
197
|
+
description: "Run full pipeline (work → review → merge)",
|
|
198
|
+
value: "auto",
|
|
199
|
+
action: "new_session",
|
|
200
|
+
prefill: "/unipi:auto plan:YYYY-MM-DD-<topic>-plan.md",
|
|
201
|
+
},
|
|
202
|
+
{ label: "Revise plan", description: "Adjust tasks or scope", value: "revise" },
|
|
203
|
+
{ label: "Done for now", description: "Return later", value: "done", action: "end_turn" },
|
|
204
|
+
],
|
|
205
|
+
allowFreeform: false,
|
|
206
|
+
})
|
|
207
|
+
```
|
|
188
208
|
|
|
189
|
-
|
|
190
|
-
- **Worktree branch** →
|
|
191
|
-
- **Main branch** →
|
|
209
|
+
Use the correct `<work-command>`:
|
|
210
|
+
- **Worktree branch** → `/unipi:work worktree:<branch-name> specs:YYYY-MM-DD-<topic>-plan`
|
|
211
|
+
- **Main branch** → `/unipi:work specs:YYYY-MM-DD-<topic>-plan` (no worktree arg)
|
|
192
212
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
213
|
+
Copyable fallback commands when `ask_user` is unavailable:
|
|
214
|
+
```
|
|
215
|
+
/unipi:work worktree:<branch-name> specs:YYYY-MM-DD-<topic>-plan
|
|
216
|
+
/unipi:work specs:YYYY-MM-DD-<topic>-plan
|
|
217
|
+
/unipi:auto plan:YYYY-MM-DD-<topic>-plan.md
|
|
218
|
+
```
|
|
196
219
|
|
|
197
|
-
Recommend starting a **new session** for work if using a worktree.
|
|
220
|
+
Recommend starting a **new session** for work if using a worktree; the ask_user launcher handles compact/direct queuing when available.
|
|
198
221
|
|
|
199
222
|
---
|
|
200
223
|
|
|
@@ -117,18 +117,34 @@ Followed by description explaining the status.
|
|
|
117
117
|
|
|
118
118
|
## Phase 5: Handoff
|
|
119
119
|
|
|
120
|
-
Based on review results
|
|
120
|
+
Based on review results, use `ask_user` `new_session` options when available so the selected next workflow command can be queued automatically. If `ask_user` is unavailable, present the same choices conversationally and keep copyable commands visible.
|
|
121
121
|
|
|
122
122
|
**If all tasks done and checks pass:**
|
|
123
123
|
|
|
124
124
|
*If `workbranch` is set (worktree):*
|
|
125
125
|
> "All tasks complete and verified. Ready to merge back to main."
|
|
126
|
+
|
|
127
|
+
Offer:
|
|
128
|
+
```ts
|
|
129
|
+
ask_user({
|
|
130
|
+
question: "Merge this worktree now?",
|
|
131
|
+
options: [
|
|
132
|
+
{ label: "Proceed to /unipi:worktree-merge", value: "merge", action: "new_session", prefill: "/unipi:worktree-merge" },
|
|
133
|
+
{ label: "Consolidate learnings", value: "consolidate", action: "new_session", prefill: "/unipi:consolidate" },
|
|
134
|
+
{ label: "Done for now", value: "done", action: "end_turn" },
|
|
135
|
+
],
|
|
136
|
+
allowFreeform: false,
|
|
137
|
+
})
|
|
138
|
+
```
|
|
139
|
+
Copyable fallback:
|
|
126
140
|
```
|
|
127
141
|
/unipi:worktree-merge
|
|
128
142
|
```
|
|
129
143
|
|
|
130
144
|
*If `workbranch` is empty (main branch):*
|
|
131
145
|
> "All tasks complete and verified. Changes already on main — no merge needed."
|
|
146
|
+
|
|
147
|
+
Offer `/unipi:consolidate` as a `new_session` handoff when available. Copyable fallback:
|
|
132
148
|
```
|
|
133
149
|
/unipi:consolidate
|
|
134
150
|
```
|
|
@@ -141,6 +157,8 @@ Either way, user can consolidate learnings:
|
|
|
141
157
|
**If tasks incomplete or checks fail:**
|
|
142
158
|
> "Tasks remaining and/or checks failing. Continue work?"
|
|
143
159
|
|
|
160
|
+
Offer the applicable `/unipi:work ...` command as a `new_session` handoff when available.
|
|
161
|
+
|
|
144
162
|
*If `workbranch` is set:*
|
|
145
163
|
```
|
|
146
164
|
/unipi:work worktree:<branch> specs:<plan-path>
|
|
@@ -153,6 +171,8 @@ Either way, user can consolidate learnings:
|
|
|
153
171
|
|
|
154
172
|
**If scoped review complete:**
|
|
155
173
|
> "Scoped review complete. Run full review or continue work?"
|
|
174
|
+
|
|
175
|
+
Offer both commands as `new_session` options when available:
|
|
156
176
|
```
|
|
157
177
|
/unipi:review-work plan:<plan-path> (full review)
|
|
158
178
|
/unipi:work specs:<plan-path> (continue work)
|
package/skills/work/SKILL.md
CHANGED
|
@@ -163,13 +163,34 @@ When all tasks are `completed:`:
|
|
|
163
163
|
|
|
164
164
|
**If working in worktree:**
|
|
165
165
|
> "All tasks complete. Worktree: `{branch}`. Recommend reviewing before merge."
|
|
166
|
+
|
|
167
|
+
If `ask_user` is available, offer an automatic handoff:
|
|
168
|
+
```ts
|
|
169
|
+
ask_user({
|
|
170
|
+
question: "Review this work now?",
|
|
171
|
+
options: [
|
|
172
|
+
{
|
|
173
|
+
label: "Proceed to /unipi:review-work",
|
|
174
|
+
description: "Review before merge",
|
|
175
|
+
value: "review",
|
|
176
|
+
action: "new_session",
|
|
177
|
+
prefill: "/unipi:review-work plan:<plan-path>",
|
|
178
|
+
},
|
|
179
|
+
{ label: "Done for now", value: "done", action: "end_turn" },
|
|
180
|
+
],
|
|
181
|
+
allowFreeform: false,
|
|
182
|
+
})
|
|
183
|
+
```
|
|
184
|
+
Copyable fallback:
|
|
166
185
|
```
|
|
167
186
|
/unipi:review-work plan:<plan-path>
|
|
168
187
|
```
|
|
169
|
-
**Recommend starting a new session** for review.
|
|
188
|
+
**Recommend starting a new session** for review; the ask_user launcher can compact/direct queue the command.
|
|
170
189
|
|
|
171
190
|
**If working on main branch:**
|
|
172
191
|
> "All tasks complete. All changes committed directly on main."
|
|
192
|
+
|
|
193
|
+
If `ask_user` is available, offer the same review handoff with `prefill: "/unipi:review-work plan:<plan-path>"`. Copyable fallback:
|
|
173
194
|
```
|
|
174
195
|
/unipi:review-work plan:<plan-path>
|
|
175
196
|
```
|