@tuanhung303/opencode-acp 0.0.1

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 (159) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +166 -0
  3. package/dist/index.d.ts +4 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +79 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/lib/commands/budget.d.ts +15 -0
  8. package/dist/lib/commands/budget.d.ts.map +1 -0
  9. package/dist/lib/commands/budget.js +120 -0
  10. package/dist/lib/commands/budget.js.map +1 -0
  11. package/dist/lib/commands/context.d.ts +49 -0
  12. package/dist/lib/commands/context.d.ts.map +1 -0
  13. package/dist/lib/commands/context.js +191 -0
  14. package/dist/lib/commands/context.js.map +1 -0
  15. package/dist/lib/commands/help.d.ts +15 -0
  16. package/dist/lib/commands/help.d.ts.map +1 -0
  17. package/dist/lib/commands/help.js +28 -0
  18. package/dist/lib/commands/help.js.map +1 -0
  19. package/dist/lib/commands/protected.d.ts +17 -0
  20. package/dist/lib/commands/protected.d.ts.map +1 -0
  21. package/dist/lib/commands/protected.js +50 -0
  22. package/dist/lib/commands/protected.js.map +1 -0
  23. package/dist/lib/commands/stats.d.ts +15 -0
  24. package/dist/lib/commands/stats.d.ts.map +1 -0
  25. package/dist/lib/commands/stats.js +64 -0
  26. package/dist/lib/commands/stats.js.map +1 -0
  27. package/dist/lib/commands/sweep.d.ts +23 -0
  28. package/dist/lib/commands/sweep.d.ts.map +1 -0
  29. package/dist/lib/commands/sweep.js +194 -0
  30. package/dist/lib/commands/sweep.js.map +1 -0
  31. package/dist/lib/config-schema.d.ts +119 -0
  32. package/dist/lib/config-schema.d.ts.map +1 -0
  33. package/dist/lib/config-schema.js +97 -0
  34. package/dist/lib/config-schema.js.map +1 -0
  35. package/dist/lib/config.d.ts +59 -0
  36. package/dist/lib/config.d.ts.map +1 -0
  37. package/dist/lib/config.js +426 -0
  38. package/dist/lib/config.js.map +1 -0
  39. package/dist/lib/hooks.d.ts +31 -0
  40. package/dist/lib/hooks.d.ts.map +1 -0
  41. package/dist/lib/hooks.js +230 -0
  42. package/dist/lib/hooks.js.map +1 -0
  43. package/dist/lib/logger.d.ts +55 -0
  44. package/dist/lib/logger.d.ts.map +1 -0
  45. package/dist/lib/logger.js +230 -0
  46. package/dist/lib/logger.js.map +1 -0
  47. package/dist/lib/messages/index.d.ts +3 -0
  48. package/dist/lib/messages/index.d.ts.map +1 -0
  49. package/dist/lib/messages/index.js +3 -0
  50. package/dist/lib/messages/index.js.map +1 -0
  51. package/dist/lib/messages/inject.d.ts +10 -0
  52. package/dist/lib/messages/inject.d.ts.map +1 -0
  53. package/dist/lib/messages/inject.js +10 -0
  54. package/dist/lib/messages/inject.js.map +1 -0
  55. package/dist/lib/messages/prune.d.ts +13 -0
  56. package/dist/lib/messages/prune.d.ts.map +1 -0
  57. package/dist/lib/messages/prune.js +173 -0
  58. package/dist/lib/messages/prune.js.map +1 -0
  59. package/dist/lib/messages/utils.d.ts +43 -0
  60. package/dist/lib/messages/utils.d.ts.map +1 -0
  61. package/dist/lib/messages/utils.js +262 -0
  62. package/dist/lib/messages/utils.js.map +1 -0
  63. package/dist/lib/prompts/discard-tool-spec.d.ts +2 -0
  64. package/dist/lib/prompts/discard-tool-spec.d.ts.map +1 -0
  65. package/dist/lib/prompts/discard-tool-spec.js +54 -0
  66. package/dist/lib/prompts/discard-tool-spec.js.map +1 -0
  67. package/dist/lib/prompts/extract-tool-spec.d.ts +2 -0
  68. package/dist/lib/prompts/extract-tool-spec.d.ts.map +1 -0
  69. package/dist/lib/prompts/extract-tool-spec.js +56 -0
  70. package/dist/lib/prompts/extract-tool-spec.js.map +1 -0
  71. package/dist/lib/prompts/index.d.ts +2 -0
  72. package/dist/lib/prompts/index.d.ts.map +1 -0
  73. package/dist/lib/prompts/index.js +29 -0
  74. package/dist/lib/prompts/index.js.map +1 -0
  75. package/dist/lib/prompts/restore-tool-spec.d.ts +2 -0
  76. package/dist/lib/prompts/restore-tool-spec.d.ts.map +1 -0
  77. package/dist/lib/prompts/restore-tool-spec.js +37 -0
  78. package/dist/lib/prompts/restore-tool-spec.js.map +1 -0
  79. package/dist/lib/prompts/system/both.d.ts +2 -0
  80. package/dist/lib/prompts/system/both.d.ts.map +1 -0
  81. package/dist/lib/prompts/system/both.js +65 -0
  82. package/dist/lib/prompts/system/both.js.map +1 -0
  83. package/dist/lib/prompts/system/discard.d.ts +2 -0
  84. package/dist/lib/prompts/system/discard.d.ts.map +1 -0
  85. package/dist/lib/prompts/system/discard.js +55 -0
  86. package/dist/lib/prompts/system/discard.js.map +1 -0
  87. package/dist/lib/prompts/system/extract.d.ts +2 -0
  88. package/dist/lib/prompts/system/extract.d.ts.map +1 -0
  89. package/dist/lib/prompts/system/extract.js +55 -0
  90. package/dist/lib/prompts/system/extract.js.map +1 -0
  91. package/dist/lib/protected-file-patterns.d.ts +12 -0
  92. package/dist/lib/protected-file-patterns.d.ts.map +1 -0
  93. package/dist/lib/protected-file-patterns.js +69 -0
  94. package/dist/lib/protected-file-patterns.js.map +1 -0
  95. package/dist/lib/safe-execute.d.ts +20 -0
  96. package/dist/lib/safe-execute.d.ts.map +1 -0
  97. package/dist/lib/safe-execute.js +38 -0
  98. package/dist/lib/safe-execute.js.map +1 -0
  99. package/dist/lib/shared-utils.d.ts +4 -0
  100. package/dist/lib/shared-utils.d.ts.map +1 -0
  101. package/dist/lib/shared-utils.js +14 -0
  102. package/dist/lib/shared-utils.js.map +1 -0
  103. package/dist/lib/state/index.d.ts +4 -0
  104. package/dist/lib/state/index.d.ts.map +1 -0
  105. package/dist/lib/state/index.js +4 -0
  106. package/dist/lib/state/index.js.map +1 -0
  107. package/dist/lib/state/persistence.d.ts +27 -0
  108. package/dist/lib/state/persistence.d.ts.map +1 -0
  109. package/dist/lib/state/persistence.js +165 -0
  110. package/dist/lib/state/persistence.js.map +1 -0
  111. package/dist/lib/state/state.d.ts +8 -0
  112. package/dist/lib/state/state.d.ts.map +1 -0
  113. package/dist/lib/state/state.js +166 -0
  114. package/dist/lib/state/state.js.map +1 -0
  115. package/dist/lib/state/tool-cache.d.ts +15 -0
  116. package/dist/lib/state/tool-cache.d.ts.map +1 -0
  117. package/dist/lib/state/tool-cache.js +99 -0
  118. package/dist/lib/state/tool-cache.js.map +1 -0
  119. package/dist/lib/state/types.d.ts +83 -0
  120. package/dist/lib/state/types.d.ts.map +1 -0
  121. package/dist/lib/state/types.js +2 -0
  122. package/dist/lib/state/types.js.map +1 -0
  123. package/dist/lib/state/utils.d.ts +2 -0
  124. package/dist/lib/state/utils.d.ts.map +1 -0
  125. package/dist/lib/state/utils.js +10 -0
  126. package/dist/lib/state/utils.js.map +1 -0
  127. package/dist/lib/strategies/deduplication.d.ts +11 -0
  128. package/dist/lib/strategies/deduplication.d.ts.map +1 -0
  129. package/dist/lib/strategies/deduplication.js +178 -0
  130. package/dist/lib/strategies/deduplication.js.map +1 -0
  131. package/dist/lib/strategies/index.d.ts +5 -0
  132. package/dist/lib/strategies/index.d.ts.map +1 -0
  133. package/dist/lib/strategies/index.js +5 -0
  134. package/dist/lib/strategies/index.js.map +1 -0
  135. package/dist/lib/strategies/purge-errors.d.ts +13 -0
  136. package/dist/lib/strategies/purge-errors.d.ts.map +1 -0
  137. package/dist/lib/strategies/purge-errors.js +62 -0
  138. package/dist/lib/strategies/purge-errors.js.map +1 -0
  139. package/dist/lib/strategies/supersede-writes.d.ts +13 -0
  140. package/dist/lib/strategies/supersede-writes.d.ts.map +1 -0
  141. package/dist/lib/strategies/supersede-writes.js +90 -0
  142. package/dist/lib/strategies/supersede-writes.js.map +1 -0
  143. package/dist/lib/strategies/tools.d.ts +15 -0
  144. package/dist/lib/strategies/tools.d.ts.map +1 -0
  145. package/dist/lib/strategies/tools.js +288 -0
  146. package/dist/lib/strategies/tools.js.map +1 -0
  147. package/dist/lib/strategies/utils.d.ts +11 -0
  148. package/dist/lib/strategies/utils.d.ts.map +1 -0
  149. package/dist/lib/strategies/utils.js +75 -0
  150. package/dist/lib/strategies/utils.js.map +1 -0
  151. package/dist/lib/ui/notification.d.ts +12 -0
  152. package/dist/lib/ui/notification.d.ts.map +1 -0
  153. package/dist/lib/ui/notification.js +81 -0
  154. package/dist/lib/ui/notification.js.map +1 -0
  155. package/dist/lib/ui/utils.d.ts +10 -0
  156. package/dist/lib/ui/utils.d.ts.map +1 -0
  157. package/dist/lib/ui/utils.js +113 -0
  158. package/dist/lib/ui/utils.js.map +1 -0
  159. package/package.json +62 -0
