pi-soly 1.5.0 → 1.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/core.ts +33 -1
- package/index.ts +32 -0
- package/package.json +1 -1
package/core.ts
CHANGED
|
@@ -758,7 +758,9 @@ export function buildRulesSection(
|
|
|
758
758
|
|
|
759
759
|
const section = `
|
|
760
760
|
|
|
761
|
-
## soly project rules
|
|
761
|
+
## ⚠️ MANDATORY: soly project rules
|
|
762
|
+
|
|
763
|
+
**These rules are NON-NEGOTIABLE. Before writing or editing ANY code, re-read the rules above that apply to the file path you are about to modify. If a rule contradicts your instinct, the rule wins.**
|
|
762
764
|
|
|
763
765
|
${headerHint}
|
|
764
766
|
|
|
@@ -1612,3 +1614,33 @@ export function buildDriftReminder(turnsSinceLastVerb: number): string | null {
|
|
|
1612
1614
|
const when = turnsSinceLastVerb === 1 ? "1 turn" : `${turnsSinceLastVerb} turns`;
|
|
1613
1615
|
return `soly drift hint: ${when} since last soly verb. Consider \`${verb}\` to sync state (pause saves HANDOFF for resume across compactions).`;
|
|
1614
1616
|
}
|
|
1617
|
+
|
|
1618
|
+
// =============================================================================
|
|
1619
|
+
// Post-work rules check: which rules apply to a set of edited files?
|
|
1620
|
+
// =============================================================================
|
|
1621
|
+
//
|
|
1622
|
+
// Used by the turn_end hook to surface a checklist of rules that SHOULD have
|
|
1623
|
+
// been followed during this turn. Honest post-hook — does not claim to detect
|
|
1624
|
+
// violations, just lists what was applicable so the user can verify.
|
|
1625
|
+
|
|
1626
|
+
export function rulesApplicableToFiles(
|
|
1627
|
+
rules: RuleFile[],
|
|
1628
|
+
editedFiles: string[],
|
|
1629
|
+
): string[] {
|
|
1630
|
+
const applicable = new Set<string>();
|
|
1631
|
+
for (const filePath of editedFiles) {
|
|
1632
|
+
for (const rule of rules) {
|
|
1633
|
+
if (!rule.enabled) continue;
|
|
1634
|
+
const globs = rule.meta.globs;
|
|
1635
|
+
const always = rule.meta.always === true;
|
|
1636
|
+
if (always) {
|
|
1637
|
+
applicable.add(rule.relPath);
|
|
1638
|
+
continue;
|
|
1639
|
+
}
|
|
1640
|
+
if (globs && globs.some((g) => matchesGlob(filePath, g))) {
|
|
1641
|
+
applicable.add(rule.relPath);
|
|
1642
|
+
}
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
return [...applicable];
|
|
1646
|
+
}
|
package/index.ts
CHANGED
|
@@ -36,6 +36,8 @@ import {
|
|
|
36
36
|
loadAllRules,
|
|
37
37
|
loadPhaseRules,
|
|
38
38
|
loadProjectState,
|
|
39
|
+
matchesGlob,
|
|
40
|
+
rulesApplicableToFiles,
|
|
39
41
|
STATUS_ID,
|
|
40
42
|
solyDirFor,
|
|
41
43
|
isLegacySolyDir,
|
|
@@ -125,6 +127,7 @@ export default function solyExtension(pi: ExtensionAPI) {
|
|
|
125
127
|
|
|
126
128
|
// Behavioral nudge state
|
|
127
129
|
let nudgeActiveForTask = false;
|
|
130
|
+
let editedFilesThisTurn = new Set<string>();
|
|
128
131
|
let lastNudgePromptKey = "";
|
|
129
132
|
|
|
130
133
|
// Git context (cached, refreshed on hot reload + before_agent_start)
|
|
@@ -709,6 +712,35 @@ export default function solyExtension(pi: ExtensionAPI) {
|
|
|
709
712
|
if (rulesChanged || stateChanged) {
|
|
710
713
|
updateStatus(ctx);
|
|
711
714
|
}
|
|
715
|
+
|
|
716
|
+
// Post-work rules check: surface applicable rules for files edited
|
|
717
|
+
// in this turn. Honest post-hook — doesn't pretend to detect violations,
|
|
718
|
+
// just reminds the user which rules SHOULD have been followed.
|
|
719
|
+
if (editedFilesThisTurn.size > 0) {
|
|
720
|
+
const applicable = rulesApplicableToFiles(
|
|
721
|
+
combinedRules(),
|
|
722
|
+
[...editedFilesThisTurn],
|
|
723
|
+
);
|
|
724
|
+
if (applicable.length > 0) {
|
|
725
|
+
ctx.ui.notify(
|
|
726
|
+
`📋 Rules check: edited ${editedFilesThisTurn.size} file(s), ${applicable.length} rule(s) applied:\n • ${applicable.join("\n • ")}`,
|
|
727
|
+
"info",
|
|
728
|
+
);
|
|
729
|
+
}
|
|
730
|
+
editedFilesThisTurn = new Set();
|
|
731
|
+
}
|
|
732
|
+
});
|
|
733
|
+
|
|
734
|
+
// ============================================================================
|
|
735
|
+
// tool_call: track files edited in this turn. Used at turn_end to surface
|
|
736
|
+
// applicable rules as a post-work checklist ("did the agent follow them?").
|
|
737
|
+
// ============================================================================
|
|
738
|
+
pi.on("tool_call", async (event, _ctx) => {
|
|
739
|
+
if (event.toolName !== "edit" && event.toolName !== "write") return;
|
|
740
|
+
const input = event.input as { path?: string };
|
|
741
|
+
if (input?.path) {
|
|
742
|
+
editedFilesThisTurn.add(input.path);
|
|
743
|
+
}
|
|
712
744
|
});
|
|
713
745
|
|
|
714
746
|
// Mount built-in sub-features
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-soly",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.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",
|