@cortexkit/opencode-magic-context 0.21.6 → 0.21.8

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 (76) hide show
  1. package/README.md +1 -1
  2. package/dist/config/agent-disable.d.ts +26 -0
  3. package/dist/config/agent-disable.d.ts.map +1 -0
  4. package/dist/config/index.d.ts.map +1 -1
  5. package/dist/config/schema/magic-context.d.ts +0 -6
  6. package/dist/config/schema/magic-context.d.ts.map +1 -1
  7. package/dist/features/magic-context/compartment-lease.d.ts +14 -0
  8. package/dist/features/magic-context/compartment-lease.d.ts.map +1 -0
  9. package/dist/features/magic-context/compartment-storage.d.ts +5 -1
  10. package/dist/features/magic-context/compartment-storage.d.ts.map +1 -1
  11. package/dist/features/magic-context/compression-depth-storage.d.ts +2 -1
  12. package/dist/features/magic-context/compression-depth-storage.d.ts.map +1 -1
  13. package/dist/features/magic-context/dreamer/runner.d.ts.map +1 -1
  14. package/dist/features/magic-context/migrations.d.ts.map +1 -1
  15. package/dist/features/magic-context/sidekick/agent.d.ts.map +1 -1
  16. package/dist/features/magic-context/storage-db.d.ts.map +1 -1
  17. package/dist/features/magic-context/storage-meta-persisted.d.ts +5 -0
  18. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  19. package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -1
  20. package/dist/features/magic-context/storage-meta.d.ts +1 -1
  21. package/dist/features/magic-context/storage-meta.d.ts.map +1 -1
  22. package/dist/features/magic-context/storage-subagent-invocations.d.ts +52 -0
  23. package/dist/features/magic-context/storage-subagent-invocations.d.ts.map +1 -0
  24. package/dist/features/magic-context/storage.d.ts +3 -2
  25. package/dist/features/magic-context/storage.d.ts.map +1 -1
  26. package/dist/features/magic-context/subagent-token-capture.d.ts +33 -0
  27. package/dist/features/magic-context/subagent-token-capture.d.ts.map +1 -0
  28. package/dist/features/magic-context/user-memory/review-user-memories.d.ts.map +1 -1
  29. package/dist/features/magic-context/work-metrics.d.ts +13 -0
  30. package/dist/features/magic-context/work-metrics.d.ts.map +1 -0
  31. package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
  32. package/dist/hooks/magic-context/compartment-runner-compressor.d.ts +4 -0
  33. package/dist/hooks/magic-context/compartment-runner-compressor.d.ts.map +1 -1
  34. package/dist/hooks/magic-context/compartment-runner-historian.d.ts +2 -0
  35. package/dist/hooks/magic-context/compartment-runner-historian.d.ts.map +1 -1
  36. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
  37. package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts.map +1 -1
  38. package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
  39. package/dist/hooks/magic-context/compartment-runner-types.d.ts +3 -0
  40. package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
  41. package/dist/hooks/magic-context/compartment-runner.d.ts +5 -0
  42. package/dist/hooks/magic-context/compartment-runner.d.ts.map +1 -1
  43. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  44. package/dist/hooks/magic-context/transform-compartment-phase.d.ts +2 -2
  45. package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
  46. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +1 -0
  47. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  48. package/dist/hooks/magic-context/transform.d.ts +2 -0
  49. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  50. package/dist/index.d.ts.map +1 -1
  51. package/dist/index.js +14944 -14084
  52. package/dist/plugin/conflict-warning-hook.d.ts +10 -0
  53. package/dist/plugin/conflict-warning-hook.d.ts.map +1 -1
  54. package/dist/plugin/dream-timer.d.ts.map +1 -1
  55. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  56. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  57. package/dist/plugin/tool-registry.d.ts.map +1 -1
  58. package/dist/shared/announcement.d.ts +55 -0
  59. package/dist/shared/announcement.d.ts.map +1 -0
  60. package/dist/shared/format-threshold.d.ts +24 -0
  61. package/dist/shared/format-threshold.d.ts.map +1 -0
  62. package/dist/shared/rpc-types.d.ts +2 -0
  63. package/dist/shared/rpc-types.d.ts.map +1 -1
  64. package/dist/shared/subagent-runner.d.ts +5 -0
  65. package/dist/shared/subagent-runner.d.ts.map +1 -1
  66. package/dist/tui/data/context-db.d.ts +14 -0
  67. package/dist/tui/data/context-db.d.ts.map +1 -1
  68. package/package.json +1 -1
  69. package/src/shared/announcement.test.ts +143 -0
  70. package/src/shared/announcement.ts +97 -0
  71. package/src/shared/format-threshold.ts +28 -0
  72. package/src/shared/rpc-types.ts +2 -0
  73. package/src/shared/subagent-runner.ts +14 -0
  74. package/src/tui/data/context-db.ts +45 -0
  75. package/src/tui/index.tsx +85 -29
  76. package/src/tui/slots/sidebar-content.tsx +51 -60
