@osovv/vv-opencode 1.2.7 → 1.2.10

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 (66) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +63 -3
  3. package/dist/commands/patch-provider.js +2 -0
  4. package/dist/commands/patch-provider.js.map +1 -1
  5. package/dist/commands/plugin-list.js +8 -3
  6. package/dist/commands/plugin-list.js.map +1 -1
  7. package/dist/commands/plugin-toggle.js +8 -1
  8. package/dist/commands/plugin-toggle.js.map +1 -1
  9. package/dist/index.d.ts +1 -0
  10. package/dist/index.js +5 -4
  11. package/dist/index.js.map +1 -1
  12. package/dist/lib/opencode.js +3 -0
  13. package/dist/lib/opencode.js.map +1 -1
  14. package/dist/lib/plugin-toggle-config.d.ts +44 -2
  15. package/dist/lib/plugin-toggle-config.js +132 -11
  16. package/dist/lib/plugin-toggle-config.js.map +1 -1
  17. package/dist/lib/vvoc-config.d.ts +80 -2
  18. package/dist/lib/vvoc-config.js +62 -1
  19. package/dist/lib/vvoc-config.js.map +1 -1
  20. package/dist/plugins/hashline-edit/diff-summary.d.ts +7 -0
  21. package/dist/plugins/hashline-edit/diff-summary.js +79 -0
  22. package/dist/plugins/hashline-edit/diff-summary.js.map +1 -0
  23. package/dist/plugins/hashline-edit/edit-operation-primitives.js +22 -3
  24. package/dist/plugins/hashline-edit/edit-operation-primitives.js.map +1 -1
  25. package/dist/plugins/hashline-edit/index.js +315 -76
  26. package/dist/plugins/hashline-edit/index.js.map +1 -1
  27. package/dist/plugins/hashline-edit/normalize-edits.js +29 -25
  28. package/dist/plugins/hashline-edit/normalize-edits.js.map +1 -1
  29. package/dist/plugins/hashline-edit/replace-engine.d.ts +24 -0
  30. package/dist/plugins/hashline-edit/replace-engine.js +246 -0
  31. package/dist/plugins/hashline-edit/replace-engine.js.map +1 -0
  32. package/dist/plugins/hashline-edit/routing.d.ts +21 -0
  33. package/dist/plugins/hashline-edit/routing.js +105 -0
  34. package/dist/plugins/hashline-edit/routing.js.map +1 -0
  35. package/dist/plugins/hashline-edit/session-state.d.ts +23 -0
  36. package/dist/plugins/hashline-edit/session-state.js +70 -0
  37. package/dist/plugins/hashline-edit/session-state.js.map +1 -0
  38. package/dist/plugins/hashline-edit/str-replace-editor.d.ts +50 -0
  39. package/dist/plugins/hashline-edit/str-replace-editor.js +285 -0
  40. package/dist/plugins/hashline-edit/str-replace-editor.js.map +1 -0
  41. package/dist/plugins/hashline-edit/tool-description.d.ts +2 -1
  42. package/dist/plugins/hashline-edit/tool-description.js +31 -10
  43. package/dist/plugins/hashline-edit/tool-description.js.map +1 -1
  44. package/dist/plugins/hashline-edit/validation.d.ts +1 -0
  45. package/dist/plugins/hashline-edit/validation.js +13 -3
  46. package/dist/plugins/hashline-edit/validation.js.map +1 -1
  47. package/dist/plugins/tool-history-compaction/config.d.ts +28 -0
  48. package/dist/plugins/tool-history-compaction/config.js +133 -0
  49. package/dist/plugins/tool-history-compaction/config.js.map +1 -0
  50. package/dist/plugins/tool-history-compaction/index.d.ts +2 -0
  51. package/dist/plugins/tool-history-compaction/index.js +35 -0
  52. package/dist/plugins/tool-history-compaction/index.js.map +1 -0
  53. package/dist/plugins/tool-history-compaction/prune.d.ts +22 -0
  54. package/dist/plugins/tool-history-compaction/prune.js +70 -0
  55. package/dist/plugins/tool-history-compaction/prune.js.map +1 -0
  56. package/dist/plugins/tool-history-compaction/read-slim.d.ts +27 -0
  57. package/dist/plugins/tool-history-compaction/read-slim.js +91 -0
  58. package/dist/plugins/tool-history-compaction/read-slim.js.map +1 -0
  59. package/dist/plugins/tool-history-compaction/retention.d.ts +10 -0
  60. package/dist/plugins/tool-history-compaction/retention.js +45 -0
  61. package/dist/plugins/tool-history-compaction/retention.js.map +1 -0
  62. package/dist/plugins/tool-history-compaction/transform.d.ts +15 -0
  63. package/dist/plugins/tool-history-compaction/transform.js +93 -0
  64. package/dist/plugins/tool-history-compaction/transform.js.map +1 -0
  65. package/package.json +5 -1
  66. package/schemas/vvoc/v3.json +43 -2
@@ -1,8 +1,8 @@
1
1
  // FILE: src/plugins/hashline-edit/validation.ts
2
- // VERSION: 0.4.0
2
+ // VERSION: 0.5.0
3
3
  // START_MODULE_CONTRACT
4
4
  // PURPOSE: Parse and validate hashline references with optional context-anchored hashes against the current file snapshot before edits are applied.
