scream-code 0.15.7 → 0.15.9

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.
@@ -6,7 +6,7 @@ const __dirname = __cjsShimDirname(__filename);
6
6
  import { i as __require, o as __toESM, r as __exportAll, t as __commonJSMin } from "./chunk-D90kvbyJ.mjs";
7
7
  import { C as join$1, D as resolve$1, E as relative$1, S as isAbsolute$1, T as parse$7, a as isSupportedFile, b as basename$1, i as ingestFile, r as ingestDirectory, t as multiSearch, w as normalize$1, x as dirname$2, y as KnowledgeStore } from "./src-tDEINaMV.mjs";
8
8
  import { t as require_base64_js } from "./base64-js-DzVmk6Nb.mjs";
9
- import { a as setLocale, i as getLocale, n as assertScreamHostIdentity, o as t, r as createScreamDefaultHeaders, t as TextInputDialogComponent } from "./text-input-dialog-CnQM0DYj.mjs";
9
+ import { a as setLocale, i as getLocale, n as assertScreamHostIdentity, o as t, r as createScreamDefaultHeaders, t as TextInputDialogComponent } from "./text-input-dialog-Dx7LJTG6.mjs";
10
10
  import { createRequire } from "node:module";
11
11
  import { createHash, randomBytes, randomInt, randomUUID } from "node:crypto";
12
12
  import * as fs$1 from "node:fs/promises";
@@ -67201,7 +67201,14 @@ const McpServerCommonFields = {
67201
67201
  startupTimeoutMs: z.number().int().min(1).optional(),
67202
67202
  toolTimeoutMs: z.number().int().min(1).optional(),
67203
67203
  enabledTools: z.array(z.string()).optional(),
67204
- disabledTools: z.array(z.string()).optional()
67204
+ disabledTools: z.array(z.string()).optional(),
67205
+ /**
67206
+ * Open-vocabulary capabilities this server provides (e.g. `["browser"]`).
67207
+ * Semantics: absent = auto-detect via built-in fingerprints;
67208
+ * `[]` = explicitly opted out of fingerprinting; non-empty = explicit
67209
+ * declaration (highest priority). See `mcp/capabilities.ts`.
67210
+ */
67211
+ capabilities: z.array(z.string().min(1)).optional()
67205
67212
  };
