pi-soly 1.16.1 → 1.16.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/config.ts +7 -3
- package/package.json +1 -1
- package/workflows/execute.ts +5 -2
- package/workflows/parser.ts +4 -4
- package/workflows/planning.ts +9 -4
package/config.ts
CHANGED
|
@@ -272,9 +272,13 @@ function deepMerge(base: SolyConfig, over: RawConfig): SolyConfig {
|
|
|
272
272
|
merged.editor.command = over.editor.command;
|
|
273
273
|
}
|
|
274
274
|
if (over.plan && typeof over.plan.defaultBranchPrefix === "string") {
|
|
275
|
-
// Sanitize: allow only kebab-case
|
|
276
|
-
// Empty string is allowed and means
|
|
277
|
-
|
|
275
|
+
// Sanitize: lowercase, then allow only kebab-case chars (no
|
|
276
|
+
// slashes/dots/spaces). Empty string is allowed and means
|
|
277
|
+
// "no prefix". We do NOT warn on slash/uppercase — the user
|
|
278
|
+
// probably meant a different prefix shape; silently normalizing
|
|
279
|
+
// keeps configs from being rejected for cosmetic reasons.
|
|
280
|
+
const lowercased = over.plan.defaultBranchPrefix.toLowerCase();
|
|
281
|
+
const sanitized = lowercased.replace(/[^a-z0-9-]/g, "");
|
|
278
282
|
const collapsed = sanitized.replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
279
283
|
merged.plan.defaultBranchPrefix = collapsed;
|
|
280
284
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-soly",
|
|
3
|
-
"version": "1.16.
|
|
3
|
+
"version": "1.16.2",
|
|
4
4
|
"description": "Project management + workflow framework for pi-coding-agent. Plans, state, MANDATORY rules, self-review, multi-question picker, native footer + welcome chrome — one npm install, zero config. The LLM drives execution and delegates to a worker subagent when available.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
package/workflows/execute.ts
CHANGED
|
@@ -274,9 +274,12 @@ When the subagent completes, synthesize the result. Do not re-execute its work.
|
|
|
274
274
|
};
|
|
275
275
|
}
|
|
276
276
|
|
|
277
|
-
// === PLAN MODE (new dual-mode: `<type>/<name>` plans live under .agents/plans/<name>/) ===
|
|
277
|
+
// === PLAN MODE (new dual-mode: `<type>/<name>` plans live under .agents/plans/<prefix>-<name>/) ===
|
|
278
278
|
if (target.kind === "plan") {
|
|
279
|
-
|
|
279
|
+
// Plan dir is always flattened: `<prefix>-<name>` if a prefix is
|
|
280
|
+
// present, else just `<name>`.
|
|
281
|
+
const dirSlug = target.prefix ? `${target.prefix}-${target.name}` : target.name;
|
|
282
|
+
const planDirAbs = `${state.solyDir}/plans/${dirSlug}`;
|
|
280
283
|
const planFile = `${planDirAbs}/PLAN.md`;
|
|
281
284
|
let planBody: string;
|
|
282
285
|
try {
|
package/workflows/parser.ts
CHANGED
|
@@ -241,7 +241,7 @@ function parseNewTaskFlag(
|
|
|
241
241
|
*/
|
|
242
242
|
export type ExecuteTarget =
|
|
243
243
|
| { kind: "phase"; phase: number; plan: number | null; raw: string }
|
|
244
|
-
| { kind: "plan"; name: string; raw: string }
|
|
244
|
+
| { kind: "plan"; name: string; prefix: string | null; raw: string }
|
|
245
245
|
| { kind: "task"; taskId: string; raw: string }
|
|
246
246
|
| { kind: "all"; raw: string }
|
|
247
247
|
| { kind: "feature"; feature: string; raw: string };
|
|
@@ -287,7 +287,7 @@ export function describeExecuteTarget(args: string[]): ExecuteTarget | null {
|
|
|
287
287
|
|
|
288
288
|
const plan = parsePlanName(target);
|
|
289
289
|
if (!("error" in plan)) {
|
|
290
|
-
return { kind: "plan", name: plan.name, raw };
|
|
290
|
+
return { kind: "plan", name: plan.name, prefix: plan.prefix, raw };
|
|
291
291
|
}
|
|
292
292
|
|
|
293
293
|
const phase = parsePhaseShape(target);
|
|
@@ -313,7 +313,7 @@ export function describeExecuteTarget(args: string[]): ExecuteTarget | null {
|
|
|
313
313
|
*/
|
|
314
314
|
export type PlanTarget =
|
|
315
315
|
| { kind: "phase"; phase: number; raw: string }
|
|
316
|
-
| { kind: "plan"; name: string; raw: string }
|
|
316
|
+
| { kind: "plan"; name: string; prefix: string | null; raw: string }
|
|
317
317
|
| { kind: "task"; taskId: string; raw: string }
|
|
318
318
|
| { kind: "new-task"; slug: string; feature: string; raw: string }
|
|
319
319
|
| { kind: "feature"; feature: string; raw: string };
|
|
@@ -361,7 +361,7 @@ export function describePlanTarget(args: string[]): PlanTarget | null {
|
|
|
361
361
|
|
|
362
362
|
const plan = parsePlanName(target);
|
|
363
363
|
if (!("error" in plan)) {
|
|
364
|
-
return { kind: "plan", name: plan.name, raw };
|
|
364
|
+
return { kind: "plan", name: plan.name, prefix: plan.prefix, raw };
|
|
365
365
|
}
|
|
366
366
|
|
|
367
367
|
// Plan target only matches plain N (no .MM — plan is per-phase, executed
|
package/workflows/planning.ts
CHANGED
|
@@ -91,9 +91,13 @@ export function buildPlanTransform(cmd: SolyCommand, state: SolyState): Planning
|
|
|
91
91
|
};
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
// === PLAN MODE (new dual-mode: `<type>/<name>` plans live under .agents/plans/<name>/) ===
|
|
94
|
+
// === PLAN MODE (new dual-mode: `<type>/<name>` plans live under .agents/plans/<prefix>-<name>/) ===
|
|
95
95
|
if (target.kind === "plan") {
|
|
96
|
-
|
|
96
|
+
// Plan dir is always flattened: `<prefix>-<name>` if a prefix is
|
|
97
|
+
// present (user typed `<prefix>/<slug>` or the project default
|
|
98
|
+
// applied), else just `<name>`.
|
|
99
|
+
const dirSlug = target.prefix ? `${target.prefix}-${target.name}` : target.name;
|
|
100
|
+
const planDirAbs = `${state.solyDir}/plans/${dirSlug}`;
|
|
97
101
|
const planFile = `${planDirAbs}/PLAN.md`;
|
|
98
102
|
let planBody: string;
|
|
99
103
|
try {
|
|
@@ -514,10 +518,11 @@ export function buildDiscussTransform(
|
|
|
514
518
|
};
|
|
515
519
|
}
|
|
516
520
|
|
|
517
|
-
// Plan mode: `<
|
|
521
|
+
// Plan mode: `<slug>` or `<prefix>/<slug>`
|
|
518
522
|
const planParsed = parsePlanName(arg);
|
|
519
523
|
if (!("error" in planParsed)) {
|
|
520
|
-
const
|
|
524
|
+
const dirSlug = planParsed.prefix ? `${planParsed.prefix}-${planParsed.name}` : planParsed.name;
|
|
525
|
+
const planDirAbs = `${state.solyDir}/plans/${dirSlug}`;
|
|
521
526
|
const planFile = `${planDirAbs}/PLAN.md`;
|
|
522
527
|
let planBody: string;
|
|
523
528
|
try {
|