@@ -0,0 +1,165 @@
1
+ /**
2
+ * State persistence module for ACP plugin.
3
+ * Persists pruned tool IDs across sessions so they survive OpenCode restarts.
4
+ * Storage location: ~/.local/share/opencode/storage/plugin/acp/{sessionId}.json
5
+ *
6
+ * Uses atomic writes (temp file + rename) to prevent data corruption.
7
+ */
8
+ import * as fs from "fs/promises";
9
+ import { existsSync } from "fs";
10
+ import { homedir } from "os";
11
+ import { join } from "path";
12
+ const STORAGE_DIR = join(homedir(), ".local", "share", "opencode", "storage", "plugin", "acp");
13
+ // Write lock to prevent concurrent writes to the same file
14
+ const writeLocks = new Map();
15
+ async function ensureStorageDir() {
16
+ if (!existsSync(STORAGE_DIR)) {
17
+ await fs.mkdir(STORAGE_DIR, { recursive: true });
18
+ }
19
+ }
20
+ function getSessionFilePath(sessionId) {
21
+ return join(STORAGE_DIR, `${sessionId}.json`);
22
+ }
23
+ /**
24
+ * Atomically write content to a file using temp file + rename pattern.
25
+ * This prevents data corruption from partial writes or crashes.
26
+ */
27
+ async function atomicWriteFile(filePath, content) {
28
+ const tempPath = `${filePath}.tmp`;
29
+ try {
30
+ // Write to temp file first
31
+ await fs.writeFile(tempPath, content, "utf-8");
32
+ // Atomic rename (on POSIX systems, rename is atomic)
33
+ await fs.rename(tempPath, filePath);
34
+ }
35
+ catch (error) {
36
+ // Clean up temp file on failure
37
+ try {
38
+ await fs.unlink(tempPath);
39
+ }
40
+ catch {
41
+ // Ignore cleanup errors
42
+ }
43
+ throw error;
44
+ }
45
+ }
46
+ /**
47
+ * Acquire a write lock for a specific file path.
48
+ * Ensures only one write operation happens at a time per file.
49
+ */
50
+ async function withWriteLock(filePath, fn) {
51
+ // Wait for any existing write to complete
52
+ const existingLock = writeLocks.get(filePath);
53
+ if (existingLock) {
54
+ await existingLock.catch(() => { }); // Ignore errors from previous writes
55
+ }
56
+ // Create new lock
57
+ let resolve;
58
+ const lockPromise = new Promise((r) => {
59
+ resolve = r;
60
+ });
61
+ writeLocks.set(filePath, lockPromise);
62
+ try {
63
+ return await fn();
64
+ }
65
+ finally {
66
+ resolve();
67
+ writeLocks.delete(filePath);
68
+ }
69
+ }
70
+ export async function saveSessionState(sessionState, logger, sessionName) {
71
+ try {
72
+ if (!sessionState.sessionId) {
73
+ return;
74
+ }
75
+ await ensureStorageDir();
76
+ const state = {
77
+ sessionName: sessionName,
78
+ prune: sessionState.prune,
79
+ stats: sessionState.stats,
80
+ lastUpdated: new Date().toISOString(),
81
+ // Hash-based discard system (convert Maps to objects)
82
+ hashToCallId: Object.fromEntries(sessionState.hashToCallId),
83
+ callIdToHash: Object.fromEntries(sessionState.callIdToHash),
84
+ discardHistory: sessionState.discardHistory,
85
+ };
86
+ const filePath = getSessionFilePath(sessionState.sessionId);
87
+ const content = JSON.stringify(state, null, 2);
88
+ // Use write lock and atomic write to prevent corruption
89
+ await withWriteLock(filePath, async () => {
90
+ await atomicWriteFile(filePath, content);
91
+ });
92
+ logger.info("Saved session state to disk", {
93
+ sessionId: sessionState.sessionId,
94
+ totalTokensSaved: state.stats.totalPruneTokens,
95
+ });
96
+ }
97
+ catch (error) {
98
+ logger.error("Failed to save session state", {
99
+ sessionId: sessionState.sessionId,
100
+ error: error?.message,
101
+ });
102
+ }
103
+ }
104
+ export async function loadSessionState(sessionId, logger) {
105
+ try {
106
+ const filePath = getSessionFilePath(sessionId);
107
+ if (!existsSync(filePath)) {
108
+ return null;
109
+ }
110
+ const content = await fs.readFile(filePath, "utf-8");
111
+ const state = JSON.parse(content);
112
+ if (!state || !state.prune || !Array.isArray(state.prune.toolIds) || !state.stats) {
113
+ logger.warn("Invalid session state file, ignoring", {
114
+ sessionId: sessionId,
115
+ });
116
+ return null;
117
+ }
118
+ logger.info("Loaded session state from disk", {
119
+ sessionId: sessionId,
120
+ });
121
+ return state;
122
+ }
123
+ catch (error) {
124
+ logger.warn("Failed to load session state", {
125
+ sessionId: sessionId,
126
+ error: error?.message,
127
+ });
128
+ return null;
129
+ }
130
+ }
131
+ export async function loadAllSessionStats(logger) {
132
+ const result = {
133
+ totalTokens: 0,
134
+ totalTools: 0,
135
+ sessionCount: 0,
136
+ };
137
+ try {
138
+ if (!existsSync(STORAGE_DIR)) {
139
+ return result;
140
+ }
141
+ const files = await fs.readdir(STORAGE_DIR);
142
+ const jsonFiles = files.filter((f) => f.endsWith(".json"));
143
+ for (const file of jsonFiles) {
144
+ try {
145
+ const filePath = join(STORAGE_DIR, file);
146
+ const content = await fs.readFile(filePath, "utf-8");
147
+ const state = JSON.parse(content);
148
+ if (state?.stats?.totalPruneTokens && state?.prune?.toolIds) {
149
+ result.totalTokens += state.stats.totalPruneTokens;
150
+ result.totalTools += state.prune.toolIds.length;
151
+ result.sessionCount++;
152
+ }
153
+ }
154
+ catch {
155
+ // Skip invalid files
156
+ }
157
+ }
158
+ logger.debug("Loaded all-time stats", result);
159
+ }
160
+ catch (error) {
161
+ logger.warn("Failed to load all-time stats", { error: error?.message });
162
+ }
163
+ return result;
164
+ }
165
+ //# sourceMappingURL=persistence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persistence.js","sourceRoot":"","sources":["../../../lib/state/persistence.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { SessionState, WithParts } from "./types";
2
+ import type { Logger } from "../logger";
3
+ export declare const checkSession: (client: any, state: SessionState, logger: Logger, messages: WithParts[]) => Promise<void>;
4
+ export declare function createSessionState(): SessionState;
5
+ export declare function resetSessionState(state: SessionState): void;
6
+ export declare function ensureSessionInitialized(client: any, state: SessionState, sessionId: string, logger: Logger, messages: WithParts[]): Promise<void>;
7
+ export declare function countTurns(state: SessionState, messages: WithParts[]): number;
8
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../lib/state/state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAsB,SAAS,EAAmB,MAAM,SAAS,CAAA;AAC3F,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAKvC,eAAO,MAAM,YAAY,GACrB,QAAQ,GAAG,EACX,OAAO,YAAY,EACnB,QAAQ,MAAM,EACd,UAAU,SAAS,EAAE,KACtB,OAAO,CAAC,IAAI,CA4Bd,CAAA;AAED,wBAAgB,kBAAkB,IAAI,YAAY,CAkCjD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAgC3D;AAED,wBAAsB,wBAAwB,CAC1C,MAAM,EAAE,GAAG,EACX,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,SAAS,EAAE,GACtB,OAAO,CAAC,IAAI,CAAC,CAiDf;AAYD,wBAAgB,UAAU,CAAC,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,MAAM,CAc7E"}
@@ -0,0 +1,166 @@
1
+ import { loadSessionState } from "./persistence";
2
+ import { isSubAgentSession } from "./utils";
3
+ import { getLastUserMessage, isMessageCompacted } from "../shared-utils";
4
+ export const checkSession = async (client, state, logger, messages) => {
5
+ const lastUserMessage = getLastUserMessage(messages);
6
+ if (!lastUserMessage) {
7
+ return;
8
+ }
9
+ const lastSessionId = lastUserMessage.info.sessionID;
10
+ if (state.sessionId === null || state.sessionId !== lastSessionId) {
11
+ logger.info(`Session changed: ${state.sessionId} -> ${lastSessionId}`);
12
+ try {
13
+ await ensureSessionInitialized(client, state, lastSessionId, logger, messages);
14
+ }
15
+ catch (err) {
16
+ logger.error("Failed to initialize session state", { error: err.message });
17
+ }
18
+ }
19
+ const lastCompactionTimestamp = findLastCompactionTimestamp(messages);
20
+ if (lastCompactionTimestamp > state.lastCompaction) {
21
+ state.lastCompaction = lastCompactionTimestamp;
22
+ state.toolParameters.clear();
23
+ state.prune.toolIds = [];
24
+ logger.info("Detected compaction from messages - cleared tool cache", {
25
+ timestamp: lastCompactionTimestamp,
26
+ });
27
+ }
28
+ state.currentTurn = countTurns(state, messages);
29
+ };
30
+ export function createSessionState() {
31
+ return {
32
+ sessionId: null,
33
+ isSubAgent: false,
34
+ prune: {
35
+ toolIds: [],
36
+ },
37
+ stats: {
38
+ pruneTokenCounter: 0,
39
+ totalPruneTokens: 0,
40
+ pruneMessageCounter: 0,
41
+ totalPruneMessages: 0,
42
+ strategyStats: {
43
+ deduplication: { count: 0, tokens: 0 },
44
+ supersedeWrites: { count: 0, tokens: 0 },
45
+ purgeErrors: { count: 0, tokens: 0 },
46
+ manualDiscard: { count: 0, tokens: 0 },
47
+ extraction: { count: 0, tokens: 0 },
48
+ },
49
+ },
50
+ toolParameters: new Map(),
51
+ lastToolPrune: false,
52
+ lastCompaction: 0,
53
+ currentTurn: 0,
54
+ variant: undefined,
55
+ lastDiscardStats: null,
56
+ lastUserMessageId: null,
57
+ // Hash-based discard system
58
+ hashToCallId: new Map(),
59
+ callIdToHash: new Map(),
60
+ discardHistory: [],
61
+ // Soft prune cache for restore capability
62
+ softPrunedTools: new Map(),
63
+ };
64
+ }
65
+ export function resetSessionState(state) {
66
+ state.sessionId = null;
67
+ state.isSubAgent = false;
68
+ state.prune = {
69
+ toolIds: [],
70
+ };
71
+ state.stats = {
72
+ pruneTokenCounter: 0,
73
+ totalPruneTokens: 0,
74
+ pruneMessageCounter: 0,
75
+ totalPruneMessages: 0,
76
+ strategyStats: {
77
+ deduplication: { count: 0, tokens: 0 },
78
+ supersedeWrites: { count: 0, tokens: 0 },
79
+ purgeErrors: { count: 0, tokens: 0 },
80
+ manualDiscard: { count: 0, tokens: 0 },
81
+ extraction: { count: 0, tokens: 0 },
82
+ },
83
+ };
84
+ state.toolParameters.clear();
85
+ state.lastToolPrune = false;
86
+ state.lastCompaction = 0;
87
+ state.currentTurn = 0;
88
+ state.variant = undefined;
89
+ state.lastDiscardStats = null;
90
+ state.lastUserMessageId = null;
91
+ // Hash-based discard system
92
+ state.hashToCallId.clear();
93
+ state.callIdToHash.clear();
94
+ state.discardHistory = [];
95
+ // Soft prune cache for restore capability
96
+ state.softPrunedTools.clear();
97
+ }
98
+ export async function ensureSessionInitialized(client, state, sessionId, logger, messages) {
99
+ if (state.sessionId === sessionId) {
100
+ return;
101
+ }
102
+ logger.info("session ID = " + sessionId);
103
+ logger.info("Initializing session state", { sessionId: sessionId });
104
+ resetSessionState(state);
105
+ state.sessionId = sessionId;
106
+ const isSubAgent = await isSubAgentSession(client, sessionId);
107
+ state.isSubAgent = isSubAgent;
108
+ logger.info("isSubAgent = " + isSubAgent);
109
+ state.lastCompaction = findLastCompactionTimestamp(messages);
110
+ state.currentTurn = countTurns(state, messages);
111
+ const persisted = await loadSessionState(sessionId, logger);
112
+ if (persisted === null) {
113
+ return;
114
+ }
115
+ state.prune = {
116
+ toolIds: persisted.prune.toolIds || [],
117
+ };
118
+ state.stats = {
119
+ pruneTokenCounter: persisted.stats?.pruneTokenCounter || 0,
120
+ totalPruneTokens: persisted.stats?.totalPruneTokens || 0,
121
+ pruneMessageCounter: persisted.stats?.pruneMessageCounter || 0,
122
+ totalPruneMessages: persisted.stats?.totalPruneMessages || 0,
123
+ strategyStats: persisted.stats?.strategyStats || {
124
+ deduplication: { count: 0, tokens: 0 },
125
+ supersedeWrites: { count: 0, tokens: 0 },
126
+ purgeErrors: { count: 0, tokens: 0 },
127
+ manualDiscard: { count: 0, tokens: 0 },
128
+ extraction: { count: 0, tokens: 0 },
129
+ },
130
+ };
131
+ // Restore hash-based discard system (convert objects back to Maps)
132
+ if (persisted.hashToCallId) {
133
+ state.hashToCallId = new Map(Object.entries(persisted.hashToCallId));
134
+ }
135
+ if (persisted.callIdToHash) {
136
+ state.callIdToHash = new Map(Object.entries(persisted.callIdToHash));
137
+ }
138
+ if (persisted.discardHistory) {
139
+ state.discardHistory = persisted.discardHistory;
140
+ }
141
+ }
142
+ function findLastCompactionTimestamp(messages) {
143
+ for (let i = messages.length - 1; i >= 0; i--) {
144
+ const msg = messages[i];
145
+ if (msg && msg.info.role === "assistant" && msg.info.summary === true) {
146
+ return msg.info.time.created;
147
+ }
148
+ }
149
+ return 0;
150
+ }
151
+ export function countTurns(state, messages) {
152
+ let turnCount = 0;
153
+ for (const msg of messages) {
154
+ if (isMessageCompacted(state, msg)) {
155
+ continue;
156
+ }
157
+ const parts = Array.isArray(msg.parts) ? msg.parts : [];
158
+ for (const part of parts) {
159
+ if (part.type === "step-start") {
160
+ turnCount++;
161
+ }
162
+ }
163
+ }
164
+ return turnCount;
165
+ }
166
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../../lib/state/state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { SessionState, WithParts } from "./index";
2
+ import type { Logger } from "../logger";
3
+ import { PluginConfig } from "../config";
4
+ /**
5
+ * Sync tool parameters from OpenCode's session.messages() API.
6
+ * Also generates stable hashes for each tool call.
7
+ */
8
+ export declare function syncToolCache(state: SessionState, config: PluginConfig, logger: Logger, messages: WithParts[]): Promise<void>;
9
+ /**
10
+ * Trim the tool parameters cache to prevent unbounded memory growth.
11
+ * Uses FIFO eviction - removes oldest entries first.
12
+ * Also cleans up corresponding hash mappings to prevent memory leaks.
13
+ */
14
+ export declare function trimToolParametersCache(state: SessionState): void;
15
+ //# sourceMappingURL=tool-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-cache.d.ts","sourceRoot":"","sources":["../../../lib/state/tool-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAc,SAAS,EAAE,MAAM,SAAS,CAAA;AAClE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAMxC;;;GAGG;AACH,wBAAsB,aAAa,CAC/B,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,SAAS,EAAE,GACtB,OAAO,CAAC,IAAI,CAAC,CAyFf;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAoBjE"}
@@ -0,0 +1,99 @@
1
+ import { isMessageCompacted } from "../shared-utils";
2
+ import { generateToolHash } from "../messages/utils";
3
+ const MAX_TOOL_CACHE_SIZE = 1000;
4
+ /**
5
+ * Sync tool parameters from OpenCode's session.messages() API.
6
+ * Also generates stable hashes for each tool call.
7
+ */
8
+ export async function syncToolCache(state, config, logger, messages) {
9
+ try {
10
+ logger.info("Syncing tool parameters from OpenCode messages");
11
+ let turnCounter = 0;
12
+ for (const msg of messages) {
13
+ if (isMessageCompacted(state, msg)) {
14
+ continue;
15
+ }
16
+ const parts = Array.isArray(msg.parts) ? msg.parts : [];
17
+ for (const part of parts) {
18
+ if (part.type === "step-start") {
19
+ turnCounter++;
20
+ continue;
21
+ }
22
+ if (part.type !== "tool" || !part.callID) {
23
+ continue;
24
+ }
25
+ const turnProtectionEnabled = config.turnProtection.enabled;
26
+ const turnProtectionTurns = config.turnProtection.turns;
27
+ const isProtectedByTurn = turnProtectionEnabled &&
28
+ turnProtectionTurns > 0 &&
29
+ state.currentTurn - turnCounter < turnProtectionTurns;
30
+ state.lastToolPrune =
31
+ (part.tool === "discard" || part.tool === "extract") &&
32
+ part.state.status === "completed";
33
+ if (state.toolParameters.has(part.callID)) {
34
+ continue;
35
+ }
36
+ if (isProtectedByTurn) {
37
+ continue;
38
+ }
39
+ const allProtectedTools = config.tools.settings.protectedTools;
40
+ // Skip hash generation for protected tools
41
+ if (!allProtectedTools.includes(part.tool)) {
42
+ // Generate hash for this tool call
43
+ const baseHash = generateToolHash(part.tool, part.state?.input ?? {});
44
+ // Handle collision: if hash exists for a different callID, append sequence number
45
+ let finalHash = baseHash;
46
+ if (state.hashToCallId.has(baseHash) &&
47
+ state.hashToCallId.get(baseHash) !== part.callID) {
48
+ let seq = 2;
49
+ while (state.hashToCallId.has(`${baseHash.slice(0, -1)}_${seq}#`)) {
50
+ seq++;
51
+ }
52
+ finalHash = `${baseHash.slice(0, -1)}_${seq}#`;
53
+ logger.warn(`Hash collision detected for ${part.tool}, using ${finalHash}`);
54
+ }
55
+ // Store bidirectional mapping
56
+ state.hashToCallId.set(finalHash, part.callID);
57
+ state.callIdToHash.set(part.callID, finalHash);
58
+ }
59
+ state.toolParameters.set(part.callID, {
60
+ tool: part.tool,
61
+ parameters: part.state?.input ?? {},
62
+ status: part.state.status,
63
+ error: part.state.status === "error" ? part.state.error : undefined,
64
+ turn: turnCounter,
65
+ });
66
+ const hash = state.callIdToHash.get(part.callID) || "(protected)";
67
+ logger.info(`Cached tool id: ${part.callID} hash: ${hash} (turn ${turnCounter})`);
68
+ }
69
+ }
70
+ logger.info(`Synced cache - size: ${state.toolParameters.size}, hashes: ${state.hashToCallId.size}, currentTurn: ${state.currentTurn}`);
71
+ trimToolParametersCache(state);
72
+ }
73
+ catch (error) {
74
+ logger.warn("Failed to sync tool parameters from OpenCode", {
75
+ error: error instanceof Error ? error.message : String(error),
76
+ });
77
+ }
78
+ }
79
+ /**
80
+ * Trim the tool parameters cache to prevent unbounded memory growth.
81
+ * Uses FIFO eviction - removes oldest entries first.
82
+ * Also cleans up corresponding hash mappings to prevent memory leaks.
83
+ */
84
+ export function trimToolParametersCache(state) {
85
+ if (state.toolParameters.size <= MAX_TOOL_CACHE_SIZE) {
86
+ return;
87
+ }
88
+ const keysToRemove = Array.from(state.toolParameters.keys()).slice(0, state.toolParameters.size - MAX_TOOL_CACHE_SIZE);
89
+ for (const callId of keysToRemove) {
90
+ state.toolParameters.delete(callId);
91
+ // Clean up hash mappings for evicted entries
92
+ const hash = state.callIdToHash.get(callId);
93
+ if (hash) {
94
+ state.hashToCallId.delete(hash);
95
+ state.callIdToHash.delete(callId);
96
+ }
97
+ }
98
+ }
99
+ //# sourceMappingURL=tool-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-cache.js","sourceRoot":"","sources":["../../../lib/state/tool-cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ import { Message, Part } from "@opencode-ai/sdk/v2";
2
+ export interface WithParts {
3
+ info: Message;
4
+ parts: Part[];
5
+ }
6
+ export type ToolStatus = "pending" | "running" | "completed" | "error";
7
+ export interface ToolParameterEntry {
8
+ tool: string;
9
+ parameters: any;
10
+ status?: ToolStatus;
11
+ error?: string;
12
+ turn: number;
13
+ }
14
+ export interface SessionStats {
15
+ pruneTokenCounter: number;
16
+ totalPruneTokens: number;
17
+ pruneMessageCounter: number;
18
+ totalPruneMessages: number;
19
+ strategyStats: {
20
+ deduplication: {
21
+ count: number;
22
+ tokens: number;
23
+ };
24
+ supersedeWrites: {
25
+ count: number;
26
+ tokens: number;
27
+ };
28
+ purgeErrors: {
29
+ count: number;
30
+ tokens: number;
31
+ };
32
+ manualDiscard: {
33
+ count: number;
34
+ tokens: number;
35
+ };
36
+ extraction: {
37
+ count: number;
38
+ tokens: number;
39
+ };
40
+ };
41
+ }
42
+ export interface Prune {
43
+ toolIds: string[];
44
+ }
45
+ export interface LastDiscardStats {
46
+ itemCount: number;
47
+ tokensSaved: number;
48
+ }
49
+ /**
50
+ * Statistics for a single discard operation.
51
+ * Used to track token savings per discard.
52
+ */
53
+ export interface DiscardStats {
54
+ timestamp: number;
55
+ hashes: string[];
56
+ tokensSaved: number;
57
+ reason: string;
58
+ }
59
+ export interface SessionState {
60
+ sessionId: string | null;
61
+ isSubAgent: boolean;
62
+ prune: Prune;
63
+ stats: SessionStats;
64
+ toolParameters: Map<string, ToolParameterEntry>;
65
+ lastToolPrune: boolean;
66
+ lastCompaction: number;
67
+ currentTurn: number;
68
+ variant: string | undefined;
69
+ lastDiscardStats: LastDiscardStats | null;
70
+ lastUserMessageId: string | null;
71
+ hashToCallId: Map<string, string>;
72
+ callIdToHash: Map<string, string>;
73
+ discardHistory: DiscardStats[];
74
+ softPrunedTools: Map<string, SoftPrunedEntry>;
75
+ }
76
+ export interface SoftPrunedEntry {
77
+ originalOutput: string;
78
+ tool: string;
79
+ parameters: any;
80
+ prunedAt: number;
81
+ hash: string;
82
+ }
83
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../lib/state/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAA;AAEnD,MAAM,WAAW,SAAS;IACtB,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,EAAE,IAAI,EAAE,CAAA;CAChB;AAED,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,OAAO,CAAA;AAEtE,MAAM,WAAW,kBAAkB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,GAAG,CAAA;IACf,MAAM,CAAC,EAAE,UAAU,CAAA;IACnB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,YAAY;IACzB,iBAAiB,EAAE,MAAM,CAAA;IACzB,gBAAgB,EAAE,MAAM,CAAA;IACxB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,kBAAkB,EAAE,MAAM,CAAA;IAE1B,aAAa,EAAE;QACX,aAAa,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAA;QAChD,eAAe,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAA;QAClD,WAAW,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAA;QAC9C,aAAa,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAA;QAChD,UAAU,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAA;KAChD,CAAA;CACJ;AAED,MAAM,WAAW,KAAK;IAClB,OAAO,EAAE,MAAM,EAAE,CAAA;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC7B,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IACzB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,YAAY;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,UAAU,EAAE,OAAO,CAAA;IACnB,KAAK,EAAE,KAAK,CAAA;IACZ,KAAK,EAAE,YAAY,CAAA;IACnB,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAA;IAC/C,aAAa,EAAE,OAAO,CAAA;IACtB,cAAc,EAAE,MAAM,CAAA;IACtB,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAAA;IACzC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;IAGhC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACjC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACjC,cAAc,EAAE,YAAY,EAAE,CAAA;IAG9B,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;CAChD;AAED,MAAM,WAAW,eAAe;IAC5B,cAAc,EAAE,MAAM,CAAA;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,GAAG,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;CACf"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../lib/state/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export declare function isSubAgentSession(client: any, sessionID: string): Promise<boolean>;
2
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../lib/state/utils.ts"],"names":[],"mappings":"AAAA,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOxF"}
@@ -0,0 +1,10 @@
1
+ export async function isSubAgentSession(client, sessionID) {
2
+ try {
3
+ const result = await client.session.get({ path: { id: sessionID } });
4
+ return !!result.data?.parentID;
5
+ }
6
+ catch (error) {
7
+ return false;
8
+ }
9
+ }
10
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../lib/state/utils.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,MAAW,EAAE,SAAiB;IAClE,IAAI,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,CAAC,CAAA;QACpE,OAAO,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAA;IAClC,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QAClB,OAAO,KAAK,CAAA;IAChB,CAAC;AACL,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { PluginConfig } from "../config";
2
+ import { Logger } from "../logger";
3
+ import type { SessionState, WithParts } from "../state";
4
+ /**
5
+ * Deduplication strategy - prunes older tool calls that have identical
6
+ * tool name and parameters, keeping only the most recent occurrence.
7
+ * Also handles fuzzy deduplication for overlapping file reads.
8
+ * Modifies the session state in place to add pruned tool call IDs.
9
+ */
10
+ export declare const deduplicate: (state: SessionState, logger: Logger, config: PluginConfig, messages: WithParts[]) => void;
11
+ //# sourceMappingURL=deduplication.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deduplication.d.ts","sourceRoot":"","sources":["../../../lib/strategies/deduplication.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAClC,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAevD;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GACpB,OAAO,YAAY,EACnB,QAAQ,MAAM,EACd,QAAQ,YAAY,EACpB,UAAU,SAAS,EAAE,KACtB,IA8EF,CAAA"}