67206
67213
  const McpServerStdioConfigSchema = z.object({
67207
67214
  transport: z.literal("stdio"),
@@ -83173,71 +83180,83 @@ function formatElapsed$1(ms) {
83173
83180
  if (totalSeconds < 60) return `${totalSeconds}s`;
83174
83181
  return `${Math.floor(totalSeconds / 60)}m${(totalSeconds % 60).toString().padStart(2, "0")}s`;
83175
83182
  }
83176
- //#endregion
83177
- //#region ../../packages/agent-core/src/agent/injection/mcp-browser-skill.ts
83178
- const BROWSER_SKILL_GUIDANCE = `\
83183
+ const MCP_CAPABILITY_GUIDES = [{
83184
+ capability: "browser",
83185
+ variant: "mcp_browser_skill",
83186
+ text: `\
83179
83187
  ## Browser Automation (chrome-devtools-mcp)
83180
83188
 
83181
- You have chrome-devtools-mcp tools available (\`mcp__chrome_devtools__*\`).
83182
- These give you full control over a Chrome browser instance so you can test,
83183
- debug, and inspect web pages directly.
83184
-
83185
- ### Navigation & Pages
83186
- - \`navigate_page\` — Go to a URL
83187
- - \`new_page\` / \`close_page\` / \`list_pages\` / \`select_page\` — Manage tabs
83189
+ A Chrome DevTools MCP server is connected (\`mcp__chrome_devtools__*\` tools).
83190
+ It drives a live Chrome instance for testing, debugging and performance
83191
+ analysis. Every page-scoped tool needs its \`pageId\`; use \`list_pages\` to
83192
+ see which pages exist.
83188
83193
 
83189
- ### Inspecting the Page
83190
- - \`take_snapshot\` Full ARIA accessibility tree (best for understanding page structure)
83191
- - \`take_screenshot\` Capture visual screenshot (element, viewport, or full page)
83192
- - \`evaluate_script\` Execute arbitrary JS in the page (e.g. \`document.title\`, \`window.scrollBy()\`)
83193
- - \`list_console_messages\` / \`get_console_message\` Read console logs and errors
83194
- - \`list_network_requests\` / \`get_network_request\` Inspect HTTP traffic
83194
+ ### Golden rules
83195
+ - \`take_snapshot\` (ARIA tree) before any interaction \`click\` / \`fill\` /
83196
+ \`hover\` target the \`uid\`s it returns.
83197
+ - **Snapshot uids go stale after navigation or major DOM changes.** Always
83198
+ \`take_snapshot\` again right before acting; reusing uids from the previous
83199
+ page is the most common failure.
83200
+ - Screenshots: pass \`filePath\` to save to disk, then read the file only if
83201
+ you must inspect it — inline images burn context. The server already
83202
+ downscales and compresses screenshots for you.
83203
+ - After a navigation, verify page health with \`list_console_messages\`
83204
+ (JS errors) and \`list_network_requests\` (failed loads).
83205
+ - Close pages you no longer need with \`close_page\`.
83195
83206
 
83196
- ### Interacting with the Page
83197
- - \`click\` / \`hover\` / \`press_key\` / \`type_text\` / \`fill\` / \`fill_form\` — Interact with elements
83198
- - \`drag\` — Drag and drop elements
83199
- - \`wait_for\` Wait for text/element to appear before acting
83200
- - \`upload_file\` — Attach local files to file inputs
83201
- - \`handle_dialog\` Accept or dismiss browser dialogs (alert/confirm/prompt)
83207
+ ### Task tool map
83208
+ - Open / manage pages: \`navigate_page\`, \`new_page\`, \`list_pages\`,
83209
+ \`select_page\`, \`close_page\`, \`resize_page\`
83210
+ - Read state: \`take_snapshot\`, \`evaluate_script\` (arbitrary in-page JS),
83211
+ \`take_screenshot\`, \`wait_for\`
83212
+ - Interact: \`click\`, \`fill\`, \`fill_form\` (batch prefer over many fills),
83213
+ \`type_text\`, \`press_key\`, \`hover\`, \`drag\`, \`upload_file\`,
83214
+ \`handle_dialog\`
83215
+ - Debug: \`list_console_messages\`, \`get_console_message\`,
83216
+ \`list_network_requests\`, \`get_network_request\`
83217
+ - Performance & memory: \`performance_start_trace\`, \`performance_stop_trace\`,
83218
+ \`performance_analyze_insight\`, \`lighthouse_audit\`, \`take_heapsnapshot\`,
83219
+ \`emulate\` (network/CPU throttling, dark mode, mobile viewports)
83202
83220
 
83203
- ### Performance & Debugging
83204
- - \`performance_start_trace\` / \`performance_stop_trace\` / \`performance_analyze_insight\` Record and analyze page load performance
83205
- - \`lighthouse_audit\` Run a full Lighthouse audit
83206
- - \`emulate\` Emulate device metrics, user agent, or CPU throttling
83221
+ ### Local dev preview workflow
83222
+ Use this whenever a local dev server backs a UI change (vite/next/webpack…):
83223
+ 1. Start the server in the background (e.g. \`pnpm dev\`) and note its port.
83224
+ 2. \`new_page\` \`navigate_page\` to \`http://localhost:<port>\`.
83225
+ 3. Verify health before eyeballing: \`list_console_messages\` (JS errors) +
83226
+ \`list_network_requests\` (404s / failed modules).
83227
+ 4. \`take_snapshot\` for structure, \`take_screenshot\` (with \`filePath\`) for
83228
+ visual acceptance of the changed part.
83229
+ 5. After further code edits, \`navigate_page\` type=\`reload\` and repeat
83230
+ steps 3-4; HMR usually applies without a reload.
83207
83231
 
83208
- ### Usage Pattern
83209
- 1. \`navigate_page\` to the target URL
83210
- 2. \`take_snapshot\` to understand the page structure and find element UIDs
83211
- 3. \`click\` / \`fill\` / \`type_text\` to interact using snapshot UIDs
83212
- 4. \`take_screenshot\` to verify the visual result
83213
- 5. \`list_console_messages\` to check for JS errors
83214
-
83215
- ### When to Use
83216
- - User asks to test a localhost app → navigate + screenshot + console check
83217
- - User asks to debug frontend issues → check console errors + network requests
83218
- - User asks to verify UI changes → screenshot before/after
83219
- - User asks to test a form flow → fill + click + wait_for + screenshot
83220
- - User asks to check page performance → performance_start_trace
83221
- - Do NOT use for simple HTTP data fetching — prefer FetchURL for that.
83222
-
83223
- ### Notes
83224
- - Use \`take_snapshot\` before interacting — it provides stable element UIDs for click/fill
83225
- - \`evaluate_script\` can do anything JS can (scroll, read DOM, trigger events)
83226
- - Close pages you no longer need with \`close_page\` to manage memory`;
83227
- const MCP_SERVER_NAME = "chrome-devtools";
83228
- var McpBrowserSkillInjector = class extends DynamicInjector {
83229
- injectionVariant = "mcp_browser_skill";
83230
- constructor(agent) {
83232
+ ### When to use
83233
+ - Test a localhost app → navigate + screenshot + console check
83234
+ - Debug frontend issues console errors + network requests
83235
+ - Verify a UI change screenshot before/after
83236
+ - Walk a form flow fill_form + click + wait_for + screenshot
83237
+ - Page performance questions performance_start_trace
83238
+ - Do NOT use for simple HTTP data fetching — prefer FetchURL.`
83239
+ }];
83240
+ var McpCapabilityGuideInjector = class extends DynamicInjector {
83241
+ guide;
83242
+ injectionVariant;
83243
+ constructor(agent, guide) {
83231
83244
  super(agent);
83245
+ this.guide = guide;
83246
+ this.injectionVariant = guide.variant;
83232
83247
  }
83233
83248
  getInjection() {
83234
83249
  if (this.injectedAt !== null) return void 0;
83235
83250
  const mcp = this.agent.mcp;
83236
83251
  if (!mcp) return void 0;
83237
- if (!mcp.list().some((e) => e.status === "connected" && e.name === MCP_SERVER_NAME)) return void 0;
83238
- return BROWSER_SKILL_GUIDANCE;
83252
+ if (!mcp.list().some((entry) => entry.status === "connected" && entry.capabilities.includes(this.guide.capability))) return void 0;
83253
+ return this.guide.text;
83239
83254
  }
83240
83255
  };
83256
+ /** One injector per registered capability guide. */
83257
+ function createMcpCapabilityGuideInjectors(agent) {
83258
+ return MCP_CAPABILITY_GUIDES.map((guide) => new McpCapabilityGuideInjector(agent, guide));
83259
+ }
83241
83260
  //#endregion
83242
83261
  //#region ../../packages/agent-core/src/agent/injection/permission-mode.ts
83243
83262
  const AUTO_MODE_ENTER_REMINDER = [
@@ -83811,7 +83830,7 @@ var InjectionManager = class {
83811
83830
  this.agent = agent;
83812
83831
  this.injectors = [
83813
83832
  new PluginSessionStartInjector(agent),
83814
- new McpBrowserSkillInjector(agent),
83833
+ ...createMcpCapabilityGuideInjectors(agent),
83815
83834
  new WolfPackModeInjector(agent),
83816
83835
  new PlanModeInjector(agent),
83817
83836
  new PermissionModeInjector(agent),
@@ -103343,6 +103362,58 @@ function isFileExistsError(error) {
103343
103362
  return typeof error === "object" && error !== null && error.code === "EEXIST";
103344
103363
  }
103345
103364
  //#endregion
103365
+ //#region ../../packages/agent-core/src/mcp/capabilities.ts
103366
+ function isStringArray(value) {
103367
+ return Array.isArray(value) && value.every((item) => typeof item === "string");
103368
+ }
103369
+ /** Normalize a declared list: string items only, trimmed, lowercased, deduped. */
103370
+ function normalizeCapabilityList(value) {
103371
+ const out = [];
103372
+ for (const item of value) {
103373
+ if (typeof item !== "string") continue;
103374
+ const normalized = item.trim().toLowerCase();
103375
+ if (normalized.length > 0 && !out.includes(normalized)) out.push(normalized);
103376
+ }
103377
+ return out;
103378
+ }
103379
+ /**
103380
+ * `args` lives only on the stdio branch of the discriminated union, and the
103381
+ * runtime addServer path may carry unvalidated payloads — read it defensively
103382
+ * so fingerprints never throw regardless of transport or shape.
103383
+ */
103384
+ function stringArgsOf(config) {
103385
+ const args = config.args;
103386
+ return isStringArray(args) ? args : void 0;
103387
+ }
103388
+ /**
103389
+ * Built-in fingerprint table. Keep entries cheap and conservative — a false
103390
+ * capability just shows a label / injects a guide; the user can always opt
103391
+ * out with an explicit `capabilities: []`.
103392
+ */
103393
+ const MCP_CAPABILITY_PATTERNS = [{
103394
+ capability: "browser",
103395
+ matches: (name, config) => name === "chrome-devtools" || stringArgsOf(config)?.some((arg) => arg.includes("chrome-devtools-mcp")) === true
103396
+ }, {
103397
+ capability: "memory",
103398
+ matches: (name, config) => name === "scream-life" || stringArgsOf(config)?.some((arg) => arg.includes("scream-life")) === true
103399
+ }];
103400
+ function fingerprintCapabilities(name, config) {
103401
+ const out = [];
103402
+ for (const pattern of MCP_CAPABILITY_PATTERNS) try {
103403
+ if (pattern.matches(name, config)) out.push(pattern.capability);
103404
+ } catch {}
103405
+ return out;
103406
+ }
103407
+ /**
103408
+ * Resolve the effective capabilities of one MCP server entry.
103409
+ * Never throws; returns `[]` for unknown servers.
103410
+ */
103411
+ function resolveServerCapabilities(name, config) {
103412
+ const raw = config.capabilities;
103413
+ if (Array.isArray(raw)) return normalizeCapabilityList(raw);
103414
+ return fingerprintCapabilities(name, config);
103415
+ }
103416
+ //#endregion
103346
103417
  //#region ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.4.3/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js
103347
103418
  function isZ4Schema(s) {
103348
103419
  return !!s._zod;
@@ -106823,7 +106894,8 @@ function toPublicEntry(entry) {
106823
106894
  transport: entry.config.transport,
106824
106895
  status: entry.status,
106825
106896
  toolCount: entry.status === "connected" && entry.enabledNames !== void 0 ? entry.enabledNames.size : 0,
106826
- error: entry.error
106897
+ error: entry.error,
106898
+ capabilities: resolveServerCapabilities(entry.name, entry.config)
106827
106899
  };
106828
106900
  }
106829
106901
  function computeEnabledNames(config, tools) {
@@ -107878,8 +107950,25 @@ var Session$1 = class {
107878
107950
  return this.writeMetadataPromise;
107879
107951
  }
107880
107952
  async readMetadata() {
107881
- const text = await this.options.jian.readText(this.metadataPath);
107882
- this.metadata = JSON.parse(text);
107953
+ let text;
107954
+ try {
107955
+ text = await this.options.jian.readText(this.metadataPath);
107956
+ } catch (error) {
107957
+ if (error.code === "ENOENT") return this.metadata;
107958
+ throw error;
107959
+ }
107960
+ try {
107961
+ this.metadata = JSON.parse(text);
107962
+ } catch {
107963
+ this.metadata = {
107964
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
107965
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
107966
+ title: "New Session",
107967
+ isCustomTitle: false,
107968
+ agents: {},
107969
+ custom: {}
107970
+ };
107971
+ }
107883
107972
  return this.metadata;
107884
107973
  }
107885
107974
  async flushMetadata() {
@@ -107978,7 +108067,8 @@ var Session$1 = class {
107978
108067
  transport: entry.transport,
107979
108068
  status: entry.status,
107980
108069
  toolCount: entry.toolCount,
107981
- error: entry.error
108070
+ error: entry.error,
108071
+ capabilities: entry.capabilities
107982
108072
  }
107983
108073
  }).catch(() => {});
107984
108074
  }
@@ -123523,6 +123613,18 @@ const SessionSummaryStateSchema = z.object({
123523
123613
  title: z.string().optional(),
123524
123614
  custom: z.record(z.string(), z.unknown()).optional()
123525
123615
  });
123616
+ let stateWriteCounter = 0;
123617
+ /**
123618
+ * Atomic state.json write: plain writeFile truncates the target before the
123619
+ * new bytes land, so a process killed mid-write leaves a 0-byte state.json
123620
+ * and the next resume crashes on JSON.parse. Temp-file + rename makes the
123621
+ * swap all-or-nothing.
123622
+ */
123623
+ async function writeStateAtomically(statePath, content) {
123624
+ const tmpPath = `${statePath}.${process.pid}.${Date.now().toString(36)}.${(stateWriteCounter++).toString(36)}.tmp`;
123625
+ await writeFile(tmpPath, content, "utf-8");
123626
+ await rename(tmpPath, statePath);
123627
+ }
123526
123628
  var SessionStore = class {
123527
123629
  homeDir;
123528
123630
  sessionsDir;
@@ -123612,7 +123714,7 @@ var SessionStore = class {
123612
123714
  title: normalized,
123613
123715
  isCustomTitle: true
123614
123716
  };
123615
- await writeFile(statePath, `${JSON.stringify(next, null, 2)}\n`, "utf-8");
123717
+ await writeStateAtomically(statePath, `${JSON.stringify(next, null, 2)}\n`);
123616
123718
  }
123617
123719
  async delete(id) {
123618
123720
  assertSafeSessionId(id);
@@ -123717,7 +123819,7 @@ var SessionStore = class {
123717
123819
  agents: rewriteAgentHomedirs(parsed["agents"], sourceDir, targetDir),
123718
123820
  custom: Object.assign({}, isRecord$1(parsed["custom"]) ? parsed["custom"] : {}, input.metadata)
123719
123821
  };
123720
- await writeFile(statePath, `${JSON.stringify(next, null, 2)}\n`, "utf-8");
123822
+ await writeStateAtomically(statePath, `${JSON.stringify(next, null, 2)}\n`);
123721
123823
  }
123722
123824
  async summaryFromDir(id, sessionDir, workDir) {
123723
123825
  const dirStat = await stat(sessionDir);
@@ -133494,7 +133596,7 @@ async function guidedGoalSetup(host) {
133494
133596
  host.showNotice(t("goal.storm_breaker"), t("goal.conflict_loop"));
133495
133597
  return;
133496
133598
  }
133497
- const { TextInputDialogComponent } = await import("./text-input-dialog-MAm2GHmm.mjs");
133599
+ const { TextInputDialogComponent } = await import("./text-input-dialog-2cG5VK1G.mjs");
133498
133600
  const initialDesc = await promptText(host, TextInputDialogComponent, {
133499
133601
  title: t("goal.setup_title_initial"),
133500
133602
  subtitle: t("goal.setup_desc_hint"),
@@ -133515,7 +133617,7 @@ async function guidedGoalSetup(host) {
133515
133617
  await showGoalConfigWizard(host, session, confirmed.trim() || objective, false);
133516
133618
  }
133517
133619
  async function showGoalConfigWizard(host, session, objective, replace) {
133518
- const { TextInputDialogComponent } = await import("./text-input-dialog-MAm2GHmm.mjs");
133620
+ const { TextInputDialogComponent } = await import("./text-input-dialog-2cG5VK1G.mjs");
133519
133621
  const turnInput = await promptNumber(host, TextInputDialogComponent, {
133520
133622
  title: t("goal.wizard_title", { objective }),
133521
133623
  subtitle: t("goal.budget_turns_hint"),
@@ -138823,8 +138925,15 @@ function getRecommended() {
138823
138925
  args: [
138824
138926
  "-y",
138825
138927
  "chrome-devtools-mcp@latest",
138826
- "--no-usage-statistics"
138827
- ]
138928
+ "--no-usage-statistics",
138929
+ "--no-performance-crux",
138930
+ "--screenshot-format=jpeg",
138931
+ "--screenshot-quality=85",
138932
+ "--screenshot-max-width=1600"
138933
+ ],
138934
+ env: { CHROME_DEVTOOLS_MCP_NO_UPDATE_CHECKS: "1" },
138935
+ startupTimeoutMs: 18e4,
138936
+ capabilities: ["browser"]
138828
138937
  }, {
138829
138938
  name: "scream-life",
138830
138939
  displayName: "ScreamLife",
@@ -138832,7 +138941,8 @@ function getRecommended() {
138832
138941
  command: "bun",
138833
138942
  args: ["{INSTALL_DIR}/Core/mcp-server.ts"],
138834
138943
  env: { SCREAM_LIFE_DB_PATH: "{INSTALL_DIR}/Data/scream-life.db" },
138835
- gitUrl: "https://github.com/LIUTod/scream-life.git"
138944
+ gitUrl: "https://github.com/LIUTod/scream-life.git",
138945
+ capabilities: ["memory"]
138836
138946
  }];
138837
138947
  }
138838
138948
  function getStatusLabels() {
@@ -138844,6 +138954,12 @@ function getStatusLabels() {
138844
138954
  "needs-auth": t("mcp.auth_required")
138845
138955
  };
138846
138956
  }
138957
+ function getCapabilityLabels() {
138958
+ return {
138959
+ browser: t("mcp.capability_browser"),
138960
+ memory: t("mcp.capability_memory")
138961
+ };
138962
+ }
138847
138963
  async function handleMcpCommand(host, _args) {
138848
138964
  if (!host.session) {
138849
138965
  host.showError(t("mcp.no_session"));
@@ -138914,6 +139030,8 @@ function buildRows(servers) {
138914
139030
  for (const s of servers) {
138915
139031
  const statusLabel = getStatusLabels()[s.status] ?? s.status;
138916
139032
  const toolInfo = s.status === "connected" ? `${s.toolCount} tools` : "";
139033
+ const capLabels = getCapabilityLabels();
139034
+ const capInfo = (s.capabilities ?? []).map((c) => capLabels[c] ?? c).join(" ");
138917
139035
  const errorInfo = s.error ? ` — ${sanitizeDesc(s.error)}` : "";
138918
139036
  rows.push({
138919
139037
  kind: "installed",
@@ -138925,6 +139043,7 @@ function buildRows(servers) {
138925
139043
  description: [
138926
139044
  statusLabel,
138927
139045
  toolInfo,
139046
+ capInfo,
138928
139047
  errorInfo
138929
139048
  ].filter(Boolean).join(" ")
138930
139049
  });
@@ -139030,12 +139149,21 @@ async function installMcp(host, rec) {
139030
139149
  resolvedArgs = rec.args.map((a) => a.replaceAll("{INSTALL_DIR}", installDir));
139031
139150
  if (resolvedEnv !== void 0) resolvedEnv = Object.fromEntries(Object.entries(resolvedEnv).map(([k, v]) => [k, v.replaceAll("{INSTALL_DIR}", installDir)]));
139032
139151
  }
139033
- await writeMcpConfig(host, rec.name, rec.command, resolvedArgs, resolvedEnv);
139152
+ await writeMcpConfig(host, {
139153
+ name: rec.name,
139154
+ command: rec.command,
139155
+ args: resolvedArgs,
139156
+ env: resolvedEnv,
139157
+ startupTimeoutMs: rec.startupTimeoutMs,
139158
+ capabilities: rec.capabilities
139159
+ });
139034
139160
  const serverConfig = {
139035
139161
  transport: "stdio",
139036
139162
  command: rec.command,
139037
139163
  args: resolvedArgs
139038
139164
  };
139165
+ if (rec.startupTimeoutMs !== void 0) serverConfig.startupTimeoutMs = rec.startupTimeoutMs;
139166
+ if (rec.capabilities !== void 0) serverConfig.capabilities = rec.capabilities;
139039
139167
  if (resolvedEnv !== void 0 && Object.keys(resolvedEnv).length > 0) serverConfig.env = resolvedEnv;
139040
139168
  await session.addMcpServer(rec.name, serverConfig);
139041
139169
  spinner.stop({
@@ -139083,7 +139211,7 @@ async function uninstallMcp(host, name) {
139083
139211
  host.showError(t("mcp.uninstall_failed", { msg: error instanceof Error ? error.message : String(error) }));
139084
139212
  }
139085
139213
  }
139086
- async function writeMcpConfig(host, name, command, args, env) {
139214
+ async function writeMcpConfig(host, entry) {
139087
139215
  const configPath = join(getDataDir(), "mcp.json");
139088
139216
  let data = {};
139089
139217
  try {
@@ -139093,12 +139221,13 @@ async function writeMcpConfig(host, name, command, args, env) {
139093
139221
  const servers = data["mcpServers"] ?? {};
139094
139222
  const config = {
139095
139223
  transport: "stdio",
139096
- command,
139097
- args,
139098
- startupTimeoutMs: 3e5
139224
+ command: entry.command,
139225
+ args: entry.args
139099
139226
  };
139100
- if (env !== void 0 && Object.keys(env).length > 0) config["env"] = env;
139101
- servers[name] = config;
139227
+ if (entry.startupTimeoutMs !== void 0) config["startupTimeoutMs"] = entry.startupTimeoutMs;
139228
+ if (entry.capabilities !== void 0) config["capabilities"] = entry.capabilities;
139229
+ if (entry.env !== void 0 && Object.keys(entry.env).length > 0) config["env"] = entry.env;
139230
+ servers[entry.name] = config;
139102
139231
  data["mcpServers"] = servers;
139103
139232
  await mkdir(dirname$1(configPath), { recursive: true });
139104
139233
  await writeFile(configPath, JSON.stringify(data, null, 2), "utf-8");
@@ -140614,6 +140743,8 @@ function openUrl(url) {
140614
140743
  */
140615
140744
  const activeServers = /* @__PURE__ */ new Set();
140616
140745
  const activeTimers = /* @__PURE__ */ new Set();
140746
+ /** Idle watchdog: closes all graph servers when no viewer kept them alive. */
140747
+ let idleTimer = null;
140617
140748
  function registerServer(server) {
140618
140749
  activeServers.add(server);
140619
140750
  server.on("close", () => {
@@ -140621,6 +140752,10 @@ function registerServer(server) {
140621
140752
  });
140622
140753
  }
140623
140754
  function closeAllServers() {
140755
+ if (idleTimer !== null) {
140756
+ clearTimeout(idleTimer);
140757
+ idleTimer = null;
140758
+ }
140624
140759
  for (const timer of activeTimers) clearInterval(timer);
140625
140760
  activeTimers.clear();
140626
140761
  for (const server of activeServers) server.close();
@@ -141824,6 +141959,7 @@ async function handleWeb(host) {
141824
141959
  const store = await getKnowledgeStore();
141825
141960
  const s = await store.stats();
141826
141961
  if (s.entities === 0 && s.events === 0) throw new Error(t("knowledge.empty_store"));
141962
+ closeAllServers();
141827
141963
  const server = createServer((req, res) => {
141828
141964
  if (req.url === "/api/graph") {
141829
141965
  serveGraphJSON(store, res);
@@ -141858,6 +141994,10 @@ async function handleWeb(host) {
141858
141994
  });
141859
141995
  });
141860
141996
  const url = `http://127.0.0.1:${server.address().port}`;
141997
+ idleTimer = setTimeout(() => {
141998
+ closeAllServers();
141999
+ }, 10 * 6e4);
142000
+ idleTimer.unref();
141861
142001
  openUrl(url);
141862
142002
  host.showStatus(t("knowledge.web_opened", { url }));
141863
142003
  }
@@ -143228,6 +143368,14 @@ async function executeSlashCommand(host, input) {
143228
143368
  host.showError(formatErrorMessage(error));
143229
143369
  }
143230
143370
  return;
143371
+ case "invalid":
143372
+ host.showError(`Invalid command: /${intent.commandName}`);
143373
+ return;
143374
+ default: {
143375
+ const unhandled = intent;
143376
+ host.showError(`Unhandled slash-command intent: ${String(unhandled)}`);
143377
+ return;
143378
+ }
143231
143379
  }
143232
143380
  }
143233
143381
  async function handleBuiltInSlashCommand(host, name, args) {
@@ -143399,4 +143547,4 @@ async function handleBuiltInSlashCommand(host, name, args) {
143399
143547
  }
143400
143548
  }
143401
143549
  //#endregion
143402
- export { handleTitleCommand as $, argsRecord as $t, renderDiffLinesClustered as A, detectShellEnvironment as An, DISABLE_TERMINAL_THEME_REPORTING as At, BackgroundAgentStatusComponent as B, fetchCatalog as Bn, TERMINAL_THEME_DARK as Bt, handleRevokeCommand as C, startManualEmbeddingDownload as Cn, createMarkdownTheme as Ct, toggleEmptySessionHint as D, TuiLikePreferencesSchema as Dn, detectTerminalTheme as Dt, isTurnElapsedEnabled as E, TuiConfigParseError as En, getColorPalette as Et, estimateTokens as F, CLI_COMMAND_NAME as Fn, OSC11_RESPONSE_PREFIX as Ft, getBreathingFrame as G, MemoryMemoStore as Gn, lerpGradient as Gt, AgentGroupComponent as H, ScreamHarness as Hn, isBusy as Ht, getSharedSpeedTracker as I, CLI_UI_MODE as In, OSC11_RESPONSE_PREFIX_NO_ESC as It, refineGoal as J, resolveGlobalLogPath as Jn, handleConnectCommand as Jt, resetBreathingClock as K, flushDiagnosticLogs as Kn, handleTraceCommand as Kt, SkillActivationComponent as L, CLI_USER_AGENT_PRODUCT as Ln, QUERY_TERMINAL_THEME as Lt, langFromPath as M, getInputHistoryFile as Mn, ENABLE_TERMINAL_THEME_REPORTING as Mt, CachedContainer as N, getLogDir as Nn, OSC11_QUERY as Nt, ToolCallComponent as O, loadTuiConfig as On, parseOsc11BackgroundTheme as Ot, ThinkingComponent as P, detectInstallSource as Pn, OSC11_RESPONSE as Pt, handleInitCommand as Q, SCREAM_ERROR_INFO as Qn, appendStreamingArgsPreview as Qt, ReadGroupComponent as R, PRODUCT_NAME as Rn, TERMINAL_FOCUS_IN as Rt, getDaemonInstructions as S, isEmbeddingModelCached as Sn, createEditorTheme as St, isEmptySessionHintDismissed as T, PULSE_WAVE_FRAMES as Tn, contrastTextHex as Tt, WelcomeComponent as U, MCP_OAUTH_AUTHORIZATION_URL_TOOL_UPDATE as Un, isStreaming as Ut, AssistantMessageComponent as V, saveCatalogCache as Vn, TERMINAL_THEME_LIGHT as Vt, BREATHE_CYCLE_MS as W, resolveScreamHome as Wn, FooterComponent as Wt, handleExportMdCommand as X, isOrphanedToolCallError as Xn, printableChar as Xt, handleExportDebugZipCommand as Y, isScreamError as Yn, handleLogoutCommand as Yt, handleForkCommand as Z, ErrorCodes as Zn, STATUS_BULLET as Zt, refreshUpdateCache as _, BUILTIN_SLASH_COMMANDS as _n, supportsBalance as _t, handleExtensionCommand as a, truncateErrorMessage as an, handleCompactCommand as at, readJsonlFile as b, setExperimentalFlags as bn, showUsage as bt, hasDispose as c, EXIT_CONFIRM_WINDOW_MS as cn, handleModelCommand as ct, formatMemoryMemoForInjection as d, TIP_ROTATION_INTERVAL_MS as dn, handleWolfpackCommand as dt, formatErrorMessage as en, toTerminalHyperlink as et, handleMemoryCommand as f, getCtrlCHint as fn, handleYoloCommand as ft, selectUpdateTarget as g, buildSkillSlashCommands as gn, refreshProviderBalance as gt, handleUpdateCommand as h, getNoActiveSessionMessage as hn, showSettingsSelector as ht, buildRoleAdditionalText as i, stringValue as in, handleBotCommand as it, highlightLines as j, getDataDir as jn, ENABLE_TERMINAL_FOCUS_REPORTING as jt, renderDiffLines as k, saveTuiConfig as kn, DISABLE_TERMINAL_FOCUS_REPORTING as kt, isPlanExpandable as l, MAIN_AGENT_ID$1 as ln, handlePlanCommand as lt, handleMcpCommand as m, getLlmNotSetMessage as mn, showPermissionPicker as mt, clearEvalPanelState as n, parseStreamingArgs as nn, getModelCycleLevel as nt, handleSkillCommand as o, CHARS_PER_TOKEN as on, handleEditorCommand as ot, handleChannelCommand as p, getCtrlDHint as pn, showModelPicker as pt, clearGoalState as q, log as qn, handleSearchCommand as qt, openUrl as r, serializeToolResultOutput as rn, handleAutoCommand as rt, disposeChildren as s, EMPTY_SESSION_HINT_URL as sn, handleFusionPlanCommand as st, dispatchInput as t, isTodoItemShape as tn, changeThinkingLevel as tt, MoonLoader as u, SESSION_TIPS as un, handleThemeCommand as ut, readUpdateCache as v, sortSlashCommands as vn, clearInfoPanelState as vt, UserMessageComponent as w, PIXEL_PULSE_FRAMES as wn, createThemeStyles as wt, handleCcCommand as x, getKnowledgeStore as xn, resolveThemeSync as xt, appendJsonlLine as y, isExperimentalFlagEnabled as yn, showStatusReport as yt, parseReadGroupOutput as z, DEFAULT_CATALOG_URL as zn, TERMINAL_FOCUS_OUT as zt };
143550
+ export { handleTitleCommand as $, ErrorCodes as $n, argsRecord as $t, renderDiffLinesClustered as A, detectShellEnvironment as An, DISABLE_TERMINAL_THEME_REPORTING as At, BackgroundAgentStatusComponent as B, fetchCatalog as Bn, TERMINAL_THEME_DARK as Bt, handleRevokeCommand as C, startManualEmbeddingDownload as Cn, createMarkdownTheme as Ct, toggleEmptySessionHint as D, TuiLikePreferencesSchema as Dn, detectTerminalTheme as Dt, isTurnElapsedEnabled as E, TuiConfigParseError as En, getColorPalette as Et, estimateTokens as F, CLI_COMMAND_NAME as Fn, OSC11_RESPONSE_PREFIX as Ft, getBreathingFrame as G, MCP_OAUTH_AUTHORIZATION_URL_TOOL_UPDATE as Gn, lerpGradient as Gt, AgentGroupComponent as H, ScreamHarness as Hn, isBusy as Ht, getSharedSpeedTracker as I, CLI_UI_MODE as In, OSC11_RESPONSE_PREFIX_NO_ESC as It, refineGoal as J, flushDiagnosticLogs as Jn, handleConnectCommand as Jt, resetBreathingClock as K, resolveScreamHome as Kn, handleTraceCommand as Kt, SkillActivationComponent as L, CLI_USER_AGENT_PRODUCT as Ln, QUERY_TERMINAL_THEME as Lt, langFromPath as M, getInputHistoryFile as Mn, ENABLE_TERMINAL_THEME_REPORTING as Mt, CachedContainer as N, getLogDir as Nn, OSC11_QUERY as Nt, ToolCallComponent as O, loadTuiConfig as On, parseOsc11BackgroundTheme as Ot, ThinkingComponent as P, detectInstallSource as Pn, OSC11_RESPONSE as Pt, handleInitCommand as Q, isOrphanedToolCallError as Qn, appendStreamingArgsPreview as Qt, ReadGroupComponent as R, PRODUCT_NAME as Rn, TERMINAL_FOCUS_IN as Rt, getDaemonInstructions as S, isEmbeddingModelCached as Sn, createEditorTheme as St, isEmptySessionHintDismissed as T, PULSE_WAVE_FRAMES as Tn, contrastTextHex as Tt, WelcomeComponent as U, encodeWorkDirKey as Un, isStreaming as Ut, AssistantMessageComponent as V, saveCatalogCache as Vn, TERMINAL_THEME_LIGHT as Vt, BREATHE_CYCLE_MS as W, appendSessionIndexEntry as Wn, FooterComponent as Wt, handleExportMdCommand as X, resolveGlobalLogPath as Xn, printableChar as Xt, handleExportDebugZipCommand as Y, log as Yn, handleLogoutCommand as Yt, handleForkCommand as Z, isScreamError as Zn, STATUS_BULLET as Zt, refreshUpdateCache as _, BUILTIN_SLASH_COMMANDS as _n, supportsBalance as _t, handleExtensionCommand as a, truncateErrorMessage as an, handleCompactCommand as at, readJsonlFile as b, setExperimentalFlags as bn, showUsage as bt, hasDispose as c, EXIT_CONFIRM_WINDOW_MS as cn, handleModelCommand as ct, formatMemoryMemoForInjection as d, TIP_ROTATION_INTERVAL_MS as dn, handleWolfpackCommand as dt, formatErrorMessage as en, SCREAM_ERROR_INFO as er, toTerminalHyperlink as et, handleMemoryCommand as f, getCtrlCHint as fn, handleYoloCommand as ft, selectUpdateTarget as g, buildSkillSlashCommands as gn, refreshProviderBalance as gt, handleUpdateCommand as h, getNoActiveSessionMessage as hn, showSettingsSelector as ht, buildRoleAdditionalText as i, stringValue as in, handleBotCommand as it, highlightLines as j, getDataDir as jn, ENABLE_TERMINAL_FOCUS_REPORTING as jt, renderDiffLines as k, saveTuiConfig as kn, DISABLE_TERMINAL_FOCUS_REPORTING as kt, isPlanExpandable as l, MAIN_AGENT_ID$1 as ln, handlePlanCommand as lt, handleMcpCommand as m, getLlmNotSetMessage as mn, showPermissionPicker as mt, clearEvalPanelState as n, parseStreamingArgs as nn, getModelCycleLevel as nt, handleSkillCommand as o, CHARS_PER_TOKEN as on, handleEditorCommand as ot, handleChannelCommand as p, getCtrlDHint as pn, showModelPicker as pt, clearGoalState as q, MemoryMemoStore as qn, handleSearchCommand as qt, openUrl as r, serializeToolResultOutput as rn, handleAutoCommand as rt, disposeChildren as s, EMPTY_SESSION_HINT_URL as sn, handleFusionPlanCommand as st, dispatchInput as t, isTodoItemShape as tn, changeThinkingLevel as tt, MoonLoader as u, SESSION_TIPS as un, handleThemeCommand as ut, readUpdateCache as v, sortSlashCommands as vn, clearInfoPanelState as vt, UserMessageComponent as w, PIXEL_PULSE_FRAMES as wn, createThemeStyles as wt, handleCcCommand as x, getKnowledgeStore as xn, resolveThemeSync as xt, appendJsonlLine as y, isExperimentalFlagEnabled as yn, showStatusReport as yt, parseReadGroupOutput as z, DEFAULT_CATALOG_URL as zn, TERMINAL_FOCUS_OUT as zt };
package/dist/main.mjs CHANGED
@@ -6,7 +6,7 @@ const __dirname = __cjsShimDirname(__filename);
6
6
  import "./suppress-sqlite-warning-C2VB0doZ.mjs";
7
7
  //#region src/main.ts
8
8
  try {
9
- (await import("./app-BWXezRMl.mjs")).main();
9
+ (await import("./app-DQdNroOu.mjs")).main();
10
10
  } catch (error) {
11
11
  process.stderr.write(`${error instanceof Error ? error.stack ?? error.message : String(error)}\n`);
12
12
  process.exit(1);