pi-soly 2.0.0 → 2.1.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/config.ts +0 -10
- package/core.ts +0 -62
- package/index.ts +0 -25
- package/package.json +1 -1
package/config.ts
CHANGED
|
@@ -49,13 +49,6 @@ export interface SolyConfig {
|
|
|
49
49
|
* "off" — no gate.
|
|
50
50
|
* Booleans accepted for back-compat: true = "scope", false = "off". */
|
|
51
51
|
confirmBeforeCode: boolean | "off" | "ask" | "scope";
|
|
52
|
-
/** Inject a compact list of rules applicable to the file being
|
|
53
|
-
* edited/written, appended to the tool's result. Forces the LLM to
|
|
54
|
-
* confirm in the next message which rules were applied — closes the
|
|
55
|
-
* "rules read at start of turn, forgotten by edit time" gap.
|
|
56
|
-
* Default on. Disable for verbose rule sets that would otherwise
|
|
57
|
-
* flood the per-edit context. */
|
|
58
|
-
preActionRuleReminder: boolean;
|
|
59
52
|
};
|
|
60
53
|
display: {
|
|
61
54
|
/** Always show the recommended (⭐) option as the first row. */
|
|
@@ -148,7 +141,6 @@ export const DEFAULT_CONFIG: SolyConfig = {
|
|
|
148
141
|
nudgeNotify: false,
|
|
149
142
|
toolHints: true,
|
|
150
143
|
confirmBeforeCode: "scope",
|
|
151
|
-
preActionRuleReminder: true,
|
|
152
144
|
},
|
|
153
145
|
display: {
|
|
154
146
|
defaultRecommendedFirst: true,
|
|
@@ -248,8 +240,6 @@ function deepMerge(base: SolyConfig, over: RawConfig): SolyConfig {
|
|
|
248
240
|
over.agent.confirmBeforeCode === "scope"
|
|
249
241
|
)
|
|
250
242
|
merged.agent.confirmBeforeCode = over.agent.confirmBeforeCode;
|
|
251
|
-
if (typeof over.agent.preActionRuleReminder === "boolean")
|
|
252
|
-
merged.agent.preActionRuleReminder = over.agent.preActionRuleReminder;
|
|
253
243
|
}
|
|
254
244
|
if (over.display) {
|
|
255
245
|
if (typeof over.display.defaultRecommendedFirst === "boolean")
|
package/core.ts
CHANGED
|
@@ -571,68 +571,6 @@ ${blocks.join("\n\n---\n\n")}${skippedNote}
|
|
|
571
571
|
return { section, loaded: applicable.map(ruleKey), interactive };
|
|
572
572
|
}
|
|
573
573
|
|
|
574
|
-
// ============================================================================
|
|
575
|
-
// Per-file rule lookup (used by pre-action reminder in tool_result hook)
|
|
576
|
-
// ============================================================================
|
|
577
|
-
//
|
|
578
|
-
// Returns the subset of `rules` that apply to a single file path. Mirrors the
|
|
579
|
-
// glob logic in `buildRulesSection` (always/no-globs = universal; otherwise
|
|
580
|
-
// match `filePath` against `meta.globs`). Excludes disabled rules. Use this
|
|
581
|
-
// to feed the pre-action reminder — LLM should see applicable rules AT THE
|
|
582
|
-
// MOMENT of edit, not just at the start of the turn (where they decay).
|
|
583
|
-
export function getApplicableRulesForFile(
|
|
584
|
-
filePath: string,
|
|
585
|
-
rules: RuleFile[],
|
|
586
|
-
): RuleFile[] {
|
|
587
|
-
return rules.filter((r) => {
|
|
588
|
-
if (!r.enabled) return false;
|
|
589
|
-
if (r.meta.always === true) return true;
|
|
590
|
-
const globs = r.meta.globs;
|
|
591
|
-
if (!globs || globs.length === 0) return true;
|
|
592
|
-
return globs.some((g) => matchesGlob(filePath, g));
|
|
593
|
-
});
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
// Formats a compact reminder block for the LLM to see right after editing
|
|
597
|
-
// `filePath`. Sorted by priority (high → medium → low → undefined), capped
|
|
598
|
-
// at `cap` rules (default 3) so the LLM isn't flooded. Returns "" when no
|
|
599
|
-
// rules apply — caller should treat that as "don't inject anything".
|
|
600
|
-
export function formatRuleReminder(
|
|
601
|
-
rules: RuleFile[],
|
|
602
|
-
filePath: string,
|
|
603
|
-
cap = 3,
|
|
604
|
-
): string {
|
|
605
|
-
if (rules.length === 0) return "";
|
|
606
|
-
|
|
607
|
-
const priorityOrder: Record<string, number> = { high: 0, medium: 1, low: 2 };
|
|
608
|
-
const sorted = [...rules].sort((a, b) => {
|
|
609
|
-
const pa = priorityOrder[a.meta.priority ?? ""] ?? 1;
|
|
610
|
-
const pb = priorityOrder[b.meta.priority ?? ""] ?? 1;
|
|
611
|
-
if (pa !== pb) return pa - pb;
|
|
612
|
-
return a.relPath.localeCompare(b.relPath);
|
|
613
|
-
});
|
|
614
|
-
|
|
615
|
-
const shown = sorted.slice(0, cap);
|
|
616
|
-
const remaining = rules.length - shown.length;
|
|
617
|
-
|
|
618
|
-
const lines: string[] = [];
|
|
619
|
-
lines.push(`\n\n---\n\n📋 **Applicable rules for \`${filePath}\`:**\n`);
|
|
620
|
-
shown.forEach((r, i) => {
|
|
621
|
-
const desc = r.meta.description ? ` — ${r.meta.description}` : "";
|
|
622
|
-
lines.push(`${i + 1}. [\`${r.relPath}\`]${desc}`);
|
|
623
|
-
});
|
|
624
|
-
if (remaining > 0) {
|
|
625
|
-
lines.push(
|
|
626
|
-
`\n_…and ${remaining} more — use \`/why ${filePath}\` to see all._`,
|
|
627
|
-
);
|
|
628
|
-
}
|
|
629
|
-
lines.push(
|
|
630
|
-
`\nIn your next message, briefly confirm which were applied (or note why not).`,
|
|
631
|
-
);
|
|
632
|
-
|
|
633
|
-
return lines.join("\n");
|
|
634
|
-
}
|
|
635
|
-
|
|
636
574
|
// ============================================================================
|
|
637
575
|
// Phase-scoped rules loader
|
|
638
576
|
// ============================================================================
|
package/index.ts
CHANGED
|
@@ -32,9 +32,7 @@ import {
|
|
|
32
32
|
CONTEXT_WINDOW_TOKENS,
|
|
33
33
|
DEFAULT_PROGRESS,
|
|
34
34
|
extractFilePathsFromPrompt,
|
|
35
|
-
formatRuleReminder,
|
|
36
35
|
formatTok,
|
|
37
|
-
getApplicableRulesForFile,
|
|
38
36
|
loadAllRules,
|
|
39
37
|
loadPhaseRules,
|
|
40
38
|
loadProjectState,
|
|
@@ -901,29 +899,6 @@ export default function solyExtension(pi: ExtensionAPI) {
|
|
|
901
899
|
}
|
|
902
900
|
});
|
|
903
901
|
|
|
904
|
-
// ============================================================================
|
|
905
|
-
// tool_result: inject a compact reminder of rules applicable to the file
|
|
906
|
-
// just edited/written, so the LLM sees them AT THE MOMENT of action (not
|
|
907
|
-
// 30 turns later when they've decayed in attention). The LLM is asked to
|
|
908
|
-
// confirm in its next message which rules were applied — closing the gap
|
|
909
|
-
// where rules loaded at the start of a turn are forgotten by the time the
|
|
910
|
-
// agent actually edits something.
|
|
911
|
-
// ============================================================================
|
|
912
|
-
pi.on("tool_result", async (event, _ctx) => {
|
|
913
|
-
if (!getActiveConfig().agent.preActionRuleReminder) return;
|
|
914
|
-
if (event.toolName !== "edit" && event.toolName !== "write") return;
|
|
915
|
-
if (event.isError) return; // tool failed — don't pile on
|
|
916
|
-
const input = event.input as { path?: string };
|
|
917
|
-
const filePath = input?.path;
|
|
918
|
-
if (!filePath) return;
|
|
919
|
-
const applicable = getApplicableRulesForFile(filePath, combinedRules());
|
|
920
|
-
const reminder = formatRuleReminder(applicable, filePath);
|
|
921
|
-
if (!reminder) return;
|
|
922
|
-
return {
|
|
923
|
-
content: [...event.content, { type: "text" as const, text: reminder }],
|
|
924
|
-
};
|
|
925
|
-
});
|
|
926
|
-
|
|
927
902
|
// ============================================================================
|
|
928
903
|
// Chrome: working-indicator telemetry lifecycle + reactive data refresh
|
|
929
904
|
// ============================================================================
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-soly",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
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 the workflow inline via the soly_workflow tool — no external subagent plugin.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|