@cortexkit/opencode-magic-context 0.5.2 → 0.6.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 +18 -2
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli.js +14 -0
- package/dist/config/schema/magic-context.d.ts +21 -0
- package/dist/config/schema/magic-context.d.ts.map +1 -1
- package/dist/features/magic-context/compaction-marker.d.ts +72 -0
- package/dist/features/magic-context/compaction-marker.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/runner.d.ts +8 -0
- package/dist/features/magic-context/dreamer/runner.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/scheduler.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -1
- package/dist/features/magic-context/migrations.d.ts +8 -0
- package/dist/features/magic-context/migrations.d.ts.map +1 -0
- package/dist/features/magic-context/plugin-messages.d.ts +75 -0
- package/dist/features/magic-context/plugin-messages.d.ts.map +1 -0
- package/dist/features/magic-context/storage-db.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-persisted.d.ts +10 -0
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
- package/dist/features/magic-context/storage-notes.d.ts +51 -5
- package/dist/features/magic-context/storage-notes.d.ts.map +1 -1
- package/dist/features/magic-context/storage.d.ts +1 -2
- package/dist/features/magic-context/storage.d.ts.map +1 -1
- package/dist/features/magic-context/user-memory/review-user-memories.d.ts +20 -0
- package/dist/features/magic-context/user-memory/review-user-memories.d.ts.map +1 -0
- package/dist/features/magic-context/user-memory/storage-user-memory.d.ts +33 -0
- package/dist/features/magic-context/user-memory/storage-user-memory.d.ts.map +1 -0
- package/dist/hooks/magic-context/command-handler.d.ts +4 -0
- package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/compaction-marker-manager.d.ts +27 -0
- package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-parser.d.ts +1 -0
- package/dist/hooks/magic-context/compartment-parser.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-prompt.d.ts +4 -1
- package/dist/hooks/magic-context/compartment-prompt.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-compressor.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-types.d.ts +5 -0
- package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook.d.ts +7 -0
- 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/note-nudger.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
- package/dist/hooks/magic-context/system-prompt-hash.d.ts +2 -0
- package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts +4 -0
- package/dist/hooks/magic-context/transform-compartment-phase.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 +1228 -149
- package/dist/plugin/dream-timer.d.ts +4 -0
- package/dist/plugin/dream-timer.d.ts.map +1 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/plugin/tui-action-consumer.d.ts +13 -0
- package/dist/plugin/tui-action-consumer.d.ts.map +1 -0
- package/dist/tools/ctx-note/constants.d.ts +1 -1
- package/dist/tools/ctx-note/constants.d.ts.map +1 -1
- package/dist/tools/ctx-note/tools.d.ts.map +1 -1
- package/dist/tools/ctx-note/types.d.ts +3 -1
- package/dist/tools/ctx-note/types.d.ts.map +1 -1
- package/dist/tui/data/context-db.d.ts +20 -0
- package/dist/tui/data/context-db.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/tui/data/context-db.ts +114 -6
- package/src/tui/index.tsx +77 -2
- package/src/tui/slots/sidebar-content.tsx +3 -2
- package/dist/features/magic-context/storage-smart-notes.d.ts +0 -24
- package/dist/features/magic-context/storage-smart-notes.d.ts.map +0 -1
|
@@ -13,5 +13,9 @@ export declare function startDreamScheduleTimer(args: {
|
|
|
13
13
|
dreamerConfig?: DreamerConfig;
|
|
14
14
|
embeddingConfig: EmbeddingConfig;
|
|
15
15
|
memoryEnabled: boolean;
|
|
16
|
+
experimentalUserMemories?: {
|
|
17
|
+
enabled: boolean;
|
|
18
|
+
promotionThreshold: number;
|
|
19
|
+
};
|
|
16
20
|
}): (() => void) | undefined;
|
|
17
21
|
//# sourceMappingURL=dream-timer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dream-timer.d.ts","sourceRoot":"","sources":["../../src/plugin/dream-timer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAMrF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAK7C;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IAChC,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,eAAe,EAAE,eAAe,CAAC;IACjC,aAAa,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"dream-timer.d.ts","sourceRoot":"","sources":["../../src/plugin/dream-timer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAMrF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAK7C;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IAChC,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,eAAe,EAAE,eAAe,CAAC;IACjC,aAAa,EAAE,OAAO,CAAC;IACvB,wBAAwB,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,kBAAkB,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/E,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAqE3B"}
|
|
@@ -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,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACrC,GAAG,EAAE,aAAa,CAAC;IACnB,YAAY,EAAE,wBAAwB,CAAC;CAC1C;;;;;;
|
|
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,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACrC,GAAG,EAAE,aAAa,CAAC;IACnB,YAAY,EAAE,wBAAwB,CAAC;CAC1C;;;;;;qBA4C+R,CAAC;;;;;;;;;;;;qBATjR,CAAN;mBAAiB,CAAC;;;;;0BASwtW,CAAC;;;;;;EADpvW"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { MagicContextConfig } from "../config/schema/magic-context";
|
|
2
|
+
import type { PluginContext } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Start a server-side consumer that polls plugin_messages for TUI→server
|
|
5
|
+
* action messages and dispatches them. Currently handles:
|
|
6
|
+
* - { command: "recomp" } — executes /ctx-recomp for the given session
|
|
7
|
+
*/
|
|
8
|
+
export declare function startTuiActionConsumer(args: {
|
|
9
|
+
client: PluginContext["client"];
|
|
10
|
+
directory: string;
|
|
11
|
+
config: MagicContextConfig;
|
|
12
|
+
}): (() => void) | undefined;
|
|
13
|
+
//# sourceMappingURL=tui-action-consumer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tui-action-consumer.d.ts","sourceRoot":"","sources":["../../src/plugin/tui-action-consumer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAMzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAQ7C;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IACzC,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,kBAAkB,CAAC;CAC9B,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CA+D3B"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const CTX_NOTE_DESCRIPTION = "Save or inspect durable session notes that persist for this session.\nUse this for short goals, constraints, decisions, or reminders worth carrying forward.\n\nActions:\n- `write`: Append one note. Optionally provide `surface_condition` to create a smart note.\n- `read`: Show current notes
|
|
1
|
+
export declare const CTX_NOTE_DESCRIPTION = "Save or inspect durable session notes that persist for this session.\nUse this for short goals, constraints, decisions, or reminders worth carrying forward.\n\nActions:\n- `write`: Append one note. Optionally provide `surface_condition` to create a smart note.\n- `read`: Show current notes. Defaults to active session notes + ready smart notes; use `filter` to inspect all, pending, ready, active, or dismissed notes.\n- `dismiss`: Dismiss a note by `note_id`.\n- `update`: Update a note by `note_id`.\n\n**Smart Notes**: When `surface_condition` is provided with `write`, the note becomes a project-scoped smart note.\nThe dreamer evaluates smart note conditions during nightly runs and surfaces them when conditions are met.\nExample: `ctx_note(action=\"write\", content=\"Implement X because Y\", surface_condition=\"When PR #42 is merged in this repo\")`\n\nHistorian reads these notes, deduplicates them, and rewrites the remaining useful notes over time.";
|
|
2
2
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-note/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-note/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,s8BAakE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-note/tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,KAAK,cAAc,EAAQ,MAAM,qBAAqB,CAAC;AAchE,MAAM,WAAW,eAAe;IAC5B,EAAE,EAAE,QAAQ,CAAC;IACb,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC5B;
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-note/tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,KAAK,cAAc,EAAQ,MAAM,qBAAqB,CAAC;AAchE,MAAM,WAAW,eAAe;IAC5B,EAAE,EAAE,QAAQ,CAAC;IACb,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC5B;AAkND,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAIxF"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
export type CtxNoteReadFilter = "all" | "active" | "pending" | "ready" | "dismissed";
|
|
1
2
|
export interface CtxNoteArgs {
|
|
2
|
-
action?: "write" | "read" | "
|
|
3
|
+
action?: "write" | "read" | "dismiss" | "update";
|
|
3
4
|
content?: string;
|
|
4
5
|
surface_condition?: string;
|
|
6
|
+
filter?: CtxNoteReadFilter;
|
|
5
7
|
note_id?: number;
|
|
6
8
|
}
|
|
7
9
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-note/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IACxB,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/tools/ctx-note/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,WAAW,CAAC;AAErF,MAAM,WAAW,WAAW;IACxB,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;IACjD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB"}
|
|
@@ -51,4 +51,24 @@ export interface StatusDetail extends SidebarSnapshot {
|
|
|
51
51
|
export declare function closeDb(): void;
|
|
52
52
|
export declare function loadSidebarSnapshot(sessionId: string, directory: string): SidebarSnapshot;
|
|
53
53
|
export declare function loadStatusDetail(sessionId: string, directory: string, modelKey?: string): StatusDetail;
|
|
54
|
+
/**
|
|
55
|
+
* Get compartment count for a session (used by recomp confirmation dialog).
|
|
56
|
+
*/
|
|
57
|
+
export declare function getCompartmentCount(sessionId: string): number;
|
|
58
|
+
/**
|
|
59
|
+
* Consume pending server→TUI messages from the plugin_messages table.
|
|
60
|
+
* Returns consumed messages and marks them as consumed.
|
|
61
|
+
*/
|
|
62
|
+
export interface TuiMessage {
|
|
63
|
+
id: number;
|
|
64
|
+
type: string;
|
|
65
|
+
payload: Record<string, unknown>;
|
|
66
|
+
sessionId: string | null;
|
|
67
|
+
createdAt: number;
|
|
68
|
+
}
|
|
69
|
+
export declare function consumeTuiMessages(): TuiMessage[];
|
|
70
|
+
/**
|
|
71
|
+
* Send a message from TUI to server via plugin_messages.
|
|
72
|
+
*/
|
|
73
|
+
export declare function sendMessageToServer(type: string, payload: Record<string, unknown>, sessionId?: string): boolean;
|
|
54
74
|
//# 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":"AAKA,MAAM,WAAW,eAAe;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,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;IAE/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,sEAAsE;AACtE,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;IAExD,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,OAAO,CAAC;IAEtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,uBAAuB,EAAE,MAAM,CAAC;IAChC,cAAc,EAAE,MAAM,CAAC;IAEvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AA+BD,wBAAgB,OAAO,IAAI,IAAI,CAU9B;AA+BD,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,eAAe,CAuNzF;AAED,wBAAgB,gBAAgB,CAC5B,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,GAClB,YAAY,CAmMd"}
|
|
1
|
+
{"version":3,"file":"context-db.d.ts","sourceRoot":"","sources":["../../../src/tui/data/context-db.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,eAAe;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,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;IAE/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,sEAAsE;AACtE,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;IAExD,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,OAAO,CAAC;IAEtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,uBAAuB,EAAE,MAAM,CAAC;IAChC,cAAc,EAAE,MAAM,CAAC;IAEvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AA+BD,wBAAgB,OAAO,IAAI,IAAI,CAU9B;AA+BD,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,eAAe,CAuNzF;AAED,wBAAgB,gBAAgB,CAC5B,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,GAClB,YAAY,CAmMd;AAyCD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAW7D;AAED;;;GAGG;AACH,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,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,kBAAkB,IAAI,UAAU,EAAE,CAoDjD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,SAAS,CAAC,EAAE,MAAM,GACnB,OAAO,CAiBT"}
|
package/package.json
CHANGED
|
@@ -70,11 +70,11 @@ function getDb(): Database | null {
|
|
|
70
70
|
return cachedDb;
|
|
71
71
|
}
|
|
72
72
|
try {
|
|
73
|
-
// Open
|
|
74
|
-
//
|
|
73
|
+
// Open read-write: WAL-mode DBs need write access to the -shm file,
|
|
74
|
+
// and the TUI writes to plugin_messages for the message bus.
|
|
75
75
|
cachedDb = new Database(targetPath);
|
|
76
76
|
cachedDb.exec("PRAGMA journal_mode = WAL");
|
|
77
|
-
cachedDb.exec("PRAGMA
|
|
77
|
+
cachedDb.exec("PRAGMA busy_timeout = 3000");
|
|
78
78
|
dbPath = targetPath;
|
|
79
79
|
return cachedDb;
|
|
80
80
|
} catch (err) {
|
|
@@ -233,7 +233,7 @@ export function loadSidebarSnapshot(sessionId: string, directory: string): Sideb
|
|
|
233
233
|
try {
|
|
234
234
|
const noteRow = db
|
|
235
235
|
.query<{ count: number }, [string]>(
|
|
236
|
-
`SELECT COUNT(*) as count FROM notes WHERE session_id =
|
|
236
|
+
`SELECT COUNT(*) as count FROM notes WHERE session_id = ? AND type = 'session' AND status = 'active'`,
|
|
237
237
|
)
|
|
238
238
|
.get(sessionId);
|
|
239
239
|
sessionNoteCount = noteRow?.count ?? 0;
|
|
@@ -247,12 +247,12 @@ export function loadSidebarSnapshot(sessionId: string, directory: string): Sideb
|
|
|
247
247
|
try {
|
|
248
248
|
const smartRow = db
|
|
249
249
|
.query<{ count: number }, [string]>(
|
|
250
|
-
`SELECT COUNT(*) as count FROM
|
|
250
|
+
`SELECT COUNT(*) as count FROM notes WHERE project_path = ? AND type = 'smart' AND status = 'ready'`,
|
|
251
251
|
)
|
|
252
252
|
.get(projectIdentity);
|
|
253
253
|
readySmartNoteCount = smartRow?.count ?? 0;
|
|
254
254
|
} catch {
|
|
255
|
-
//
|
|
255
|
+
// notes table may not exist
|
|
256
256
|
}
|
|
257
257
|
}
|
|
258
258
|
|
|
@@ -582,3 +582,111 @@ function readMagicContextConfig(directory: string): Record<string, unknown> | nu
|
|
|
582
582
|
}
|
|
583
583
|
return null;
|
|
584
584
|
}
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* Get compartment count for a session (used by recomp confirmation dialog).
|
|
588
|
+
*/
|
|
589
|
+
export function getCompartmentCount(sessionId: string): number {
|
|
590
|
+
const db = getDb();
|
|
591
|
+
if (!db) return 0;
|
|
592
|
+
try {
|
|
593
|
+
const row = db
|
|
594
|
+
.prepare("SELECT COUNT(*) as count FROM compartments WHERE session_id = ?")
|
|
595
|
+
.get(sessionId) as { count: number } | null;
|
|
596
|
+
return row?.count ?? 0;
|
|
597
|
+
} catch {
|
|
598
|
+
return 0;
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
/**
|
|
603
|
+
* Consume pending server→TUI messages from the plugin_messages table.
|
|
604
|
+
* Returns consumed messages and marks them as consumed.
|
|
605
|
+
*/
|
|
606
|
+
export interface TuiMessage {
|
|
607
|
+
id: number;
|
|
608
|
+
type: string;
|
|
609
|
+
payload: Record<string, unknown>;
|
|
610
|
+
sessionId: string | null;
|
|
611
|
+
createdAt: number;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
export function consumeTuiMessages(): TuiMessage[] {
|
|
615
|
+
const db = getDb();
|
|
616
|
+
if (!db) return [];
|
|
617
|
+
|
|
618
|
+
try {
|
|
619
|
+
// Check if plugin_messages table exists (migration may not have run yet)
|
|
620
|
+
const tableCheck = db
|
|
621
|
+
.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='plugin_messages'")
|
|
622
|
+
.get();
|
|
623
|
+
if (!tableCheck) return [];
|
|
624
|
+
|
|
625
|
+
const now = Date.now();
|
|
626
|
+
const rows = db
|
|
627
|
+
.prepare(
|
|
628
|
+
"SELECT id, type, payload, session_id, created_at FROM plugin_messages WHERE direction = 'server_to_tui' AND consumed_at IS NULL ORDER BY created_at ASC",
|
|
629
|
+
)
|
|
630
|
+
.all() as Array<{
|
|
631
|
+
id: number;
|
|
632
|
+
type: string;
|
|
633
|
+
payload: string;
|
|
634
|
+
session_id: string | null;
|
|
635
|
+
created_at: number;
|
|
636
|
+
}>;
|
|
637
|
+
|
|
638
|
+
if (rows.length === 0) return [];
|
|
639
|
+
|
|
640
|
+
const ids = rows.map((r) => r.id);
|
|
641
|
+
db.prepare(
|
|
642
|
+
`UPDATE plugin_messages SET consumed_at = ? WHERE id IN (${ids.map(() => "?").join(",")})`,
|
|
643
|
+
).run(now, ...ids);
|
|
644
|
+
|
|
645
|
+
// Cleanup old messages
|
|
646
|
+
db.prepare("DELETE FROM plugin_messages WHERE created_at < ?").run(now - 5 * 60 * 1000);
|
|
647
|
+
|
|
648
|
+
return rows.map((r) => {
|
|
649
|
+
let payload: Record<string, unknown> = {};
|
|
650
|
+
try {
|
|
651
|
+
payload = JSON.parse(r.payload);
|
|
652
|
+
} catch {
|
|
653
|
+
// Intentional: malformed payload treated as empty
|
|
654
|
+
}
|
|
655
|
+
return {
|
|
656
|
+
id: r.id,
|
|
657
|
+
type: r.type,
|
|
658
|
+
payload,
|
|
659
|
+
sessionId: r.session_id,
|
|
660
|
+
createdAt: r.created_at,
|
|
661
|
+
};
|
|
662
|
+
});
|
|
663
|
+
} catch {
|
|
664
|
+
return [];
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
/**
|
|
669
|
+
* Send a message from TUI to server via plugin_messages.
|
|
670
|
+
*/
|
|
671
|
+
export function sendMessageToServer(
|
|
672
|
+
type: string,
|
|
673
|
+
payload: Record<string, unknown>,
|
|
674
|
+
sessionId?: string,
|
|
675
|
+
): boolean {
|
|
676
|
+
const db = getDb();
|
|
677
|
+
if (!db) return false;
|
|
678
|
+
|
|
679
|
+
try {
|
|
680
|
+
const tableCheck = db
|
|
681
|
+
.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='plugin_messages'")
|
|
682
|
+
.get();
|
|
683
|
+
if (!tableCheck) return false;
|
|
684
|
+
|
|
685
|
+
db.prepare(
|
|
686
|
+
"INSERT INTO plugin_messages (direction, type, payload, session_id, created_at) VALUES (?, ?, ?, ?, ?)",
|
|
687
|
+
).run("tui_to_server", type, JSON.stringify(payload), sessionId ?? null, Date.now());
|
|
688
|
+
return true;
|
|
689
|
+
} catch {
|
|
690
|
+
return false;
|
|
691
|
+
}
|
|
692
|
+
}
|
package/src/tui/index.tsx
CHANGED
|
@@ -5,7 +5,8 @@ import { dirname, join } from "node:path"
|
|
|
5
5
|
import { createMemo } from "solid-js"
|
|
6
6
|
import type { TuiPlugin, TuiPluginApi, TuiThemeCurrent } from "@opencode-ai/plugin/tui"
|
|
7
7
|
import { createSidebarContentSlot } from "./slots/sidebar-content"
|
|
8
|
-
import
|
|
8
|
+
import packageJson from "../../package.json"
|
|
9
|
+
import { closeDb, consumeTuiMessages, getCompartmentCount, loadStatusDetail, sendMessageToServer, type StatusDetail } from "./data/context-db"
|
|
9
10
|
import { detectConflicts } from "../shared/conflict-detector"
|
|
10
11
|
import { fixConflicts } from "../shared/conflict-fixer"
|
|
11
12
|
import { readJsoncFile } from "../shared/jsonc-parser"
|
|
@@ -278,7 +279,7 @@ const StatusDialog = (props: { api: TuiPluginApi; s: StatusDetail }) => {
|
|
|
278
279
|
{/* Title */}
|
|
279
280
|
<box justifyContent="center" width="100%" marginBottom={1}>
|
|
280
281
|
<text fg={t().accent}>
|
|
281
|
-
<b>⚡ Magic Context Status</b>
|
|
282
|
+
<b>⚡ Magic Context Status</b> <text fg={t().textMuted}>v{packageJson.version}</text>
|
|
282
283
|
</text>
|
|
283
284
|
</box>
|
|
284
285
|
|
|
@@ -406,6 +407,36 @@ function getModelKeyFromMessages(api: TuiPluginApi, sessionId: string): string |
|
|
|
406
407
|
return undefined
|
|
407
408
|
}
|
|
408
409
|
|
|
410
|
+
function showRecompDialog(api: TuiPluginApi) {
|
|
411
|
+
const sessionId = getSessionId(api)
|
|
412
|
+
if (!sessionId) {
|
|
413
|
+
api.ui.toast({ message: "No active session", variant: "warning" })
|
|
414
|
+
return
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
const count = getCompartmentCount(sessionId)
|
|
418
|
+
api.ui.dialog.replace(() => (
|
|
419
|
+
<api.ui.DialogConfirm
|
|
420
|
+
title="⚠️ Recomp Confirmation"
|
|
421
|
+
message={[
|
|
422
|
+
`You have ${count} compartments.`,
|
|
423
|
+
"",
|
|
424
|
+
"Recomp will regenerate all compartments and facts from raw history.",
|
|
425
|
+
"This may take a long time and consume significant tokens.",
|
|
426
|
+
"",
|
|
427
|
+
"Proceed?",
|
|
428
|
+
].join("\n")}
|
|
429
|
+
onConfirm={() => {
|
|
430
|
+
sendMessageToServer("action", { command: "recomp" }, sessionId)
|
|
431
|
+
api.ui.toast({ message: "Recomp requested — historian will start shortly", variant: "info", duration: 5000 })
|
|
432
|
+
}}
|
|
433
|
+
onCancel={() => {
|
|
434
|
+
api.ui.toast({ message: "Recomp cancelled", variant: "info", duration: 3000 })
|
|
435
|
+
}}
|
|
436
|
+
/>
|
|
437
|
+
))
|
|
438
|
+
}
|
|
439
|
+
|
|
409
440
|
function showStatusDialog(api: TuiPluginApi) {
|
|
410
441
|
const sessionId = getSessionId(api)
|
|
411
442
|
if (!sessionId) {
|
|
@@ -435,10 +466,54 @@ const tui: TuiPlugin = async (api, _options, meta) => {
|
|
|
435
466
|
showStatusDialog(api)
|
|
436
467
|
},
|
|
437
468
|
},
|
|
469
|
+
{
|
|
470
|
+
title: "Magic Context: Recomp",
|
|
471
|
+
value: "magic-context.recomp",
|
|
472
|
+
category: "Magic Context",
|
|
473
|
+
slash: { name: "ctx-recomp" },
|
|
474
|
+
onSelect() {
|
|
475
|
+
showRecompDialog(api)
|
|
476
|
+
},
|
|
477
|
+
},
|
|
438
478
|
])
|
|
439
479
|
|
|
480
|
+
// Poll for server→TUI messages (toasts, dialogs) every 2 seconds
|
|
481
|
+
const messagePoller = setInterval(() => {
|
|
482
|
+
try {
|
|
483
|
+
const messages = consumeTuiMessages()
|
|
484
|
+
for (const msg of messages) {
|
|
485
|
+
if (msg.type === "toast") {
|
|
486
|
+
const p = msg.payload
|
|
487
|
+
api.ui.toast({
|
|
488
|
+
message: String(p.message ?? ""),
|
|
489
|
+
variant: (p.variant as "info" | "warning" | "error" | "success") ?? "info",
|
|
490
|
+
duration: typeof p.duration === "number" ? p.duration : 5000,
|
|
491
|
+
})
|
|
492
|
+
} else if (msg.type === "dialog_confirm") {
|
|
493
|
+
const p = msg.payload
|
|
494
|
+
const dialogId = String(p.id ?? "")
|
|
495
|
+
api.ui.dialog.replace(() => (
|
|
496
|
+
<api.ui.DialogConfirm
|
|
497
|
+
title={String(p.title ?? "Confirm")}
|
|
498
|
+
message={String(p.message ?? "")}
|
|
499
|
+
onConfirm={() => {
|
|
500
|
+
sendMessageToServer("dialog_result", { id: dialogId, confirmed: true }, msg.sessionId ?? undefined)
|
|
501
|
+
}}
|
|
502
|
+
onCancel={() => {
|
|
503
|
+
sendMessageToServer("dialog_result", { id: dialogId, confirmed: false }, msg.sessionId ?? undefined)
|
|
504
|
+
}}
|
|
505
|
+
/>
|
|
506
|
+
))
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
} catch {
|
|
510
|
+
// Intentional: message polling should never crash the TUI
|
|
511
|
+
}
|
|
512
|
+
}, 2000)
|
|
513
|
+
|
|
440
514
|
// Clean up on dispose
|
|
441
515
|
api.lifecycle.onDispose(() => {
|
|
516
|
+
clearInterval(messagePoller)
|
|
442
517
|
closeDb()
|
|
443
518
|
})
|
|
444
519
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/** @jsxImportSource @opentui/solid */
|
|
2
2
|
import { createEffect, createMemo, createSignal, on, onCleanup } from "solid-js"
|
|
3
3
|
import type { TuiSlotPlugin, TuiPluginApi, TuiThemeCurrent } from "@opencode-ai/plugin/tui"
|
|
4
|
+
import packageJson from "../../../package.json"
|
|
4
5
|
import { loadSidebarSnapshot, type SidebarSnapshot } from "../data/context-db"
|
|
5
6
|
|
|
6
7
|
const SINGLE_BORDER = { type: "single" } as any
|
|
@@ -303,10 +304,10 @@ const SidebarContent = (props: {
|
|
|
303
304
|
<box flexDirection="row" justifyContent="space-between" alignItems="center">
|
|
304
305
|
<box paddingLeft={1} paddingRight={1} backgroundColor={props.theme.accent}>
|
|
305
306
|
<text fg={props.theme.background}>
|
|
306
|
-
<b>Magic
|
|
307
|
+
<b>Magic Context</b>
|
|
307
308
|
</text>
|
|
308
309
|
</box>
|
|
309
|
-
<text fg={props.theme.
|
|
310
|
+
<text fg={props.theme.textMuted}>v{packageJson.version}</text>
|
|
310
311
|
</box>
|
|
311
312
|
|
|
312
313
|
{/* Token breakdown bar */}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import type { Database } from "bun:sqlite";
|
|
2
|
-
export type SmartNoteStatus = "pending" | "ready" | "dismissed";
|
|
3
|
-
export interface SmartNote {
|
|
4
|
-
id: number;
|
|
5
|
-
projectPath: string;
|
|
6
|
-
content: string;
|
|
7
|
-
surfaceCondition: string;
|
|
8
|
-
status: SmartNoteStatus;
|
|
9
|
-
createdSessionId: string | null;
|
|
10
|
-
createdAt: number;
|
|
11
|
-
updatedAt: number;
|
|
12
|
-
lastCheckedAt: number | null;
|
|
13
|
-
readyAt: number | null;
|
|
14
|
-
readyReason: string | null;
|
|
15
|
-
}
|
|
16
|
-
export declare function addSmartNote(db: Database, projectPath: string, content: string, surfaceCondition: string, sessionId?: string): SmartNote;
|
|
17
|
-
export declare function getSmartNotes(db: Database, projectPath: string, status?: SmartNoteStatus): SmartNote[];
|
|
18
|
-
export declare function getPendingSmartNotes(db: Database, projectPath: string): SmartNote[];
|
|
19
|
-
export declare function getReadySmartNotes(db: Database, projectPath: string): SmartNote[];
|
|
20
|
-
export declare function markSmartNoteReady(db: Database, noteId: number, readyReason?: string): void;
|
|
21
|
-
export declare function markSmartNoteChecked(db: Database, noteId: number): void;
|
|
22
|
-
export declare function dismissSmartNote(db: Database, noteId: number): boolean;
|
|
23
|
-
export declare function deleteSmartNote(db: Database, noteId: number): boolean;
|
|
24
|
-
//# sourceMappingURL=storage-smart-notes.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"storage-smart-notes.d.ts","sourceRoot":"","sources":["../../../src/features/magic-context/storage-smart-notes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,OAAO,GAAG,WAAW,CAAC;AAEhE,MAAM,WAAW,SAAS;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,eAAe,CAAC;IACxB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAiDD,wBAAgB,YAAY,CACxB,EAAE,EAAE,QAAQ,EACZ,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM,EACxB,SAAS,CAAC,EAAE,MAAM,GACnB,SAAS,CAWX;AAED,wBAAgB,aAAa,CACzB,EAAE,EAAE,QAAQ,EACZ,WAAW,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,eAAe,GACzB,SAAS,EAAE,CAMb;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,CAEnF;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,CAEjF;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAK3F;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAOvE;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAKtE;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAGrE"}
|