@@ -21,4 +21,14 @@ export declare function cleanupConflictWarnings(client: unknown, directory: stri
21
21
  * Sends an ignored message that auto-deletes after 1 second.
22
22
  */
23
23
  export declare function sendTuiSetupNotification(client: unknown, directory: string, serverUrl?: string): Promise<void>;
24
+ /**
25
+ * Desktop startup announcement: post a one-shot ignored message describing
26
+ * what's new in this release. Mirrors the TUI's RPC-driven dialog path so both
27
+ * surfaces deliver the same announcement once per ANNOUNCEMENT_VERSION.
28
+ *
29
+ * Persistence lives in `getMagicContextStorageDir()/last_announced_version`,
30
+ * shared with the TUI handlers and the Pi plugin so a dismissal in any harness
31
+ * suppresses the others for the same announcement.
32
+ */
33
+ export declare function sendStartupAnnouncement(client: unknown, directory: string, version: string, features: ReadonlyArray<string>, footer: string, markSeen: (version: string) => void): Promise<void>;
24
34
  //# sourceMappingURL=conflict-warning-hook.d.ts.map
@@ -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;AAmLlE;;GAEG;AACH,wBAAsB,mBAAmB,CACrC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,cAAc,GAC/B,OAAO,CAAC,IAAI,CAAC,CA+Cf;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CACzC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAqHf;AAkCD;;;GAGG;AACH,wBAAsB,wBAAwB,CAC1C,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAkEf"}
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;AAoLlE;;GAEG;AACH,wBAAsB,mBAAmB,CACrC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,cAAc,GAC/B,OAAO,CAAC,IAAI,CAAC,CA+Cf;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CACzC,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAqHf;AAkCD;;;GAGG;AACH,wBAAsB,wBAAwB,CAC1C,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAkEf;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,CA8Df"}
@@ -1 +1 @@
1
- {"version":3,"file":"dream-timer.d.ts","sourceRoot":"","sources":["../../src/plugin/dream-timer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAapE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAK7C;;;;;GAKG;AACH,UAAU,mBAAmB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IAChC,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,wBAAwB,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,kBAAkB,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5E,uBAAuB,CAAC,EAAE;QACtB,OAAO,EAAE,OAAO,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,iBAAiB,CAAC,EAAE;QAChB,OAAO,EAAE,OAAO,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACxE;AAQD;;;;;;;;;;GAUG;AACH,wBAAsB,uBAAuB,CACzC,IAAI,EAAE,mBAAmB,GAC1B,OAAO,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC,CA0DnC"}
1
+ {"version":3,"file":"dream-timer.d.ts","sourceRoot":"","sources":["../../src/plugin/dream-timer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAapE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAK7C;;;;;GAKG;AACH,UAAU,mBAAmB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IAChC,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,wBAAwB,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,kBAAkB,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5E,uBAAuB,CAAC,EAAE;QACtB,OAAO,EAAE,OAAO,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,iBAAiB,CAAC,EAAE;QAChB,OAAO,EAAE,OAAO,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACxE;AAQD;;;;;;;;;;GAUG;AACH,wBAAsB,uBAAuB,CACzC,IAAI,EAAE,mBAAmB,GAC1B,OAAO,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC,CA4DnC"}
@@ -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;AAU7D,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;;;;;;qBAoDkuJ,CAAC;;;;;;;;;;;;qBAA9sC,CAAC;mBAAyB,CAAC;iBAAuB,CAAC;iBAAuB,CAAC;0BAAc,CAAC;uBAAiB,CAAC;;;;;;0BAAwgtB,CAAC;;;;;;EAD1o0B"}
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;AAU7D,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;;;;;;qBAoDkuJ,CAAC;;;;;;;;;;;;qBAA9sC,CAAC;mBAAyB,CAAC;iBAAuB,CAAC;iBAAuB,CAAC;0BAAc,CAAC;uBAAiB,CAAC;;;;;;0BAA+luB,CAAC;;;;;;EADju1B"}
@@ -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;AAGzE,OAAO,EAAE,KAAK,eAAe,IAAI,QAAQ,EAAgB,MAAM,mCAAmC,CAAC;AAWnG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AASlF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAmDzE,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,CA6UjB;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,CAuKd;AAED;;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,CAwIN"}
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,EAAE,KAAK,eAAe,IAAI,QAAQ,EAAgB,MAAM,mCAAmC,CAAC;AAWnG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAgBlF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAmDzE,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,CAmVjB;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,CAuKd;AAED;;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,CAkKN"}
@@ -1 +1 @@
1
- {"version":3,"file":"tool-registry.d.ts","sourceRoot":"","sources":["../../src/plugin/tool-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAe1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACrC,GAAG,EAAE,aAAa,CAAC;IACnB,YAAY,EAAE,wBAAwB,CAAC;CAC1C,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAyEjC"}
1
+ {"version":3,"file":"tool-registry.d.ts","sourceRoot":"","sources":["../../src/plugin/tool-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAgB1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACrC,GAAG,EAAE,aAAa,CAAC;IACnB,YAAY,EAAE,wBAAwB,CAAC;CAC1C,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAyEjC"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Release-notes startup announcement shared by OpenCode plugin and Pi plugin.
3
+ *
4
+ * Bump `ANNOUNCEMENT_VERSION` and populate `ANNOUNCEMENT_FEATURES` *only* when a
5
+ * release ships user-facing news worth surfacing once at startup. Patch releases
6
+ * with no user-visible changes should leave both untouched — that way a user who
7
+ * already dismissed the dialog for the current `ANNOUNCEMENT_VERSION` won't see
8
+ * it again on the next bugfix bump.
9
+ *
10
+ * The persisted state is a single line of text (`last_announced_version`) under
11
+ * `getMagicContextStorageDir()`. OpenCode and Pi share the same file because
12
+ * they share the same storage root — so dismissing in one harness suppresses
13
+ * the dialog in the other for the same announcement.
14
+ *
15
+ * Leave both empty (`""` and `[]`) to skip the dialog entirely.
16
+ */
17
+ /**
18
+ * Bump only when there are user-visible changes worth a startup dialog.
19
+ * Does NOT need to match the published package version.
20
+ */
21
+ export declare const ANNOUNCEMENT_VERSION = "0.21.7";
22
+ /**
23
+ * Short, user-facing bullet strings. Keep each line ~80 chars or shorter so the
24
+ * TUI dialog renders cleanly without horizontal scroll on a typical terminal.
25
+ */
26
+ export declare const ANNOUNCEMENT_FEATURES: ReadonlyArray<string>;
27
+ /**
28
+ * Persistent footer rendered below the version-specific bullets in every
29
+ * announcement. Stays in place across releases so users always see the Discord
30
+ * invite without us needing to repeat it in `ANNOUNCEMENT_FEATURES` each time.
31
+ *
32
+ * Leave empty (`""`) to suppress the footer.
33
+ */
34
+ export declare const ANNOUNCEMENT_FOOTER = "Join us on Discord: https://discord.gg/F2uWxjGnU";
35
+ /**
36
+ * Read the most recently dismissed announcement version, or `""` if none.
37
+ *
38
+ * Best-effort: any read failure returns `""` (which forces the announcement to
39
+ * re-show). The cost of a spurious second dialog is much smaller than the cost
40
+ * of suppressing a real announcement due to a transient FS error.
41
+ */
42
+ export declare function readLastAnnouncedVersion(): string;
43
+ /**
44
+ * Persist `version` as the most recently dismissed announcement. Best-effort:
45
+ * write failures are swallowed so dialog-confirm flows never throw on storage
46
+ * errors. Worst case the user sees the same dialog once more on next startup.
47
+ */
48
+ export declare function markAnnouncementSeen(version: string): void;
49
+ /**
50
+ * True when the configured `ANNOUNCEMENT_VERSION` has not yet been dismissed
51
+ * AND there is at least one feature to show. Used by both the TUI dialog path
52
+ * and the Desktop ignored-message fallback.
53
+ */
54
+ export declare function shouldShowAnnouncement(): boolean;
55
+ //# sourceMappingURL=announcement.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"announcement.d.ts","sourceRoot":"","sources":["../../src/shared/announcement.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH;;;GAGG;AACH,eAAO,MAAM,oBAAoB,WAAW,CAAC;AAE7C;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,aAAa,CAAC,MAAM,CAOvD,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,qDAAqD,CAAC;AAQtF;;;;;;GAMG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAQjD;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAS1D;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAGhD"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Format an execute-threshold percentage for human-facing display.
3
+ *
4
+ * `executeThreshold` in the snapshot is always a percentage number, but it
5
+ * comes from two very different config paths:
6
+ * 1. `execute_threshold_percentage` (or its model-keyed variant) — user
7
+ * configures an integer like 65 directly. We must render exactly that.
8
+ * 2. `execute_threshold_tokens` — user configures absolute token cap (e.g.
9
+ * 128000). The resolver in `event-resolvers.ts` divides that by the
10
+ * model's context limit (`(128000 / 907788) * 100`) and the result is
11
+ * a long float like `14.099783080260304` that overflows the TUI cell
12
+ * (issue #90).
13
+ *
14
+ * Behaviour:
15
+ * - Integer input (≤0.05 fractional drift) renders without decimals.
16
+ * - Anything else is rendered with one decimal digit, which is precise
17
+ * enough to convey the configured token budget without smearing across
18
+ * two lines in a narrow sidebar.
19
+ *
20
+ * Returns the formatted percentage WITHOUT the trailing `%` so callers can
21
+ * compose richer strings like `47.5% / 65%` consistently.
22
+ */
23
+ export declare function formatThresholdPercent(value: number | undefined | null): string;
24
+ //# sourceMappingURL=format-threshold.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-threshold.d.ts","sourceRoot":"","sources":["../../src/shared/format-threshold.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAK/E"}
@@ -54,6 +54,8 @@ export interface SidebarSnapshot {
54
54
  * scheduler and transform paths.
55
55
  */
56
56
  executeThreshold: number;
57
+ newWorkTokens?: number | null;
58
+ totalInputTokens?: number | null;
57
59
  }
58
60
  export interface StatusDetail extends SidebarSnapshot {
59
61
  tagCounter: number;
@@ -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,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;CAC5B;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,aAAa,EAAE,MAAM,CAAC;IACtB,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,aAAa,EAAE,MAAM,CAAC;IACtB,uBAAuB,EAAE,MAAM,CAAC;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,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":"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,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;CACpC;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,aAAa,EAAE,MAAM,CAAC;IACtB,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,aAAa,EAAE,MAAM,CAAC;IACtB,uBAAuB,EAAE,MAAM,CAAC;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,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"}
@@ -88,6 +88,11 @@ export interface SubagentRunOptions {
88
88
  * runner's hot path. Errors are swallowed.
89
89
  */
90
90
  onProgress?: (event: SubagentProgressEvent) => void;
91
+ /** Optional token accounting metadata. When present, harness runners persist subagent_invocations. */
92
+ accountingSessionId?: string | undefined;
93
+ accountingSubagent?: "historian" | "historian_editor" | "compressor" | "dreamer" | "sidekick" | "user_memory_review" | "recomp" | undefined;
94
+ accountingTask?: string | null | undefined;
95
+ accountingParentInvocationId?: number | null | undefined;
91
96
  }
92
97
  /**
93
98
  * Progress events emitted by a runner during a run. Distinct from the final
@@ -1 +1 @@
1
- {"version":3,"file":"subagent-runner.d.ts","sourceRoot":"","sources":["../../src/shared/subagent-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,WAAW,kBAAkB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IACjC;;;;;;;;;OASG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAEnC;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC;CACvD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,qBAAqB,GAC3B;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GACrE;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GACtD;IACI,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,KAAK,EAAE,OAAO,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;CACd,GACD;IACI,IAAI,EAAE,UAAU,CAAC;IACjB,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,EAAE,EAAE,MAAM,CAAC;CACd,GACD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAErF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,MAAM,iBAAiB,GACvB;IACI,EAAE,EAAE,IAAI,CAAC;IACT,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC,GACD;IACI,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EACA,SAAS,GACT,OAAO,GACP,cAAc,GACd,WAAW,GACX,cAAc,GACd,eAAe,GACf,cAAc,GACd,cAAc,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC,CAAC;AAER;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc;IAC3B,yEAAyE;IACzE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB;;;;;;OAMG;IACH,GAAG,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAChE"}
1
+ {"version":3,"file":"subagent-runner.d.ts","sourceRoot":"","sources":["../../src/shared/subagent-runner.ts"],"names":[],"mappings":"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"}
@@ -17,6 +17,20 @@ export interface TuiMessage {
17
17
  payload: Record<string, unknown>;
18
18
  sessionId?: string;
19
19
  }
20
+ /**
21
+ * Fetch the current startup announcement from the server, if any.
22
+ * Returns `{show: false}` when there's nothing to announce or when the
23
+ * configured ANNOUNCEMENT_VERSION has already been dismissed.
24
+ */
25
+ export interface AnnouncementResponse {
26
+ show: boolean;
27
+ version?: string;
28
+ features?: string[];
29
+ footer?: string;
30
+ }
31
+ export declare function getAnnouncement(): Promise<AnnouncementResponse>;
32
+ /** Mark the current ANNOUNCEMENT_VERSION as dismissed on the server. */
33
+ export declare function markAnnounced(): Promise<boolean>;
20
34
  /** Poll for pending server→TUI notifications via RPC. */
21
35
  export declare function consumeTuiMessages(): Promise<TuiMessage[]>;
22
36
  //# sourceMappingURL=context-db.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"context-db.d.ts","sourceRoot":"","sources":["../../../src/tui/data/context-db.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAA0B,eAAe,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEpG,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC;AAc9C,2DAA2D;AAC3D,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAGrD;AAED,+BAA+B;AAC/B,wBAAgB,QAAQ,IAAI,IAAI,CAI/B;AAwFD,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,CA4CvB;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,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,yDAAyD;AACzD,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAqBhE"}
1
+ {"version":3,"file":"context-db.d.ts","sourceRoot":"","sources":["../../../src/tui/data/context-db.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAA0B,eAAe,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEpG,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC;AAc9C,2DAA2D;AAC3D,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAGrD;AAED,+BAA+B;AAC/B,wBAAgB,QAAQ,IAAI,IAAI,CAI/B;AA0FD,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,CA4CvB;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,MAAM,WAAW,UAAU;IACvB,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,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAqBhE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/opencode-magic-context",
3
- "version": "0.21.6",
3
+ "version": "0.21.8",
4
4
  "type": "module",
5
5
  "description": "OpenCode plugin for Magic Context — cross-session memory and context management",
6
6
  "main": "dist/index.js",
@@ -0,0 +1,143 @@
1
+ import { afterEach, beforeEach, describe, expect, test } from "bun:test";
2
+ import * as fs from "node:fs";
3
+ import * as os from "node:os";
4
+ import * as path from "node:path";
5
+
6
+ /**
7
+ * `announcement.ts` reads/writes a single `last_announced_version` file under
8
+ * `getMagicContextStorageDir()`. The behavior we test:
9
+ * 1. `markAnnouncementSeen` then `readLastAnnouncedVersion` round-trips
10
+ * 2. `shouldShowAnnouncement` returns false after a matching mark
11
+ * 3. `shouldShowAnnouncement` returns true after a non-matching mark
12
+ * 4. Empty-version inputs are no-ops (don't crash, don't write garbage)
13
+ *
14
+ * We isolate writes by pointing `XDG_DATA_HOME` at a temp dir before requiring
15
+ * the module fresh per test, since the module captures the storage path at
16
+ * import time via `getMagicContextStorageDir()`.
17
+ */
18
+
19
+ let tmpRoot = "";
20
+ let originalXdg: string | undefined;
21
+
22
+ beforeEach(() => {
23
+ tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), "mc-announcement-test-"));
24
+ originalXdg = process.env.XDG_DATA_HOME;
25
+ process.env.XDG_DATA_HOME = tmpRoot;
26
+ });
27
+
28
+ afterEach(() => {
29
+ if (originalXdg === undefined) {
30
+ delete process.env.XDG_DATA_HOME;
31
+ } else {
32
+ process.env.XDG_DATA_HOME = originalXdg;
33
+ }
34
+ try {
35
+ fs.rmSync(tmpRoot, { recursive: true, force: true });
36
+ } catch {
37
+ // best-effort
38
+ }
39
+ });
40
+
41
+ describe("announcement state persistence", () => {
42
+ test("round-trips a dismissed version through the file", async () => {
43
+ // Fresh import after XDG override so the module captures the temp path
44
+ const mod = await import(`./announcement?t=${Date.now()}-rt`);
45
+ const { readLastAnnouncedVersion, markAnnouncementSeen } = mod;
46
+
47
+ expect(readLastAnnouncedVersion()).toBe("");
48
+
49
+ markAnnouncementSeen("9.9.9");
50
+ expect(readLastAnnouncedVersion()).toBe("9.9.9");
51
+
52
+ markAnnouncementSeen("9.9.10");
53
+ expect(readLastAnnouncedVersion()).toBe("9.9.10");
54
+ });
55
+
56
+ test("ignores empty / zero-length version marks", async () => {
57
+ const mod = await import(`./announcement?t=${Date.now()}-empty`);
58
+ const { readLastAnnouncedVersion, markAnnouncementSeen } = mod;
59
+
60
+ markAnnouncementSeen("");
61
+ expect(readLastAnnouncedVersion()).toBe("");
62
+ });
63
+
64
+ test("creates the storage directory if it does not exist", async () => {
65
+ const mod = await import(`./announcement?t=${Date.now()}-mkdir`);
66
+ const { markAnnouncementSeen } = mod;
67
+
68
+ // Storage dir lives under tmpRoot + cortexkit/magic-context — does not
69
+ // exist yet at the start of the test
70
+ const expectedDir = path.join(tmpRoot, "cortexkit", "magic-context");
71
+ expect(fs.existsSync(expectedDir)).toBe(false);
72
+
73
+ markAnnouncementSeen("0.21.7");
74
+
75
+ expect(fs.existsSync(expectedDir)).toBe(true);
76
+ expect(fs.readFileSync(path.join(expectedDir, "last_announced_version"), "utf-8")).toBe(
77
+ "0.21.7",
78
+ );
79
+ });
80
+
81
+ test("trims whitespace from stored version on read", async () => {
82
+ const mod = await import(`./announcement?t=${Date.now()}-trim`);
83
+ const { readLastAnnouncedVersion } = mod;
84
+
85
+ const dir = path.join(tmpRoot, "cortexkit", "magic-context");
86
+ fs.mkdirSync(dir, { recursive: true });
87
+ fs.writeFileSync(path.join(dir, "last_announced_version"), " 1.2.3 \n");
88
+
89
+ expect(readLastAnnouncedVersion()).toBe("1.2.3");
90
+ });
91
+ });
92
+
93
+ describe("shouldShowAnnouncement gating", () => {
94
+ test("returns false when the live version is already marked", async () => {
95
+ const mod = await import(`./announcement?t=${Date.now()}-match`);
96
+ const {
97
+ ANNOUNCEMENT_VERSION,
98
+ ANNOUNCEMENT_FEATURES,
99
+ markAnnouncementSeen,
100
+ shouldShowAnnouncement,
101
+ } = mod;
102
+
103
+ // Skip the test if announcements are currently disabled (empty constants)
104
+ // — the gate's empty-input behavior is covered separately below.
105
+ if (!ANNOUNCEMENT_VERSION || ANNOUNCEMENT_FEATURES.length === 0) {
106
+ return;
107
+ }
108
+
109
+ markAnnouncementSeen(ANNOUNCEMENT_VERSION);
110
+ expect(shouldShowAnnouncement()).toBe(false);
111
+ });
112
+
113
+ test("returns true when the live version was never marked", async () => {
114
+ const mod = await import(`./announcement?t=${Date.now()}-none`);
115
+ const { ANNOUNCEMENT_VERSION, ANNOUNCEMENT_FEATURES, shouldShowAnnouncement } = mod;
116
+
117
+ if (!ANNOUNCEMENT_VERSION || ANNOUNCEMENT_FEATURES.length === 0) {
118
+ // When empty, the gate is always false regardless of state
119
+ expect(shouldShowAnnouncement()).toBe(false);
120
+ return;
121
+ }
122
+
123
+ // No mark has been written in this fresh tmpRoot, so the gate is open
124
+ expect(shouldShowAnnouncement()).toBe(true);
125
+ });
126
+
127
+ test("returns true when a different (older) version is marked", async () => {
128
+ const mod = await import(`./announcement?t=${Date.now()}-older`);
129
+ const {
130
+ ANNOUNCEMENT_VERSION,
131
+ ANNOUNCEMENT_FEATURES,
132
+ markAnnouncementSeen,
133
+ shouldShowAnnouncement,
134
+ } = mod;
135
+
136
+ if (!ANNOUNCEMENT_VERSION || ANNOUNCEMENT_FEATURES.length === 0) {
137
+ return;
138
+ }
139
+
140
+ markAnnouncementSeen("0.0.0-pre-historic");
141
+ expect(shouldShowAnnouncement()).toBe(true);
142
+ });
143
+ });
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Release-notes startup announcement shared by OpenCode plugin and Pi plugin.
3
+ *
4
+ * Bump `ANNOUNCEMENT_VERSION` and populate `ANNOUNCEMENT_FEATURES` *only* when a
5
+ * release ships user-facing news worth surfacing once at startup. Patch releases
6
+ * with no user-visible changes should leave both untouched — that way a user who
7
+ * already dismissed the dialog for the current `ANNOUNCEMENT_VERSION` won't see
8
+ * it again on the next bugfix bump.
9
+ *
10
+ * The persisted state is a single line of text (`last_announced_version`) under
11
+ * `getMagicContextStorageDir()`. OpenCode and Pi share the same file because
12
+ * they share the same storage root — so dismissing in one harness suppresses
13
+ * the dialog in the other for the same announcement.
14
+ *
15
+ * Leave both empty (`""` and `[]`) to skip the dialog entirely.
16
+ */
17
+
18
+ import * as fs from "node:fs";
19
+ import * as path from "node:path";
20
+ import { getMagicContextStorageDir } from "./data-path";
21
+
22
+ /**
23
+ * Bump only when there are user-visible changes worth a startup dialog.
24
+ * Does NOT need to match the published package version.
25
+ */
26
+ export const ANNOUNCEMENT_VERSION = "0.21.7";
27
+
28
+ /**
29
+ * Short, user-facing bullet strings. Keep each line ~80 chars or shorter so the
30
+ * TUI dialog renders cleanly without horizontal scroll on a typical terminal.
31
+ */
32
+ export const ANNOUNCEMENT_FEATURES: ReadonlyArray<string> = [
33
+ "Pi parity sweep: 44 audit findings fixed, including a critical SHIP-BLOCKER where /ctx-flush did not drain the pending Pi compaction queue.",
34
+ "Pi historian recovery fix: empty/no-op historian returns now clear emergency recovery so sessions cannot loop forever at 95%.",
35
+ "trimPiMessagesToBoundary now sweeps non-contiguous tool-result orphans, fixing provider 400s after compaction in long Pi sessions.",
36
+ "Hidden subagent tool isolation: historian, dreamer, and sidekick can no longer spawn subagents or run unsafe tools.",
37
+ "TUI sidebar and /ctx-status header now show execute threshold inline: '47.5% / 65%' on the left, '475K / 1.0M' on the right.",
38
+ "doctor --issue now caps GitHub issue bodies at ~60KB with a dedicated 'Recent errors' section so reports stay submittable.",
39
+ ];
40
+
41
+ /**
42
+ * Persistent footer rendered below the version-specific bullets in every
43
+ * announcement. Stays in place across releases so users always see the Discord
44
+ * invite without us needing to repeat it in `ANNOUNCEMENT_FEATURES` each time.
45
+ *
46
+ * Leave empty (`""`) to suppress the footer.
47
+ */
48
+ export const ANNOUNCEMENT_FOOTER = "Join us on Discord: https://discord.gg/F2uWxjGnU";
49
+
50
+ const STATE_FILENAME = "last_announced_version";
51
+
52
+ function getStateFilePath(): string {
53
+ return path.join(getMagicContextStorageDir(), STATE_FILENAME);
54
+ }
55
+
56
+ /**
57
+ * Read the most recently dismissed announcement version, or `""` if none.
58
+ *
59
+ * Best-effort: any read failure returns `""` (which forces the announcement to
60
+ * re-show). The cost of a spurious second dialog is much smaller than the cost
61
+ * of suppressing a real announcement due to a transient FS error.
62
+ */
63
+ export function readLastAnnouncedVersion(): string {
64
+ try {
65
+ const file = getStateFilePath();
66
+ if (!fs.existsSync(file)) return "";
67
+ return fs.readFileSync(file, "utf-8").trim();
68
+ } catch {
69
+ return "";
70
+ }
71
+ }
72
+
73
+ /**
74
+ * Persist `version` as the most recently dismissed announcement. Best-effort:
75
+ * write failures are swallowed so dialog-confirm flows never throw on storage
76
+ * errors. Worst case the user sees the same dialog once more on next startup.
77
+ */
78
+ export function markAnnouncementSeen(version: string): void {
79
+ if (!version) return;
80
+ try {
81
+ const dir = getMagicContextStorageDir();
82
+ fs.mkdirSync(dir, { recursive: true });
83
+ fs.writeFileSync(getStateFilePath(), version);
84
+ } catch {
85
+ // best-effort
86
+ }
87
+ }
88
+
89
+ /**
90
+ * True when the configured `ANNOUNCEMENT_VERSION` has not yet been dismissed
91
+ * AND there is at least one feature to show. Used by both the TUI dialog path
92
+ * and the Desktop ignored-message fallback.
93
+ */
94
+ export function shouldShowAnnouncement(): boolean {
95
+ if (!ANNOUNCEMENT_VERSION || ANNOUNCEMENT_FEATURES.length === 0) return false;
96
+ return readLastAnnouncedVersion() !== ANNOUNCEMENT_VERSION;
97
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Format an execute-threshold percentage for human-facing display.
3
+ *
4
+ * `executeThreshold` in the snapshot is always a percentage number, but it
5
+ * comes from two very different config paths:
6
+ * 1. `execute_threshold_percentage` (or its model-keyed variant) — user
7
+ * configures an integer like 65 directly. We must render exactly that.
8
+ * 2. `execute_threshold_tokens` — user configures absolute token cap (e.g.
9
+ * 128000). The resolver in `event-resolvers.ts` divides that by the
10
+ * model's context limit (`(128000 / 907788) * 100`) and the result is
11
+ * a long float like `14.099783080260304` that overflows the TUI cell
12
+ * (issue #90).
13
+ *
14
+ * Behaviour:
15
+ * - Integer input (≤0.05 fractional drift) renders without decimals.
16
+ * - Anything else is rendered with one decimal digit, which is precise
17
+ * enough to convey the configured token budget without smearing across
18
+ * two lines in a narrow sidebar.
19
+ *
20
+ * Returns the formatted percentage WITHOUT the trailing `%` so callers can
21
+ * compose richer strings like `47.5% / 65%` consistently.
22
+ */
23
+ export function formatThresholdPercent(value: number | undefined | null): string {
24
+ if (typeof value !== "number" || !Number.isFinite(value)) return "—";
25
+ const rounded = Math.round(value);
26
+ if (Math.abs(value - rounded) < 0.05) return String(rounded);
27
+ return value.toFixed(1);
28
+ }
@@ -55,6 +55,8 @@ export interface SidebarSnapshot {
55
55
  * scheduler and transform paths.
56
56
  */
57
57
  executeThreshold: number;
58
+ newWorkTokens?: number | null;
59
+ totalInputTokens?: number | null;
58
60
  }
59
61
 
60
62
  export interface StatusDetail extends SidebarSnapshot {
@@ -90,6 +90,20 @@ export interface SubagentRunOptions {
90
90
  * runner's hot path. Errors are swallowed.
91
91
  */
92
92
  onProgress?: (event: SubagentProgressEvent) => void;
93
+
94
+ /** Optional token accounting metadata. When present, harness runners persist subagent_invocations. */
95
+ accountingSessionId?: string | undefined;
96
+ accountingSubagent?:
97
+ | "historian"
98
+ | "historian_editor"
99
+ | "compressor"
100
+ | "dreamer"
101
+ | "sidekick"
102
+ | "user_memory_review"
103
+ | "recomp"
104
+ | undefined;
105
+ accountingTask?: string | null | undefined;
106
+ accountingParentInvocationId?: number | null | undefined;
93
107
  }
94
108
 
95
109
  /**
@@ -59,6 +59,8 @@ const EMPTY_SNAPSHOT: SidebarSnapshot = {
59
59
  toolCallTokens: 0,
60
60
  toolDefinitionTokens: 0,
61
61
  executeThreshold: 65,
62
+ newWorkTokens: null,
63
+ totalInputTokens: null,
62
64
  };
63
65
 
64
66
  /**
@@ -233,6 +235,49 @@ export interface TuiMessage {
233
235
  sessionId?: string;
234
236
  }
235
237
 
238
+ /**
239
+ * Fetch the current startup announcement from the server, if any.
240
+ * Returns `{show: false}` when there's nothing to announce or when the
241
+ * configured ANNOUNCEMENT_VERSION has already been dismissed.
242
+ */
243
+ export interface AnnouncementResponse {
244
+ show: boolean;
245
+ version?: string;
246
+ features?: string[];
247
+ footer?: string;
248
+ }
249
+
250
+ export async function getAnnouncement(): Promise<AnnouncementResponse> {
251
+ if (!rpcClient) return { show: false };
252
+ try {
253
+ const result = await rpcClient.call<{
254
+ show?: boolean;
255
+ version?: string;
256
+ features?: string[];
257
+ footer?: string;
258
+ }>("get-announcement", {});
259
+ return {
260
+ show: result.show === true,
261
+ version: result.version,
262
+ features: Array.isArray(result.features) ? result.features : undefined,
263
+ footer: typeof result.footer === "string" ? result.footer : undefined,
264
+ };
265
+ } catch {
266
+ return { show: false };
267
+ }
268
+ }
269
+
270
+ /** Mark the current ANNOUNCEMENT_VERSION as dismissed on the server. */
271
+ export async function markAnnounced(): Promise<boolean> {
272
+ if (!rpcClient) return false;
273
+ try {
274
+ const result = await rpcClient.call<{ ok?: boolean }>("mark-announced", {});
275
+ return result.ok === true;
276
+ } catch {
277
+ return false;
278
+ }
279
+ }
280
+
236
281
  /** Poll for pending server→TUI notifications via RPC. */
237
282
  export async function consumeTuiMessages(): Promise<TuiMessage[]> {
238
283
  if (!rpcClient) return [];