@xynogen/pix-runtime 0.14.0 → 0.15.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/README.md CHANGED
@@ -10,7 +10,7 @@ See `DESIGN.md` for the full contract.
10
10
  ## What it does
11
11
 
12
12
  - Versioned, sparse `pix.json` (`$version: 1`) — defaults resolve in code.
13
- - Typed sections: `collapse`, `pretty`, `io`, `compaction`, `optimizer`, `gate`, `fetch`, `search`, `voice`, `toolbox`.
13
+ - Typed sections: `collapse`, `pretty`, `io`, `compaction`, `edit`, `optimizer`, `gate`, `fetch`, `search`, `voice`, `toolbox`.
14
14
  - `/pix` has a Footer tab for `pretty.footer` visibility.
15
15
  - Startup imports legacy service config files and archives them only after a successful save.
16
16
  - Atomic writes behind a serialized in-process queue and a short-lived
@@ -65,6 +65,17 @@ The default floor is 100K and the hard minimum is 25K (values below clamp up);
65
65
  `/pix` offers 25K, 50K, 100K, 150K, 200K, 300K, 400K, 600K, 800K, and 1M.
66
66
  pix-core consumes both settings.
67
67
 
68
+ Over that threshold, pix-core masks older tool output before it summarizes.
69
+ `compaction.maskKeep` (default `10`) is the number of newest tool results kept as
70
+ is. Older successful `bash`/`grep`/`find`/`ls`/`read` output becomes a one-line
71
+ stub; errors stay. `compaction.maskMinTokens` (default `5000`) skips a pass that
72
+ would free fewer tokens, because each pass breaks the prompt cache. Both are
73
+ `pix.json` calibration knobs with no `/pix` picker.
74
+
75
+ `edit.rejectNewSyntaxErrors` (default `false`, `/pix` → **Edit → syntax guard**)
76
+ makes pix-diagnostics restore a file and fail the edit when LSP reports a syntax
77
+ error that was not there before. Type errors never trigger it.
78
+
68
79
  Collapse policy helpers:
69
80
 