5
- // SCOPE: Anchor normalization, line reference parsing with optional anchor hash, full-batch validation with anchor-hash verification, and mismatch diagnostics for current hashline anchors.
5
+ // SCOPE: Anchor normalization, line reference parsing with optional anchor hash, mandatory three-part edit reference enforcement, full-batch validation with anchor-hash verification, and mismatch diagnostics for current hashline anchors.
6
6
  // DEPENDS: [src/plugins/hashline-edit/constants.ts, src/plugins/hashline-edit/hash-computation.ts]
7
7
  // LINKS: [M-PLUGIN-HASHLINE-EDIT]
8
8
  // ROLE: RUNTIME
@@ -13,13 +13,14 @@
13
13
  // LineRef - Parsed `{ line, hash, anchorHash? }` structure for a normalized hashline anchor.
14
14
  // normalizeLineRef - Strip copied prefixes and inline content from a raw anchor string.
15
15
  // parseLineRef - Parse a normalized hashline anchor and fail loudly on malformed references.
16
+ // requireThreePartRef - Parse an edit anchor and reject two-part references missing the anchor hash.
16
17
  // validateLineRef - Validate a single anchor against the current file lines including context-anchored hash.
17
18
  // validateLineRefs - Validate a batch of anchors and aggregate mismatches.
18
19
  // HashlineMismatchError - Rich mismatch error that includes updated surrounding anchors.
19
20
  // END_MODULE_MAP
20
21
  //
21
22
  // START_CHANGE_SUMMARY
22
- // LAST_CHANGE: [v0.4.0 - Removed old hash compatibility fallback so validation accepts only current line and context hashes.]
23
+ // LAST_CHANGE: [v0.5.0 - Added requireThreePartRef so edit anchors must carry the full line#hash#anchor triple.]
23
24
  // END_CHANGE_SUMMARY
24
25
  import { HASHLINE_REF_PATTERN } from "./constants.js";
25
26
  import { computeAnchorHash, computeLineHash } from "./hash-computation.js";
@@ -77,6 +78,15 @@ export function parseLineRef(ref) {
77
78
  }
78
79
  throw new Error(`Invalid line reference format: "${ref}". Expected format: "{line_number}#{hash_id}" or "{line_number}#{hash_id}#{anchor_hash}"`);
79
80
  }
