xaq-cli 0.1.0-nightly.83 → 0.1.0-nightly.84

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.
@@ -156,7 +156,7 @@ function registerExtensionCommands(program) {
156
156
  const dataOption = (cmd) => cmd.option("-d, --data <dir>", `xaq's data directory (default ~/.xaq, or an existing ~/.${LEGACY_PRODUCT}; env XAQ_DATA)`);
157
157
  const withApi = async (o, run) => {
158
158
  const { CLEANUP_SIGNALS, openAdminChannel } = await import("./admin-Buw2v1X4.js");
159
- const { TerminalPrompter } = await import("./prompt-CKMQx_MJ.js");
159
+ const { TerminalPrompter } = await import("./prompt-BEH311I7.js");
160
160
  const channel = openAdminChannel({ dataDir: resolveDataDir(o.data, { quiet: true }) });
161
161
  const handlers = CLEANUP_SIGNALS.map((sig) => {
162
162
  const h = () => {
@@ -193,4 +193,4 @@ Examples:
193
193
  //#endregion
194
194
  export { registerExtensionCommands };
195
195
 
196
- //# sourceMappingURL=cli-CWUY8Vua.js.map
196
+ //# sourceMappingURL=cli-Ctx_ruei.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cli-CWUY8Vua.js","names":[],"sources":["../server/extensions/cli.ts"],"sourcesContent":["// `xaq ext add | list | update | remove`: run on xaq's machine, through the daemon's /api/extensions over the local\n// admin channel (server/connections-cli/admin.ts), so the daemon's own checks (and B2's usedBy) apply.\n\nimport type { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport type { ExtensionErrorBody, ExtensionResolveResult, ExtensionUpdateResult, ExtensionView } from \"../../shared/extensions.ts\";\nimport { LEGACY_PRODUCT } from \"../brand.ts\";\nimport { resolveDataDir } from \"../config.ts\";\nimport { AdminApiError, type AdminChannel } from \"../connections-cli/admin.ts\";\nimport type { Prompter } from \"../connections-cli/prompt.ts\";\nimport { safeText } from \"../listen/ui.ts\";\nimport { NPX } from \"../listen/version.ts\";\nimport { parseSource } from \"./sources.ts\";\n\nconst enc = encodeURIComponent;\n\n/** The admin extensions API as the CLI uses it. */\nexport class ExtensionsApi {\n constructor(readonly channel: Pick<AdminChannel, \"request\">) {}\n list(): Promise<ExtensionView[]> {\n return this.channel.request(\"GET\", \"/api/extensions\");\n }\n resolve(source: string): Promise<ExtensionResolveResult> {\n return this.channel.request(\"POST\", \"/api/extensions/resolve\", { source });\n }\n install(source: string, confirmThirdParty: boolean, expectIntegrity: string): Promise<ExtensionView> {\n return this.channel.request(\"POST\", \"/api/extensions\", { source, confirmThirdParty, expectIntegrity });\n }\n update(name: string, body: { confirm: boolean; expectIntegrity?: string }): Promise<ExtensionUpdateResult> {\n return this.channel.request(\"POST\", `/api/extensions/${enc(name)}/update`, body);\n }\n remove(name: string, force: boolean): Promise<void> {\n return this.channel.request(\"DELETE\", `/api/extensions/${enc(name)}${force ? \"?force=true\" : \"\"}`);\n }\n}\n\nexport interface ExtDeps {\n api: ExtensionsApi;\n prompter: Prompter;\n /** Where a relative directory is resolved (default: this process's cwd). */\n cwd?: string;\n}\n\nconst shortCommit = (c: string | null) => (c ? c.slice(0, 12) : \"(directory)\");\nconst origin = (e: Pick<ExtensionView, \"official\">) => (e.official ? pc.green(\"official\") : pc.yellow(\"third-party\"));\n\nfunction describe(p: Prompter, e: ExtensionView): void {\n p.print(`${pc.bold(safeText(e.displayName, 60))} ${pc.dim(`(${e.name})`)} ${safeText(e.version, 40)}, kind ${e.kind}, ${origin(e)}`);\n p.print(` source ${safeText(e.source, 200)}`);\n p.print(` commit ${shortCommit(e.commit)}`);\n p.print(` integrity ${e.integrity}`);\n if (e.kind === \"code\") p.print(` network ${e.network.length ? e.network.map((h) => safeText(h, 100)).join(\", \") : \"none declared\"}`);\n}\n\nfunction printWarnings(p: Prompter, warnings: string[]): void {\n if (!warnings.length) return;\n p.print(\"\");\n for (const w of warnings) p.print(pc.yellow(`! ${safeText(w, 600)}`));\n p.print(\"\");\n}\n\n/** An API error body (a 409 that carries usedBy / warnings), or null. */\nconst errorBody = (err: unknown): ExtensionErrorBody | null => (err instanceof AdminApiError ? ((err.body as ExtensionErrorBody | null) ?? null) : null);\n\nexport async function addExtension(input: string, deps: ExtDeps): Promise<number> {\n const { api, prompter: p } = deps;\n // A directory is resolved here, against this terminal's cwd (and ~), not the daemon's: it gets the absolute path.\n const spec = parseSource(input, { cwd: deps.cwd ?? process.cwd() });\n const source = spec.type === \"local\" ? spec.path : input.trim();\n p.print(`Fetching ${pc.cyan(safeText(source, 200))}…`);\n const { candidate, warnings, installed } = await api.resolve(source);\n describe(p, candidate);\n if (installed) {\n if (installed.integrity === candidate.integrity) {\n p.print(`${pc.green(\"✔\")} ${candidate.name} ${installed.version} is already installed.`);\n return 0;\n }\n p.print(pc.yellow(`${candidate.name} is already installed (${installed.version}, ${shortCommit(installed.commit)}). To change it: ${NPX} ext update ${candidate.name}`));\n return 1;\n }\n if (!candidate.official) {\n printWarnings(p, warnings);\n if (!(await p.confirm(`Install the third-party extension ${candidate.name}?`, false))) {\n p.print(\"Nothing was installed.\");\n return 0;\n }\n }\n const ext = await api.install(source, !candidate.official, candidate.integrity);\n p.print(`${pc.green(\"✔\")} Installed ${ext.name} ${ext.version}${ext.commit ? ` (${shortCommit(ext.commit)})` : \"\"}.`);\n return 0;\n}\n\nexport async function listExtensions(deps: ExtDeps): Promise<number> {\n const { api, prompter: p } = deps;\n const all = await api.list();\n if (!all.length) {\n p.print(`No extensions installed. Add one: ${NPX} ext add <name|github-url|git-url|./dir>`);\n return 0;\n }\n const w = Math.max(4, ...all.map((e) => e.name.length));\n const v = Math.max(7, ...all.map((e) => safeText(e.version, 20).length));\n p.print(pc.dim(`${\"NAME\".padEnd(w)} ${\"VERSION\".padEnd(v)} ${\"COMMIT\".padEnd(12)} ${\"ORIGIN\".padEnd(11)} ${\"USED BY\".padEnd(16)} SOURCE`));\n for (const e of all) {\n const used = e.usedBy.length ? safeText(e.usedBy.join(\", \"), 40) : \"-\";\n p.print(\n `${e.name.padEnd(w)} ${safeText(e.version, 20).padEnd(v)} ${shortCommit(e.commit).padEnd(12)} ${(e.official ? \"official\" : \"third-party\").padEnd(11)} ${used.padEnd(16)} ${safeText(e.source, 120)}`,\n );\n }\n return 0;\n}\n\nexport async function updateExtension(name: string, deps: ExtDeps): Promise<number> {\n const { api, prompter: p } = deps;\n p.print(`Checking ${pc.cyan(name)} for an update…`);\n const preview = await api.update(name, { confirm: false });\n if (!preview.update) {\n p.print(`${pc.green(\"✔\")} ${name} is up to date.`);\n return 0;\n }\n const { from, to, warnings } = preview.update;\n const row = (label: string, a: string, b: string) => p.print(` ${label.padEnd(10)} ${a} → ${a === b ? pc.dim(b) : pc.bold(b)}`);\n p.print(`Update ${pc.bold(name)}:`);\n row(\"version\", safeText(from.version, 40), safeText(to.version, 40));\n row(\"commit\", shortCommit(from.commit), shortCommit(to.commit));\n row(\"integrity\", from.integrity, to.integrity);\n if (from.kind !== to.kind) row(\"kind\", from.kind, to.kind);\n const hosts = (e: ExtensionView) => (e.network.length ? e.network.map((h) => safeText(h, 100)).join(\", \") : \"none\");\n if (to.kind === \"code\" && hosts(from) !== hosts(to)) row(\"network\", hosts(from), hosts(to));\n printWarnings(p, warnings);\n if (from.usedBy.length) p.print(pc.dim(`Used by ${from.usedBy.join(\", \")}: they switch to the new version.`));\n if (!(await p.confirm(`Install ${name} ${safeText(to.version, 40)}?`, false))) {\n p.print(\"Nothing was changed.\");\n return 0;\n }\n const done = await api.update(name, { confirm: true, expectIntegrity: to.integrity });\n if (!done.update) {\n p.print(`${pc.green(\"✔\")} ${name} is up to date.`);\n return 0;\n }\n p.print(`${pc.green(\"✔\")} Updated ${name} to ${safeText(done.update.to.version, 40)}${done.update.to.commit ? ` (${shortCommit(done.update.to.commit)})` : \"\"}.`);\n return 0;\n}\n\nexport async function removeExtension(name: string, flags: { force?: boolean }, deps: ExtDeps): Promise<number> {\n const { api, prompter: p } = deps;\n const ext = (await api.list()).find((e) => e.name === name);\n if (!ext) throw new Error(`${name} isn't installed.`);\n if (ext.usedBy.length && !flags.force) {\n p.print(pc.yellow(`${name} is used by ${ext.usedBy.join(\", \")}.`));\n p.print(`Remove those connections first (${NPX} connections remove <name>), or pass --force, which disables them (their credentials stay until you remove them).`);\n return 1;\n }\n const what = ext.usedBy.length ? ` and disable ${ext.usedBy.join(\", \")}` : \"\";\n if (!(await p.confirm(`Remove the extension ${name}${what}?`, false))) return 0;\n try {\n await api.remove(name, !!flags.force);\n } catch (err) {\n const body = errorBody(err);\n if (body?.error.code === \"in_use\") {\n p.print(pc.yellow(`${name} is used by ${(body.usedBy ?? []).join(\", \")}. Pass --force to disable them and remove it.`));\n return 1;\n }\n throw err;\n }\n p.print(`${pc.green(\"✔\")} Removed ${name}.`);\n return 0;\n}\n\nconst GROUP = \"MCP connections (on xaq's machine):\";\n\nexport function registerExtensionCommands(program: Command): void {\n const dataOption = (cmd: Command) => cmd.option(\"-d, --data <dir>\", `xaq's data directory (default ~/.xaq, or an existing ~/.${LEGACY_PRODUCT}; env XAQ_DATA)`);\n const withApi = async (o: { data?: string; yes?: boolean }, run: (deps: ExtDeps) => Promise<number>) => {\n const { CLEANUP_SIGNALS, openAdminChannel } = await import(\"../connections-cli/admin.ts\");\n const { TerminalPrompter } = await import(\"../connections-cli/prompt.ts\");\n const channel = openAdminChannel({ dataDir: resolveDataDir(o.data, { quiet: true }) });\n const handlers = CLEANUP_SIGNALS.map((sig) => {\n const h = () => {\n channel.close();\n process.exit(sig === \"SIGINT\" ? 130 : 128 + (sig === \"SIGTERM\" ? 15 : 1));\n };\n process.once(sig, h);\n return [sig, h] as const;\n });\n try {\n process.exitCode = await run({ api: new ExtensionsApi(channel), prompter: new TerminalPrompter(!!o.yes) });\n } finally {\n for (const [sig, h] of handlers) process.removeListener(sig, h);\n channel.close();\n }\n };\n\n const ext = program\n .command(\"ext\")\n .description(\"extensions: the integrations xaq can connect to (Notion, WHOOP, T3 Code, …), from the official registry or elsewhere\")\n .summary(\"add, list, update or remove extensions\")\n .helpGroup(GROUP);\n\n dataOption(\n ext\n .command(\"add\")\n .description(\"install an extension: a registry name, a GitHub URL, another git URL (#ref, #ref:path), or a ./directory\")\n .argument(\"<name|url|path>\", \"e.g. notion, https://github.com/you/repo/tree/main/ext, ./my-extension\"),\n )\n .option(\"-y, --yes\", \"install a third-party extension without asking (the warning is still printed)\")\n .addHelpText(\n \"after\",\n `\nAnything that isn't the official registry (wynn-dev/xaq-extensions) is third-party: you see its kind, its declared\nnetwork hosts and its source first, and confirm. A code extension runs on this machine with network access.\n\nExamples:\n ${NPX} ext add notion\n ${NPX} ext add https://github.com/you/xaq-ext/tree/main/extensions/thing\n ${NPX} ext add https://git.example.com/you/ext.git#v1.2.0\n ${NPX} ext add ./my-extension`,\n )\n .action((source: string, o: { data?: string; yes?: boolean }) => withApi(o, (deps) => addExtension(source, deps)));\n\n dataOption(ext.command(\"list\").description(\"list installed extensions: version, commit, official or third-party, and the connections using each\")).action((o: { data?: string }) =>\n withApi(o, (deps) => listExtensions(deps)),\n );\n\n dataOption(ext.command(\"update\").description(\"show what an update changes (version, commit, integrity) and install it on confirmation\").argument(\"<name>\", \"the extension's name\"))\n .option(\"-y, --yes\", \"install the update without asking\")\n .action((name: string, o: { data?: string; yes?: boolean }) => withApi(o, (deps) => updateExtension(name, deps)));\n\n dataOption(ext.command(\"remove\").description(\"remove an extension (refused while connections use it, unless --force)\").argument(\"<name>\", \"the extension's name\"))\n .option(\"--force\", \"also when connections use it: they're disabled (credentials stay until you remove them)\")\n .option(\"-y, --yes\", \"don't ask\")\n .action((name: string, o: { data?: string; yes?: boolean; force?: boolean }) => withApi(o, (deps) => removeExtension(name, o, deps)));\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli-Ctx_ruei.js","names":[],"sources":["../server/extensions/cli.ts"],"sourcesContent":["// `xaq ext add | list | update | remove`: run on xaq's machine, through the daemon's /api/extensions over the local\n// admin channel (server/connections-cli/admin.ts), so the daemon's own checks (and B2's usedBy) apply.\n\nimport type { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport type { ExtensionErrorBody, ExtensionResolveResult, ExtensionUpdateResult, ExtensionView } from \"../../shared/extensions.ts\";\nimport { LEGACY_PRODUCT } from \"../brand.ts\";\nimport { resolveDataDir } from \"../config.ts\";\nimport { AdminApiError, type AdminChannel } from \"../connections-cli/admin.ts\";\nimport type { Prompter } from \"../connections-cli/prompt.ts\";\nimport { safeText } from \"../listen/ui.ts\";\nimport { NPX } from \"../listen/version.ts\";\nimport { parseSource } from \"./sources.ts\";\n\nconst enc = encodeURIComponent;\n\n/** The admin extensions API as the CLI uses it. */\nexport class ExtensionsApi {\n constructor(readonly channel: Pick<AdminChannel, \"request\">) {}\n list(): Promise<ExtensionView[]> {\n return this.channel.request(\"GET\", \"/api/extensions\");\n }\n resolve(source: string): Promise<ExtensionResolveResult> {\n return this.channel.request(\"POST\", \"/api/extensions/resolve\", { source });\n }\n install(source: string, confirmThirdParty: boolean, expectIntegrity: string): Promise<ExtensionView> {\n return this.channel.request(\"POST\", \"/api/extensions\", { source, confirmThirdParty, expectIntegrity });\n }\n update(name: string, body: { confirm: boolean; expectIntegrity?: string }): Promise<ExtensionUpdateResult> {\n return this.channel.request(\"POST\", `/api/extensions/${enc(name)}/update`, body);\n }\n remove(name: string, force: boolean): Promise<void> {\n return this.channel.request(\"DELETE\", `/api/extensions/${enc(name)}${force ? \"?force=true\" : \"\"}`);\n }\n}\n\nexport interface ExtDeps {\n api: ExtensionsApi;\n prompter: Prompter;\n /** Where a relative directory is resolved (default: this process's cwd). */\n cwd?: string;\n}\n\nconst shortCommit = (c: string | null) => (c ? c.slice(0, 12) : \"(directory)\");\nconst origin = (e: Pick<ExtensionView, \"official\">) => (e.official ? pc.green(\"official\") : pc.yellow(\"third-party\"));\n\nfunction describe(p: Prompter, e: ExtensionView): void {\n p.print(`${pc.bold(safeText(e.displayName, 60))} ${pc.dim(`(${e.name})`)} ${safeText(e.version, 40)}, kind ${e.kind}, ${origin(e)}`);\n p.print(` source ${safeText(e.source, 200)}`);\n p.print(` commit ${shortCommit(e.commit)}`);\n p.print(` integrity ${e.integrity}`);\n if (e.kind === \"code\") p.print(` network ${e.network.length ? e.network.map((h) => safeText(h, 100)).join(\", \") : \"none declared\"}`);\n}\n\nfunction printWarnings(p: Prompter, warnings: string[]): void {\n if (!warnings.length) return;\n p.print(\"\");\n for (const w of warnings) p.print(pc.yellow(`! ${safeText(w, 600)}`));\n p.print(\"\");\n}\n\n/** An API error body (a 409 that carries usedBy / warnings), or null. */\nconst errorBody = (err: unknown): ExtensionErrorBody | null => (err instanceof AdminApiError ? ((err.body as ExtensionErrorBody | null) ?? null) : null);\n\nexport async function addExtension(input: string, deps: ExtDeps): Promise<number> {\n const { api, prompter: p } = deps;\n // A directory is resolved here, against this terminal's cwd (and ~), not the daemon's: it gets the absolute path.\n const spec = parseSource(input, { cwd: deps.cwd ?? process.cwd() });\n const source = spec.type === \"local\" ? spec.path : input.trim();\n p.print(`Fetching ${pc.cyan(safeText(source, 200))}…`);\n const { candidate, warnings, installed } = await api.resolve(source);\n describe(p, candidate);\n if (installed) {\n if (installed.integrity === candidate.integrity) {\n p.print(`${pc.green(\"✔\")} ${candidate.name} ${installed.version} is already installed.`);\n return 0;\n }\n p.print(pc.yellow(`${candidate.name} is already installed (${installed.version}, ${shortCommit(installed.commit)}). To change it: ${NPX} ext update ${candidate.name}`));\n return 1;\n }\n if (!candidate.official) {\n printWarnings(p, warnings);\n if (!(await p.confirm(`Install the third-party extension ${candidate.name}?`, false))) {\n p.print(\"Nothing was installed.\");\n return 0;\n }\n }\n const ext = await api.install(source, !candidate.official, candidate.integrity);\n p.print(`${pc.green(\"✔\")} Installed ${ext.name} ${ext.version}${ext.commit ? ` (${shortCommit(ext.commit)})` : \"\"}.`);\n return 0;\n}\n\nexport async function listExtensions(deps: ExtDeps): Promise<number> {\n const { api, prompter: p } = deps;\n const all = await api.list();\n if (!all.length) {\n p.print(`No extensions installed. Add one: ${NPX} ext add <name|github-url|git-url|./dir>`);\n return 0;\n }\n const w = Math.max(4, ...all.map((e) => e.name.length));\n const v = Math.max(7, ...all.map((e) => safeText(e.version, 20).length));\n p.print(pc.dim(`${\"NAME\".padEnd(w)} ${\"VERSION\".padEnd(v)} ${\"COMMIT\".padEnd(12)} ${\"ORIGIN\".padEnd(11)} ${\"USED BY\".padEnd(16)} SOURCE`));\n for (const e of all) {\n const used = e.usedBy.length ? safeText(e.usedBy.join(\", \"), 40) : \"-\";\n p.print(\n `${e.name.padEnd(w)} ${safeText(e.version, 20).padEnd(v)} ${shortCommit(e.commit).padEnd(12)} ${(e.official ? \"official\" : \"third-party\").padEnd(11)} ${used.padEnd(16)} ${safeText(e.source, 120)}`,\n );\n }\n return 0;\n}\n\nexport async function updateExtension(name: string, deps: ExtDeps): Promise<number> {\n const { api, prompter: p } = deps;\n p.print(`Checking ${pc.cyan(name)} for an update…`);\n const preview = await api.update(name, { confirm: false });\n if (!preview.update) {\n p.print(`${pc.green(\"✔\")} ${name} is up to date.`);\n return 0;\n }\n const { from, to, warnings } = preview.update;\n const row = (label: string, a: string, b: string) => p.print(` ${label.padEnd(10)} ${a} → ${a === b ? pc.dim(b) : pc.bold(b)}`);\n p.print(`Update ${pc.bold(name)}:`);\n row(\"version\", safeText(from.version, 40), safeText(to.version, 40));\n row(\"commit\", shortCommit(from.commit), shortCommit(to.commit));\n row(\"integrity\", from.integrity, to.integrity);\n if (from.kind !== to.kind) row(\"kind\", from.kind, to.kind);\n const hosts = (e: ExtensionView) => (e.network.length ? e.network.map((h) => safeText(h, 100)).join(\", \") : \"none\");\n if (to.kind === \"code\" && hosts(from) !== hosts(to)) row(\"network\", hosts(from), hosts(to));\n printWarnings(p, warnings);\n if (from.usedBy.length) p.print(pc.dim(`Used by ${from.usedBy.join(\", \")}: they switch to the new version.`));\n if (!(await p.confirm(`Install ${name} ${safeText(to.version, 40)}?`, false))) {\n p.print(\"Nothing was changed.\");\n return 0;\n }\n const done = await api.update(name, { confirm: true, expectIntegrity: to.integrity });\n if (!done.update) {\n p.print(`${pc.green(\"✔\")} ${name} is up to date.`);\n return 0;\n }\n p.print(`${pc.green(\"✔\")} Updated ${name} to ${safeText(done.update.to.version, 40)}${done.update.to.commit ? ` (${shortCommit(done.update.to.commit)})` : \"\"}.`);\n return 0;\n}\n\nexport async function removeExtension(name: string, flags: { force?: boolean }, deps: ExtDeps): Promise<number> {\n const { api, prompter: p } = deps;\n const ext = (await api.list()).find((e) => e.name === name);\n if (!ext) throw new Error(`${name} isn't installed.`);\n if (ext.usedBy.length && !flags.force) {\n p.print(pc.yellow(`${name} is used by ${ext.usedBy.join(\", \")}.`));\n p.print(`Remove those connections first (${NPX} connections remove <name>), or pass --force, which disables them (their credentials stay until you remove them).`);\n return 1;\n }\n const what = ext.usedBy.length ? ` and disable ${ext.usedBy.join(\", \")}` : \"\";\n if (!(await p.confirm(`Remove the extension ${name}${what}?`, false))) return 0;\n try {\n await api.remove(name, !!flags.force);\n } catch (err) {\n const body = errorBody(err);\n if (body?.error.code === \"in_use\") {\n p.print(pc.yellow(`${name} is used by ${(body.usedBy ?? []).join(\", \")}. Pass --force to disable them and remove it.`));\n return 1;\n }\n throw err;\n }\n p.print(`${pc.green(\"✔\")} Removed ${name}.`);\n return 0;\n}\n\nconst GROUP = \"MCP connections (on xaq's machine):\";\n\nexport function registerExtensionCommands(program: Command): void {\n const dataOption = (cmd: Command) => cmd.option(\"-d, --data <dir>\", `xaq's data directory (default ~/.xaq, or an existing ~/.${LEGACY_PRODUCT}; env XAQ_DATA)`);\n const withApi = async (o: { data?: string; yes?: boolean }, run: (deps: ExtDeps) => Promise<number>) => {\n const { CLEANUP_SIGNALS, openAdminChannel } = await import(\"../connections-cli/admin.ts\");\n const { TerminalPrompter } = await import(\"../connections-cli/prompt.ts\");\n const channel = openAdminChannel({ dataDir: resolveDataDir(o.data, { quiet: true }) });\n const handlers = CLEANUP_SIGNALS.map((sig) => {\n const h = () => {\n channel.close();\n process.exit(sig === \"SIGINT\" ? 130 : 128 + (sig === \"SIGTERM\" ? 15 : 1));\n };\n process.once(sig, h);\n return [sig, h] as const;\n });\n try {\n process.exitCode = await run({ api: new ExtensionsApi(channel), prompter: new TerminalPrompter(!!o.yes) });\n } finally {\n for (const [sig, h] of handlers) process.removeListener(sig, h);\n channel.close();\n }\n };\n\n const ext = program\n .command(\"ext\")\n .description(\"extensions: the integrations xaq can connect to (Notion, WHOOP, T3 Code, …), from the official registry or elsewhere\")\n .summary(\"add, list, update or remove extensions\")\n .helpGroup(GROUP);\n\n dataOption(\n ext\n .command(\"add\")\n .description(\"install an extension: a registry name, a GitHub URL, another git URL (#ref, #ref:path), or a ./directory\")\n .argument(\"<name|url|path>\", \"e.g. notion, https://github.com/you/repo/tree/main/ext, ./my-extension\"),\n )\n .option(\"-y, --yes\", \"install a third-party extension without asking (the warning is still printed)\")\n .addHelpText(\n \"after\",\n `\nAnything that isn't the official registry (wynn-dev/xaq-extensions) is third-party: you see its kind, its declared\nnetwork hosts and its source first, and confirm. A code extension runs on this machine with network access.\n\nExamples:\n ${NPX} ext add notion\n ${NPX} ext add https://github.com/you/xaq-ext/tree/main/extensions/thing\n ${NPX} ext add https://git.example.com/you/ext.git#v1.2.0\n ${NPX} ext add ./my-extension`,\n )\n .action((source: string, o: { data?: string; yes?: boolean }) => withApi(o, (deps) => addExtension(source, deps)));\n\n dataOption(ext.command(\"list\").description(\"list installed extensions: version, commit, official or third-party, and the connections using each\")).action((o: { data?: string }) =>\n withApi(o, (deps) => listExtensions(deps)),\n );\n\n dataOption(ext.command(\"update\").description(\"show what an update changes (version, commit, integrity) and install it on confirmation\").argument(\"<name>\", \"the extension's name\"))\n .option(\"-y, --yes\", \"install the update without asking\")\n .action((name: string, o: { data?: string; yes?: boolean }) => withApi(o, (deps) => updateExtension(name, deps)));\n\n dataOption(ext.command(\"remove\").description(\"remove an extension (refused while connections use it, unless --force)\").argument(\"<name>\", \"the extension's name\"))\n .option(\"--force\", \"also when connections use it: they're disabled (credentials stay until you remove them)\")\n .option(\"-y, --yes\", \"don't ask\")\n .action((name: string, o: { data?: string; yes?: boolean; force?: boolean }) => withApi(o, (deps) => removeExtension(name, o, deps)));\n}\n"],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -59,7 +59,7 @@ const SERVER_GROUP = "Run xaq:";
59
59
  const AGENT_GROUP = "On an agent's machine:";
60
60
  withServerOptions(program.command("start", { isDefault: true }).description("run xaq in this terminal and print the setup link (the default command)").summary("run it in this terminal (the default command)").helpGroup(SERVER_GROUP)).option("--no-open", "don't open a browser on first run").option("--dev", "development: API only, the console runs on Vite (:5173)").allowExcessArguments().action(async (o, cmd) => {
61
61
  if (cmd.args.length) throw new Error(unknownCommand(cmd.args[0]));
62
- const { runForeground } = await import("./server-DvFqIeG0.js");
62
+ const { runForeground } = await import("./server-Bz2-63ji.js");
63
63
  await runForeground({
64
64
  ...configInput(o),
65
65
  dev: !!o.dev,
@@ -140,9 +140,9 @@ program.command("reset-password").description("forgot the console password? Remo
140
140
  });
141
141
  const { registerListenCommands } = await import("./commands-CIiohOpI.js");
142
142
  registerListenCommands(program);
143
- const { registerConnectionsCommands } = await import("./commands-CU46puIx.js");
143
+ const { registerConnectionsCommands } = await import("./commands-297K61sb.js");
144
144
  registerConnectionsCommands(program);
145
- const { registerExtensionCommands } = await import("./cli-CWUY8Vua.js");
145
+ const { registerExtensionCommands } = await import("./cli-Ctx_ruei.js");
146
146
  registerExtensionCommands(program);
147
147
  const AGENT_SUMMARIES = {
148
148
  connect: "pair an agent; you approve it in the console",
@@ -10,7 +10,7 @@ const dataOption = (cmd) => cmd.option("-d, --data <dir>", `xaq's data directory
10
10
  async function withApi(o, run) {
11
11
  const { CLEANUP_SIGNALS, openAdminChannel } = await import("./admin-Buw2v1X4.js");
12
12
  const { ConnectionsApi } = await import("./api-2WDmyFjs.js");
13
- const { TerminalPrompter } = await import("./prompt-CKMQx_MJ.js");
13
+ const { TerminalPrompter } = await import("./prompt-BEH311I7.js");
14
14
  const channel = openAdminChannel({ dataDir: dataDirOf(o) });
15
15
  const handlers = CLEANUP_SIGNALS.map((sig) => {
16
16
  const h = () => {
@@ -51,27 +51,27 @@ Examples:
51
51
  ${NPX} connections add t3code --url http://100.101.102.103:3773 # one per T3 server; have a T3 pairing code ready
52
52
  ${NPX} connections add https://mcp.example.com/mcp --access read
53
53
  ${NPX} connections add http://127.0.0.1:8787/mcp # asks before allowing a server on this machine`).action(async (target, o) => {
54
- const { addConnection } = await import("./manage-DGvJajD1.js");
54
+ const { addConnection } = await import("./manage-Cr-TRCDw.js");
55
55
  process.exitCode = await withApi(o, (deps) => addConnection(target, o, deps));
56
56
  });
57
57
  dataOption(connections.command("list").description("list connections with their status and access")).action(async (o) => {
58
- const { listConnections } = await import("./manage-DGvJajD1.js");
58
+ const { listConnections } = await import("./manage-Cr-TRCDw.js");
59
59
  process.exitCode = await withApi(o, (deps) => listConnections(deps));
60
60
  });
61
61
  dataOption(connections.command("reconnect").description("sign in again (OAuth) or replace the key (header)").argument("<name>", "the connection's name")).option("--paste", "paste the address the browser lands on (automatic over SSH)").option("--header <name>", "header connections: the header's name (default: asks, Authorization)").action(async (slug, o) => {
62
- const { reconnectConnection } = await import("./manage-DGvJajD1.js");
62
+ const { reconnectConnection } = await import("./manage-Cr-TRCDw.js");
63
63
  process.exitCode = await withApi(o, (deps) => reconnectConnection(slug, o, deps));
64
64
  });
65
65
  dataOption(connections.command("disable").description("turn a connection off at once (the kill switch); turn it back on in the console").argument("<name>", "the connection's name")).option("-y, --yes", "don't ask").action(async (slug, o) => {
66
- const { disableConnection } = await import("./manage-DGvJajD1.js");
66
+ const { disableConnection } = await import("./manage-Cr-TRCDw.js");
67
67
  process.exitCode = await withApi(o, (deps) => disableConnection(slug, deps));
68
68
  });
69
69
  dataOption(connections.command("rename").description("change a connection's short name (agents see its tools as <name>__<tool>) or its display name").argument("<name>", "the connection's current short name (or its id)")).option("--slug <new>", "the new short name: 1-24 lowercase letters, digits and dashes (calls by the old tool names stop working)").option("--name <display-name>", "a new display name").option("-y, --yes", "don't ask").action(async (target, o) => {
70
- const { renameConnection } = await import("./manage-DGvJajD1.js");
70
+ const { renameConnection } = await import("./manage-Cr-TRCDw.js");
71
71
  process.exitCode = await withApi(o, (deps) => renameConnection(target, o, deps));
72
72
  });
73
73
  dataOption(connections.command("remove").description("remove a connection and delete its credentials").argument("<name>", "the connection's name")).option("-y, --yes", "don't ask").action(async (slug, o) => {
74
- const { removeConnection } = await import("./manage-DGvJajD1.js");
74
+ const { removeConnection } = await import("./manage-Cr-TRCDw.js");
75
75
  process.exitCode = await withApi(o, (deps) => removeConnection(slug, deps));
76
76
  });
77
77
  dataOption(program.command("import", { hidden: false }).description("move an agent tool's MCP servers into xaq: one connection each, credentials moved into xaq").summary("import MCP servers from Hermes, Claude Code, Cursor or Codex").helpGroup(GROUP).requiredOption("--from <client>", "hermes, claude-code, cursor or codex")).option("--dry-run", "print exactly what would be created and changed, and change nothing").option("--access <level>", "for every imported connection: full, ask (the default) or read").option("--agent <name>", "an agent that gets them (repeatable; default: all agents; \"all\")", collect).option("--profile <name>", "the agent profile setup-mcp uses for the single xaq entry (default \"default\")").option("--allow-private <origin>", "allow this exact scheme://host:port on this machine or a private network without asking (repeatable; --yes never does)", collect).option("-y, --yes", "answer yes to the confirmations (scripts); never to a private-network allow or a project's .mcp.json servers").addHelpText("after", `
@@ -86,10 +86,10 @@ with the single xaq entry, after a timestamped backup. The entry keeps the name
86
86
  Examples:
87
87
  ${NPX} import --from hermes --dry-run
88
88
  ${NPX} import --from hermes`).action(async (o) => {
89
- const { runImport } = await import("./import-spafY6Qe.js");
89
+ const { runImport } = await import("./import-BWrQCTD4.js");
90
90
  const self = await selfOrigins(dataDirOf(o));
91
91
  if (o.dryRun) {
92
- const { TerminalPrompter } = await import("./prompt-CKMQx_MJ.js");
92
+ const { TerminalPrompter } = await import("./prompt-BEH311I7.js");
93
93
  const { openAdminChannel } = await import("./admin-Buw2v1X4.js");
94
94
  const { ConnectionsApi } = await import("./api-2WDmyFjs.js");
95
95
  let channel = null;
@@ -114,4 +114,4 @@ Examples:
114
114
  //#endregion
115
115
  export { registerConnectionsCommands };
116
116
 
117
- //# sourceMappingURL=commands-CU46puIx.js.map
117
+ //# sourceMappingURL=commands-297K61sb.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"commands-CU46puIx.js","names":[],"sources":["../server/connections-cli/commands.ts"],"sourcesContent":["import type { Command } from \"commander\";\nimport { NPX } from \"../listen/version.ts\";\nimport { LEGACY_PRODUCT } from \"../brand.ts\";\nimport { resolveDataDir } from \"../config.ts\";\n\n/**\n * `connections …` and `import --from …`: run on the daemon's machine, talking to its admin API through the\n * one-time local admin session (admin.ts). Listed in --help since the console (#65) shipped; while the daemon's\n * `brokerUpstreams` setting is off they say so (CONNECTIONS_VISIBLE).\n */\nexport const CONNECTIONS_VISIBLE = true;\nconst GROUP = \"MCP connections (on xaq's machine):\";\n\nconst collect = (value: string, previous: string[] | undefined) => [...(previous ?? []), value];\n// --data, else XAQ_DATA (AGENTINBOX_DATA), else ~/.xaq or an existing pre-rename ~/.agentinbox (config.ts; rename-xaq: keep).\nconst dataDirOf = (o: { data?: string }) => resolveDataDir(o.data, { quiet: true });\nconst dataOption = (cmd: Command) => cmd.option(\"-d, --data <dir>\", `xaq's data directory (default ~/.xaq, or an existing ~/.${LEGACY_PRODUCT}; env XAQ_DATA)`);\n\nasync function withApi<T>(o: { data?: string; yes?: boolean }, run: (deps: { api: import(\"./api.ts\").ConnectionsApi; prompter: import(\"./prompt.ts\").Prompter }) => Promise<T>): Promise<T> {\n const { CLEANUP_SIGNALS, openAdminChannel } = await import(\"./admin.ts\");\n const { ConnectionsApi } = await import(\"./api.ts\");\n const { TerminalPrompter } = await import(\"./prompt.ts\");\n const channel = openAdminChannel({ dataDir: dataDirOf(o) });\n const handlers = CLEANUP_SIGNALS.map((sig) => {\n const h = () => {\n channel.close();\n process.exit(sig === \"SIGINT\" ? 130 : 128 + (sig === \"SIGTERM\" ? 15 : 1));\n };\n process.once(sig, h);\n return [sig, h] as const;\n });\n try {\n return await run({ api: new ConnectionsApi(channel), prompter: new TerminalPrompter(!!o.yes) });\n } finally {\n for (const [sig, h] of handlers) process.removeListener(sig, h);\n channel.close();\n }\n}\n\n/** This xaq's own MCP origins, so `import` never imports its own entry. */\nasync function selfOrigins(dataDir: string): Promise<string[]> {\n const { runningInstance } = await import(\"../instance.ts\");\n const { daemonOrigin } = await import(\"./admin.ts\");\n const running = runningInstance(dataDir);\n if (!running) return [];\n return [daemonOrigin(running), `http://localhost:${running.port}`, `http://127.0.0.1:${running.port}`, `http://[::1]:${running.port}`];\n}\n\nexport function registerConnectionsCommands(program: Command): void {\n const connections = program\n .command(\"connections\", { hidden: !CONNECTIONS_VISIBLE })\n .description(\"the MCP servers xaq connects agents to (Notion, T3 Code, any MCP URL, installed extensions); run on xaq's machine\")\n .summary(\"add, list, reconnect or remove connected MCP servers\")\n .helpGroup(GROUP);\n\n dataOption(\n connections\n .command(\"add\")\n .description(\"connect an installed extension (install it first: `ext add notion`) or any MCP server URL, interactively\")\n .argument(\"<integration-or-url>\", \"an installed extension (`ext add notion|t3code|whoop|brightspace` first), or an MCP server URL such as https://mcp.example.com/mcp\"),\n )\n .option(\"--url <address>\", \"t3code: your T3 Code server's address, e.g. http://100.101.102.103:3773 (asked when omitted)\")\n .option(\"--slug <name>\", \"its short name: agents see its tools as <name>__<tool>\")\n .option(\"--name <name>\", \"its display name (unique; default: the server's host, or the integration's name)\")\n .option(\"--access <level>\", \"full, ask (ask before risky actions; the default) or read\")\n .option(\"--agent <name>\", 'an agent that gets it (repeatable; default: all agents; \"all\")', collect)\n .option(\"--header <name>\", \"header for a server that wants a static key (default Authorization)\")\n .option(\"--paste\", \"paste the address the browser lands on after signing in, instead of waiting for the redirect (automatic over SSH)\")\n .option(\"--allow-private <origin>\", \"allow this exact scheme://host:port on this machine or a private network without asking (--yes never does)\")\n .option(\"-y, --yes\", \"answer yes to confirmations and take the defaults (never to a private-network allow)\")\n .addHelpText(\n \"after\",\n `\nExamples:\n ${NPX} connections add notion\n ${NPX} connections add t3code --url http://100.101.102.103:3773 # one per T3 server; have a T3 pairing code ready\n ${NPX} connections add https://mcp.example.com/mcp --access read\n ${NPX} connections add http://127.0.0.1:8787/mcp # asks before allowing a server on this machine`,\n )\n .action(async (target: string, o: import(\"./manage.ts\").AddFlags & { data?: string }) => {\n const { addConnection } = await import(\"./manage.ts\");\n process.exitCode = await withApi(o, (deps) => addConnection(target, o, deps));\n });\n\n dataOption(connections.command(\"list\").description(\"list connections with their status and access\")).action(async (o: { data?: string }) => {\n const { listConnections } = await import(\"./manage.ts\");\n process.exitCode = await withApi(o, (deps) => listConnections(deps));\n });\n\n dataOption(connections.command(\"reconnect\").description(\"sign in again (OAuth) or replace the key (header)\").argument(\"<name>\", \"the connection's name\"))\n .option(\"--paste\", \"paste the address the browser lands on (automatic over SSH)\")\n .option(\"--header <name>\", \"header connections: the header's name (default: asks, Authorization)\")\n .action(async (slug: string, o: { data?: string; paste?: boolean; header?: string }) => {\n const { reconnectConnection } = await import(\"./manage.ts\");\n process.exitCode = await withApi(o, (deps) => reconnectConnection(slug, o, deps));\n });\n\n dataOption(connections.command(\"disable\").description(\"turn a connection off at once (the kill switch); turn it back on in the console\").argument(\"<name>\", \"the connection's name\"))\n .option(\"-y, --yes\", \"don't ask\")\n .action(async (slug: string, o: { data?: string; yes?: boolean }) => {\n const { disableConnection } = await import(\"./manage.ts\");\n process.exitCode = await withApi(o, (deps) => disableConnection(slug, deps));\n });\n\n dataOption(\n connections\n .command(\"rename\")\n .description(\"change a connection's short name (agents see its tools as <name>__<tool>) or its display name\")\n .argument(\"<name>\", \"the connection's current short name (or its id)\"),\n )\n .option(\"--slug <new>\", \"the new short name: 1-24 lowercase letters, digits and dashes (calls by the old tool names stop working)\")\n .option(\"--name <display-name>\", \"a new display name\")\n .option(\"-y, --yes\", \"don't ask\")\n .action(async (target: string, o: { data?: string; yes?: boolean; slug?: string; name?: string }) => {\n const { renameConnection } = await import(\"./manage.ts\");\n process.exitCode = await withApi(o, (deps) => renameConnection(target, o, deps));\n });\n\n dataOption(connections.command(\"remove\").description(\"remove a connection and delete its credentials\").argument(\"<name>\", \"the connection's name\"))\n .option(\"-y, --yes\", \"don't ask\")\n .action(async (slug: string, o: { data?: string; yes?: boolean }) => {\n const { removeConnection } = await import(\"./manage.ts\");\n process.exitCode = await withApi(o, (deps) => removeConnection(slug, deps));\n });\n\n dataOption(\n program\n .command(\"import\", { hidden: !CONNECTIONS_VISIBLE })\n .description(\"move an agent tool's MCP servers into xaq: one connection each, credentials moved into xaq\")\n .summary(\"import MCP servers from Hermes, Claude Code, Cursor or Codex\")\n .helpGroup(GROUP)\n .requiredOption(\"--from <client>\", \"hermes, claude-code, cursor or codex\"),\n )\n .option(\"--dry-run\", \"print exactly what would be created and changed, and change nothing\")\n .option(\"--access <level>\", \"for every imported connection: full, ask (the default) or read\")\n .option(\"--agent <name>\", 'an agent that gets them (repeatable; default: all agents; \"all\")', collect)\n .option(\"--profile <name>\", \"the agent profile setup-mcp uses for the single xaq entry (default \\\"default\\\")\")\n .option(\"--allow-private <origin>\", \"allow this exact scheme://host:port on this machine or a private network without asking (repeatable; --yes never does)\", collect)\n .option(\"-y, --yes\", \"answer yes to the confirmations (scripts); never to a private-network allow or a project's .mcp.json servers\")\n .addHelpText(\n \"after\",\n `\nReads: hermes ~/.hermes/config.yaml mcp_servers (+ ~/.hermes/.env) · claude-code ~/.claude.json and ./.mcp.json ·\ncursor ~/.cursor/mcp.json · codex ~/.codex/config.toml. Static headers move into xaq (encrypted); OAuth\nservers are created needing Connect (their tokens stay in the client); local (stdio) servers aren't supported yet\nand stay where they are. Servers on this machine or a private network are created only after you confirm the exact\nhost:port. Then it offers setup-mcp --tool <client>, which replaces the entries that now work through xaq\nwith the single xaq entry, after a timestamped backup. The entry keeps the name the profile already uses (\"xaq\", or\n\"${LEGACY_PRODUCT}\" for a profile set up before the rename), so Hermes routes and cron jobs confined to it keep working.\n\nExamples:\n ${NPX} import --from hermes --dry-run\n ${NPX} import --from hermes`,\n )\n .action(async (o: import(\"./import.ts\").ImportFlags & { data?: string }) => {\n const { runImport } = await import(\"./import.ts\");\n const self = await selfOrigins(dataDirOf(o));\n if (o.dryRun) {\n // Read-only: the admin channel (when the daemon runs) only lists existing connections.\n const { TerminalPrompter } = await import(\"./prompt.ts\");\n const { openAdminChannel } = await import(\"./admin.ts\");\n const { ConnectionsApi } = await import(\"./api.ts\");\n let channel: import(\"./admin.ts\").AdminChannel | null = null;\n try {\n process.exitCode = await runImport(o, {\n prompter: new TerminalPrompter(!!o.yes),\n openApi: () => new ConnectionsApi((channel = openAdminChannel({ dataDir: dataDirOf(o) }))),\n selfOrigins: self,\n });\n } finally {\n (channel as import(\"./admin.ts\").AdminChannel | null)?.close();\n }\n return;\n }\n process.exitCode = await withApi(o, (deps) => runImport(o, { prompter: deps.prompter, openApi: () => deps.api, selfOrigins: self }));\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"commands-297K61sb.js","names":[],"sources":["../server/connections-cli/commands.ts"],"sourcesContent":["import type { Command } from \"commander\";\nimport { NPX } from \"../listen/version.ts\";\nimport { LEGACY_PRODUCT } from \"../brand.ts\";\nimport { resolveDataDir } from \"../config.ts\";\n\n/**\n * `connections …` and `import --from …`: run on the daemon's machine, talking to its admin API through the\n * one-time local admin session (admin.ts). Listed in --help since the console (#65) shipped; while the daemon's\n * `brokerUpstreams` setting is off they say so (CONNECTIONS_VISIBLE).\n */\nexport const CONNECTIONS_VISIBLE = true;\nconst GROUP = \"MCP connections (on xaq's machine):\";\n\nconst collect = (value: string, previous: string[] | undefined) => [...(previous ?? []), value];\n// --data, else XAQ_DATA (AGENTINBOX_DATA), else ~/.xaq or an existing pre-rename ~/.agentinbox (config.ts; rename-xaq: keep).\nconst dataDirOf = (o: { data?: string }) => resolveDataDir(o.data, { quiet: true });\nconst dataOption = (cmd: Command) => cmd.option(\"-d, --data <dir>\", `xaq's data directory (default ~/.xaq, or an existing ~/.${LEGACY_PRODUCT}; env XAQ_DATA)`);\n\nasync function withApi<T>(o: { data?: string; yes?: boolean }, run: (deps: { api: import(\"./api.ts\").ConnectionsApi; prompter: import(\"./prompt.ts\").Prompter }) => Promise<T>): Promise<T> {\n const { CLEANUP_SIGNALS, openAdminChannel } = await import(\"./admin.ts\");\n const { ConnectionsApi } = await import(\"./api.ts\");\n const { TerminalPrompter } = await import(\"./prompt.ts\");\n const channel = openAdminChannel({ dataDir: dataDirOf(o) });\n const handlers = CLEANUP_SIGNALS.map((sig) => {\n const h = () => {\n channel.close();\n process.exit(sig === \"SIGINT\" ? 130 : 128 + (sig === \"SIGTERM\" ? 15 : 1));\n };\n process.once(sig, h);\n return [sig, h] as const;\n });\n try {\n return await run({ api: new ConnectionsApi(channel), prompter: new TerminalPrompter(!!o.yes) });\n } finally {\n for (const [sig, h] of handlers) process.removeListener(sig, h);\n channel.close();\n }\n}\n\n/** This xaq's own MCP origins, so `import` never imports its own entry. */\nasync function selfOrigins(dataDir: string): Promise<string[]> {\n const { runningInstance } = await import(\"../instance.ts\");\n const { daemonOrigin } = await import(\"./admin.ts\");\n const running = runningInstance(dataDir);\n if (!running) return [];\n return [daemonOrigin(running), `http://localhost:${running.port}`, `http://127.0.0.1:${running.port}`, `http://[::1]:${running.port}`];\n}\n\nexport function registerConnectionsCommands(program: Command): void {\n const connections = program\n .command(\"connections\", { hidden: !CONNECTIONS_VISIBLE })\n .description(\"the MCP servers xaq connects agents to (Notion, T3 Code, any MCP URL, installed extensions); run on xaq's machine\")\n .summary(\"add, list, reconnect or remove connected MCP servers\")\n .helpGroup(GROUP);\n\n dataOption(\n connections\n .command(\"add\")\n .description(\"connect an installed extension (install it first: `ext add notion`) or any MCP server URL, interactively\")\n .argument(\"<integration-or-url>\", \"an installed extension (`ext add notion|t3code|whoop|brightspace` first), or an MCP server URL such as https://mcp.example.com/mcp\"),\n )\n .option(\"--url <address>\", \"t3code: your T3 Code server's address, e.g. http://100.101.102.103:3773 (asked when omitted)\")\n .option(\"--slug <name>\", \"its short name: agents see its tools as <name>__<tool>\")\n .option(\"--name <name>\", \"its display name (unique; default: the server's host, or the integration's name)\")\n .option(\"--access <level>\", \"full, ask (ask before risky actions; the default) or read\")\n .option(\"--agent <name>\", 'an agent that gets it (repeatable; default: all agents; \"all\")', collect)\n .option(\"--header <name>\", \"header for a server that wants a static key (default Authorization)\")\n .option(\"--paste\", \"paste the address the browser lands on after signing in, instead of waiting for the redirect (automatic over SSH)\")\n .option(\"--allow-private <origin>\", \"allow this exact scheme://host:port on this machine or a private network without asking (--yes never does)\")\n .option(\"-y, --yes\", \"answer yes to confirmations and take the defaults (never to a private-network allow)\")\n .addHelpText(\n \"after\",\n `\nExamples:\n ${NPX} connections add notion\n ${NPX} connections add t3code --url http://100.101.102.103:3773 # one per T3 server; have a T3 pairing code ready\n ${NPX} connections add https://mcp.example.com/mcp --access read\n ${NPX} connections add http://127.0.0.1:8787/mcp # asks before allowing a server on this machine`,\n )\n .action(async (target: string, o: import(\"./manage.ts\").AddFlags & { data?: string }) => {\n const { addConnection } = await import(\"./manage.ts\");\n process.exitCode = await withApi(o, (deps) => addConnection(target, o, deps));\n });\n\n dataOption(connections.command(\"list\").description(\"list connections with their status and access\")).action(async (o: { data?: string }) => {\n const { listConnections } = await import(\"./manage.ts\");\n process.exitCode = await withApi(o, (deps) => listConnections(deps));\n });\n\n dataOption(connections.command(\"reconnect\").description(\"sign in again (OAuth) or replace the key (header)\").argument(\"<name>\", \"the connection's name\"))\n .option(\"--paste\", \"paste the address the browser lands on (automatic over SSH)\")\n .option(\"--header <name>\", \"header connections: the header's name (default: asks, Authorization)\")\n .action(async (slug: string, o: { data?: string; paste?: boolean; header?: string }) => {\n const { reconnectConnection } = await import(\"./manage.ts\");\n process.exitCode = await withApi(o, (deps) => reconnectConnection(slug, o, deps));\n });\n\n dataOption(connections.command(\"disable\").description(\"turn a connection off at once (the kill switch); turn it back on in the console\").argument(\"<name>\", \"the connection's name\"))\n .option(\"-y, --yes\", \"don't ask\")\n .action(async (slug: string, o: { data?: string; yes?: boolean }) => {\n const { disableConnection } = await import(\"./manage.ts\");\n process.exitCode = await withApi(o, (deps) => disableConnection(slug, deps));\n });\n\n dataOption(\n connections\n .command(\"rename\")\n .description(\"change a connection's short name (agents see its tools as <name>__<tool>) or its display name\")\n .argument(\"<name>\", \"the connection's current short name (or its id)\"),\n )\n .option(\"--slug <new>\", \"the new short name: 1-24 lowercase letters, digits and dashes (calls by the old tool names stop working)\")\n .option(\"--name <display-name>\", \"a new display name\")\n .option(\"-y, --yes\", \"don't ask\")\n .action(async (target: string, o: { data?: string; yes?: boolean; slug?: string; name?: string }) => {\n const { renameConnection } = await import(\"./manage.ts\");\n process.exitCode = await withApi(o, (deps) => renameConnection(target, o, deps));\n });\n\n dataOption(connections.command(\"remove\").description(\"remove a connection and delete its credentials\").argument(\"<name>\", \"the connection's name\"))\n .option(\"-y, --yes\", \"don't ask\")\n .action(async (slug: string, o: { data?: string; yes?: boolean }) => {\n const { removeConnection } = await import(\"./manage.ts\");\n process.exitCode = await withApi(o, (deps) => removeConnection(slug, deps));\n });\n\n dataOption(\n program\n .command(\"import\", { hidden: !CONNECTIONS_VISIBLE })\n .description(\"move an agent tool's MCP servers into xaq: one connection each, credentials moved into xaq\")\n .summary(\"import MCP servers from Hermes, Claude Code, Cursor or Codex\")\n .helpGroup(GROUP)\n .requiredOption(\"--from <client>\", \"hermes, claude-code, cursor or codex\"),\n )\n .option(\"--dry-run\", \"print exactly what would be created and changed, and change nothing\")\n .option(\"--access <level>\", \"for every imported connection: full, ask (the default) or read\")\n .option(\"--agent <name>\", 'an agent that gets them (repeatable; default: all agents; \"all\")', collect)\n .option(\"--profile <name>\", \"the agent profile setup-mcp uses for the single xaq entry (default \\\"default\\\")\")\n .option(\"--allow-private <origin>\", \"allow this exact scheme://host:port on this machine or a private network without asking (repeatable; --yes never does)\", collect)\n .option(\"-y, --yes\", \"answer yes to the confirmations (scripts); never to a private-network allow or a project's .mcp.json servers\")\n .addHelpText(\n \"after\",\n `\nReads: hermes ~/.hermes/config.yaml mcp_servers (+ ~/.hermes/.env) · claude-code ~/.claude.json and ./.mcp.json ·\ncursor ~/.cursor/mcp.json · codex ~/.codex/config.toml. Static headers move into xaq (encrypted); OAuth\nservers are created needing Connect (their tokens stay in the client); local (stdio) servers aren't supported yet\nand stay where they are. Servers on this machine or a private network are created only after you confirm the exact\nhost:port. Then it offers setup-mcp --tool <client>, which replaces the entries that now work through xaq\nwith the single xaq entry, after a timestamped backup. The entry keeps the name the profile already uses (\"xaq\", or\n\"${LEGACY_PRODUCT}\" for a profile set up before the rename), so Hermes routes and cron jobs confined to it keep working.\n\nExamples:\n ${NPX} import --from hermes --dry-run\n ${NPX} import --from hermes`,\n )\n .action(async (o: import(\"./import.ts\").ImportFlags & { data?: string }) => {\n const { runImport } = await import(\"./import.ts\");\n const self = await selfOrigins(dataDirOf(o));\n if (o.dryRun) {\n // Read-only: the admin channel (when the daemon runs) only lists existing connections.\n const { TerminalPrompter } = await import(\"./prompt.ts\");\n const { openAdminChannel } = await import(\"./admin.ts\");\n const { ConnectionsApi } = await import(\"./api.ts\");\n let channel: import(\"./admin.ts\").AdminChannel | null = null;\n try {\n process.exitCode = await runImport(o, {\n prompter: new TerminalPrompter(!!o.yes),\n openApi: () => new ConnectionsApi((channel = openAdminChannel({ dataDir: dataDirOf(o) }))),\n selfOrigins: self,\n });\n } finally {\n (channel as import(\"./admin.ts\").AdminChannel | null)?.close();\n }\n return;\n }\n process.exitCode = await withApi(o, (deps) => runImport(o, { prompter: deps.prompter, openApi: () => deps.api, selfOrigins: self }));\n });\n}\n"],"mappings":"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"}
@@ -5,7 +5,7 @@ import { a as mcpServerName, n as loadProfile, r as profileExists } from "./prof
5
5
  import "./recipes-D_quZbpA.js";
6
6
  import { i as safeText } from "./ui-B8Sd4Y7Y.js";
7
7
  import { _ as readTomlMcpServers, a as cursorConfigFile, c as mcpTarget, g as UNREADABLE$1, h as readTopMap, i as codexConfigFile, m as readMcpServers, n as claudeConfigFile, p as UNREADABLE, s as hermesHome, u as setupMcp } from "./mcpsetup-DjMhHnJo.js";
8
- import { _ as accessLabel, a as isWorking, b as chooseAgents, g as checkTarget, h as slugify, m as reconnectHint, p as waitWorking, v as agentsLabel, x as parseAccess, y as chooseAccess } from "./manage-z7PyU7z-.js";
8
+ import { S as parseAccess, _ as checkTarget, b as chooseAccess, g as slugify, h as reconnectHint, m as waitWorking, o as isWorking, v as accessLabel, x as chooseAgents, y as agentsLabel } from "./manage-BWPCsatQ.js";
9
9
  import { existsSync, readFileSync } from "node:fs";
10
10
  import { join } from "node:path";
11
11
  import pc from "picocolors";
@@ -912,4 +912,4 @@ async function offerSetup(deps, api, client, who, working, pending, code) {
912
912
  //#endregion
913
913
  export { runImport };
914
914
 
915
- //# sourceMappingURL=import-spafY6Qe.js.map
915
+ //# sourceMappingURL=import-BWrQCTD4.js.map