pi-soly 1.0.0 → 1.2.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/commands.ts +3 -2
- package/core.ts +19 -4
- package/index.ts +14 -5
- package/package.json +1 -1
- package/skills/soly-framework/SKILL.md +6 -4
package/commands.ts
CHANGED
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
formatAnalyticsFull,
|
|
27
27
|
formatTok,
|
|
28
28
|
readIfExists,
|
|
29
|
+
solyDirFor,
|
|
29
30
|
type RuleFile,
|
|
30
31
|
type SolyState,
|
|
31
32
|
} from "./core.ts";
|
|
@@ -204,7 +205,7 @@ export function registerCommands(pi: ExtensionAPI, deps: CommandsDeps): void {
|
|
|
204
205
|
}
|
|
205
206
|
const cat = categories[choice];
|
|
206
207
|
if (!cat) return;
|
|
207
|
-
const dir = path.join(cwd, "
|
|
208
|
+
const dir = path.join(solyDirFor(cwd), "rules", cat.name);
|
|
208
209
|
try {
|
|
209
210
|
fs.mkdirSync(dir, { recursive: true });
|
|
210
211
|
} catch {}
|
|
@@ -296,7 +297,7 @@ What must the LLM do?
|
|
|
296
297
|
const lastSeg = parsed.pathname.split("/").filter(Boolean).pop() ?? "rule.md";
|
|
297
298
|
const safeName = lastSeg.replace(/[^A-Za-z0-9._-]/g, "_");
|
|
298
299
|
const fileName = safeName.endsWith(".md") ? safeName : `${safeName}.md`;
|
|
299
|
-
const rulesRoot = path.join(process.cwd(), "
|
|
300
|
+
const rulesRoot = path.join(solyDirFor(process.cwd()), "rules");
|
|
300
301
|
fs.mkdirSync(rulesRoot, { recursive: true });
|
|
301
302
|
const targetFile = path.join(rulesRoot, fileName);
|
|
302
303
|
// Refuse to overwrite without warning
|
package/core.ts
CHANGED
|
@@ -1521,12 +1521,27 @@ export function buildStatusLine(
|
|
|
1521
1521
|
// Soly dir helper
|
|
1522
1522
|
// ============================================================================
|
|
1523
1523
|
|
|
1524
|
-
/**
|
|
1525
|
-
export const SOLY_DIRNAME = ".
|
|
1524
|
+
/** Preferred soly dir name (vendor-neutral). */
|
|
1525
|
+
export const SOLY_DIRNAME = ".agents";
|
|
1526
1526
|
|
|
1527
|
-
/**
|
|
1527
|
+
/** Legacy soly dir name. Kept for backward compat with existing projects. */
|
|
1528
|
+
export const LEGACY_SOLY_DIRNAME = ".soly";
|
|
1529
|
+
|
|
1530
|
+
/** Which project subdir name is currently in use. Returns the first
|
|
1531
|
+
* one that exists, preferring `.agents/`. Falls back to `.soly/` if
|
|
1532
|
+
* no `.agents/` exists. If neither exists, returns `.agents/` (so
|
|
1533
|
+
* new writes go to the new location). */
|
|
1528
1534
|
export function solyDirFor(cwd: string): string {
|
|
1529
|
-
|
|
1535
|
+
if (fs.existsSync(path.join(cwd, SOLY_DIRNAME))) return path.join(cwd, SOLY_DIRNAME);
|
|
1536
|
+
if (fs.existsSync(path.join(cwd, LEGACY_SOLY_DIRNAME))) return path.join(cwd, LEGACY_SOLY_DIRNAME);
|
|
1537
|
+
return path.join(cwd, SOLY_DIRNAME); // default to new for new projects
|
|
1538
|
+
}
|
|
1539
|
+
|
|
1540
|
+
/** True if the legacy `.soly/` dir is in active use (and `.agents/` isn't). */
|
|
1541
|
+
export function isLegacySolyDir(cwd: string): boolean {
|
|
1542
|
+
const newPath = path.join(cwd, SOLY_DIRNAME);
|
|
1543
|
+
const oldPath = path.join(cwd, LEGACY_SOLY_DIRNAME);
|
|
1544
|
+
return !fs.existsSync(newPath) && fs.existsSync(oldPath);
|
|
1530
1545
|
}
|
|
1531
1546
|
|
|
1532
1547
|
// ============================================================================
|
package/index.ts
CHANGED
|
@@ -38,6 +38,7 @@ import {
|
|
|
38
38
|
loadProjectState,
|
|
39
39
|
STATUS_ID,
|
|
40
40
|
solyDirFor,
|
|
41
|
+
isLegacySolyDir,
|
|
41
42
|
buildNextHint,
|
|
42
43
|
buildDriftReminder,
|
|
43
44
|
type RuleFile,
|
|
@@ -53,6 +54,7 @@ import {
|
|
|
53
54
|
type SolyConfig,
|
|
54
55
|
} from "./config.ts";
|
|
55
56
|
import { classifyTaskHeuristics, buildNudgeSection } from "./nudge.ts";
|
|
57
|
+
import { notifyNudge, notifyDeprecation } from "./notification.ts";
|
|
56
58
|
import { registerCommands, type CommandUI } from "./commands.ts";
|
|
57
59
|
import { registerTools } from "./tools.ts";
|
|
58
60
|
import { registerWorkflows } from "./workflows/index.ts";
|
|
@@ -350,6 +352,17 @@ export default function solyExtension(pi: ExtensionAPI) {
|
|
|
350
352
|
// ============================================================================
|
|
351
353
|
|
|
352
354
|
pi.on("session_start", async (event, ctx) => {
|
|
355
|
+
// Deprecation warning: if the project still uses `.soly/`, nudge the
|
|
356
|
+
// user toward `.agents/`. One-time per session.
|
|
357
|
+
if (isLegacySolyDir(ctx.cwd)) {
|
|
358
|
+
notifyDeprecation(
|
|
359
|
+
ctx.ui,
|
|
360
|
+
`.soly/ (legacy)`,
|
|
361
|
+
`.agents/ (vendor-neutral)`,
|
|
362
|
+
`Run \`mv .soly .agents\` to migrate. Both names work for now.`,
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
|
|
353
366
|
// Rules sources (priority order, higher wins on relPath collision).
|
|
354
367
|
// Project rules always beat global rules. .soly/rules.local/ is
|
|
355
368
|
// gitignored — for personal overrides on top of the project's rules.
|
|
@@ -663,11 +676,7 @@ export default function solyExtension(pi: ExtensionAPI) {
|
|
|
663
676
|
const angle =
|
|
664
677
|
heuristics.suggestedAngles[0] ?? "want me to confirm assumptions before I start?";
|
|
665
678
|
|
|
666
|
-
|
|
667
|
-
? "soly: research-heavy prompt — clarifying question?"
|
|
668
|
-
: "soly: non-trivial prompt — clarifying question?";
|
|
669
|
-
|
|
670
|
-
ctx.ui.notify(`${label} ${angle}`, "info");
|
|
679
|
+
notifyNudge(ctx.ui, heuristics.researchHeavy ? "research" : "nonTrivial", angle);
|
|
671
680
|
nudgeActiveForTask = true;
|
|
672
681
|
lastNudgePromptKey = text.slice(0, 200);
|
|
673
682
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-soly",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.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",
|
|
@@ -81,11 +81,13 @@ The **soly** extension adds project-management workflow to [pi-coding-agent](htt
|
|
|
81
81
|
│ └── data-scientist.md
|
|
82
82
|
```
|
|
83
83
|
|
|
84
|
-
**Two parallel conventions:** `.soly/` is soly
|
|
84
|
+
**Two parallel conventions (migration in progress):** `.soly/` is the legacy soly state. `.agents/` is the new vendor-neutral home. The two work side-by-side:
|
|
85
85
|
|
|
86
|
-
- Use `.
|
|
87
|
-
- Use `.
|
|
88
|
-
- Use `AGENTS.md
|
|
86
|
+
- **Use `.agents/`** for new projects (recommended)
|
|
87
|
+
- **Use `.soly/`** for legacy projects (still works, will show a deprecation warning)
|
|
88
|
+
- **Use `AGENTS.md`** for top-level project-wide agent conventions
|
|
89
|
+
|
|
90
|
+
To migrate: `mv .soly .agents` — soly picks up the new location automatically. No data loss.
|
|
89
91
|
|
|
90
92
|
## Frontmatter conventions
|
|
91
93
|
|