zam-core 0.10.1 → 0.10.3
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/.agent/skills/zam/SKILL.md +31 -5
- package/.agents/skills/zam/SKILL.md +31 -5
- package/.claude/skills/zam/SKILL.md +31 -5
- package/README.md +5 -3
- package/dist/cli/app.js +725 -281
- package/dist/cli/app.js.map +1 -1
- package/dist/cli/commands/mcp.js +148 -50
- package/dist/cli/commands/mcp.js.map +1 -1
- package/dist/copilot-extension/extension.mjs +520 -0
- package/dist/copilot-extension/host.bundle.js +5317 -0
- package/dist/copilot-extension/manifest.json +9 -0
- package/dist/copilot-extension/mcp-client.bundle.mjs +74 -0
- package/dist/ui/graph-panel.html +21 -18
- package/dist/vscode-extension/ZAM_Companion_0.10.3.vsix +0 -0
- package/dist/vscode-extension/extension.cjs +109 -0
- package/dist/vscode-extension/host.bundle.js +5331 -0
- package/dist/vscode-extension/manifest.json +5 -0
- package/package.json +4 -2
package/dist/cli/app.js
CHANGED
|
@@ -5481,20 +5481,20 @@ import { homedir as homedir5 } from "os";
|
|
|
5481
5481
|
import { join as join8 } from "path";
|
|
5482
5482
|
import { fileURLToPath } from "url";
|
|
5483
5483
|
function getPackageSkillPath(agent = "default") {
|
|
5484
|
-
const
|
|
5484
|
+
const packageRoot4 = [
|
|
5485
5485
|
fileURLToPath(new URL("../../..", import.meta.url)),
|
|
5486
5486
|
fileURLToPath(new URL("../..", import.meta.url)),
|
|
5487
5487
|
fileURLToPath(new URL("..", import.meta.url))
|
|
5488
5488
|
].find((candidate) => existsSync7(join8(candidate, "package.json"))) ?? "";
|
|
5489
|
-
if (!
|
|
5489
|
+
if (!packageRoot4) return "";
|
|
5490
5490
|
if (agent === "codex") {
|
|
5491
|
-
const codexPath = join8(
|
|
5491
|
+
const codexPath = join8(packageRoot4, ".agents", "skills", "zam", "SKILL.md");
|
|
5492
5492
|
if (existsSync7(codexPath)) return codexPath;
|
|
5493
5493
|
return "";
|
|
5494
5494
|
}
|
|
5495
5495
|
if (agent === "claude") {
|
|
5496
5496
|
const claudePath = join8(
|
|
5497
|
-
|
|
5497
|
+
packageRoot4,
|
|
5498
5498
|
".claude",
|
|
5499
5499
|
"skills",
|
|
5500
5500
|
"zam",
|
|
@@ -5503,9 +5503,9 @@ function getPackageSkillPath(agent = "default") {
|
|
|
5503
5503
|
if (existsSync7(claudePath)) return claudePath;
|
|
5504
5504
|
return "";
|
|
5505
5505
|
}
|
|
5506
|
-
let path = join8(
|
|
5506
|
+
let path = join8(packageRoot4, ".agent", "skills", "zam", "SKILL.md");
|
|
5507
5507
|
if (existsSync7(path)) return path;
|
|
5508
|
-
path = join8(
|
|
5508
|
+
path = join8(packageRoot4, ".claude", "skills", "zam", "SKILL.md");
|
|
5509
5509
|
if (existsSync7(path)) return path;
|
|
5510
5510
|
return "";
|
|
5511
5511
|
}
|
|
@@ -6808,16 +6808,16 @@ var init_kernel = __esm({
|
|
|
6808
6808
|
});
|
|
6809
6809
|
|
|
6810
6810
|
// src/cli/app.ts
|
|
6811
|
-
import { readFileSync as
|
|
6812
|
-
import { dirname as
|
|
6813
|
-
import { fileURLToPath as
|
|
6811
|
+
import { readFileSync as readFileSync20 } from "fs";
|
|
6812
|
+
import { dirname as dirname14, join as join29 } from "path";
|
|
6813
|
+
import { fileURLToPath as fileURLToPath8 } from "url";
|
|
6814
6814
|
import { Command as Command27 } from "commander";
|
|
6815
6815
|
|
|
6816
6816
|
// src/cli/commands/agent.ts
|
|
6817
6817
|
init_kernel();
|
|
6818
|
-
import { existsSync as
|
|
6819
|
-
import { homedir as
|
|
6820
|
-
import { dirname as
|
|
6818
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync10, writeFileSync as writeFileSync9 } from "fs";
|
|
6819
|
+
import { homedir as homedir11 } from "os";
|
|
6820
|
+
import { dirname as dirname7, join as join15 } from "path";
|
|
6821
6821
|
import { Command } from "commander";
|
|
6822
6822
|
|
|
6823
6823
|
// src/cli/agent-harness.ts
|
|
@@ -7040,6 +7040,18 @@ function openTerminalWindow(opts) {
|
|
|
7040
7040
|
}
|
|
7041
7041
|
|
|
7042
7042
|
// src/cli/agent-harness.ts
|
|
7043
|
+
var ANTIGRAVITY_IDE_CANDIDATE_PATHS = {
|
|
7044
|
+
darwin: [
|
|
7045
|
+
join12(
|
|
7046
|
+
homedir8(),
|
|
7047
|
+
".antigravity-ide",
|
|
7048
|
+
"antigravity-ide",
|
|
7049
|
+
"bin",
|
|
7050
|
+
"antigravity-ide"
|
|
7051
|
+
),
|
|
7052
|
+
"/Applications/Antigravity IDE.app/Contents/Resources/app/bin/antigravity-ide"
|
|
7053
|
+
]
|
|
7054
|
+
};
|
|
7043
7055
|
var AGENT_HARNESSES = [
|
|
7044
7056
|
{ id: "claude-code", label: "Claude Code", kind: "cli", command: "claude" },
|
|
7045
7057
|
{ id: "codex", label: "Codex", kind: "cli", command: "codex" },
|
|
@@ -7061,19 +7073,41 @@ var AGENT_HARNESSES = [
|
|
|
7061
7073
|
id: "antigravity",
|
|
7062
7074
|
label: "Antigravity",
|
|
7063
7075
|
kind: "app",
|
|
7064
|
-
command: "antigravity"
|
|
7076
|
+
command: "antigravity",
|
|
7077
|
+
candidatePaths: {
|
|
7078
|
+
darwin: [
|
|
7079
|
+
...ANTIGRAVITY_IDE_CANDIDATE_PATHS.darwin ?? [],
|
|
7080
|
+
"/Applications/Antigravity.app/Contents/MacOS/Antigravity"
|
|
7081
|
+
]
|
|
7082
|
+
}
|
|
7065
7083
|
},
|
|
7066
7084
|
{ id: "goose", label: "goose", kind: "cli", command: "goose" }
|
|
7067
7085
|
];
|
|
7068
7086
|
function getHarness(id) {
|
|
7069
7087
|
return AGENT_HARNESSES.find((h) => h.id === id);
|
|
7070
7088
|
}
|
|
7089
|
+
function resolveAntigravityIdeExecutable(deps = {}) {
|
|
7090
|
+
const find = deps.find ?? findExecutable;
|
|
7091
|
+
const exists = deps.exists ?? existsSync12;
|
|
7092
|
+
const platform = deps.platform ?? process.platform;
|
|
7093
|
+
const found = find("antigravity-ide");
|
|
7094
|
+
if (found) return found;
|
|
7095
|
+
return ANTIGRAVITY_IDE_CANDIDATE_PATHS[platform]?.find((path) => exists(path)) ?? null;
|
|
7096
|
+
}
|
|
7071
7097
|
function resolveHarnessExecutable(harness, overrideCommand, deps = {}) {
|
|
7072
7098
|
const find = deps.find ?? findExecutable;
|
|
7073
7099
|
const exists = deps.exists ?? existsSync12;
|
|
7074
7100
|
const platform = deps.platform ?? process.platform;
|
|
7075
7101
|
const found = find(overrideCommand || harness.command);
|
|
7076
7102
|
if (found) return found;
|
|
7103
|
+
if (!overrideCommand && harness.id === "antigravity") {
|
|
7104
|
+
const foundIde = resolveAntigravityIdeExecutable({
|
|
7105
|
+
find,
|
|
7106
|
+
exists,
|
|
7107
|
+
platform
|
|
7108
|
+
});
|
|
7109
|
+
if (foundIde) return foundIde;
|
|
7110
|
+
}
|
|
7077
7111
|
if (harness.kind === "app") {
|
|
7078
7112
|
for (const candidate of harness.candidatePaths?.[platform] ?? []) {
|
|
7079
7113
|
if (exists(candidate)) return candidate;
|
|
@@ -7118,6 +7152,76 @@ function launchHarness(harness, opts) {
|
|
|
7118
7152
|
console.log(`Launched ${harness.label} in ${opts.workspace}`);
|
|
7119
7153
|
}
|
|
7120
7154
|
}
|
|
7155
|
+
function detectInstalledConnectHarnesses(options = {}) {
|
|
7156
|
+
const home = options.home ?? homedir8();
|
|
7157
|
+
const platform = options.platform ?? process.platform;
|
|
7158
|
+
const find = options.find ?? findExecutable;
|
|
7159
|
+
const exists = options.exists ?? existsSync12;
|
|
7160
|
+
const detected = [];
|
|
7161
|
+
const hasCommandOrPath = (command, paths = []) => Boolean(find(command)) || paths.some((path) => exists(path));
|
|
7162
|
+
if (hasCommandOrPath("codex", [
|
|
7163
|
+
join12(home, ".codex"),
|
|
7164
|
+
...platform === "darwin" ? ["/Applications/Codex.app"] : platform === "win32" ? [join12(home, "AppData", "Local", "Programs", "Codex")] : []
|
|
7165
|
+
])) {
|
|
7166
|
+
detected.push("codex");
|
|
7167
|
+
}
|
|
7168
|
+
const vscodePaths = platform === "darwin" ? [
|
|
7169
|
+
"/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code",
|
|
7170
|
+
join12(
|
|
7171
|
+
home,
|
|
7172
|
+
"Applications",
|
|
7173
|
+
"Visual Studio Code.app",
|
|
7174
|
+
"Contents",
|
|
7175
|
+
"Resources",
|
|
7176
|
+
"app",
|
|
7177
|
+
"bin",
|
|
7178
|
+
"code"
|
|
7179
|
+
)
|
|
7180
|
+
] : platform === "win32" ? [
|
|
7181
|
+
join12(
|
|
7182
|
+
home,
|
|
7183
|
+
"AppData",
|
|
7184
|
+
"Local",
|
|
7185
|
+
"Programs",
|
|
7186
|
+
"Microsoft VS Code",
|
|
7187
|
+
"bin",
|
|
7188
|
+
"code.cmd"
|
|
7189
|
+
)
|
|
7190
|
+
] : ["/usr/bin/code", "/usr/local/bin/code", "/snap/bin/code"];
|
|
7191
|
+
if (hasCommandOrPath("code", vscodePaths)) detected.push("vscode");
|
|
7192
|
+
const copilotHome = options.copilotHome ?? join12(home, ".copilot");
|
|
7193
|
+
if (hasCommandOrPath("copilot", [
|
|
7194
|
+
copilotHome,
|
|
7195
|
+
...platform === "darwin" ? ["/Applications/GitHub Copilot.app"] : []
|
|
7196
|
+
])) {
|
|
7197
|
+
detected.push("copilot");
|
|
7198
|
+
}
|
|
7199
|
+
if (hasCommandOrPath("opencode", [join12(home, ".config", "opencode")])) {
|
|
7200
|
+
detected.push("opencode");
|
|
7201
|
+
}
|
|
7202
|
+
if (hasCommandOrPath("goose", [join12(home, ".config", "goose")])) {
|
|
7203
|
+
detected.push("goose");
|
|
7204
|
+
}
|
|
7205
|
+
if (hasCommandOrPath("antigravity", [
|
|
7206
|
+
join12(home, ".gemini", "config"),
|
|
7207
|
+
...platform === "darwin" ? [
|
|
7208
|
+
join12(
|
|
7209
|
+
home,
|
|
7210
|
+
".antigravity-ide",
|
|
7211
|
+
"antigravity-ide",
|
|
7212
|
+
"bin",
|
|
7213
|
+
"antigravity-ide"
|
|
7214
|
+
),
|
|
7215
|
+
"/Applications/Antigravity.app",
|
|
7216
|
+
"/Applications/Antigravity IDE.app"
|
|
7217
|
+
] : []
|
|
7218
|
+
]) || find("antigravity-ide")) {
|
|
7219
|
+
detected.push("antigravity");
|
|
7220
|
+
}
|
|
7221
|
+
const claudeDesktopPath = platform === "darwin" ? "/Applications/Claude.app" : platform === "win32" ? join12(home, "AppData", "Local", "AnthropicClaude") : join12(home, ".config", "Claude");
|
|
7222
|
+
if (exists(claudeDesktopPath)) detected.push("claude-desktop");
|
|
7223
|
+
return detected;
|
|
7224
|
+
}
|
|
7121
7225
|
function parseMcpJsonConfig(path, content) {
|
|
7122
7226
|
let parsed;
|
|
7123
7227
|
try {
|
|
@@ -7248,6 +7352,36 @@ approval_mode = "prompt"
|
|
|
7248
7352
|
content = existingStr ? `${existingStr.trimEnd()}
|
|
7249
7353
|
${block}` : block;
|
|
7250
7354
|
}
|
|
7355
|
+
} else if (harnessId === "vscode") {
|
|
7356
|
+
const platform = opts.platform ?? process.platform;
|
|
7357
|
+
targetPath = platform === "win32" ? join12(opts.home, "AppData", "Roaming", "Code", "User", "mcp.json") : platform === "darwin" ? join12(
|
|
7358
|
+
opts.home,
|
|
7359
|
+
"Library",
|
|
7360
|
+
"Application Support",
|
|
7361
|
+
"Code",
|
|
7362
|
+
"User",
|
|
7363
|
+
"mcp.json"
|
|
7364
|
+
) : join12(opts.home, ".config", "Code", "User", "mcp.json");
|
|
7365
|
+
hint = "Reload VS Code after setup. ZAM Companion stays separate from the Codex chat and can be moved to any panel or sidebar.";
|
|
7366
|
+
let existing = {};
|
|
7367
|
+
if (exists(targetPath)) {
|
|
7368
|
+
existing = parseMcpJsonConfig(targetPath, read(targetPath));
|
|
7369
|
+
}
|
|
7370
|
+
if (existing.servers !== void 0 && (typeof existing.servers !== "object" || existing.servers === null || Array.isArray(existing.servers))) {
|
|
7371
|
+
throw new Error(
|
|
7372
|
+
`Cannot update ${targetPath}: servers must be a JSON object`
|
|
7373
|
+
);
|
|
7374
|
+
}
|
|
7375
|
+
if (existing.inputs !== void 0 && !Array.isArray(existing.inputs)) {
|
|
7376
|
+
throw new Error(`Cannot update ${targetPath}: inputs must be an array`);
|
|
7377
|
+
}
|
|
7378
|
+
if (!existing.servers) existing.servers = {};
|
|
7379
|
+
const expectedServer = { command: opts.zamPath, args: ["mcp"] };
|
|
7380
|
+
const currentServer = existing.servers.zam;
|
|
7381
|
+
alreadyConfigured = Array.isArray(existing.inputs) && typeof currentServer === "object" && currentServer !== null && !Array.isArray(currentServer) && JSON.stringify(currentServer) === JSON.stringify(expectedServer);
|
|
7382
|
+
existing.servers.zam = expectedServer;
|
|
7383
|
+
if (!existing.inputs) existing.inputs = [];
|
|
7384
|
+
content = JSON.stringify(existing, null, 2);
|
|
7251
7385
|
} else if (harnessId === "goose") {
|
|
7252
7386
|
targetPath = join12(opts.home, ".config", "goose", "config.yaml");
|
|
7253
7387
|
hint = "goose will load the 'zam' extension on next session start. Run 'goose configure' to manage extensions.";
|
|
@@ -7286,8 +7420,11 @@ ${zamExtension}
|
|
|
7286
7420
|
`;
|
|
7287
7421
|
}
|
|
7288
7422
|
} else if (harnessId === "copilot") {
|
|
7289
|
-
targetPath = join12(
|
|
7290
|
-
|
|
7423
|
+
targetPath = join12(
|
|
7424
|
+
opts.copilotHome ?? join12(opts.home, ".copilot"),
|
|
7425
|
+
"mcp-config.json"
|
|
7426
|
+
);
|
|
7427
|
+
hint = "Restart GitHub Copilot or start a new session to load the 'zam' MCP server and its focused Recall, Graph, and Settings canvases.";
|
|
7291
7428
|
let existing = {};
|
|
7292
7429
|
if (exists(targetPath)) {
|
|
7293
7430
|
existing = parseMcpJsonConfig(targetPath, read(targetPath));
|
|
@@ -7311,6 +7448,231 @@ ${zamExtension}
|
|
|
7311
7448
|
};
|
|
7312
7449
|
}
|
|
7313
7450
|
|
|
7451
|
+
// src/cli/copilot-extension.ts
|
|
7452
|
+
import {
|
|
7453
|
+
existsSync as existsSync13,
|
|
7454
|
+
lstatSync,
|
|
7455
|
+
mkdirSync as mkdirSync8,
|
|
7456
|
+
readFileSync as readFileSync10,
|
|
7457
|
+
writeFileSync as writeFileSync7
|
|
7458
|
+
} from "fs";
|
|
7459
|
+
import { homedir as homedir9 } from "os";
|
|
7460
|
+
import { dirname as dirname5, join as join13, resolve as resolve3 } from "path";
|
|
7461
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
7462
|
+
var EXTENSION_NAME = "zam-mcp-apps";
|
|
7463
|
+
var EXTENSION_FILES = [
|
|
7464
|
+
"extension.mjs",
|
|
7465
|
+
"host.bundle.js",
|
|
7466
|
+
"mcp-client.bundle.mjs",
|
|
7467
|
+
"manifest.json"
|
|
7468
|
+
];
|
|
7469
|
+
var packageRoot = [
|
|
7470
|
+
fileURLToPath2(new URL("../..", import.meta.url)),
|
|
7471
|
+
fileURLToPath2(new URL("../../..", import.meta.url))
|
|
7472
|
+
].find((candidate) => existsSync13(join13(candidate, "package.json"))) ?? fileURLToPath2(new URL("../..", import.meta.url));
|
|
7473
|
+
function defaultCliEntry() {
|
|
7474
|
+
return join13(dirname5(fileURLToPath2(import.meta.url)), "index.js");
|
|
7475
|
+
}
|
|
7476
|
+
function resolveCopilotHome(home = homedir9(), configuredHome = process.env.COPILOT_HOME) {
|
|
7477
|
+
return configuredHome?.trim() ? resolve3(configuredHome) : join13(home, ".copilot");
|
|
7478
|
+
}
|
|
7479
|
+
function resolveCopilotZamLaunch(zamPath, options = {}) {
|
|
7480
|
+
const cliEntry = options.cliEntry ?? defaultCliEntry();
|
|
7481
|
+
if (existsSync13(cliEntry)) {
|
|
7482
|
+
return {
|
|
7483
|
+
command: options.nodePath ?? process.execPath,
|
|
7484
|
+
args: [cliEntry, "mcp"]
|
|
7485
|
+
};
|
|
7486
|
+
}
|
|
7487
|
+
return {
|
|
7488
|
+
command: zamPath,
|
|
7489
|
+
args: ["mcp"]
|
|
7490
|
+
};
|
|
7491
|
+
}
|
|
7492
|
+
function planCopilotExtensionInstall(options) {
|
|
7493
|
+
const sourceDir = options.assetsDir ?? join13(packageRoot, "dist", "copilot-extension");
|
|
7494
|
+
for (const file of EXTENSION_FILES) {
|
|
7495
|
+
if (!existsSync13(join13(sourceDir, file))) {
|
|
7496
|
+
throw new Error(
|
|
7497
|
+
`Copilot MCP Apps asset is missing: ${join13(sourceDir, file)}. Run \`npm run build\` and retry.`
|
|
7498
|
+
);
|
|
7499
|
+
}
|
|
7500
|
+
}
|
|
7501
|
+
const manifest = JSON.parse(
|
|
7502
|
+
readFileSync10(join13(sourceDir, "manifest.json"), "utf8")
|
|
7503
|
+
);
|
|
7504
|
+
if (manifest.name !== EXTENSION_NAME || typeof manifest.version !== "string" || !manifest.version) {
|
|
7505
|
+
throw new Error(
|
|
7506
|
+
`Invalid Copilot MCP Apps manifest: ${join13(sourceDir, "manifest.json")}`
|
|
7507
|
+
);
|
|
7508
|
+
}
|
|
7509
|
+
const copilotHome = resolveCopilotHome(
|
|
7510
|
+
options.home,
|
|
7511
|
+
options.copilotHome ?? process.env.COPILOT_HOME
|
|
7512
|
+
);
|
|
7513
|
+
return {
|
|
7514
|
+
sourceDir,
|
|
7515
|
+
destinationDir: join13(copilotHome, "extensions", EXTENSION_NAME),
|
|
7516
|
+
launch: resolveCopilotZamLaunch(options.zamPath, options),
|
|
7517
|
+
files: EXTENSION_FILES
|
|
7518
|
+
};
|
|
7519
|
+
}
|
|
7520
|
+
function writeIfChanged(path, content) {
|
|
7521
|
+
const next = Buffer.isBuffer(content) ? content : Buffer.from(content);
|
|
7522
|
+
if (existsSync13(path) && readFileSync10(path).equals(next)) return false;
|
|
7523
|
+
writeFileSync7(path, next);
|
|
7524
|
+
return true;
|
|
7525
|
+
}
|
|
7526
|
+
function installCopilotExtension(options) {
|
|
7527
|
+
const plan = planCopilotExtensionInstall(options);
|
|
7528
|
+
if (options.dryRun) {
|
|
7529
|
+
return { ...plan, action: "planned", changedFiles: [] };
|
|
7530
|
+
}
|
|
7531
|
+
const destinationExisted = existsSync13(plan.destinationDir);
|
|
7532
|
+
if (destinationExisted && lstatSync(plan.destinationDir).isSymbolicLink()) {
|
|
7533
|
+
throw new Error(
|
|
7534
|
+
`Refusing to replace symlinked Copilot extension directory: ${plan.destinationDir}`
|
|
7535
|
+
);
|
|
7536
|
+
}
|
|
7537
|
+
mkdirSync8(plan.destinationDir, { recursive: true });
|
|
7538
|
+
const changedFiles = [];
|
|
7539
|
+
for (const file of plan.files) {
|
|
7540
|
+
const source = join13(plan.sourceDir, file);
|
|
7541
|
+
const destination = join13(plan.destinationDir, file);
|
|
7542
|
+
if (writeIfChanged(destination, readFileSync10(source))) {
|
|
7543
|
+
changedFiles.push(file);
|
|
7544
|
+
}
|
|
7545
|
+
}
|
|
7546
|
+
const launchContent = `${JSON.stringify(
|
|
7547
|
+
{
|
|
7548
|
+
schemaVersion: 1,
|
|
7549
|
+
command: plan.launch.command,
|
|
7550
|
+
args: plan.launch.args
|
|
7551
|
+
},
|
|
7552
|
+
null,
|
|
7553
|
+
2
|
|
7554
|
+
)}
|
|
7555
|
+
`;
|
|
7556
|
+
if (writeIfChanged(join13(plan.destinationDir, "launch.json"), launchContent)) {
|
|
7557
|
+
changedFiles.push("launch.json");
|
|
7558
|
+
}
|
|
7559
|
+
return {
|
|
7560
|
+
...plan,
|
|
7561
|
+
action: !destinationExisted ? "installed" : changedFiles.length > 0 ? "updated" : "unchanged",
|
|
7562
|
+
changedFiles
|
|
7563
|
+
};
|
|
7564
|
+
}
|
|
7565
|
+
|
|
7566
|
+
// src/cli/vscode-extension.ts
|
|
7567
|
+
import { execFileSync as execFileSync3 } from "child_process";
|
|
7568
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync9, readFileSync as readFileSync11, writeFileSync as writeFileSync8 } from "fs";
|
|
7569
|
+
import { homedir as homedir10 } from "os";
|
|
7570
|
+
import { dirname as dirname6, join as join14 } from "path";
|
|
7571
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
7572
|
+
var packageRoot2 = [
|
|
7573
|
+
fileURLToPath3(new URL("../..", import.meta.url)),
|
|
7574
|
+
fileURLToPath3(new URL("../../..", import.meta.url))
|
|
7575
|
+
].find((candidate) => existsSync14(join14(candidate, "package.json"))) ?? fileURLToPath3(new URL("../..", import.meta.url));
|
|
7576
|
+
function resolveVscodeExecutable(options = {}) {
|
|
7577
|
+
const home = options.home ?? homedir10();
|
|
7578
|
+
const platform = options.platform ?? process.platform;
|
|
7579
|
+
const find = options.find ?? findExecutable;
|
|
7580
|
+
const exists = options.exists ?? existsSync14;
|
|
7581
|
+
const found = find("code");
|
|
7582
|
+
if (found) return found;
|
|
7583
|
+
const candidates = platform === "darwin" ? [
|
|
7584
|
+
"/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code",
|
|
7585
|
+
join14(
|
|
7586
|
+
home,
|
|
7587
|
+
"Applications",
|
|
7588
|
+
"Visual Studio Code.app",
|
|
7589
|
+
"Contents",
|
|
7590
|
+
"Resources",
|
|
7591
|
+
"app",
|
|
7592
|
+
"bin",
|
|
7593
|
+
"code"
|
|
7594
|
+
)
|
|
7595
|
+
] : platform === "win32" ? [
|
|
7596
|
+
join14(
|
|
7597
|
+
home,
|
|
7598
|
+
"AppData",
|
|
7599
|
+
"Local",
|
|
7600
|
+
"Programs",
|
|
7601
|
+
"Microsoft VS Code",
|
|
7602
|
+
"bin",
|
|
7603
|
+
"code.cmd"
|
|
7604
|
+
)
|
|
7605
|
+
] : ["/usr/bin/code", "/usr/local/bin/code", "/snap/bin/code"];
|
|
7606
|
+
return candidates.find((candidate) => exists(candidate)) ?? null;
|
|
7607
|
+
}
|
|
7608
|
+
function packageVersion() {
|
|
7609
|
+
const parsed = JSON.parse(
|
|
7610
|
+
readFileSync11(join14(packageRoot2, "package.json"), "utf8")
|
|
7611
|
+
);
|
|
7612
|
+
if (typeof parsed.version !== "string" || !parsed.version) {
|
|
7613
|
+
throw new Error("Cannot determine the ZAM package version");
|
|
7614
|
+
}
|
|
7615
|
+
return parsed.version;
|
|
7616
|
+
}
|
|
7617
|
+
function planVscodeExtensionInstall(options) {
|
|
7618
|
+
const home = options.home ?? homedir10();
|
|
7619
|
+
const version = options.version ?? packageVersion();
|
|
7620
|
+
const assetsDir = options.assetsDir ?? join14(packageRoot2, "dist", "vscode-extension");
|
|
7621
|
+
const vsixPath = join14(assetsDir, `ZAM_Companion_${version}.vsix`);
|
|
7622
|
+
if (!existsSync14(vsixPath)) {
|
|
7623
|
+
throw new Error(
|
|
7624
|
+
`ZAM Companion VSIX asset is missing: ${vsixPath}. Run \`npm run build\` and retry.`
|
|
7625
|
+
);
|
|
7626
|
+
}
|
|
7627
|
+
const codePath = options.codePath ?? resolveVscodeExecutable({
|
|
7628
|
+
home,
|
|
7629
|
+
platform: options.platform,
|
|
7630
|
+
find: options.find,
|
|
7631
|
+
exists: options.exists
|
|
7632
|
+
});
|
|
7633
|
+
if (!codePath) {
|
|
7634
|
+
throw new Error(
|
|
7635
|
+
"Visual Studio Code was not detected. Install VS Code or add its 'code' command to PATH."
|
|
7636
|
+
);
|
|
7637
|
+
}
|
|
7638
|
+
return {
|
|
7639
|
+
version,
|
|
7640
|
+
vsixPath,
|
|
7641
|
+
codePath,
|
|
7642
|
+
launchConfigPath: join14(home, ".zam", "vscode-launch.json"),
|
|
7643
|
+
launch: { command: options.zamPath, args: ["mcp"] }
|
|
7644
|
+
};
|
|
7645
|
+
}
|
|
7646
|
+
function installVscodeExtension(options) {
|
|
7647
|
+
const plan = planVscodeExtensionInstall(options);
|
|
7648
|
+
if (options.dryRun) return { ...plan, action: "planned" };
|
|
7649
|
+
const launchContent = `${JSON.stringify(
|
|
7650
|
+
{
|
|
7651
|
+
schemaVersion: 1,
|
|
7652
|
+
version: plan.version,
|
|
7653
|
+
command: plan.launch.command,
|
|
7654
|
+
args: plan.launch.args
|
|
7655
|
+
},
|
|
7656
|
+
null,
|
|
7657
|
+
2
|
|
7658
|
+
)}
|
|
7659
|
+
`;
|
|
7660
|
+
const existed = existsSync14(plan.launchConfigPath);
|
|
7661
|
+
const changed = !existed || readFileSync11(plan.launchConfigPath, "utf8") !== launchContent;
|
|
7662
|
+
const run = options.run ?? ((command, args) => {
|
|
7663
|
+
execFileSync3(command, args, { stdio: "pipe" });
|
|
7664
|
+
});
|
|
7665
|
+
run(plan.codePath, ["--install-extension", plan.vsixPath, "--force"]);
|
|
7666
|
+
if (changed) {
|
|
7667
|
+
mkdirSync9(dirname6(plan.launchConfigPath), { recursive: true });
|
|
7668
|
+
writeFileSync8(plan.launchConfigPath, launchContent, "utf8");
|
|
7669
|
+
}
|
|
7670
|
+
return {
|
|
7671
|
+
...plan,
|
|
7672
|
+
action: !existed ? "installed" : changed ? "updated" : "unchanged"
|
|
7673
|
+
};
|
|
7674
|
+
}
|
|
7675
|
+
|
|
7314
7676
|
// src/cli/commands/agent.ts
|
|
7315
7677
|
var C = {
|
|
7316
7678
|
reset: "\x1B[0m",
|
|
@@ -7326,6 +7688,7 @@ var CONNECT_HARNESSES = [
|
|
|
7326
7688
|
"claude-desktop",
|
|
7327
7689
|
"antigravity",
|
|
7328
7690
|
"codex",
|
|
7691
|
+
"vscode",
|
|
7329
7692
|
"opencode",
|
|
7330
7693
|
"goose",
|
|
7331
7694
|
"copilot"
|
|
@@ -7334,7 +7697,7 @@ function isConnectHarnessId(value) {
|
|
|
7334
7697
|
return CONNECT_HARNESSES.includes(value);
|
|
7335
7698
|
}
|
|
7336
7699
|
function agentsMdPresent(cwd = process.cwd()) {
|
|
7337
|
-
return
|
|
7700
|
+
return existsSync15(join15(cwd, "AGENTS.md"));
|
|
7338
7701
|
}
|
|
7339
7702
|
function printStatus() {
|
|
7340
7703
|
const installed = hasCommand("opencode");
|
|
@@ -7440,16 +7803,34 @@ var openCmd = new Command("open").description("Open an agent harness in the work
|
|
|
7440
7803
|
const workspace = opts.dir ?? process.cwd();
|
|
7441
7804
|
launchHarness(harness, { executable, workspace, shell });
|
|
7442
7805
|
});
|
|
7443
|
-
var connectCmd = new Command("connect").description(
|
|
7444
|
-
"
|
|
7445
|
-
|
|
7806
|
+
var connectCmd = new Command("connect").description(
|
|
7807
|
+
"Configure ZAM for detected user agent harnesses, or one explicit harness"
|
|
7808
|
+
).argument(
|
|
7809
|
+
"[harness]",
|
|
7810
|
+
"Optional harness: claude-code | claude-desktop | antigravity | codex | vscode | opencode | goose | copilot"
|
|
7446
7811
|
).option(
|
|
7447
7812
|
"--print",
|
|
7448
7813
|
"Print configuration changes instead of writing them to disk"
|
|
7449
7814
|
).action(async (harnessArg, opts) => {
|
|
7450
|
-
|
|
7815
|
+
let explicitHarness;
|
|
7816
|
+
if (harnessArg) {
|
|
7817
|
+
if (!isConnectHarnessId(harnessArg)) {
|
|
7818
|
+
console.error(
|
|
7819
|
+
`Unsupported harness: ${harnessArg}. Supported: ${CONNECT_HARNESSES.join(", ")}.`
|
|
7820
|
+
);
|
|
7821
|
+
process.exit(1);
|
|
7822
|
+
} else {
|
|
7823
|
+
explicitHarness = harnessArg;
|
|
7824
|
+
}
|
|
7825
|
+
}
|
|
7826
|
+
const home = homedir11();
|
|
7827
|
+
const harnesses = explicitHarness ? [explicitHarness] : detectInstalledConnectHarnesses({
|
|
7828
|
+
home,
|
|
7829
|
+
copilotHome: process.env.COPILOT_HOME
|
|
7830
|
+
});
|
|
7831
|
+
if (harnesses.length === 0) {
|
|
7451
7832
|
console.error(
|
|
7452
|
-
|
|
7833
|
+
"No supported user-scoped agent harness was detected. Install Codex, VS Code, or another supported host, or pass a harness explicitly."
|
|
7453
7834
|
);
|
|
7454
7835
|
process.exit(1);
|
|
7455
7836
|
}
|
|
@@ -7460,54 +7841,117 @@ var connectCmd = new Command("connect").description("Configure the ZAM MCP serve
|
|
|
7460
7841
|
);
|
|
7461
7842
|
zamPath = "zam";
|
|
7462
7843
|
}
|
|
7463
|
-
|
|
7464
|
-
|
|
7465
|
-
|
|
7466
|
-
|
|
7467
|
-
|
|
7468
|
-
|
|
7469
|
-
|
|
7470
|
-
|
|
7471
|
-
|
|
7472
|
-
|
|
7473
|
-
|
|
7474
|
-
|
|
7475
|
-
|
|
7476
|
-
|
|
7477
|
-
|
|
7478
|
-
|
|
7844
|
+
for (const harness of harnesses) {
|
|
7845
|
+
let result;
|
|
7846
|
+
try {
|
|
7847
|
+
result = connectHarnessMcp(harness, {
|
|
7848
|
+
zamPath,
|
|
7849
|
+
cwd: process.cwd(),
|
|
7850
|
+
home,
|
|
7851
|
+
copilotHome: process.env.COPILOT_HOME
|
|
7852
|
+
});
|
|
7853
|
+
} catch (error) {
|
|
7854
|
+
console.error(
|
|
7855
|
+
`Error preparing ${harness} MCP configuration: ${error instanceof Error ? error.message : String(error)}`
|
|
7856
|
+
);
|
|
7857
|
+
process.exit(1);
|
|
7858
|
+
}
|
|
7859
|
+
let copilotExtension;
|
|
7860
|
+
let vscodeExtension;
|
|
7861
|
+
try {
|
|
7862
|
+
if (harness === "copilot") {
|
|
7863
|
+
copilotExtension = installCopilotExtension({
|
|
7864
|
+
home,
|
|
7865
|
+
zamPath,
|
|
7866
|
+
dryRun: Boolean(opts.print)
|
|
7867
|
+
});
|
|
7868
|
+
} else if (harness === "vscode") {
|
|
7869
|
+
vscodeExtension = installVscodeExtension({
|
|
7870
|
+
home,
|
|
7871
|
+
zamPath,
|
|
7872
|
+
dryRun: Boolean(opts.print)
|
|
7873
|
+
});
|
|
7874
|
+
} else if (harness === "antigravity") {
|
|
7875
|
+
const antigravityPath = resolveAntigravityIdeExecutable();
|
|
7876
|
+
if (antigravityPath) {
|
|
7877
|
+
vscodeExtension = installVscodeExtension({
|
|
7878
|
+
home,
|
|
7879
|
+
zamPath,
|
|
7880
|
+
codePath: antigravityPath,
|
|
7881
|
+
dryRun: Boolean(opts.print)
|
|
7882
|
+
});
|
|
7883
|
+
}
|
|
7884
|
+
}
|
|
7885
|
+
} catch (error) {
|
|
7886
|
+
console.error(
|
|
7887
|
+
`Error preparing ${harness} companion extension: ${error instanceof Error ? error.message : String(error)}`
|
|
7888
|
+
);
|
|
7889
|
+
process.exit(1);
|
|
7890
|
+
}
|
|
7891
|
+
if (opts.print) {
|
|
7892
|
+
if (harnesses.length > 1) console.log(`${C.bold}${harness}${C.reset}`);
|
|
7893
|
+
console.log(`Path: ${result.path}`);
|
|
7894
|
+
console.log(`Content:
|
|
7479
7895
|
${result.content}`);
|
|
7480
|
-
|
|
7481
|
-
|
|
7482
|
-
|
|
7483
|
-
|
|
7484
|
-
|
|
7485
|
-
|
|
7486
|
-
|
|
7896
|
+
if (copilotExtension) {
|
|
7897
|
+
console.log(`Extension: ${copilotExtension.destinationDir}`);
|
|
7898
|
+
console.log(
|
|
7899
|
+
`Launch: ${copilotExtension.launch.command} ${copilotExtension.launch.args.join(" ")}`
|
|
7900
|
+
);
|
|
7901
|
+
}
|
|
7902
|
+
if (vscodeExtension) {
|
|
7903
|
+
console.log(`Extension: ${vscodeExtension.vsixPath}`);
|
|
7904
|
+
console.log(`Launch config: ${vscodeExtension.launchConfigPath}`);
|
|
7905
|
+
}
|
|
7906
|
+
continue;
|
|
7907
|
+
}
|
|
7908
|
+
if (result.alreadyConfigured) {
|
|
7909
|
+
console.log(
|
|
7910
|
+
`${C.green}\u2713${C.reset} ${harness}: MCP server 'zam' already configured in ${result.path}`
|
|
7911
|
+
);
|
|
7912
|
+
} else {
|
|
7913
|
+
try {
|
|
7914
|
+
mkdirSync10(dirname7(result.path), { recursive: true });
|
|
7915
|
+
writeFileSync9(result.path, result.content, "utf-8");
|
|
7916
|
+
console.log(
|
|
7917
|
+
`${C.green}\u2713${C.reset} ${harness}: wrote MCP configuration to ${result.path}`
|
|
7918
|
+
);
|
|
7919
|
+
} catch (error) {
|
|
7920
|
+
console.error(
|
|
7921
|
+
`Error writing ${harness} MCP configuration: ${error instanceof Error ? error.message : String(error)}`
|
|
7922
|
+
);
|
|
7923
|
+
process.exit(1);
|
|
7924
|
+
}
|
|
7925
|
+
}
|
|
7926
|
+
if (copilotExtension) {
|
|
7927
|
+
console.log(
|
|
7928
|
+
`${C.green}\u2713${C.reset} Copilot MCP Apps extension ${copilotExtension.action} at ${copilotExtension.destinationDir}`
|
|
7929
|
+
);
|
|
7930
|
+
}
|
|
7931
|
+
if (vscodeExtension) {
|
|
7932
|
+
console.log(
|
|
7933
|
+
`${C.green}\u2713${C.reset} ZAM Companion ${vscodeExtension.action} from ${vscodeExtension.vsixPath}`
|
|
7934
|
+
);
|
|
7935
|
+
}
|
|
7936
|
+
console.log(` ${C.dim}${result.hint}${C.reset}`);
|
|
7487
7937
|
}
|
|
7488
|
-
|
|
7489
|
-
|
|
7490
|
-
|
|
7938
|
+
if (!opts.print) {
|
|
7939
|
+
const skills = distributeGlobalSkills(home);
|
|
7940
|
+
const installed = skills.filter((result) => result.success).length;
|
|
7491
7941
|
console.log(
|
|
7492
|
-
`${C.green}\u2713${C.reset}
|
|
7942
|
+
`${C.green}\u2713${C.reset} Refreshed ${installed}/${skills.length} global ZAM skill installations`
|
|
7493
7943
|
);
|
|
7494
|
-
console.log(` ${C.dim}${result.hint}${C.reset}`);
|
|
7495
|
-
} catch (error) {
|
|
7496
|
-
console.error(
|
|
7497
|
-
`Error writing MCP configuration: ${error instanceof Error ? error.message : String(error)}`
|
|
7498
|
-
);
|
|
7499
|
-
process.exit(1);
|
|
7500
7944
|
}
|
|
7501
7945
|
});
|
|
7502
7946
|
var agentCommand = new Command("agent").description("Provision and inspect the agent that drives ZAM sessions").addCommand(installCmd).addCommand(statusCmd).addCommand(openCmd).addCommand(listCmd).addCommand(connectCmd).action(printStatus);
|
|
7503
7947
|
|
|
7504
7948
|
// src/cli/commands/bridge.ts
|
|
7505
7949
|
init_kernel();
|
|
7506
|
-
import { execFileSync as
|
|
7950
|
+
import { execFileSync as execFileSync4 } from "child_process";
|
|
7507
7951
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
7508
|
-
import { existsSync as
|
|
7509
|
-
import { homedir as
|
|
7510
|
-
import { join as
|
|
7952
|
+
import { existsSync as existsSync19, readdirSync as readdirSync2, readFileSync as readFileSync16, rmSync as rmSync3 } from "fs";
|
|
7953
|
+
import { homedir as homedir13, tmpdir as tmpdir3 } from "os";
|
|
7954
|
+
import { join as join22, resolve as resolve5 } from "path";
|
|
7511
7955
|
import { Command as Command2 } from "commander";
|
|
7512
7956
|
import { ulid as ulid9 } from "ulid";
|
|
7513
7957
|
|
|
@@ -7518,7 +7962,7 @@ import fs from "fs";
|
|
|
7518
7962
|
// src/cli/llm/client.ts
|
|
7519
7963
|
init_kernel();
|
|
7520
7964
|
import { spawn as spawn2 } from "child_process";
|
|
7521
|
-
import { existsSync as
|
|
7965
|
+
import { existsSync as existsSync16, readFileSync as readFileSync12, statSync as statSync2 } from "fs";
|
|
7522
7966
|
var DEFAULT_LLM_URL = "http://localhost:8000/v1";
|
|
7523
7967
|
var DEFAULT_LLM_MAX_TOKENS = 1e4;
|
|
7524
7968
|
var RECALL_QUESTION_MAX_OUTPUT_TOKENS = 400;
|
|
@@ -8234,7 +8678,7 @@ async function extractTextFromScanViaLLM(db, imagePath) {
|
|
|
8234
8678
|
"Vision role is not enabled in settings (llm.vision.enabled)"
|
|
8235
8679
|
);
|
|
8236
8680
|
}
|
|
8237
|
-
if (!
|
|
8681
|
+
if (!existsSync16(imagePath)) {
|
|
8238
8682
|
throw new Error(`Scan file not found: ${imagePath}`);
|
|
8239
8683
|
}
|
|
8240
8684
|
const stat = statSync2(imagePath);
|
|
@@ -8255,7 +8699,7 @@ async function extractTextFromScanViaLLM(db, imagePath) {
|
|
|
8255
8699
|
if (!mime) {
|
|
8256
8700
|
throw new Error("Unsupported scan format; use PNG, JPEG, or WebP");
|
|
8257
8701
|
}
|
|
8258
|
-
const imageBytes =
|
|
8702
|
+
const imageBytes = readFileSync12(imagePath);
|
|
8259
8703
|
const dataUrl = `data:${mime};base64,${imageBytes.toString("base64")}`;
|
|
8260
8704
|
const visionEndpoint = await getVisionConfig(db);
|
|
8261
8705
|
const langName = LANGUAGE_NAMES[p.locale] || "English";
|
|
@@ -8472,7 +8916,7 @@ async function prepareRecallChain(db, opts) {
|
|
|
8472
8916
|
} else {
|
|
8473
8917
|
spawnLocalRunner(endpoint.url, endpoint.model, endpoint.runner);
|
|
8474
8918
|
while (Date.now() < deadline) {
|
|
8475
|
-
await new Promise((
|
|
8919
|
+
await new Promise((resolve11) => setTimeout(resolve11, 1e3));
|
|
8476
8920
|
if (await isLlmOnline(endpoint.url)) {
|
|
8477
8921
|
online = true;
|
|
8478
8922
|
break;
|
|
@@ -8687,7 +9131,7 @@ function spawnLocalRunner(url, model, hint) {
|
|
|
8687
9131
|
const { runner, port } = detectRunner(url, model, hint);
|
|
8688
9132
|
try {
|
|
8689
9133
|
if (runner === "fastflowlm") {
|
|
8690
|
-
const flmExe =
|
|
9134
|
+
const flmExe = existsSync16("C:\\Program Files\\flm\\flm.exe") ? "C:\\Program Files\\flm\\flm.exe" : "flm";
|
|
8691
9135
|
if (!hasCommand("flm") && flmExe === "flm") return;
|
|
8692
9136
|
spawn2(flmExe, ["serve", model, "--port", port], {
|
|
8693
9137
|
detached: true,
|
|
@@ -8708,7 +9152,7 @@ function spawnLocalRunner(url, model, hint) {
|
|
|
8708
9152
|
async function startLocalRunner(url, model, locale, hint) {
|
|
8709
9153
|
const { runner, port } = detectRunner(url, model, hint);
|
|
8710
9154
|
if (runner === "fastflowlm") {
|
|
8711
|
-
const flmExe =
|
|
9155
|
+
const flmExe = existsSync16("C:\\Program Files\\flm\\flm.exe") ? "C:\\Program Files\\flm\\flm.exe" : "flm";
|
|
8712
9156
|
if (!hasCommand("flm") && flmExe === "flm") {
|
|
8713
9157
|
console.warn(
|
|
8714
9158
|
"\x1B[31m\u2717 FastFlowLM is configured but could not be found on the system.\x1B[0m"
|
|
@@ -8765,7 +9209,7 @@ async function startLocalRunner(url, model, locale, hint) {
|
|
|
8765
9209
|
let attempts = 0;
|
|
8766
9210
|
const dotsPerLine = 30;
|
|
8767
9211
|
while (true) {
|
|
8768
|
-
await new Promise((
|
|
9212
|
+
await new Promise((resolve11) => setTimeout(resolve11, 500));
|
|
8769
9213
|
if (await isLlmOnline(url)) {
|
|
8770
9214
|
if (attempts > 0) process.stdout.write("\n");
|
|
8771
9215
|
return true;
|
|
@@ -8854,8 +9298,8 @@ async function fetchWithInteractiveTimeout(url, options = {}) {
|
|
|
8854
9298
|
const dotsPerLine = 30;
|
|
8855
9299
|
while (true) {
|
|
8856
9300
|
let timeoutId;
|
|
8857
|
-
const timeoutPromise = new Promise((
|
|
8858
|
-
timeoutId = setTimeout(() =>
|
|
9301
|
+
const timeoutPromise = new Promise((resolve11) => {
|
|
9302
|
+
timeoutId = setTimeout(() => resolve11("timeout"), timeoutMs);
|
|
8859
9303
|
});
|
|
8860
9304
|
const dotsInterval = setInterval(() => {
|
|
8861
9305
|
process.stdout.write(".");
|
|
@@ -9187,8 +9631,8 @@ async function readImageOCR(db, imagePath) {
|
|
|
9187
9631
|
|
|
9188
9632
|
// src/cli/bridge-handlers.ts
|
|
9189
9633
|
init_kernel();
|
|
9190
|
-
import { mkdirSync as
|
|
9191
|
-
import { join as
|
|
9634
|
+
import { mkdirSync as mkdirSync12, writeFileSync as writeFileSync10 } from "fs";
|
|
9635
|
+
import { join as join18 } from "path";
|
|
9192
9636
|
|
|
9193
9637
|
// src/cli/knowledge-contexts.ts
|
|
9194
9638
|
init_kernel();
|
|
@@ -9435,16 +9879,16 @@ async function resolveSuggestMinSimilarity(db) {
|
|
|
9435
9879
|
}
|
|
9436
9880
|
|
|
9437
9881
|
// src/cli/update/latest-version.ts
|
|
9438
|
-
import { readFileSync as
|
|
9439
|
-
import { dirname as
|
|
9440
|
-
import { fileURLToPath as
|
|
9882
|
+
import { readFileSync as readFileSync13 } from "fs";
|
|
9883
|
+
import { dirname as dirname8, join as join16 } from "path";
|
|
9884
|
+
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
9441
9885
|
var GITHUB_REPO = "zam-os/zam";
|
|
9442
9886
|
function currentVersion() {
|
|
9443
|
-
const here =
|
|
9887
|
+
const here = dirname8(fileURLToPath4(import.meta.url));
|
|
9444
9888
|
for (const up of ["..", "../..", "../../.."]) {
|
|
9445
9889
|
try {
|
|
9446
9890
|
const pkg2 = JSON.parse(
|
|
9447
|
-
|
|
9891
|
+
readFileSync13(join16(here, up, "package.json"), "utf-8")
|
|
9448
9892
|
);
|
|
9449
9893
|
if (pkg2.version) return pkg2.version;
|
|
9450
9894
|
} catch {
|
|
@@ -9474,16 +9918,16 @@ async function fetchLatestVersion(repo) {
|
|
|
9474
9918
|
|
|
9475
9919
|
// src/cli/workspaces/active.ts
|
|
9476
9920
|
init_kernel();
|
|
9477
|
-
import { existsSync as
|
|
9478
|
-
import { homedir as
|
|
9479
|
-
import { basename as basename3, join as
|
|
9921
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync11 } from "fs";
|
|
9922
|
+
import { homedir as homedir12 } from "os";
|
|
9923
|
+
import { basename as basename3, join as join17, resolve as resolve4 } from "path";
|
|
9480
9924
|
var LEGACY_WORKSPACE_DIR_KEY = "personal.workspace_dir";
|
|
9481
9925
|
var DEFAULT_WORKSPACE_ID = "personal";
|
|
9482
9926
|
function defaultWorkspaceDir() {
|
|
9483
|
-
return
|
|
9927
|
+
return join17(homedir12(), "Documents", "zam");
|
|
9484
9928
|
}
|
|
9485
9929
|
function normalizeWorkspacePath(path) {
|
|
9486
|
-
const resolved =
|
|
9930
|
+
const resolved = resolve4(path);
|
|
9487
9931
|
return process.platform === "win32" ? resolved.toLowerCase() : resolved;
|
|
9488
9932
|
}
|
|
9489
9933
|
function sameWorkspacePath(left, right) {
|
|
@@ -9512,7 +9956,7 @@ async function clearLegacyWorkspaceDir(db) {
|
|
|
9512
9956
|
async function migrateLegacyWorkspaceDir(db) {
|
|
9513
9957
|
const legacyDir = await getSetting(db, LEGACY_WORKSPACE_DIR_KEY);
|
|
9514
9958
|
if (!legacyDir) return void 0;
|
|
9515
|
-
const path =
|
|
9959
|
+
const path = resolve4(legacyDir);
|
|
9516
9960
|
const existing = findWorkspaceByPath(path);
|
|
9517
9961
|
const migrated = existing ?? {
|
|
9518
9962
|
id: getConfiguredWorkspaces().some(
|
|
@@ -9535,13 +9979,13 @@ async function ensureActiveWorkspace(db) {
|
|
|
9535
9979
|
await migrateLegacyWorkspaceDir(db);
|
|
9536
9980
|
const active = getActiveWorkspace();
|
|
9537
9981
|
if (active) {
|
|
9538
|
-
|
|
9982
|
+
mkdirSync11(active.path, { recursive: true });
|
|
9539
9983
|
return active;
|
|
9540
9984
|
}
|
|
9541
9985
|
const configured = getConfiguredWorkspaces()[0];
|
|
9542
9986
|
if (configured) {
|
|
9543
9987
|
setActiveWorkspaceId(configured.id);
|
|
9544
|
-
|
|
9988
|
+
mkdirSync11(configured.path, { recursive: true });
|
|
9545
9989
|
return configured;
|
|
9546
9990
|
}
|
|
9547
9991
|
const workspace = {
|
|
@@ -9550,7 +9994,7 @@ async function ensureActiveWorkspace(db) {
|
|
|
9550
9994
|
kind: "personal",
|
|
9551
9995
|
path: defaultWorkspaceDir()
|
|
9552
9996
|
};
|
|
9553
|
-
|
|
9997
|
+
mkdirSync11(workspace.path, { recursive: true });
|
|
9554
9998
|
upsertConfiguredWorkspace(workspace);
|
|
9555
9999
|
setActiveWorkspaceId(workspace.id);
|
|
9556
10000
|
await clearLegacyWorkspaceDir(db);
|
|
@@ -9564,7 +10008,7 @@ async function activateWorkspace(db, workspace) {
|
|
|
9564
10008
|
}
|
|
9565
10009
|
async function activateWorkspacePath(db, dir, opts = {}) {
|
|
9566
10010
|
await migrateLegacyWorkspaceDir(db);
|
|
9567
|
-
const path =
|
|
10011
|
+
const path = resolve4(dir);
|
|
9568
10012
|
const existing = opts.id ? void 0 : findWorkspaceByPath(path);
|
|
9569
10013
|
if (existing) {
|
|
9570
10014
|
setActiveWorkspaceId(existing.id);
|
|
@@ -9589,7 +10033,7 @@ async function removeWorkspaceAndResolveActive(db, id) {
|
|
|
9589
10033
|
};
|
|
9590
10034
|
}
|
|
9591
10035
|
function existingWorkspaceDirOrHome(workspace) {
|
|
9592
|
-
return
|
|
10036
|
+
return existsSync17(workspace.path) ? workspace.path : homedir12();
|
|
9593
10037
|
}
|
|
9594
10038
|
|
|
9595
10039
|
// src/cli/bridge-handlers.ts
|
|
@@ -10361,11 +10805,11 @@ async function backupCreate(db, params) {
|
|
|
10361
10805
|
const targetDir = params.dir || (await ensureActiveWorkspace(db)).path;
|
|
10362
10806
|
const snapshot = await exportSnapshot(db);
|
|
10363
10807
|
const manifest = verifySnapshot(snapshot);
|
|
10364
|
-
const backupDir =
|
|
10365
|
-
|
|
10808
|
+
const backupDir = join18(targetDir, "zam-backups");
|
|
10809
|
+
mkdirSync12(backupDir, { recursive: true });
|
|
10366
10810
|
const stamp = manifest.createdAt.replace(/[:.]/g, "-");
|
|
10367
|
-
const path =
|
|
10368
|
-
|
|
10811
|
+
const path = join18(backupDir, `zam-snapshot-${stamp}.sql`);
|
|
10812
|
+
writeFileSync10(path, snapshot, "utf-8");
|
|
10369
10813
|
return {
|
|
10370
10814
|
ok: true,
|
|
10371
10815
|
path,
|
|
@@ -13050,9 +13494,9 @@ function getCurriculumProvider(id) {
|
|
|
13050
13494
|
// src/cli/llm/vision.ts
|
|
13051
13495
|
init_kernel();
|
|
13052
13496
|
import { randomBytes } from "crypto";
|
|
13053
|
-
import { readFileSync as
|
|
13497
|
+
import { readFileSync as readFileSync14 } from "fs";
|
|
13054
13498
|
import { tmpdir as tmpdir2 } from "os";
|
|
13055
|
-
import { basename as basename4, join as
|
|
13499
|
+
import { basename as basename4, join as join19 } from "path";
|
|
13056
13500
|
var LANGUAGE_NAMES2 = {
|
|
13057
13501
|
en: "English",
|
|
13058
13502
|
de: "German",
|
|
@@ -13088,13 +13532,13 @@ async function observeUiSnapshotViaLLM(db, input8) {
|
|
|
13088
13532
|
const imageUrls = [];
|
|
13089
13533
|
const isVideo = /\.(mp4|mov|m4v|avi|mkv|webm)$/i.test(input8.imagePath);
|
|
13090
13534
|
if (isVideo) {
|
|
13091
|
-
const { mkdirSync:
|
|
13535
|
+
const { mkdirSync: mkdirSync18, readdirSync: readdirSync3, rmSync: rmSync4 } = await import("fs");
|
|
13092
13536
|
const { execSync: execSync6 } = await import("child_process");
|
|
13093
|
-
const tempDir =
|
|
13537
|
+
const tempDir = join19(
|
|
13094
13538
|
tmpdir2(),
|
|
13095
13539
|
`zam-frames-${randomBytes(4).toString("hex")}`
|
|
13096
13540
|
);
|
|
13097
|
-
|
|
13541
|
+
mkdirSync18(tempDir, { recursive: true });
|
|
13098
13542
|
try {
|
|
13099
13543
|
execSync6(
|
|
13100
13544
|
`ffmpeg -i "${input8.imagePath}" -vf "fps=1/3,scale=1280:-1" -vsync vfr "${tempDir}/frame_%03d.png"`,
|
|
@@ -13123,7 +13567,7 @@ async function observeUiSnapshotViaLLM(db, input8) {
|
|
|
13123
13567
|
}
|
|
13124
13568
|
}
|
|
13125
13569
|
for (const file of sampledFiles) {
|
|
13126
|
-
const bytes =
|
|
13570
|
+
const bytes = readFileSync14(join19(tempDir, file));
|
|
13127
13571
|
imageUrls.push(`data:image/png;base64,${bytes.toString("base64")}`);
|
|
13128
13572
|
}
|
|
13129
13573
|
} finally {
|
|
@@ -13133,7 +13577,7 @@ async function observeUiSnapshotViaLLM(db, input8) {
|
|
|
13133
13577
|
}
|
|
13134
13578
|
}
|
|
13135
13579
|
} else {
|
|
13136
|
-
const imageBytes =
|
|
13580
|
+
const imageBytes = readFileSync14(input8.imagePath);
|
|
13137
13581
|
const ext = input8.imagePath.split(".").pop()?.toLowerCase();
|
|
13138
13582
|
const mime = ext === "jpg" || ext === "jpeg" ? "image/jpeg" : "image/png";
|
|
13139
13583
|
imageUrls.push(`data:${mime};base64,${imageBytes.toString("base64")}`);
|
|
@@ -13602,36 +14046,36 @@ async function withProviderScope(machine, action) {
|
|
|
13602
14046
|
|
|
13603
14047
|
// src/cli/provisioning/index.ts
|
|
13604
14048
|
import {
|
|
13605
|
-
existsSync as
|
|
13606
|
-
lstatSync,
|
|
13607
|
-
mkdirSync as
|
|
13608
|
-
readFileSync as
|
|
14049
|
+
existsSync as existsSync18,
|
|
14050
|
+
lstatSync as lstatSync2,
|
|
14051
|
+
mkdirSync as mkdirSync13,
|
|
14052
|
+
readFileSync as readFileSync15,
|
|
13609
14053
|
realpathSync,
|
|
13610
14054
|
rmSync as rmSync2,
|
|
13611
14055
|
symlinkSync,
|
|
13612
|
-
writeFileSync as
|
|
14056
|
+
writeFileSync as writeFileSync11
|
|
13613
14057
|
} from "fs";
|
|
13614
|
-
import { basename as basename5, dirname as
|
|
13615
|
-
import { fileURLToPath as
|
|
13616
|
-
var
|
|
13617
|
-
|
|
13618
|
-
|
|
13619
|
-
].find((candidate) =>
|
|
14058
|
+
import { basename as basename5, dirname as dirname9, join as join20 } from "path";
|
|
14059
|
+
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
14060
|
+
var packageRoot3 = [
|
|
14061
|
+
fileURLToPath5(new URL("../..", import.meta.url)),
|
|
14062
|
+
fileURLToPath5(new URL("../../..", import.meta.url))
|
|
14063
|
+
].find((candidate) => existsSync18(join20(candidate, "package.json"))) ?? fileURLToPath5(new URL("../..", import.meta.url));
|
|
13620
14064
|
var ALL_SETUP_AGENTS = ["claude", "copilot", "codex", "agent"];
|
|
13621
14065
|
var SKILL_PAIRS = [
|
|
13622
14066
|
{
|
|
13623
|
-
from:
|
|
13624
|
-
to:
|
|
14067
|
+
from: join20(packageRoot3, ".claude", "skills", "zam", "SKILL.md"),
|
|
14068
|
+
to: join20(".claude", "skills", "zam", "SKILL.md"),
|
|
13625
14069
|
agents: ["claude", "copilot"]
|
|
13626
14070
|
},
|
|
13627
14071
|
{
|
|
13628
|
-
from:
|
|
13629
|
-
to:
|
|
14072
|
+
from: join20(packageRoot3, ".agent", "skills", "zam", "SKILL.md"),
|
|
14073
|
+
to: join20(".agent", "skills", "zam", "SKILL.md"),
|
|
13630
14074
|
agents: ["agent"]
|
|
13631
14075
|
},
|
|
13632
14076
|
{
|
|
13633
|
-
from:
|
|
13634
|
-
to:
|
|
14077
|
+
from: join20(packageRoot3, ".agents", "skills", "zam", "SKILL.md"),
|
|
14078
|
+
to: join20(".agents", "skills", "zam", "SKILL.md"),
|
|
13635
14079
|
agents: ["codex"]
|
|
13636
14080
|
}
|
|
13637
14081
|
];
|
|
@@ -13661,7 +14105,7 @@ function parseSetupAgents(value) {
|
|
|
13661
14105
|
}
|
|
13662
14106
|
function pathExists(path) {
|
|
13663
14107
|
try {
|
|
13664
|
-
|
|
14108
|
+
lstatSync2(path);
|
|
13665
14109
|
return true;
|
|
13666
14110
|
} catch {
|
|
13667
14111
|
return false;
|
|
@@ -13669,7 +14113,7 @@ function pathExists(path) {
|
|
|
13669
14113
|
}
|
|
13670
14114
|
function isSymbolicLink(path) {
|
|
13671
14115
|
try {
|
|
13672
|
-
return
|
|
14116
|
+
return lstatSync2(path).isSymbolicLink();
|
|
13673
14117
|
} catch {
|
|
13674
14118
|
return false;
|
|
13675
14119
|
}
|
|
@@ -13690,16 +14134,16 @@ function linkPointsTo(sourceDir, destinationDir) {
|
|
|
13690
14134
|
}
|
|
13691
14135
|
function isZamSkillCopy(destinationDir) {
|
|
13692
14136
|
try {
|
|
13693
|
-
if (!
|
|
13694
|
-
const skillFile =
|
|
13695
|
-
if (!
|
|
13696
|
-
return /^name:\s*zam\s*$/m.test(
|
|
14137
|
+
if (!lstatSync2(destinationDir).isDirectory()) return false;
|
|
14138
|
+
const skillFile = join20(destinationDir, "SKILL.md");
|
|
14139
|
+
if (!existsSync18(skillFile)) return false;
|
|
14140
|
+
return /^name:\s*zam\s*$/m.test(readFileSync15(skillFile, "utf8"));
|
|
13697
14141
|
} catch {
|
|
13698
14142
|
return false;
|
|
13699
14143
|
}
|
|
13700
14144
|
}
|
|
13701
14145
|
function classifySkillDestination(sourceDir, destinationDir) {
|
|
13702
|
-
if (!
|
|
14146
|
+
if (!existsSync18(sourceDir)) return "source-missing";
|
|
13703
14147
|
if (!isSymbolicLink(destinationDir) && pathsResolveToSameDirectory(sourceDir, destinationDir)) {
|
|
13704
14148
|
return "source-directory";
|
|
13705
14149
|
}
|
|
@@ -13716,9 +14160,9 @@ function wireSkills(cwd = process.cwd(), agents = parseSetupAgents(), opts = {})
|
|
|
13716
14160
|
};
|
|
13717
14161
|
for (const { from, to, agents: pairAgents } of SKILL_PAIRS) {
|
|
13718
14162
|
if (!pairAgents.some((agent) => agents.has(agent))) continue;
|
|
13719
|
-
const sourceDir =
|
|
13720
|
-
const destinationDir =
|
|
13721
|
-
const label =
|
|
14163
|
+
const sourceDir = dirname9(from);
|
|
14164
|
+
const destinationDir = dirname9(join20(cwd, to));
|
|
14165
|
+
const label = dirname9(to);
|
|
13722
14166
|
const state = classifySkillDestination(sourceDir, destinationDir);
|
|
13723
14167
|
if (state === "source-missing") {
|
|
13724
14168
|
if (!opts.quiet) {
|
|
@@ -13775,7 +14219,7 @@ function wireSkills(cwd = process.cwd(), agents = parseSetupAgents(), opts = {})
|
|
|
13775
14219
|
if (destinationExists) {
|
|
13776
14220
|
rmSync2(destinationDir, { recursive: true, force: true });
|
|
13777
14221
|
}
|
|
13778
|
-
|
|
14222
|
+
mkdirSync13(dirname9(destinationDir), { recursive: true });
|
|
13779
14223
|
symlinkSync(
|
|
13780
14224
|
sourceDir,
|
|
13781
14225
|
destinationDir,
|
|
@@ -13791,8 +14235,8 @@ function inspectSkillLinks(cwd = process.cwd(), agents = parseSetupAgents()) {
|
|
|
13791
14235
|
const results = [];
|
|
13792
14236
|
for (const { from, to, agents: pairAgents } of SKILL_PAIRS) {
|
|
13793
14237
|
if (!pairAgents.some((agent) => agents.has(agent))) continue;
|
|
13794
|
-
const sourceDir =
|
|
13795
|
-
const destinationDir =
|
|
14238
|
+
const sourceDir = dirname9(from);
|
|
14239
|
+
const destinationDir = dirname9(join20(cwd, to));
|
|
13796
14240
|
results.push({
|
|
13797
14241
|
agents: pairAgents,
|
|
13798
14242
|
source: sourceDir,
|
|
@@ -13818,15 +14262,15 @@ function upsertMarkedBlock(dest, blockBody, dryRun) {
|
|
|
13818
14262
|
const block = `${ZAM_BLOCK_START}
|
|
13819
14263
|
${blockBody.trim()}
|
|
13820
14264
|
${ZAM_BLOCK_END}`;
|
|
13821
|
-
if (!
|
|
14265
|
+
if (!existsSync18(dest)) {
|
|
13822
14266
|
if (!dryRun) {
|
|
13823
|
-
|
|
13824
|
-
|
|
14267
|
+
mkdirSync13(dirname9(dest), { recursive: true });
|
|
14268
|
+
writeFileSync11(dest, `${block}
|
|
13825
14269
|
`, "utf8");
|
|
13826
14270
|
}
|
|
13827
14271
|
return "write";
|
|
13828
14272
|
}
|
|
13829
|
-
const existing =
|
|
14273
|
+
const existing = readFileSync15(dest, "utf8");
|
|
13830
14274
|
if (existing.includes(block)) return "skip";
|
|
13831
14275
|
const start = existing.indexOf(ZAM_BLOCK_START);
|
|
13832
14276
|
const end = existing.indexOf(ZAM_BLOCK_END);
|
|
@@ -13834,7 +14278,7 @@ ${ZAM_BLOCK_END}`;
|
|
|
13834
14278
|
|
|
13835
14279
|
${block}
|
|
13836
14280
|
`;
|
|
13837
|
-
if (!dryRun)
|
|
14281
|
+
if (!dryRun) writeFileSync11(dest, next, "utf8");
|
|
13838
14282
|
return start >= 0 && end > start ? "update" : "write";
|
|
13839
14283
|
}
|
|
13840
14284
|
function logInstructionAction(action, label, dryRun) {
|
|
@@ -13846,8 +14290,8 @@ function logInstructionAction(action, label, dryRun) {
|
|
|
13846
14290
|
}
|
|
13847
14291
|
function writeClaudeMd(skipClaudeMd, cwd = process.cwd(), opts = {}) {
|
|
13848
14292
|
if (skipClaudeMd) return;
|
|
13849
|
-
const dest =
|
|
13850
|
-
if (
|
|
14293
|
+
const dest = join20(cwd, "CLAUDE.md");
|
|
14294
|
+
if (existsSync18(dest)) {
|
|
13851
14295
|
if (!opts.updateExisting) {
|
|
13852
14296
|
console.log(` skip CLAUDE.md (already present)`);
|
|
13853
14297
|
return;
|
|
@@ -13890,14 +14334,14 @@ Use \`zam connector setup turso\` to store cloud credentials in
|
|
|
13890
14334
|
if (opts.dryRun) {
|
|
13891
14335
|
console.log(` would write CLAUDE.md`);
|
|
13892
14336
|
} else {
|
|
13893
|
-
|
|
14337
|
+
writeFileSync11(dest, content, "utf8");
|
|
13894
14338
|
console.log(` write CLAUDE.md`);
|
|
13895
14339
|
}
|
|
13896
14340
|
}
|
|
13897
14341
|
function writeAgentsMd(skipAgentsMd, cwd = process.cwd(), opts = {}) {
|
|
13898
14342
|
if (skipAgentsMd) return;
|
|
13899
|
-
const dest =
|
|
13900
|
-
if (
|
|
14343
|
+
const dest = join20(cwd, "AGENTS.md");
|
|
14344
|
+
if (existsSync18(dest)) {
|
|
13901
14345
|
if (!opts.updateExisting) {
|
|
13902
14346
|
console.log(` skip AGENTS.md (already present)`);
|
|
13903
14347
|
return;
|
|
@@ -13947,12 +14391,12 @@ Codex discovers repository skills under \`.agents/skills/\`. Run
|
|
|
13947
14391
|
if (opts.dryRun) {
|
|
13948
14392
|
console.log(` would write AGENTS.md`);
|
|
13949
14393
|
} else {
|
|
13950
|
-
|
|
14394
|
+
writeFileSync11(dest, content, "utf8");
|
|
13951
14395
|
console.log(` write AGENTS.md`);
|
|
13952
14396
|
}
|
|
13953
14397
|
}
|
|
13954
14398
|
function writeCopilotInstructions(cwd = process.cwd(), opts = {}) {
|
|
13955
|
-
const dest =
|
|
14399
|
+
const dest = join20(cwd, ".github", "copilot-instructions.md");
|
|
13956
14400
|
const action = upsertMarkedBlock(
|
|
13957
14401
|
dest,
|
|
13958
14402
|
`## ZAM learning sessions
|
|
@@ -13993,13 +14437,13 @@ async function resolveUser(opts, db, resolveOpts) {
|
|
|
13993
14437
|
}
|
|
13994
14438
|
|
|
13995
14439
|
// src/cli/workspaces/backup.ts
|
|
13996
|
-
import { mkdirSync as
|
|
13997
|
-
import { join as
|
|
14440
|
+
import { mkdirSync as mkdirSync14 } from "fs";
|
|
14441
|
+
import { join as join21 } from "path";
|
|
13998
14442
|
async function backupDatabaseTo(db, targetDir) {
|
|
13999
|
-
const backupDir =
|
|
14000
|
-
|
|
14443
|
+
const backupDir = join21(targetDir, "zam-backups");
|
|
14444
|
+
mkdirSync14(backupDir, { recursive: true });
|
|
14001
14445
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
14002
|
-
const dest =
|
|
14446
|
+
const dest = join21(backupDir, `zam-${stamp}.db`);
|
|
14003
14447
|
await db.exec(`VACUUM INTO '${dest.replace(/'/g, "''")}'`);
|
|
14004
14448
|
return dest;
|
|
14005
14449
|
}
|
|
@@ -14130,20 +14574,20 @@ bridgeCommand.command("workspace-info").description("Report the workspace dir, i
|
|
|
14130
14574
|
activeWorkspace,
|
|
14131
14575
|
workspaceDir: activeWorkspace.path,
|
|
14132
14576
|
defaultWorkspaceDir: defaultWorkspaceDir(),
|
|
14133
|
-
dataDir:
|
|
14577
|
+
dataDir: join22(homedir13(), ".zam")
|
|
14134
14578
|
});
|
|
14135
14579
|
});
|
|
14136
14580
|
});
|
|
14137
14581
|
function provisionConfiguredWorkspaces() {
|
|
14138
14582
|
return getConfiguredWorkspaces().flatMap(
|
|
14139
|
-
(workspace) =>
|
|
14583
|
+
(workspace) => existsSync19(workspace.path) ? wireSkills(workspace.path, parseSetupAgents(), { quiet: true }) : []
|
|
14140
14584
|
);
|
|
14141
14585
|
}
|
|
14142
14586
|
function buildWorkspaceLinkHealth(workspaces) {
|
|
14143
14587
|
const agents = parseSetupAgents();
|
|
14144
14588
|
const map = {};
|
|
14145
14589
|
for (const workspace of workspaces) {
|
|
14146
|
-
if (!
|
|
14590
|
+
if (!existsSync19(workspace.path)) continue;
|
|
14147
14591
|
const links = inspectSkillLinks(workspace.path, agents);
|
|
14148
14592
|
map[workspace.id] = {
|
|
14149
14593
|
health: summarizeSkillLinkHealth(links),
|
|
@@ -14173,7 +14617,7 @@ bridgeCommand.command("workspace-list").description("List configured ZAM workspa
|
|
|
14173
14617
|
activeWorkspace,
|
|
14174
14618
|
workspaceDir: activeWorkspace.path,
|
|
14175
14619
|
defaultWorkspaceDir: defaultWorkspaceDir(),
|
|
14176
|
-
dataDir:
|
|
14620
|
+
dataDir: join22(homedir13(), ".zam"),
|
|
14177
14621
|
linkHealth: buildWorkspaceLinkHealth(workspaces)
|
|
14178
14622
|
});
|
|
14179
14623
|
});
|
|
@@ -14188,7 +14632,7 @@ bridgeCommand.command("workspace-repair-links").description(
|
|
|
14188
14632
|
if (!id) jsonError("A non-empty --id is required");
|
|
14189
14633
|
const workspace = getConfiguredWorkspaces().find((item) => item.id === id);
|
|
14190
14634
|
if (!workspace) jsonError(`Workspace "${id}" is not configured`);
|
|
14191
|
-
if (!
|
|
14635
|
+
if (!existsSync19(workspace.path)) {
|
|
14192
14636
|
jsonError(`Workspace path does not exist: ${workspace.path}`);
|
|
14193
14637
|
}
|
|
14194
14638
|
const agents = parseSetupAgents(opts.agents);
|
|
@@ -14219,8 +14663,8 @@ function parseBridgeWorkspaceKind(value) {
|
|
|
14219
14663
|
bridgeCommand.command("workspace-add").description("Register an existing directory as a ZAM workspace (JSON)").requiredOption("--path <dir>", "Existing workspace/repository directory").option("--id <id>", "Workspace id").option("--label <label>", "Human-readable label").option("--kind <kind>", "Workspace kind", "custom").action(async (opts) => {
|
|
14220
14664
|
const raw = String(opts.path ?? "").trim();
|
|
14221
14665
|
if (!raw) jsonError("A non-empty --path is required");
|
|
14222
|
-
const path =
|
|
14223
|
-
if (!
|
|
14666
|
+
const path = resolve5(raw);
|
|
14667
|
+
if (!existsSync19(path)) jsonError(`Workspace path does not exist: ${path}`);
|
|
14224
14668
|
const id = opts.id ? String(opts.id).trim() : void 0;
|
|
14225
14669
|
if (opts.id && !id) jsonError("A non-empty --id is required");
|
|
14226
14670
|
const kind = parseBridgeWorkspaceKind(opts.kind);
|
|
@@ -14264,8 +14708,8 @@ bridgeCommand.command("workspace-remove").description("Unregister a ZAM workspac
|
|
|
14264
14708
|
bridgeCommand.command("set-workspace-dir").description("Set the personal workspace directory (JSON)").requiredOption("--dir <path>", "Path to the workspace directory").action(async (opts) => {
|
|
14265
14709
|
const raw = String(opts.dir ?? "").trim();
|
|
14266
14710
|
if (!raw) jsonError("A non-empty --dir is required");
|
|
14267
|
-
const dir =
|
|
14268
|
-
if (!
|
|
14711
|
+
const dir = resolve5(raw);
|
|
14712
|
+
if (!existsSync19(dir)) jsonError(`Workspace path does not exist: ${dir}`);
|
|
14269
14713
|
const skillLinks = wireSkills(dir, parseSetupAgents(), { quiet: true });
|
|
14270
14714
|
await withDb2(async (db) => {
|
|
14271
14715
|
const workspace = await activateWorkspacePath(db, dir);
|
|
@@ -14328,7 +14772,7 @@ bridgeCommand.command("agent-open").description("Launch an agent harness in the
|
|
|
14328
14772
|
jsonError(`Workspace is not configured: ${opts.workspace}`);
|
|
14329
14773
|
}
|
|
14330
14774
|
const activeWorkspace = await ensureActiveWorkspace(db);
|
|
14331
|
-
const workspace = opts.dir ?
|
|
14775
|
+
const workspace = opts.dir ? existsSync19(opts.dir) ? opts.dir : homedir13() : existingWorkspaceDirOrHome(configuredWorkspace ?? activeWorkspace);
|
|
14332
14776
|
launchHarness(harness, {
|
|
14333
14777
|
executable,
|
|
14334
14778
|
workspace,
|
|
@@ -14700,7 +15144,7 @@ bridgeCommand.command("discover-skills").description(
|
|
|
14700
15144
|
"20"
|
|
14701
15145
|
).action(async (opts) => {
|
|
14702
15146
|
try {
|
|
14703
|
-
const monitorDir =
|
|
15147
|
+
const monitorDir = join22(homedir13(), ".zam", "monitor");
|
|
14704
15148
|
let files;
|
|
14705
15149
|
try {
|
|
14706
15150
|
files = readdirSync2(monitorDir).filter((f) => f.endsWith(".jsonl"));
|
|
@@ -14713,7 +15157,7 @@ bridgeCommand.command("discover-skills").description(
|
|
|
14713
15157
|
return;
|
|
14714
15158
|
}
|
|
14715
15159
|
const limit = Number(opts.limit);
|
|
14716
|
-
const sorted = files.map((f) => ({ name: f, path:
|
|
15160
|
+
const sorted = files.map((f) => ({ name: f, path: join22(monitorDir, f) })).sort((a, b) => b.name.localeCompare(a.name)).slice(0, limit);
|
|
14717
15161
|
const sessionCommands = /* @__PURE__ */ new Map();
|
|
14718
15162
|
for (const file of sorted) {
|
|
14719
15163
|
const sessionId = file.name.replace(".jsonl", "");
|
|
@@ -14825,7 +15269,7 @@ bridgeCommand.command("observe-ui-snapshot").description(
|
|
|
14825
15269
|
});
|
|
14826
15270
|
function resolveWindowsPowerShell() {
|
|
14827
15271
|
try {
|
|
14828
|
-
|
|
15272
|
+
execFileSync4("where.exe", ["pwsh.exe"], { stdio: "ignore" });
|
|
14829
15273
|
return "pwsh";
|
|
14830
15274
|
} catch {
|
|
14831
15275
|
return "powershell";
|
|
@@ -14840,7 +15284,7 @@ function captureScreenshot(outputPath, hwnd, processName) {
|
|
|
14840
15284
|
throw new Error(`Invalid process name format: ${processName}`);
|
|
14841
15285
|
}
|
|
14842
15286
|
if (platform === "win32") {
|
|
14843
|
-
const stdout =
|
|
15287
|
+
const stdout = execFileSync4(
|
|
14844
15288
|
resolveWindowsPowerShell(),
|
|
14845
15289
|
[
|
|
14846
15290
|
"-NoProfile",
|
|
@@ -15153,13 +15597,13 @@ Write-CaptureResult "fullscreen" $hwndVal $matchedBy
|
|
|
15153
15597
|
} else if (platform === "darwin") {
|
|
15154
15598
|
if (hwnd) {
|
|
15155
15599
|
const parsedHwnd = hwnd.startsWith("0x") ? parseInt(hwnd, 16) : parseInt(hwnd, 10);
|
|
15156
|
-
|
|
15600
|
+
execFileSync4("screencapture", ["-l", String(parsedHwnd), outputPath], {
|
|
15157
15601
|
stdio: "pipe"
|
|
15158
15602
|
});
|
|
15159
15603
|
return { method: "screencapture-window", target: null };
|
|
15160
15604
|
} else if (processName) {
|
|
15161
15605
|
try {
|
|
15162
|
-
const windowId =
|
|
15606
|
+
const windowId = execFileSync4(
|
|
15163
15607
|
"osascript",
|
|
15164
15608
|
[
|
|
15165
15609
|
"-e",
|
|
@@ -15168,17 +15612,17 @@ Write-CaptureResult "fullscreen" $hwndVal $matchedBy
|
|
|
15168
15612
|
{ encoding: "utf8", stdio: ["pipe", "pipe", "ignore"] }
|
|
15169
15613
|
).trim();
|
|
15170
15614
|
if (windowId && /^\d+$/.test(windowId)) {
|
|
15171
|
-
|
|
15615
|
+
execFileSync4("screencapture", ["-l", windowId, outputPath], {
|
|
15172
15616
|
stdio: "pipe"
|
|
15173
15617
|
});
|
|
15174
15618
|
return { method: "screencapture-window", target: null };
|
|
15175
15619
|
}
|
|
15176
15620
|
} catch {
|
|
15177
15621
|
}
|
|
15178
|
-
|
|
15622
|
+
execFileSync4("screencapture", ["-x", outputPath], { stdio: "pipe" });
|
|
15179
15623
|
return { method: "screencapture-full", target: null };
|
|
15180
15624
|
} else {
|
|
15181
|
-
|
|
15625
|
+
execFileSync4("screencapture", ["-x", outputPath], { stdio: "pipe" });
|
|
15182
15626
|
return { method: "screencapture-full", target: null };
|
|
15183
15627
|
}
|
|
15184
15628
|
} else {
|
|
@@ -15215,7 +15659,7 @@ bridgeCommand.command("capture-ui").description("Capture a screenshot for agent-
|
|
|
15215
15659
|
return;
|
|
15216
15660
|
}
|
|
15217
15661
|
}
|
|
15218
|
-
const outputPath = opts.image ?? opts.output ??
|
|
15662
|
+
const outputPath = opts.image ?? opts.output ?? join22(tmpdir3(), `zam-capture-${randomBytes2(4).toString("hex")}.png`);
|
|
15219
15663
|
const captureResult = isProvided ? { method: "provided", target: null } : captureScreenshot(outputPath, opts.hwnd, opts.processName);
|
|
15220
15664
|
if (!isProvided) {
|
|
15221
15665
|
const post = decidePostCapture(policy, {
|
|
@@ -15243,7 +15687,7 @@ bridgeCommand.command("capture-ui").description("Capture a screenshot for agent-
|
|
|
15243
15687
|
return;
|
|
15244
15688
|
}
|
|
15245
15689
|
}
|
|
15246
|
-
const imageBytes =
|
|
15690
|
+
const imageBytes = readFileSync16(outputPath);
|
|
15247
15691
|
const base64 = imageBytes.toString("base64");
|
|
15248
15692
|
jsonOut2({
|
|
15249
15693
|
sessionId: opts.session ?? null,
|
|
@@ -15270,11 +15714,11 @@ bridgeCommand.command("start-recording").description("Start screen recording in
|
|
|
15270
15714
|
return;
|
|
15271
15715
|
}
|
|
15272
15716
|
const sessionId = opts.session;
|
|
15273
|
-
const statePath =
|
|
15717
|
+
const statePath = join22(tmpdir3(), `zam-recording-${sessionId}.json`);
|
|
15274
15718
|
const defaultExt = platform === "win32" ? ".mkv" : ".mov";
|
|
15275
|
-
const outputPath = opts.output ??
|
|
15276
|
-
const { existsSync:
|
|
15277
|
-
if (
|
|
15719
|
+
const outputPath = opts.output ?? join22(tmpdir3(), `zam-recording-${sessionId}${defaultExt}`);
|
|
15720
|
+
const { existsSync: existsSync28, writeFileSync: writeFileSync16, openSync, closeSync } = await import("fs");
|
|
15721
|
+
if (existsSync28(statePath)) {
|
|
15278
15722
|
jsonOut2({
|
|
15279
15723
|
sessionId,
|
|
15280
15724
|
started: false,
|
|
@@ -15282,7 +15726,7 @@ bridgeCommand.command("start-recording").description("Start screen recording in
|
|
|
15282
15726
|
});
|
|
15283
15727
|
return;
|
|
15284
15728
|
}
|
|
15285
|
-
const logPath =
|
|
15729
|
+
const logPath = join22(tmpdir3(), `zam-recording-${sessionId}.log`);
|
|
15286
15730
|
let logFd;
|
|
15287
15731
|
try {
|
|
15288
15732
|
logFd = openSync(logPath, "w");
|
|
@@ -15328,7 +15772,7 @@ bridgeCommand.command("start-recording").description("Start screen recording in
|
|
|
15328
15772
|
}
|
|
15329
15773
|
child.unref();
|
|
15330
15774
|
if (child.pid) {
|
|
15331
|
-
|
|
15775
|
+
writeFileSync16(
|
|
15332
15776
|
statePath,
|
|
15333
15777
|
JSON.stringify({
|
|
15334
15778
|
pid: child.pid,
|
|
@@ -15364,9 +15808,9 @@ bridgeCommand.command("stop-recording").description(
|
|
|
15364
15808
|
return;
|
|
15365
15809
|
}
|
|
15366
15810
|
const sessionId = opts.session;
|
|
15367
|
-
const statePath =
|
|
15368
|
-
const { existsSync:
|
|
15369
|
-
if (!
|
|
15811
|
+
const statePath = join22(tmpdir3(), `zam-recording-${sessionId}.json`);
|
|
15812
|
+
const { existsSync: existsSync28, readFileSync: readFileSync21, rmSync: rmSync4 } = await import("fs");
|
|
15813
|
+
if (!existsSync28(statePath)) {
|
|
15370
15814
|
jsonOut2({
|
|
15371
15815
|
sessionId,
|
|
15372
15816
|
stopped: false,
|
|
@@ -15374,7 +15818,7 @@ bridgeCommand.command("stop-recording").description(
|
|
|
15374
15818
|
});
|
|
15375
15819
|
return;
|
|
15376
15820
|
}
|
|
15377
|
-
const state = JSON.parse(
|
|
15821
|
+
const state = JSON.parse(readFileSync21(statePath, "utf8"));
|
|
15378
15822
|
const { pid, outputPath } = state;
|
|
15379
15823
|
try {
|
|
15380
15824
|
process.kill(pid, "SIGINT");
|
|
@@ -15390,7 +15834,7 @@ bridgeCommand.command("stop-recording").description(
|
|
|
15390
15834
|
};
|
|
15391
15835
|
let attempts = 0;
|
|
15392
15836
|
while (isProcessRunning(pid) && attempts < 20) {
|
|
15393
|
-
await new Promise((
|
|
15837
|
+
await new Promise((resolve11) => setTimeout(resolve11, 250));
|
|
15394
15838
|
attempts++;
|
|
15395
15839
|
}
|
|
15396
15840
|
if (isProcessRunning(pid)) {
|
|
@@ -15403,7 +15847,7 @@ bridgeCommand.command("stop-recording").description(
|
|
|
15403
15847
|
rmSync4(statePath, { force: true });
|
|
15404
15848
|
} catch {
|
|
15405
15849
|
}
|
|
15406
|
-
if (!
|
|
15850
|
+
if (!existsSync28(outputPath)) {
|
|
15407
15851
|
jsonOut2({
|
|
15408
15852
|
sessionId,
|
|
15409
15853
|
stopped: false,
|
|
@@ -15640,7 +16084,7 @@ bridgeCommand.command("cloud-model-hint").description("Suggest a cloud model for
|
|
|
15640
16084
|
});
|
|
15641
16085
|
bridgeCommand.command("local-llm-hints").description("Detect installed local LLM servers and suggest defaults (JSON)").action(() => {
|
|
15642
16086
|
const profile = getSystemProfile();
|
|
15643
|
-
const flmInstalled = hasCommand("flm") ||
|
|
16087
|
+
const flmInstalled = hasCommand("flm") || existsSync19("C:\\Program Files\\flm\\flm.exe");
|
|
15644
16088
|
const ollamaInstalled = isOllamaInstalled();
|
|
15645
16089
|
const runners = [
|
|
15646
16090
|
{ id: "flm", label: "FastFlowLM", installed: flmInstalled },
|
|
@@ -18190,26 +18634,26 @@ var doctorCommand = new Command5("doctor").description(
|
|
|
18190
18634
|
// src/cli/commands/git-sync.ts
|
|
18191
18635
|
init_kernel();
|
|
18192
18636
|
import { execSync as execSync5 } from "child_process";
|
|
18193
|
-
import { chmodSync as chmodSync2, existsSync as
|
|
18194
|
-
import { join as
|
|
18637
|
+
import { chmodSync as chmodSync2, existsSync as existsSync20, writeFileSync as writeFileSync12 } from "fs";
|
|
18638
|
+
import { join as join23 } from "path";
|
|
18195
18639
|
import { Command as Command6 } from "commander";
|
|
18196
18640
|
function installHook2() {
|
|
18197
|
-
const gitDir =
|
|
18198
|
-
if (!
|
|
18641
|
+
const gitDir = join23(process.cwd(), ".git");
|
|
18642
|
+
if (!existsSync20(gitDir)) {
|
|
18199
18643
|
console.error(
|
|
18200
18644
|
"Error: Current directory is not the root of a Git repository."
|
|
18201
18645
|
);
|
|
18202
18646
|
process.exit(1);
|
|
18203
18647
|
}
|
|
18204
|
-
const hooksDir =
|
|
18205
|
-
const hookPath =
|
|
18648
|
+
const hooksDir = join23(gitDir, "hooks");
|
|
18649
|
+
const hookPath = join23(hooksDir, "post-commit");
|
|
18206
18650
|
const hookContent = `#!/bin/sh
|
|
18207
18651
|
# ZAM Spaced Repetition Auto-Stale Hook
|
|
18208
18652
|
# Triggered automatically on git commits to decay modified concept cards.
|
|
18209
18653
|
zam git-sync --commit HEAD --quiet
|
|
18210
18654
|
`;
|
|
18211
18655
|
try {
|
|
18212
|
-
|
|
18656
|
+
writeFileSync12(hookPath, hookContent, { encoding: "utf-8", flag: "w" });
|
|
18213
18657
|
try {
|
|
18214
18658
|
chmodSync2(hookPath, "755");
|
|
18215
18659
|
} catch (_e) {
|
|
@@ -18312,8 +18756,8 @@ ZAM Auto-Stale Complete: Scanned ${changedFiles.length} file(s).`
|
|
|
18312
18756
|
|
|
18313
18757
|
// src/cli/commands/goal.ts
|
|
18314
18758
|
init_kernel();
|
|
18315
|
-
import { existsSync as
|
|
18316
|
-
import { resolve as
|
|
18759
|
+
import { existsSync as existsSync21, mkdirSync as mkdirSync15 } from "fs";
|
|
18760
|
+
import { resolve as resolve6 } from "path";
|
|
18317
18761
|
import { input as input2 } from "@inquirer/prompts";
|
|
18318
18762
|
import { Command as Command7 } from "commander";
|
|
18319
18763
|
async function resolveGoalsDir() {
|
|
@@ -18326,7 +18770,7 @@ async function resolveGoalsDir() {
|
|
|
18326
18770
|
} finally {
|
|
18327
18771
|
await db?.close();
|
|
18328
18772
|
}
|
|
18329
|
-
return goalsDir ?
|
|
18773
|
+
return goalsDir ? resolve6(goalsDir) : resolve6("goals");
|
|
18330
18774
|
}
|
|
18331
18775
|
var goalCommand = new Command7("goal").description(
|
|
18332
18776
|
"Manage learning goals (markdown files)"
|
|
@@ -18336,7 +18780,7 @@ goalCommand.command("list").description("List all goals").option(
|
|
|
18336
18780
|
"Filter by status (active, completed, paused, abandoned)"
|
|
18337
18781
|
).option("--tree", "Show goals as a tree with parent/child relationships").option("--json", "Output as JSON").action(async (opts) => {
|
|
18338
18782
|
const goalsDir = await resolveGoalsDir();
|
|
18339
|
-
if (!
|
|
18783
|
+
if (!existsSync21(goalsDir)) {
|
|
18340
18784
|
console.error(`Goals directory not found: ${goalsDir}`);
|
|
18341
18785
|
console.error(
|
|
18342
18786
|
"Set it with: zam settings set personal.goals_dir /path/to/goals"
|
|
@@ -18437,8 +18881,8 @@ ${"\u2500".repeat(50)}`);
|
|
|
18437
18881
|
});
|
|
18438
18882
|
goalCommand.command("create").description("Create a new goal").option("--slug <slug>", "Goal slug (used as filename)").option("--title <title>", "Goal title").option("--parent <slug>", "Parent goal slug").option("--description <text>", "Goal description").option("--json", "Output as JSON").action(async (opts) => {
|
|
18439
18883
|
const goalsDir = await resolveGoalsDir();
|
|
18440
|
-
if (!
|
|
18441
|
-
|
|
18884
|
+
if (!existsSync21(goalsDir)) {
|
|
18885
|
+
mkdirSync15(goalsDir, { recursive: true });
|
|
18442
18886
|
}
|
|
18443
18887
|
let slug = opts.slug;
|
|
18444
18888
|
let title = opts.title;
|
|
@@ -18498,22 +18942,22 @@ goalCommand.command("status <slug> <status>").description("Update a goal's statu
|
|
|
18498
18942
|
|
|
18499
18943
|
// src/cli/commands/init.ts
|
|
18500
18944
|
init_kernel();
|
|
18501
|
-
import { existsSync as
|
|
18502
|
-
import { homedir as
|
|
18503
|
-
import { join as
|
|
18945
|
+
import { existsSync as existsSync22, mkdirSync as mkdirSync16, writeFileSync as writeFileSync13 } from "fs";
|
|
18946
|
+
import { homedir as homedir14 } from "os";
|
|
18947
|
+
import { join as join24, resolve as resolve7 } from "path";
|
|
18504
18948
|
import { confirm, input as input3 } from "@inquirer/prompts";
|
|
18505
18949
|
import { Command as Command8 } from "commander";
|
|
18506
|
-
var HOME2 =
|
|
18950
|
+
var HOME2 = homedir14();
|
|
18507
18951
|
function printLine(char = "\u2550", len = 60, color = "\x1B[36m") {
|
|
18508
18952
|
console.log(`${color}${char.repeat(len)}\x1B[0m`);
|
|
18509
18953
|
}
|
|
18510
18954
|
function bootstrapSandboxWorkspace(workspaceDir) {
|
|
18511
|
-
|
|
18512
|
-
|
|
18513
|
-
|
|
18514
|
-
const worldviewFile =
|
|
18515
|
-
if (!
|
|
18516
|
-
|
|
18955
|
+
mkdirSync16(join24(workspaceDir, "beliefs"), { recursive: true });
|
|
18956
|
+
mkdirSync16(join24(workspaceDir, "goals"), { recursive: true });
|
|
18957
|
+
mkdirSync16(join24(workspaceDir, "skills"), { recursive: true });
|
|
18958
|
+
const worldviewFile = join24(workspaceDir, "beliefs", "worldview.md");
|
|
18959
|
+
if (!existsSync22(worldviewFile)) {
|
|
18960
|
+
writeFileSync13(
|
|
18517
18961
|
worldviewFile,
|
|
18518
18962
|
`# Personal Worldview
|
|
18519
18963
|
|
|
@@ -18525,9 +18969,9 @@ Here, I declare the core concepts and principles I want to master.
|
|
|
18525
18969
|
"utf8"
|
|
18526
18970
|
);
|
|
18527
18971
|
}
|
|
18528
|
-
const goalsFile =
|
|
18529
|
-
if (!
|
|
18530
|
-
|
|
18972
|
+
const goalsFile = join24(workspaceDir, "goals", "goals.md");
|
|
18973
|
+
if (!existsSync22(goalsFile)) {
|
|
18974
|
+
writeFileSync13(
|
|
18531
18975
|
goalsFile,
|
|
18532
18976
|
`# Personal Goals
|
|
18533
18977
|
|
|
@@ -18549,8 +18993,8 @@ var initCommand = new Command8("init").description("Launch the guided interactiv
|
|
|
18549
18993
|
);
|
|
18550
18994
|
printLine();
|
|
18551
18995
|
console.log("\n\x1B[1m[1/5] Setting up Local Workspace Sandbox\x1B[0m");
|
|
18552
|
-
const defaultWorkspace =
|
|
18553
|
-
const workspacePath =
|
|
18996
|
+
const defaultWorkspace = join24(HOME2, "Documents", "zam");
|
|
18997
|
+
const workspacePath = resolve7(
|
|
18554
18998
|
await input3({
|
|
18555
18999
|
message: "Choose your ZAM workspace directory:",
|
|
18556
19000
|
default: defaultWorkspace
|
|
@@ -19751,7 +20195,7 @@ observerCommand.command("revoke <process>").description("Remove a process from o
|
|
|
19751
20195
|
|
|
19752
20196
|
// src/cli/commands/profile.ts
|
|
19753
20197
|
init_kernel();
|
|
19754
|
-
import { dirname as
|
|
20198
|
+
import { dirname as dirname10, resolve as resolve8 } from "path";
|
|
19755
20199
|
import { Command as Command13 } from "commander";
|
|
19756
20200
|
var C2 = {
|
|
19757
20201
|
reset: "\x1B[0m",
|
|
@@ -19779,7 +20223,7 @@ var profileCommand = new Command13("profile").description("Show or change this m
|
|
|
19779
20223
|
if (opts.mode) setInstallMode(opts.mode);
|
|
19780
20224
|
db = await openDatabaseWithSync({ initialize: true });
|
|
19781
20225
|
if (opts.dir) {
|
|
19782
|
-
await activateWorkspacePath(db,
|
|
20226
|
+
await activateWorkspacePath(db, resolve8(opts.dir), {
|
|
19783
20227
|
kind: "personal",
|
|
19784
20228
|
label: "Personal"
|
|
19785
20229
|
});
|
|
@@ -19792,7 +20236,7 @@ var profileCommand = new Command13("profile").description("Show or change this m
|
|
|
19792
20236
|
mode: getInstallMode(),
|
|
19793
20237
|
personalDir,
|
|
19794
20238
|
syncProvider: detectSyncProvider(personalDir),
|
|
19795
|
-
dataDir:
|
|
20239
|
+
dataDir: dirname10(dbPath),
|
|
19796
20240
|
dbPath
|
|
19797
20241
|
};
|
|
19798
20242
|
if (opts.json) {
|
|
@@ -20181,7 +20625,7 @@ ${"\u2550".repeat(50)}`);
|
|
|
20181
20625
|
|
|
20182
20626
|
// src/cli/commands/session.ts
|
|
20183
20627
|
init_kernel();
|
|
20184
|
-
import { readFileSync as
|
|
20628
|
+
import { readFileSync as readFileSync17 } from "fs";
|
|
20185
20629
|
import { input as input6, select as select2 } from "@inquirer/prompts";
|
|
20186
20630
|
import { Command as Command16 } from "commander";
|
|
20187
20631
|
var sessionCommand = new Command16("session").description(
|
|
@@ -20372,7 +20816,7 @@ function loadPatternFile(path) {
|
|
|
20372
20816
|
if (!path) return [];
|
|
20373
20817
|
let parsed;
|
|
20374
20818
|
try {
|
|
20375
|
-
parsed = JSON.parse(
|
|
20819
|
+
parsed = JSON.parse(readFileSync17(path, "utf-8"));
|
|
20376
20820
|
} catch (err) {
|
|
20377
20821
|
throw new Error(
|
|
20378
20822
|
`Cannot read synthesis patterns from ${path}: ${err.message}`
|
|
@@ -20563,7 +21007,7 @@ sessionCommand.command("end").description("End a session and show summary").requ
|
|
|
20563
21007
|
|
|
20564
21008
|
// src/cli/commands/settings.ts
|
|
20565
21009
|
init_kernel();
|
|
20566
|
-
import { existsSync as
|
|
21010
|
+
import { existsSync as existsSync23 } from "fs";
|
|
20567
21011
|
import { Command as Command17 } from "commander";
|
|
20568
21012
|
var settingsCommand = new Command17("settings").description(
|
|
20569
21013
|
"Manage user settings"
|
|
@@ -20728,7 +21172,7 @@ settingsCommand.command("repos").description("Show or set Personal, Team, and Or
|
|
|
20728
21172
|
console.log("\nValidation:");
|
|
20729
21173
|
for (const [name, path] of Object.entries(paths)) {
|
|
20730
21174
|
if (path) {
|
|
20731
|
-
const exists =
|
|
21175
|
+
const exists = existsSync23(path);
|
|
20732
21176
|
console.log(
|
|
20733
21177
|
` ${name.padEnd(9)}: ${exists ? "\x1B[32m\u2713 Valid folder\x1B[0m" : "\x1B[31m\u2717 Directory does not exist\x1B[0m"}`
|
|
20734
21178
|
);
|
|
@@ -20741,7 +21185,7 @@ settingsCommand.command("repos").description("Show or set Personal, Team, and Or
|
|
|
20741
21185
|
|
|
20742
21186
|
// src/cli/commands/setup.ts
|
|
20743
21187
|
init_kernel();
|
|
20744
|
-
import { resolve as
|
|
21188
|
+
import { resolve as resolve9 } from "path";
|
|
20745
21189
|
import { Command as Command18 } from "commander";
|
|
20746
21190
|
function formatDatabaseInitTarget(target) {
|
|
20747
21191
|
switch (target.kind) {
|
|
@@ -20801,7 +21245,7 @@ var setupCommand = new Command18("setup").description(
|
|
|
20801
21245
|
console.error(`Error: ${err.message}`);
|
|
20802
21246
|
process.exit(1);
|
|
20803
21247
|
}
|
|
20804
|
-
const target =
|
|
21248
|
+
const target = resolve9(opts.target ?? process.cwd());
|
|
20805
21249
|
const updateExistingInstructions = Boolean(opts.target) || opts.force;
|
|
20806
21250
|
console.log(
|
|
20807
21251
|
`Setting up ZAM in ${target}${opts.dryRun ? " (dry run)" : ""}
|
|
@@ -20925,8 +21369,8 @@ skillCommand.command("add").description("Register a new agent skill").requiredOp
|
|
|
20925
21369
|
|
|
20926
21370
|
// src/cli/commands/snapshot.ts
|
|
20927
21371
|
init_kernel();
|
|
20928
|
-
import { existsSync as
|
|
20929
|
-
import { dirname as
|
|
21372
|
+
import { existsSync as existsSync24, mkdirSync as mkdirSync17, readFileSync as readFileSync18, writeFileSync as writeFileSync14 } from "fs";
|
|
21373
|
+
import { dirname as dirname11, join as join25 } from "path";
|
|
20930
21374
|
import { Command as Command20 } from "commander";
|
|
20931
21375
|
function defaultOutName() {
|
|
20932
21376
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d+Z$/, "").replace(/:/g, "-");
|
|
@@ -20955,12 +21399,12 @@ var exportCmd = new Command20("export").description("Write a portable SQL-text s
|
|
|
20955
21399
|
process.stdout.write(snapshot);
|
|
20956
21400
|
return;
|
|
20957
21401
|
}
|
|
20958
|
-
const out = opts.out ??
|
|
20959
|
-
const dir =
|
|
20960
|
-
if (dir && dir !== "." && !
|
|
20961
|
-
|
|
21402
|
+
const out = opts.out ?? join25(personalDir, "snapshots", defaultOutName());
|
|
21403
|
+
const dir = dirname11(out);
|
|
21404
|
+
if (dir && dir !== "." && !existsSync24(dir)) {
|
|
21405
|
+
mkdirSync17(dir, { recursive: true });
|
|
20962
21406
|
}
|
|
20963
|
-
|
|
21407
|
+
writeFileSync14(out, snapshot, "utf-8");
|
|
20964
21408
|
console.log(`Snapshot written: ${out}`);
|
|
20965
21409
|
console.log(
|
|
20966
21410
|
` ${total} row(s)${nonEmpty.length ? ` \u2014 ${nonEmpty.join(", ")}` : ""}`
|
|
@@ -20974,11 +21418,11 @@ var exportCmd = new Command20("export").description("Write a portable SQL-text s
|
|
|
20974
21418
|
var importCmd = new Command20("import").description("Restore a snapshot into the database").argument("<file>", "Snapshot file to restore").option("--force", "Overwrite a non-empty database", false).action(async (file, opts) => {
|
|
20975
21419
|
let db;
|
|
20976
21420
|
try {
|
|
20977
|
-
if (!
|
|
21421
|
+
if (!existsSync24(file)) {
|
|
20978
21422
|
console.error(`Error: Snapshot file not found: ${file}`);
|
|
20979
21423
|
process.exit(1);
|
|
20980
21424
|
}
|
|
20981
|
-
const snapshot =
|
|
21425
|
+
const snapshot = readFileSync18(file, "utf-8");
|
|
20982
21426
|
db = await openDatabaseWithSync({ initialize: true });
|
|
20983
21427
|
const result = await importSnapshot(db, snapshot, { force: opts.force });
|
|
20984
21428
|
await db.close();
|
|
@@ -20996,11 +21440,11 @@ var importCmd = new Command20("import").description("Restore a snapshot into the
|
|
|
20996
21440
|
});
|
|
20997
21441
|
var verifyCmd = new Command20("verify").description("Check a snapshot's manifest and checksum without importing").argument("<file>", "Snapshot file to verify").action((file) => {
|
|
20998
21442
|
try {
|
|
20999
|
-
if (!
|
|
21443
|
+
if (!existsSync24(file)) {
|
|
21000
21444
|
console.error(`Error: Snapshot file not found: ${file}`);
|
|
21001
21445
|
process.exit(1);
|
|
21002
21446
|
}
|
|
21003
|
-
const manifest = verifySnapshot(
|
|
21447
|
+
const manifest = verifySnapshot(readFileSync18(file, "utf-8"));
|
|
21004
21448
|
const { total, nonEmpty } = summarize(manifest.tables);
|
|
21005
21449
|
console.log(`Valid snapshot (format v${manifest.version})`);
|
|
21006
21450
|
console.log(` created: ${manifest.createdAt}`);
|
|
@@ -21549,10 +21993,10 @@ tokenCommand.command("reembed").description("Backfill or refresh semantic-search
|
|
|
21549
21993
|
// src/cli/commands/ui.ts
|
|
21550
21994
|
init_kernel();
|
|
21551
21995
|
import { spawn as spawn3, spawnSync } from "child_process";
|
|
21552
|
-
import { existsSync as
|
|
21553
|
-
import { homedir as
|
|
21554
|
-
import { dirname as
|
|
21555
|
-
import { fileURLToPath as
|
|
21996
|
+
import { existsSync as existsSync25 } from "fs";
|
|
21997
|
+
import { homedir as homedir15 } from "os";
|
|
21998
|
+
import { dirname as dirname12, join as join26 } from "path";
|
|
21999
|
+
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
21556
22000
|
import { Command as Command23 } from "commander";
|
|
21557
22001
|
var C3 = {
|
|
21558
22002
|
reset: "\x1B[0m",
|
|
@@ -21563,14 +22007,14 @@ var C3 = {
|
|
|
21563
22007
|
dim: "\x1B[2m"
|
|
21564
22008
|
};
|
|
21565
22009
|
function findDesktopDir() {
|
|
21566
|
-
const starts = [process.cwd(),
|
|
22010
|
+
const starts = [process.cwd(), dirname12(fileURLToPath6(import.meta.url))];
|
|
21567
22011
|
for (const start of starts) {
|
|
21568
22012
|
let dir = start;
|
|
21569
22013
|
for (let i = 0; i < 10; i++) {
|
|
21570
|
-
if (
|
|
21571
|
-
return
|
|
22014
|
+
if (existsSync25(join26(dir, "desktop", "src-tauri", "tauri.conf.json"))) {
|
|
22015
|
+
return join26(dir, "desktop");
|
|
21572
22016
|
}
|
|
21573
|
-
const parent =
|
|
22017
|
+
const parent = dirname12(dir);
|
|
21574
22018
|
if (parent === dir) break;
|
|
21575
22019
|
dir = parent;
|
|
21576
22020
|
}
|
|
@@ -21578,30 +22022,30 @@ function findDesktopDir() {
|
|
|
21578
22022
|
return null;
|
|
21579
22023
|
}
|
|
21580
22024
|
function findBuiltApp(desktopDir) {
|
|
21581
|
-
const releaseDir =
|
|
22025
|
+
const releaseDir = join26(desktopDir, "src-tauri", "target", "release");
|
|
21582
22026
|
if (process.platform === "win32") {
|
|
21583
22027
|
for (const name of ["ZAM.exe", "zam.exe", "zam-desktop.exe"]) {
|
|
21584
|
-
const p =
|
|
21585
|
-
if (
|
|
22028
|
+
const p = join26(releaseDir, name);
|
|
22029
|
+
if (existsSync25(p)) return p;
|
|
21586
22030
|
}
|
|
21587
22031
|
} else if (process.platform === "darwin") {
|
|
21588
|
-
const app =
|
|
21589
|
-
if (
|
|
22032
|
+
const app = join26(releaseDir, "bundle", "macos", "ZAM.app");
|
|
22033
|
+
if (existsSync25(app)) return app;
|
|
21590
22034
|
} else {
|
|
21591
22035
|
for (const name of ["zam", "ZAM", "zam-desktop"]) {
|
|
21592
|
-
const p =
|
|
21593
|
-
if (
|
|
22036
|
+
const p = join26(releaseDir, name);
|
|
22037
|
+
if (existsSync25(p)) return p;
|
|
21594
22038
|
}
|
|
21595
22039
|
}
|
|
21596
22040
|
return null;
|
|
21597
22041
|
}
|
|
21598
22042
|
function findInstalledApp() {
|
|
21599
22043
|
const candidates = process.platform === "win32" ? [
|
|
21600
|
-
process.env.LOCALAPPDATA &&
|
|
21601
|
-
process.env.ProgramFiles &&
|
|
21602
|
-
process.env["ProgramFiles(x86)"] &&
|
|
21603
|
-
] : process.platform === "darwin" ? ["/Applications/ZAM.app",
|
|
21604
|
-
return candidates.find((candidate) => candidate &&
|
|
22044
|
+
process.env.LOCALAPPDATA && join26(process.env.LOCALAPPDATA, "Programs", "ZAM", "ZAM.exe"),
|
|
22045
|
+
process.env.ProgramFiles && join26(process.env.ProgramFiles, "ZAM", "ZAM.exe"),
|
|
22046
|
+
process.env["ProgramFiles(x86)"] && join26(process.env["ProgramFiles(x86)"], "ZAM", "ZAM.exe")
|
|
22047
|
+
] : process.platform === "darwin" ? ["/Applications/ZAM.app", join26(homedir15(), "Applications", "ZAM.app")] : ["/opt/ZAM/zam", "/usr/bin/zam-desktop"];
|
|
22048
|
+
return candidates.find((candidate) => candidate && existsSync25(candidate)) || null;
|
|
21605
22049
|
}
|
|
21606
22050
|
function runNpm(args, opts) {
|
|
21607
22051
|
const res = spawnSync("npm", args, {
|
|
@@ -21612,7 +22056,7 @@ function runNpm(args, opts) {
|
|
|
21612
22056
|
return res.status ?? 1;
|
|
21613
22057
|
}
|
|
21614
22058
|
function ensureDesktopDeps(desktopDir) {
|
|
21615
|
-
if (
|
|
22059
|
+
if (existsSync25(join26(desktopDir, "node_modules"))) return true;
|
|
21616
22060
|
console.log(
|
|
21617
22061
|
`${C3.cyan}Installing desktop dependencies (one-time)...${C3.reset}`
|
|
21618
22062
|
);
|
|
@@ -21638,13 +22082,13 @@ function requireRust() {
|
|
|
21638
22082
|
function hasMsvcBuildTools() {
|
|
21639
22083
|
if (process.platform !== "win32") return true;
|
|
21640
22084
|
const pf86 = process.env["ProgramFiles(x86)"] || "C:\\Program Files (x86)";
|
|
21641
|
-
const vswhere =
|
|
22085
|
+
const vswhere = join26(
|
|
21642
22086
|
pf86,
|
|
21643
22087
|
"Microsoft Visual Studio",
|
|
21644
22088
|
"Installer",
|
|
21645
22089
|
"vswhere.exe"
|
|
21646
22090
|
);
|
|
21647
|
-
if (!
|
|
22091
|
+
if (!existsSync25(vswhere)) return false;
|
|
21648
22092
|
const res = spawnSync(
|
|
21649
22093
|
vswhere,
|
|
21650
22094
|
[
|
|
@@ -21676,7 +22120,7 @@ function requireMsvcOnWindows() {
|
|
|
21676
22120
|
return false;
|
|
21677
22121
|
}
|
|
21678
22122
|
function warnIfCliMissing(repoRoot) {
|
|
21679
|
-
if (!
|
|
22123
|
+
if (!existsSync25(join26(repoRoot, "dist", "cli", "index.js"))) {
|
|
21680
22124
|
console.warn(
|
|
21681
22125
|
`${C3.yellow}\u26A0 CLI build not found (dist/cli/index.js). The GUI bridge needs it \u2014 run 'npm run build' at the repo root.${C3.reset}`
|
|
21682
22126
|
);
|
|
@@ -21739,7 +22183,7 @@ var uiCommand = new Command23("ui").description("Launch the ZAM Desktop GUI (Act
|
|
|
21739
22183
|
).option("--shortcut", "Create Desktop + Start-menu shortcuts to the GUI").action((opts) => {
|
|
21740
22184
|
const installedApp = findInstalledApp();
|
|
21741
22185
|
if (!opts.dev && !opts.build && !opts.shortcut && installedApp) {
|
|
21742
|
-
launchApp(installedApp,
|
|
22186
|
+
launchApp(installedApp, homedir15());
|
|
21743
22187
|
return;
|
|
21744
22188
|
}
|
|
21745
22189
|
const desktopDir = findDesktopDir();
|
|
@@ -21749,7 +22193,7 @@ var uiCommand = new Command23("ui").description("Launch the ZAM Desktop GUI (Act
|
|
|
21749
22193
|
);
|
|
21750
22194
|
process.exit(1);
|
|
21751
22195
|
}
|
|
21752
|
-
const repoRoot =
|
|
22196
|
+
const repoRoot = dirname12(desktopDir);
|
|
21753
22197
|
if (opts.build) {
|
|
21754
22198
|
if (!requireRust()) process.exit(1);
|
|
21755
22199
|
if (!requireMsvcOnWindows()) process.exit(1);
|
|
@@ -21760,7 +22204,7 @@ var uiCommand = new Command23("ui").description("Launch the ZAM Desktop GUI (Act
|
|
|
21760
22204
|
);
|
|
21761
22205
|
const code = runNpm(["run", "tauri", "build"], { cwd: desktopDir });
|
|
21762
22206
|
if (code === 0) {
|
|
21763
|
-
const bundle =
|
|
22207
|
+
const bundle = join26(
|
|
21764
22208
|
desktopDir,
|
|
21765
22209
|
"src-tauri",
|
|
21766
22210
|
"target",
|
|
@@ -21800,7 +22244,7 @@ ${C3.green}\u2713 Done. Installer is in:${C3.reset}
|
|
|
21800
22244
|
);
|
|
21801
22245
|
process.exit(1);
|
|
21802
22246
|
}
|
|
21803
|
-
createShortcuts(shortcutTarget,
|
|
22247
|
+
createShortcuts(shortcutTarget, dirname12(shortcutTarget));
|
|
21804
22248
|
return;
|
|
21805
22249
|
}
|
|
21806
22250
|
if (builtApp) {
|
|
@@ -21838,9 +22282,9 @@ ${C3.dim}After that, 'zam ui' launches it directly.${C3.reset}`
|
|
|
21838
22282
|
// src/cli/commands/update.ts
|
|
21839
22283
|
init_kernel();
|
|
21840
22284
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
21841
|
-
import { existsSync as
|
|
21842
|
-
import { dirname as
|
|
21843
|
-
import { fileURLToPath as
|
|
22285
|
+
import { existsSync as existsSync26, readFileSync as readFileSync19, realpathSync as realpathSync2 } from "fs";
|
|
22286
|
+
import { dirname as dirname13, join as join27 } from "path";
|
|
22287
|
+
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
21844
22288
|
import { confirm as confirm3 } from "@inquirer/prompts";
|
|
21845
22289
|
import { Command as Command24 } from "commander";
|
|
21846
22290
|
var CHANNELS = [
|
|
@@ -21861,7 +22305,7 @@ var C4 = {
|
|
|
21861
22305
|
function versionAt(dir) {
|
|
21862
22306
|
try {
|
|
21863
22307
|
const pkg2 = JSON.parse(
|
|
21864
|
-
|
|
22308
|
+
readFileSync19(join27(dir, "package.json"), "utf-8")
|
|
21865
22309
|
);
|
|
21866
22310
|
return pkg2.version ?? "unknown";
|
|
21867
22311
|
} catch {
|
|
@@ -21919,14 +22363,14 @@ var checkCmd = new Command24("check").description("Check whether a newer ZAM has
|
|
|
21919
22363
|
}
|
|
21920
22364
|
);
|
|
21921
22365
|
function findSourceRepo() {
|
|
21922
|
-
let dir = realpathSync2(
|
|
21923
|
-
let parent =
|
|
22366
|
+
let dir = realpathSync2(dirname13(fileURLToPath7(import.meta.url)));
|
|
22367
|
+
let parent = dirname13(dir);
|
|
21924
22368
|
while (parent !== dir) {
|
|
21925
|
-
if (
|
|
22369
|
+
if (existsSync26(join27(dir, ".git"))) return dir;
|
|
21926
22370
|
dir = parent;
|
|
21927
|
-
parent =
|
|
22371
|
+
parent = dirname13(dir);
|
|
21928
22372
|
}
|
|
21929
|
-
return
|
|
22373
|
+
return existsSync26(join27(dir, ".git")) ? dir : null;
|
|
21930
22374
|
}
|
|
21931
22375
|
function runGit(cwd, args, capture) {
|
|
21932
22376
|
const res = spawnSync2("git", args, {
|
|
@@ -21947,7 +22391,7 @@ function runNpm2(args, cwd) {
|
|
|
21947
22391
|
function smokeTestBuild(src) {
|
|
21948
22392
|
const res = spawnSync2(
|
|
21949
22393
|
process.execPath,
|
|
21950
|
-
[
|
|
22394
|
+
[join27(src, "dist", "cli", "index.js"), "--version"],
|
|
21951
22395
|
{
|
|
21952
22396
|
cwd: src,
|
|
21953
22397
|
encoding: "utf8",
|
|
@@ -22027,7 +22471,7 @@ Fix it manually in ${src} (try \`npm ci && npm run build\`, and check your Node
|
|
|
22027
22471
|
console.log(`${C4.dim}\u2192 zam setup --force${C4.reset}`);
|
|
22028
22472
|
const setup = spawnSync2(
|
|
22029
22473
|
process.execPath,
|
|
22030
|
-
[
|
|
22474
|
+
[join27(src, "dist", "cli", "index.js"), "setup", "--force"],
|
|
22031
22475
|
{ cwd: process.cwd(), stdio: "inherit" }
|
|
22032
22476
|
);
|
|
22033
22477
|
if (setup.status !== 0) {
|
|
@@ -22139,15 +22583,15 @@ var whoamiCommand = new Command25("whoami").description("Show or set the default
|
|
|
22139
22583
|
|
|
22140
22584
|
// src/cli/commands/workspace.ts
|
|
22141
22585
|
init_kernel();
|
|
22142
|
-
import { execFileSync as
|
|
22143
|
-
import { existsSync as
|
|
22144
|
-
import { homedir as
|
|
22145
|
-
import { join as
|
|
22586
|
+
import { execFileSync as execFileSync5 } from "child_process";
|
|
22587
|
+
import { existsSync as existsSync27, writeFileSync as writeFileSync15 } from "fs";
|
|
22588
|
+
import { homedir as homedir16 } from "os";
|
|
22589
|
+
import { join as join28, resolve as resolve10 } from "path";
|
|
22146
22590
|
import { confirm as confirm4, input as input7 } from "@inquirer/prompts";
|
|
22147
22591
|
import { Command as Command26 } from "commander";
|
|
22148
22592
|
function runGit2(cwd, args) {
|
|
22149
22593
|
try {
|
|
22150
|
-
return
|
|
22594
|
+
return execFileSync5("git", args, {
|
|
22151
22595
|
cwd,
|
|
22152
22596
|
stdio: "pipe",
|
|
22153
22597
|
encoding: "utf8"
|
|
@@ -22226,7 +22670,7 @@ workspaceCommand.command("list").description("List configured ZAM workspaces").o
|
|
|
22226
22670
|
const workspaces = getConfiguredWorkspaces();
|
|
22227
22671
|
const agents = parseSetupAgents();
|
|
22228
22672
|
const linkHealth = Object.fromEntries(
|
|
22229
|
-
workspaces.filter((workspace) =>
|
|
22673
|
+
workspaces.filter((workspace) => existsSync27(workspace.path)).map((workspace) => [
|
|
22230
22674
|
workspace.id,
|
|
22231
22675
|
summarizeSkillLinkHealth(inspectSkillLinks(workspace.path, agents))
|
|
22232
22676
|
])
|
|
@@ -22268,8 +22712,8 @@ workspaceCommand.command("add <id>").description("Register an existing directory
|
|
|
22268
22712
|
`Source-control provider (${WORKSPACE_SOURCE_CONTROLS.join(" | ")})`
|
|
22269
22713
|
).option("--scopes <list>", "Comma-separated knowledge scopes").option("--default-agent <id>", "Default agent harness for this workspace").action((id, opts) => {
|
|
22270
22714
|
try {
|
|
22271
|
-
const path =
|
|
22272
|
-
if (!
|
|
22715
|
+
const path = resolve10(String(opts.path));
|
|
22716
|
+
if (!existsSync27(path)) {
|
|
22273
22717
|
console.error(`Workspace path does not exist: ${path}`);
|
|
22274
22718
|
process.exit(1);
|
|
22275
22719
|
}
|
|
@@ -22363,7 +22807,7 @@ workspaceCommand.command("publish").description("Publish your local workspace sa
|
|
|
22363
22807
|
);
|
|
22364
22808
|
process.exit(1);
|
|
22365
22809
|
}
|
|
22366
|
-
if (!
|
|
22810
|
+
if (!existsSync27(workspaceDir)) {
|
|
22367
22811
|
console.error(
|
|
22368
22812
|
`\x1B[31m\u2717 Workspace directory does not exist: ${workspaceDir}\x1B[0m`
|
|
22369
22813
|
);
|
|
@@ -22377,15 +22821,15 @@ Active workspace: \x1B[36m${workspaceDir}\x1B[0m`);
|
|
|
22377
22821
|
);
|
|
22378
22822
|
process.exit(1);
|
|
22379
22823
|
}
|
|
22380
|
-
const gitignorePath =
|
|
22381
|
-
if (!
|
|
22382
|
-
|
|
22824
|
+
const gitignorePath = join28(workspaceDir, ".gitignore");
|
|
22825
|
+
if (!existsSync27(gitignorePath)) {
|
|
22826
|
+
writeFileSync15(
|
|
22383
22827
|
gitignorePath,
|
|
22384
22828
|
"node_modules/\n.agent/\n.agents/\n.claude/\n.gemini/\n.goose/\n*.log\n",
|
|
22385
22829
|
"utf8"
|
|
22386
22830
|
);
|
|
22387
22831
|
}
|
|
22388
|
-
const hasGitRepo =
|
|
22832
|
+
const hasGitRepo = existsSync27(join28(workspaceDir, ".git"));
|
|
22389
22833
|
if (!hasGitRepo) {
|
|
22390
22834
|
console.log("Initializing local Git repository...");
|
|
22391
22835
|
runGit2(workspaceDir, ["init", "-b", "main"]);
|
|
@@ -22417,7 +22861,7 @@ Active workspace: \x1B[36m${workspaceDir}\x1B[0m`);
|
|
|
22417
22861
|
if (proceedGh) {
|
|
22418
22862
|
try {
|
|
22419
22863
|
console.log(`Creating GitHub repository ${repoName}...`);
|
|
22420
|
-
|
|
22864
|
+
execFileSync5("gh", ghRepoCreateArgs(repoName, repoVisibility), {
|
|
22421
22865
|
cwd: workspaceDir,
|
|
22422
22866
|
stdio: "inherit"
|
|
22423
22867
|
});
|
|
@@ -22472,7 +22916,7 @@ Active workspace: \x1B[36m${workspaceDir}\x1B[0m`);
|
|
|
22472
22916
|
}
|
|
22473
22917
|
});
|
|
22474
22918
|
workspaceCommand.command("data-dir").description("Print the ZAM data directory (database, credentials, config)").option("--json", "Output as JSON").action((opts) => {
|
|
22475
|
-
const dir =
|
|
22919
|
+
const dir = join28(homedir16(), ".zam");
|
|
22476
22920
|
console.log(opts.json ? JSON.stringify({ dataDir: dir }) : dir);
|
|
22477
22921
|
});
|
|
22478
22922
|
workspaceCommand.command("backup").description("Back up the local ZAM database into your workspace").option(
|
|
@@ -22513,9 +22957,9 @@ workspaceCommand.command("backup").description("Back up the local ZAM database i
|
|
|
22513
22957
|
});
|
|
22514
22958
|
|
|
22515
22959
|
// src/cli/app.ts
|
|
22516
|
-
var __dirname =
|
|
22960
|
+
var __dirname = dirname14(fileURLToPath8(import.meta.url));
|
|
22517
22961
|
var pkg = JSON.parse(
|
|
22518
|
-
|
|
22962
|
+
readFileSync20(join29(__dirname, "..", "..", "package.json"), "utf-8")
|
|
22519
22963
|
);
|
|
22520
22964
|
var program = new Command27();
|
|
22521
22965
|
program.name("zam").description(
|