81
+ export function requireThreePartRef(ref, context) {
82
+ const parsed = parseLineRefWithHint(ref, []);
83
+ if (!parsed.anchorHash) {
84
+ throw new Error(`${context}: anchor "${ref}" is missing the anchor hash. Use the full three-part ` +
85
+ '"{line_number}#{hash_id}#{anchor_hash}" reference copied exactly from the latest read output. ' +
86
+ "Two-part references are no longer accepted for edits.");
87
+ }
88
+ return parsed;
89
+ }
80
90
  export class HashlineMismatchError extends Error {
81
91
  mismatches;
82
92
  fileLines;
@@ -1 +1 @@
1
- {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../../src/plugins/hashline-edit/validation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../../src/plugins/hashline-edit/validation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { type RetainTools } from "./retention.js";
2
+ import { DEFAULT_TOOL_HISTORY_COMPACTION_ENTRY } from "../../lib/plugin-toggle-config.js";
3
+ export interface ToolHistoryCompactionConfig {
4
+ /** Number of most recent completed tool calls (plus the last assistant message) never rewritten. */
5
+ protectLastCalls: number;
6
+ /** Minimum character savings for a rewrite to be applied; smaller rewrites are skipped. */
7
+ minSavingsChars: number;
8
+ /** Prune when output text exceeds this many code points; 0 disables pruning. */
9
+ outputMaxChars: number;
10
+ /** Leading code points retained when pruning. */
11
+ headChars: number;
12
+ /** Trailing code points retained when pruning. */
13
+ tailChars: number;
14
+ /** Replace old read outputs with a [Read <file>] header instead of pruning them. */
15
+ readSlim: boolean;
16
+ /** Tool names (case-insensitive substrings) whose outputs are never compacted. */
17
+ retainTools: RetainTools;
18
+ }
19
+ export interface ResolvedToolHistoryCompactionEntry {
20
+ enabled: boolean;
21
+ config: ToolHistoryCompactionConfig;
22
+ }
23
+ export { DEFAULT_TOOL_HISTORY_COMPACTION_ENTRY };
24
+ /** Resolve a partial config record against defaults, failing loudly on unknown keys or invalid values. */
25
+ export declare function resolveConfig(raw: unknown): ToolHistoryCompactionConfig;
26
+ /** Parse the plugins["tool-history-compaction"] boolean-or-object union. */
27
+ export declare function parseToolHistoryCompactionEntry(raw: unknown): ResolvedToolHistoryCompactionEntry;
28
+ export declare const DEFAULT_TOOL_HISTORY_COMPACTION: ToolHistoryCompactionConfig;
@@ -0,0 +1,133 @@
1
+ // FILE: src/plugins/tool-history-compaction/config.ts
2
+ // VERSION: 0.1.0
3
+ // START_MODULE_CONTRACT
4
+ // PURPOSE: Define strict tool-history-compaction configuration parsing, validation, and defaults.
5
+ // SCOPE: Config vocabulary, fail-loud validation of budgets and invariants, boolean-or-object plugin entry parsing, and the default materializable entry for vvoc sync.
6
+ // DEPENDS: [src/plugins/tool-history-compaction/retention.ts]
7
+ // LINKS: [M-PLUGIN-TOOL-HISTORY-COMPACTION]
8
+ // ROLE: RUNTIME
9
+ // MAP_MODE: EXPORTS
10
+ // END_MODULE_CONTRACT
11
+ //
12
+ // START_MODULE_MAP
13
+ // ToolHistoryCompactionConfig - Resolved immutable compaction settings.
14
+ // ResolvedToolHistoryCompactionEntry - Enabled flag plus resolved config from an entry.
15
+ // DEFAULT_TOOL_HISTORY_COMPACTION_ENTRY - Default vvoc materializable plugin entry.
16
+ // DEFAULT_TOOL_HISTORY_COMPACTION - Resolved default config.
17
+ // resolveConfig - Strictly resolve a partial config record against defaults.
18
+ // parseToolHistoryCompactionEntry - Strictly parse the plugins entry into enabled flag and config.
19
+ // END_MODULE_MAP
20
+ //
21
+ // START_CHANGE_SUMMARY
22
+ // LAST_CHANGE: [v0.1.0 - Established config parsing with DSH-style head/tail budgets, retention list, protected tail, and min-savings guard.]
23
+ // END_CHANGE_SUMMARY
24
+ import { PRUNE_MARKER } from "./prune.js";
25
+ import { DEFAULT_TOOL_HISTORY_COMPACTION_ENTRY } from "../../lib/plugin-toggle-config.js";
26
+ // END_BLOCK_VOCABULARY
27
+ // START_BLOCK_DEFAULTS
28
+ export { DEFAULT_TOOL_HISTORY_COMPACTION_ENTRY };
29
+ // END_BLOCK_DEFAULTS
30
+ // START_BLOCK_PARSE
31
+ function isRecord(value) {
32
+ return typeof value === "object" && value !== null && !Array.isArray(value);
33
+ }
34
+ const CONFIG_KEYS = new Set([
35
+ "protectLastCalls",
36
+ "minSavingsChars",
37
+ "outputMaxChars",
38
+ "headChars",
39
+ "tailChars",
40
+ "readSlim",
41
+ "retainTools",
42
+ ]);
43
+ function parseNonNegativeInt(raw, key) {
44
+ if (typeof raw !== "number" || !Number.isInteger(raw) || raw < 0) {
45
+ throw new Error(`tool-history-compaction: ${key} must be a non-negative integer; got ${JSON.stringify(raw)}`);
46
+ }
47
+ return raw;
48
+ }
49
+ function parseRetainTools(raw) {
50
+ if (!Array.isArray(raw)) {
51
+ throw new Error("tool-history-compaction: retainTools must be an array of non-empty strings");
52
+ }
53
+ for (const entry of raw) {
54
+ if (typeof entry !== "string" || entry.trim().length === 0) {
55
+ throw new Error("tool-history-compaction: retainTools entries must be non-empty strings");
56
+ }
57
+ }
58
+ return [...raw];
59
+ }
60
+ function assertBudgetsFit(config) {
61
+ if (config.outputMaxChars > 0) {
62
+ const required = config.headChars + config.tailChars + PRUNE_MARKER.length;
63
+ if (required > config.outputMaxChars) {
64
+ throw new Error(`tool-history-compaction: headChars + tailChars + marker (${required}) must fit within outputMaxChars (${config.outputMaxChars})`);
65
+ }
66
+ }
67
+ }
68
+ /** Resolve a partial config record against defaults, failing loudly on unknown keys or invalid values. */
69
+ export function resolveConfig(raw) {
70
+ if (raw === undefined || raw === null) {
71
+ return { ...DEFAULT_TOOL_HISTORY_COMPACTION };
72
+ }
73
+ if (!isRecord(raw)) {
74
+ throw new Error("tool-history-compaction: config must be an object");
75
+ }
76
+ for (const key of Object.keys(raw)) {
77
+ if (!CONFIG_KEYS.has(key)) {
78
+ throw new Error(`tool-history-compaction: unknown config key "${key}"`);
79
+ }
80
+ }
81
+ const readSlim = raw.readSlim === undefined ? DEFAULT_TOOL_HISTORY_COMPACTION.readSlim : raw.readSlim;
82
+ if (typeof readSlim !== "boolean") {
83
+ throw new Error(`tool-history-compaction: readSlim must be a boolean; got ${JSON.stringify(raw.readSlim)}`);
84
+ }
85
+ const resolved = {
86
+ protectLastCalls: raw.protectLastCalls === undefined
87
+ ? DEFAULT_TOOL_HISTORY_COMPACTION.protectLastCalls
88
+ : parseNonNegativeInt(raw.protectLastCalls, "protectLastCalls"),
89
+ minSavingsChars: raw.minSavingsChars === undefined
90
+ ? DEFAULT_TOOL_HISTORY_COMPACTION.minSavingsChars
91
+ : parseNonNegativeInt(raw.minSavingsChars, "minSavingsChars"),
92
+ outputMaxChars: raw.outputMaxChars === undefined
93
+ ? DEFAULT_TOOL_HISTORY_COMPACTION.outputMaxChars
94
+ : parseNonNegativeInt(raw.outputMaxChars, "outputMaxChars"),
95
+ headChars: raw.headChars === undefined
96
+ ? DEFAULT_TOOL_HISTORY_COMPACTION.headChars
97
+ : parseNonNegativeInt(raw.headChars, "headChars"),
98
+ tailChars: raw.tailChars === undefined
99
+ ? DEFAULT_TOOL_HISTORY_COMPACTION.tailChars
100
+ : parseNonNegativeInt(raw.tailChars, "tailChars"),
101
+ readSlim,
102
+ retainTools: raw.retainTools === undefined
103
+ ? [...DEFAULT_TOOL_HISTORY_COMPACTION.retainTools]
104
+ : parseRetainTools(raw.retainTools),
105
+ };
106
+ assertBudgetsFit(resolved);
107
+ return resolved;
108
+ }
109
+ /** Parse the plugins["tool-history-compaction"] boolean-or-object union. */
110
+ export function parseToolHistoryCompactionEntry(raw) {
111
+ if (raw === undefined || raw === null) {
112
+ return { enabled: true, config: { ...DEFAULT_TOOL_HISTORY_COMPACTION } };
113
+ }
114
+ if (typeof raw === "boolean") {
115
+ return { enabled: raw, config: { ...DEFAULT_TOOL_HISTORY_COMPACTION } };
116
+ }
117
+ if (!isRecord(raw)) {
118
+ throw new Error('tool-history-compaction: plugins["tool-history-compaction"] must be a boolean or an object');
119
+ }
120
+ const enabled = raw.enabled === undefined ? true : raw.enabled;
121
+ if (typeof enabled !== "boolean") {
122
+ throw new Error("tool-history-compaction: enabled must be a boolean");
123
+ }
124
+ const { enabled: _ignored, ...configRaw } = raw;
125
+ return { enabled, config: resolveConfig(configRaw) };
126
+ }
127
+ // END_BLOCK_PARSE
128
+ // START_BLOCK_DEFAULT_RESOLVE
129
+ // Computed after resolveConfig so module-level initialization stays free of TDZ hazards.
130
+ const defaultConfig = Object.fromEntries(Object.entries(DEFAULT_TOOL_HISTORY_COMPACTION_ENTRY).filter(([key]) => key !== "enabled"));
131
+ export const DEFAULT_TOOL_HISTORY_COMPACTION = resolveConfig(defaultConfig);
132
+ // END_BLOCK_DEFAULT_RESOLVE
133
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/plugins/tool-history-compaction/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { type Plugin } from "@opencode-ai/plugin";
2
+ export declare const ToolHistoryCompactionPlugin: Plugin;
@@ -0,0 +1,35 @@
1
+ // FILE: src/plugins/tool-history-compaction/index.ts
2
+ // VERSION: 0.1.0
3
+ // START_MODULE_CONTRACT
4
+ // PURPOSE: Register the tool-history-compaction plugin: load vvoc config, gate on the enabled toggle, and rewrite only the in-memory message copy the model is about to receive via experimental.chat.messages.transform.
5
+ // SCOPE: Plugin entry point, config loading, transform hook registration, and disabled no-op.
6
+ // DEPENDS: [@opencode-ai/plugin, src/lib/config-layers.ts, src/plugins/tool-history-compaction/config.ts, src/plugins/tool-history-compaction/transform.ts]
7
+ // LINKS: [M-PLUGIN-TOOL-HISTORY-COMPACTION]
8
+ // ROLE: RUNTIME
9
+ // MAP_MODE: EXPORTS
10
+ // END_MODULE_CONTRACT
11
+ //
12
+ // START_MODULE_MAP
13
+ // ToolHistoryCompactionPlugin - OpenCode plugin that compacts old tool outputs in the replay without touching storage or inputs.
14
+ // END_MODULE_MAP
15
+ //
16
+ // START_CHANGE_SUMMARY
17
+ // LAST_CHANGE: [v0.1.0 - Established the transform-only compaction plugin with retention classification and DSH-style pruning.]
18
+ // END_CHANGE_SUMMARY
19
+ import { loadVvocConfig } from "../../lib/config-layers.js";
20
+ import { parseToolHistoryCompactionEntry } from "./config.js";
21
+ import { compactMessages } from "./transform.js";
22
+ // START_BLOCK_PLUGIN
23
+ export const ToolHistoryCompactionPlugin = async ({ directory }) => {
24
+ const vvoc = await loadVvocConfig({ cwd: directory });
25
+ const entry = parseToolHistoryCompactionEntry(vvoc.config.plugins?.["tool-history-compaction"]);
26
+ if (!entry.enabled)
27
+ return {};
28
+ return {
29
+ "experimental.chat.messages.transform": async (_input, output) => {
30
+ compactMessages(output.messages, entry.config);
31
+ },
32
+ };
33
+ };
34
+ // END_BLOCK_PLUGIN
35
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/plugins/tool-history-compaction/index.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,iBAAiB;AACjB,wBAAwB;AACxB,4NAA4N;AAC5N,gGAAgG;AAChG,8JAA8J;AAC9J,8CAA8C;AAC9C,kBAAkB;AAClB,sBAAsB;AACtB,sBAAsB;AACtB,EAAE;AACF,mBAAmB;AACnB,mIAAmI;AACnI,iBAAiB;AACjB,EAAE;AACF,uBAAuB;AACvB,kIAAkI;AAClI,qBAAqB;AAGrB,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,+BAA+B,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,qBAAqB;AACrB,MAAM,CAAC,MAAM,2BAA2B,GAAW,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;IACzE,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC;IACtD,MAAM,KAAK,GAAG,+BAA+B,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,yBAAyB,CAAC,CAAC,CAAC;IAChG,IAAI,CAAC,KAAK,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IAE9B,OAAO;QACL,sCAAsC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YAC/D,eAAe,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QACjD,CAAC;KACF,CAAC;AACJ,CAAC,CAAC;AACF,mBAAmB"}
@@ -0,0 +1,22 @@
1
+ import type { ToolHistoryCompactionConfig } from "./config.js";
2
+ /** Fixed marker substituted for every pruned output middle. */
3
+ export declare const PRUNE_MARKER = "[... tool output pruned ...]";
4
+ /** Count Unicode code points without splitting surrogate pairs. */
5
+ export declare function countCodePoints(text: string): number;
6
+ /** Slice text by code points, never splitting a surrogate pair. */
7
+ export declare function codePointSlice(text: string, start: number, end: number): string;
8
+ /** Whether text already carries the prune marker (previous compaction pass). */
9
+ export declare function alreadyCompacted(text: string): boolean;
10
+ export interface PruneResult {
11
+ output: string;
12
+ savings: number;
13
+ }
14
+ /**
15
+ * Prune an over-budget output to head + marker + tail.
16
+ * Returns null when the output is ineligible: non-string, pruning disabled,
17
+ * under threshold, already compacted, or savings below minSavingsChars.
18
+ * @param text - tool output text.
19
+ * @param config - resolved compaction config.
20
+ * @returns pruned form or null.
21
+ */
22
+ export declare function pruneOutput(text: string, config: ToolHistoryCompactionConfig): PruneResult | null;
@@ -0,0 +1,70 @@
1
+ // FILE: src/plugins/tool-history-compaction/prune.ts
2
+ // VERSION: 0.1.0
3
+ // START_MODULE_CONTRACT
4
+ // PURPOSE: Deterministic head/marker/tail pruning of over-budget tool outputs with code-point-safe slicing, min-savings guard, and marker-based idempotence.
5
+ // SCOPE: Code-point counting and slicing, the fixed prune marker, the prune decision function, and already-compacted detection.
6
+ // DEPENDS: [src/plugins/tool-history-compaction/config.ts]
7
+ // LINKS: [M-PLUGIN-TOOL-HISTORY-COMPACTION]
8
+ // ROLE: RUNTIME
9
+ // MAP_MODE: EXPORTS
10
+ // END_MODULE_CONTRACT
11
+ //
12
+ // START_MODULE_MAP
13
+ // PRUNE_MARKER - Fixed marker substituted for every pruned output middle.
14
+ // countCodePoints - Unicode code-point count without splitting surrogate pairs.
15
+ // codePointSlice - Slice text by code points.
16
+ // pruneOutput - Return the pruned form when eligible, otherwise null.
17
+ // alreadyCompacted - Whether text already carries the prune marker.
18
+ // PruneResult - Pruned output plus measured savings.
19
+ // END_MODULE_MAP
20
+ //
21
+ // START_CHANGE_SUMMARY
22
+ // LAST_CHANGE: [v0.1.0 - Established the DSH-style head/marker/tail prune engine.]
23
+ // END_CHANGE_SUMMARY
24
+ // START_BLOCK_CONSTANTS
25
+ /** Fixed marker substituted for every pruned output middle. */
26
+ export const PRUNE_MARKER = "[... tool output pruned ...]";
27
+ // END_BLOCK_CONSTANTS
28
+ // START_BLOCK_MEASURE
29
+ /** Count Unicode code points without splitting surrogate pairs. */
30
+ export function countCodePoints(text) {
31
+ return Array.from(text).length;
32
+ }
33
+ /** Slice text by code points, never splitting a surrogate pair. */
34
+ export function codePointSlice(text, start, end) {
35
+ return Array.from(text).slice(start, end).join("");
36
+ }
37
+ // END_BLOCK_MEASURE
38
+ // START_BLOCK_DETECT
39
+ /** Whether text already carries the prune marker (previous compaction pass). */
40
+ export function alreadyCompacted(text) {
41
+ return typeof text === "string" && text.includes(PRUNE_MARKER);
42
+ }
43
+ /**
44
+ * Prune an over-budget output to head + marker + tail.
45
+ * Returns null when the output is ineligible: non-string, pruning disabled,
46
+ * under threshold, already compacted, or savings below minSavingsChars.
47
+ * @param text - tool output text.
48
+ * @param config - resolved compaction config.
49
+ * @returns pruned form or null.
50
+ */
51
+ export function pruneOutput(text, config) {
52
+ if (typeof text !== "string" || text.length === 0)
53
+ return null;
54
+ if (config.outputMaxChars <= 0)
55
+ return null;
56
+ if (alreadyCompacted(text))
57
+ return null;
58
+ const length = countCodePoints(text);
59
+ if (length <= config.outputMaxChars)
60
+ return null;
61
+ const head = codePointSlice(text, 0, config.headChars);
62
+ const tail = codePointSlice(text, length - config.tailChars, length);
63
+ const output = head + PRUNE_MARKER + tail;
64
+ const savings = length - countCodePoints(output);
65
+ if (savings < config.minSavingsChars)
66
+ return null;
67
+ return { output, savings };
68
+ }
69
+ // END_BLOCK_PRUNE
70
+ //# sourceMappingURL=prune.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prune.js","sourceRoot":"","sources":["../../../src/plugins/tool-history-compaction/prune.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,iBAAiB;AACjB,wBAAwB;AACxB,+JAA+J;AAC/J,kIAAkI;AAClI,6DAA6D;AAC7D,8CAA8C;AAC9C,kBAAkB;AAClB,sBAAsB;AACtB,sBAAsB;AACtB,EAAE;AACF,mBAAmB;AACnB,4EAA4E;AAC5E,kFAAkF;AAClF,gDAAgD;AAChD,wEAAwE;AACxE,sEAAsE;AACtE,uDAAuD;AACvD,iBAAiB;AACjB,EAAE;AACF,uBAAuB;AACvB,qFAAqF;AACrF,qBAAqB;AAIrB,wBAAwB;AACxB,+DAA+D;AAC/D,MAAM,CAAC,MAAM,YAAY,GAAG,8BAA8B,CAAC;AAC3D,sBAAsB;AAEtB,sBAAsB;AACtB,mEAAmE;AACnE,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;AACjC,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,KAAa,EAAE,GAAW;IACrE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACrD,CAAC;AACD,oBAAoB;AAEpB,qBAAqB;AACrB,gFAAgF;AAChF,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;AACjE,CAAC;AASD;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,MAAmC;IAC3E,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/D,IAAI,MAAM,CAAC,cAAc,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,IAAI,gBAAgB,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAExC,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,MAAM,IAAI,MAAM,CAAC,cAAc;QAAE,OAAO,IAAI,CAAC;IAEjD,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IACvD,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACrE,MAAM,MAAM,GAAG,IAAI,GAAG,YAAY,GAAG,IAAI,CAAC;IAC1C,MAAM,OAAO,GAAG,MAAM,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IACjD,IAAI,OAAO,GAAG,MAAM,CAAC,eAAe;QAAE,OAAO,IAAI,CAAC;IAElD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AAC7B,CAAC;AACD,kBAAkB"}
@@ -0,0 +1,27 @@
1
+ import type { ToolHistoryCompactionConfig } from "./config.js";
2
+ export interface ReadInputLike {
3
+ filePath?: unknown;
4
+ path?: unknown;
5
+ file?: unknown;
6
+ }
7
+ /** Recover the file path from read input aliases; unknown values yield undefined. */
8
+ export declare function fileFromReadInput(input: ReadInputLike | undefined): string | undefined;
9
+ /**
10
+ * Recover the covered line range ("first-last") from a line-numbered output.
11
+ * Returns undefined when the output is not deterministically line-numbered.
12
+ */
13
+ export declare function rangeFromReadOutput(output: string | undefined): string | undefined;
14
+ export interface SlimReadResult {
15
+ output: string;
16
+ savings: number;
17
+ }
18
+ /**
19
+ * Collapse an old read output to [Read <file>, lines X-Y] when the file is
20
+ * recoverable and the savings clear the min-savings guard. Returns null when
21
+ * not applicable; the caller falls back to output pruning (never fabricates).
22
+ * @param input - part.state.input.
23
+ * @param output - part.state.output.
24
+ * @param config - resolved compaction config.
25
+ * @returns slim form or null.
26
+ */
27
+ export declare function slimReadOutput(input: unknown, output: unknown, config: ToolHistoryCompactionConfig): SlimReadResult | null;
@@ -0,0 +1,91 @@
1
+ // FILE: src/plugins/tool-history-compaction/read-slim.ts
2
+ // VERSION: 0.1.0
3
+ // START_MODULE_CONTRACT
4
+ // PURPOSE: Collapse old read tool outputs to a compact [Read <file>, lines X-Y] header, recovering the file from the input and the line range from the output when deterministically available.
5
+ // SCOPE: Read input file extraction, line-numbered output range recovery, savings-gated slim decision, and idempotence detection.
6
+ // DEPENDS: [src/plugins/tool-history-compaction/config.ts]
7
+ // LINKS: [M-PLUGIN-TOOL-HISTORY-COMPACTION]
8
+ // ROLE: RUNTIME
9
+ // MAP_MODE: EXPORTS
10
+ // END_MODULE_CONTRACT
11
+ //
12
+ // START_MODULE_MAP
13
+ // fileFromReadInput - Recover the file path from read input aliases.
14
+ // ReadInputLike - Read input object with filePath/path/file aliases.
15
+ // rangeFromReadOutput - Recover the covered line range from a line-numbered output.
16
+ // slimReadOutput - Return the [Read <file>] form when eligible, otherwise null (fallback to pruning).
17
+ // SlimReadResult - Slim form plus measured savings.
18
+ // END_MODULE_MAP
19
+ //
20
+ // START_CHANGE_SUMMARY
21
+ // LAST_CHANGE: [v0.1.0 - Established old-read collapse with fail-closed fallback.]
22
+ // END_CHANGE_SUMMARY
23
+ import { countCodePoints } from "./prune.js";
24
+ // START_BLOCK_RANGE
25
+ // Matches a line-numbered output line: OpenCode "N| content" / "N: content"
26
+ // and hashline anchored "N#ID#ANCHOR|content". Never fabricates a number.
27
+ const LINE_NUMBER_PREFIX = /^\s*(\d+)(?:#[^|:]*)?(?:\||:)/;
28
+ /** Recover the file path from read input aliases; unknown values yield undefined. */
29
+ export function fileFromReadInput(input) {
30
+ if (!input || typeof input !== "object")
31
+ return undefined;
32
+ for (const key of ["filePath", "path", "file"]) {
33
+ const value = input[key];
34
+ if (typeof value === "string" && value.length > 0)
35
+ return value;
36
+ }
37
+ return undefined;
38
+ }
39
+ // END_BLOCK_FILE
40
+ // START_BLOCK_RANGE_FN
41
+ /**
42
+ * Recover the covered line range ("first-last") from a line-numbered output.
43
+ * Returns undefined when the output is not deterministically line-numbered.
44
+ */
45
+ export function rangeFromReadOutput(output) {
46
+ if (typeof output !== "string" || output.length === 0)
47
+ return undefined;
48
+ let first;
49
+ let last;
50
+ for (const line of output.split("\n")) {
51
+ const match = LINE_NUMBER_PREFIX.exec(line);
52
+ if (match) {
53
+ const number = Number.parseInt(match[1] ?? "0", 10);
54
+ if (first === undefined)
55
+ first = number;
56
+ last = number;
57
+ }
58
+ }
59
+ if (first === undefined || last === undefined || first > last)
60
+ return undefined;
61
+ return `${first}-${last}`;
62
+ }
63
+ function alreadySlimmed(output) {
64
+ return output.startsWith("[Read ");
65
+ }
66
+ /**
67
+ * Collapse an old read output to [Read <file>, lines X-Y] when the file is
68
+ * recoverable and the savings clear the min-savings guard. Returns null when
69
+ * not applicable; the caller falls back to output pruning (never fabricates).
70
+ * @param input - part.state.input.
71
+ * @param output - part.state.output.
72
+ * @param config - resolved compaction config.
73
+ * @returns slim form or null.
74
+ */
75
+ export function slimReadOutput(input, output, config) {
76
+ if (typeof output !== "string" || output.length === 0)
77
+ return null;
78
+ if (alreadySlimmed(output))
79
+ return null;
80
+ const file = fileFromReadInput(input);
81
+ if (file === undefined)
82
+ return null;
83
+ const range = rangeFromReadOutput(output);
84
+ const slim = range === undefined ? `[Read ${file}]` : `[Read ${file}, lines ${range}]`;
85
+ const savings = countCodePoints(output) - countCodePoints(slim);
86
+ if (savings < config.minSavingsChars)
87
+ return null;
88
+ return { output: slim, savings };
89
+ }
90
+ // END_BLOCK_SLIM
91
+ //# sourceMappingURL=read-slim.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-slim.js","sourceRoot":"","sources":["../../../src/plugins/tool-history-compaction/read-slim.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,iBAAiB;AACjB,wBAAwB;AACxB,kMAAkM;AAClM,oIAAoI;AACpI,6DAA6D;AAC7D,8CAA8C;AAC9C,kBAAkB;AAClB,sBAAsB;AACtB,sBAAsB;AACtB,EAAE;AACF,mBAAmB;AACnB,uEAAuE;AACvE,uEAAuE;AACvE,sFAAsF;AACtF,wGAAwG;AACxG,sDAAsD;AACtD,iBAAiB;AACjB,EAAE;AACF,uBAAuB;AACvB,qFAAqF;AACrF,qBAAqB;AAGrB,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,oBAAoB;AACpB,4EAA4E;AAC5E,0EAA0E;AAC1E,MAAM,kBAAkB,GAAG,+BAA+B,CAAC;AAU3D,qFAAqF;AACrF,MAAM,UAAU,iBAAiB,CAAC,KAAgC;IAChE,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAC1D,KAAK,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAU,EAAE,CAAC;QACxD,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QACzB,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;IAClE,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AACD,iBAAiB;AAEjB,uBAAuB;AACvB;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAA0B;IAC5D,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACxE,IAAI,KAAyB,CAAC;IAC9B,IAAI,IAAwB,CAAC;IAC7B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;YACpD,IAAI,KAAK,KAAK,SAAS;gBAAE,KAAK,GAAG,MAAM,CAAC;YACxC,IAAI,GAAG,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IACD,IAAI,KAAK,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,IAAI,KAAK,GAAG,IAAI;QAAE,OAAO,SAAS,CAAC;IAChF,OAAO,GAAG,KAAK,IAAI,IAAI,EAAE,CAAC;AAC5B,CAAC;AASD,SAAS,cAAc,CAAC,MAAc;IACpC,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;AACrC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAC5B,KAAc,EACd,MAAe,EACf,MAAmC;IAEnC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACnE,IAAI,cAAc,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IAExC,MAAM,IAAI,GAAG,iBAAiB,CAAC,KAAkC,CAAC,CAAC;IACnE,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAEpC,MAAM,KAAK,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,IAAI,GAAG,CAAC,CAAC,CAAC,SAAS,IAAI,WAAW,KAAK,GAAG,CAAC;IACvF,MAAM,OAAO,GAAG,eAAe,CAAC,MAAM,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IAChE,IAAI,OAAO,GAAG,MAAM,CAAC,eAAe;QAAE,OAAO,IAAI,CAAC;IAElD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AACnC,CAAC;AACD,iBAAiB"}
@@ -0,0 +1,10 @@
1
+ /** Knowledge-tool substrings: results that stay relevant for the whole session. */
2
+ export declare const DEFAULT_RETAIN_TOOLS: readonly string[];
3
+ export type RetainTools = readonly string[];
4
+ /**
5
+ * Whether a tool name matches any retain substring, case-insensitively.
6
+ * @param tool - tool name from a message part.
7
+ * @param retainTools - configured retain substrings.
8
+ * @returns true when the tool output must never be compacted.
9
+ */
10
+ export declare function isRetainedTool(tool: string | undefined, retainTools: RetainTools): boolean;
@@ -0,0 +1,45 @@
1
+ // FILE: src/plugins/tool-history-compaction/retention.ts
2
+ // VERSION: 0.1.0
3
+ // START_MODULE_CONTRACT
4
+ // PURPOSE: Classify tool outputs into knowledge (retained) versus ephemeral (compaction-eligible) by case-insensitive substring matching on the tool name.
5
+ // SCOPE: The pure isRetainedTool predicate; the default retention list is re-exported from the shared lib table.
6
+ // DEPENDS: [src/lib/plugin-toggle-config.ts]
7
+ // LINKS: [M-PLUGIN-TOOL-HISTORY-COMPACTION]
8
+ // ROLE: RUNTIME
9
+ // MAP_MODE: EXPORTS
10
+ // END_MODULE_CONTRACT
11
+ //
12
+ // START_MODULE_MAP
13
+ // DEFAULT_RETAIN_TOOLS - Default knowledge-tool substrings (re-exported from the shared lib table).
14
+ // RetainTools - Readonly array of case-insensitive tool-name substrings.
15
+ // isRetainedTool - Whether a tool name matches any retain substring.
16
+ // END_MODULE_MAP
17
+ //
18
+ // START_CHANGE_SUMMARY
19
+ // LAST_CHANGE: [v0.1.0 - Established the knowledge-versus-ephemeral retention classification; defaults owned by the shared lib table.]
20
+ // END_CHANGE_SUMMARY
21
+ import { DEFAULT_TOOL_HISTORY_COMPACTION_RETAIN_TOOLS } from "../../lib/plugin-toggle-config.js";
22
+ // START_BLOCK_DEFAULTS
23
+ /** Knowledge-tool substrings: results that stay relevant for the whole session. */
24
+ export const DEFAULT_RETAIN_TOOLS = DEFAULT_TOOL_HISTORY_COMPACTION_RETAIN_TOOLS;
25
+ // END_BLOCK_DEFAULTS
26
+ // START_BLOCK_MATCH
27
+ /**
28
+ * Whether a tool name matches any retain substring, case-insensitively.
29
+ * @param tool - tool name from a message part.
30
+ * @param retainTools - configured retain substrings.
31
+ * @returns true when the tool output must never be compacted.
32
+ */
33
+ export function isRetainedTool(tool, retainTools) {
34
+ if (typeof tool !== "string" || tool.length === 0)
35
+ return false;
36
+ const lower = tool.toLowerCase();
37
+ for (const pattern of retainTools) {
38
+ if (pattern.length > 0 && lower.includes(pattern.toLowerCase())) {
39
+ return true;
40
+ }
41
+ }
42
+ return false;
43
+ }
44
+ // END_BLOCK_MATCH
45
+ //# sourceMappingURL=retention.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retention.js","sourceRoot":"","sources":["../../../src/plugins/tool-history-compaction/retention.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,iBAAiB;AACjB,wBAAwB;AACxB,6JAA6J;AAC7J,mHAAmH;AACnH,+CAA+C;AAC/C,8CAA8C;AAC9C,kBAAkB;AAClB,sBAAsB;AACtB,sBAAsB;AACtB,EAAE;AACF,mBAAmB;AACnB,sGAAsG;AACtG,2EAA2E;AAC3E,uEAAuE;AACvE,iBAAiB;AACjB,EAAE;AACF,uBAAuB;AACvB,yIAAyI;AACzI,qBAAqB;AACrB,OAAO,EAAE,4CAA4C,EAAE,MAAM,mCAAmC,CAAC;AAEjG,uBAAuB;AACvB,mFAAmF;AACnF,MAAM,CAAC,MAAM,oBAAoB,GAAsB,4CAA4C,CAAC;AAIpG,qBAAqB;AAErB,oBAAoB;AACpB;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,IAAwB,EAAE,WAAwB;IAC/E,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAChE,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,KAAK,MAAM,OAAO,IAAI,WAAW,EAAE,CAAC;QAClC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;YAChE,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AACD,kBAAkB"}
@@ -0,0 +1,15 @@
1
+ import type { Part } from "@opencode-ai/sdk";
2
+ import type { ToolHistoryCompactionConfig } from "./config.js";
3
+ export interface TransformMessage {
4
+ info: unknown;
5
+ parts: Part[];
6
+ }
7
+ /**
8
+ * Deterministically rewrite eligible tool part outputs in place.
9
+ * Model-agnostic: the current model is not needed. Non-destructive to inputs,
10
+ * part structure, and ordering. Idempotent: already-compacted parts are skipped
11
+ * by their markers, so a second pass is a no-op.
12
+ * @param messages - the transform hook's in-memory message list.
13
+ * @param config - resolved compaction config.
14
+ */
15
+ export declare function compactMessages(messages: TransformMessage[], config: ToolHistoryCompactionConfig): void;