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.
Files changed (4) hide show
  1. package/config.ts +0 -10
  2. package/core.ts +0 -62
  3. package/index.ts +0 -25
  4. 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.0.0",
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",