@cortexkit/opencode-magic-context 0.24.0 → 0.25.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 +4 -2
- package/dist/agents/magic-context-prompt.d.ts.map +1 -1
- package/dist/features/magic-context/compartment-chunk-embedding.d.ts +18 -0
- package/dist/features/magic-context/compartment-chunk-embedding.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-local.d.ts +4 -0
- package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-openai.d.ts +14 -0
- package/dist/features/magic-context/memory/embedding-openai.d.ts.map +1 -1
- package/dist/features/magic-context/memory/storage-memory-embeddings.d.ts +6 -0
- package/dist/features/magic-context/memory/storage-memory-embeddings.d.ts.map +1 -1
- package/dist/features/magic-context/project-embedding-registry.d.ts +38 -0
- package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
- package/dist/features/magic-context/storage-db.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-session.d.ts +1 -0
- package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-shared.d.ts +2 -1
- package/dist/features/magic-context/storage-meta-shared.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta.d.ts +1 -1
- package/dist/features/magic-context/storage-meta.d.ts.map +1 -1
- package/dist/features/magic-context/storage-tags.d.ts +20 -1
- package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
- package/dist/features/magic-context/storage.d.ts +2 -2
- package/dist/features/magic-context/storage.d.ts.map +1 -1
- package/dist/features/magic-context/types.d.ts +1 -0
- package/dist/features/magic-context/types.d.ts.map +1 -1
- package/dist/hooks/magic-context/apply-operations.d.ts +3 -2
- package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
- package/dist/hooks/magic-context/caveman-cleanup.d.ts +1 -0
- package/dist/hooks/magic-context/caveman-cleanup.d.ts.map +1 -1
- package/dist/hooks/magic-context/channel2-delivery.d.ts +2 -0
- package/dist/hooks/magic-context/channel2-delivery.d.ts.map +1 -1
- package/dist/hooks/magic-context/command-handler.d.ts +7 -5
- package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts +14 -4
- package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts.map +1 -1
- package/dist/hooks/magic-context/embed-session-state.d.ts +14 -0
- package/dist/hooks/magic-context/embed-session-state.d.ts.map +1 -0
- package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/format-embed-status.d.ts +9 -0
- package/dist/hooks/magic-context/format-embed-status.d.ts.map +1 -0
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts +1 -0
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
- package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts +1 -1
- package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts.map +1 -1
- package/dist/hooks/magic-context/recomp-orchestrator.d.ts.map +1 -1
- package/dist/hooks/magic-context/strip-content.d.ts +0 -1
- package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-content-primitives.d.ts +2 -0
- package/dist/hooks/magic-context/tag-content-primitives.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
- package/dist/hooks/magic-context/tool-drop-target.d.ts +1 -1
- package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
- package/dist/hooks/magic-context/tool-reclaim.d.ts +12 -0
- package/dist/hooks/magic-context/tool-reclaim.d.ts.map +1 -0
- package/dist/hooks/magic-context/transform-operations.d.ts +1 -1
- package/dist/hooks/magic-context/transform-operations.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +2 -0
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1117 -378
- package/dist/plugin/conflict-warning-hook.d.ts.map +1 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/shared/announcement.d.ts +1 -1
- package/dist/shared/model-suggestion-retry.d.ts.map +1 -1
- package/dist/shared/rpc-types.d.ts +20 -0
- package/dist/shared/rpc-types.d.ts.map +1 -1
- package/dist/shared/sqlite.d.ts +5 -1
- package/dist/shared/sqlite.d.ts.map +1 -1
- package/dist/shared/tui-preferences.d.ts +32 -0
- package/dist/shared/tui-preferences.d.ts.map +1 -0
- package/dist/tools/ctx-expand/constants.d.ts +1 -1
- package/dist/tools/ctx-expand/constants.d.ts.map +1 -1
- package/dist/tools/ctx-expand/render.d.ts +43 -0
- package/dist/tools/ctx-expand/render.d.ts.map +1 -0
- package/dist/tools/ctx-expand/tools.d.ts.map +1 -1
- package/dist/tools/ctx-expand/types.d.ts +6 -2
- package/dist/tools/ctx-expand/types.d.ts.map +1 -1
- package/dist/tools/ctx-reduce/constants.d.ts +1 -1
- package/dist/tools/ctx-reduce/constants.d.ts.map +1 -1
- package/dist/tui/data/context-db.d.ts +4 -2
- package/dist/tui/data/context-db.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/shared/announcement.ts +6 -6
- package/src/shared/model-suggestion-retry.test.ts +61 -1
- package/src/shared/model-suggestion-retry.ts +22 -0
- package/src/shared/rpc-types.ts +11 -0
- package/src/shared/sqlite-bind-style.test.ts +82 -0
- package/src/shared/sqlite.ts +30 -1
- package/src/shared/tag-transcript.test.ts +3 -1
- package/src/shared/tag-transcript.ts +19 -17
- package/src/shared/tui-preferences.test.ts +210 -0
- package/src/shared/tui-preferences.ts +303 -0
- package/src/tui/data/context-db.ts +34 -2
- package/src/tui/index.tsx +58 -4
- package/src/tui/slots/sidebar-content.tsx +106 -12
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conflict-warning-hook.d.ts","sourceRoot":"","sources":["../../src/plugin/conflict-warning-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAsLlE;;GAEG;AACH,wBAAsB,mBAAmB,CACrC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,cAAc,GAC/B,OAAO,CAAC,IAAI,CAAC,CAqDf;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CACzC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAwHf;AAkCD;;;GAGG;AACH,wBAAsB,wBAAwB,CAC1C,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAsEf;AAED;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CACxC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE;IAAE,gBAAgB,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAE,GAC/D,OAAO,CAAC,IAAI,CAAC,CAsCf;AAED;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CACzC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,EAC/B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GACpC,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"conflict-warning-hook.d.ts","sourceRoot":"","sources":["../../src/plugin/conflict-warning-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAsLlE;;GAEG;AACH,wBAAsB,mBAAmB,CACrC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,cAAc,GAC/B,OAAO,CAAC,IAAI,CAAC,CAqDf;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CACzC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAwHf;AAkCD;;;GAGG;AACH,wBAAsB,wBAAwB,CAC1C,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAsEf;AAED;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CACxC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE;IAAE,gBAAgB,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAE,GAC/D,OAAO,CAAC,IAAI,CAAC,CAsCf;AAED;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CACzC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,EAC/B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GACpC,OAAO,CAAC,IAAI,CAAC,CAkFf"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-session-hooks.d.ts","sourceRoot":"","sources":["../../../src/plugin/hooks/create-session-hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAO7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAC;AACrF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACrC,GAAG,EAAE,aAAa,CAAC;IACnB,YAAY,EAAE,wBAAwB,CAAC;IACvC,gBAAgB,EAAE,gBAAgB,CAAC;CACtC;;;;;;qBAuDizK,CAAC;;;;;;;;;;;;qBAA93D,CAAC;mBAAyB,CAAC;iBAAuB,CAAC;iBAAuB,CAAC;0BAAc,CAAC;uBAAiB,CAAC;;;;;;
|
|
1
|
+
{"version":3,"file":"create-session-hooks.d.ts","sourceRoot":"","sources":["../../../src/plugin/hooks/create-session-hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAO7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAC;AACrF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACrC,GAAG,EAAE,aAAa,CAAC;IACnB,YAAY,EAAE,wBAAwB,CAAC;IACvC,gBAAgB,EAAE,gBAAgB,CAAC;CACtC;;;;;;qBAuDizK,CAAC;;;;;;;;;;;;qBAA93D,CAAC;mBAAyB,CAAC;iBAAuB,CAAC;iBAAuB,CAAC;0BAAc,CAAC;uBAAiB,CAAC;;;;;;0BAAsilC,CAAC;;;;;;EADvksC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc-handlers.d.ts","sourceRoot":"","sources":["../../src/plugin/rpc-handlers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"rpc-handlers.d.ts","sourceRoot":"","sources":["../../src/plugin/rpc-handlers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAGzE,OAAO,EACH,KAAK,eAAe,IAAI,QAAQ,EAGnC,MAAM,mCAAmC,CAAC;AAc3C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAqBlF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,KAAK,EAAe,eAAe,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AA0FtF,wBAAgB,oBAAoB,CAChC,EAAE,EAAE,QAAQ,EACZ,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,qBAAqB,CAAC,EAAE,MAAM,EAK9B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,eAAe,CA2VjB;AAED,wBAAgB,iBAAiB,CAC7B,EAAE,EAAE,QAAQ,EACZ,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,qBAAqB,CAAC,EAAE,MAAM,GAC/B,YAAY,CA+Jd;AA4BD;;GAEG;AACH,wBAAgB,mBAAmB,CAC/B,SAAS,EAAE,qBAAqB,EAChC,IAAI,EAAE;IACF,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,MAAM,EAAE,OAAO,CAAC;IAChB,gBAAgB,EAAE,gBAAgB,CAAC;CACtC,GACF,IAAI,CAgPN"}
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* Bump only when there are user-visible changes worth a startup dialog.
|
|
19
19
|
* Does NOT need to match the published package version.
|
|
20
20
|
*/
|
|
21
|
-
export declare const ANNOUNCEMENT_VERSION = "0.
|
|
21
|
+
export declare const ANNOUNCEMENT_VERSION = "0.25.0";
|
|
22
22
|
/**
|
|
23
23
|
* Short, user-facing bullet strings. Keep each line ~80 chars or shorter so the
|
|
24
24
|
* TUI dialog renders cleanly without horizontal scroll on a typical terminal.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-suggestion-retry.d.ts","sourceRoot":"","sources":["../../src/shared/model-suggestion-retry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAM7D,KAAK,MAAM,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAEtD,KAAK,UAAU,GAAG;IACd,KAAK,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B,CAAC;AAEF,KAAK,UAAU,GAAG;IACd,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IACrB,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B,CAAC;AAEF,MAAM,WAAW,kBAAkB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wFAAwF;IACxF,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;;;;;;;;;;;OAcG;IACH,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACtB;AAiBD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,mBAAmB,GAAG,IAAI,CA4C/E;
|
|
1
|
+
{"version":3,"file":"model-suggestion-retry.d.ts","sourceRoot":"","sources":["../../src/shared/model-suggestion-retry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAM7D,KAAK,MAAM,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAEtD,KAAK,UAAU,GAAG;IACd,KAAK,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B,CAAC;AAEF,KAAK,UAAU,GAAG;IACd,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IACrB,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B,CAAC;AAEF,MAAM,WAAW,kBAAkB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wFAAwF;IACxF,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;;;;;;;;;;;OAcG;IACH,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACtB;AAiBD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,mBAAmB,GAAG,IAAI,CA4C/E;AA6JD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,kCAAkC,CACpD,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,UAAU,EAChB,OAAO,GAAE,kBAAuB,GACjC,OAAO,CAAC,IAAI,CAAC,CAgFf"}
|
|
@@ -123,6 +123,26 @@ export interface StatusDetail extends SidebarSnapshot {
|
|
|
123
123
|
compressionBudget: number | null;
|
|
124
124
|
compressionUsage: string | null;
|
|
125
125
|
}
|
|
126
|
+
/** Embedding coverage for `/ctx-embed` status (mirrors getEmbeddingCoverageStatus). */
|
|
127
|
+
export interface EmbedDetail {
|
|
128
|
+
enabled: boolean;
|
|
129
|
+
model: string;
|
|
130
|
+
provider: string;
|
|
131
|
+
session: {
|
|
132
|
+
embedded: number;
|
|
133
|
+
total: number;
|
|
134
|
+
};
|
|
135
|
+
memories: {
|
|
136
|
+
embedded: number;
|
|
137
|
+
total: number;
|
|
138
|
+
};
|
|
139
|
+
commits: {
|
|
140
|
+
embedded: number;
|
|
141
|
+
total: number;
|
|
142
|
+
gitEnabled: boolean;
|
|
143
|
+
};
|
|
144
|
+
statusText: string;
|
|
145
|
+
}
|
|
126
146
|
export interface RpcNotificationMessage {
|
|
127
147
|
id: number;
|
|
128
148
|
type: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc-types.d.ts","sourceRoot":"","sources":["../../src/shared/rpc-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;;;OAOG;IACH,oBAAoB,EAAE,MAAM,CAAC;IAC7B;;;;;;;;OAQG;IACH,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC;;;;;OAKG;IACH,cAAc,CAAC,EAAE;QACb,gEAAgE;QAChE,IAAI,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC;QACtC,KAAK,EAAE,QAAQ,GAAG,WAAW,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;QAC9D,iBAAiB,EAAE,MAAM,CAAC;QAC1B,aAAa,EAAE,MAAM,CAAC;QACtB,SAAS,EAAE,MAAM,CAAC;QAClB,mBAAmB,EAAE,MAAM,CAAC;QAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,IAAI,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,IAAI,CAAC;CACZ;AAED,MAAM,WAAW,YAAa,SAAQ,eAAe;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,OAAO,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,oBAAoB,EAAE,YAAY,GAAG,QAAQ,CAAC;IAC9C;;;OAGG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,uBAAuB,EAAE,MAAM,CAAC;IAChC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,sBAAsB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB"}
|
|
1
|
+
{"version":3,"file":"rpc-types.d.ts","sourceRoot":"","sources":["../../src/shared/rpc-types.ts"],"names":[],"mappings":"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"}
|
package/dist/shared/sqlite.d.ts
CHANGED
|
@@ -25,12 +25,16 @@
|
|
|
25
25
|
* - db.transaction(fn) → wrapped function ← shimmed for node:sqlite
|
|
26
26
|
* - db.close()
|
|
27
27
|
*
|
|
28
|
-
* The
|
|
28
|
+
* The three backend differences we bridge for node:sqlite:
|
|
29
29
|
* 1. node:sqlite has no `db.transaction(fn)` helper — we add a savepoint-aware
|
|
30
30
|
* shim (below) that matches better-sqlite3/bun semantics.
|
|
31
31
|
* 2. node:sqlite's constructor option is `readOnly` (camel-case), not
|
|
32
32
|
* better-sqlite3/bun's `readonly` — we translate it so call sites are
|
|
33
33
|
* unchanged.
|
|
34
|
+
* 3. node:sqlite reads a lone array bind arg (`.run([a,b])`) as NAMED params
|
|
35
|
+
* and throws `Unknown named parameter '0'`; bun binds it positionally. We
|
|
36
|
+
* normalize it in the `prepare()` override (below) so the bind surface is
|
|
37
|
+
* identical (issue #151 / Pi /ctx-dream).
|
|
34
38
|
* Everything else (named params with bare keys, ATTACH under defensive mode,
|
|
35
39
|
* `run()` → {changes,lastInsertRowid}) is identical and was verified directly.
|
|
36
40
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/shared/sqlite.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/shared/sqlite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAMH,OAAO,KAAK,aAAa,MAAM,gBAAgB,CAAC;AAyHhD,eAAO,MAAM,QAAQ,EAAE,OAAO,aAA4B,CAAC;AAE3D,+DAA+D;AAC/D,MAAM,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC;AAE9C;;;;;;;;;GASG;AACH,MAAM,MAAM,SAAS,GAAG,aAAa,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export declare const TUI_PREFS_FILE_ENV = "OPENCODE_TUI_PREFERENCES_FILE";
|
|
2
|
+
export declare function getTuiPreferencesFile(): string;
|
|
3
|
+
export declare function readTuiPreferencesFile(): Promise<Record<string, unknown>>;
|
|
4
|
+
export declare function readTuiPreferencesFileSync(): Record<string, unknown>;
|
|
5
|
+
export declare const PLUGIN_KEY = "magic-context";
|
|
6
|
+
export declare const DEFAULT_SLOT_ORDER = 200;
|
|
7
|
+
export interface MagicContextTuiPrefs {
|
|
8
|
+
forceToTop: boolean;
|
|
9
|
+
order: number;
|
|
10
|
+
startCollapsed: boolean;
|
|
11
|
+
rememberCollapsed: boolean;
|
|
12
|
+
collapsed: boolean | null;
|
|
13
|
+
header: {
|
|
14
|
+
label: string;
|
|
15
|
+
};
|
|
16
|
+
sections: {
|
|
17
|
+
historian: boolean;
|
|
18
|
+
memory: boolean;
|
|
19
|
+
status: boolean;
|
|
20
|
+
dreamer: boolean;
|
|
21
|
+
stats: boolean;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export type TuiSections = MagicContextTuiPrefs["sections"];
|
|
25
|
+
export declare const DEFAULT_PREFS: MagicContextTuiPrefs;
|
|
26
|
+
export declare function resolveMagicContextPrefs(root: Record<string, unknown>): MagicContextTuiPrefs;
|
|
27
|
+
export declare function computeEffectiveOrder(root: Record<string, unknown>, pluginKey: string, defaultOrder: number): number;
|
|
28
|
+
type JsonValue = string | number | boolean | null;
|
|
29
|
+
export declare function queueTuiPreferenceUpdate(pluginKey: string, path: string[], value: JsonValue): Promise<void>;
|
|
30
|
+
export declare function watchTuiPreferences(onChange: () => void): () => void;
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=tui-preferences.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tui-preferences.d.ts","sourceRoot":"","sources":["../../src/shared/tui-preferences.ts"],"names":[],"mappings":"AAqBA,eAAO,MAAM,kBAAkB,kCAAkC,CAAC;AAGlE,wBAAgB,qBAAqB,IAAI,MAAM,CAO9C;AAQD,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAS/E;AAMD,wBAAgB,0BAA0B,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASpE;AAED,eAAO,MAAM,UAAU,kBAAkB,CAAC;AAC1C,eAAO,MAAM,kBAAkB,MAAM,CAAC;AAEtC,MAAM,WAAW,oBAAoB;IACjC,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,OAAO,CAAC;IACxB,iBAAiB,EAAE,OAAO,CAAC;IAE3B,SAAS,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE;QACJ,KAAK,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,QAAQ,EAAE;QACN,SAAS,EAAE,OAAO,CAAC;QACnB,MAAM,EAAE,OAAO,CAAC;QAChB,MAAM,EAAE,OAAO,CAAC;QAChB,OAAO,EAAE,OAAO,CAAC;QACjB,KAAK,EAAE,OAAO,CAAC;KAClB,CAAC;CACL;AAED,MAAM,MAAM,WAAW,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC;AAE3D,eAAO,MAAM,aAAa,EAAE,oBAc3B,CAAC;AAmBF,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,oBAAoB,CAyB5F;AAgBD,wBAAgB,qBAAqB,CACjC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GACrB,MAAM,CAOR;AASD,KAAK,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AA0DlD,wBAAgB,wBAAwB,CACpC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EAAE,EACd,KAAK,EAAE,SAAS,GACjB,OAAO,CAAC,IAAI,CAAC,CAGf;AAeD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAuCpE"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export declare const CTX_EXPAND_DESCRIPTION = "Recover the original conversation from your compacted history.\n\nOlder parts of this session are summarized into <compartment> blocks inside <session-history> \u2014 e.g. <compartment start=\"120\" end=\"245\" title=\"Fixed tagger collision\">. Each one replaces the raw messages in that ordinal range with a summary. When the summary isn't enough \u2014 you need exact wording, a specific value, an error message, or the reasoning behind a decision \u2014 expand the range:\n\nctx_expand(start=120, end=245) \u2190 the compartment's own start/end attributes\n\nReturns the raw transcript as [N] U:/A: lines, capped at ~15K tokens; an oversized range returns the head and tells you where to continue. Also works with ordinals from ctx_search message results \u2014 expand a window around a hit (e.g. start=N-10, end=N+5). Ranges after the last compartment are your live tail \u2014 already visible in context, not expandable.";
|
|
1
|
+
export declare const CTX_EXPAND_DESCRIPTION = "Recover the original conversation from your compacted history.\n\nOlder parts of this session are summarized into <compartment> blocks inside <session-history> \u2014 e.g. <compartment start=\"120\" end=\"245\" title=\"Fixed tagger collision\">. Each one replaces the raw messages in that ordinal range with a summary. When the summary isn't enough \u2014 you need exact wording, a specific value, an error message, or the reasoning behind a decision \u2014 expand the range:\n\nctx_expand(start=120, end=245) \u2190 the compartment's own start/end attributes\n\nReturns the raw transcript as [N] U:/A: lines, capped at ~15K tokens; an oversized range returns the head and tells you where to continue. Also works with ordinals from ctx_search message results \u2014 expand a window around a hit (e.g. start=N-10, end=N+5). Ranges after the last compartment are your live tail \u2014 already visible in context, not expandable.\n\nTwo recovery modes for finer detail:\n- ctx_expand(start=120, end=245, verbose=true) \u2014 lists each message SEPARATELY with its ordinal [N] and a per-part preview (each tool call shown with its output size). Use this to find the exact message or tool call you want, then recover it in full by ordinal.\n- ctx_expand(message=138) \u2014 returns the FULL untruncated content of the message at that ordinal: every text part, and every tool call's complete input + output, read from stored history. This is the cheap way to get back a tool output you dropped with ctx_reduce \u2014 the original is still in storage even though the wire shows [dropped \u00A7N\u00A7]. If the message was deleted from history (session prune/revert), it says so.";
|
|
2
2
|
export declare const CTX_EXPAND_TOKEN_BUDGET = 15000;
|
|
3
3
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-expand/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,sBAAsB,
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-expand/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,sBAAsB,6oDAU6X,CAAC;AAEja,eAAO,MAAM,uBAAuB,QAAS,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verbose / by-id rendering for ctx_expand.
|
|
3
|
+
*
|
|
4
|
+
* The default ctx_expand range view returns a CONDENSED digest (turns merged,
|
|
5
|
+
* tool calls collapsed to `TC: name(arg)`). These two renderers add the recovery
|
|
6
|
+
* modes:
|
|
7
|
+
*
|
|
8
|
+
* - `renderVerboseRange`: every message shown SEPARATELY with its message id
|
|
9
|
+
* and a per-part preview, so the agent can see exactly what's in a range and
|
|
10
|
+
* pick the id of a specific message/tool call to recover in full.
|
|
11
|
+
* - `renderMessageById`: the FULL untruncated content of one message (any
|
|
12
|
+
* role) — every text part, and every tool call's complete input + output —
|
|
13
|
+
* read straight from the harness's stored history (opencode.db / Pi JSONL).
|
|
14
|
+
* This is the cheap way back from a `ctx_reduce` drop: the wire placeholder
|
|
15
|
+
* is `[dropped §N§]`, but the original output still lives in storage until
|
|
16
|
+
* the row is genuinely deleted (session prune/revert), in which case we say
|
|
17
|
+
* so rather than re-running the tool (which could now give a different
|
|
18
|
+
* answer).
|
|
19
|
+
*
|
|
20
|
+
* Both read through the shared provider-aware helpers, so Pi works by registering
|
|
21
|
+
* its `RawMessageProvider` for the call exactly like the range view does.
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Full untruncated recovery of one message by its ORDINAL — the same `[N]`
|
|
25
|
+
* identifier the agent already uses everywhere (compartment start/end, ctx_search
|
|
26
|
+
* hits, the verbose range view). Returns a "deleted" message when no message sits
|
|
27
|
+
* at that ordinal (pruned/reverted or wrong ordinal).
|
|
28
|
+
*/
|
|
29
|
+
export declare function renderMessageByOrdinal(sessionId: string, ordinal: number): string;
|
|
30
|
+
export interface VerboseRangeResult {
|
|
31
|
+
text: string;
|
|
32
|
+
/** Last ordinal actually rendered (for the continuation hint). */
|
|
33
|
+
lastOrdinal: number;
|
|
34
|
+
/** True when the budget cut the range short. */
|
|
35
|
+
truncated: boolean;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Verbose range view: every message in [start, end] shown separately, with its
|
|
39
|
+
* id and a per-part preview, bounded by `tokenBudget`. The agent reads the ids
|
|
40
|
+
* here and recovers any one message in full with ctx_expand(id=...).
|
|
41
|
+
*/
|
|
42
|
+
export declare function renderVerboseRange(sessionId: string, start: number, end: number, tokenBudget: number): VerboseRangeResult;
|
|
43
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-expand/render.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAoLH;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAkBjF;AAED,MAAM,WAAW,kBAAkB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,WAAW,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,SAAS,EAAE,OAAO,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAC9B,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,GACpB,kBAAkB,CA0BpB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-expand/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAQ,MAAM,qBAAqB,CAAC;AAEhE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-expand/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAQ,MAAM,qBAAqB,CAAC;AAEhE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAM5E,MAAM,WAAW,iBAAiB;IAC9B,EAAE,EAAE,eAAe,CAAC;CACvB;AA8GD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAI5F"}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
export interface CtxExpandArgs {
|
|
2
|
-
start
|
|
3
|
-
end
|
|
2
|
+
start?: number;
|
|
3
|
+
end?: number;
|
|
4
|
+
/** Verbose range view: each message + tool call shown separately, with ordinals. */
|
|
5
|
+
verbose?: boolean;
|
|
6
|
+
/** Full untruncated recovery of one message (any role) by its ordinal. */
|
|
7
|
+
message?: number;
|
|
4
8
|
}
|
|
5
9
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-expand/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC1B,KAAK,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-expand/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oFAAoF;IACpF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const CTX_REDUCE_DESCRIPTION = "
|
|
1
|
+
export declare const CTX_REDUCE_DESCRIPTION = "Mark spent tagged content as discardable to reclaim context space. This is NOT an immediate delete. Use \u00A7N\u00A7 identifiers visible in the conversation. The `drop` param accepts ranges: \"3-5\", \"1,2,9\", \"1-5,8\".\n\nHow it works:\n- Marking QUEUES content for release. It stays fully visible to you until context space is actually needed \u2014 which may be as soon as the next turn if you are already under pressure, or many turns later if not. So mark spent outputs as soon as you finish with them; don't hoard the call for the end of the turn.\n- The newest tags are protected: marking one just queues it until it ages out of the recent window, so marking recent output is harmless.\n- When content is finally released it becomes a short placeholder, and re-running the tool is the only way to get it back. So mark only what you are genuinely DONE with \u2014 the test is \"have I extracted what I need from this?\", not \"is it safe / do I have time before it drops?\".\n\nMark discardable once processed: large outputs you've summarized, repeated or redundant dumps, data written to disk, status/log output that only confirmed an expected state.\nKeep: user messages, unresolved errors, raw evidence you haven't extracted yet, and outputs whose exact wording may matter later.\nNever blanket-mark large ranges (e.g. \"1-50\") \u2014 review what each tag holds first.";
|
|
2
2
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-reduce/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,sBAAsB,
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-reduce/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,sBAAsB,02CASoD,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { SidebarSnapshot, StatusDetail } from "../../shared/rpc-types";
|
|
2
|
-
export type { SidebarSnapshot, StatusDetail };
|
|
1
|
+
import type { EmbedDetail, SidebarSnapshot, StatusDetail } from "../../shared/rpc-types";
|
|
2
|
+
export type { EmbedDetail, SidebarSnapshot, StatusDetail };
|
|
3
3
|
/** Initialize the RPC client. Call once on TUI startup. */
|
|
4
4
|
export declare function initRpcClient(directory: string): void;
|
|
5
5
|
export declare function getRpcGeneration(): number;
|
|
@@ -9,6 +9,8 @@ export declare function closeRpc(): void;
|
|
|
9
9
|
export declare function loadSidebarSnapshot(sessionId: string, directory: string): Promise<SidebarSnapshot>;
|
|
10
10
|
/** Fetch full status detail from the server via RPC. */
|
|
11
11
|
export declare function loadStatusDetail(sessionId: string, directory: string, modelKey?: string): Promise<StatusDetail>;
|
|
12
|
+
/** Fetch embedding coverage status for `/ctx-embed` via RPC. */
|
|
13
|
+
export declare function loadEmbedDetail(sessionId: string, directory: string): Promise<EmbedDetail>;
|
|
12
14
|
/** Get compartment count via RPC. */
|
|
13
15
|
export declare function getCompartmentCount(sessionId: string): Promise<number>;
|
|
14
16
|
/** Send recomp request to server via RPC. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-db.d.ts","sourceRoot":"","sources":["../../../src/tui/data/context-db.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"context-db.d.ts","sourceRoot":"","sources":["../../../src/tui/data/context-db.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACR,WAAW,EAEX,eAAe,EACf,YAAY,EACf,MAAM,wBAAwB,CAAC;AAEhC,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC;AAe3D,2DAA2D;AAC3D,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAOrD;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,+BAA+B;AAC/B,wBAAgB,QAAQ,IAAI,IAAI,CAO/B;AA4FD,sDAAsD;AACtD,wBAAsB,mBAAmB,CACrC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,CAAC,CA4B1B;AAED,wDAAwD;AACxD,wBAAsB,gBAAgB,CAClC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,YAAY,CAAC,CAyCvB;AAYD,gEAAgE;AAChE,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAchG;AAED,qCAAqC;AACrC,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ5E;AAED,6CAA6C;AAC7C,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQvE;AAED;mFACmF;AACnF,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQxE;AAED;;iDAEiD;AACjD,wBAAsB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAUhF;AAED,MAAM,WAAW,UAAU;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAkBrE;AAED,wEAAwE;AACxE,wBAAsB,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC,CAQtD;AAED,yDAAyD;AACzD,wBAAsB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAyBjF;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI,CAWtF"}
|
package/package.json
CHANGED
|
@@ -23,18 +23,18 @@ import { getMagicContextStorageDir } from "./data-path";
|
|
|
23
23
|
* Bump only when there are user-visible changes worth a startup dialog.
|
|
24
24
|
* Does NOT need to match the published package version.
|
|
25
25
|
*/
|
|
26
|
-
export const ANNOUNCEMENT_VERSION = "0.
|
|
26
|
+
export const ANNOUNCEMENT_VERSION = "0.25.0";
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* Short, user-facing bullet strings. Keep each line ~80 chars or shorter so the
|
|
30
30
|
* TUI dialog renders cleanly without horizontal scroll on a typical terminal.
|
|
31
31
|
*/
|
|
32
32
|
export const ANNOUNCEMENT_FEATURES: ReadonlyArray<string> = [
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
33
|
+
"Old tool output is now reclaimed automatically: once a file read / search / command output has gone a full execute cycle unused, it's dropped on the next one — no need to call ctx_reduce for stale results.",
|
|
34
|
+
"Recover anything that was dropped: ctx_expand({ message: N }) returns a dropped message's full content (every tool call's input + output) from storage. ctx_expand({ start, end, verbose: true }) lists a range message-by-message to find it.",
|
|
35
|
+
"Searchable history made reliable: /ctx-embed shows embedding coverage and runs a resilient backfill (retries transient failures, no longer bails on the first hiccup); the active session now auto-embeds in the background. ctx_reduce guidance also reframed as deferred + recoverable so models trim spent output earlier.",
|
|
36
|
+
"Pi: fixed /ctx-dream (was failing with 'Unknown named parameter') and local-embedding load failures on Windows/Desktop (#151, #128).",
|
|
37
|
+
"Runaway background agents on weak/local models are now capped and force-stopped (#154, #152). Plus several prompt-cache busts removed.",
|
|
38
38
|
];
|
|
39
39
|
|
|
40
40
|
/**
|
|
@@ -7,10 +7,11 @@ type PromptCall = {
|
|
|
7
7
|
signal?: AbortSignal;
|
|
8
8
|
};
|
|
9
9
|
|
|
10
|
-
function createClient(prompt: ReturnType<typeof mock>) {
|
|
10
|
+
function createClient(prompt: ReturnType<typeof mock>, abort?: ReturnType<typeof mock>) {
|
|
11
11
|
return {
|
|
12
12
|
session: {
|
|
13
13
|
prompt,
|
|
14
|
+
abort: abort ?? mock(async () => ({})),
|
|
14
15
|
},
|
|
15
16
|
} as never;
|
|
16
17
|
}
|
|
@@ -164,6 +165,65 @@ describe("promptSyncWithModelSuggestionRetry", () => {
|
|
|
164
165
|
expect(prompt).toHaveBeenCalledTimes(1);
|
|
165
166
|
});
|
|
166
167
|
|
|
168
|
+
// #154: our timeout must force-stop the child's SERVER-SIDE run loop via
|
|
169
|
+
// session.abort — cancelling our client fetch alone leaves the child looping
|
|
170
|
+
// the LLM past the timeout (uncancellable, only dies on process exit).
|
|
171
|
+
test("timeout fires session.abort on the child session", async () => {
|
|
172
|
+
// A prompt that respects the AbortController by hanging until aborted,
|
|
173
|
+
// then throwing — mirrors a real in-flight request our timeout cancels.
|
|
174
|
+
const prompt = mock((opts: { signal?: AbortSignal }) => {
|
|
175
|
+
return new Promise((_resolve, reject) => {
|
|
176
|
+
opts.signal?.addEventListener("abort", () => reject(new Error("aborted")));
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
const abort = mock(async () => ({}));
|
|
180
|
+
const client = createClient(prompt as never, abort);
|
|
181
|
+
|
|
182
|
+
await expect(
|
|
183
|
+
promptSyncWithModelSuggestionRetry(client, createArgs(), { timeoutMs: 20 }),
|
|
184
|
+
).rejects.toThrow(/timed out/);
|
|
185
|
+
expect(abort).toHaveBeenCalledTimes(1);
|
|
186
|
+
expect((abort.mock.calls[0]?.[0] as { path: { id: string } }).path.id).toBe("ses-test");
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
// External abort (e.g. dreamer lease loss) mid-flight must also stop the
|
|
190
|
+
// server-side loop, not just our fetch.
|
|
191
|
+
test("external abort fires session.abort on the child session", async () => {
|
|
192
|
+
const controller = new AbortController();
|
|
193
|
+
const prompt = mock((opts: { signal?: AbortSignal }) => {
|
|
194
|
+
return new Promise((_resolve, reject) => {
|
|
195
|
+
opts.signal?.addEventListener("abort", () => reject(new Error("aborted")));
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
const abort = mock(async () => ({}));
|
|
199
|
+
const client = createClient(prompt as never, abort);
|
|
200
|
+
|
|
201
|
+
setTimeout(() => controller.abort(), 10);
|
|
202
|
+
await expect(
|
|
203
|
+
promptSyncWithModelSuggestionRetry(client, createArgs(), { signal: controller.signal }),
|
|
204
|
+
).rejects.toThrow(/aborted by external signal/);
|
|
205
|
+
expect(abort).toHaveBeenCalledTimes(1);
|
|
206
|
+
expect((abort.mock.calls[0]?.[0] as { path: { id: string } }).path.id).toBe("ses-test");
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
// A failing session.abort must not mask the original timeout/abort error.
|
|
210
|
+
test("session.abort failure does not mask the timeout error", async () => {
|
|
211
|
+
const prompt = mock((opts: { signal?: AbortSignal }) => {
|
|
212
|
+
return new Promise((_resolve, reject) => {
|
|
213
|
+
opts.signal?.addEventListener("abort", () => reject(new Error("aborted")));
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
const abort = mock(async () => {
|
|
217
|
+
throw new Error("abort endpoint 500");
|
|
218
|
+
});
|
|
219
|
+
const client = createClient(prompt as never, abort);
|
|
220
|
+
|
|
221
|
+
await expect(
|
|
222
|
+
promptSyncWithModelSuggestionRetry(client, createArgs(), { timeoutMs: 20 }),
|
|
223
|
+
).rejects.toThrow(/timed out/);
|
|
224
|
+
expect(abort).toHaveBeenCalledTimes(1);
|
|
225
|
+
});
|
|
226
|
+
|
|
167
227
|
test("suggestion retry within attempt succeeds", async () => {
|
|
168
228
|
const suggestionError = new Error("model not found");
|
|
169
229
|
suggestionError.name = "ProviderModelNotFoundError";
|
|
@@ -143,9 +143,17 @@ async function promptWithTimeout(
|
|
|
143
143
|
} as Parameters<typeof client.session.prompt>[0]);
|
|
144
144
|
} catch (error) {
|
|
145
145
|
if (signal?.aborted) {
|
|
146
|
+
// External abort (e.g. dreamer lease loss): the child run loop is an
|
|
147
|
+
// independent SERVER-SIDE fiber — cancelling our client fetch alone
|
|
148
|
+
// leaves it looping the LLM forever (issue #154). Force-stop it.
|
|
149
|
+
await abortChildRun(client, args.path.id);
|
|
146
150
|
throw new Error("prompt aborted by external signal");
|
|
147
151
|
}
|
|
148
152
|
if (controller.signal.aborted) {
|
|
153
|
+
// Our timeout fired. Same problem: abort the server-side run loop, not
|
|
154
|
+
// just our fetch, or the child keeps re-calling the LLM past the
|
|
155
|
+
// timeout (uncancellable by the user's ESC — issue #154).
|
|
156
|
+
await abortChildRun(client, args.path.id);
|
|
149
157
|
throw new Error(`prompt timed out after ${timeoutMs}ms`);
|
|
150
158
|
}
|
|
151
159
|
throw error;
|
|
@@ -155,6 +163,20 @@ async function promptWithTimeout(
|
|
|
155
163
|
}
|
|
156
164
|
}
|
|
157
165
|
|
|
166
|
+
/**
|
|
167
|
+
* Force-stop a spawned child session's server-side run loop. `controller.abort()`
|
|
168
|
+
* on the prompt signal only cancels OUR client fetch; the run loop is a separate
|
|
169
|
+
* instance-scoped fiber that `POST /session/{id}/abort` interrupts. Best-effort —
|
|
170
|
+
* a failure here must not mask the original timeout/abort error.
|
|
171
|
+
*/
|
|
172
|
+
async function abortChildRun(client: Client, sessionId: string): Promise<void> {
|
|
173
|
+
try {
|
|
174
|
+
await client.session.abort({ path: { id: sessionId } });
|
|
175
|
+
} catch (error) {
|
|
176
|
+
log(`[model-retry] child session abort failed for ${sessionId}: ${String(error)}`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
158
180
|
/**
|
|
159
181
|
* Returns true if the error indicates a NON-RETRYABLE condition where iterating
|
|
160
182
|
* to a fallback model would be pointless or harmful:
|
package/src/shared/rpc-types.ts
CHANGED
|
@@ -123,6 +123,17 @@ export interface StatusDetail extends SidebarSnapshot {
|
|
|
123
123
|
compressionUsage: string | null;
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
+
/** Embedding coverage for `/ctx-embed` status (mirrors getEmbeddingCoverageStatus). */
|
|
127
|
+
export interface EmbedDetail {
|
|
128
|
+
enabled: boolean;
|
|
129
|
+
model: string;
|
|
130
|
+
provider: string;
|
|
131
|
+
session: { embedded: number; total: number };
|
|
132
|
+
memories: { embedded: number; total: number };
|
|
133
|
+
commits: { embedded: number; total: number; gitEnabled: boolean };
|
|
134
|
+
statusText: string;
|
|
135
|
+
}
|
|
136
|
+
|
|
126
137
|
export interface RpcNotificationMessage {
|
|
127
138
|
id: number;
|
|
128
139
|
type: string;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { describe, expect, it } from "bun:test";
|
|
2
|
+
import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Guard: SQLite statement binds must use SPREAD positional args
|
|
7
|
+
* (`stmt.run(a, b)`), never the ARRAY form (`stmt.run([a, b])`).
|
|
8
|
+
*
|
|
9
|
+
* Why this is a CI guard, not just a style preference: bun:sqlite (OpenCode)
|
|
10
|
+
* binds a lone array positionally, but node:sqlite (Pi, OpenCode Desktop) reads
|
|
11
|
+
* it as NAMED params ("0","1") and throws `Unknown named parameter '0'`. An
|
|
12
|
+
* array-form bind therefore passes every OpenCode/Bun test yet breaks Pi/Desktop
|
|
13
|
+
* silently — exactly how issue #151 (/ctx-dream) shipped. The sqlite.ts
|
|
14
|
+
* chokepoint now normalizes array binds for node:sqlite so it can no longer
|
|
15
|
+
* CRASH, but the array form is still discouraged: it relies on the shim, reads
|
|
16
|
+
* inconsistently with the rest of the codebase (all spread), and the guard
|
|
17
|
+
* catches it at PR time so the shim stays a safety net, not a crutch.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
// Scan EVERY package's src, not just plugin's. pi-plugin and cli have no
|
|
21
|
+
// sqlite.ts of their own — they run on the shared chokepoint — so an array-form
|
|
22
|
+
// bind written in their code would break under node:sqlite (Pi/Desktop) exactly
|
|
23
|
+
// like #151, and the plugin-only scan would never see it. Roots are resolved
|
|
24
|
+
// relative to plugin/src so the guard works from the plugin package.
|
|
25
|
+
const PLUGIN_SRC = join(import.meta.dir, "..");
|
|
26
|
+
const SCAN_ROOTS = [
|
|
27
|
+
PLUGIN_SRC,
|
|
28
|
+
join(PLUGIN_SRC, "../../pi-plugin/src"),
|
|
29
|
+
join(PLUGIN_SRC, "../../cli/src"),
|
|
30
|
+
].filter((dir) => existsSync(dir));
|
|
31
|
+
// The chokepoint itself documents the pattern in prose/comments; the guard's own
|
|
32
|
+
// source mentions it; allow those two (relative to whichever root contains them).
|
|
33
|
+
const ALLOWED = new Set(["shared/sqlite.ts", "shared/sqlite-bind-style.test.ts"]);
|
|
34
|
+
// `stmt.run([` / `.get([` / `.all([` — but `.all([` also matches Promise.all([.
|
|
35
|
+
const BIND_PATTERN = /\.(run|get|all)\(\[/;
|
|
36
|
+
|
|
37
|
+
function collectTsFiles(dir: string, acc: string[] = []): string[] {
|
|
38
|
+
for (const entry of readdirSync(dir)) {
|
|
39
|
+
const full = join(dir, entry);
|
|
40
|
+
const st = statSync(full);
|
|
41
|
+
if (st.isDirectory()) {
|
|
42
|
+
collectTsFiles(full, acc);
|
|
43
|
+
} else if (entry.endsWith(".ts") && !entry.endsWith(".test.ts")) {
|
|
44
|
+
acc.push(full);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return acc;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
describe("sqlite bind style", () => {
|
|
51
|
+
it("uses spread positional binds, never the array form", () => {
|
|
52
|
+
const violations: string[] = [];
|
|
53
|
+
for (const root of SCAN_ROOTS) {
|
|
54
|
+
for (const file of collectTsFiles(root)) {
|
|
55
|
+
const rel = file.slice(root.length + 1);
|
|
56
|
+
if (ALLOWED.has(rel)) continue;
|
|
57
|
+
const lines = readFileSync(file, "utf8").split("\n");
|
|
58
|
+
lines.forEach((line, i) => {
|
|
59
|
+
if (!BIND_PATTERN.test(line)) return;
|
|
60
|
+
// Promise.all([...]) is not a SQLite statement bind.
|
|
61
|
+
if (line.includes("Promise.all(")) return;
|
|
62
|
+
// Skip comment lines.
|
|
63
|
+
const trimmed = line.trim();
|
|
64
|
+
if (trimmed.startsWith("//") || trimmed.startsWith("*")) return;
|
|
65
|
+
// Disambiguate which package the hit is in.
|
|
66
|
+
const pkg = root.includes("pi-plugin")
|
|
67
|
+
? "pi-plugin"
|
|
68
|
+
: root.includes("cli")
|
|
69
|
+
? "cli"
|
|
70
|
+
: "plugin";
|
|
71
|
+
violations.push(`${pkg}/${rel}:${i + 1} ${trimmed}`);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
expect(
|
|
76
|
+
violations,
|
|
77
|
+
`Array-form SQLite binds found — use spread positional .run(a, b) ` +
|
|
78
|
+
`instead of .run([a, b]) (breaks under node:sqlite on Pi/Desktop):\n` +
|
|
79
|
+
violations.join("\n"),
|
|
80
|
+
).toEqual([]);
|
|
81
|
+
});
|
|
82
|
+
});
|
package/src/shared/sqlite.ts
CHANGED
|
@@ -25,12 +25,16 @@
|
|
|
25
25
|
* - db.transaction(fn) → wrapped function ← shimmed for node:sqlite
|
|
26
26
|
* - db.close()
|
|
27
27
|
*
|
|
28
|
-
* The
|
|
28
|
+
* The three backend differences we bridge for node:sqlite:
|
|
29
29
|
* 1. node:sqlite has no `db.transaction(fn)` helper — we add a savepoint-aware
|
|
30
30
|
* shim (below) that matches better-sqlite3/bun semantics.
|
|
31
31
|
* 2. node:sqlite's constructor option is `readOnly` (camel-case), not
|
|
32
32
|
* better-sqlite3/bun's `readonly` — we translate it so call sites are
|
|
33
33
|
* unchanged.
|
|
34
|
+
* 3. node:sqlite reads a lone array bind arg (`.run([a,b])`) as NAMED params
|
|
35
|
+
* and throws `Unknown named parameter '0'`; bun binds it positionally. We
|
|
36
|
+
* normalize it in the `prepare()` override (below) so the bind surface is
|
|
37
|
+
* identical (issue #151 / Pi /ctx-dream).
|
|
34
38
|
* Everything else (named params with bare keys, ATTACH under defensive mode,
|
|
35
39
|
* `run()` → {changes,lastInsertRowid}) is identical and was verified directly.
|
|
36
40
|
*/
|
|
@@ -104,6 +108,31 @@ function buildNodeSqliteDatabaseClass(DatabaseSync: any): typeof BetterSqlite3 {
|
|
|
104
108
|
super(typeof filename === "string" ? filename : ":memory:", translated);
|
|
105
109
|
}
|
|
106
110
|
|
|
111
|
+
// Normalize a single ARRAY bind arg to spread positional, matching
|
|
112
|
+
// bun:sqlite. bun's `.run([a,b])` binds positionally; node:sqlite instead
|
|
113
|
+
// reads a lone array as NAMED params with keys "0","1" and throws
|
|
114
|
+
// `Unknown named parameter '0'`. That divergence let an array-form bind
|
|
115
|
+
// (e.g. `.run([x, y])`) silently work on OpenCode/Bun yet break Pi and
|
|
116
|
+
// OpenCode Desktop (both node:sqlite) — issue #151 (/ctx-dream). Wrapping
|
|
117
|
+
// every prepared statement here keeps the two backends' bind surface
|
|
118
|
+
// truly identical so this whole class is impossible regardless of how a
|
|
119
|
+
// call site writes its bind. Named-object binds (`.run({k:v})`), no-arg
|
|
120
|
+
// calls, and already-spread positional args are passed through unchanged;
|
|
121
|
+
// the normalization only triggers on the exact 1-array shape. Overhead
|
|
122
|
+
// measured at ~12ns/call against real node:sqlite (negligible).
|
|
123
|
+
// biome-ignore lint/suspicious/noExplicitAny: node:sqlite StatementSync has no shipped types here.
|
|
124
|
+
prepare(sql: string): any {
|
|
125
|
+
const stmt = super.prepare(sql);
|
|
126
|
+
for (const method of ["run", "get", "all"] as const) {
|
|
127
|
+
const original = stmt[method].bind(stmt);
|
|
128
|
+
stmt[method] = (...args: unknown[]): unknown =>
|
|
129
|
+
args.length === 1 && Array.isArray(args[0])
|
|
130
|
+
? original(...args[0])
|
|
131
|
+
: original(...args);
|
|
132
|
+
}
|
|
133
|
+
return stmt;
|
|
134
|
+
}
|
|
135
|
+
|
|
107
136
|
// biome-ignore lint/suspicious/noExplicitAny: mirrors better-sqlite3's generic transaction(fn) signature.
|
|
108
137
|
transaction<F extends (...args: any[]) => any>(fn: F): F {
|
|
109
138
|
// biome-ignore lint/suspicious/noExplicitAny: faithful pass-through of this/args to fn.
|
|
@@ -203,7 +203,9 @@ describe("tagTranscript tool aggregation", () => {
|
|
|
203
203
|
result = targets.get(tag ?? -1)?.truncate?.();
|
|
204
204
|
}).not.toThrow();
|
|
205
205
|
expect(result).toBe("truncated");
|
|
206
|
-
|
|
206
|
+
// Skeleton-drop now renders the one canonical placeholder, not a
|
|
207
|
+
// separate "[truncated]" vocabulary.
|
|
208
|
+
expect(toolUse.getText()).toBe(`[dropped \u00a7${tag}\u00a7]`);
|
|
207
209
|
});
|
|
208
210
|
|
|
209
211
|
it("drops every contiguous folded tool_result block for the paired callId", () => {
|