70
81
  ```ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xynogen/pix-runtime",
3
- "version": "0.14.0",
3
+ "version": "0.15.0",
4
4
  "description": "Pix shared runtime — versioned pix.json config, atomic persistence, typed change events",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -22,6 +22,7 @@ import type { PixRuntime } from "./runtime.ts";
22
22
  import { type DeepPartial, deepMerge, type SectionHandle } from "./schema.ts";
23
23
  import { collapseSection } from "./sections/collapse.ts";
24
24
  import { compactionSection } from "./sections/compaction.ts";
25
+ import { editSection } from "./sections/edit.ts";
25
26
  import { gateSection } from "./sections/gate.ts";
26
27
  import { ioSection } from "./sections/io.ts";
27
28
  import { prettySection, type RenderSize } from "./sections/pretty.ts";
@@ -176,6 +177,14 @@ const SETTINGS: SettingRow<unknown>[] = [
176
177
  read: (v) => formatTokens(v.minimumTokens),
177
178
  patch: (value) => ({ minimumTokens: parseTokens(value) }),
178
179
  }),
180
+ row({
181
+ section: "Edit",
182
+ label: "syntax guard",
183
+ handle: editSection,
184
+ values: ["off", "on"],
185
+ read: (v) => (v.rejectNewSyntaxErrors ? "on" : "off"),
186
+ patch: (value) => ({ rejectNewSyntaxErrors: value === "on" }),
187
+ }),
179
188
  row({
180
189
  section: "Gate",
181
190
  label: "Guardrails",
@@ -12,6 +12,10 @@ export interface CompactionConfig {
12
12
  triggerPercent: number;
13
13
  /** Absolute floor for a percentage-based trigger. */
14
14
  minimumTokens: number;
15
+ /** Over threshold: newest tool results kept as is; older bash/grep/find/ls/read output is masked. */
16
+ maskKeep: number;
17
+ /** Skip a masking pass that would free fewer tokens than this (each pass breaks the prompt cache). */
18
+ maskMinTokens: number;
15
19
  }
16
20
 
17
21
  const MINIMUM_TOKEN_FLOOR = 25_000;
@@ -20,6 +24,8 @@ const MINIMUM_TOKEN_DEFAULT = 100_000;
20
24
  const DEFAULTS: Readonly<CompactionConfig> = {
21
25
  triggerPercent: 60,
22
26
  minimumTokens: MINIMUM_TOKEN_DEFAULT,
27
+ maskKeep: 10,
28
+ maskMinTokens: 5_000,
23
29
  };
24
30
 
25
31
  /** Clamp to [0, 100]; non-numbers fall back. */
@@ -35,6 +41,12 @@ function minimumTokensOr(v: unknown, fallback: number): number {
35
41
  return Math.max(MINIMUM_TOKEN_FLOOR, Math.round(v));
36
42
  }
37
43
 
44
+ /** Non-negative integer; non-numbers fall back. */
45
+ function countOr(v: unknown, fallback: number): number {
46
+ if (typeof v !== "number" || !Number.isFinite(v)) return fallback;
47
+ return Math.max(0, Math.round(v));
48
+ }
49
+
38
50
  function parseTokenString(label: string): number | undefined {
39
51
  const raw = label.trim();
40
52
  if (!raw) return undefined;
@@ -60,6 +72,8 @@ export const compactionSection = defineSection<"compaction", CompactionConfig>({
60
72
  return {
61
73
  triggerPercent: pctOr(raw.triggerPercent, DEFAULTS.triggerPercent),
62
74
  minimumTokens: minimumTokensOr(coercedMin, DEFAULTS.minimumTokens),
75
+ maskKeep: countOr(raw.maskKeep, DEFAULTS.maskKeep),
76
+ maskMinTokens: countOr(raw.maskMinTokens, DEFAULTS.maskMinTokens),
63
77
  };
64
78
  },
65
79
  });
@@ -0,0 +1,21 @@
1
+ import { boolOr, defineSection, isObj } from "../schema.ts";
2
+
3
+ export interface EditConfig {
4
+ /** Restore the file and fail the edit when LSP reports new syntax errors after it. */
5
+ rejectNewSyntaxErrors: boolean;
6
+ }
7
+
8
+ const DEFAULTS: Readonly<EditConfig> = {
9
+ rejectNewSyntaxErrors: false,
10
+ };
11
+
12
+ export const editSection = defineSection<"edit", EditConfig>({
13
+ key: "edit",
14
+ defaults: DEFAULTS,
15
+ parse(raw) {
16
+ if (!isObj(raw)) return { ...DEFAULTS };
17
+ return {
18
+ rejectNewSyntaxErrors: boolOr(raw.rejectNewSyntaxErrors, DEFAULTS.rejectNewSyntaxErrors),
19
+ };
20
+ },
21
+ });
@@ -1,5 +1,6 @@
1
1
  export { type CollapseConfig, collapseSection } from "./collapse.ts";
2
2
  export { type CompactionConfig, compactionSection } from "./compaction.ts";
3
+ export { type EditConfig, editSection } from "./edit.ts";
3
4
  export {
4
5
  type GateConfig,
5
6
  type GateRuleConfig,
@@ -25,6 +26,7 @@ export {
25
26
 
26
27
  import { collapseSection } from "./collapse.ts";
27
28
  import { compactionSection } from "./compaction.ts";
29
+ import { editSection } from "./edit.ts";
28
30
  import { gateSection } from "./gate.ts";
29
31
  import { ioSection } from "./io.ts";
30
32
  import { optimizerSection } from "./optimizer.ts";
@@ -50,6 +52,7 @@ export const builtinSections = [
50
52
  optimizerSection,
51
53
  gateSection,
52
54
  compactionSection,
55
+ editSection,
53
56
  fetchSection,
54
57
  searchSection,
55
58
  voiceSection,