@cortexkit/opencode-magic-context 0.30.3 → 0.30.4
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/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -187
- package/dist/plugin/conflict-warning-hook.d.ts +0 -5
- package/dist/plugin/conflict-warning-hook.d.ts.map +1 -1
- package/dist/shared/announcement.d.ts +1 -1
- package/dist/shared/announcement.d.ts.map +1 -1
- package/dist/shared/tui-config.d.ts +7 -2
- package/dist/shared/tui-config.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/shared/announcement.ts +4 -2
- package/src/shared/tui-config.ts +7 -2
- package/src/tui/index.tsx +0 -127
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAU,YAAY,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAU,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAylBhE,QAAA,MAAM,MAAM,EAAE,YAGb,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -165587,7 +165587,6 @@ var init_rpc_notifications = __esm(() => {
|
|
|
165587
165587
|
// src/plugin/conflict-warning-hook.ts
|
|
165588
165588
|
var exports_conflict_warning_hook = {};
|
|
165589
165589
|
__export(exports_conflict_warning_hook, {
|
|
165590
|
-
sendTuiSetupNotification: () => sendTuiSetupNotification,
|
|
165591
165590
|
sendStartupAnnouncement: () => sendStartupAnnouncement,
|
|
165592
165591
|
sendSchemaFenceWarning: () => sendSchemaFenceWarning,
|
|
165593
165592
|
sendConflictWarning: () => sendConflictWarning,
|
|
@@ -165827,58 +165826,6 @@ async function cleanupEnabledMessages(messages, serverUrl, sessionId) {
|
|
|
165827
165826
|
}
|
|
165828
165827
|
}
|
|
165829
165828
|
}
|
|
165830
|
-
async function sendTuiSetupNotification(client, directory, serverUrl) {
|
|
165831
|
-
const { sessionId } = getDesktopState(directory);
|
|
165832
|
-
if (!sessionId)
|
|
165833
|
-
return;
|
|
165834
|
-
if (await waitForSafeNotificationTarget(client, sessionId) === "skip")
|
|
165835
|
-
return;
|
|
165836
|
-
const text = [
|
|
165837
|
-
`${TUI_SETUP_MARKER}`,
|
|
165838
|
-
"",
|
|
165839
|
-
"Magic Context added its TUI plugin to your tui.json.",
|
|
165840
|
-
"Restart OpenCode to see the sidebar with live context breakdown,",
|
|
165841
|
-
"token usage, historian status, memory counts, and more."
|
|
165842
|
-
].join(`
|
|
165843
|
-
`);
|
|
165844
|
-
try {
|
|
165845
|
-
const c = client;
|
|
165846
|
-
const promptInput = {
|
|
165847
|
-
path: { id: sessionId },
|
|
165848
|
-
body: {
|
|
165849
|
-
noReply: true,
|
|
165850
|
-
parts: [{ type: "text", text, ignored: true }]
|
|
165851
|
-
}
|
|
165852
|
-
};
|
|
165853
|
-
if (typeof c.session?.prompt === "function") {
|
|
165854
|
-
await Promise.resolve(c.session.prompt(promptInput));
|
|
165855
|
-
} else if (typeof c.session?.promptAsync === "function") {
|
|
165856
|
-
await c.session.promptAsync(promptInput);
|
|
165857
|
-
}
|
|
165858
|
-
} catch {
|
|
165859
|
-
return;
|
|
165860
|
-
}
|
|
165861
|
-
if (!serverUrl)
|
|
165862
|
-
return;
|
|
165863
|
-
setTimeout(async () => {
|
|
165864
|
-
try {
|
|
165865
|
-
const msgs = await getSessionMessages(client, sessionId);
|
|
165866
|
-
for (let i = msgs.length - 1;i >= 0; i--) {
|
|
165867
|
-
const msg = msgs[i];
|
|
165868
|
-
const msgId = msg.info?.id;
|
|
165869
|
-
if (!msgId || msg.info?.role !== "user")
|
|
165870
|
-
break;
|
|
165871
|
-
const parts = msg.parts ?? [];
|
|
165872
|
-
const isTuiSetup = parts.length > 0 && parts.every((p) => p.ignored === true && p.type === "text" && typeof p.text === "string" && p.text.startsWith(TUI_SETUP_MARKER));
|
|
165873
|
-
if (isTuiSetup) {
|
|
165874
|
-
await deleteMessage(serverUrl, sessionId, msgId);
|
|
165875
|
-
} else {
|
|
165876
|
-
break;
|
|
165877
|
-
}
|
|
165878
|
-
}
|
|
165879
|
-
} catch {}
|
|
165880
|
-
}, 1000);
|
|
165881
|
-
}
|
|
165882
165829
|
async function sendSchemaFenceWarning(client, directory, detail) {
|
|
165883
165830
|
const { sessionId } = getDesktopState(directory);
|
|
165884
165831
|
if (!sessionId)
|
|
@@ -165960,7 +165907,7 @@ async function sendStartupAnnouncement(client, directory, version2, features, fo
|
|
|
165960
165907
|
}
|
|
165961
165908
|
markSeen(version2);
|
|
165962
165909
|
}
|
|
165963
|
-
var CONFLICT_WARNING_MARKER = "⚠️ Magic Context is disabled due to conflicting configuration:", SCHEMA_FENCE_MARKER = "⚠️ Magic Context is disabled — database is newer than this version", ENABLED_MARKER = "✨ Magic Context is now enabled",
|
|
165910
|
+
var CONFLICT_WARNING_MARKER = "⚠️ Magic Context is disabled due to conflicting configuration:", SCHEMA_FENCE_MARKER = "⚠️ Magic Context is disabled — database is newer than this version", ENABLED_MARKER = "✨ Magic Context is now enabled", ANNOUNCEMENT_MARKER = "✨ Magic Context — what's new in", cachedDesktopStateByDir;
|
|
165964
165911
|
var init_conflict_warning_hook = __esm(() => {
|
|
165965
165912
|
init_conflict_detector();
|
|
165966
165913
|
init_logger();
|
|
@@ -184923,133 +184870,16 @@ function shouldShowAnnouncement() {
|
|
|
184923
184870
|
}
|
|
184924
184871
|
return ordering > 0;
|
|
184925
184872
|
}
|
|
184926
|
-
var ANNOUNCEMENT_VERSION = "0.30.
|
|
184873
|
+
var ANNOUNCEMENT_VERSION = "0.30.4", ANNOUNCEMENT_FEATURES, ANNOUNCEMENT_FOOTER = "Join us on Discord: https://discord.gg/F2uWxjGnU", STATE_FILENAME = "last_announced_version";
|
|
184927
184874
|
var init_announcement = __esm(() => {
|
|
184928
184875
|
init_data_path();
|
|
184929
184876
|
ANNOUNCEMENT_FEATURES = [
|
|
184930
|
-
"
|
|
184877
|
+
"Pi: fixed historian and dreamer failing when your model comes from a provider extension (Antigravity, Anthropic OAuth, etc.). Subagents now load your extensions.",
|
|
184878
|
+
"Pi: fixed the retrospective and refresh-primers dreamer tasks reading sessions through the wrong API.",
|
|
184879
|
+
"OpenCode: the plugin no longer re-adds its TUI sidebar entry on startup, so removing it from tui.jsonc now sticks."
|
|
184931
184880
|
];
|
|
184932
184881
|
});
|
|
184933
184882
|
|
|
184934
|
-
// src/shared/tui-config.ts
|
|
184935
|
-
var exports_tui_config = {};
|
|
184936
|
-
__export(exports_tui_config, {
|
|
184937
|
-
ensureTuiPluginEntry: () => ensureTuiPluginEntry
|
|
184938
|
-
});
|
|
184939
|
-
import {
|
|
184940
|
-
chmodSync as chmodSync4,
|
|
184941
|
-
existsSync as existsSync19,
|
|
184942
|
-
mkdirSync as mkdirSync12,
|
|
184943
|
-
readFileSync as readFileSync15,
|
|
184944
|
-
renameSync as renameSync6,
|
|
184945
|
-
statSync as statSync8,
|
|
184946
|
-
writeFileSync as writeFileSync12
|
|
184947
|
-
} from "node:fs";
|
|
184948
|
-
import { dirname as dirname10, join as join21 } from "node:path";
|
|
184949
|
-
function pluginEntryId(entry) {
|
|
184950
|
-
if (typeof entry === "string")
|
|
184951
|
-
return entry;
|
|
184952
|
-
if (Array.isArray(entry) && typeof entry[0] === "string")
|
|
184953
|
-
return entry[0];
|
|
184954
|
-
return "";
|
|
184955
|
-
}
|
|
184956
|
-
function isLocalMagicContextDevEntry(entry) {
|
|
184957
|
-
const id = pluginEntryId(entry);
|
|
184958
|
-
if (!id)
|
|
184959
|
-
return false;
|
|
184960
|
-
if (id === PLUGIN_NAME || id.startsWith(`${PLUGIN_NAME}@`))
|
|
184961
|
-
return false;
|
|
184962
|
-
const isPath = id.startsWith("file://") || id.startsWith("/") || id.startsWith("./") || id.includes("\\");
|
|
184963
|
-
if (!isPath)
|
|
184964
|
-
return false;
|
|
184965
|
-
return id.includes("opencode-magic-context") || id.includes("magic-context");
|
|
184966
|
-
}
|
|
184967
|
-
function isMagicContextPluginEntry(entry) {
|
|
184968
|
-
const id = pluginEntryId(entry);
|
|
184969
|
-
if (!id)
|
|
184970
|
-
return false;
|
|
184971
|
-
if (id === PLUGIN_NAME || id.startsWith(`${PLUGIN_NAME}@`))
|
|
184972
|
-
return true;
|
|
184973
|
-
return isLocalMagicContextDevEntry(entry);
|
|
184974
|
-
}
|
|
184975
|
-
function writeTuiConfigAtomic(configPath, config2) {
|
|
184976
|
-
const body = `${import_comment_json3.stringify(config2, null, 2)}
|
|
184977
|
-
`;
|
|
184978
|
-
const tmpPath = `${configPath}.tmp`;
|
|
184979
|
-
writeFileSync12(tmpPath, body);
|
|
184980
|
-
try {
|
|
184981
|
-
if (statSync8(configPath, { throwIfNoEntry: false })?.isFile()) {
|
|
184982
|
-
chmodSync4(tmpPath, statSync8(configPath).mode & 511);
|
|
184983
|
-
}
|
|
184984
|
-
} catch {}
|
|
184985
|
-
renameSync6(tmpPath, configPath);
|
|
184986
|
-
}
|
|
184987
|
-
function resolveTuiConfigPath() {
|
|
184988
|
-
const configDir = getOpenCodeConfigPaths({ binary: "opencode" }).configDir;
|
|
184989
|
-
const jsoncPath = join21(configDir, "tui.jsonc");
|
|
184990
|
-
const jsonPath = join21(configDir, "tui.json");
|
|
184991
|
-
if (existsSync19(jsoncPath))
|
|
184992
|
-
return jsoncPath;
|
|
184993
|
-
if (existsSync19(jsonPath))
|
|
184994
|
-
return jsonPath;
|
|
184995
|
-
return jsoncPath;
|
|
184996
|
-
}
|
|
184997
|
-
function ensureTuiPluginEntry() {
|
|
184998
|
-
try {
|
|
184999
|
-
const configPath = resolveTuiConfigPath();
|
|
185000
|
-
let config2 = {};
|
|
185001
|
-
if (existsSync19(configPath)) {
|
|
185002
|
-
const raw = readFileSync15(configPath, "utf-8");
|
|
185003
|
-
config2 = import_comment_json3.parse(raw) ?? {};
|
|
185004
|
-
}
|
|
185005
|
-
const plugins = Array.isArray(config2.plugin) ? [...config2.plugin] : [];
|
|
185006
|
-
const existingIdx = plugins.findIndex(isMagicContextPluginEntry);
|
|
185007
|
-
if (existingIdx >= 0) {
|
|
185008
|
-
const existing = plugins[existingIdx];
|
|
185009
|
-
if (isLocalMagicContextDevEntry(existing)) {
|
|
185010
|
-
return false;
|
|
185011
|
-
}
|
|
185012
|
-
const id = pluginEntryId(existing);
|
|
185013
|
-
if (id === PLUGIN_ENTRY) {
|
|
185014
|
-
return false;
|
|
185015
|
-
}
|
|
185016
|
-
if (id === PLUGIN_NAME) {
|
|
185017
|
-
if (Array.isArray(existing) && existing.length >= 1) {
|
|
185018
|
-
const replacement = [...existing];
|
|
185019
|
-
replacement[0] = PLUGIN_ENTRY;
|
|
185020
|
-
plugins[existingIdx] = replacement;
|
|
185021
|
-
} else {
|
|
185022
|
-
plugins[existingIdx] = PLUGIN_ENTRY;
|
|
185023
|
-
}
|
|
185024
|
-
} else {
|
|
185025
|
-
return false;
|
|
185026
|
-
}
|
|
185027
|
-
} else {
|
|
185028
|
-
const hasDev = plugins.some(isLocalMagicContextDevEntry);
|
|
185029
|
-
if (!hasDev) {
|
|
185030
|
-
plugins.push(PLUGIN_ENTRY);
|
|
185031
|
-
} else {
|
|
185032
|
-
return false;
|
|
185033
|
-
}
|
|
185034
|
-
}
|
|
185035
|
-
config2.plugin = plugins;
|
|
185036
|
-
mkdirSync12(dirname10(configPath), { recursive: true });
|
|
185037
|
-
writeTuiConfigAtomic(configPath, config2);
|
|
185038
|
-
log(`[magic-context] updated TUI plugin entry in ${configPath}`);
|
|
185039
|
-
return true;
|
|
185040
|
-
} catch (error51) {
|
|
185041
|
-
log(`[magic-context] failed to update tui.json: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
185042
|
-
return false;
|
|
185043
|
-
}
|
|
185044
|
-
}
|
|
185045
|
-
var import_comment_json3, PLUGIN_NAME = "@cortexkit/opencode-magic-context", PLUGIN_ENTRY;
|
|
185046
|
-
var init_tui_config = __esm(() => {
|
|
185047
|
-
init_logger();
|
|
185048
|
-
init_opencode_config_dir();
|
|
185049
|
-
import_comment_json3 = __toESM(require_src2(), 1);
|
|
185050
|
-
PLUGIN_ENTRY = `${PLUGIN_NAME}@latest`;
|
|
185051
|
-
});
|
|
185052
|
-
|
|
185053
184883
|
// src/agents/permissions.ts
|
|
185054
184884
|
init_logger();
|
|
185055
184885
|
function buildAllowOnlyPermission(allowedTools, agentLabel) {
|
|
@@ -205134,18 +204964,6 @@ var server = async (ctx) => {
|
|
|
205134
204964
|
const serverUrlStr = serverUrl instanceof URL ? serverUrl.toString().replace(/\/$/, "") : undefined;
|
|
205135
204965
|
cleanupConflictWarnings(ctx.client, ctx.directory, serverUrlStr);
|
|
205136
204966
|
}
|
|
205137
|
-
if (pluginConfig.enabled) {
|
|
205138
|
-
try {
|
|
205139
|
-
const { ensureTuiPluginEntry: ensureTuiPluginEntry2 } = await Promise.resolve().then(() => (init_tui_config(), exports_tui_config));
|
|
205140
|
-
const tuiAdded = ensureTuiPluginEntry2();
|
|
205141
|
-
if (tuiAdded) {
|
|
205142
|
-
const { sendTuiSetupNotification: sendTuiSetupNotification2 } = await Promise.resolve().then(() => (init_conflict_warning_hook(), exports_conflict_warning_hook));
|
|
205143
|
-
const serverUrl = ctx.serverUrl;
|
|
205144
|
-
const serverUrlStr = serverUrl instanceof URL ? serverUrl.toString().replace(/\/$/, "") : undefined;
|
|
205145
|
-
sendTuiSetupNotification2(ctx.client, ctx.directory, serverUrlStr);
|
|
205146
|
-
}
|
|
205147
|
-
} catch {}
|
|
205148
|
-
}
|
|
205149
204967
|
if (pluginConfig.enabled && !conflictResult?.hasConflict) {
|
|
205150
204968
|
try {
|
|
205151
204969
|
const {
|
|
@@ -16,11 +16,6 @@ export declare function sendConflictWarning(client: unknown, directory: string,
|
|
|
16
16
|
* Called at startup when no conflicts exist (plugin is enabled normally).
|
|
17
17
|
*/
|
|
18
18
|
export declare function cleanupConflictWarnings(client: unknown, directory: string, serverUrl?: string): Promise<void>;
|
|
19
|
-
/**
|
|
20
|
-
* Notify the user that tui.json was configured with the sidebar plugin.
|
|
21
|
-
* Sends an ignored message that auto-deletes after 1 second.
|
|
22
|
-
*/
|
|
23
|
-
export declare function sendTuiSetupNotification(client: unknown, directory: string, serverUrl?: string): Promise<void>;
|
|
24
19
|
/**
|
|
25
20
|
* Desktop schema-fence warning. When OpenCode and Pi share context.db and one
|
|
26
21
|
* harness auto-updates first, it migrates the DB to a newer schema; the lagging
|
|
@@ -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;
|
|
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;AAqLlE;;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;;;;;;;;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,CA2Cf;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"}
|
|
@@ -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.30.
|
|
21
|
+
export declare const ANNOUNCEMENT_VERSION = "0.30.4";
|
|
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":"announcement.d.ts","sourceRoot":"","sources":["../../src/shared/announcement.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAOH;;;GAGG;AACH,eAAO,MAAM,oBAAoB,WAAW,CAAC;AAE7C;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,aAAa,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"announcement.d.ts","sourceRoot":"","sources":["../../src/shared/announcement.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAOH;;;GAGG;AACH,eAAO,MAAM,oBAAoB,WAAW,CAAC;AAE7C;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,aAAa,CAAC,MAAM,CAIvD,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,qDAAqD,CAAC;AAyBtF;;;;GAIG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAGjD;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAS1D;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CA0BhD"}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* Configure tui.json with the magic-context TUI plugin entry.
|
|
3
|
+
*
|
|
4
|
+
* Called ONLY from the CLI setup wizard and `doctor` (via the core export) —
|
|
5
|
+
* never at plugin startup. Startup injection would re-add the entry on every
|
|
6
|
+
* launch, so a user who deliberately removed the sidebar could never keep it
|
|
7
|
+
* removed; opting in/out of the sidebar is the user's call, made explicitly
|
|
8
|
+
* through setup or doctor.
|
|
4
9
|
*/
|
|
5
10
|
/**
|
|
6
11
|
* Ensure tui.json has the magic-context TUI plugin entry.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tui-config.d.ts","sourceRoot":"","sources":["../../src/shared/tui-config.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"tui-config.d.ts","sourceRoot":"","sources":["../../src/shared/tui-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAyEH;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAqD9C"}
|
package/package.json
CHANGED
|
@@ -24,14 +24,16 @@ import { getMagicContextStorageDir } from "./data-path";
|
|
|
24
24
|
* Bump only when there are user-visible changes worth a startup dialog.
|
|
25
25
|
* Does NOT need to match the published package version.
|
|
26
26
|
*/
|
|
27
|
-
export const ANNOUNCEMENT_VERSION = "0.30.
|
|
27
|
+
export const ANNOUNCEMENT_VERSION = "0.30.4";
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* Short, user-facing bullet strings. Keep each line ~80 chars or shorter so the
|
|
31
31
|
* TUI dialog renders cleanly without horizontal scroll on a typical terminal.
|
|
32
32
|
*/
|
|
33
33
|
export const ANNOUNCEMENT_FEATURES: ReadonlyArray<string> = [
|
|
34
|
-
"
|
|
34
|
+
"Pi: fixed historian and dreamer failing when your model comes from a provider extension (Antigravity, Anthropic OAuth, etc.). Subagents now load your extensions.",
|
|
35
|
+
"Pi: fixed the retrospective and refresh-primers dreamer tasks reading sessions through the wrong API.",
|
|
36
|
+
"OpenCode: the plugin no longer re-adds its TUI sidebar entry on startup, so removing it from tui.jsonc now sticks.",
|
|
35
37
|
];
|
|
36
38
|
|
|
37
39
|
/**
|
package/src/shared/tui-config.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* Configure tui.json with the magic-context TUI plugin entry.
|
|
3
|
+
*
|
|
4
|
+
* Called ONLY from the CLI setup wizard and `doctor` (via the core export) —
|
|
5
|
+
* never at plugin startup. Startup injection would re-add the entry on every
|
|
6
|
+
* launch, so a user who deliberately removed the sidebar could never keep it
|
|
7
|
+
* removed; opting in/out of the sidebar is the user's call, made explicitly
|
|
8
|
+
* through setup or doctor.
|
|
4
9
|
*/
|
|
5
10
|
|
|
6
11
|
import {
|
package/src/tui/index.tsx
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
/** @jsxImportSource @opentui/solid */
|
|
2
2
|
// @ts-nocheck
|
|
3
|
-
import { existsSync, mkdirSync, writeFileSync } from "node:fs"
|
|
4
|
-
import { dirname, join } from "node:path"
|
|
5
3
|
import { createMemo } from "solid-js"
|
|
6
4
|
import type { TuiPlugin, TuiPluginApi, TuiThemeCurrent } from "@opencode-ai/plugin/tui"
|
|
7
5
|
import { createSidebarContentSlot, kickRecompProgressRefresh } from "./slots/sidebar-content"
|
|
@@ -11,10 +9,7 @@ import { startNotificationSocket, stopNotificationSocket, type SocketNotificatio
|
|
|
11
9
|
import { formatThresholdPercent } from "../shared/format-threshold"
|
|
12
10
|
import { detectConflicts } from "../shared/conflict-detector"
|
|
13
11
|
import { fixConflicts } from "../shared/conflict-fixer"
|
|
14
|
-
import { readJsoncFile } from "../shared/jsonc-parser"
|
|
15
|
-
import { getOpenCodeConfigPaths } from "../shared/opencode-config-dir"
|
|
16
12
|
|
|
17
|
-
const PLUGIN_NAME = "@cortexkit/opencode-magic-context"
|
|
18
13
|
const DEFAULT_TOAST_DURATION_MS = 5000
|
|
19
14
|
let unifiedToastDurationMs = DEFAULT_TOAST_DURATION_MS
|
|
20
15
|
|
|
@@ -58,71 +53,6 @@ function showToast(
|
|
|
58
53
|
})
|
|
59
54
|
}
|
|
60
55
|
|
|
61
|
-
function ensureParentDir(filePath: string) {
|
|
62
|
-
mkdirSync(dirname(filePath), { recursive: true })
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function resolveTuiConfigPath() {
|
|
66
|
-
const configDir = getOpenCodeConfigPaths({ binary: "opencode" }).configDir
|
|
67
|
-
const jsoncPath = join(configDir, "tui.jsonc")
|
|
68
|
-
const jsonPath = join(configDir, "tui.json")
|
|
69
|
-
|
|
70
|
-
if (existsSync(jsoncPath)) {
|
|
71
|
-
return jsoncPath
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
if (existsSync(jsonPath)) {
|
|
75
|
-
return jsonPath
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return jsonPath
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
function readTuiConfig(filePath: string): Record<string, unknown> | null {
|
|
82
|
-
if (!existsSync(filePath)) {
|
|
83
|
-
return {}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return readJsoncFile<Record<string, unknown>>(filePath)
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function hasMagicContextTuiPlugin(): boolean {
|
|
90
|
-
const configPath = resolveTuiConfigPath()
|
|
91
|
-
const config = readTuiConfig(configPath)
|
|
92
|
-
if (!config) {
|
|
93
|
-
return false
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const plugins = Array.isArray(config.plugin)
|
|
97
|
-
? config.plugin.filter((plugin): plugin is string => typeof plugin === "string")
|
|
98
|
-
: []
|
|
99
|
-
|
|
100
|
-
return plugins.some((plugin) => plugin === PLUGIN_NAME || plugin.startsWith(`${PLUGIN_NAME}@`))
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function addMagicContextTuiPlugin(): { ok: boolean; updated: boolean } {
|
|
104
|
-
const configPath = resolveTuiConfigPath()
|
|
105
|
-
const config = readTuiConfig(configPath)
|
|
106
|
-
if (!config) {
|
|
107
|
-
return { ok: false, updated: false }
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
const plugins = Array.isArray(config.plugin)
|
|
111
|
-
? config.plugin.filter((plugin): plugin is string => typeof plugin === "string")
|
|
112
|
-
: []
|
|
113
|
-
|
|
114
|
-
if (plugins.some((plugin) => plugin === PLUGIN_NAME || plugin.startsWith(`${PLUGIN_NAME}@`))) {
|
|
115
|
-
return { ok: true, updated: false }
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
plugins.push(PLUGIN_NAME)
|
|
119
|
-
config.plugin = plugins
|
|
120
|
-
|
|
121
|
-
ensureParentDir(configPath)
|
|
122
|
-
writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\n`)
|
|
123
|
-
return { ok: true, updated: true }
|
|
124
|
-
}
|
|
125
|
-
|
|
126
56
|
function showConflictDialog(api: TuiPluginApi, directory: string, reasons: string[], conflicts: ReturnType<typeof detectConflicts>["conflicts"]) {
|
|
127
57
|
api.ui.dialog.replace(() => (
|
|
128
58
|
<api.ui.DialogConfirm
|
|
@@ -157,59 +87,6 @@ function showConflictDialog(api: TuiPluginApi, directory: string, reasons: strin
|
|
|
157
87
|
))
|
|
158
88
|
}
|
|
159
89
|
|
|
160
|
-
function showTuiSetupDialog(api: TuiPluginApi) {
|
|
161
|
-
api.ui.dialog.replace(() => (
|
|
162
|
-
<api.ui.DialogConfirm
|
|
163
|
-
title="✨ Enable Magic Context Sidebar"
|
|
164
|
-
message={[
|
|
165
|
-
"Magic Context can show a sidebar with live context breakdown,",
|
|
166
|
-
"token usage, historian status, memory counts, and dreamer info.",
|
|
167
|
-
"",
|
|
168
|
-
"This requires adding the plugin to your tui.json config",
|
|
169
|
-
"(OpenCode's TUI plugin configuration file).",
|
|
170
|
-
"",
|
|
171
|
-
"Add it now?",
|
|
172
|
-
].join("\n")}
|
|
173
|
-
onConfirm={() => {
|
|
174
|
-
const result = addMagicContextTuiPlugin()
|
|
175
|
-
if (!result.ok) {
|
|
176
|
-
setTimeout(() => {
|
|
177
|
-
api.ui.dialog.replace(() => (
|
|
178
|
-
<api.ui.DialogAlert
|
|
179
|
-
title="❌ Setup Failed"
|
|
180
|
-
message={'Could not update tui.json automatically. Add the plugin manually:\n\n { "plugin": ["@cortexkit/opencode-magic-context"] }'}
|
|
181
|
-
onConfirm={() => {
|
|
182
|
-
showToast(api, { message: "Add plugin to tui.json manually", variant: "warning" })
|
|
183
|
-
}}
|
|
184
|
-
/>
|
|
185
|
-
))
|
|
186
|
-
}, 50)
|
|
187
|
-
return
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
setTimeout(() => {
|
|
191
|
-
api.ui.dialog.replace(() => (
|
|
192
|
-
<api.ui.DialogAlert
|
|
193
|
-
title="✅ Sidebar Enabled"
|
|
194
|
-
message="tui.json updated with Magic Context plugin.\n\nPlease restart OpenCode to see the sidebar."
|
|
195
|
-
onConfirm={() => {
|
|
196
|
-
showToast(api, {
|
|
197
|
-
message: "Restart OpenCode to see the sidebar",
|
|
198
|
-
variant: "warning",
|
|
199
|
-
durationOverrideMs: 10_000,
|
|
200
|
-
})
|
|
201
|
-
}}
|
|
202
|
-
/>
|
|
203
|
-
))
|
|
204
|
-
}, 50)
|
|
205
|
-
}}
|
|
206
|
-
onCancel={() => {
|
|
207
|
-
showToast(api, { message: "You can add the sidebar later via: npx @cortexkit/opencode-magic-context@latest doctor", variant: "info" })
|
|
208
|
-
}}
|
|
209
|
-
/>
|
|
210
|
-
))
|
|
211
|
-
}
|
|
212
|
-
|
|
213
90
|
function fmt(n: number): string {
|
|
214
91
|
if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`
|
|
215
92
|
if (n >= 1_000) return `${Math.round(n / 1_000)}K`
|
|
@@ -955,10 +832,6 @@ const tui: TuiPlugin = async (api, _options, meta) => {
|
|
|
955
832
|
// launch will retry. Dialog only appears once per ANNOUNCEMENT_VERSION
|
|
956
833
|
// (persisted via mark-announced RPC writing last_announced_version).
|
|
957
834
|
void showStartupAnnouncement(api)
|
|
958
|
-
|
|
959
|
-
// Note: if TUI plugin is loaded, tui.json already has our entry.
|
|
960
|
-
// But if the user added it manually and later removes it, or if they
|
|
961
|
-
// use setup/doctor which handles tui.json, this code is already running.
|
|
962
835
|
}
|
|
963
836
|
|
|
964
837
|
const id = "opencode-magic-context"
|