zam-core 0.10.9 → 0.10.11
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/cli/app.js +122 -47
- package/dist/cli/app.js.map +1 -1
- package/dist/cli/commands/mcp.js +123 -49
- package/dist/cli/commands/mcp.js.map +1 -1
- package/dist/copilot-extension/host.bundle.js +1 -1
- package/dist/copilot-extension/manifest.json +1 -1
- package/dist/copilot-extension/mcp-client.bundle.mjs +1 -1
- package/dist/index.js +56 -35
- package/dist/index.js.map +1 -1
- package/dist/ui/recall-panel.html +82 -6
- package/dist/ui/settings-panel.html +18 -1
- package/dist/vscode-extension/ZAM_Companion_0.10.11.vsix +0 -0
- package/dist/vscode-extension/extension.cjs +27 -26
- package/dist/vscode-extension/host.bundle.js +1537 -1536
- package/dist/vscode-extension/manifest.json +2 -2
- package/package.json +1 -1
- package/dist/vscode-extension/ZAM_Companion_0.10.9.vsix +0 -0
package/dist/cli/app.js
CHANGED
|
@@ -892,9 +892,26 @@ function loadLibsql() {
|
|
|
892
892
|
);
|
|
893
893
|
}
|
|
894
894
|
}
|
|
895
|
+
function isTransientRemoteDatabaseError(err) {
|
|
896
|
+
const message = err instanceof Error ? err.message : "";
|
|
897
|
+
return TRANSIENT_REMOTE_ERROR_PATTERNS.some(
|
|
898
|
+
(pattern) => pattern.test(message)
|
|
899
|
+
);
|
|
900
|
+
}
|
|
895
901
|
async function openDatabase(options = {}) {
|
|
896
902
|
const { dbPath, provider, isRemote, isEmbeddedReplica, configuredCloud } = resolveDatabaseTarget(options);
|
|
897
903
|
const shouldInitialize = options.initialize === true || !isRemote && !isEmbeddedReplica && !existsSync2(dbPath);
|
|
904
|
+
const openViaHttpProvider = async (url) => {
|
|
905
|
+
const db = openRemoteDatabase({
|
|
906
|
+
url,
|
|
907
|
+
authToken: configuredCloud?.token ?? options.authToken
|
|
908
|
+
});
|
|
909
|
+
if (options.initialize) {
|
|
910
|
+
await db.exec(SCHEMA);
|
|
911
|
+
}
|
|
912
|
+
await runMigrations(db);
|
|
913
|
+
return db;
|
|
914
|
+
};
|
|
898
915
|
if (provider === "remote") {
|
|
899
916
|
const url = isRemote ? dbPath : options.syncUrl;
|
|
900
917
|
if (!url) {
|
|
@@ -902,15 +919,7 @@ async function openDatabase(options = {}) {
|
|
|
902
919
|
"The remote database provider is selected but no Turso URL is configured. Run: zam connector setup turso"
|
|
903
920
|
);
|
|
904
921
|
}
|
|
905
|
-
|
|
906
|
-
url,
|
|
907
|
-
authToken: configuredCloud?.token ?? options.authToken
|
|
908
|
-
});
|
|
909
|
-
if (options.initialize) {
|
|
910
|
-
await db2.exec(SCHEMA);
|
|
911
|
-
}
|
|
912
|
-
await runMigrations(db2);
|
|
913
|
-
return db2;
|
|
922
|
+
return openViaHttpProvider(url);
|
|
914
923
|
}
|
|
915
924
|
if (shouldInitialize && !isRemote) {
|
|
916
925
|
const dir = dirname2(dbPath);
|
|
@@ -956,39 +965,43 @@ async function openDatabase(options = {}) {
|
|
|
956
965
|
}
|
|
957
966
|
}
|
|
958
967
|
} catch (nativeErr) {
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
const db2 = openRemoteDatabase({
|
|
962
|
-
url: fallbackUrl,
|
|
963
|
-
authToken: configuredCloud?.token ?? options.authToken
|
|
964
|
-
});
|
|
965
|
-
if (options.initialize) {
|
|
966
|
-
await db2.exec(SCHEMA);
|
|
967
|
-
}
|
|
968
|
-
await runMigrations(db2);
|
|
969
|
-
return db2;
|
|
968
|
+
if (isRemote && !isEmbeddedReplica) {
|
|
969
|
+
return openViaHttpProvider(dbPath);
|
|
970
970
|
}
|
|
971
971
|
throw nativeErr;
|
|
972
972
|
}
|
|
973
973
|
} else {
|
|
974
974
|
driver = openLocalSqlite(dbPath);
|
|
975
975
|
}
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
976
|
+
const finishOpen = async () => {
|
|
977
|
+
if (!isRemote && !isEmbeddedReplica) {
|
|
978
|
+
driver.pragma("journal_mode = WAL");
|
|
979
|
+
}
|
|
980
|
+
driver.pragma("foreign_keys = ON");
|
|
981
|
+
if (!isRemote) {
|
|
982
|
+
driver.pragma("busy_timeout = 5000");
|
|
983
|
+
}
|
|
984
|
+
const db = wrapSyncDatabase(driver);
|
|
985
|
+
if (isEmbeddedReplica) {
|
|
986
|
+
await db.sync?.();
|
|
987
|
+
}
|
|
988
|
+
if (shouldInitialize) {
|
|
989
|
+
await db.exec(SCHEMA);
|
|
990
|
+
}
|
|
991
|
+
await runMigrations(db);
|
|
992
|
+
return db;
|
|
993
|
+
};
|
|
994
|
+
if (isRemote && !isEmbeddedReplica) {
|
|
995
|
+
try {
|
|
996
|
+
return await finishOpen();
|
|
997
|
+
} catch (err) {
|
|
998
|
+
if (isTransientRemoteDatabaseError(err)) {
|
|
999
|
+
return openViaHttpProvider(dbPath);
|
|
1000
|
+
}
|
|
1001
|
+
throw err;
|
|
1002
|
+
}
|
|
989
1003
|
}
|
|
990
|
-
|
|
991
|
-
return db;
|
|
1004
|
+
return finishOpen();
|
|
992
1005
|
}
|
|
993
1006
|
function resolveProvider(options, credentialsMode, isRemote) {
|
|
994
1007
|
if (options.provider) return options.provider;
|
|
@@ -1120,7 +1133,7 @@ async function runMigrations(db) {
|
|
|
1120
1133
|
);
|
|
1121
1134
|
}
|
|
1122
1135
|
}
|
|
1123
|
-
var DEFAULT_DB_DIR, DEFAULT_DB_PATH, require2;
|
|
1136
|
+
var DEFAULT_DB_DIR, DEFAULT_DB_PATH, require2, TRANSIENT_REMOTE_ERROR_PATTERNS;
|
|
1124
1137
|
var init_connection = __esm({
|
|
1125
1138
|
"src/kernel/db/connection.ts"() {
|
|
1126
1139
|
"use strict";
|
|
@@ -1131,6 +1144,14 @@ var init_connection = __esm({
|
|
|
1131
1144
|
DEFAULT_DB_DIR = join2(homedir2(), ".zam");
|
|
1132
1145
|
DEFAULT_DB_PATH = join2(DEFAULT_DB_DIR, "zam.db");
|
|
1133
1146
|
require2 = createRequire(import.meta.url);
|
|
1147
|
+
TRANSIENT_REMOTE_ERROR_PATTERNS = [
|
|
1148
|
+
/status=5\d\d/i,
|
|
1149
|
+
/websocket/i,
|
|
1150
|
+
/stream closed/i,
|
|
1151
|
+
/connection (?:closed|reset|refused)/i,
|
|
1152
|
+
/fetch failed/i,
|
|
1153
|
+
/\b(?:ETIMEDOUT|ENOTFOUND|ECONNREFUSED|ECONNRESET|EAI_AGAIN|EPIPE)\b/
|
|
1154
|
+
];
|
|
1134
1155
|
}
|
|
1135
1156
|
});
|
|
1136
1157
|
|
|
@@ -7855,6 +7876,12 @@ function resolveVscodeExecutable(options = {}) {
|
|
|
7855
7876
|
] : ["/usr/bin/code", "/usr/local/bin/code", "/snap/bin/code"];
|
|
7856
7877
|
return candidates.find((candidate) => exists(candidate)) ?? null;
|
|
7857
7878
|
}
|
|
7879
|
+
function buildVscodeCliInvocation(command, args, platform = process.platform) {
|
|
7880
|
+
const needsShell = platform === "win32" && /\.(cmd|bat)$/i.test(command);
|
|
7881
|
+
if (!needsShell) return { command, args, shell: false };
|
|
7882
|
+
const quote = (value) => `"${value}"`;
|
|
7883
|
+
return { command: quote(command), args: args.map(quote), shell: true };
|
|
7884
|
+
}
|
|
7858
7885
|
function packageVersion() {
|
|
7859
7886
|
const parsed = JSON.parse(
|
|
7860
7887
|
readFileSync11(join14(packageRoot2, "package.json"), "utf8")
|
|
@@ -7910,7 +7937,11 @@ function installVscodeExtension(options) {
|
|
|
7910
7937
|
const existed = existsSync14(plan.launchConfigPath);
|
|
7911
7938
|
const changed = !existed || readFileSync11(plan.launchConfigPath, "utf8") !== launchContent;
|
|
7912
7939
|
const run = options.run ?? ((command, args) => {
|
|
7913
|
-
|
|
7940
|
+
const invocation = buildVscodeCliInvocation(command, args);
|
|
7941
|
+
execFileSync3(invocation.command, invocation.args, {
|
|
7942
|
+
stdio: "pipe",
|
|
7943
|
+
shell: invocation.shell
|
|
7944
|
+
});
|
|
7914
7945
|
});
|
|
7915
7946
|
run(plan.codePath, ["--install-extension", plan.vsixPath, "--force"]);
|
|
7916
7947
|
if (changed) {
|
|
@@ -7967,7 +7998,7 @@ function resolveDeps(deps) {
|
|
|
7967
7998
|
findZam: deps.findZam ?? (() => {
|
|
7968
7999
|
const globalZam = findExecutable("zam");
|
|
7969
8000
|
if (globalZam) return globalZam;
|
|
7970
|
-
if (process.argv[1]
|
|
8001
|
+
if (process.argv[1]?.endsWith("index.js")) {
|
|
7971
8002
|
return process.argv[1];
|
|
7972
8003
|
}
|
|
7973
8004
|
return null;
|
|
@@ -10060,7 +10091,7 @@ async function readWebLink(url) {
|
|
|
10060
10091
|
redirect: "manual",
|
|
10061
10092
|
signal: controller.signal,
|
|
10062
10093
|
headers: {
|
|
10063
|
-
"User-Agent": "ZAM-Content-Studio/0.10.
|
|
10094
|
+
"User-Agent": "ZAM-Content-Studio/0.10.11"
|
|
10064
10095
|
}
|
|
10065
10096
|
});
|
|
10066
10097
|
if (res.status >= 300 && res.status < 400) {
|
|
@@ -10445,9 +10476,11 @@ function findWorkspaceByPath(dir) {
|
|
|
10445
10476
|
);
|
|
10446
10477
|
}
|
|
10447
10478
|
async function clearLegacyWorkspaceDir(db) {
|
|
10479
|
+
if (!db) return;
|
|
10448
10480
|
await deleteSetting(db, LEGACY_WORKSPACE_DIR_KEY);
|
|
10449
10481
|
}
|
|
10450
10482
|
async function migrateLegacyWorkspaceDir(db) {
|
|
10483
|
+
if (!db) return void 0;
|
|
10451
10484
|
const legacyDir = await getSetting(db, LEGACY_WORKSPACE_DIR_KEY);
|
|
10452
10485
|
if (!legacyDir) return void 0;
|
|
10453
10486
|
const path = resolve4(legacyDir);
|
|
@@ -29134,6 +29167,21 @@ async function withDb(fn, onError = defaultErrorHandler) {
|
|
|
29134
29167
|
await db?.close();
|
|
29135
29168
|
}
|
|
29136
29169
|
}
|
|
29170
|
+
async function withOptionalDb(fn, onError = defaultErrorHandler) {
|
|
29171
|
+
let db = null;
|
|
29172
|
+
try {
|
|
29173
|
+
db = await openDatabase();
|
|
29174
|
+
} catch {
|
|
29175
|
+
db = null;
|
|
29176
|
+
}
|
|
29177
|
+
try {
|
|
29178
|
+
await fn(db);
|
|
29179
|
+
} catch (err) {
|
|
29180
|
+
onError(err.message);
|
|
29181
|
+
} finally {
|
|
29182
|
+
await db?.close();
|
|
29183
|
+
}
|
|
29184
|
+
}
|
|
29137
29185
|
function jsonOut(data) {
|
|
29138
29186
|
console.log(JSON.stringify(data, null, 2));
|
|
29139
29187
|
}
|
|
@@ -29343,6 +29391,9 @@ function parseProviderScope(scope) {
|
|
|
29343
29391
|
async function withDb2(fn) {
|
|
29344
29392
|
await withDb(fn, jsonError);
|
|
29345
29393
|
}
|
|
29394
|
+
async function withOptionalDb2(fn) {
|
|
29395
|
+
await withOptionalDb(fn, jsonError);
|
|
29396
|
+
}
|
|
29346
29397
|
var bridgeCommand = new Command2("bridge").description(
|
|
29347
29398
|
"Machine-readable JSON protocol for AI integration"
|
|
29348
29399
|
);
|
|
@@ -29411,7 +29462,7 @@ bridgeCommand.command("update-check").description("Check whether a newer ZAM rel
|
|
|
29411
29462
|
}
|
|
29412
29463
|
});
|
|
29413
29464
|
bridgeCommand.command("workspace-info").description("Report the workspace dir, its default, and the data dir (JSON)").action(async () => {
|
|
29414
|
-
await
|
|
29465
|
+
await withOptionalDb2(async (db) => {
|
|
29415
29466
|
const activeWorkspace = await ensureActiveWorkspace(db);
|
|
29416
29467
|
jsonOut2({
|
|
29417
29468
|
activeWorkspaceId: activeWorkspace.id,
|
|
@@ -29452,7 +29503,7 @@ async function ensureDesktopWorkspace(db) {
|
|
|
29452
29503
|
};
|
|
29453
29504
|
}
|
|
29454
29505
|
bridgeCommand.command("workspace-list").description("List configured ZAM workspaces (JSON)").action(async () => {
|
|
29455
|
-
await
|
|
29506
|
+
await withOptionalDb2(async (db) => {
|
|
29456
29507
|
const activeWorkspace = await ensureActiveWorkspace(db);
|
|
29457
29508
|
const workspaces = getConfiguredWorkspaces();
|
|
29458
29509
|
jsonOut2({
|
|
@@ -29513,7 +29564,7 @@ bridgeCommand.command("workspace-add").description("Register an existing directo
|
|
|
29513
29564
|
if (opts.id && !id) jsonError("A non-empty --id is required");
|
|
29514
29565
|
const kind = parseBridgeWorkspaceKind(opts.kind);
|
|
29515
29566
|
const skillLinks = wireSkills(path, parseSetupAgents(), { quiet: true });
|
|
29516
|
-
await
|
|
29567
|
+
await withOptionalDb2(async (db) => {
|
|
29517
29568
|
const workspace = await activateWorkspacePath(db, path, {
|
|
29518
29569
|
...id ? { id } : {},
|
|
29519
29570
|
...opts.label ? { label: opts.label } : {},
|
|
@@ -29535,7 +29586,7 @@ bridgeCommand.command("workspace-remove").description("Unregister a ZAM workspac
|
|
|
29535
29586
|
if (!id) jsonError("A non-empty --id is required");
|
|
29536
29587
|
const workspace = getConfiguredWorkspaces().find((item) => item.id === id);
|
|
29537
29588
|
if (!workspace) jsonError(`Workspace "${id}" is not configured`);
|
|
29538
|
-
await
|
|
29589
|
+
await withOptionalDb2(async (db) => {
|
|
29539
29590
|
const { activeWorkspace, workspaces } = await removeWorkspaceAndResolveActive(db, id);
|
|
29540
29591
|
const skillLinks = provisionConfiguredWorkspaces();
|
|
29541
29592
|
jsonOut2({
|
|
@@ -29555,7 +29606,7 @@ bridgeCommand.command("set-workspace-dir").description("Set the personal workspa
|
|
|
29555
29606
|
const dir = resolve6(raw);
|
|
29556
29607
|
if (!existsSync21(dir)) jsonError(`Workspace path does not exist: ${dir}`);
|
|
29557
29608
|
const skillLinks = wireSkills(dir, parseSetupAgents(), { quiet: true });
|
|
29558
|
-
await
|
|
29609
|
+
await withOptionalDb2(async (db) => {
|
|
29559
29610
|
const workspace = await activateWorkspacePath(db, dir);
|
|
29560
29611
|
jsonOut2({
|
|
29561
29612
|
ok: true,
|
|
@@ -31155,6 +31206,7 @@ bridgeCommand.command("local-llm-hints").description("Detect installed local LLM
|
|
|
31155
31206
|
var UI_WRITABLE_SETTINGS = /* @__PURE__ */ new Set([
|
|
31156
31207
|
"llm.enabled",
|
|
31157
31208
|
"llm.vision.enabled",
|
|
31209
|
+
"recall.quick_mode",
|
|
31158
31210
|
"system.locale"
|
|
31159
31211
|
]);
|
|
31160
31212
|
bridgeCommand.command("setting-set").description("Set a single allowlisted ZAM setting value (JSON)").requiredOption("--key <key>", "Setting key").requiredOption("--value <value>", "Setting value").action(async (opts) => {
|
|
@@ -31374,6 +31426,9 @@ bridgeCommand.command("get-settings").description("Get active ZAM settings (JSON
|
|
|
31374
31426
|
enabled,
|
|
31375
31427
|
url,
|
|
31376
31428
|
model
|
|
31429
|
+
},
|
|
31430
|
+
recall: {
|
|
31431
|
+
quickMode: await getSetting(db, "recall.quick_mode") === "true"
|
|
31377
31432
|
}
|
|
31378
31433
|
});
|
|
31379
31434
|
});
|
|
@@ -32856,8 +32911,17 @@ bridgeCommand.command("unassign-knowledge-context").description("Remove a token
|
|
|
32856
32911
|
});
|
|
32857
32912
|
});
|
|
32858
32913
|
bridgeCommand.command("get-active-knowledge-context").description("Get the active knowledge context name (JSON)").action(async () => {
|
|
32859
|
-
await
|
|
32914
|
+
await withOptionalDb2(async (db) => {
|
|
32860
32915
|
const configured = getActiveWorkspaceContext();
|
|
32916
|
+
if (!db) {
|
|
32917
|
+
jsonOut2({
|
|
32918
|
+
success: true,
|
|
32919
|
+
activeContext: configured ?? null,
|
|
32920
|
+
staleContext: null,
|
|
32921
|
+
validated: false
|
|
32922
|
+
});
|
|
32923
|
+
return;
|
|
32924
|
+
}
|
|
32861
32925
|
const active = configured ? await getKnowledgeContextByName(db, configured) : void 0;
|
|
32862
32926
|
jsonOut2({
|
|
32863
32927
|
success: true,
|
|
@@ -32867,7 +32931,7 @@ bridgeCommand.command("get-active-knowledge-context").description("Get the activ
|
|
|
32867
32931
|
});
|
|
32868
32932
|
});
|
|
32869
32933
|
bridgeCommand.command("set-active-knowledge-context").description("Set the active knowledge context name (JSON)").argument("[name]", "Context name to use (use empty/none to clear)").action(async (name) => {
|
|
32870
|
-
await
|
|
32934
|
+
await withOptionalDb2(async (db) => {
|
|
32871
32935
|
if (!name || name === "none" || name === "null" || name === "undefined") {
|
|
32872
32936
|
if (!setActiveWorkspaceContext(void 0)) {
|
|
32873
32937
|
jsonError("No active workspace configured");
|
|
@@ -32875,6 +32939,13 @@ bridgeCommand.command("set-active-knowledge-context").description("Set the activ
|
|
|
32875
32939
|
jsonOut2({ success: true, activeContext: null });
|
|
32876
32940
|
return;
|
|
32877
32941
|
}
|
|
32942
|
+
if (!db) {
|
|
32943
|
+
if (!setActiveWorkspaceContext(name)) {
|
|
32944
|
+
jsonError("No active workspace configured");
|
|
32945
|
+
}
|
|
32946
|
+
jsonOut2({ success: true, activeContext: name, validated: false });
|
|
32947
|
+
return;
|
|
32948
|
+
}
|
|
32878
32949
|
const context = await getKnowledgeContextByName(db, name);
|
|
32879
32950
|
if (!context) {
|
|
32880
32951
|
jsonError(`Knowledge context not found: ${name}`);
|
|
@@ -36704,7 +36775,11 @@ import { Command as Command17 } from "commander";
|
|
|
36704
36775
|
var settingsCommand = new Command17("settings").description(
|
|
36705
36776
|
"Manage user settings"
|
|
36706
36777
|
);
|
|
36707
|
-
var BOOLEAN_SETTING_KEYS = /* @__PURE__ */ new Set([
|
|
36778
|
+
var BOOLEAN_SETTING_KEYS = /* @__PURE__ */ new Set([
|
|
36779
|
+
"llm.enabled",
|
|
36780
|
+
"llm.vision.enabled",
|
|
36781
|
+
"recall.quick_mode"
|
|
36782
|
+
]);
|
|
36708
36783
|
function normalizeSettingValue(key, value) {
|
|
36709
36784
|
if (!BOOLEAN_SETTING_KEYS.has(key)) return value;
|
|
36710
36785
|
const lower = value.toLowerCase();
|