grain-tools 0.10.12 → 0.10.14

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.
@@ -206,11 +206,12 @@ function classifyRecordInstance(record2, status, nowMs) {
206
206
  const processStartedAt = nowMs - status.uptime * 1e3;
207
207
  return Math.abs(publishedAt - processStartedAt) <= RECORD_INSTANCE_START_SKEW_MS ? "match" : "mismatch";
208
208
  }
209
- var DAEMON_SERVICE_IDENTITY, DAEMON_SERVICE_IDENTITY_IPC, DAEMON_SERVICE_IDENTITY_STDIO, MCP_SERVICE_IDENTITY, RECORD_INSTANCE_START_SKEW_MS;
209
+ var DAEMON_SERVICE_IDENTITY, GRAIN_SERVICE_LABEL, DAEMON_SERVICE_IDENTITY_IPC, DAEMON_SERVICE_IDENTITY_STDIO, MCP_SERVICE_IDENTITY, RECORD_INSTANCE_START_SKEW_MS;
210
210
  var init_daemonRecordInstance = __esm({
211
211
  "src/common/daemonRecordInstance.ts"() {
212
212
  "use strict";
213
213
  DAEMON_SERVICE_IDENTITY = "grain-daemon";
214
+ GRAIN_SERVICE_LABEL = `tools.${DAEMON_SERVICE_IDENTITY}`;
214
215
  DAEMON_SERVICE_IDENTITY_IPC = `${DAEMON_SERVICE_IDENTITY}-ipc`;
215
216
  DAEMON_SERVICE_IDENTITY_STDIO = `${DAEMON_SERVICE_IDENTITY}-stdio`;
216
217
  MCP_SERVICE_IDENTITY = "grain-mcp";
@@ -19277,13 +19278,40 @@ var init_StdioBridge = __esm({
19277
19278
  }
19278
19279
  }
19279
19280
  async forwardAgentMessage(message, fatal) {
19281
+ const isInitialize = "method" in message && message.method === "initialize";
19282
+ if (!this.initializeRequest && !isInitialize) {
19283
+ if ("method" in message && "id" in message) {
19284
+ await this.options.agentTransport.send({
19285
+ jsonrpc: "2.0",
19286
+ id: message.id,
19287
+ error: {
19288
+ code: -32601,
19289
+ message: `Method not found: ${message.method}. This server speaks MCP 2025-11-25; open a session with initialize.`
19290
+ }
19291
+ }).catch(() => void 0);
19292
+ }
19293
+ return;
19294
+ }
19295
+ const isHandshake = isInitialize || "method" in message && message.method === "notifications/initialized";
19296
+ if (!isInitialize && this.sessionOpening) {
19297
+ await this.sessionOpening;
19298
+ }
19280
19299
  if (this.reconnecting) {
19281
- this.queuedAgentMessages.push(message);
19300
+ if (!isHandshake) {
19301
+ this.queuedAgentMessages.push(message);
19302
+ }
19282
19303
  return;
19283
19304
  }
19305
+ const sending = this.daemonTransport.send(message);
19306
+ if (isInitialize) {
19307
+ this.sessionOpening = sending.catch(() => void 0);
19308
+ }
19284
19309
  try {
19285
- await this.daemonTransport.send(message);
19310
+ await sending;
19286
19311
  } catch {
19312
+ if (!isHandshake) {
19313
+ this.queuedAgentMessages.push(message);
19314
+ }
19287
19315
  void this.reconnect(fatal);
19288
19316
  }
19289
19317
  }
@@ -19462,6 +19490,48 @@ var init_DaemonAuthToken = __esm({
19462
19490
  }
19463
19491
  });
19464
19492
 
19493
+ // src/common/serviceMode.ts
19494
+ function serviceModePath(configDir) {
19495
+ return path7.join(configDir, SERVICE_MODE_FILENAME);
19496
+ }
19497
+ function writeServiceMode(fileSystem, configDir, record2) {
19498
+ fileSystem.writeFileSync(serviceModePath(configDir), `${JSON.stringify(record2, null, 2)}
19499
+ `, {
19500
+ mode: 384
19501
+ });
19502
+ }
19503
+ function readServiceModeStatus(configDir) {
19504
+ let raw;
19505
+ try {
19506
+ raw = fs5.readFileSync(serviceModePath(configDir), "utf8");
19507
+ } catch {
19508
+ return { type: "missing" };
19509
+ }
19510
+ let parsed;
19511
+ try {
19512
+ parsed = JSON.parse(raw);
19513
+ } catch {
19514
+ return { type: "unparseable" };
19515
+ }
19516
+ if (typeof parsed !== "object" || parsed === null) {
19517
+ return { type: "malformed" };
19518
+ }
19519
+ const r = parsed;
19520
+ if (r["mode"] !== "spawn-on-demand") {
19521
+ return { type: "malformed" };
19522
+ }
19523
+ return { type: "valid", record: r };
19524
+ }
19525
+ var fs5, path7, SERVICE_MODE_FILENAME;
19526
+ var init_serviceMode = __esm({
19527
+ "src/common/serviceMode.ts"() {
19528
+ "use strict";
19529
+ fs5 = __toESM(require("fs"));
19530
+ path7 = __toESM(require("path"));
19531
+ SERVICE_MODE_FILENAME = "service-mode.json";
19532
+ }
19533
+ });
19534
+
19465
19535
  // src/common/localUrl.ts
19466
19536
  function formatUserFacingLocalUrl(host, port) {
19467
19537
  const displayHost = host === "127.0.0.1" || host === "::1" ? "localhost" : host;
@@ -19481,7 +19551,7 @@ async function readGrainServiceStatus(configDir = resolveGrainHome()) {
19481
19551
  let reason = "";
19482
19552
  switch (endpoint.type) {
19483
19553
  case "missing":
19484
- reason = GRAIN_NOT_INSTALLED_MESSAGE;
19554
+ reason = readServiceModeStatus(configDir).type === "valid" ? GRAIN_STARTS_ON_DEMAND_MESSAGE : GRAIN_NOT_INSTALLED_MESSAGE;
19485
19555
  break;
19486
19556
  case "unparseable":
19487
19557
  reason = "Grain's note of where it is listening is damaged, so it cannot be reached. Run `grain install` to rewrite it.";
@@ -19541,15 +19611,17 @@ async function statusCommand() {
19541
19611
  console.log(JSON.stringify(await readGrainServiceStatus(), null, 2));
19542
19612
  return 0;
19543
19613
  }
19544
- var http2;
19614
+ var http2, GRAIN_STARTS_ON_DEMAND_MESSAGE;
19545
19615
  var init_statusCommand = __esm({
19546
19616
  "src/server/cli/statusCommand.ts"() {
19547
19617
  "use strict";
19548
19618
  http2 = __toESM(require("http"));
19549
19619
  init_daemonEndpointFile();
19550
19620
  init_grainHome();
19621
+ init_serviceMode();
19551
19622
  init_daemonRecordInstance();
19552
19623
  init_localUrl();
19624
+ GRAIN_STARTS_ON_DEMAND_MESSAGE = "Grain is set up to start when needed on this machine and is not running right now. Run `grain start` to start it.";
19553
19625
  }
19554
19626
  });
19555
19627
 
@@ -19576,6 +19648,206 @@ var init_firstValueStep = __esm({
19576
19648
  }
19577
19649
  });
19578
19650
 
19651
+ // src/common/toolProfiles.ts
19652
+ function toolRuleFor(profile, tool) {
19653
+ return profile.policy?.rules?.[TOOL_RESOURCE_CLASS[tool]] ?? "allow";
19654
+ }
19655
+ function toolRefusalMessage(profile, tool) {
19656
+ return `Tool '${tool}' is not permitted for the '${profile.name}' profile: its resource class '${TOOL_RESOURCE_CLASS[tool]}' is refused by policy. The tool exists and is advertised; this call was declined, not lost.`;
19657
+ }
19658
+ function toolRefusalResult(profile, tool) {
19659
+ return {
19660
+ isError: true,
19661
+ content: [{ type: "text", text: toolRefusalMessage(profile, tool) }],
19662
+ structuredContent: { errorKind: "permission", errorId: "tool_not_permitted_for_profile" }
19663
+ };
19664
+ }
19665
+ function refuseIfNotPermitted(profile, tool) {
19666
+ const name = tool;
19667
+ if (TOOL_RESOURCE_CLASS[name] === void 0)
19668
+ return void 0;
19669
+ if (toolRuleFor(profile, name) === "allow")
19670
+ return void 0;
19671
+ return toolRefusalResult(profile, name);
19672
+ }
19673
+ function isToolProfileName(value) {
19674
+ return value === "vscode" || value === "headless" || value === "readonly" || value === "agent";
19675
+ }
19676
+ function operatorProfileOverride(onUnknownEnvValue) {
19677
+ const fromEnv = process.env["MCP_PROFILE"];
19678
+ if (fromEnv === void 0)
19679
+ return void 0;
19680
+ if (isToolProfileName(fromEnv))
19681
+ return TOOL_PROFILES[fromEnv];
19682
+ onUnknownEnvValue?.(fromEnv);
19683
+ return void 0;
19684
+ }
19685
+ function resolveToolProfile(explicit, onUnknownEnvValue) {
19686
+ if (explicit) {
19687
+ return TOOL_PROFILES[explicit];
19688
+ }
19689
+ const fromEnv = process.env["MCP_PROFILE"];
19690
+ if (fromEnv !== void 0) {
19691
+ if (isToolProfileName(fromEnv)) {
19692
+ return TOOL_PROFILES[fromEnv];
19693
+ }
19694
+ onUnknownEnvValue?.(fromEnv);
19695
+ }
19696
+ return TOOL_PROFILES.vscode;
19697
+ }
19698
+ function isSafeModeActive(profile, liveSafeMode) {
19699
+ return profile.forceSafeMode || liveSafeMode;
19700
+ }
19701
+ function toolNamesForProfile(profile) {
19702
+ const cached2 = toolNameSets.get(profile);
19703
+ if (cached2)
19704
+ return cached2;
19705
+ const names = new Set(profile.tools);
19706
+ toolNameSets.set(profile, names);
19707
+ return names;
19708
+ }
19709
+ function composeToolProfiles(...profiles) {
19710
+ const present = profiles.filter((p) => p !== void 0);
19711
+ if (present.length === 0)
19712
+ return TOOL_PROFILES.vscode;
19713
+ if (present.length === 1)
19714
+ return present[0];
19715
+ const sets = present.map((p) => new Set(p.tools));
19716
+ const rules = {};
19717
+ for (const p of present) {
19718
+ for (const [cls, rule] of Object.entries(p.policy?.rules ?? {})) {
19719
+ if (rule === "refuse")
19720
+ rules[cls] = "refuse";
19721
+ }
19722
+ }
19723
+ const refusalCount = (p) => Object.keys(p.policy?.rules ?? {}).length;
19724
+ const narrowest = present.reduce((a, b) => {
19725
+ if (b.tools.length !== a.tools.length)
19726
+ return b.tools.length < a.tools.length ? b : a;
19727
+ return refusalCount(b) > refusalCount(a) ? b : a;
19728
+ });
19729
+ return {
19730
+ name: narrowest.name,
19731
+ tools: ALL_TOOLS.filter((tool) => sets.every((s) => s.has(tool))),
19732
+ forceSafeMode: present.some((p) => p.forceSafeMode),
19733
+ ...Object.keys(rules).length > 0 ? { policy: { rules } } : {}
19734
+ };
19735
+ }
19736
+ function createToolProfileResolver(explicit, onUnknownEnvValue) {
19737
+ const defaultProfile = resolveToolProfile(explicit, onUnknownEnvValue);
19738
+ const pinned = explicit === void 0 ? void 0 : TOOL_PROFILES[explicit];
19739
+ const fromEnv = operatorProfileOverride(onUnknownEnvValue);
19740
+ return {
19741
+ defaultProfile,
19742
+ forCall(profile) {
19743
+ const declared = profile === void 0 ? void 0 : TOOL_PROFILES[profile];
19744
+ if (pinned === void 0 && fromEnv === void 0 && declared === void 0) {
19745
+ return defaultProfile;
19746
+ }
19747
+ return composeToolProfiles(pinned, fromEnv, declared);
19748
+ }
19749
+ };
19750
+ }
19751
+ var ALL_TOOLS, READ_ONLY_TOOLS, TOOL_RESOURCE_CLASS, TOOL_PROFILES, WEB_PROXIED_TOOLS, toolNameSets;
19752
+ var init_toolProfiles = __esm({
19753
+ "src/common/toolProfiles.ts"() {
19754
+ "use strict";
19755
+ ALL_TOOLS = [
19756
+ "list_connectors",
19757
+ "run_query",
19758
+ "get_tab_info",
19759
+ "list_sessions",
19760
+ "list_connections",
19761
+ "save_connection",
19762
+ "request_connection_credentials",
19763
+ "test_connection",
19764
+ "delete_connection",
19765
+ "list_schemas",
19766
+ "list_tables",
19767
+ "describe_table",
19768
+ "cancel_query",
19769
+ "close_tab",
19770
+ "render_chart",
19771
+ "save_chart",
19772
+ "list_charts",
19773
+ "ledger_stats",
19774
+ "verify_ledger",
19775
+ "record_ui_event"
19776
+ ];
19777
+ READ_ONLY_TOOLS = [
19778
+ "list_connectors",
19779
+ "run_query",
19780
+ "get_tab_info",
19781
+ "list_sessions",
19782
+ "list_connections",
19783
+ "test_connection",
19784
+ "list_schemas",
19785
+ "list_tables",
19786
+ "describe_table",
19787
+ "cancel_query",
19788
+ "close_tab",
19789
+ "render_chart",
19790
+ "list_charts",
19791
+ "ledger_stats",
19792
+ "verify_ledger",
19793
+ "record_ui_event"
19794
+ ];
19795
+ TOOL_RESOURCE_CLASS = {
19796
+ list_connectors: "read",
19797
+ list_connections: "read",
19798
+ list_sessions: "read",
19799
+ get_tab_info: "read",
19800
+ list_schemas: "read",
19801
+ list_tables: "read",
19802
+ describe_table: "read",
19803
+ list_charts: "read",
19804
+ ledger_stats: "read",
19805
+ verify_ledger: "read",
19806
+ test_connection: "read",
19807
+ cancel_query: "session",
19808
+ close_tab: "session",
19809
+ render_chart: "session",
19810
+ run_query: "query",
19811
+ save_connection: "connection-config",
19812
+ delete_connection: "connection-config",
19813
+ request_connection_credentials: "credential",
19814
+ save_chart: "workspace-write",
19815
+ record_ui_event: "app-telemetry"
19816
+ };
19817
+ TOOL_PROFILES = {
19818
+ // Human-in-the-loop VS Code surface: full toolset, safe mode from settings.
19819
+ vscode: { name: "vscode", tools: ALL_TOOLS, forceSafeMode: false },
19820
+ // Autonomous agents: starts as the full current toolset (RFC-062); will
19821
+ // diverge toward synchronous/structured tools without breaking clients.
19822
+ headless: { name: "headless", tools: ALL_TOOLS, forceSafeMode: false },
19823
+ // Safe exploration: no profile/credential mutation, SQL gating always on.
19824
+ readonly: { name: "readonly", tools: READ_ONLY_TOOLS, forceSafeMode: true },
19825
+ // RFC-134: intended as the default for an attached AI agent surface — may read,
19826
+ // query and chart, may not change saved connections or ask for stored credentials.
19827
+ // This profile is assigned to the local agent identity and enforced on the stdio bridge.
19828
+ // End-to-end enforcement is proven by the 'bridged client (agent profile) is permitted
19829
+ // read tools but refused config/credential tools' test in stdio_bridge.test.ts.
19830
+ // SQL restriction is deliberately not forced here: `grain.mcpSafeMode`
19831
+ // already defaults to on, and a ceiling would make that setting silently stop
19832
+ // working for the recommended agent path.
19833
+ agent: {
19834
+ name: "agent",
19835
+ tools: ALL_TOOLS,
19836
+ forceSafeMode: false,
19837
+ policy: { rules: { "connection-config": "refuse", credential: "refuse" } }
19838
+ }
19839
+ };
19840
+ WEB_PROXIED_TOOLS = [
19841
+ "list_connectors",
19842
+ "list_connections",
19843
+ "save_connection",
19844
+ "test_connection",
19845
+ "delete_connection"
19846
+ ];
19847
+ toolNameSets = /* @__PURE__ */ new WeakMap();
19848
+ }
19849
+ });
19850
+
19579
19851
  // src/common/telemetry/TelemetrySchema.ts
19580
19852
  function isTelemetryEventName(value) {
19581
19853
  return EVENT_SET.has(value);
@@ -19601,6 +19873,38 @@ function normalizeTelemetryConnector(value) {
19601
19873
  function isTelemetryErrorCode(value) {
19602
19874
  return typeof value === "string" && ERROR_CODE_SET.has(value);
19603
19875
  }
19876
+ function normalizeTelemetryDiagnosticErrorCode(value) {
19877
+ const text = typeof value === "number" && Number.isFinite(value) ? String(value) : value;
19878
+ return typeof text === "string" && /^[A-Za-z0-9_.-]{1,32}$/.test(text) ? text : void 0;
19879
+ }
19880
+ function normalizeTelemetryDiagnosticErrorClass(value) {
19881
+ return typeof value === "string" && /^[A-Za-z][A-Za-z0-9_]{0,63}$/.test(value) ? value : void 0;
19882
+ }
19883
+ function diagnosticErrorCodeOf(error52) {
19884
+ if (error52 === null || typeof error52 !== "object") {
19885
+ return void 0;
19886
+ }
19887
+ const record2 = error52;
19888
+ const code = normalizeTelemetryDiagnosticErrorCode(record2.code);
19889
+ if (code) {
19890
+ return code;
19891
+ }
19892
+ if (record2.cause === null || typeof record2.cause !== "object") {
19893
+ return void 0;
19894
+ }
19895
+ return normalizeTelemetryDiagnosticErrorCode(record2.cause.code);
19896
+ }
19897
+ function diagnosticErrorClassOf(error52) {
19898
+ if (error52 === null || typeof error52 !== "object") {
19899
+ return void 0;
19900
+ }
19901
+ const record2 = error52;
19902
+ const constructorName = normalizeTelemetryDiagnosticErrorClass(record2.constructor?.name);
19903
+ if (constructorName && constructorName !== "Error" && constructorName !== "Object") {
19904
+ return constructorName;
19905
+ }
19906
+ return normalizeTelemetryDiagnosticErrorClass(record2.name) ?? constructorName;
19907
+ }
19604
19908
  function normalizeTelemetryToolName(value) {
19605
19909
  return value && TOOL_NAME_SET.has(value) ? value : "unknown";
19606
19910
  }
@@ -19770,6 +20074,10 @@ function sanitizeTelemetryProperty(rule, value) {
19770
20074
  return typeof value === "string" && DISCOVERY_KEY_PATTERN.test(value) ? value : void 0;
19771
20075
  case "errorCode":
19772
20076
  return typeof value === "string" && ERROR_CODE_SET.has(value) ? value : void 0;
20077
+ case "diagnosticErrorCode":
20078
+ return normalizeTelemetryDiagnosticErrorCode(value);
20079
+ case "diagnosticErrorClass":
20080
+ return normalizeTelemetryDiagnosticErrorClass(value);
19773
20081
  case "loopExecutor":
19774
20082
  return typeof value === "string" && LOOP_EXECUTOR_SET.has(value) ? value : void 0;
19775
20083
  case "mcpClient":
@@ -19822,6 +20130,8 @@ function sanitizeTelemetryProperty(rule, value) {
19822
20130
  return typeof value === "string" && TOOL_NAME_SET.has(value) ? value : void 0;
19823
20131
  case "uiAction":
19824
20132
  return typeof value === "string" && UI_ACTION_SET.has(value) ? value : void 0;
20133
+ case "uiActionOutcome":
20134
+ return typeof value === "string" && UI_ACTION_OUTCOME_SET.has(value) ? value : void 0;
19825
20135
  case "version":
19826
20136
  return typeof value === "string" && VERSION_PATTERN.test(value) ? value : void 0;
19827
20137
  case "firstValueStep":
@@ -19830,12 +20140,13 @@ function sanitizeTelemetryProperty(rule, value) {
19830
20140
  return isFirstValueOutcome(value) ? value : void 0;
19831
20141
  }
19832
20142
  }
19833
- var TELEMETRY_SCHEMA_VERSION, TELEMETRY_EVENTS, REQUEST_ORIGINS, REQUEST_ORIGIN_SET, TELEMETRY_RESOURCE_KINDS, TELEMETRY_MCP_CLIENTS, MCP_CLIENT_SET, TELEMETRY_UI_ACTIONS, UI_ACTION_SET, TELEMETRY_CONNECTORS, TELEMETRY_TOOL_NAMES, TELEMETRY_COMMAND_IDS, TELEMETRY_PLATFORMS, TELEMETRY_SURFACES, TELEMETRY_STATES, TELEMETRY_SOURCES, TELEMETRY_STATUS_REASONS, TELEMETRY_STATEMENT_TYPES, TELEMETRY_DURATION_BUCKETS, TELEMETRY_ROW_COUNT_BUCKETS, TELEMETRY_COLUMN_COUNT_BUCKETS, TELEMETRY_QUERY_LENGTH_BUCKETS, TELEMETRY_SELECTION_MODES, TELEMETRY_TAB_MODES, TELEMETRY_ERROR_CODES, TELEMETRY_LOOP_EXECUTORS, TELEMETRY_ERROR_IDS, TELEMETRY_ERROR_KINDS, TELEMETRY_FLAG_KEYS, TELEMETRY_ACQUISITION_CHANNELS, TELEMETRY_FLAG_SOURCES, TELEMETRY_FLAG_REASONS, COMMON_PROPERTY_RULES, EVENT_PROPERTY_RULES, EVENT_SET, COMMAND_ID_SET, PLATFORM_SET, SURFACE_SET, STATE_SET, SOURCE_SET, STATUS_REASON_SET, STATEMENT_TYPE_SET, DURATION_BUCKET_SET, ROW_COUNT_BUCKET_SET, COLUMN_COUNT_BUCKET_SET, QUERY_LENGTH_BUCKET_SET, SELECTION_MODE_SET, TAB_MODE_SET, RESOURCE_KIND_SET, ERROR_KIND_SET, ERROR_ID_SET, ERROR_CODE_SET, LOOP_EXECUTOR_SET, CONNECTOR_SET, TOOL_NAME_SET, FLAG_KEY_SET, FLAG_SOURCE_SET, FLAG_REASON_SET, ACQUISITION_CHANNEL_SET, UUID_PATTERN, SAFE_STRING_PATTERN, VERSION_PATTERN, DISCOVERY_KEY_PATTERN, DIGITS_PATTERN, CRASH_KIND_SET, MCP_ERROR_PHASE_SET, SERVICE_LIFECYCLE_PHASE_SET, SERVICE_LIFECYCLE_OUTCOME_SET;
20143
+ var TELEMETRY_SCHEMA_VERSION, TELEMETRY_EVENTS, REQUEST_ORIGINS, REQUEST_ORIGIN_SET, TELEMETRY_RESOURCE_KINDS, TELEMETRY_MCP_CLIENTS, MCP_CLIENT_SET, TELEMETRY_UI_ACTIONS, UI_ACTION_SET, UI_ACTION_OUTCOME_SET, TELEMETRY_CONNECTORS, TELEMETRY_TOOL_NAMES, TELEMETRY_COMMAND_IDS, TELEMETRY_PLATFORMS, TELEMETRY_SURFACES, TELEMETRY_STATES, TELEMETRY_SOURCES, TELEMETRY_STATUS_REASONS, TELEMETRY_STATEMENT_TYPES, TELEMETRY_DURATION_BUCKETS, TELEMETRY_ROW_COUNT_BUCKETS, TELEMETRY_COLUMN_COUNT_BUCKETS, TELEMETRY_QUERY_LENGTH_BUCKETS, TELEMETRY_SELECTION_MODES, TELEMETRY_TAB_MODES, TELEMETRY_ERROR_CODES, TELEMETRY_LOOP_EXECUTORS, TELEMETRY_ERROR_IDS, TELEMETRY_ERROR_KINDS, TELEMETRY_FLAG_KEYS, TELEMETRY_ACQUISITION_CHANNELS, TELEMETRY_FLAG_SOURCES, TELEMETRY_FLAG_REASONS, COMMON_PROPERTY_RULES, EVENT_PROPERTY_RULES, EVENT_SET, COMMAND_ID_SET, PLATFORM_SET, SURFACE_SET, STATE_SET, SOURCE_SET, STATUS_REASON_SET, STATEMENT_TYPE_SET, DURATION_BUCKET_SET, ROW_COUNT_BUCKET_SET, COLUMN_COUNT_BUCKET_SET, QUERY_LENGTH_BUCKET_SET, SELECTION_MODE_SET, TAB_MODE_SET, RESOURCE_KIND_SET, ERROR_KIND_SET, ERROR_ID_SET, ERROR_CODE_SET, LOOP_EXECUTOR_SET, CONNECTOR_SET, TOOL_NAME_SET, FLAG_KEY_SET, FLAG_SOURCE_SET, FLAG_REASON_SET, ACQUISITION_CHANNEL_SET, UUID_PATTERN, SAFE_STRING_PATTERN, VERSION_PATTERN, DISCOVERY_KEY_PATTERN, DIGITS_PATTERN, CRASH_KIND_SET, MCP_ERROR_PHASE_SET, SERVICE_LIFECYCLE_PHASE_SET, SERVICE_LIFECYCLE_OUTCOME_SET;
19834
20144
  var init_TelemetrySchema = __esm({
19835
20145
  "src/common/telemetry/TelemetrySchema.ts"() {
19836
20146
  "use strict";
19837
20147
  init_firstValueStep();
19838
- TELEMETRY_SCHEMA_VERSION = "2.6";
20148
+ init_toolProfiles();
20149
+ TELEMETRY_SCHEMA_VERSION = "2.7";
19839
20150
  TELEMETRY_EVENTS = [
19840
20151
  "extension_activated",
19841
20152
  "command_invoked",
@@ -19886,8 +20197,16 @@ var init_TelemetrySchema = __esm({
19886
20197
  "unknown"
19887
20198
  ];
19888
20199
  MCP_CLIENT_SET = new Set(TELEMETRY_MCP_CLIENTS);
19889
- TELEMETRY_UI_ACTIONS = ["sort", "filter", "export", "tab_switch"];
20200
+ TELEMETRY_UI_ACTIONS = [
20201
+ "sort",
20202
+ "filter",
20203
+ "export",
20204
+ "tab_switch",
20205
+ "run_query",
20206
+ "connection_created"
20207
+ ];
19890
20208
  UI_ACTION_SET = new Set(TELEMETRY_UI_ACTIONS);
20209
+ UI_ACTION_OUTCOME_SET = /* @__PURE__ */ new Set(["success", "error"]);
19891
20210
  TELEMETRY_CONNECTORS = [
19892
20211
  "trino",
19893
20212
  "postgres",
@@ -19902,29 +20221,7 @@ var init_TelemetrySchema = __esm({
19902
20221
  "custom",
19903
20222
  "unknown"
19904
20223
  ];
19905
- TELEMETRY_TOOL_NAMES = [
19906
- "list_connectors",
19907
- "run_query",
19908
- "get_tab_info",
19909
- "list_sessions",
19910
- "list_connections",
19911
- "save_connection",
19912
- "request_connection_credentials",
19913
- "test_connection",
19914
- "delete_connection",
19915
- "list_schemas",
19916
- "list_tables",
19917
- "describe_table",
19918
- "cancel_query",
19919
- "close_tab",
19920
- "render_chart",
19921
- "save_chart",
19922
- "list_charts",
19923
- "ledger_stats",
19924
- "verify_ledger",
19925
- "record_ui_event",
19926
- "unknown"
19927
- ];
20224
+ TELEMETRY_TOOL_NAMES = [...ALL_TOOLS, "unknown"];
19928
20225
  TELEMETRY_COMMAND_IDS = [
19929
20226
  "grain.showDaemonInfo",
19930
20227
  "grain.mcp.restart",
@@ -19967,6 +20264,7 @@ var init_TelemetrySchema = __esm({
19967
20264
  "extension_host",
19968
20265
  "onboarding",
19969
20266
  "query_editor",
20267
+ "workspace_ready",
19970
20268
  "connection_manager",
19971
20269
  "connection_form",
19972
20270
  "results_grid",
@@ -20302,6 +20600,7 @@ var init_TelemetrySchema = __esm({
20302
20600
  "connection_save_unknown",
20303
20601
  /** The supervisor rejected registration of the installed service. */
20304
20602
  "service_supervisor_registration_failed",
20603
+ "service_runtime_provision_failed",
20305
20604
  /** The supervisor rejected starting the installed service. */
20306
20605
  "service_supervisor_start_failed",
20307
20606
  /** The supervisor accepted the service, but it never published a reachable endpoint. */
@@ -20427,6 +20726,8 @@ var init_TelemetrySchema = __esm({
20427
20726
  success: "boolean",
20428
20727
  duration_bucket: "durationBucket",
20429
20728
  error_kind: "errorKind",
20729
+ error_code: "diagnosticErrorCode",
20730
+ error_class: "diagnosticErrorClass",
20430
20731
  error_id: "errorId",
20431
20732
  connector: "connector"
20432
20733
  },
@@ -20473,7 +20774,11 @@ var init_TelemetrySchema = __esm({
20473
20774
  duration_bucket: "durationBucket",
20474
20775
  error_kind: "errorKind"
20475
20776
  },
20476
- ledger_health: { entries_bucket: "rowCountBucket", write_failures_bucket: "rowCountBucket" },
20777
+ ledger_health: {
20778
+ entries_bucket: "rowCountBucket",
20779
+ write_failures_bucket: "rowCountBucket",
20780
+ outcome: "safeString"
20781
+ },
20477
20782
  ledger_verify_completed: {
20478
20783
  outcome: "safeString",
20479
20784
  entries_checked_bucket: "rowCountBucket",
@@ -20508,7 +20813,8 @@ var init_TelemetrySchema = __esm({
20508
20813
  },
20509
20814
  ui_state_shown: {},
20510
20815
  ui_action_performed: {
20511
- ui_action: "uiAction"
20816
+ ui_action: "uiAction",
20817
+ outcome: "uiActionOutcome"
20512
20818
  },
20513
20819
  first_value_step: {
20514
20820
  step: "firstValueStep",
@@ -20908,7 +21214,7 @@ var init_TelemetryEmitter = __esm({
20908
21214
 
20909
21215
  // src/common/telemetryConsent.ts
20910
21216
  function telemetryConsentPath(configDir) {
20911
- return path9.join(configDir, TELEMETRY_CONSENT_FILENAME);
21217
+ return path10.join(configDir, TELEMETRY_CONSENT_FILENAME);
20912
21218
  }
20913
21219
  function writeTelemetryConsent(fileSystem, configDir, record2) {
20914
21220
  const targetPath = telemetryConsentPath(configDir);
@@ -20928,7 +21234,7 @@ function writeTelemetryConsent(fileSystem, configDir, record2) {
20928
21234
  function readTelemetryConsentStatus(configDir) {
20929
21235
  let raw;
20930
21236
  try {
20931
- raw = fs7.readFileSync(telemetryConsentPath(configDir), "utf8");
21237
+ raw = fs8.readFileSync(telemetryConsentPath(configDir), "utf8");
20932
21238
  } catch {
20933
21239
  return { type: "missing" };
20934
21240
  }
@@ -20964,12 +21270,12 @@ function readTelemetryConsentStatus(configDir) {
20964
21270
  }
20965
21271
  };
20966
21272
  }
20967
- var fs7, path9, TELEMETRY_CONSENT_FILENAME;
21273
+ var fs8, path10, TELEMETRY_CONSENT_FILENAME;
20968
21274
  var init_telemetryConsent = __esm({
20969
21275
  "src/common/telemetryConsent.ts"() {
20970
21276
  "use strict";
20971
- fs7 = __toESM(require("fs"));
20972
- path9 = __toESM(require("path"));
21277
+ fs8 = __toESM(require("fs"));
21278
+ path10 = __toESM(require("path"));
20973
21279
  TELEMETRY_CONSENT_FILENAME = "telemetry-consent.json";
20974
21280
  }
20975
21281
  });
@@ -20979,7 +21285,7 @@ function isAcquisitionChannel(value) {
20979
21285
  return typeof value === "string" && ACQUISITION_CHANNEL_SET2.has(value);
20980
21286
  }
20981
21287
  function acquisitionChannelPath(configDir) {
20982
- return path10.join(configDir, ACQUISITION_CHANNEL_FILENAME);
21288
+ return path11.join(configDir, ACQUISITION_CHANNEL_FILENAME);
20983
21289
  }
20984
21290
  function acquisitionChannelFromEnvironment(env2) {
20985
21291
  const channel = env2["GRAIN_ACQUISITION_CHANNEL"];
@@ -20996,7 +21302,7 @@ function writeAcquisitionChannel(fileSystem, configDir, record2) {
20996
21302
  function readAcquisitionChannelStatus(configDir) {
20997
21303
  let raw;
20998
21304
  try {
20999
- raw = fs8.readFileSync(acquisitionChannelPath(configDir), "utf8");
21305
+ raw = fs9.readFileSync(acquisitionChannelPath(configDir), "utf8");
21000
21306
  } catch {
21001
21307
  return { type: "missing" };
21002
21308
  }
@@ -21015,12 +21321,12 @@ function readAcquisitionChannelStatus(configDir) {
21015
21321
  }
21016
21322
  return { type: "valid", record: { channel: record2["channel"] } };
21017
21323
  }
21018
- var fs8, path10, ACQUISITION_CHANNEL_FILENAME, ACQUISITION_CHANNELS, ACQUISITION_CHANNEL_SET2;
21324
+ var fs9, path11, ACQUISITION_CHANNEL_FILENAME, ACQUISITION_CHANNELS, ACQUISITION_CHANNEL_SET2;
21019
21325
  var init_acquisitionChannel = __esm({
21020
21326
  "src/common/acquisitionChannel.ts"() {
21021
21327
  "use strict";
21022
- fs8 = __toESM(require("fs"));
21023
- path10 = __toESM(require("path"));
21328
+ fs9 = __toESM(require("fs"));
21329
+ path11 = __toESM(require("path"));
21024
21330
  ACQUISITION_CHANNEL_FILENAME = "acquisition-channel.json";
21025
21331
  ACQUISITION_CHANNELS = ["marketplace", "open_vsx", "cli"];
21026
21332
  ACQUISITION_CHANNEL_SET2 = new Set(ACQUISITION_CHANNELS);
@@ -21044,13 +21350,13 @@ function isHumanOrigin(origin2) {
21044
21350
  function isDaemonEmittedOrigin(origin2) {
21045
21351
  return origin2 !== "vscode_extension";
21046
21352
  }
21047
- var crypto5, fs9, path11, INSTALL_ID_FILENAME, UUID_PATTERN2, TELEMETRY_CONSENT_REFRESH_MS, DaemonTelemetryService;
21353
+ var crypto5, fs10, path12, INSTALL_ID_FILENAME, UUID_PATTERN2, TELEMETRY_CONSENT_REFRESH_MS, DaemonTelemetryService;
21048
21354
  var init_DaemonTelemetryService = __esm({
21049
21355
  "src/server/DaemonTelemetryService.ts"() {
21050
21356
  "use strict";
21051
21357
  crypto5 = __toESM(require("crypto"));
21052
- fs9 = __toESM(require("fs"));
21053
- path11 = __toESM(require("path"));
21358
+ fs10 = __toESM(require("fs"));
21359
+ path12 = __toESM(require("path"));
21054
21360
  init_TelemetryEmitter();
21055
21361
  init_TelemetrySchema();
21056
21362
  init_ConsoleLogger();
@@ -21154,9 +21460,9 @@ var init_DaemonTelemetryService = __esm({
21154
21460
  if (this.cachedInstallId) {
21155
21461
  return this.cachedInstallId;
21156
21462
  }
21157
- const filePath = path11.join(this.configDir, INSTALL_ID_FILENAME);
21463
+ const filePath = path12.join(this.configDir, INSTALL_ID_FILENAME);
21158
21464
  try {
21159
- const existing = fs9.readFileSync(filePath, "utf8").trim();
21465
+ const existing = fs10.readFileSync(filePath, "utf8").trim();
21160
21466
  if (UUID_PATTERN2.test(existing)) {
21161
21467
  this.cachedInstallId = existing;
21162
21468
  return this.cachedInstallId;
@@ -21165,8 +21471,8 @@ var init_DaemonTelemetryService = __esm({
21165
21471
  }
21166
21472
  this.cachedInstallId = crypto5.randomUUID();
21167
21473
  try {
21168
- fs9.mkdirSync(this.configDir, { recursive: true });
21169
- fs9.writeFileSync(filePath, this.cachedInstallId, "utf8");
21474
+ fs10.mkdirSync(this.configDir, { recursive: true });
21475
+ fs10.writeFileSync(filePath, this.cachedInstallId, "utf8");
21170
21476
  } catch (e2) {
21171
21477
  logger.warn("[Daemon] Could not persist telemetry install ID:", e2);
21172
21478
  }
@@ -21193,7 +21499,7 @@ function downloadToFile(url3, destPath, options) {
21193
21499
  const responseTimeoutMs = options?.responseTimeoutMs ?? 1e4;
21194
21500
  const idleTimeoutMs = options?.idleTimeoutMs ?? 3e4;
21195
21501
  return new Promise((resolve11, reject) => {
21196
- fs10.mkdirSync(path12.dirname(destPath), { recursive: true });
21502
+ fs11.mkdirSync(path13.dirname(destPath), { recursive: true });
21197
21503
  let settled = false;
21198
21504
  let file4;
21199
21505
  let responseTimeout = void 0;
@@ -21215,7 +21521,7 @@ function downloadToFile(url3, destPath, options) {
21215
21521
  if (file4) {
21216
21522
  file4.destroy();
21217
21523
  }
21218
- fs10.rm(destPath, { force: true }, () => reject(err));
21524
+ fs11.rm(destPath, { force: true }, () => reject(err));
21219
21525
  };
21220
21526
  const client = clientFor(url3);
21221
21527
  const request2 = client.get(url3, (response) => {
@@ -21236,7 +21542,7 @@ function downloadToFile(url3, destPath, options) {
21236
21542
  };
21237
21543
  response.on("data", resetIdleTimeout);
21238
21544
  resetIdleTimeout();
21239
- file4 = fs10.createWriteStream(destPath);
21545
+ file4 = fs11.createWriteStream(destPath);
21240
21546
  response.pipe(file4);
21241
21547
  response.on("error", failOnce);
21242
21548
  file4.on("finish", () => {
@@ -21261,7 +21567,7 @@ function downloadToFile(url3, destPath, options) {
21261
21567
  function sha512File(filePath) {
21262
21568
  return new Promise((resolve11, reject) => {
21263
21569
  const hash2 = crypto6.createHash("sha512");
21264
- const stream4 = fs10.createReadStream(filePath);
21570
+ const stream4 = fs11.createReadStream(filePath);
21265
21571
  stream4.on("data", (chunk) => hash2.update(chunk));
21266
21572
  stream4.on("end", () => resolve11(hash2.digest("base64")));
21267
21573
  stream4.on("error", reject);
@@ -21270,7 +21576,7 @@ function sha512File(filePath) {
21270
21576
  function sha256File(filePath) {
21271
21577
  return new Promise((resolve11, reject) => {
21272
21578
  const hash2 = crypto6.createHash("sha256");
21273
- const stream4 = fs10.createReadStream(filePath);
21579
+ const stream4 = fs11.createReadStream(filePath);
21274
21580
  stream4.on("data", (chunk) => hash2.update(chunk));
21275
21581
  stream4.on("end", () => resolve11(hash2.digest("hex")));
21276
21582
  stream4.on("error", reject);
@@ -21280,14 +21586,14 @@ function verifyIntegrity(actualBase64Sha512, expectedIntegrity) {
21280
21586
  const expectedBase64 = expectedIntegrity.replace(/^sha512-/, "");
21281
21587
  return actualBase64Sha512 === expectedBase64;
21282
21588
  }
21283
- var http4, https2, fs10, path12, crypto6;
21589
+ var http4, https2, fs11, path13, crypto6;
21284
21590
  var init_ArtifactDownloader = __esm({
21285
21591
  "src/server/runtime/ArtifactDownloader.ts"() {
21286
21592
  "use strict";
21287
21593
  http4 = __toESM(require("http"));
21288
21594
  https2 = __toESM(require("https"));
21289
- fs10 = __toESM(require("fs"));
21290
- path12 = __toESM(require("path"));
21595
+ fs11 = __toESM(require("fs"));
21596
+ path13 = __toESM(require("path"));
21291
21597
  crypto6 = __toESM(require("crypto"));
21292
21598
  }
21293
21599
  });
@@ -21371,37 +21677,37 @@ function parseTar(buffer) {
21371
21677
  return entries;
21372
21678
  }
21373
21679
  async function extractTarGz(tarGzPath, destDir) {
21374
- const compressed = fs11.readFileSync(tarGzPath);
21680
+ const compressed = fs12.readFileSync(tarGzPath);
21375
21681
  const tarBuffer = zlib.gunzipSync(compressed);
21376
21682
  const entries = parseTar(tarBuffer);
21377
- const resolvedDestDir = path13.resolve(destDir);
21378
- fs11.mkdirSync(resolvedDestDir, { recursive: true });
21379
- const within = (candidate) => candidate === resolvedDestDir || candidate.startsWith(resolvedDestDir + path13.sep);
21683
+ const resolvedDestDir = path14.resolve(destDir);
21684
+ fs12.mkdirSync(resolvedDestDir, { recursive: true });
21685
+ const within = (candidate) => candidate === resolvedDestDir || candidate.startsWith(resolvedDestDir + path14.sep);
21380
21686
  for (const entry of entries) {
21381
21687
  if (!entry.name || entry.name === "." || entry.name === "./") {
21382
21688
  continue;
21383
21689
  }
21384
- const targetPath = path13.resolve(resolvedDestDir, entry.name);
21690
+ const targetPath = path14.resolve(resolvedDestDir, entry.name);
21385
21691
  if (!within(targetPath)) {
21386
21692
  throw new Error(
21387
21693
  `Refusing to extract tar entry that escapes destination directory: ${entry.name}`
21388
21694
  );
21389
21695
  }
21390
21696
  if (entry.typeflag === "5" || entry.name.endsWith("/")) {
21391
- fs11.mkdirSync(targetPath, { recursive: true });
21697
+ fs12.mkdirSync(targetPath, { recursive: true });
21392
21698
  continue;
21393
21699
  }
21394
21700
  if (entry.typeflag === "0" || entry.typeflag === "\0" || entry.typeflag === "7") {
21395
- fs11.mkdirSync(path13.dirname(targetPath), { recursive: true });
21396
- fs11.writeFileSync(targetPath, entry.content);
21701
+ fs12.mkdirSync(path14.dirname(targetPath), { recursive: true });
21702
+ fs12.writeFileSync(targetPath, entry.content);
21397
21703
  continue;
21398
21704
  }
21399
21705
  if (entry.typeflag === "2") {
21400
21706
  if (!entry.linkname) {
21401
21707
  throw new Error(`Tar symlink entry has no target: ${entry.name}`);
21402
21708
  }
21403
- const resolvedLink = path13.resolve(path13.dirname(targetPath), entry.linkname);
21404
- if (path13.isAbsolute(entry.linkname) || !within(resolvedLink)) {
21709
+ const resolvedLink = path14.resolve(path14.dirname(targetPath), entry.linkname);
21710
+ if (path14.isAbsolute(entry.linkname) || !within(resolvedLink)) {
21405
21711
  throw new Error(
21406
21712
  `Refusing to extract tar symlink that escapes destination directory: ${entry.name} -> ${entry.linkname}`
21407
21713
  );
@@ -21409,9 +21715,9 @@ async function extractTarGz(tarGzPath, destDir) {
21409
21715
  if (process.platform === "win32") {
21410
21716
  continue;
21411
21717
  }
21412
- fs11.mkdirSync(path13.dirname(targetPath), { recursive: true });
21413
- fs11.rmSync(targetPath, { force: true });
21414
- fs11.symlinkSync(entry.linkname, targetPath);
21718
+ fs12.mkdirSync(path14.dirname(targetPath), { recursive: true });
21719
+ fs12.rmSync(targetPath, { force: true });
21720
+ fs12.symlinkSync(entry.linkname, targetPath);
21415
21721
  continue;
21416
21722
  }
21417
21723
  throw new Error(
@@ -21419,12 +21725,12 @@ async function extractTarGz(tarGzPath, destDir) {
21419
21725
  );
21420
21726
  }
21421
21727
  }
21422
- var fs11, path13, zlib, GNU_LONG_NAME, GNU_LONG_LINK, PAX_EXTENDED_HEADER, PAX_GLOBAL_HEADER;
21728
+ var fs12, path14, zlib, GNU_LONG_NAME, GNU_LONG_LINK, PAX_EXTENDED_HEADER, PAX_GLOBAL_HEADER;
21423
21729
  var init_MinimalTarExtractor = __esm({
21424
21730
  "src/server/runtime/MinimalTarExtractor.ts"() {
21425
21731
  "use strict";
21426
- fs11 = __toESM(require("fs"));
21427
- path13 = __toESM(require("path"));
21732
+ fs12 = __toESM(require("fs"));
21733
+ path14 = __toESM(require("path"));
21428
21734
  zlib = __toESM(require("zlib"));
21429
21735
  GNU_LONG_NAME = "L";
21430
21736
  GNU_LONG_LINK = "K";
@@ -21444,13 +21750,13 @@ function currentPlatformKey() {
21444
21750
  return key;
21445
21751
  }
21446
21752
  function artifactRuntimeDir(sqlPreviewHome, artifactId) {
21447
- return path14.join(sqlPreviewHome, "runtime", artifactId);
21753
+ return path15.join(sqlPreviewHome, "runtime", artifactId);
21448
21754
  }
21449
21755
  function artifactVersionDir(sqlPreviewHome, artifactId, version3) {
21450
- return path14.join(artifactRuntimeDir(sqlPreviewHome, artifactId), version3);
21756
+ return path15.join(artifactRuntimeDir(sqlPreviewHome, artifactId), version3);
21451
21757
  }
21452
21758
  function artifactManifestPath(versionDir) {
21453
- return path14.join(versionDir, ".provision-manifest.json");
21759
+ return path15.join(versionDir, ".provision-manifest.json");
21454
21760
  }
21455
21761
  function isManifestRecord(value) {
21456
21762
  return typeof value === "object" && value !== null;
@@ -21469,7 +21775,7 @@ function isLegacyDuckDbProvisionManifest(value) {
21469
21775
  }
21470
21776
  function readManifest(manifestPath) {
21471
21777
  try {
21472
- const raw = fs12.readFileSync(manifestPath, "utf8");
21778
+ const raw = fs13.readFileSync(manifestPath, "utf8");
21473
21779
  const parsed = JSON.parse(raw);
21474
21780
  if (isArtifactProvisionManifest(parsed) || isLegacyDuckDbProvisionManifest(parsed)) {
21475
21781
  return parsed;
@@ -21480,15 +21786,15 @@ function readManifest(manifestPath) {
21480
21786
  }
21481
21787
  }
21482
21788
  function writeManifest(manifestPath, manifest) {
21483
- fs12.mkdirSync(path14.dirname(manifestPath), { recursive: true });
21484
- fs12.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2), "utf8");
21789
+ fs13.mkdirSync(path15.dirname(manifestPath), { recursive: true });
21790
+ fs13.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2), "utf8");
21485
21791
  }
21486
- var fs12, path14, SUPPORTED_PLATFORMS;
21792
+ var fs13, path15, SUPPORTED_PLATFORMS;
21487
21793
  var init_ManagedArtifactTypes = __esm({
21488
21794
  "src/server/runtime/ManagedArtifactTypes.ts"() {
21489
21795
  "use strict";
21490
- fs12 = __toESM(require("fs"));
21491
- path14 = __toESM(require("path"));
21796
+ fs13 = __toESM(require("fs"));
21797
+ path15 = __toESM(require("path"));
21492
21798
  SUPPORTED_PLATFORMS = [
21493
21799
  "darwin-arm64",
21494
21800
  "darwin-x64",
@@ -21575,18 +21881,18 @@ var init_protocolVersion = __esm({
21575
21881
 
21576
21882
  // src/server/install/applicationPayload.ts
21577
21883
  function applicationDir(configHome, version3) {
21578
- return path19.join(configHome, "app", version3);
21884
+ return path20.join(configHome, "app", version3);
21579
21885
  }
21580
21886
  function isStandaloneApplication(configHome, entryPath) {
21581
21887
  if (!entryPath) {
21582
21888
  return false;
21583
21889
  }
21584
- const appRoot = path19.resolve(configHome, "app") + path19.sep;
21585
- return path19.resolve(entryPath).startsWith(appRoot);
21890
+ const appRoot = path20.resolve(configHome, "app") + path20.sep;
21891
+ return path20.resolve(entryPath).startsWith(appRoot);
21586
21892
  }
21587
21893
  function isWithin(parent, child) {
21588
- const relative5 = path19.relative(path19.resolve(parent), path19.resolve(child));
21589
- return relative5 === "" || !relative5.startsWith(`..${path19.sep}`) && relative5 !== "..";
21894
+ const relative5 = path20.relative(path20.resolve(parent), path20.resolve(child));
21895
+ return relative5 === "" || !relative5.startsWith(`..${path20.sep}`) && relative5 !== "..";
21590
21896
  }
21591
21897
  function removeDirectoryBestEffort(fileSystem, directory) {
21592
21898
  try {
@@ -21596,7 +21902,7 @@ function removeDirectoryBestEffort(fileSystem, directory) {
21596
21902
  }
21597
21903
  }
21598
21904
  function writeVersionManifest(fileSystem, directory, version3) {
21599
- const manifestPath = path19.join(directory, "package.json");
21905
+ const manifestPath = path20.join(directory, "package.json");
21600
21906
  let manifest = { name: "grain-daemon", private: true };
21601
21907
  try {
21602
21908
  const existing = JSON.parse(fileSystem.readFileSync(manifestPath, "utf8"));
@@ -21610,10 +21916,10 @@ function writeVersionManifest(fileSystem, directory, version3) {
21610
21916
  `, "utf8");
21611
21917
  }
21612
21918
  function installApplicationPayload(options) {
21613
- const fileSystem = options.fileSystem ?? fs16;
21919
+ const fileSystem = options.fileSystem ?? fs17;
21614
21920
  const { configHome, version: version3, sourceEntry } = options;
21615
21921
  const destinationDir = applicationDir(configHome, version3);
21616
- const applicationRoot = path19.join(configHome, "app");
21922
+ const applicationRoot = path20.join(configHome, "app");
21617
21923
  if (!isWithin(applicationRoot, destinationDir)) {
21618
21924
  throw new Error(`Application version must stay inside ${applicationRoot}`);
21619
21925
  }
@@ -21623,21 +21929,21 @@ function installApplicationPayload(options) {
21623
21929
  fileSystem.rmSync(staging, { recursive: true, force: true });
21624
21930
  fileSystem.mkdirSync(staging, { recursive: true });
21625
21931
  const isDirectory = fileSystem.statSync(sourceEntry).isDirectory();
21626
- const entryName = isDirectory ? "standalone.js" : path19.basename(sourceEntry);
21932
+ const entryName = isDirectory ? "standalone.js" : path20.basename(sourceEntry);
21627
21933
  if (isDirectory) {
21628
21934
  fileSystem.cpSync(sourceEntry, staging, { recursive: true });
21629
21935
  } else {
21630
- fileSystem.copyFileSync(sourceEntry, path19.join(staging, entryName));
21936
+ fileSystem.copyFileSync(sourceEntry, path20.join(staging, entryName));
21631
21937
  const pagesDir = [
21632
- path19.join(path19.dirname(sourceEntry), "dist"),
21633
- path19.join(path19.dirname(sourceEntry), "..", "..", "dist")
21634
- ].find((candidate) => fileSystem.existsSync(path19.join(candidate, "web-app.html")));
21938
+ path20.join(path20.dirname(sourceEntry), "dist"),
21939
+ path20.join(path20.dirname(sourceEntry), "..", "..", "dist")
21940
+ ].find((candidate) => fileSystem.existsSync(path20.join(candidate, "web-app.html")));
21635
21941
  if (pagesDir) {
21636
- fileSystem.mkdirSync(path19.join(staging, "dist"), { recursive: true });
21942
+ fileSystem.mkdirSync(path20.join(staging, "dist"), { recursive: true });
21637
21943
  for (const page of ["web-app.html", "mcp-app.html"]) {
21638
- const pagePath = path19.join(pagesDir, page);
21944
+ const pagePath = path20.join(pagesDir, page);
21639
21945
  if (fileSystem.existsSync(pagePath)) {
21640
- fileSystem.copyFileSync(pagePath, path19.join(staging, "dist", page));
21946
+ fileSystem.copyFileSync(pagePath, path20.join(staging, "dist", page));
21641
21947
  }
21642
21948
  }
21643
21949
  }
@@ -21664,23 +21970,23 @@ function installApplicationPayload(options) {
21664
21970
  throw error52;
21665
21971
  }
21666
21972
  removeDirectoryBestEffort(fileSystem, backup);
21667
- return path19.join(destinationDir, entryName);
21973
+ return path20.join(destinationDir, entryName);
21668
21974
  }
21669
21975
  function retainedApplicationVersions(configHome) {
21670
21976
  try {
21671
- return fs16.readdirSync(path19.join(configHome, "app"), { withFileTypes: true }).filter(
21977
+ return fs17.readdirSync(path20.join(configHome, "app"), { withFileTypes: true }).filter(
21672
21978
  (entry) => entry.isDirectory() && !entry.name.includes(".staging-") && !entry.name.includes(".backup-")
21673
21979
  ).map((entry) => entry.name).sort((left, right) => compareSemver(right, left));
21674
21980
  } catch {
21675
21981
  return [];
21676
21982
  }
21677
21983
  }
21678
- var fs16, path19;
21984
+ var fs17, path20;
21679
21985
  var init_applicationPayload = __esm({
21680
21986
  "src/server/install/applicationPayload.ts"() {
21681
21987
  "use strict";
21682
- fs16 = __toESM(require("fs"));
21683
- path19 = __toESM(require("path"));
21988
+ fs17 = __toESM(require("fs"));
21989
+ path20 = __toESM(require("path"));
21684
21990
  init_protocolVersion();
21685
21991
  }
21686
21992
  });
@@ -21724,7 +22030,7 @@ async function runRegistration(platform2, runner, command, args) {
21724
22030
  if (isUserServicesForbidden(platform2, result.output)) {
21725
22031
  throw new UserServicesForbiddenError(result.output);
21726
22032
  }
21727
- throw new Error(`${command} ${args.join(" ")} failed: ${result.output.trim()}`);
22033
+ throw new RegistrationError(command, args, result.exitCode, result.output);
21728
22034
  }
21729
22035
  async function runStart(runner, command, args) {
21730
22036
  const result = await runner.run(command, args);
@@ -21741,12 +22047,45 @@ function isCommandMissing(error52) {
21741
22047
  }
21742
22048
  function createSupervisorAdapter(platform2, runner, uid) {
21743
22049
  if (platform2 === "darwin") {
21744
- const target = (identifier) => `gui/${uid}/${identifier}`;
22050
+ const target = (domain2, identifier) => `${domain2}/${uid}/${identifier}`;
22051
+ const registeredTarget = async (identifier) => {
22052
+ for (const domain2 of ["gui", "user"]) {
22053
+ const serviceTarget = target(domain2, identifier);
22054
+ if (await probeRegistration(runner, "launchctl", ["print", serviceTarget])) {
22055
+ return serviceTarget;
22056
+ }
22057
+ }
22058
+ return void 0;
22059
+ };
21745
22060
  return {
21746
- isRegistered: (identifier) => probeRegistration(runner, "launchctl", ["print", target(identifier)]),
21747
- register: (unitPath) => runRegistration(platform2, runner, "launchctl", ["bootstrap", `gui/${uid}`, unitPath]),
21748
- unregister: (identifier) => runRegistration(platform2, runner, "launchctl", ["bootout", target(identifier)]),
21749
- start: (identifier) => runStart(runner, "launchctl", ["kickstart", "-k", target(identifier)])
22061
+ isRegistered: async (identifier) => await registeredTarget(identifier) !== void 0,
22062
+ register: async (unitPath) => {
22063
+ try {
22064
+ await runRegistration(platform2, runner, "launchctl", [
22065
+ "bootstrap",
22066
+ `gui/${uid}`,
22067
+ unitPath
22068
+ ]);
22069
+ } catch (error52) {
22070
+ if (!(error52 instanceof RegistrationError) || !(error52.exitCode === 125 || /(?:^|\D)125(?:\D|$)|Domain does not support specified action/i.test(error52.output))) {
22071
+ throw error52;
22072
+ }
22073
+ await runRegistration(platform2, runner, "launchctl", [
22074
+ "bootstrap",
22075
+ `user/${uid}`,
22076
+ unitPath
22077
+ ]);
22078
+ }
22079
+ },
22080
+ unregister: async (identifier) => runRegistration(platform2, runner, "launchctl", [
22081
+ "bootout",
22082
+ await registeredTarget(identifier) ?? target("gui", identifier)
22083
+ ]),
22084
+ start: async (identifier) => runStart(runner, "launchctl", [
22085
+ "kickstart",
22086
+ "-k",
22087
+ await registeredTarget(identifier) ?? target("gui", identifier)
22088
+ ])
21750
22089
  };
21751
22090
  }
21752
22091
  if (platform2 === "linux") {
@@ -21797,7 +22136,7 @@ function createSupervisorAdapter(platform2, runner, uid) {
21797
22136
  start: (identifier) => runStart(runner, "schtasks", ["/Run", "/TN", identifier])
21798
22137
  };
21799
22138
  }
21800
- var import_child_process3, UserServicesForbiddenError, ServiceManagerMissingError;
22139
+ var import_child_process3, UserServicesForbiddenError, ServiceManagerMissingError, RegistrationError;
21801
22140
  var init_supervisorAdapter = __esm({
21802
22141
  "src/server/install/supervisorAdapter.ts"() {
21803
22142
  "use strict";
@@ -21806,6 +22145,13 @@ var init_supervisorAdapter = __esm({
21806
22145
  };
21807
22146
  ServiceManagerMissingError = class extends UserServicesForbiddenError {
21808
22147
  };
22148
+ RegistrationError = class extends Error {
22149
+ constructor(command, args, exitCode, output) {
22150
+ super(`${command} ${args.join(" ")} failed: ${output.trim()}`);
22151
+ this.exitCode = exitCode;
22152
+ this.output = output;
22153
+ }
22154
+ };
21809
22155
  }
21810
22156
  });
21811
22157
 
@@ -21816,7 +22162,7 @@ var require_package = __commonJS({
21816
22162
  name: "grain",
21817
22163
  displayName: "Grain SQL",
21818
22164
  description: "Run SQL in VS Code and expose safe, visible MCP database tools for Claude, Cursor, and other AI agents.",
21819
- version: "0.10.12",
22165
+ version: "0.10.14",
21820
22166
  license: "UNLICENSED",
21821
22167
  mcpName: "io.github.pattrnlabs/grain",
21822
22168
  publisher: "pattrnlabs",
@@ -21869,7 +22215,8 @@ var require_package = __commonJS({
21869
22215
  "Other"
21870
22216
  ],
21871
22217
  activationEvents: [
21872
- "onLanguage:sql"
22218
+ "onLanguage:sql",
22219
+ "onStartupFinished"
21873
22220
  ],
21874
22221
  main: "./out/extension.js",
21875
22222
  contributes: {
@@ -22166,6 +22513,22 @@ var require_package = __commonJS({
22166
22513
  maximum: 20,
22167
22514
  order: 10
22168
22515
  },
22516
+ "grain.panelTheme": {
22517
+ type: "string",
22518
+ enum: [
22519
+ "inherit",
22520
+ "grain-light",
22521
+ "grain-dark"
22522
+ ],
22523
+ default: "inherit",
22524
+ description: "Color theme for the Grain results panel. Inherit follows your VS Code theme; the Grain themes use the Grain brand palette and type.",
22525
+ enumDescriptions: [
22526
+ "Follow the active VS Code color theme",
22527
+ "Grain Light: the Grain brand palette on a light ground",
22528
+ "Grain Dark: the Grain brand palette on a dark ground"
22529
+ ],
22530
+ order: 10.2
22531
+ },
22169
22532
  "grain.filterResultsByActiveFile": {
22170
22533
  type: "boolean",
22171
22534
  default: true,
@@ -22221,7 +22584,7 @@ var require_package = __commonJS({
22221
22584
  },
22222
22585
  "grain.mcpEnabled": {
22223
22586
  type: "boolean",
22224
- default: false,
22587
+ default: true,
22225
22588
  description: "(Beta) Serve the MCP surface so LLM agents can interact with Grain. When off, the daemon does not register /mcp at all. Changing this restarts the daemon. An explicitly launched stdio bridge is treated as consent and still works; to refuse MCP everywhere, set mcp.enabled to false in ~/.grain/daemon.json.",
22226
22589
  order: 20
22227
22590
  },
@@ -22362,11 +22725,17 @@ var require_package = __commonJS({
22362
22725
  watch: "tsc -watch -p ./",
22363
22726
  package: "node scripts/package-vsix.js",
22364
22727
  "ci:burn": "node scripts/ci-burn.mjs",
22365
- lint: 'eslint "src/**/*.ts" "scripts/**/*.js" "scripts/**/*.mjs" --cache',
22366
- "lint:fix": 'eslint "src/**/*.ts" "scripts/**/*.js" --fix --cache',
22367
- format: 'prettier --write "src/**/*.{ts,js,json}"',
22368
- "format:check": 'prettier --check "src/**/*.{ts,js,json}" --cache',
22728
+ lint: "oxlint -c .oxlintrc.json src scripts",
22729
+ "lint:legacy": 'eslint "src/**/*.ts" "scripts/**/*.js" "scripts/**/*.mjs" --cache',
22730
+ "lint:fix": "oxlint -c .oxlintrc.json --fix src scripts",
22731
+ "lint:fix:legacy": 'eslint "src/**/*.ts" "scripts/**/*.js" --fix --cache',
22732
+ format: 'oxfmt "src/**/*.{ts,js,json}"',
22733
+ "format:legacy": 'npx --yes prettier@3.6.2 --write "src/**/*.{ts,js,json}"',
22734
+ "format:check": 'oxfmt --check "src/**/*.{ts,js,json}"',
22369
22735
  workbench: "vite --config vite.config.workbench.mts",
22736
+ "check:panel-themes:vscode": "node scripts/check-panel-themes-vscode.cjs",
22737
+ "test:gui": "jest --config jest.medium.config.js --runInBand --roots <rootDir>/src/test/gui --testRegex \\.gui\\.test\\.js$",
22738
+ "check:panel-themes:workbench": "node scripts/check-panel-themes-workbench.cjs",
22370
22739
  "check:ui-contract": "node scripts/check-ui-token-contract.js",
22371
22740
  "check:brand-tokens": "node scripts/check-brand-tokens.js",
22372
22741
  "check:identity": "node scripts/check-identity.js",
@@ -22374,7 +22743,7 @@ var require_package = __commonJS({
22374
22743
  "check:token-theme-parity": "node scripts/check-token-theme-parity.js",
22375
22744
  "generate:duckdb-pins": "node scripts/generate-duckdb-pins.js",
22376
22745
  "generate:artifact-pins": "node scripts/generate-artifact-pins.js",
22377
- "generate:node-pins": "node scripts/generate-node-pins.js && npx prettier --write src/server/runtime/nodePins.generated.ts",
22746
+ "generate:node-pins": "node scripts/generate-node-pins.js && npx oxfmt src/server/runtime/nodePins.generated.ts",
22378
22747
  "check:duckdb-pins": "node scripts/check-duckdb-pins.js",
22379
22748
  "rfc:check": "node scripts/validate-rfcs.js",
22380
22749
  "docs:coverage-manifest": "node scripts/generate-coverage-manifest.js",
@@ -22389,7 +22758,11 @@ var require_package = __commonJS({
22389
22758
  "check:no-execpath-units": "node scripts/check-no-execpath-units.js",
22390
22759
  "check:gates": "node scripts/check-gates.js",
22391
22760
  "rfc:new": "node scripts/new-rfc.js",
22392
- "type-check": "tsc --noEmit --incremental --tsBuildInfoFile .tsbuildinfo",
22761
+ "type-check": "tsgo --noEmit -p ./",
22762
+ "type-check:legacy": "tsc --noEmit --incremental --tsBuildInfoFile .tsbuildinfo",
22763
+ typecheck: "npm run -s type-check",
22764
+ "typecheck:compare": "node scripts/compare-typecheck.js",
22765
+ "check:fast": "node scripts/check-fast.js",
22393
22766
  "esbuild-base": "esbuild ./src/extension.ts --bundle --outfile=out/extension.js --external:vscode --external:ws --format=cjs --platform=node",
22394
22767
  "esbuild-daemon": "esbuild ./src/server/Daemon.ts --bundle --outfile=out/server/Daemon.js --platform=node --format=cjs --external:vscode --external:@duckdb/node-api --external:@napi-rs/keyring --external:@google-cloud/bigquery --external:mysql2 --external:mysql2/* --external:mssql --external:snowflake-sdk --external:sql.js --alias:@opentelemetry/configuration=./src/stubs/otel-configuration-stub.js --alias:@opentelemetry/exporter-trace-otlp-grpc=./src/stubs/otel-grpc-exporters-stub.js --alias:@opentelemetry/exporter-logs-otlp-grpc=./src/stubs/otel-grpc-exporters-stub.js --alias:@opentelemetry/exporter-metrics-otlp-grpc=./src/stubs/otel-grpc-exporters-stub.js",
22395
22768
  "esbuild-standalone": 'esbuild ./src/server/standalone.ts --bundle --outfile=out/server/standalone.js --platform=node --format=cjs --external:vscode --external:@duckdb/node-api --external:@napi-rs/keyring --external:@google-cloud/bigquery --external:mysql2 --external:mysql2/* --external:mssql --external:snowflake-sdk --external:sql.js --banner:js="#!/usr/bin/env node" --alias:@opentelemetry/configuration=./src/stubs/otel-configuration-stub.js --alias:@opentelemetry/exporter-trace-otlp-grpc=./src/stubs/otel-grpc-exporters-stub.js --alias:@opentelemetry/exporter-logs-otlp-grpc=./src/stubs/otel-grpc-exporters-stub.js --alias:@opentelemetry/exporter-metrics-otlp-grpc=./src/stubs/otel-grpc-exporters-stub.js',
@@ -22446,7 +22819,7 @@ var require_package = __commonJS({
22446
22819
  "test:integration:stdio-bridge": 'node scripts/emit-seam-receipt.js "npm run test:integration:stdio-bridge" -- jest --config jest.config.js --runInBand --runTestsByPath src/test/integration/stdio_bridge.test.ts',
22447
22820
  "test:medium:rfc-baseline": "jest --config jest.medium.config.js --runInBand --runTestsByPath src/test/medium/rfcBaselineResolution.medium.test.js",
22448
22821
  "test:integration": "node ./out/test/runTest.js",
22449
- prewalkthrough: "npm run compile",
22822
+ prewalkthrough: "npm run compile && node scripts/build-daemon.js --entry=standalone",
22450
22823
  walkthrough: "node scripts/walkthrough-runner/run.js",
22451
22824
  "pretest:mcp-conformance": "npm run build:packages:dev && node scripts/build-daemon.js --entry=standalone",
22452
22825
  "test:mcp-conformance": "node scripts/run-mcp-conformance.js",
@@ -22485,7 +22858,6 @@ var require_package = __commonJS({
22485
22858
  "check:release-notes": "node scripts/release-note-fragments.js validate",
22486
22859
  "check:release-note-range": "node scripts/release-note-fragments.js check",
22487
22860
  "changelog:draft": "node scripts/release-note-fragments.js draft",
22488
- typecheck: "npm run type-check",
22489
22861
  "docs:graph": "node scripts/generate-architecture-graph.js",
22490
22862
  "docs:api": "typedoc",
22491
22863
  "docs:gen": "npm run docs:graph && npm run docs:api",
@@ -22529,6 +22901,7 @@ var require_package = __commonJS({
22529
22901
  "@types/vscode": "^1.80.0",
22530
22902
  "@typescript-eslint/eslint-plugin": "^5.59.8",
22531
22903
  "@typescript-eslint/parser": "^5.59.8",
22904
+ "@typescript/native-preview": "^7.0.0-dev.20260707.2",
22532
22905
  "@vitejs/plugin-react-swc": "^4.3.0",
22533
22906
  "@vscode/test-electron": "^2.5.2",
22534
22907
  "@vscode/vsce": "^3.9.1",
@@ -22537,8 +22910,6 @@ var require_package = __commonJS({
22537
22910
  "dotenv-cli": "^7.4.1",
22538
22911
  esbuild: "^0.17.19",
22539
22912
  eslint: "^8.41.0",
22540
- "eslint-config-prettier": "^9.1.2",
22541
- "eslint-plugin-prettier": "^5.5.3",
22542
22913
  glob: "^11.0.1",
22543
22914
  husky: "^8.0.3",
22544
22915
  jest: "^29.7.0",
@@ -22547,9 +22918,11 @@ var require_package = __commonJS({
22547
22918
  "lint-staged": "^15.5.2",
22548
22919
  madge: "^8.0.0",
22549
22920
  mocha: "^11.1.0",
22921
+ oxfmt: "^0.70.0",
22922
+ oxlint: "^1.85.0",
22550
22923
  "patch-package": "^8.0.1",
22551
22924
  pg: "^8.17.2",
22552
- prettier: "^3.6.2",
22925
+ "playwright-core": "1.62.1",
22553
22926
  secretlint: "^11.3.1",
22554
22927
  semver: "^7.8.5",
22555
22928
  sinon: "^20.0.0",
@@ -22559,6 +22932,7 @@ var require_package = __commonJS({
22559
22932
  typescript: "^5.1.3",
22560
22933
  vite: "^5.4.21",
22561
22934
  "vite-plugin-singlefile": "^2.3.0",
22935
+ vitest: "^3.2.7",
22562
22936
  yaml: "^2.8.3"
22563
22937
  },
22564
22938
  dependencies: {
@@ -22593,11 +22967,11 @@ var require_package = __commonJS({
22593
22967
  },
22594
22968
  "lint-staged": {
22595
22969
  "*.{ts,js,mjs}": [
22596
- "eslint --fix",
22597
- "prettier --write"
22970
+ "oxlint -c .oxlintrc.json --fix",
22971
+ "oxfmt"
22598
22972
  ],
22599
22973
  "*.{json,md}": [
22600
- "prettier --write"
22974
+ "oxfmt"
22601
22975
  ],
22602
22976
  "*.{ts,js,mjs,cjs,json,env,yaml,yml,sh,toml,ini,cfg,conf,pem,key,crt}": [
22603
22977
  "secretlint"
@@ -22612,206 +22986,6 @@ var require_package = __commonJS({
22612
22986
  }
22613
22987
  });
22614
22988
 
22615
- // src/common/toolProfiles.ts
22616
- function toolRuleFor(profile, tool) {
22617
- return profile.policy?.rules?.[TOOL_RESOURCE_CLASS[tool]] ?? "allow";
22618
- }
22619
- function toolRefusalMessage(profile, tool) {
22620
- return `Tool '${tool}' is not permitted for the '${profile.name}' profile: its resource class '${TOOL_RESOURCE_CLASS[tool]}' is refused by policy. The tool exists and is advertised; this call was declined, not lost.`;
22621
- }
22622
- function toolRefusalResult(profile, tool) {
22623
- return {
22624
- isError: true,
22625
- content: [{ type: "text", text: toolRefusalMessage(profile, tool) }],
22626
- structuredContent: { errorKind: "permission", errorId: "tool_not_permitted_for_profile" }
22627
- };
22628
- }
22629
- function refuseIfNotPermitted(profile, tool) {
22630
- const name = tool;
22631
- if (TOOL_RESOURCE_CLASS[name] === void 0)
22632
- return void 0;
22633
- if (toolRuleFor(profile, name) === "allow")
22634
- return void 0;
22635
- return toolRefusalResult(profile, name);
22636
- }
22637
- function isToolProfileName(value) {
22638
- return value === "vscode" || value === "headless" || value === "readonly" || value === "agent";
22639
- }
22640
- function operatorProfileOverride(onUnknownEnvValue) {
22641
- const fromEnv = process.env["MCP_PROFILE"];
22642
- if (fromEnv === void 0)
22643
- return void 0;
22644
- if (isToolProfileName(fromEnv))
22645
- return TOOL_PROFILES[fromEnv];
22646
- onUnknownEnvValue?.(fromEnv);
22647
- return void 0;
22648
- }
22649
- function resolveToolProfile(explicit, onUnknownEnvValue) {
22650
- if (explicit) {
22651
- return TOOL_PROFILES[explicit];
22652
- }
22653
- const fromEnv = process.env["MCP_PROFILE"];
22654
- if (fromEnv !== void 0) {
22655
- if (isToolProfileName(fromEnv)) {
22656
- return TOOL_PROFILES[fromEnv];
22657
- }
22658
- onUnknownEnvValue?.(fromEnv);
22659
- }
22660
- return TOOL_PROFILES.vscode;
22661
- }
22662
- function isSafeModeActive(profile, liveSafeMode) {
22663
- return profile.forceSafeMode || liveSafeMode;
22664
- }
22665
- function toolNamesForProfile(profile) {
22666
- const cached2 = toolNameSets.get(profile);
22667
- if (cached2)
22668
- return cached2;
22669
- const names = new Set(profile.tools);
22670
- toolNameSets.set(profile, names);
22671
- return names;
22672
- }
22673
- function composeToolProfiles(...profiles) {
22674
- const present = profiles.filter((p) => p !== void 0);
22675
- if (present.length === 0)
22676
- return TOOL_PROFILES.vscode;
22677
- if (present.length === 1)
22678
- return present[0];
22679
- const sets = present.map((p) => new Set(p.tools));
22680
- const rules = {};
22681
- for (const p of present) {
22682
- for (const [cls, rule] of Object.entries(p.policy?.rules ?? {})) {
22683
- if (rule === "refuse")
22684
- rules[cls] = "refuse";
22685
- }
22686
- }
22687
- const refusalCount = (p) => Object.keys(p.policy?.rules ?? {}).length;
22688
- const narrowest = present.reduce((a, b) => {
22689
- if (b.tools.length !== a.tools.length)
22690
- return b.tools.length < a.tools.length ? b : a;
22691
- return refusalCount(b) > refusalCount(a) ? b : a;
22692
- });
22693
- return {
22694
- name: narrowest.name,
22695
- tools: ALL_TOOLS.filter((tool) => sets.every((s) => s.has(tool))),
22696
- forceSafeMode: present.some((p) => p.forceSafeMode),
22697
- ...Object.keys(rules).length > 0 ? { policy: { rules } } : {}
22698
- };
22699
- }
22700
- function createToolProfileResolver(explicit, onUnknownEnvValue) {
22701
- const defaultProfile = resolveToolProfile(explicit, onUnknownEnvValue);
22702
- const pinned = explicit === void 0 ? void 0 : TOOL_PROFILES[explicit];
22703
- const fromEnv = operatorProfileOverride(onUnknownEnvValue);
22704
- return {
22705
- defaultProfile,
22706
- forCall(profile) {
22707
- const declared = profile === void 0 ? void 0 : TOOL_PROFILES[profile];
22708
- if (pinned === void 0 && fromEnv === void 0 && declared === void 0) {
22709
- return defaultProfile;
22710
- }
22711
- return composeToolProfiles(pinned, fromEnv, declared);
22712
- }
22713
- };
22714
- }
22715
- var ALL_TOOLS, READ_ONLY_TOOLS, TOOL_RESOURCE_CLASS, TOOL_PROFILES, WEB_PROXIED_TOOLS, toolNameSets;
22716
- var init_toolProfiles = __esm({
22717
- "src/common/toolProfiles.ts"() {
22718
- "use strict";
22719
- ALL_TOOLS = [
22720
- "list_connectors",
22721
- "run_query",
22722
- "get_tab_info",
22723
- "list_sessions",
22724
- "list_connections",
22725
- "save_connection",
22726
- "request_connection_credentials",
22727
- "test_connection",
22728
- "delete_connection",
22729
- "list_schemas",
22730
- "list_tables",
22731
- "describe_table",
22732
- "cancel_query",
22733
- "close_tab",
22734
- "render_chart",
22735
- "save_chart",
22736
- "list_charts",
22737
- "ledger_stats",
22738
- "verify_ledger",
22739
- "record_ui_event"
22740
- ];
22741
- READ_ONLY_TOOLS = [
22742
- "list_connectors",
22743
- "run_query",
22744
- "get_tab_info",
22745
- "list_sessions",
22746
- "list_connections",
22747
- "test_connection",
22748
- "list_schemas",
22749
- "list_tables",
22750
- "describe_table",
22751
- "cancel_query",
22752
- "close_tab",
22753
- "render_chart",
22754
- "list_charts",
22755
- "ledger_stats",
22756
- "verify_ledger",
22757
- "record_ui_event"
22758
- ];
22759
- TOOL_RESOURCE_CLASS = {
22760
- list_connectors: "read",
22761
- list_connections: "read",
22762
- list_sessions: "read",
22763
- get_tab_info: "read",
22764
- list_schemas: "read",
22765
- list_tables: "read",
22766
- describe_table: "read",
22767
- list_charts: "read",
22768
- ledger_stats: "read",
22769
- verify_ledger: "read",
22770
- test_connection: "read",
22771
- cancel_query: "session",
22772
- close_tab: "session",
22773
- render_chart: "session",
22774
- run_query: "query",
22775
- save_connection: "connection-config",
22776
- delete_connection: "connection-config",
22777
- request_connection_credentials: "credential",
22778
- save_chart: "workspace-write",
22779
- record_ui_event: "app-telemetry"
22780
- };
22781
- TOOL_PROFILES = {
22782
- // Human-in-the-loop VS Code surface: full toolset, safe mode from settings.
22783
- vscode: { name: "vscode", tools: ALL_TOOLS, forceSafeMode: false },
22784
- // Autonomous agents: starts as the full current toolset (RFC-062); will
22785
- // diverge toward synchronous/structured tools without breaking clients.
22786
- headless: { name: "headless", tools: ALL_TOOLS, forceSafeMode: false },
22787
- // Safe exploration: no profile/credential mutation, SQL gating always on.
22788
- readonly: { name: "readonly", tools: READ_ONLY_TOOLS, forceSafeMode: true },
22789
- // RFC-134: intended as the default for an attached AI agent surface — may read,
22790
- // query and chart, may not change saved connections or ask for stored credentials.
22791
- // This profile is assigned to the local agent identity and enforced on the stdio bridge.
22792
- // End-to-end enforcement is proven by the 'bridged client (agent profile) is permitted
22793
- // read tools but refused config/credential tools' test in stdio_bridge.test.ts.
22794
- // SQL restriction is deliberately not forced here: `grain.mcpSafeMode`
22795
- // already defaults to on, and a ceiling would make that setting silently stop
22796
- // working for the recommended agent path.
22797
- agent: {
22798
- name: "agent",
22799
- tools: ALL_TOOLS,
22800
- forceSafeMode: false,
22801
- policy: { rules: { "connection-config": "refuse", credential: "refuse" } }
22802
- }
22803
- };
22804
- WEB_PROXIED_TOOLS = [
22805
- "list_connectors",
22806
- "list_connections",
22807
- "save_connection",
22808
- "test_connection",
22809
- "delete_connection"
22810
- ];
22811
- toolNameSets = /* @__PURE__ */ new WeakMap();
22812
- }
22813
- });
22814
-
22815
22989
  // src/server/auth/ClientRegistry.ts
22816
22990
  function clientRegistryPath(configDir) {
22817
22991
  return import_path3.default.join(configDir, CLIENT_REGISTRY_FILENAME);
@@ -23017,32 +23191,32 @@ async function startCommand(configDir = resolveGrainHome(), spawner = import_chi
23017
23191
  const lockPath = path24.join(configDir, "start.lock");
23018
23192
  let claimedLock = false;
23019
23193
  try {
23020
- const content = fs20.readFileSync(lockPath, "utf8");
23194
+ const content = fs21.readFileSync(lockPath, "utf8");
23021
23195
  const parts = content.split("\n");
23022
23196
  const pidStr = parts[0];
23023
23197
  const tsStr = parts[1];
23024
23198
  if (pidStr === void 0 || tsStr === void 0) {
23025
- fs20.unlinkSync(lockPath);
23199
+ fs21.unlinkSync(lockPath);
23026
23200
  } else {
23027
23201
  const lockPid = parseInt(pidStr, 10);
23028
23202
  const lockTs = parseInt(tsStr, 10);
23029
23203
  if (!isNaN(lockTs) && clock.now() - lockTs > 2e4) {
23030
- fs20.unlinkSync(lockPath);
23204
+ fs21.unlinkSync(lockPath);
23031
23205
  } else if (!isNaN(lockPid)) {
23032
23206
  try {
23033
23207
  process.kill(lockPid, 0);
23034
23208
  } catch {
23035
- fs20.unlinkSync(lockPath);
23209
+ fs21.unlinkSync(lockPath);
23036
23210
  }
23037
23211
  }
23038
23212
  }
23039
23213
  } catch {
23040
23214
  }
23041
23215
  try {
23042
- const fd = fs20.openSync(lockPath, "wx");
23043
- fs20.writeSync(fd, `${process.pid}
23216
+ const fd = fs21.openSync(lockPath, "wx");
23217
+ fs21.writeSync(fd, `${process.pid}
23044
23218
  ${clock.now()}`);
23045
- fs20.closeSync(fd);
23219
+ fs21.closeSync(fd);
23046
23220
  claimedLock = true;
23047
23221
  } catch (e2) {
23048
23222
  if (e2.code !== "EEXIST") {
@@ -23051,8 +23225,8 @@ ${clock.now()}`);
23051
23225
  }
23052
23226
  const logPath = path24.join(configDir, "daemon.log");
23053
23227
  if (claimedLock) {
23054
- const out2 = fs20.openSync(logPath, "a");
23055
- const err = fs20.openSync(logPath, "a");
23228
+ const out2 = fs21.openSync(logPath, "a");
23229
+ const err = fs21.openSync(logPath, "a");
23056
23230
  const child = spawner(process.execPath, [process.argv[1] ?? ""], {
23057
23231
  detached: true,
23058
23232
  stdio: ["ignore", out2, err],
@@ -23087,18 +23261,18 @@ ${clock.now()}`);
23087
23261
  } finally {
23088
23262
  if (claimedLock) {
23089
23263
  try {
23090
- fs20.unlinkSync(lockPath);
23264
+ fs21.unlinkSync(lockPath);
23091
23265
  } catch {
23092
23266
  }
23093
23267
  }
23094
23268
  }
23095
23269
  }
23096
- var import_child_process4, fs20, path24, http5, OWNERSHIP_PROBE_PATH;
23270
+ var import_child_process4, fs21, path24, http5, OWNERSHIP_PROBE_PATH;
23097
23271
  var init_startCommand = __esm({
23098
23272
  "src/server/cli/startCommand.ts"() {
23099
23273
  "use strict";
23100
23274
  import_child_process4 = require("child_process");
23101
- fs20 = __toESM(require("fs"));
23275
+ fs21 = __toESM(require("fs"));
23102
23276
  path24 = __toESM(require("path"));
23103
23277
  http5 = __toESM(require("http"));
23104
23278
  init_grainHome();
@@ -23140,7 +23314,7 @@ var init_localBrowserPaths = __esm({
23140
23314
  function findPackageRoot(startDir) {
23141
23315
  let dir3 = startDir;
23142
23316
  for (let i = 0; i < 8; i++) {
23143
- if (fs21.existsSync(path25.join(dir3, "package.json"))) {
23317
+ if (fs22.existsSync(path25.join(dir3, "package.json"))) {
23144
23318
  return dir3;
23145
23319
  }
23146
23320
  const parent = path25.dirname(dir3);
@@ -23154,17 +23328,17 @@ function findPackageRoot(startDir) {
23154
23328
  function readDaemonVersion() {
23155
23329
  try {
23156
23330
  const pkgPath = path25.join(findPackageRoot(__dirname), "package.json");
23157
- const pkg = JSON.parse(fs21.readFileSync(pkgPath, "utf8"));
23331
+ const pkg = JSON.parse(fs22.readFileSync(pkgPath, "utf8"));
23158
23332
  return pkg.version ?? null;
23159
23333
  } catch {
23160
23334
  return null;
23161
23335
  }
23162
23336
  }
23163
- var fs21, path25;
23337
+ var fs22, path25;
23164
23338
  var init_daemonVersion = __esm({
23165
23339
  "src/server/daemonVersion.ts"() {
23166
23340
  "use strict";
23167
- fs21 = __toESM(require("fs"));
23341
+ fs22 = __toESM(require("fs"));
23168
23342
  path25 = __toESM(require("path"));
23169
23343
  }
23170
23344
  });
@@ -45701,7 +45875,7 @@ var require_view = __commonJS({
45701
45875
  "use strict";
45702
45876
  var debug = require_src()("express:view");
45703
45877
  var path46 = require("node:path");
45704
- var fs44 = require("node:fs");
45878
+ var fs45 = require("node:fs");
45705
45879
  var dirname16 = path46.dirname;
45706
45880
  var basename5 = path46.basename;
45707
45881
  var extname = path46.extname;
@@ -45781,7 +45955,7 @@ var require_view = __commonJS({
45781
45955
  function tryStat(path47) {
45782
45956
  debug('stat "%s"', path47);
45783
45957
  try {
45784
- return fs44.statSync(path47);
45958
+ return fs45.statSync(path47);
45785
45959
  } catch (e2) {
45786
45960
  return void 0;
45787
45961
  }
@@ -77968,7 +78142,7 @@ var require_send = __commonJS({
77968
78142
  var escapeHtml2 = require_escape_html();
77969
78143
  var etag = require_etag();
77970
78144
  var fresh = require_fresh();
77971
- var fs44 = require("fs");
78145
+ var fs45 = require("fs");
77972
78146
  var mime = require_mime_types4();
77973
78147
  var ms = require_ms();
77974
78148
  var onFinished = require_on_finished();
@@ -78251,7 +78425,7 @@ var require_send = __commonJS({
78251
78425
  var i = 0;
78252
78426
  var self2 = this;
78253
78427
  debug('stat "%s"', path47);
78254
- fs44.stat(path47, function onstat(err, stat) {
78428
+ fs45.stat(path47, function onstat(err, stat) {
78255
78429
  var pathEndsWithSep = path47[path47.length - 1] === sep7;
78256
78430
  if (err && err.code === "ENOENT" && !extname(path47) && !pathEndsWithSep) {
78257
78431
  return next(err);
@@ -78271,7 +78445,7 @@ var require_send = __commonJS({
78271
78445
  }
78272
78446
  var p = path47 + "." + self2._extensions[i++];
78273
78447
  debug('stat "%s"', p);
78274
- fs44.stat(p, function(err2, stat) {
78448
+ fs45.stat(p, function(err2, stat) {
78275
78449
  if (err2)
78276
78450
  return next(err2);
78277
78451
  if (stat.isDirectory())
@@ -78292,7 +78466,7 @@ var require_send = __commonJS({
78292
78466
  }
78293
78467
  var p = join37(path47, self2._index[i]);
78294
78468
  debug('stat "%s"', p);
78295
- fs44.stat(p, function(err2, stat) {
78469
+ fs45.stat(p, function(err2, stat) {
78296
78470
  if (err2)
78297
78471
  return next(err2);
78298
78472
  if (stat.isDirectory())
@@ -78306,7 +78480,7 @@ var require_send = __commonJS({
78306
78480
  SendStream.prototype.stream = function stream4(path47, options) {
78307
78481
  var self2 = this;
78308
78482
  var res = this.res;
78309
- var stream5 = fs44.createReadStream(path47, options);
78483
+ var stream5 = fs45.createReadStream(path47, options);
78310
78484
  this.emit("stream", stream5);
78311
78485
  stream5.pipe(res);
78312
78486
  function cleanup() {
@@ -79198,13 +79372,13 @@ function endpointExists(endpoint) {
79198
79372
  if (isWindowsNamedPipe(endpoint)) {
79199
79373
  return true;
79200
79374
  }
79201
- return fs22.existsSync(endpoint);
79375
+ return fs23.existsSync(endpoint);
79202
79376
  }
79203
- var fs22, os6, path26, import_crypto5, UNIX_SOCKET_PATH_MAX_BYTES, SOCKET_BASENAME, PRIVATE_SOCKET_BASENAME_LENGTH;
79377
+ var fs23, os6, path26, import_crypto5, UNIX_SOCKET_PATH_MAX_BYTES, SOCKET_BASENAME, PRIVATE_SOCKET_BASENAME_LENGTH;
79204
79378
  var init_ipcEndpoint = __esm({
79205
79379
  "src/common/ipcEndpoint.ts"() {
79206
79380
  "use strict";
79207
- fs22 = __toESM(require("fs"));
79381
+ fs23 = __toESM(require("fs"));
79208
79382
  os6 = __toESM(require("os"));
79209
79383
  path26 = __toESM(require("path"));
79210
79384
  import_crypto5 = require("crypto");
@@ -79344,11 +79518,11 @@ var init_ConnectorRegistry = __esm({
79344
79518
  });
79345
79519
 
79346
79520
  // src/services/DriverManager.ts
79347
- var fs23, path27, DriverManager;
79521
+ var fs24, path27, DriverManager;
79348
79522
  var init_DriverManager = __esm({
79349
79523
  "src/services/DriverManager.ts"() {
79350
79524
  "use strict";
79351
- fs23 = __toESM(require("fs"));
79525
+ fs24 = __toESM(require("fs"));
79352
79526
  path27 = __toESM(require("path"));
79353
79527
  DriverManager = class {
79354
79528
  constructor(configDir, driverResolver) {
@@ -79367,7 +79541,7 @@ var init_DriverManager = __esm({
79367
79541
  }
79368
79542
  if (this.configDir) {
79369
79543
  const driverPath = path27.join(this.configDir, "drivers", "node_modules", driverName);
79370
- if (fs23.existsSync(driverPath)) {
79544
+ if (fs24.existsSync(driverPath)) {
79371
79545
  return driverPath;
79372
79546
  }
79373
79547
  }
@@ -79378,7 +79552,7 @@ var init_DriverManager = __esm({
79378
79552
  */
79379
79553
  async getConnectorExecutablePath(connectorType, customPath) {
79380
79554
  if (customPath) {
79381
- if (path27.isAbsolute(customPath) && fs23.existsSync(customPath)) {
79555
+ if (path27.isAbsolute(customPath) && fs24.existsSync(customPath)) {
79382
79556
  return customPath;
79383
79557
  }
79384
79558
  throw new Error(`Custom connector executable not found at path: ${customPath}`);
@@ -79404,7 +79578,7 @@ var init_DriverManager = __esm({
79404
79578
  path27.join(__dirname, "..", "..", "..", "packages", executableName, "dist", "cli.js")
79405
79579
  ];
79406
79580
  for (const p of possiblePaths) {
79407
- if (fs23.existsSync(p)) {
79581
+ if (fs24.existsSync(p)) {
79408
79582
  return p;
79409
79583
  }
79410
79584
  }
@@ -79815,11 +79989,11 @@ var src_exports = {};
79815
79989
  __export(src_exports, {
79816
79990
  default: () => DuckDbConnector
79817
79991
  });
79818
- var fs24, import_connector_api, DuckDbConnector;
79992
+ var fs25, import_connector_api, DuckDbConnector;
79819
79993
  var init_src = __esm({
79820
79994
  "packages/sql-preview-duckdb/src/index.ts"() {
79821
79995
  "use strict";
79822
- fs24 = __toESM(require("fs"));
79996
+ fs25 = __toESM(require("fs"));
79823
79997
  import_connector_api = __toESM(require_dist2());
79824
79998
  init_descriptor();
79825
79999
  DuckDbConnector = class {
@@ -79890,7 +80064,7 @@ var init_src = __esm({
79890
80064
  }
79891
80065
  if (config2.mounts) {
79892
80066
  for (const filePath of Object.values(config2.mounts)) {
79893
- if (!fs24.existsSync(filePath)) {
80067
+ if (!fs25.existsSync(filePath)) {
79894
80068
  }
79895
80069
  }
79896
80070
  }
@@ -79937,12 +80111,18 @@ var init_src = __esm({
79937
80111
  }
79938
80112
  if (cell !== null && typeof cell === "object") {
79939
80113
  const c = cell;
80114
+ if (typeof c.toDouble === "function" && typeof c.width === "number") {
80115
+ return c.width <= 15 ? c.toDouble() : c.toString();
80116
+ }
79940
80117
  if (typeof c.days === "number") {
79941
80118
  return typeof c.toString === "function" ? c.toString() : new Date(c.days * 864e5).toISOString().slice(0, 10);
79942
80119
  }
79943
80120
  if (c.micros !== void 0) {
79944
80121
  return typeof c.toString === "function" ? c.toString() : new Date(Number(c.micros) / 1e3).toISOString().replace("T", " ").slice(0, 19);
79945
80122
  }
80123
+ if (typeof c.toString === "function" && c.toString !== Object.prototype.toString) {
80124
+ return c.toString();
80125
+ }
79946
80126
  }
79947
80127
  return cell;
79948
80128
  })
@@ -90196,7 +90376,7 @@ var require_form_data = __commonJS({
90196
90376
  var http9 = require("http");
90197
90377
  var https6 = require("https");
90198
90378
  var parseUrl2 = require("url").parse;
90199
- var fs44 = require("fs");
90379
+ var fs45 = require("fs");
90200
90380
  var Stream = require("stream").Stream;
90201
90381
  var crypto19 = require("crypto");
90202
90382
  var mime = require_mime_types5();
@@ -90263,7 +90443,7 @@ var require_form_data = __commonJS({
90263
90443
  if (value.end != void 0 && value.end != Infinity && value.start != void 0) {
90264
90444
  callback(null, value.end + 1 - (value.start ? value.start : 0));
90265
90445
  } else {
90266
- fs44.stat(value.path, function(err, stat) {
90446
+ fs45.stat(value.path, function(err, stat) {
90267
90447
  if (err) {
90268
90448
  callback(err);
90269
90449
  return;
@@ -97674,11 +97854,11 @@ var src_exports4 = {};
97674
97854
  __export(src_exports4, {
97675
97855
  default: () => SQLiteConnector
97676
97856
  });
97677
- var fs25, import_connector_api4, SQLiteConnector;
97857
+ var fs26, import_connector_api4, SQLiteConnector;
97678
97858
  var init_src4 = __esm({
97679
97859
  "packages/sql-preview-sqlite/src/index.ts"() {
97680
97860
  "use strict";
97681
- fs25 = __toESM(require("fs"));
97861
+ fs26 = __toESM(require("fs"));
97682
97862
  import_connector_api4 = __toESM(require_dist2());
97683
97863
  init_descriptor4();
97684
97864
  SQLiteConnector = class {
@@ -97712,7 +97892,7 @@ var init_src4 = __esm({
97712
97892
  if (!this.db) {
97713
97893
  let fileBuffer;
97714
97894
  try {
97715
- fileBuffer = await fs25.promises.readFile(databasePath);
97895
+ fileBuffer = await fs26.promises.readFile(databasePath);
97716
97896
  } catch (err) {
97717
97897
  throw new import_connector_api4.ConnectionError(`Failed to load SQLite file at ${databasePath}: ${err.message}`);
97718
97898
  }
@@ -99916,11 +100096,11 @@ var init_BuiltInProfileStore = __esm({
99916
100096
  });
99917
100097
 
99918
100098
  // src/server/connection/FileProfileStore.ts
99919
- var fs26, path28, FileProfileStore;
100099
+ var fs27, path28, FileProfileStore;
99920
100100
  var init_FileProfileStore = __esm({
99921
100101
  "src/server/connection/FileProfileStore.ts"() {
99922
100102
  "use strict";
99923
- fs26 = __toESM(require("fs"));
100103
+ fs27 = __toESM(require("fs"));
99924
100104
  path28 = __toESM(require("path"));
99925
100105
  init_ConsoleLogger();
99926
100106
  init_grainHome();
@@ -99932,20 +100112,20 @@ var init_FileProfileStore = __esm({
99932
100112
  this.ensureConfigExists();
99933
100113
  }
99934
100114
  ensureConfigExists() {
99935
- if (!fs26.existsSync(this.configPath)) {
100115
+ if (!fs27.existsSync(this.configPath)) {
99936
100116
  const dir3 = path28.dirname(this.configPath);
99937
- if (!fs26.existsSync(dir3)) {
99938
- fs26.mkdirSync(dir3, { recursive: true });
100117
+ if (!fs27.existsSync(dir3)) {
100118
+ fs27.mkdirSync(dir3, { recursive: true });
99939
100119
  }
99940
100120
  this.writeConfig({ connections: [] });
99941
100121
  }
99942
100122
  }
99943
100123
  readConfig() {
99944
100124
  try {
99945
- if (!fs26.existsSync(this.configPath)) {
100125
+ if (!fs27.existsSync(this.configPath)) {
99946
100126
  return { connections: [] };
99947
100127
  }
99948
- const raw = fs26.readFileSync(this.configPath, "utf8");
100128
+ const raw = fs27.readFileSync(this.configPath, "utf8");
99949
100129
  return JSON.parse(raw);
99950
100130
  } catch (error52) {
99951
100131
  logger.error("Failed to read config:", error52);
@@ -99953,7 +100133,7 @@ var init_FileProfileStore = __esm({
99953
100133
  }
99954
100134
  }
99955
100135
  writeConfig(config2) {
99956
- fs26.writeFileSync(this.configPath, JSON.stringify(config2, null, 2), "utf8");
100136
+ fs27.writeFileSync(this.configPath, JSON.stringify(config2, null, 2), "utf8");
99957
100137
  }
99958
100138
  async loadProfiles() {
99959
100139
  const config2 = this.readConfig();
@@ -100005,18 +100185,18 @@ var init_MemoryCredentialStore = __esm({
100005
100185
  });
100006
100186
 
100007
100187
  // src/server/connection/FileCredentialStore.ts
100008
- var fs27, path29, FileCredentialStore;
100188
+ var fs28, path29, FileCredentialStore;
100009
100189
  var init_FileCredentialStore = __esm({
100010
100190
  "src/server/connection/FileCredentialStore.ts"() {
100011
100191
  "use strict";
100012
- fs27 = __toESM(require("fs"));
100192
+ fs28 = __toESM(require("fs"));
100013
100193
  path29 = __toESM(require("path"));
100014
100194
  init_ConsoleLogger();
100015
100195
  FileCredentialStore = class {
100016
100196
  constructor(configDir) {
100017
100197
  this.credentialsPath = path29.join(configDir, "credentials.json");
100018
- if (!fs27.existsSync(configDir)) {
100019
- fs27.mkdirSync(configDir, { recursive: true });
100198
+ if (!fs28.existsSync(configDir)) {
100199
+ fs28.mkdirSync(configDir, { recursive: true });
100020
100200
  }
100021
100201
  }
100022
100202
  async getPassword(profileId) {
@@ -100037,10 +100217,10 @@ var init_FileCredentialStore = __esm({
100037
100217
  }
100038
100218
  readMap() {
100039
100219
  try {
100040
- if (!fs27.existsSync(this.credentialsPath)) {
100220
+ if (!fs28.existsSync(this.credentialsPath)) {
100041
100221
  return {};
100042
100222
  }
100043
- const raw = fs27.readFileSync(this.credentialsPath, "utf8");
100223
+ const raw = fs28.readFileSync(this.credentialsPath, "utf8");
100044
100224
  const parsed = JSON.parse(raw);
100045
100225
  return parsed && typeof parsed === "object" ? parsed : {};
100046
100226
  } catch (error52) {
@@ -100053,9 +100233,9 @@ var init_FileCredentialStore = __esm({
100053
100233
  }
100054
100234
  writeMap(map4) {
100055
100235
  const tmpPath = `${this.credentialsPath}.tmp-${process.pid}-${Date.now()}`;
100056
- fs27.writeFileSync(tmpPath, JSON.stringify(map4, null, 2), { mode: 384 });
100057
- fs27.renameSync(tmpPath, this.credentialsPath);
100058
- fs27.chmodSync(this.credentialsPath, 384);
100236
+ fs28.writeFileSync(tmpPath, JSON.stringify(map4, null, 2), { mode: 384 });
100237
+ fs28.renameSync(tmpPath, this.credentialsPath);
100238
+ fs28.chmodSync(this.credentialsPath, 384);
100059
100239
  }
100060
100240
  };
100061
100241
  }
@@ -100114,7 +100294,7 @@ var init_ExtensionCredentialStore = __esm({
100114
100294
  { method: CREDENTIAL_GET_METHOD, params: { profileId } },
100115
100295
  CredentialGetResultSchema
100116
100296
  );
100117
- return result.password;
100297
+ return result.password ?? this.fallback.getPassword(profileId);
100118
100298
  } catch (error52) {
100119
100299
  logger.warn(
100120
100300
  `[ExtensionCredentialStore] Channel unavailable for getPassword(${profileId}); falling back to file store`,
@@ -100329,7 +100509,7 @@ var init_KeychainCredentialStore = __esm({
100329
100509
  [SERVICE_NAME, profileId],
100330
100510
  this.timeoutMs
100331
100511
  );
100332
- return typeof password === "string" ? password : void 0;
100512
+ return typeof password === "string" ? password : this.fallback.getPassword(profileId);
100333
100513
  } catch (error52) {
100334
100514
  if (error52 instanceof KeychainTimeoutError) {
100335
100515
  throw error52;
@@ -101069,6 +101249,7 @@ var init_classifyQueryError = __esm({
101069
101249
  /configuration error/,
101070
101250
  /no valid connection profile/,
101071
101251
  /connection ['"].*['"] not found/,
101252
+ /connection ['"].*['"] no longer exists/,
101072
101253
  /invalid connection/,
101073
101254
  /missing required (?:field|option|setting)/,
101074
101255
  /databasepath .*(?:required|missing|empty)/
@@ -101556,13 +101737,26 @@ var init_QueryOperationRunner = __esm({
101556
101737
  sql
101557
101738
  };
101558
101739
  }
101740
+ getNextResultNumber(session) {
101741
+ let maxCount = 0;
101742
+ session.tabs.forEach((tab) => {
101743
+ const match = tab.title.match(/^Result (\d+)$/);
101744
+ if (match && match[1]) {
101745
+ const count2 = parseInt(match[1], 10);
101746
+ if (count2 > maxCount) {
101747
+ maxCount = count2;
101748
+ }
101749
+ }
101750
+ });
101751
+ return maxCount + 1;
101752
+ }
101559
101753
  resolveTab(session, providedTabId, shouldCreateNewTab, providedTitle) {
101560
101754
  if (providedTabId) {
101561
101755
  const tab = session.tabs.get(providedTabId);
101562
101756
  return {
101563
101757
  tab,
101564
101758
  tabId: providedTabId,
101565
- tabTitle: providedTitle || tab?.title || `Result ${session.tabs.size + 1}`
101759
+ tabTitle: providedTitle || tab?.title || `Result ${this.getNextResultNumber(session)}`
101566
101760
  };
101567
101761
  }
101568
101762
  if (!shouldCreateNewTab && session.activeTabId) {
@@ -101578,7 +101772,7 @@ var init_QueryOperationRunner = __esm({
101578
101772
  return {
101579
101773
  tab: void 0,
101580
101774
  tabId: `t${Math.random().toString(36).substring(2, 10)}`,
101581
- tabTitle: providedTitle || `Result ${session.tabs.size + 1}`
101775
+ tabTitle: providedTitle || `Result ${this.getNextResultNumber(session)}`
101582
101776
  };
101583
101777
  }
101584
101778
  async executeAndStore(sessionId, tabId, sql, connectionId, connectionProfile, authHeader, controller, origin2, loadAllRows, enforceReadOnly, clientConsent, workspaceRoot) {
@@ -102822,6 +103016,29 @@ function classifyForHumanGate(sql, dialect) {
102822
103016
  const classification = classifyStatement(sql, dialect);
102823
103017
  return classification.kind === "write" || classification.kind === "multi_statement" ? { kind: "confirm", classification } : { kind: "allow", classification };
102824
103018
  }
103019
+ function humanConfirmationFor(sql, dialect) {
103020
+ const verdict = classifyForHumanGate(sql, dialect);
103021
+ if (verdict.kind !== "confirm") {
103022
+ return void 0;
103023
+ }
103024
+ const classification = verdict.classification;
103025
+ if (classification.kind === "write") {
103026
+ return {
103027
+ message: `Confirmation required for write statement (${classification.keyword}).`,
103028
+ confirmation: { kind: "write", keyword: classification.keyword }
103029
+ };
103030
+ }
103031
+ if (classification.kind === "multi_statement") {
103032
+ return {
103033
+ message: `Confirmation required for multi-statement query (${classification.count} statements).`,
103034
+ confirmation: { kind: "multi_statement", count: classification.count }
103035
+ };
103036
+ }
103037
+ return {
103038
+ message: "Confirmation required because the connection dialect could not be resolved.",
103039
+ confirmation: { kind: "unknown_dialect" }
103040
+ };
103041
+ }
102825
103042
  var WRITE_KEYWORDS, READ_ONLY_START_KEYWORDS;
102826
103043
  var init_sqlPolicy = __esm({
102827
103044
  "src/common/sqlPolicy.ts"() {
@@ -115850,7 +116067,7 @@ function vRatio(u, v) {
115850
116067
  function vAngle(u, v) {
115851
116068
  return (u[0] * v[1] < u[1] * v[0] ? -1 : 1) * Math.acos(vRatio(u, v));
115852
116069
  }
115853
- function processArc(x1, y1, x2, y2, fa, fs44, rx, ry, psiDeg, cmd, path46) {
116070
+ function processArc(x1, y1, x2, y2, fa, fs45, rx, ry, psiDeg, cmd, path46) {
115854
116071
  var psi = psiDeg * (PI3 / 180);
115855
116072
  var xp = mathCos3(psi) * (x1 - x2) / 2 + mathSin3(psi) * (y1 - y2) / 2;
115856
116073
  var yp = -1 * mathSin3(psi) * (x1 - x2) / 2 + mathCos3(psi) * (y1 - y2) / 2;
@@ -115859,7 +116076,7 @@ function processArc(x1, y1, x2, y2, fa, fs44, rx, ry, psiDeg, cmd, path46) {
115859
116076
  rx *= mathSqrt3(lambda);
115860
116077
  ry *= mathSqrt3(lambda);
115861
116078
  }
115862
- var f = (fa === fs44 ? -1 : 1) * mathSqrt3((rx * rx * (ry * ry) - rx * rx * (yp * yp) - ry * ry * (xp * xp)) / (rx * rx * (yp * yp) + ry * ry * (xp * xp))) || 0;
116079
+ var f = (fa === fs45 ? -1 : 1) * mathSqrt3((rx * rx * (ry * ry) - rx * rx * (yp * yp) - ry * ry * (xp * xp)) / (rx * rx * (yp * yp) + ry * ry * (xp * xp))) || 0;
115863
116080
  var cxp = f * rx * yp / ry;
115864
116081
  var cyp = f * -ry * xp / rx;
115865
116082
  var cx = (x1 + x2) / 2 + mathCos3(psi) * cxp - mathSin3(psi) * cyp;
@@ -115878,7 +116095,7 @@ function processArc(x1, y1, x2, y2, fa, fs44, rx, ry, psiDeg, cmd, path46) {
115878
116095
  var n = Math.round(dTheta / PI3 * 1e6) / 1e6;
115879
116096
  dTheta = PI3 * 2 + n % 2 * PI3;
115880
116097
  }
115881
- path46.addData(cmd, cx, cy, rx, ry, theta, dTheta, psi, fs44);
116098
+ path46.addData(cmd, cx, cy, rx, ry, theta, dTheta, psi, fs45);
115882
116099
  }
115883
116100
  function createPathProxyFromString(data) {
115884
116101
  var path46 = new PathProxy_default();
@@ -115912,7 +116129,7 @@ function createPathProxyFromString(data) {
115912
116129
  var ry = void 0;
115913
116130
  var psi = void 0;
115914
116131
  var fa = void 0;
115915
- var fs44 = void 0;
116132
+ var fs45 = void 0;
115916
116133
  var x1 = cpx;
115917
116134
  var y1 = cpy;
115918
116135
  var len2 = void 0;
@@ -116061,24 +116278,24 @@ function createPathProxyFromString(data) {
116061
116278
  ry = p[off++];
116062
116279
  psi = p[off++];
116063
116280
  fa = p[off++];
116064
- fs44 = p[off++];
116281
+ fs45 = p[off++];
116065
116282
  x1 = cpx, y1 = cpy;
116066
116283
  cpx = p[off++];
116067
116284
  cpy = p[off++];
116068
116285
  cmd = CMD6.A;
116069
- processArc(x1, y1, cpx, cpy, fa, fs44, rx, ry, psi, cmd, path46);
116286
+ processArc(x1, y1, cpx, cpy, fa, fs45, rx, ry, psi, cmd, path46);
116070
116287
  break;
116071
116288
  case "a":
116072
116289
  rx = p[off++];
116073
116290
  ry = p[off++];
116074
116291
  psi = p[off++];
116075
116292
  fa = p[off++];
116076
- fs44 = p[off++];
116293
+ fs45 = p[off++];
116077
116294
  x1 = cpx, y1 = cpy;
116078
116295
  cpx += p[off++];
116079
116296
  cpy += p[off++];
116080
116297
  cmd = CMD6.A;
116081
- processArc(x1, y1, cpx, cpy, fa, fs44, rx, ry, psi, cmd, path46);
116298
+ processArc(x1, y1, cpx, cpy, fa, fs45, rx, ry, psi, cmd, path46);
116082
116299
  break;
116083
116300
  }
116084
116301
  }
@@ -182971,11 +183188,11 @@ var init_ChartSsrRenderer = __esm({
182971
183188
  });
182972
183189
 
182973
183190
  // src/server/charts/ChartDocumentStore.ts
182974
- var fs28, path31, ChartDocumentStore;
183191
+ var fs29, path31, ChartDocumentStore;
182975
183192
  var init_ChartDocumentStore = __esm({
182976
183193
  "src/server/charts/ChartDocumentStore.ts"() {
182977
183194
  "use strict";
182978
- fs28 = __toESM(require("fs/promises"));
183195
+ fs29 = __toESM(require("fs/promises"));
182979
183196
  path31 = __toESM(require("path"));
182980
183197
  init_ChartSpecV1();
182981
183198
  ChartDocumentStore = class {
@@ -183012,8 +183229,8 @@ var init_ChartDocumentStore = __esm({
183012
183229
  if (!target.endsWith(".chart.yml") && !target.endsWith(".chart.yaml")) {
183013
183230
  throw new Error("Chart path must end in .chart.yml or .chart.yaml");
183014
183231
  }
183015
- await fs28.mkdir(path31.dirname(target), { recursive: true });
183016
- await fs28.writeFile(target, `${JSON.stringify(validation.spec, null, 2)}
183232
+ await fs29.mkdir(path31.dirname(target), { recursive: true });
183233
+ await fs29.writeFile(target, `${JSON.stringify(validation.spec, null, 2)}
183017
183234
  `, "utf8");
183018
183235
  return path31.relative(this.workspaceRoot, target);
183019
183236
  }
@@ -183034,7 +183251,7 @@ var init_ChartDocumentStore = __esm({
183034
183251
  async readDirectory(directory) {
183035
183252
  let entries;
183036
183253
  try {
183037
- entries = await fs28.readdir(directory, { withFileTypes: true });
183254
+ entries = await fs29.readdir(directory, { withFileTypes: true });
183038
183255
  } catch (error52) {
183039
183256
  if (error52.code === "ENOENT") {
183040
183257
  return [];
@@ -183047,7 +183264,7 @@ var init_ChartDocumentStore = __esm({
183047
183264
  if (entry.isDirectory()) {
183048
183265
  results.push(...await this.readDirectory(child));
183049
183266
  } else if (/\.chart\.ya?ml$/i.test(entry.name)) {
183050
- const validation = validateChartSpec(JSON.parse(await fs28.readFile(child, "utf8")));
183267
+ const validation = validateChartSpec(JSON.parse(await fs29.readFile(child, "utf8")));
183051
183268
  if (validation.valid) {
183052
183269
  results.push({
183053
183270
  path: path31.relative(this.workspaceRoot, child),
@@ -183171,6 +183388,24 @@ var init_DaemonMcpToolManager = __esm({
183171
183388
  get isConfirmWrites() {
183172
183389
  return this.confirmWrites;
183173
183390
  }
183391
+ async humanWriteConfirmation(sql, connectionId, clientConsent) {
183392
+ if (!this.confirmWrites) {
183393
+ return void 0;
183394
+ }
183395
+ let dialect = "unknown";
183396
+ try {
183397
+ const profile = await this.queryExecutor.resolveProfile(
183398
+ sql,
183399
+ connectionId,
183400
+ void 0,
183401
+ clientConsent
183402
+ );
183403
+ dialect = isConnectorType(profile?.type) ? profile.type : "unknown";
183404
+ } catch {
183405
+ dialect = "unknown";
183406
+ }
183407
+ return humanConfirmationFor(sql, dialect);
183408
+ }
183174
183409
  /** Updates human write confirmation requirement live (e.g. from a settings-panel save). */
183175
183410
  setConfirmWrites(value) {
183176
183411
  this.confirmWrites = value;
@@ -183199,7 +183434,7 @@ var init_DaemonMcpToolManager = __esm({
183199
183434
  * received from the client.
183200
183435
  */
183201
183436
  captureUiEvent(event, properties, clientConsent) {
183202
- this.options.telemetry?.capture(event, properties, clientConsent);
183437
+ this.options.telemetry?.capture(event, { state: "unknown", ...properties }, clientConsent);
183203
183438
  }
183204
183439
  /** False for an alpha tool whose feature flag is off; such a tool is unlisted and uncallable. */
183205
183440
  isToolEnabled(name) {
@@ -183265,7 +183500,11 @@ var init_DaemonMcpToolManager = __esm({
183265
183500
  const success2 = thrown === void 0 && resultRecord?.isError !== true;
183266
183501
  let errorKind;
183267
183502
  let errorId;
183503
+ let errorCode;
183504
+ let errorClass;
183268
183505
  if (!success2) {
183506
+ errorCode = thrown !== void 0 ? diagnosticErrorCodeOf(thrown) : normalizeTelemetryDiagnosticErrorCode(resultRecord?.structuredContent?.errorCode);
183507
+ errorClass = thrown !== void 0 ? diagnosticErrorClassOf(thrown) : normalizeTelemetryDiagnosticErrorClass(resultRecord?.structuredContent?.errorClass);
183269
183508
  errorKind = thrown !== void 0 ? classifyErrorLike(thrown) : typeof resultRecord?.structuredContent?.errorKind === "string" ? resultRecord.structuredContent.errorKind : "unknown";
183270
183509
  if (typeof resultRecord?.structuredContent?.errorId === "string") {
183271
183510
  errorId = resultRecord.structuredContent.errorId;
@@ -183273,21 +183512,26 @@ var init_DaemonMcpToolManager = __esm({
183273
183512
  }
183274
183513
  const profileType = args;
183275
183514
  const connectorSource = typeof profileType?.connectionProfile?.type === "string" ? profileType.connectionProfile.type : typeof profileType?.type === "string" ? profileType.type : void 0;
183515
+ const invoked = {
183516
+ state: "mcp_server",
183517
+ source: "mcp",
183518
+ // Which agent transport this arrived on. Gating emission on origin without
183519
+ // recording it left RFC-082's rollout unmeasurable (#113).
183520
+ origin: origin2,
183521
+ mcp_client: clientLabel,
183522
+ tool_name: normalizeTelemetryToolName(name),
183523
+ success: success2,
183524
+ duration_bucket: bucketDurationMs(Date.now() - startedAt),
183525
+ ...connectorSource !== void 0 ? { connector: normalizeTelemetryConnector(connectorSource) } : {}
183526
+ };
183276
183527
  telemetry.capture(
183277
183528
  "mcp_tool_invoked",
183278
- {
183279
- state: "mcp_server",
183280
- source: "mcp",
183281
- // Which agent transport this arrived on. Gating emission on origin without
183282
- // recording it left RFC-082's rollout unmeasurable (#113).
183283
- origin: origin2,
183284
- mcp_client: clientLabel,
183285
- tool_name: normalizeTelemetryToolName(name),
183286
- success: success2,
183287
- duration_bucket: bucketDurationMs(Date.now() - startedAt),
183288
- ...errorKind !== void 0 ? { error_kind: errorKind } : {},
183289
- ...errorId !== void 0 ? { error_id: errorId } : {},
183290
- ...connectorSource !== void 0 ? { connector: normalizeTelemetryConnector(connectorSource) } : {}
183529
+ success2 ? invoked : {
183530
+ ...invoked,
183531
+ error_kind: errorKind ?? "unknown",
183532
+ ...errorCode !== void 0 ? { error_code: errorCode } : {},
183533
+ ...errorClass !== void 0 ? { error_class: errorClass } : {},
183534
+ ...errorId !== void 0 ? { error_id: errorId } : {}
183291
183535
  },
183292
183536
  clientConsent
183293
183537
  );
@@ -183311,50 +183555,33 @@ var init_DaemonMcpToolManager = __esm({
183311
183555
  const refusal = admitToolCall(profile, name, this.isToolEnabled(name));
183312
183556
  if (refusal)
183313
183557
  return refusal;
183314
- switch (name) {
183315
- case "run_query":
183316
- return this.handleRunQuery(args, origin2, profile, clientConsent);
183317
- case "get_tab_info":
183318
- return this.handleGetTabInfo(args);
183319
- case "list_sessions":
183320
- return this.handleListSessions();
183321
- case "list_connectors":
183322
- return this.handleListConnectors();
183323
- case "list_connections":
183324
- return this.handleListConnections();
183325
- case "save_connection":
183326
- return this.handleSaveConnection(args, clientConsent);
183327
- case "request_connection_credentials":
183328
- return this.handleRequestConnectionCredentials(args, clientConsent);
183329
- case "test_connection":
183330
- return this.handleTestConnection(args, origin2, clientConsent);
183331
- case "delete_connection":
183332
- return this.handleDeleteConnection(args);
183333
- case "list_schemas":
183334
- return this.handleListSchemas(args, clientConsent);
183335
- case "list_tables":
183336
- return this.handleListTables(args, clientConsent);
183337
- case "describe_table":
183338
- return this.handleDescribeTable(args, clientConsent);
183339
- case "cancel_query":
183340
- return this.handleCancelQuery(args);
183341
- case "close_tab":
183342
- return this.handleCloseTab(args);
183343
- case "render_chart":
183344
- return this.handleRenderChart(args);
183345
- case "save_chart":
183346
- return this.handleSaveChart(args, workspaceRoot);
183347
- case "list_charts":
183348
- return this.handleListCharts(workspaceRoot);
183349
- case "ledger_stats":
183350
- return this.handleLedgerStats(clientConsent);
183351
- case "verify_ledger":
183352
- return this.handleVerifyLedger(clientConsent);
183353
- case "record_ui_event":
183354
- return this.handleRecordUiEvent(args, clientConsent);
183355
- default:
183356
- throw new Error("Unknown tool");
183357
- }
183558
+ const handlers3 = {
183559
+ run_query: () => this.handleRunQuery(args, origin2, profile, clientConsent),
183560
+ get_tab_info: () => this.handleGetTabInfo(args),
183561
+ list_sessions: () => this.handleListSessions(),
183562
+ list_connectors: () => this.handleListConnectors(),
183563
+ list_connections: () => this.handleListConnections(),
183564
+ save_connection: () => this.handleSaveConnection(args, clientConsent),
183565
+ request_connection_credentials: () => this.handleRequestConnectionCredentials(args, clientConsent),
183566
+ test_connection: () => this.handleTestConnection(args, origin2, clientConsent),
183567
+ delete_connection: () => this.handleDeleteConnection(args),
183568
+ list_schemas: () => this.handleListSchemas(args, clientConsent),
183569
+ list_tables: () => this.handleListTables(args, clientConsent),
183570
+ describe_table: () => this.handleDescribeTable(args, clientConsent),
183571
+ cancel_query: () => this.handleCancelQuery(args),
183572
+ close_tab: () => this.handleCloseTab(args),
183573
+ render_chart: () => this.handleRenderChart(args),
183574
+ save_chart: () => this.handleSaveChart(args, workspaceRoot),
183575
+ list_charts: () => this.handleListCharts(workspaceRoot),
183576
+ ledger_stats: () => this.handleLedgerStats(clientConsent),
183577
+ verify_ledger: () => this.handleVerifyLedger(clientConsent),
183578
+ record_ui_event: () => this.handleRecordUiEvent(args, clientConsent)
183579
+ };
183580
+ const definition = TOOL_DEFINITIONS.find((def) => def.name === name);
183581
+ if (!definition) {
183582
+ throw new Error("Unknown tool");
183583
+ }
183584
+ return handlers3[definition.name]();
183358
183585
  }
183359
183586
  /**
183360
183587
  * RFC-088 Rung 2. The MCP app renders in an opaque-origin sandbox that cannot
@@ -183409,7 +183636,11 @@ var init_DaemonMcpToolManager = __esm({
183409
183636
  return {
183410
183637
  isError: true,
183411
183638
  content: [{ type: "text", text: e2 instanceof Error ? e2.message : String(e2) }],
183412
- structuredContent: { errorKind: classifyErrorLike(e2) }
183639
+ structuredContent: {
183640
+ errorKind: classifyErrorLike(e2),
183641
+ errorCode: diagnosticErrorCodeOf(e2),
183642
+ errorClass: diagnosticErrorClassOf(e2)
183643
+ }
183413
183644
  };
183414
183645
  }
183415
183646
  }
@@ -183431,7 +183662,11 @@ var init_DaemonMcpToolManager = __esm({
183431
183662
  return {
183432
183663
  isError: true,
183433
183664
  content: [{ type: "text", text: e2 instanceof Error ? e2.message : String(e2) }],
183434
- structuredContent: { errorKind: classifyErrorLike(e2) }
183665
+ structuredContent: {
183666
+ errorKind: classifyErrorLike(e2),
183667
+ errorCode: diagnosticErrorCodeOf(e2),
183668
+ errorClass: diagnosticErrorClassOf(e2)
183669
+ }
183435
183670
  };
183436
183671
  }
183437
183672
  }
@@ -183454,7 +183689,11 @@ var init_DaemonMcpToolManager = __esm({
183454
183689
  return {
183455
183690
  isError: true,
183456
183691
  content: [{ type: "text", text: e2 instanceof Error ? e2.message : String(e2) }],
183457
- structuredContent: { errorKind: classifyErrorLike(e2) }
183692
+ structuredContent: {
183693
+ errorKind: classifyErrorLike(e2),
183694
+ errorCode: diagnosticErrorCodeOf(e2),
183695
+ errorClass: diagnosticErrorClassOf(e2)
183696
+ }
183458
183697
  };
183459
183698
  }
183460
183699
  }
@@ -183720,9 +183959,16 @@ This link expires at ${new Date(
183720
183959
  } catch (error52) {
183721
183960
  const errorKind = classifyErrorLike(error52, typeToTest);
183722
183961
  const message = error52 instanceof Error ? error52.message : String(error52);
183962
+ const errorCode = diagnosticErrorCodeOf(error52);
183963
+ const errorClass = diagnosticErrorClassOf(error52);
183723
183964
  return this.failConnectionTest(
183724
183965
  `Connection Test Failed: ${message}`,
183725
- { errorKind, errorId: "connection_test_connection_failed" },
183966
+ {
183967
+ errorKind,
183968
+ errorId: "connection_test_connection_failed",
183969
+ ...errorCode !== void 0 ? { errorCode } : {},
183970
+ ...errorClass !== void 0 ? { errorClass } : {}
183971
+ },
183726
183972
  clientConsent
183727
183973
  );
183728
183974
  }
@@ -183741,13 +183987,21 @@ This link expires at ${new Date(
183741
183987
  if (errorKind === "config") {
183742
183988
  return this.failConnectionTest(
183743
183989
  message,
183744
- { errorKind, errorId: "connection_test_configuration_invalid" },
183990
+ {
183991
+ errorKind,
183992
+ errorId: "connection_test_configuration_invalid",
183993
+ ...result.errorCode !== void 0 ? { errorCode: result.errorCode } : {}
183994
+ },
183745
183995
  clientConsent
183746
183996
  );
183747
183997
  }
183748
183998
  return this.failConnectionTest(
183749
183999
  message,
183750
- { errorKind, errorId: "connection_test_connection_failed" },
184000
+ {
184001
+ errorKind,
184002
+ errorId: "connection_test_connection_failed",
184003
+ ...result.errorCode !== void 0 ? { errorCode: result.errorCode } : {}
184004
+ },
183751
184005
  clientConsent
183752
184006
  );
183753
184007
  }
@@ -183845,11 +184099,9 @@ This link expires at ${new Date(
183845
184099
  }
183846
184100
  }
183847
184101
  if (isHumanOrigin(origin2) && this.confirmWrites && !confirmWrite) {
183848
- const verdict = classifyForHumanGate(sql, dialect);
183849
- if (verdict.kind === "confirm") {
183850
- const classification = verdict.classification;
183851
- const message = classification.kind === "write" ? `Confirmation required for write statement (${classification.keyword}).` : classification.kind === "multi_statement" ? `Confirmation required for multi-statement query (${classification.count} statements).` : "Confirmation required because the connection dialect could not be resolved.";
183852
- const confirmation = classification.kind === "write" ? { kind: "write", keyword: classification.keyword } : classification.kind === "multi_statement" ? { kind: "multi_statement", count: classification.count } : { kind: "unknown_dialect" };
184102
+ const gate = humanConfirmationFor(sql, dialect);
184103
+ if (gate) {
184104
+ const { message, confirmation } = gate;
183853
184105
  return withQueryCallKey(
183854
184106
  {
183855
184107
  isError: true,
@@ -183912,7 +184164,9 @@ This link expires at ${new Date(
183912
184164
  status: "error",
183913
184165
  sessionId,
183914
184166
  error: message,
183915
- errorKind: classifyErrorLike(error52)
184167
+ errorKind: classifyErrorLike(error52),
184168
+ errorCode: diagnosticErrorCodeOf(error52),
184169
+ errorClass: diagnosticErrorClassOf(error52)
183916
184170
  }
183917
184171
  },
183918
184172
  callKey
@@ -183984,13 +184238,25 @@ This link expires at ${new Date(
183984
184238
  };
183985
184239
  }
183986
184240
  async handleLedgerStats(clientConsent) {
183987
- if (!this.ledger)
184241
+ if (!this.ledger) {
184242
+ this.options.telemetry?.capture(
184243
+ "ledger_health",
184244
+ {
184245
+ state: "daemon",
184246
+ outcome: "disabled",
184247
+ entries_bucket: "0",
184248
+ write_failures_bucket: "0"
184249
+ },
184250
+ clientConsent
184251
+ );
183988
184252
  return textToolResult("Ledger disabled.");
184253
+ }
183989
184254
  const stats = await this.ledger.stats();
183990
184255
  this.options.telemetry?.capture(
183991
184256
  "ledger_health",
183992
184257
  {
183993
184258
  state: "daemon",
184259
+ outcome: "enabled",
183994
184260
  entries_bucket: bucketRowCount(stats.persisted_entries),
183995
184261
  write_failures_bucket: bucketRowCount(stats.write_failures)
183996
184262
  },
@@ -183999,8 +184265,19 @@ This link expires at ${new Date(
183999
184265
  return { content: [{ type: "text", text: JSON.stringify(stats) }], structuredContent: stats };
184000
184266
  }
184001
184267
  async handleVerifyLedger(clientConsent) {
184002
- if (!this.ledger)
184268
+ if (!this.ledger) {
184269
+ this.options.telemetry?.capture(
184270
+ "ledger_verify_completed",
184271
+ {
184272
+ state: "daemon",
184273
+ outcome: "disabled",
184274
+ entries_checked_bucket: "0",
184275
+ duration_bucket: "<100ms"
184276
+ },
184277
+ clientConsent
184278
+ );
184003
184279
  return textToolResult("Ledger disabled.");
184280
+ }
184004
184281
  const startedAt = Date.now();
184005
184282
  const result = await verifyLedger(this.ledger);
184006
184283
  this.options.telemetry?.capture(
@@ -184684,6 +184961,7 @@ var init_DaemonQueryExecutor = __esm({
184684
184961
  init_optionalDrivers();
184685
184962
  init_sqlPolicy();
184686
184963
  init_classifyQueryError();
184964
+ init_TelemetrySchema();
184687
184965
  init_DaemonConfig();
184688
184966
  init_SubProcessConnectorClient();
184689
184967
  init_ConnectorProcessPool();
@@ -184872,6 +185150,15 @@ var init_DaemonQueryExecutor = __esm({
184872
185150
  }
184873
185151
  if (!profile && connectionId) {
184874
185152
  profile = await this.connectionManager.getProfile(connectionId, clientConsent);
185153
+ if (!profile) {
185154
+ throw attachErrorKind(
185155
+ new AppError(
185156
+ "query_no_connection_profile",
185157
+ `The connection '${connectionId}' no longer exists. Pick another connection and run the query again.`
185158
+ ),
185159
+ "config"
185160
+ );
185161
+ }
184875
185162
  }
184876
185163
  if (!profile) {
184877
185164
  this.logger.info(`Fetching connections for fallback...`);
@@ -185035,7 +185322,13 @@ var init_DaemonQueryExecutor = __esm({
185035
185322
  return { success: true };
185036
185323
  } catch (e2) {
185037
185324
  const message = e2 instanceof Error ? e2.message : String(e2);
185038
- return { success: false, error: message, errorKind: classifyErrorLike(e2) };
185325
+ const errorCode = diagnosticErrorCodeOf(e2);
185326
+ return {
185327
+ success: false,
185328
+ error: message,
185329
+ errorKind: classifyErrorLike(e2),
185330
+ ...errorCode !== void 0 ? { errorCode } : {}
185331
+ };
185039
185332
  }
185040
185333
  }
185041
185334
  };
@@ -192619,9 +192912,9 @@ var init_requireDaemonAuth = __esm({
192619
192912
  // src/server/surfaces/DaemonSettingsRoute.ts
192620
192913
  function persistConfigPatch(configPath, patch2) {
192621
192914
  let onDisk = {};
192622
- if (fs29.existsSync(configPath)) {
192915
+ if (fs30.existsSync(configPath)) {
192623
192916
  try {
192624
- onDisk = JSON.parse(fs29.readFileSync(configPath, "utf8"));
192917
+ onDisk = JSON.parse(fs30.readFileSync(configPath, "utf8"));
192625
192918
  } catch (err) {
192626
192919
  logger.warn(`[Daemon] Could not parse existing config at ${configPath}, overwriting:`, err);
192627
192920
  onDisk = {};
@@ -192633,7 +192926,7 @@ function persistConfigPatch(configPath, patch2) {
192633
192926
  if (patch2.mcp) {
192634
192927
  onDisk["mcp"] = { ...onDisk["mcp"], ...patch2.mcp };
192635
192928
  }
192636
- fs29.writeFileSync(configPath, JSON.stringify(onDisk, null, 2) + "\n");
192929
+ fs30.writeFileSync(configPath, JSON.stringify(onDisk, null, 2) + "\n");
192637
192930
  }
192638
192931
  function createSettingsUpdateHandler(context2) {
192639
192932
  return (req, res) => {
@@ -192695,11 +192988,11 @@ function createSettingsUpdateHandler(context2) {
192695
192988
  }
192696
192989
  };
192697
192990
  }
192698
- var fs29, SETTINGS_SAFE_MODE_DECLINED_MESSAGE, SETTINGS_CONFIRM_WRITES_DECLINED_MESSAGE;
192991
+ var fs30, SETTINGS_SAFE_MODE_DECLINED_MESSAGE, SETTINGS_CONFIRM_WRITES_DECLINED_MESSAGE;
192699
192992
  var init_DaemonSettingsRoute = __esm({
192700
192993
  "src/server/surfaces/DaemonSettingsRoute.ts"() {
192701
192994
  "use strict";
192702
- fs29 = __toESM(require("fs"));
192995
+ fs30 = __toESM(require("fs"));
192703
192996
  init_ConsoleLogger();
192704
192997
  init_requireDaemonAuth();
192705
192998
  init_ClientIdentity();
@@ -192750,13 +193043,13 @@ function distFileCandidates(fileName, baseDir = __dirname) {
192750
193043
  }
192751
193044
  function findDistFile(fileName, baseDir = __dirname) {
192752
193045
  const candidates = distFileCandidates(fileName, baseDir);
192753
- return candidates.find((candidate) => fs30.existsSync(candidate)) ?? candidates[1] ?? fileName;
193046
+ return candidates.find((candidate) => fs31.existsSync(candidate)) ?? candidates[1] ?? fileName;
192754
193047
  }
192755
- var fs30, path33;
193048
+ var fs31, path33;
192756
193049
  var init_distFiles = __esm({
192757
193050
  "src/server/surfaces/distFiles.ts"() {
192758
193051
  "use strict";
192759
- fs30 = __toESM(require("fs"));
193052
+ fs31 = __toESM(require("fs"));
192760
193053
  path33 = __toESM(require("path"));
192761
193054
  }
192762
193055
  });
@@ -193327,6 +193620,22 @@ async function handleQueryRoute(context2, req, res, options) {
193327
193620
  res.status(400).json({ error: options.missingQueryMessage });
193328
193621
  return;
193329
193622
  }
193623
+ const connectionId = options.supportsConnectionId && typeof body.connectionId === "string" ? body.connectionId : void 0;
193624
+ if (body.confirmWrite !== true) {
193625
+ const gate = await context2.toolManager.humanWriteConfirmation(
193626
+ query,
193627
+ connectionId,
193628
+ profiles.consent
193629
+ );
193630
+ if (gate) {
193631
+ res.status(409).json({
193632
+ status: "confirmation_required",
193633
+ error: gate.message,
193634
+ confirmation: gate.confirmation
193635
+ });
193636
+ return;
193637
+ }
193638
+ }
193330
193639
  const sessionId = typeof body.sessionId === "string" && body.sessionId.length > 0 ? body.sessionId : `${options.sessionPrefix}-${import_crypto11.default.randomUUID()}`;
193331
193640
  const controller = new AbortController();
193332
193641
  const cleanupDisconnectAbort = attachAbortOnHttpDisconnect(
@@ -193347,7 +193656,7 @@ async function handleQueryRoute(context2, req, res, options) {
193347
193656
  origin: "http_api",
193348
193657
  ...isSafeModeActive(policy.profile, context2.resolvedConfig.config.mcp.safeMode) ? { enforceReadOnly: true } : {},
193349
193658
  ...typeof body.tabId === "string" ? { tabId: body.tabId } : {},
193350
- ...options.supportsConnectionId && typeof body.connectionId === "string" ? { connectionId: body.connectionId } : {},
193659
+ ...connectionId !== void 0 ? { connectionId } : {},
193351
193660
  clientConsent: profiles.consent
193352
193661
  })
193353
193662
  );
@@ -193400,12 +193709,12 @@ function sendQueryResult(res, result) {
193400
193709
  function serveHtmlFile(res, fileName, notFoundMessage) {
193401
193710
  try {
193402
193711
  const htmlPath = findDistFile(fileName);
193403
- if (!fs31.existsSync(htmlPath)) {
193712
+ if (!fs32.existsSync(htmlPath)) {
193404
193713
  res.status(404).send(notFoundMessage);
193405
193714
  return;
193406
193715
  }
193407
193716
  res.setHeader("Content-Type", "text/html");
193408
- fs31.createReadStream(htmlPath).pipe(res);
193717
+ fs32.createReadStream(htmlPath).pipe(res);
193409
193718
  } catch (err) {
193410
193719
  logger.error(`[Daemon] Failed to serve ${fileName}:`, err);
193411
193720
  res.status(500).send("Internal Server Error");
@@ -193477,13 +193786,13 @@ function escapeHtml(value) {
193477
193786
  }
193478
193787
  });
193479
193788
  }
193480
- var import_crypto11, import_express, fs31, WEB_APP_CSP_DIRECTIVES, webProxiedTools;
193789
+ var import_crypto11, import_express, fs32, WEB_APP_CSP_DIRECTIVES, webProxiedTools;
193481
193790
  var init_DaemonHttpRoutes = __esm({
193482
193791
  "src/server/surfaces/DaemonHttpRoutes.ts"() {
193483
193792
  "use strict";
193484
193793
  import_crypto11 = __toESM(require("crypto"));
193485
193794
  import_express = __toESM(require_express2());
193486
- fs31 = __toESM(require("fs"));
193795
+ fs32 = __toESM(require("fs"));
193487
193796
  init_ConsoleLogger();
193488
193797
  init_httpAbort();
193489
193798
  init_toolProfiles();
@@ -203328,12 +203637,12 @@ var require_dist3 = __commonJS({
203328
203637
  throw new Error(`Unknown format "${name}"`);
203329
203638
  return f;
203330
203639
  };
203331
- function addFormats(ajv, list, fs44, exportName) {
203640
+ function addFormats(ajv, list, fs45, exportName) {
203332
203641
  var _a4;
203333
203642
  var _b2;
203334
203643
  (_a4 = (_b2 = ajv.opts.code).formats) !== null && _a4 !== void 0 ? _a4 : _b2.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
203335
203644
  for (const f of list)
203336
- ajv.addFormat(f, fs44[f]);
203645
+ ajv.addFormat(f, fs45[f]);
203337
203646
  }
203338
203647
  module2.exports = exports = formatsPlugin;
203339
203648
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -228684,7 +228993,7 @@ function readFileFromEnv(signalSpecificEnvVar, nonSignalSpecificEnvVar, warningM
228684
228993
  const filePath = signalSpecificPath ?? nonSignalSpecificPath;
228685
228994
  if (filePath != null) {
228686
228995
  try {
228687
- return fs32.readFileSync(path34.resolve(process.cwd(), filePath));
228996
+ return fs33.readFileSync(path34.resolve(process.cwd(), filePath));
228688
228997
  } catch {
228689
228998
  diag2.warn(warningMessage);
228690
228999
  return void 0;
@@ -228715,10 +229024,10 @@ function getNodeHttpConfigurationFromEnvironment(signalIdentifier, signalResourc
228715
229024
  })
228716
229025
  };
228717
229026
  }
228718
- var fs32, path34, import_core24;
229027
+ var fs33, path34, import_core24;
228719
229028
  var init_otlp_node_http_env_configuration = __esm({
228720
229029
  "node_modules/@opentelemetry/otlp-exporter-base/build/esm/configuration/otlp-node-http-env-configuration.js"() {
228721
- fs32 = __toESM(require("fs"));
229030
+ fs33 = __toESM(require("fs"));
228722
229031
  path34 = __toESM(require("path"));
228723
229032
  import_core24 = __toESM(require_src2());
228724
229033
  init_esm2();
@@ -230422,7 +230731,7 @@ var require_utils14 = __commonJS({
230422
230731
  var exporter_metrics_otlp_http_1 = require_src20();
230423
230732
  var exporter_metrics_otlp_proto_1 = require_src21();
230424
230733
  var sdk_logs_1 = require_src5();
230425
- var fs44 = require("fs");
230734
+ var fs45 = require("fs");
230426
230735
  var RESOURCE_DETECTOR_ENVIRONMENT = "env";
230427
230736
  var RESOURCE_DETECTOR_HOST = "host";
230428
230737
  var RESOURCE_DETECTOR_OS = "os";
@@ -230845,21 +231154,21 @@ var require_utils14 = __commonJS({
230845
231154
  const httpsAgentOptions = {};
230846
231155
  if (tls.ca_file) {
230847
231156
  try {
230848
- httpsAgentOptions.ca = fs44.readFileSync(tls.ca_file);
231157
+ httpsAgentOptions.ca = fs45.readFileSync(tls.ca_file);
230849
231158
  } catch (e2) {
230850
231159
  api_1.diag.warn(`Failed to read TLS CA file at ${tls.ca_file}: ${e2}`);
230851
231160
  }
230852
231161
  }
230853
231162
  if (tls.cert_file) {
230854
231163
  try {
230855
- httpsAgentOptions.cert = fs44.readFileSync(tls.cert_file);
231164
+ httpsAgentOptions.cert = fs45.readFileSync(tls.cert_file);
230856
231165
  } catch (e2) {
230857
231166
  api_1.diag.warn(`Failed to read TLS cert file at ${tls.cert_file}: ${e2}`);
230858
231167
  }
230859
231168
  }
230860
231169
  if (tls.key_file) {
230861
231170
  try {
230862
- httpsAgentOptions.key = fs44.readFileSync(tls.key_file);
231171
+ httpsAgentOptions.key = fs45.readFileSync(tls.key_file);
230863
231172
  } catch (e2) {
230864
231173
  api_1.diag.warn(`Failed to read TLS key file at ${tls.key_file}: ${e2}`);
230865
231174
  }
@@ -231838,12 +232147,12 @@ var init_guideHub = __esm({
231838
232147
  });
231839
232148
 
231840
232149
  // src/server/DaemonMcpServer.ts
231841
- var fs33, import_crypto13, import_url3, UI_RESOURCE_URI, GUIDE_HUB_RESOURCE_URI, DaemonMcpServer;
232150
+ var fs34, import_crypto13, import_url3, UI_RESOURCE_URI, GUIDE_HUB_RESOURCE_URI, DaemonMcpServer;
231842
232151
  var init_DaemonMcpServer = __esm({
231843
232152
  "src/server/DaemonMcpServer.ts"() {
231844
232153
  "use strict";
231845
232154
  init_types();
231846
- fs33 = __toESM(require("fs"));
232155
+ fs34 = __toESM(require("fs"));
231847
232156
  import_crypto13 = require("crypto");
231848
232157
  init_telemetry();
231849
232158
  init_esm2();
@@ -232022,7 +232331,7 @@ var init_DaemonMcpServer = __esm({
232022
232331
  if (uri === UI_RESOURCE_URI) {
232023
232332
  try {
232024
232333
  const htmlPath = findDistFile("mcp-app.html");
232025
- const html = await fs33.promises.readFile(htmlPath, "utf-8");
232334
+ const html = await fs34.promises.readFile(htmlPath, "utf-8");
232026
232335
  const result2 = {
232027
232336
  contents: [
232028
232337
  {
@@ -232481,11 +232790,11 @@ var init_ExtensionConnectionTracker = __esm({
232481
232790
  });
232482
232791
 
232483
232792
  // src/server/surfaces/DaemonSocketSurface.ts
232484
- var fs34, net2, path35, bindSequence, DaemonSocketSurface;
232793
+ var fs35, net2, path35, bindSequence, DaemonSocketSurface;
232485
232794
  var init_DaemonSocketSurface = __esm({
232486
232795
  "src/server/surfaces/DaemonSocketSurface.ts"() {
232487
232796
  "use strict";
232488
- fs34 = __toESM(require("fs"));
232797
+ fs35 = __toESM(require("fs"));
232489
232798
  net2 = __toESM(require("net"));
232490
232799
  path35 = __toESM(require("path"));
232491
232800
  init_ipcEndpoint();
@@ -232521,8 +232830,8 @@ var init_DaemonSocketSurface = __esm({
232521
232830
  return;
232522
232831
  }
232523
232832
  if (isRelocatedDaemonIpcEndpoint(this.options.configDir, this.options.socketPath)) {
232524
- fs34.mkdirSync(path35.dirname(this.options.socketPath), { recursive: true, mode: 448 });
232525
- fs34.chmodSync(path35.dirname(this.options.socketPath), 448);
232833
+ fs35.mkdirSync(path35.dirname(this.options.socketPath), { recursive: true, mode: 448 });
232834
+ fs35.chmodSync(path35.dirname(this.options.socketPath), 448);
232526
232835
  logger.warn(
232527
232836
  `[Daemon] Relocated IPC endpoint from ${path35.join(this.options.configDir, "srv.sock")} to ${this.options.socketPath}.`
232528
232837
  );
@@ -232538,9 +232847,9 @@ var init_DaemonSocketSurface = __esm({
232538
232847
  );
232539
232848
  }
232540
232849
  const bindPath = canPublishByRename ? privatePath : this.options.socketPath;
232541
- if (usesFilesystemPath && fs34.existsSync(bindPath)) {
232850
+ if (usesFilesystemPath && fs35.existsSync(bindPath)) {
232542
232851
  try {
232543
- fs34.unlinkSync(bindPath);
232852
+ fs35.unlinkSync(bindPath);
232544
232853
  } catch (e2) {
232545
232854
  logger.warn("Failed to clean up socket:", e2);
232546
232855
  }
@@ -232594,8 +232903,8 @@ var init_DaemonSocketSurface = __esm({
232594
232903
  const onListen = () => {
232595
232904
  if (canPublishByRename) {
232596
232905
  try {
232597
- fs34.renameSync(bindPath, this.options.socketPath);
232598
- this.ownedEndpointInode = fs34.statSync(this.options.socketPath).ino;
232906
+ fs35.renameSync(bindPath, this.options.socketPath);
232907
+ this.ownedEndpointInode = fs35.statSync(this.options.socketPath).ino;
232599
232908
  } catch (error52) {
232600
232909
  cleanup();
232601
232910
  reject(error52);
@@ -232678,10 +232987,10 @@ var init_DaemonSocketSurface = __esm({
232678
232987
  return;
232679
232988
  }
232680
232989
  try {
232681
- if (fs34.statSync(this.options.socketPath).ino !== owned) {
232990
+ if (fs35.statSync(this.options.socketPath).ino !== owned) {
232682
232991
  return;
232683
232992
  }
232684
- fs34.unlinkSync(this.options.socketPath);
232993
+ fs35.unlinkSync(this.options.socketPath);
232685
232994
  } catch {
232686
232995
  }
232687
232996
  }
@@ -247393,12 +247702,12 @@ var init_artifactPins_generated = __esm({
247393
247702
  });
247394
247703
 
247395
247704
  // src/server/runtime/ManagedArtifactRuntime.ts
247396
- var crypto18, fs35, import_module, os7, path36, ORPHAN_DOWNLOAD_MIN_AGE_MS, WAIT_LOG_INTERVAL_MS, requireFromRuntime, ManagedArtifactRuntime;
247705
+ var crypto18, fs36, import_module, os7, path36, ORPHAN_DOWNLOAD_MIN_AGE_MS, WAIT_LOG_INTERVAL_MS, requireFromRuntime, ManagedArtifactRuntime;
247397
247706
  var init_ManagedArtifactRuntime = __esm({
247398
247707
  "src/server/runtime/ManagedArtifactRuntime.ts"() {
247399
247708
  "use strict";
247400
247709
  crypto18 = __toESM(require("crypto"));
247401
- fs35 = __toESM(require("fs"));
247710
+ fs36 = __toESM(require("fs"));
247402
247711
  import_module = require("module");
247403
247712
  os7 = __toESM(require("os"));
247404
247713
  path36 = __toESM(require("path"));
@@ -247477,7 +247786,7 @@ var init_ManagedArtifactRuntime = __esm({
247477
247786
  const manifestPath = artifactManifestPath(versionDir);
247478
247787
  const existing = readManifest(manifestPath);
247479
247788
  if (existing && existing.layoutVersion === 2 && existing.platform === platform2 && this.manifestVersion(existing) === pins.artifactVersion) {
247480
- if (fs35.existsSync(versionDir)) {
247789
+ if (fs36.existsSync(versionDir)) {
247481
247790
  return versionDir;
247482
247791
  }
247483
247792
  }
@@ -247582,7 +247891,7 @@ var init_ManagedArtifactRuntime = __esm({
247582
247891
  }
247583
247892
  }
247584
247893
  const lockDir = `${versionDir}.provision-lock`;
247585
- fs35.mkdirSync(path36.dirname(lockDir), { recursive: true });
247894
+ fs36.mkdirSync(path36.dirname(lockDir), { recursive: true });
247586
247895
  const lockWaitStartMs = Date.now();
247587
247896
  const staleMs = this.options.provisionLockStaleMs ?? 5 * 60 * 1e3;
247588
247897
  const maxWaitMs = this.options.provisionLockMaxWaitMs ?? 10 * 60 * 1e3;
@@ -247622,13 +247931,13 @@ var init_ManagedArtifactRuntime = __esm({
247622
247931
  );
247623
247932
  }
247624
247933
  try {
247625
- const stats = fs35.statSync(lockDir);
247934
+ const stats = fs36.statSync(lockDir);
247626
247935
  const ageMs = Date.now() - stats.mtimeMs;
247627
247936
  if (ageMs > staleMs) {
247628
247937
  logger.warn(
247629
247938
  `[${this.logTag()}] Breaking stale provisioning lock: ${lockDir}, ageMs=${ageMs}`
247630
247939
  );
247631
- fs35.rmSync(lockDir, { recursive: true, force: true });
247940
+ fs36.rmSync(lockDir, { recursive: true, force: true });
247632
247941
  continue;
247633
247942
  }
247634
247943
  } catch (error52) {
@@ -247641,7 +247950,7 @@ var init_ManagedArtifactRuntime = __esm({
247641
247950
  heartbeatTimer = setInterval(() => {
247642
247951
  try {
247643
247952
  const now = Date.now() / 1e3;
247644
- fs35.utimesSync(lockDir, now, now);
247953
+ fs36.utimesSync(lockDir, now, now);
247645
247954
  } catch (error52) {
247646
247955
  }
247647
247956
  }, heartbeatIntervalMs);
@@ -247654,9 +247963,9 @@ var init_ManagedArtifactRuntime = __esm({
247654
247963
  }
247655
247964
  if (provisionToken) {
247656
247965
  try {
247657
- const currentToken = fs35.readFileSync(path36.join(lockDir, "owner"), "utf-8");
247966
+ const currentToken = fs36.readFileSync(path36.join(lockDir, "owner"), "utf-8");
247658
247967
  if (currentToken === provisionToken) {
247659
- fs35.rmSync(lockDir, { recursive: true, force: true });
247968
+ fs36.rmSync(lockDir, { recursive: true, force: true });
247660
247969
  }
247661
247970
  } catch (error52) {
247662
247971
  }
@@ -247669,8 +247978,8 @@ var init_ManagedArtifactRuntime = __esm({
247669
247978
  }
247670
247979
  this.reapOrphans(versionDir);
247671
247980
  const tempDir = `${versionDir}-tmp-${process.pid}-${Date.now()}`;
247672
- fs35.rmSync(tempDir, { recursive: true, force: true });
247673
- fs35.mkdirSync(tempDir, { recursive: true });
247981
+ fs36.rmSync(tempDir, { recursive: true, force: true });
247982
+ fs36.mkdirSync(tempDir, { recursive: true });
247674
247983
  const downloadPaths = [];
247675
247984
  const downloadPrefix = `sql-preview-${this.options.artifactId}-`;
247676
247985
  try {
@@ -247692,7 +248001,7 @@ var init_ManagedArtifactRuntime = __esm({
247692
248001
  }
247693
248002
  const actualHash = await sha512File(downloadPath);
247694
248003
  if (!verifyIntegrity(actualHash, tarball.integrity)) {
247695
- fs35.rmSync(downloadPath, { force: true });
248004
+ fs36.rmSync(downloadPath, { force: true });
247696
248005
  return this.fail("checksum_failed", `Integrity check failed for ${tarball.name}.`);
247697
248006
  }
247698
248007
  const packageDestDir = path36.join(
@@ -247701,10 +248010,10 @@ var init_ManagedArtifactRuntime = __esm({
247701
248010
  );
247702
248011
  await extractTarGz(downloadPath, packageDestDir);
247703
248012
  this.flattenNpmPackage(packageDestDir);
247704
- fs35.rmSync(downloadPath, { force: true });
248013
+ fs36.rmSync(downloadPath, { force: true });
247705
248014
  }
247706
- fs35.rmSync(versionDir, { recursive: true, force: true });
247707
- fs35.renameSync(tempDir, versionDir);
248015
+ fs36.rmSync(versionDir, { recursive: true, force: true });
248016
+ fs36.renameSync(tempDir, versionDir);
247708
248017
  const manifestBase = {
247709
248018
  layoutVersion: 2,
247710
248019
  platform: platform2,
@@ -247735,12 +248044,12 @@ var init_ManagedArtifactRuntime = __esm({
247735
248044
  );
247736
248045
  } finally {
247737
248046
  try {
247738
- fs35.rmSync(tempDir, { recursive: true, force: true });
248047
+ fs36.rmSync(tempDir, { recursive: true, force: true });
247739
248048
  } catch (error52) {
247740
248049
  }
247741
248050
  for (const downloadPath of downloadPaths) {
247742
248051
  try {
247743
- fs35.rmSync(downloadPath, { force: true });
248052
+ fs36.rmSync(downloadPath, { force: true });
247744
248053
  } catch (error52) {
247745
248054
  }
247746
248055
  }
@@ -247749,9 +248058,9 @@ var init_ManagedArtifactRuntime = __esm({
247749
248058
  }
247750
248059
  if (provisionToken) {
247751
248060
  try {
247752
- const currentToken = fs35.readFileSync(path36.join(lockDir, "owner"), "utf-8");
248061
+ const currentToken = fs36.readFileSync(path36.join(lockDir, "owner"), "utf-8");
247753
248062
  if (currentToken === provisionToken) {
247754
- fs35.rmSync(lockDir, { recursive: true, force: true });
248063
+ fs36.rmSync(lockDir, { recursive: true, force: true });
247755
248064
  }
247756
248065
  } catch (error52) {
247757
248066
  }
@@ -247766,12 +248075,12 @@ var init_ManagedArtifactRuntime = __esm({
247766
248075
  const versionBase = path36.basename(versionDir);
247767
248076
  const prefix = `${versionBase}-tmp-`;
247768
248077
  try {
247769
- const siblings = fs35.readdirSync(parentDir);
248078
+ const siblings = fs36.readdirSync(parentDir);
247770
248079
  for (const sibling of siblings) {
247771
248080
  if (sibling.startsWith(prefix)) {
247772
248081
  const siblingPath = path36.join(parentDir, sibling);
247773
248082
  try {
247774
- fs35.rmSync(siblingPath, { recursive: true, force: true });
248083
+ fs36.rmSync(siblingPath, { recursive: true, force: true });
247775
248084
  } catch (error52) {
247776
248085
  }
247777
248086
  }
@@ -247780,16 +248089,16 @@ var init_ManagedArtifactRuntime = __esm({
247780
248089
  }
247781
248090
  try {
247782
248091
  const downloadDir = this.downloadDir();
247783
- const files = fs35.readdirSync(downloadDir);
248092
+ const files = fs36.readdirSync(downloadDir);
247784
248093
  const now = Date.now();
247785
248094
  const downloadPrefix = `sql-preview-${this.options.artifactId}-`;
247786
248095
  for (const file4 of files) {
247787
248096
  if (file4.startsWith(downloadPrefix) && file4.endsWith(".tgz")) {
247788
248097
  const filePath = path36.join(downloadDir, file4);
247789
248098
  try {
247790
- const stats = fs35.statSync(filePath);
248099
+ const stats = fs36.statSync(filePath);
247791
248100
  if (now - stats.mtimeMs > ORPHAN_DOWNLOAD_MIN_AGE_MS) {
247792
- fs35.rmSync(filePath, { force: true });
248101
+ fs36.rmSync(filePath, { force: true });
247793
248102
  }
247794
248103
  } catch (error52) {
247795
248104
  }
@@ -247800,9 +248109,9 @@ var init_ManagedArtifactRuntime = __esm({
247800
248109
  }
247801
248110
  tryAcquireProvisionLock(lockDir) {
247802
248111
  try {
247803
- fs35.mkdirSync(lockDir, { recursive: false });
248112
+ fs36.mkdirSync(lockDir, { recursive: false });
247804
248113
  const token = `${process.pid}-${crypto18.randomUUID()}`;
247805
- fs35.writeFileSync(path36.join(lockDir, "owner"), token, "utf-8");
248114
+ fs36.writeFileSync(path36.join(lockDir, "owner"), token, "utf-8");
247806
248115
  return { acquired: true, token };
247807
248116
  } catch (error52) {
247808
248117
  if (error52.code === "EEXIST") {
@@ -247840,11 +248149,11 @@ var init_ManagedArtifactRuntime = __esm({
247840
248149
  }
247841
248150
  flattenNpmPackage(packageDestDir) {
247842
248151
  let archiveRoot = path36.join(packageDestDir, "package");
247843
- if (!fs35.statSync(archiveRoot, { throwIfNoEntry: false })?.isDirectory()) {
247844
- const entries = fs35.readdirSync(packageDestDir);
248152
+ if (!fs36.statSync(archiveRoot, { throwIfNoEntry: false })?.isDirectory()) {
248153
+ const entries = fs36.readdirSync(packageDestDir);
247845
248154
  if (entries.length === 1 && entries[0]) {
247846
248155
  const singleEntry = entries[0];
247847
- if (fs35.statSync(path36.join(packageDestDir, singleEntry)).isDirectory()) {
248156
+ if (fs36.statSync(path36.join(packageDestDir, singleEntry)).isDirectory()) {
247848
248157
  archiveRoot = path36.join(packageDestDir, singleEntry);
247849
248158
  } else {
247850
248159
  throw new Error(
@@ -247857,10 +248166,10 @@ var init_ManagedArtifactRuntime = __esm({
247857
248166
  );
247858
248167
  }
247859
248168
  }
247860
- for (const entry of fs35.readdirSync(archiveRoot)) {
247861
- fs35.renameSync(path36.join(archiveRoot, entry), path36.join(packageDestDir, entry));
248169
+ for (const entry of fs36.readdirSync(archiveRoot)) {
248170
+ fs36.renameSync(path36.join(archiveRoot, entry), path36.join(packageDestDir, entry));
247862
248171
  }
247863
- fs35.rmdirSync(archiveRoot);
248172
+ fs36.rmdirSync(archiveRoot);
247864
248173
  }
247865
248174
  };
247866
248175
  }
@@ -248056,11 +248365,11 @@ var init_DuckDbRuntime = __esm({
248056
248365
  });
248057
248366
 
248058
248367
  // src/server/runtime/DriverArtifactProvisioner.ts
248059
- var fs36, path37, DRIVER_ARTIFACTS, DriverArtifactProvisioner;
248368
+ var fs37, path37, DRIVER_ARTIFACTS, DriverArtifactProvisioner;
248060
248369
  var init_DriverArtifactProvisioner = __esm({
248061
248370
  "src/server/runtime/DriverArtifactProvisioner.ts"() {
248062
248371
  "use strict";
248063
- fs36 = __toESM(require("fs"));
248372
+ fs37 = __toESM(require("fs"));
248064
248373
  path37 = __toESM(require("path"));
248065
248374
  init_optionalDrivers();
248066
248375
  init_ManagedArtifactTypes();
@@ -248096,7 +248405,7 @@ var init_DriverArtifactProvisioner = __esm({
248096
248405
  pins.artifactVersion
248097
248406
  );
248098
248407
  const depPath = path37.join(versionDir, "node_modules", ...dependency.split("/"));
248099
- if (fs36.existsSync(depPath)) {
248408
+ if (fs37.existsSync(depPath)) {
248100
248409
  return depPath;
248101
248410
  }
248102
248411
  return null;
@@ -248226,11 +248535,11 @@ function rowToLedgerEntry(row) {
248226
248535
  function describeError3(error52) {
248227
248536
  return error52 instanceof Error ? error52.message : String(error52);
248228
248537
  }
248229
- var fs37, path38, LEDGER_DB_FILENAME, JOURNAL_SCHEMA_VERSION, META_KEY_SCHEMA_VERSION, META_KEY_HEAD_HASH, JournalStoreOpenError, openJournalPaths, JournalStore;
248538
+ var fs38, path38, LEDGER_DB_FILENAME, JOURNAL_SCHEMA_VERSION, META_KEY_SCHEMA_VERSION, META_KEY_HEAD_HASH, JournalStoreOpenError, openJournalPaths, JournalStore;
248230
248539
  var init_JournalStore = __esm({
248231
248540
  "src/server/ledger/JournalStore.ts"() {
248232
248541
  "use strict";
248233
- fs37 = __toESM(require("fs"));
248542
+ fs38 = __toESM(require("fs"));
248234
248543
  path38 = __toESM(require("path"));
248235
248544
  init_canonicalSerialize();
248236
248545
  init_LedgerTypes();
@@ -248279,7 +248588,7 @@ var init_JournalStore = __esm({
248279
248588
  const lockPath = path38.join(options.storageDir, "execution-ledger.lock");
248280
248589
  let ownsLockfile = false;
248281
248590
  try {
248282
- fs37.mkdirSync(options.storageDir, { recursive: true });
248591
+ fs38.mkdirSync(options.storageDir, { recursive: true });
248283
248592
  } catch (error52) {
248284
248593
  throw new JournalStoreOpenError(
248285
248594
  "io-error",
@@ -248290,9 +248599,9 @@ var init_JournalStore = __esm({
248290
248599
  while (attempts < 2) {
248291
248600
  attempts++;
248292
248601
  try {
248293
- const fd = fs37.openSync(lockPath, "wx");
248294
- fs37.writeSync(fd, process.pid.toString());
248295
- fs37.closeSync(fd);
248602
+ const fd = fs38.openSync(lockPath, "wx");
248603
+ fs38.writeSync(fd, process.pid.toString());
248604
+ fs38.closeSync(fd);
248296
248605
  ownsLockfile = true;
248297
248606
  break;
248298
248607
  } catch (error52) {
@@ -248304,7 +248613,7 @@ var init_JournalStore = __esm({
248304
248613
  }
248305
248614
  let existingPid;
248306
248615
  try {
248307
- const pidContent = fs37.readFileSync(lockPath, "utf8");
248616
+ const pidContent = fs38.readFileSync(lockPath, "utf8");
248308
248617
  existingPid = parseInt(pidContent, 10);
248309
248618
  } catch (readError) {
248310
248619
  if (readError.code === "ENOENT") {
@@ -248336,7 +248645,7 @@ var init_JournalStore = __esm({
248336
248645
  );
248337
248646
  }
248338
248647
  try {
248339
- fs37.unlinkSync(lockPath);
248648
+ fs38.unlinkSync(lockPath);
248340
248649
  } catch (unlinkError) {
248341
248650
  if (unlinkError.code !== "ENOENT") {
248342
248651
  throw new JournalStoreOpenError(
@@ -248356,7 +248665,7 @@ var init_JournalStore = __esm({
248356
248665
  } catch (error52) {
248357
248666
  if (ownsLockfile) {
248358
248667
  try {
248359
- fs37.unlinkSync(lockPath);
248668
+ fs38.unlinkSync(lockPath);
248360
248669
  } catch {
248361
248670
  }
248362
248671
  }
@@ -248375,7 +248684,7 @@ var init_JournalStore = __esm({
248375
248684
  } catch (error52) {
248376
248685
  if (ownsLockfile) {
248377
248686
  try {
248378
- fs37.unlinkSync(lockPath);
248687
+ fs38.unlinkSync(lockPath);
248379
248688
  } catch {
248380
248689
  }
248381
248690
  }
@@ -248484,7 +248793,7 @@ var init_JournalStore = __esm({
248484
248793
  this.connection.closeSync();
248485
248794
  this.instance.closeSync();
248486
248795
  try {
248487
- fs37.unlinkSync(this.lockPath);
248796
+ fs38.unlinkSync(this.lockPath);
248488
248797
  } catch {
248489
248798
  }
248490
248799
  }
@@ -248931,11 +249240,11 @@ var init_LedgerService = __esm({
248931
249240
  function redactFatalText(text) {
248932
249241
  return text.replace(AUTHORIZATION_VALUE2, "$1 [redacted]").replace(SENSITIVE_ASSIGNMENT2, "$1[redacted]").replace(QUERY_ASSIGNMENT2, "$1[redacted]").replace(URL_SECRET2, "$1[redacted]");
248933
249242
  }
248934
- var fs38, path39, MAX_BYTES, RETAINED_FILES, SENSITIVE_ASSIGNMENT2, QUERY_ASSIGNMENT2, AUTHORIZATION_VALUE2, URL_SECRET2, FatalJournal;
249243
+ var fs39, path39, MAX_BYTES, RETAINED_FILES, SENSITIVE_ASSIGNMENT2, QUERY_ASSIGNMENT2, AUTHORIZATION_VALUE2, URL_SECRET2, FatalJournal;
248935
249244
  var init_FatalJournal = __esm({
248936
249245
  "src/server/FatalJournal.ts"() {
248937
249246
  "use strict";
248938
- fs38 = __toESM(require("fs"));
249247
+ fs39 = __toESM(require("fs"));
248939
249248
  path39 = __toESM(require("path"));
248940
249249
  MAX_BYTES = 5 * 1024 * 1024;
248941
249250
  RETAINED_FILES = 5;
@@ -248970,23 +249279,23 @@ ${redactFatalText(detail)}
248970
249279
  return;
248971
249280
  }
248972
249281
  try {
248973
- fs38.mkdirSync(this.logDir, { recursive: true, mode: 448 });
248974
- fs38.chmodSync(this.logDir, 448);
249282
+ fs39.mkdirSync(this.logDir, { recursive: true, mode: 448 });
249283
+ fs39.chmodSync(this.logDir, 448);
248975
249284
  const bytes = Buffer.byteLength(text);
248976
249285
  this.rotateIfNeeded(bytes);
248977
249286
  this.assertNotSymlink(this.logPath);
248978
- const noFollow = fs38.constants.O_NOFOLLOW ?? 0;
248979
- const fd = fs38.openSync(
249287
+ const noFollow = fs39.constants.O_NOFOLLOW ?? 0;
249288
+ const fd = fs39.openSync(
248980
249289
  this.logPath,
248981
- fs38.constants.O_APPEND | fs38.constants.O_CREAT | fs38.constants.O_WRONLY | noFollow,
249290
+ fs39.constants.O_APPEND | fs39.constants.O_CREAT | fs39.constants.O_WRONLY | noFollow,
248982
249291
  384
248983
249292
  );
248984
249293
  try {
248985
- fs38.writeSync(fd, text);
248986
- fs38.fsyncSync(fd);
248987
- fs38.fchmodSync(fd, 384);
249294
+ fs39.writeSync(fd, text);
249295
+ fs39.fsyncSync(fd);
249296
+ fs39.fchmodSync(fd, 384);
248988
249297
  } finally {
248989
- fs38.closeSync(fd);
249298
+ fs39.closeSync(fd);
248990
249299
  }
248991
249300
  } catch {
248992
249301
  this.disabled = true;
@@ -248997,7 +249306,7 @@ ${redactFatalText(detail)}
248997
249306
  let currentBytes = 0;
248998
249307
  try {
248999
249308
  this.assertNotSymlink(this.logPath);
249000
- currentBytes = fs38.statSync(this.logPath).size;
249309
+ currentBytes = fs39.statSync(this.logPath).size;
249001
249310
  } catch (error52) {
249002
249311
  if (error52.code !== "ENOENT") {
249003
249312
  throw error52;
@@ -249007,27 +249316,27 @@ ${redactFatalText(detail)}
249007
249316
  return;
249008
249317
  }
249009
249318
  const oldest = `${this.logPath}.${RETAINED_FILES}`;
249010
- if (fs38.existsSync(oldest)) {
249319
+ if (fs39.existsSync(oldest)) {
249011
249320
  this.assertNotSymlink(oldest);
249012
- fs38.unlinkSync(oldest);
249321
+ fs39.unlinkSync(oldest);
249013
249322
  }
249014
249323
  for (let index = RETAINED_FILES - 1; index >= 1; index--) {
249015
249324
  const source = `${this.logPath}.${index}`;
249016
- if (!fs38.existsSync(source)) {
249325
+ if (!fs39.existsSync(source)) {
249017
249326
  continue;
249018
249327
  }
249019
249328
  this.assertNotSymlink(source);
249020
- fs38.renameSync(source, `${this.logPath}.${index + 1}`);
249329
+ fs39.renameSync(source, `${this.logPath}.${index + 1}`);
249021
249330
  }
249022
- if (fs38.existsSync(this.logPath)) {
249331
+ if (fs39.existsSync(this.logPath)) {
249023
249332
  this.assertNotSymlink(this.logPath);
249024
- fs38.renameSync(this.logPath, `${this.logPath}.1`);
249025
- fs38.chmodSync(`${this.logPath}.1`, 384);
249333
+ fs39.renameSync(this.logPath, `${this.logPath}.1`);
249334
+ fs39.chmodSync(`${this.logPath}.1`, 384);
249026
249335
  }
249027
249336
  }
249028
249337
  assertNotSymlink(target) {
249029
249338
  try {
249030
- if (fs38.lstatSync(target).isSymbolicLink()) {
249339
+ if (fs39.lstatSync(target).isSymbolicLink()) {
249031
249340
  throw new Error("Refusing to write fatal journal through a symbolic link");
249032
249341
  }
249033
249342
  } catch (error52) {
@@ -249100,11 +249409,11 @@ var init_registerDriverModulePath = __esm({
249100
249409
  function faultIdentity(daemonVersion, kind, errorName) {
249101
249410
  return `${daemonVersion}:${kind}:${errorName}`;
249102
249411
  }
249103
- var fs39, path41, DIAGNOSTICS_REPORT_BUDGET, DIAGNOSTICS_BUDGET_WINDOW_MS, MAX_RETAINED_REPORTS, BUDGET_VERSION, DiagnosticsBudget;
249412
+ var fs40, path41, DIAGNOSTICS_REPORT_BUDGET, DIAGNOSTICS_BUDGET_WINDOW_MS, MAX_RETAINED_REPORTS, BUDGET_VERSION, DiagnosticsBudget;
249104
249413
  var init_DiagnosticsBudget = __esm({
249105
249414
  "src/server/DiagnosticsBudget.ts"() {
249106
249415
  "use strict";
249107
- fs39 = __toESM(require("fs"));
249416
+ fs40 = __toESM(require("fs"));
249108
249417
  path41 = __toESM(require("path"));
249109
249418
  DIAGNOSTICS_REPORT_BUDGET = 3;
249110
249419
  DIAGNOSTICS_BUDGET_WINDOW_MS = 60 * 6e4;
@@ -249118,10 +249427,10 @@ var init_DiagnosticsBudget = __esm({
249118
249427
  }
249119
249428
  read() {
249120
249429
  try {
249121
- if (!fs39.existsSync(this.filePath)) {
249430
+ if (!fs40.existsSync(this.filePath)) {
249122
249431
  return { version: BUDGET_VERSION, entries: {} };
249123
249432
  }
249124
- const content = fs39.readFileSync(this.filePath, "utf8");
249433
+ const content = fs40.readFileSync(this.filePath, "utf8");
249125
249434
  const parsed = JSON.parse(content);
249126
249435
  if (!parsed || typeof parsed !== "object" || parsed.version !== BUDGET_VERSION || typeof parsed.entries !== "object" || parsed.entries === null || Array.isArray(parsed.entries)) {
249127
249436
  return { version: BUDGET_VERSION, entries: {} };
@@ -249134,12 +249443,12 @@ var init_DiagnosticsBudget = __esm({
249134
249443
  write(file4) {
249135
249444
  try {
249136
249445
  const dir3 = path41.dirname(this.filePath);
249137
- if (!fs39.existsSync(dir3)) {
249138
- fs39.mkdirSync(dir3, { recursive: true });
249446
+ if (!fs40.existsSync(dir3)) {
249447
+ fs40.mkdirSync(dir3, { recursive: true });
249139
249448
  }
249140
249449
  const tempPath = `${this.filePath}.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`;
249141
- fs39.writeFileSync(tempPath, JSON.stringify(file4, null, 2), "utf8");
249142
- fs39.renameSync(tempPath, this.filePath);
249450
+ fs40.writeFileSync(tempPath, JSON.stringify(file4, null, 2), "utf8");
249451
+ fs40.renameSync(tempPath, this.filePath);
249143
249452
  } catch (error52) {
249144
249453
  if (!this.hasLoggedWriteError) {
249145
249454
  this.hasLoggedWriteError = true;
@@ -249538,8 +249847,8 @@ function pointerPath(configHome, version3) {
249538
249847
  function removeVersion(configHome, version3) {
249539
249848
  const appPath = applicationDir(configHome, version3);
249540
249849
  try {
249541
- fs40.rmSync(appPath, { recursive: true, force: true });
249542
- fs40.rmSync(pointerPath(configHome, version3), { force: true });
249850
+ fs41.rmSync(appPath, { recursive: true, force: true });
249851
+ fs41.rmSync(pointerPath(configHome, version3), { force: true });
249543
249852
  return true;
249544
249853
  } catch {
249545
249854
  return false;
@@ -249556,11 +249865,11 @@ function pruneOldVersions(configHome, keep) {
249556
249865
  }
249557
249866
  return removed;
249558
249867
  }
249559
- var fs40, path42, SEMVER_PATTERN2;
249868
+ var fs41, path42, SEMVER_PATTERN2;
249560
249869
  var init_VersionRetention = __esm({
249561
249870
  "src/server/update/VersionRetention.ts"() {
249562
249871
  "use strict";
249563
- fs40 = __toESM(require("fs"));
249872
+ fs41 = __toESM(require("fs"));
249564
249873
  path42 = __toESM(require("path"));
249565
249874
  init_applicationPayload();
249566
249875
  SEMVER_PATTERN2 = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-(?:0|[1-9]\d*|[0-9A-Za-z-]*[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9]\d*|[0-9A-Za-z-]*[A-Za-z-][0-9A-Za-z-]*))*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
@@ -249592,7 +249901,7 @@ function removeBestEffort(fileSystem, target) {
249592
249901
  function findPayloadEntry(root) {
249593
249902
  const entries = [];
249594
249903
  const visit = (directory) => {
249595
- for (const entry2 of fs41.readdirSync(directory, { withFileTypes: true })) {
249904
+ for (const entry2 of fs42.readdirSync(directory, { withFileTypes: true })) {
249596
249905
  const entryPath = path43.join(directory, entry2.name);
249597
249906
  if (entry2.isDirectory()) {
249598
249907
  visit(entryPath);
@@ -249639,11 +249948,11 @@ function atomicWritePointer(fileSystem, pointerPath2, pointer) {
249639
249948
  }
249640
249949
  removeBestEffort(fileSystem, backupPath);
249641
249950
  }
249642
- var fs41, os8, path43, SEMVER_PATTERN3, UpdateStager;
249951
+ var fs42, os8, path43, SEMVER_PATTERN3, UpdateStager;
249643
249952
  var init_UpdateStager = __esm({
249644
249953
  "src/server/update/UpdateStager.ts"() {
249645
249954
  "use strict";
249646
- fs41 = __toESM(require("fs"));
249955
+ fs42 = __toESM(require("fs"));
249647
249956
  os8 = __toESM(require("os"));
249648
249957
  path43 = __toESM(require("path"));
249649
249958
  init_protocolVersion();
@@ -249659,7 +249968,7 @@ var init_UpdateStager = __esm({
249659
249968
  this.configHome = options.configHome;
249660
249969
  this.currentVersion = options.currentVersion;
249661
249970
  this.downloadDir = options.downloadDir ?? os8.tmpdir();
249662
- this.fileSystem = options.fileSystem ?? fs41;
249971
+ this.fileSystem = options.fileSystem ?? fs42;
249663
249972
  }
249664
249973
  stagedVersion() {
249665
249974
  const versionsDir = path43.join(this.configHome, "versions");
@@ -249787,7 +250096,7 @@ var init_UpdateStager = __esm({
249787
250096
  function namesADeadProcess(pidPath) {
249788
250097
  let pid;
249789
250098
  try {
249790
- pid = parseInt(fs42.readFileSync(pidPath, "utf8"), 10);
250099
+ pid = parseInt(fs43.readFileSync(pidPath, "utf8"), 10);
249791
250100
  } catch {
249792
250101
  return true;
249793
250102
  }
@@ -249804,7 +250113,7 @@ function namesADeadProcess(pidPath) {
249804
250113
  function pruneDeadPidFiles(configDir, ownPidPath) {
249805
250114
  let entries;
249806
250115
  try {
249807
- entries = fs42.readdirSync(configDir);
250116
+ entries = fs43.readdirSync(configDir);
249808
250117
  } catch {
249809
250118
  return [];
249810
250119
  }
@@ -249821,7 +250130,7 @@ function pruneDeadPidFiles(configDir, ownPidPath) {
249821
250130
  continue;
249822
250131
  }
249823
250132
  try {
249824
- fs42.unlinkSync(candidate);
250133
+ fs43.unlinkSync(candidate);
249825
250134
  pruned.push(entry);
249826
250135
  } catch {
249827
250136
  continue;
@@ -249829,11 +250138,11 @@ function pruneDeadPidFiles(configDir, ownPidPath) {
249829
250138
  }
249830
250139
  return pruned;
249831
250140
  }
249832
- var fs42, path44, PID_FILE_PATTERN;
250141
+ var fs43, path44, PID_FILE_PATTERN;
249833
250142
  var init_pidFilePruning = __esm({
249834
250143
  "src/server/pidFilePruning.ts"() {
249835
250144
  "use strict";
249836
- fs42 = __toESM(require("fs"));
250145
+ fs43 = __toESM(require("fs"));
249837
250146
  path44 = __toESM(require("path"));
249838
250147
  PID_FILE_PATTERN = /^server-\d+\.pid$/;
249839
250148
  }
@@ -249882,7 +250191,7 @@ function createDaemonActivationGate(sources) {
249882
250191
  })
249883
250192
  });
249884
250193
  }
249885
- function readInstalledApplicationVersion(configHome, entryPath, fileSystem = fs43) {
250194
+ function readInstalledApplicationVersion(configHome, entryPath, fileSystem = fs44) {
249886
250195
  if (!entryPath) {
249887
250196
  return null;
249888
250197
  }
@@ -249913,7 +250222,7 @@ function readInstalledApplicationVersion(configHome, entryPath, fileSystem = fs4
249913
250222
  function writePidFileAtomically(pidPath, pid) {
249914
250223
  const tempPath = `${pidPath}.${pid}.${Math.random().toString(36).slice(2)}.tmp`;
249915
250224
  try {
249916
- fs43.writeFileSync(tempPath, pid.toString());
250225
+ fs44.writeFileSync(tempPath, pid.toString());
249917
250226
  } catch {
249918
250227
  return false;
249919
250228
  }
@@ -249923,7 +250232,7 @@ function writePidFileAtomically(pidPath, pid) {
249923
250232
  let lastErrorCode;
249924
250233
  for (let attempt = 1; attempt <= MAX_RENAME_ATTEMPTS; attempt++) {
249925
250234
  try {
249926
- fs43.renameSync(tempPath, pidPath);
250235
+ fs44.renameSync(tempPath, pidPath);
249927
250236
  renameSuccess = true;
249928
250237
  break;
249929
250238
  } catch (e2) {
@@ -249942,28 +250251,28 @@ function writePidFileAtomically(pidPath, pid) {
249942
250251
  }
249943
250252
  let directWriteSuccess = false;
249944
250253
  try {
249945
- if (!fs43.existsSync(pidPath)) {
249946
- fs43.writeFileSync(pidPath, pid.toString());
250254
+ if (!fs44.existsSync(pidPath)) {
250255
+ fs44.writeFileSync(pidPath, pid.toString());
249947
250256
  directWriteSuccess = true;
249948
250257
  } else {
249949
250258
  logger.warn(`[Daemon] Failed to write PID file ${pidPath}: ${lastErrorCode || "unknown"}`);
249950
250259
  }
249951
250260
  } finally {
249952
250261
  try {
249953
- if (fs43.existsSync(tempPath)) {
249954
- fs43.unlinkSync(tempPath);
250262
+ if (fs44.existsSync(tempPath)) {
250263
+ fs44.unlinkSync(tempPath);
249955
250264
  }
249956
250265
  } catch {
249957
250266
  }
249958
250267
  }
249959
250268
  return directWriteSuccess;
249960
250269
  }
249961
- var import_express4, fs43, http8, path45, FATAL_EXIT_WATCHDOG_MS, LEDGER_CLOSE_TIMEOUT_MS, ServeInconsistencyError, TakeoverRefusalError, INGRESS_CONNECTION_ESCALATION_MS, STOP_STAGE_TIMEOUT_MS, STOP_TOTAL_TIMEOUT_MS, SERVE_INCONSISTENCY_REBIND_TIMEOUT_MS, OCCUPANT_ENDPOINT_GRACE_MS, Daemon;
250270
+ var import_express4, fs44, http8, path45, FATAL_EXIT_WATCHDOG_MS, LEDGER_CLOSE_TIMEOUT_MS, ServeInconsistencyError, TakeoverRefusalError, INGRESS_CONNECTION_ESCALATION_MS, STOP_STAGE_TIMEOUT_MS, STOP_TOTAL_TIMEOUT_MS, SERVE_INCONSISTENCY_REBIND_TIMEOUT_MS, OCCUPANT_ENDPOINT_GRACE_MS, Daemon;
249962
250271
  var init_Daemon = __esm({
249963
250272
  "src/server/Daemon.ts"() {
249964
250273
  "use strict";
249965
250274
  import_express4 = __toESM(require_express2());
249966
- fs43 = __toESM(require("fs"));
250275
+ fs44 = __toESM(require("fs"));
249967
250276
  http8 = __toESM(require("http"));
249968
250277
  path45 = __toESM(require("path"));
249969
250278
  init_ipcEndpoint();
@@ -250592,8 +250901,8 @@ var init_Daemon = __esm({
250592
250901
  }
250593
250902
  return this.ingressClosePromise;
250594
250903
  }
250595
- async terminateExistingDaemonProcess(existingPid) {
250596
- const isSqlPreviewDaemon = await this.isSqlPreviewDaemonProcess(existingPid);
250904
+ async terminateExistingDaemonProcess(existingPid, host, port) {
250905
+ const isSqlPreviewDaemon = await this.isSqlPreviewDaemonProcess(existingPid, host, port);
250597
250906
  if (!isSqlPreviewDaemon) {
250598
250907
  logger.warn(
250599
250908
  `[Daemon] Could not confirm live process ${existingPid} is a Grain daemon (its /status did not report a matching pid); leaving process untouched.`
@@ -250678,17 +250987,17 @@ var init_Daemon = __esm({
250678
250987
  return;
250679
250988
  }
250680
250989
  for (let attempt = 0; attempt < 20; attempt++) {
250681
- if (!fs43.existsSync(this.SOCKET_PATH)) {
250990
+ if (!fs44.existsSync(this.SOCKET_PATH)) {
250682
250991
  await new Promise((resolve11) => setTimeout(resolve11, 100));
250683
- if (!fs43.existsSync(this.SOCKET_PATH)) {
250992
+ if (!fs44.existsSync(this.SOCKET_PATH)) {
250684
250993
  return;
250685
250994
  }
250686
250995
  }
250687
250996
  await new Promise((resolve11) => setTimeout(resolve11, 50));
250688
250997
  }
250689
250998
  }
250690
- async isSqlPreviewDaemonProcess(pid) {
250691
- const status = await this.readExistingDaemonStatus();
250999
+ async isSqlPreviewDaemonProcess(pid, host, port) {
251000
+ const status = await this.readExistingDaemonStatus(host, port);
250692
251001
  return status?.service === DAEMON_SERVICE_IDENTITY && status.pid === pid;
250693
251002
  }
250694
251003
  async readExistingDaemonStatus(host = this.config.server.host, port = this.HTTP_PORT) {
@@ -250706,7 +251015,7 @@ var init_Daemon = __esm({
250706
251015
  host,
250707
251016
  port,
250708
251017
  path: "/status",
250709
- timeout: 500,
251018
+ timeout: 2e3,
250710
251019
  headers: this.authToken ? { Authorization: `Bearer ${this.authToken}` } : void 0
250711
251020
  },
250712
251021
  (res) => {
@@ -250756,25 +251065,66 @@ var init_Daemon = __esm({
250756
251065
  await new Promise((resolve11) => setTimeout(resolve11, 50));
250757
251066
  }
250758
251067
  }
251068
+ takeoverFailureExitCode(e2, pid) {
251069
+ const err = e2;
251070
+ if (err.code === "ESRCH") {
251071
+ logger.info(`[Daemon] Cleaning up stale PID file for ${pid}`);
251072
+ return void 0;
251073
+ }
251074
+ if (err.code === "EPERM") {
251075
+ logger.info(
251076
+ `[Daemon] PID file names live process ${pid} owned by another user (EPERM); cleaning up stale PID file.`
251077
+ );
251078
+ return void 0;
251079
+ }
251080
+ if (e2 instanceof TakeoverRefusalError && e2.code === "UNIDENTIFIED_OCCUPANT") {
251081
+ logger.error(
251082
+ `[Daemon] Endpoint ${this.config.server.host}:${this.HTTP_PORT} is occupied by live unidentified process ${pid}; refusing startup.`
251083
+ );
251084
+ return EXIT_UNIDENTIFIED_ENDPOINT_OCCUPIED;
251085
+ }
251086
+ if (e2 instanceof TakeoverRefusalError && e2.code === "PREDECESSOR_DID_NOT_DRAIN") {
251087
+ logger.error(
251088
+ `[Daemon] Predecessor daemon PID ${pid} did not exit after its drain window; refusing takeover.`
251089
+ );
251090
+ return EXIT_PREDECESSOR_DRAIN_TIMEOUT;
251091
+ }
251092
+ logger.error(`[Daemon] Failed to terminate existing process ${pid}: ${e2}`);
251093
+ return 1;
251094
+ }
251095
+ evaluateOccupantVersion(version3, state) {
251096
+ if (!version3) {
251097
+ return { yield: false };
251098
+ }
251099
+ const myVersion = require_package().version;
251100
+ const cmp = compareSemver(version3, myVersion);
251101
+ if (cmp > 0) {
251102
+ return { yield: true, reason: "newer" };
251103
+ }
251104
+ if (cmp === 0 && state !== "draining" && state !== "refusing") {
251105
+ return { yield: true, reason: "healthy same-version" };
251106
+ }
251107
+ return { yield: false };
251108
+ }
250759
251109
  async resolveEndpointOccupant() {
250760
251110
  const endpoint = `${this.config.server.host}:${this.HTTP_PORT}`;
250761
251111
  if (await isTcpPortAvailable(this.HTTP_PORT, this.config.server.host)) {
250762
251112
  return { action: "proceed" };
250763
251113
  }
250764
251114
  const status = await this.readExistingDaemonStatus();
250765
- if (status?.service !== DAEMON_SERVICE_IDENTITY || typeof status.pid !== "number") {
251115
+ const record2 = readDaemonEndpoint(this.CONFIG_DIR);
251116
+ if (status?.service !== DAEMON_SERVICE_IDENTITY || typeof status.pid !== "number" || !record2 || record2.pid !== status.pid) {
250766
251117
  logger.error(
250767
- `[Daemon] Endpoint ${endpoint} is already in use and its occupant does not identify as a Grain daemon; refusing startup.`
251118
+ `[Daemon] Endpoint ${endpoint} is already in use and its occupant does not identify as this configuration directory's daemon; refusing startup.`
250768
251119
  );
250769
251120
  return { action: "exit", code: EXIT_UNIDENTIFIED_ENDPOINT_OCCUPIED };
250770
251121
  }
250771
251122
  if (status.version) {
250772
- const myVersion = require_package().version;
250773
- const cmp = compareSemver(status.version, myVersion);
250774
- if (cmp > 0 || cmp === 0 && status.state !== "draining" && status.state !== "refusing") {
251123
+ const evalResult = this.evaluateOccupantVersion(status.version, status.state);
251124
+ if (evalResult.yield) {
250775
251125
  if (await this.waitForOccupantEndpoint(OCCUPANT_ENDPOINT_GRACE_MS)) {
250776
251126
  logger.info(
250777
- `[Daemon] Endpoint ${endpoint} is served by a ${cmp > 0 ? "newer" : "healthy same-version"} daemon v${status.version} (pid ${status.pid}) that no PID file names; yielding.`
251127
+ `[Daemon] Endpoint ${endpoint} is served by a ${evalResult.reason} daemon v${status.version} (pid ${status.pid}) that no PID file names; yielding.`
250778
251128
  );
250779
251129
  return { action: "exit", code: 42 };
250780
251130
  }
@@ -250805,10 +251155,10 @@ var init_Daemon = __esm({
250805
251155
  let deferPidClaimUntilAfterBind = this.HTTP_PORT === 0 || shouldFallbackToEphemeral;
250806
251156
  try {
250807
251157
  pruneDeadPidFiles(this.CONFIG_DIR, pidPath);
250808
- if (!shouldFallbackToEphemeral && fs43.existsSync(pidPath)) {
251158
+ if (!shouldFallbackToEphemeral && fs44.existsSync(pidPath)) {
250809
251159
  let pidContent = null;
250810
251160
  try {
250811
- pidContent = fs43.readFileSync(pidPath, "utf8");
251161
+ pidContent = fs44.readFileSync(pidPath, "utf8");
250812
251162
  } catch (error52) {
250813
251163
  logger.info(
250814
251164
  `[Daemon] PID file at ${pidPath} could not be read (${error52.code ?? "unknown"}); treating it as unclaimed and checking the endpoint instead.`
@@ -250820,13 +251170,12 @@ var init_Daemon = __esm({
250820
251170
  process.kill(existingPid, 0);
250821
251171
  const status = await this.readExistingDaemonStatus();
250822
251172
  if (status?.service === DAEMON_SERVICE_IDENTITY && status.pid === existingPid && status.version) {
250823
- const myVersion = require_package().version;
250824
- const cmp = compareSemver(status.version, myVersion);
250825
- if (cmp > 0 || cmp === 0 && status.state !== "draining" && status.state !== "refusing") {
251173
+ const evalResult = this.evaluateOccupantVersion(status.version, status.state);
251174
+ if (evalResult.yield) {
250826
251175
  logger.info(
250827
- `[Daemon] Yielding to ${cmp > 0 ? "newer" : "healthy same-version"} daemon v${status.version} (pid ${existingPid})`
251176
+ `[Daemon] Yielding to ${evalResult.reason} daemon v${status.version} (pid ${existingPid})`
250828
251177
  );
250829
- process.exit(42);
251178
+ return process.exit(42);
250830
251179
  }
250831
251180
  }
250832
251181
  const termination = await this.terminateExistingDaemonProcess(existingPid);
@@ -250840,31 +251189,14 @@ var init_Daemon = __esm({
250840
251189
  deferPidClaimUntilAfterBind = true;
250841
251190
  }
250842
251191
  } catch (e2) {
250843
- const err = e2;
250844
- if (err.code === "ESRCH") {
250845
- logger.info(`[Daemon] Cleaning up stale PID file for ${existingPid}`);
250846
- } else if (err.code === "EPERM") {
250847
- logger.info(
250848
- `[Daemon] PID file names live process ${existingPid} owned by another user (EPERM); cleaning up stale PID file.`
250849
- );
250850
- } else if (e2 instanceof TakeoverRefusalError && e2.code === "UNIDENTIFIED_OCCUPANT") {
250851
- logger.error(
250852
- `[Daemon] Endpoint ${this.config.server.host}:${this.HTTP_PORT} is occupied by live unidentified process ${existingPid}; refusing startup.`
250853
- );
250854
- return process.exit(EXIT_UNIDENTIFIED_ENDPOINT_OCCUPIED);
250855
- } else if (e2 instanceof TakeoverRefusalError && e2.code === "PREDECESSOR_DID_NOT_DRAIN") {
250856
- logger.error(
250857
- `[Daemon] Predecessor daemon PID ${existingPid} did not exit after its drain window; refusing takeover.`
250858
- );
250859
- return process.exit(EXIT_PREDECESSOR_DRAIN_TIMEOUT);
250860
- } else {
250861
- logger.error(`[Daemon] Failed to terminate existing process ${existingPid}: ${e2}`);
250862
- return process.exit(1);
251192
+ const exitCode = this.takeoverFailureExitCode(e2, existingPid);
251193
+ if (exitCode !== void 0) {
251194
+ return process.exit(exitCode);
250863
251195
  }
250864
251196
  }
250865
251197
  }
250866
- if (!deferPidClaimUntilAfterBind && !isNaN(existingPid) && fs43.existsSync(pidPath)) {
250867
- fs43.unlinkSync(pidPath);
251198
+ if (!deferPidClaimUntilAfterBind && !isNaN(existingPid) && fs44.existsSync(pidPath)) {
251199
+ fs44.unlinkSync(pidPath);
250868
251200
  }
250869
251201
  }
250870
251202
  if (!deferPidClaimUntilAfterBind && !shouldFallbackToEphemeral) {
@@ -250876,7 +251208,7 @@ var init_Daemon = __esm({
250876
251208
  deferPidClaimUntilAfterBind = true;
250877
251209
  }
250878
251210
  }
250879
- if (shouldFallbackToEphemeral) {
251211
+ if (deferPidClaimUntilAfterBind || shouldFallbackToEphemeral) {
250880
251212
  const record2 = readDaemonEndpoint(this.CONFIG_DIR);
250881
251213
  if (record2) {
250882
251214
  let alive = false;
@@ -250888,10 +251220,34 @@ var init_Daemon = __esm({
250888
251220
  if (alive) {
250889
251221
  const status = await this.readExistingDaemonStatus(record2.host, record2.port);
250890
251222
  if (status?.service === DAEMON_SERVICE_IDENTITY && status.pid === record2.pid) {
251223
+ const evalResult = this.evaluateOccupantVersion(status.version, status.state);
251224
+ if (evalResult.yield) {
251225
+ logger.info(
251226
+ `[Daemon] Endpoint in ${this.CONFIG_DIR} is already served by daemon pid ${record2.pid} at ${record2.host}:${record2.port}; yielding.`
251227
+ );
251228
+ return process.exit(42);
251229
+ }
250891
251230
  logger.info(
250892
- `[Daemon] Endpoint in ${this.CONFIG_DIR} is already served by daemon pid ${record2.pid} at ${record2.host}:${record2.port}; yielding.`
251231
+ `[Daemon] Endpoint in ${this.CONFIG_DIR} is held by older daemon pid ${record2.pid}; taking over.`
250893
251232
  );
250894
- return process.exit(42);
251233
+ try {
251234
+ const termination = await this.terminateExistingDaemonProcess(
251235
+ record2.pid,
251236
+ record2.host,
251237
+ record2.port
251238
+ );
251239
+ if (termination === "unidentified" && !await isTcpPortAvailable(this.HTTP_PORT, this.config.server.host)) {
251240
+ throw new TakeoverRefusalError(
251241
+ `Refusing to replace live unidentified PID ${record2.pid}: endpoint ${this.config.server.host}:${this.HTTP_PORT} is occupied.`,
251242
+ "UNIDENTIFIED_OCCUPANT"
251243
+ );
251244
+ }
251245
+ } catch (e2) {
251246
+ const exitCode = this.takeoverFailureExitCode(e2, record2.pid);
251247
+ if (exitCode !== void 0) {
251248
+ return process.exit(exitCode);
251249
+ }
251250
+ }
250895
251251
  }
250896
251252
  }
250897
251253
  }
@@ -251194,11 +251550,11 @@ var init_Daemon = __esm({
251194
251550
  if (this.ownsPidAndSocket && !this.preserveOwnershipArtifactsOnStop) {
251195
251551
  const pidPath = this.pidFilePath();
251196
251552
  removeDaemonEndpoint(this.CONFIG_DIR);
251197
- if (fs43.existsSync(pidPath)) {
251553
+ if (fs44.existsSync(pidPath)) {
251198
251554
  try {
251199
- const recordedPid = Number(fs43.readFileSync(pidPath, "utf8"));
251555
+ const recordedPid = Number(fs44.readFileSync(pidPath, "utf8"));
251200
251556
  if (recordedPid === process.pid) {
251201
- fs43.unlinkSync(pidPath);
251557
+ fs44.unlinkSync(pidPath);
251202
251558
  }
251203
251559
  } catch {
251204
251560
  }
@@ -251234,6 +251590,7 @@ var init_Daemon = __esm({
251234
251590
  var standalone_exports = {};
251235
251591
  __export(standalone_exports, {
251236
251592
  SERVICE_START_FLUSH_BUDGET_MS: () => SERVICE_START_FLUSH_BUDGET_MS,
251593
+ connectStdioToSharedDaemon: () => connectStdioToSharedDaemon,
251237
251594
  main: () => main
251238
251595
  });
251239
251596
  module.exports = __toCommonJS(standalone_exports);
@@ -251308,7 +251665,14 @@ function confirmsExpectedInstance(expected, identity2) {
251308
251665
  if (expected.token && identity2.pid === void 0) {
251309
251666
  return false;
251310
251667
  }
251311
- return classifyRecordInstance(expected, identity2, Date.now()) !== "mismatch";
251668
+ if (expected.pid === void 0 || expected.startedAt === void 0) {
251669
+ return true;
251670
+ }
251671
+ return classifyRecordInstance(
251672
+ { pid: expected.pid, startedAt: expected.startedAt },
251673
+ identity2,
251674
+ Date.now()
251675
+ ) !== "mismatch";
251312
251676
  }
251313
251677
  function probeSharedDaemonOnce(port, timeoutMs, expected) {
251314
251678
  return new Promise((resolve11) => {
@@ -251363,40 +251727,78 @@ function probeSharedDaemonOnce(port, timeoutMs, expected) {
251363
251727
  });
251364
251728
  });
251365
251729
  }
251730
+ function isTokenAccepted(port, token, timeoutMs) {
251731
+ return new Promise((resolve11) => {
251732
+ const request2 = http.get(
251733
+ {
251734
+ host: "127.0.0.1",
251735
+ port,
251736
+ path: "/bridge-token-check",
251737
+ timeout: timeoutMs,
251738
+ headers: { Authorization: `Bearer ${token}` }
251739
+ },
251740
+ (response) => {
251741
+ response.resume();
251742
+ resolve11(response.statusCode !== 401 && response.statusCode !== 403);
251743
+ }
251744
+ );
251745
+ request2.on("timeout", () => {
251746
+ request2.destroy();
251747
+ resolve11(true);
251748
+ });
251749
+ request2.on("error", () => resolve11(true));
251750
+ });
251751
+ }
251366
251752
 
251367
251753
  // src/server/standalone.ts
251368
251754
  init_StdioBridge();
251369
251755
  init_DaemonAuthToken();
251756
+ init_AgentToken();
251370
251757
  init_ConfigLoader();
251371
251758
 
251372
251759
  // src/server/cli/subcommands.ts
251373
251760
  init_statusCommand();
251374
251761
 
251375
251762
  // src/server/install/addToPathCommand.ts
251376
- var fs6 = __toESM(require("fs"));
251763
+ var fs7 = __toESM(require("fs"));
251377
251764
  var os2 = __toESM(require("os"));
251378
- var path8 = __toESM(require("path"));
251765
+ var path9 = __toESM(require("path"));
251379
251766
  var import_child_process = require("child_process");
251380
251767
  init_grainHome();
251381
251768
 
251382
251769
  // src/server/install/grainCommand.ts
251383
- var fs5 = __toESM(require("fs"));
251384
- var path7 = __toESM(require("path"));
251385
- function writeGrainCommand(home, platform2 = process.platform) {
251386
- const bin = path7.join(home, "bin");
251387
- fs5.mkdirSync(bin, { recursive: true });
251770
+ var fs6 = __toESM(require("fs"));
251771
+ var path8 = __toESM(require("path"));
251772
+ function writeGrainCommand(home, platform2 = process.platform, fileSystem = fs6) {
251773
+ const bin = path8.join(home, "bin");
251774
+ fileSystem.mkdirSync(bin, { recursive: true });
251388
251775
  if (platform2 === "win32") {
251389
- const libexec = path7.join(home, "libexec");
251390
- fs5.mkdirSync(libexec, { recursive: true });
251776
+ const libexec = path8.join(home, "libexec");
251777
+ fileSystem.mkdirSync(libexec, { recursive: true });
251391
251778
  const script2 = WIN_SCRIPT.replace("__GRAIN_HOME__", home);
251392
- fs5.writeFileSync(path7.join(libexec, "grain.ps1"), "\uFEFF" + script2 + "\r\n", "utf8");
251393
- fs5.writeFileSync(path7.join(bin, "grain.cmd"), CMD_SCRIPT, "ascii");
251394
- fs5.rmSync(path7.join(bin, "grain.ps1"), { force: true });
251779
+ const psPath = path8.join(libexec, "grain.ps1");
251780
+ const psContent = "\uFEFF" + script2 + "\r\n";
251781
+ if (!fileSystem.existsSync(psPath) || fileSystem.readFileSync(psPath, "utf8") !== psContent) {
251782
+ fileSystem.writeFileSync(psPath, psContent, { encoding: "utf8" });
251783
+ }
251784
+ const cmdPath = path8.join(bin, "grain.cmd");
251785
+ if (!fileSystem.existsSync(cmdPath) || fileSystem.readFileSync(cmdPath, "ascii") !== CMD_SCRIPT) {
251786
+ fileSystem.writeFileSync(cmdPath, CMD_SCRIPT, { encoding: "ascii" });
251787
+ }
251788
+ const legacyPath = path8.join(bin, "grain.ps1");
251789
+ if (fileSystem.existsSync(legacyPath)) {
251790
+ fileSystem.rmSync(legacyPath, { force: true });
251791
+ }
251395
251792
  return;
251396
251793
  }
251397
251794
  const script = POSIX_SCRIPT.replace("__GRAIN_HOME__", home);
251398
- fs5.writeFileSync(path7.join(bin, "grain"), script, { mode: 493 });
251399
- fs5.chmodSync(path7.join(bin, "grain"), 493);
251795
+ const commandPath = path8.join(bin, "grain");
251796
+ if (!fileSystem.existsSync(commandPath) || fileSystem.readFileSync(commandPath, "utf8") !== script) {
251797
+ fileSystem.writeFileSync(commandPath, script, { mode: 493 });
251798
+ }
251799
+ if ((fileSystem.statSync(commandPath).mode & 511) !== 493) {
251800
+ fileSystem.chmodSync(commandPath, 493);
251801
+ }
251400
251802
  }
251401
251803
  var POSIX_SCRIPT = `#!/bin/sh
251402
251804
  GRAIN_HOME="\${GRAIN_HOME:-__GRAIN_HOME__}"
@@ -251437,21 +251839,21 @@ var CMD_SCRIPT = '@echo off\r\npowershell -NoProfile -ExecutionPolicy Bypass -Fi
251437
251839
  // src/server/install/addToPathCommand.ts
251438
251840
  function profileForShell(deps) {
251439
251841
  const home = deps.home ?? os2.homedir();
251440
- switch (path8.basename(deps.shell ?? process.env["SHELL"] ?? "sh")) {
251842
+ switch (path9.basename(deps.shell ?? process.env["SHELL"] ?? "sh")) {
251441
251843
  case "zsh":
251442
- return path8.join(deps.zdotdir ?? process.env["ZDOTDIR"] ?? home, ".zshrc");
251844
+ return path9.join(deps.zdotdir ?? process.env["ZDOTDIR"] ?? home, ".zshrc");
251443
251845
  case "bash":
251444
- return path8.join(home, deps.platform === "darwin" ? ".bash_profile" : ".bashrc");
251846
+ return path9.join(home, deps.platform === "darwin" ? ".bash_profile" : ".bashrc");
251445
251847
  case "fish":
251446
- return path8.join(home, ".config/fish/conf.d/grain.fish");
251848
+ return path9.join(home, ".config/fish/conf.d/grain.fish");
251447
251849
  default:
251448
- return path8.join(home, ".profile");
251850
+ return path9.join(home, ".profile");
251449
251851
  }
251450
251852
  }
251451
251853
  function addToPathCommand(deps = {}) {
251452
251854
  const platform2 = deps.platform ?? process.platform;
251453
251855
  const grainHome = deps.grainHome ?? resolveGrainHome();
251454
- const bin = path8.join(grainHome, "bin");
251856
+ const bin = path9.join(grainHome, "bin");
251455
251857
  const output = deps.writeOutput ?? console.log;
251456
251858
  writeGrainCommand(grainHome, platform2);
251457
251859
  if ((deps.noModifyPath ?? process.env["GRAIN_NO_MODIFY_PATH"]) === "1") {
@@ -251475,25 +251877,42 @@ function addToPathCommand(deps = {}) {
251475
251877
  { input: value }
251476
251878
  );
251477
251879
  });
251478
- const current = read();
251479
- if (!current.split(";").some((entry) => entry.toLowerCase() === bin.toLowerCase())) {
251480
- write(current ? `${bin};${current}` : bin);
251481
- output(`Added ${bin} to your user PATH.`);
251482
- } else {
251483
- output("PATH unchanged.");
251880
+ try {
251881
+ const current = read();
251882
+ if (!current.split(";").some((entry) => entry.toLowerCase() === bin.toLowerCase())) {
251883
+ write(current ? `${bin};${current}` : bin);
251884
+ output(`Added ${bin} to your user PATH.`);
251885
+ } else {
251886
+ output("PATH unchanged.");
251887
+ }
251888
+ } catch (error52) {
251889
+ const message = error52 instanceof Error ? error52.message : String(error52);
251890
+ output(
251891
+ `Could not update your user PATH: ${message}. Add ${bin} to your PATH yourself, then open a new terminal.`
251892
+ );
251893
+ return 2;
251484
251894
  }
251485
251895
  } else {
251486
251896
  const profile = profileForShell({ ...deps, platform: platform2 });
251487
- if (!fs6.existsSync(profile) || !fs6.readFileSync(profile, "utf8").includes(bin)) {
251488
- fs6.mkdirSync(path8.dirname(profile), { recursive: true });
251489
- const line = profile.endsWith(".fish") ? `fish_add_path "${bin}"` : `export PATH="${bin}:$PATH"`;
251490
- fs6.appendFileSync(profile, `
251897
+ const line = profile.endsWith(".fish") ? `fish_add_path "${bin}"` : `export PATH="${bin}:$PATH"`;
251898
+ try {
251899
+ if (!fs7.existsSync(profile) || !fs7.readFileSync(profile, "utf8").includes(bin)) {
251900
+ fs7.mkdirSync(path9.dirname(profile), { recursive: true });
251901
+ fs7.appendFileSync(profile, `
251491
251902
  # Added by the Grain installer
251492
251903
  ${line}
251493
251904
  `);
251494
- output(`Added ${bin} to your PATH in ${profile}`);
251495
- } else {
251496
- output("PATH unchanged.");
251905
+ output(`Added ${bin} to your PATH in ${profile}`);
251906
+ } else {
251907
+ output("PATH unchanged.");
251908
+ }
251909
+ } catch (error52) {
251910
+ const message = error52 instanceof Error ? error52.message : String(error52);
251911
+ output(
251912
+ `Could not update ${profile}: ${message}. Add this line to it yourself, then open a new terminal:
251913
+ ${line}`
251914
+ );
251915
+ return 2;
251497
251916
  }
251498
251917
  }
251499
251918
  output("Open a new terminal, then run: grain");
@@ -251502,7 +251921,7 @@ ${line}
251502
251921
 
251503
251922
  // src/server/install/installCommand.ts
251504
251923
  var crypto8 = __toESM(require("crypto"));
251505
- var fs17 = __toESM(require("fs"));
251924
+ var fs18 = __toESM(require("fs"));
251506
251925
  var os4 = __toESM(require("os"));
251507
251926
  var path21 = __toESM(require("path"));
251508
251927
  init_grainHome();
@@ -251512,9 +251931,9 @@ init_DaemonTelemetryService();
251512
251931
 
251513
251932
  // src/server/runtime/NodeRuntimeProvisioner.ts
251514
251933
  var crypto7 = __toESM(require("crypto"));
251515
- var fs14 = __toESM(require("fs"));
251934
+ var fs15 = __toESM(require("fs"));
251516
251935
  var os3 = __toESM(require("os"));
251517
- var path16 = __toESM(require("path"));
251936
+ var path17 = __toESM(require("path"));
251518
251937
  init_ArtifactDownloader();
251519
251938
  init_MinimalTarExtractor();
251520
251939
  init_ManagedArtifactTypes();
@@ -251568,8 +251987,8 @@ var NODE_PLATFORM_PINS = {
251568
251987
 
251569
251988
  // src/server/runtime/daemonRuntimeIdentity.ts
251570
251989
  var import_child_process2 = require("child_process");
251571
- var fs13 = __toESM(require("fs"));
251572
- var path15 = __toESM(require("path"));
251990
+ var fs14 = __toESM(require("fs"));
251991
+ var path16 = __toESM(require("path"));
251573
251992
  var DAEMON_RUNTIME_SIGNING_IDENTIFIER = "tools.grain-daemon";
251574
251993
  function runtimeBinaryName(kind) {
251575
251994
  return kind === "exe" ? "grain-daemon.exe" : "grain-daemon";
@@ -251578,22 +251997,22 @@ function legacyRuntimeBinaryName(kind) {
251578
251997
  return kind === "exe" ? "node.exe" : "node";
251579
251998
  }
251580
251999
  function binaryDir(versionDir, kind) {
251581
- return kind === "exe" ? versionDir : path15.join(versionDir, "bin");
252000
+ return kind === "exe" ? versionDir : path16.join(versionDir, "bin");
251582
252001
  }
251583
252002
  function runtimeBinaryPath(versionDir, kind) {
251584
- return path15.join(binaryDir(versionDir, kind), runtimeBinaryName(kind));
252003
+ return path16.join(binaryDir(versionDir, kind), runtimeBinaryName(kind));
251585
252004
  }
251586
252005
  function legacyRuntimeBinaryPath(versionDir, kind) {
251587
- return path15.join(binaryDir(versionDir, kind), legacyRuntimeBinaryName(kind));
252006
+ return path16.join(binaryDir(versionDir, kind), legacyRuntimeBinaryName(kind));
251588
252007
  }
251589
252008
  function adoptRuntimeBinary(versionDir, kind, platform2 = process.platform) {
251590
252009
  const target = runtimeBinaryPath(versionDir, kind);
251591
252010
  const legacy = legacyRuntimeBinaryPath(versionDir, kind);
251592
252011
  let outcome;
251593
- if (fs13.existsSync(target)) {
252012
+ if (fs14.existsSync(target)) {
251594
252013
  outcome = "already-adopted";
251595
- } else if (fs13.existsSync(legacy)) {
251596
- fs13.renameSync(legacy, target);
252014
+ } else if (fs14.existsSync(legacy)) {
252015
+ fs14.renameSync(legacy, target);
251597
252016
  outcome = "renamed";
251598
252017
  } else {
251599
252018
  return "nothing-to-adopt";
@@ -251656,7 +252075,7 @@ var _NodeRuntimeProvisioner = class {
251656
252075
  installedNodePath() {
251657
252076
  const binary = this.binaryPath();
251658
252077
  try {
251659
- fs14.accessSync(binary, fs14.constants.X_OK);
252078
+ fs15.accessSync(binary, fs15.constants.X_OK);
251660
252079
  return binary;
251661
252080
  } catch {
251662
252081
  return this.adoptLegacyInstall();
@@ -251673,7 +252092,7 @@ var _NodeRuntimeProvisioner = class {
251673
252092
  return null;
251674
252093
  }
251675
252094
  try {
251676
- fs14.accessSync(this.binaryPath(), fs14.constants.X_OK);
252095
+ fs15.accessSync(this.binaryPath(), fs15.constants.X_OK);
251677
252096
  return this.binaryPath();
251678
252097
  } catch {
251679
252098
  return null;
@@ -251685,7 +252104,7 @@ var _NodeRuntimeProvisioner = class {
251685
252104
  if (existing) {
251686
252105
  return existing;
251687
252106
  }
251688
- const key = path16.resolve(this.versionDir());
252107
+ const key = path17.resolve(this.versionDir());
251689
252108
  const pending = _NodeRuntimeProvisioner.inFlight.get(key);
251690
252109
  if (pending) {
251691
252110
  return pending;
@@ -251703,7 +252122,7 @@ var _NodeRuntimeProvisioner = class {
251703
252122
  async provisionWithLock() {
251704
252123
  const pin = this.pin();
251705
252124
  const downloadDir = this.options.downloadDir ?? os3.tmpdir();
251706
- fs14.mkdirSync(downloadDir, { recursive: true });
252125
+ fs15.mkdirSync(downloadDir, { recursive: true });
251707
252126
  const finalDir = this.versionDir();
251708
252127
  const lock = await this.acquireProvisionLock(`${finalDir}.provision-lock`);
251709
252128
  try {
@@ -251713,9 +252132,9 @@ var _NodeRuntimeProvisioner = class {
251713
252132
  if (lockedExisting) {
251714
252133
  return lockedExisting;
251715
252134
  }
251716
- fs14.rmSync(finalDir, { recursive: true, force: true });
251717
- const stagingDir = fs14.mkdtempSync(path16.join(downloadDir, "grain-node-"));
251718
- const downloadPath = path16.join(stagingDir, pin.kind === "exe" ? "node.exe" : "node.tar.gz");
252135
+ fs15.rmSync(finalDir, { recursive: true, force: true });
252136
+ const stagingDir = fs15.mkdtempSync(path17.join(downloadDir, "grain-node-"));
252137
+ const downloadPath = path17.join(stagingDir, pin.kind === "exe" ? "node.exe" : "node.tar.gz");
251719
252138
  try {
251720
252139
  await downloadToFile(pin.url, downloadPath);
251721
252140
  const actual = await sha256File(downloadPath);
@@ -251724,24 +252143,24 @@ var _NodeRuntimeProvisioner = class {
251724
252143
  `Node runtime checksum mismatch for ${pin.platform}: expected ${pin.sha256}, got ${actual}`
251725
252144
  );
251726
252145
  }
251727
- const unpackDir = path16.join(stagingDir, "unpacked");
251728
- fs14.mkdirSync(unpackDir, { recursive: true });
252146
+ const unpackDir = path17.join(stagingDir, "unpacked");
252147
+ fs15.mkdirSync(unpackDir, { recursive: true });
251729
252148
  if (pin.kind === "exe") {
251730
- fs14.copyFileSync(downloadPath, path16.join(unpackDir, "node.exe"));
252149
+ fs15.copyFileSync(downloadPath, path17.join(unpackDir, "node.exe"));
251731
252150
  } else {
251732
252151
  await extractTarGz(downloadPath, unpackDir);
251733
252152
  }
251734
- const extractedBinary = path16.join(unpackDir, pin.binaryPathInArchive);
251735
- if (!fs14.existsSync(extractedBinary)) {
252153
+ const extractedBinary = path17.join(unpackDir, pin.binaryPathInArchive);
252154
+ if (!fs15.existsSync(extractedBinary)) {
251736
252155
  throw new Error(`Node artifact did not contain ${pin.binaryPathInArchive}`);
251737
252156
  }
251738
- fs14.chmodSync(extractedBinary, 493);
251739
- fs14.mkdirSync(path16.dirname(finalDir), { recursive: true });
252157
+ fs15.chmodSync(extractedBinary, 493);
252158
+ fs15.mkdirSync(path17.dirname(finalDir), { recursive: true });
251740
252159
  const archiveRoot = pin.binaryPathInArchive.split("/")[0];
251741
252160
  if (!archiveRoot && pin.kind !== "exe") {
251742
252161
  throw new Error(`Node artifact has an invalid binary path: ${pin.binaryPathInArchive}`);
251743
252162
  }
251744
- const sourceRoot = pin.kind === "exe" ? unpackDir : path16.join(unpackDir, archiveRoot ?? "");
252163
+ const sourceRoot = pin.kind === "exe" ? unpackDir : path17.join(unpackDir, archiveRoot ?? "");
251745
252164
  this.moveIntoPlace(sourceRoot, finalDir);
251746
252165
  adoptRuntimeBinary(finalDir, pin.kind);
251747
252166
  const provisioned = this.installedNodePath();
@@ -251761,16 +252180,16 @@ var _NodeRuntimeProvisioner = class {
251761
252180
  }
251762
252181
  }
251763
252182
  async acquireProvisionLock(lockDir) {
251764
- fs14.mkdirSync(path16.dirname(lockDir), { recursive: true });
252183
+ fs15.mkdirSync(path17.dirname(lockDir), { recursive: true });
251765
252184
  const startedAt = Date.now();
251766
252185
  const staleMs = this.options.provisionLockStaleMs ?? PROVISION_LOCK_STALE_MS;
251767
252186
  const maxWaitMs = this.options.provisionLockMaxWaitMs ?? PROVISION_LOCK_MAX_WAIT_MS;
251768
252187
  const token = `${process.pid}-${crypto7.randomUUID()}`;
251769
252188
  for (; ; ) {
251770
252189
  try {
251771
- fs14.mkdirSync(lockDir);
252190
+ fs15.mkdirSync(lockDir);
251772
252191
  try {
251773
- fs14.writeFileSync(path16.join(lockDir, "owner"), token, "utf8");
252192
+ fs15.writeFileSync(path17.join(lockDir, "owner"), token, "utf8");
251774
252193
  } catch (error52) {
251775
252194
  this.removeBestEffort(lockDir);
251776
252195
  throw error52;
@@ -251779,7 +252198,7 @@ var _NodeRuntimeProvisioner = class {
251779
252198
  () => {
251780
252199
  try {
251781
252200
  const now = Date.now() / 1e3;
251782
- fs14.utimesSync(lockDir, now, now);
252201
+ fs15.utimesSync(lockDir, now, now);
251783
252202
  } catch {
251784
252203
  return;
251785
252204
  }
@@ -251805,7 +252224,7 @@ var _NodeRuntimeProvisioner = class {
251805
252224
  }
251806
252225
  isStaleLock(lockDir, staleMs) {
251807
252226
  try {
251808
- return Date.now() - fs14.statSync(lockDir).mtimeMs > staleMs;
252227
+ return Date.now() - fs15.statSync(lockDir).mtimeMs > staleMs;
251809
252228
  } catch {
251810
252229
  return false;
251811
252230
  }
@@ -251813,8 +252232,8 @@ var _NodeRuntimeProvisioner = class {
251813
252232
  releaseProvisionLock(lock) {
251814
252233
  clearInterval(lock.heartbeat);
251815
252234
  try {
251816
- if (fs14.readFileSync(path16.join(lock.directory, "owner"), "utf8") === lock.token) {
251817
- fs14.rmSync(lock.directory, { recursive: true, force: true });
252235
+ if (fs15.readFileSync(path17.join(lock.directory, "owner"), "utf8") === lock.token) {
252236
+ fs15.rmSync(lock.directory, { recursive: true, force: true });
251818
252237
  }
251819
252238
  } catch {
251820
252239
  return;
@@ -251824,7 +252243,7 @@ var _NodeRuntimeProvisioner = class {
251824
252243
  const staleMs = this.options.stagingDirStaleMs ?? STAGING_DIR_STALE_MS;
251825
252244
  let entries;
251826
252245
  try {
251827
- entries = fs14.readdirSync(downloadDir, { withFileTypes: true });
252246
+ entries = fs15.readdirSync(downloadDir, { withFileTypes: true });
251828
252247
  } catch {
251829
252248
  return;
251830
252249
  }
@@ -251832,9 +252251,9 @@ var _NodeRuntimeProvisioner = class {
251832
252251
  if (!entry.isDirectory() || !entry.name.startsWith("grain-node-")) {
251833
252252
  continue;
251834
252253
  }
251835
- const stagingDir = path16.join(downloadDir, entry.name);
252254
+ const stagingDir = path17.join(downloadDir, entry.name);
251836
252255
  try {
251837
- if (Date.now() - fs14.statSync(stagingDir).mtimeMs > staleMs) {
252256
+ if (Date.now() - fs15.statSync(stagingDir).mtimeMs > staleMs) {
251838
252257
  this.removeBestEffort(stagingDir);
251839
252258
  }
251840
252259
  } catch {
@@ -251843,12 +252262,12 @@ var _NodeRuntimeProvisioner = class {
251843
252262
  }
251844
252263
  }
251845
252264
  reapDestinationStages(finalDir) {
251846
- const parentDir = path16.dirname(finalDir);
251847
- const prefix = `.${path16.basename(finalDir)}-tmp-`;
252265
+ const parentDir = path17.dirname(finalDir);
252266
+ const prefix = `.${path17.basename(finalDir)}-tmp-`;
251848
252267
  const staleMs = this.options.stagingDirStaleMs ?? STAGING_DIR_STALE_MS;
251849
252268
  let entries;
251850
252269
  try {
251851
- entries = fs14.readdirSync(parentDir, { withFileTypes: true });
252270
+ entries = fs15.readdirSync(parentDir, { withFileTypes: true });
251852
252271
  } catch {
251853
252272
  return;
251854
252273
  }
@@ -251856,9 +252275,9 @@ var _NodeRuntimeProvisioner = class {
251856
252275
  if (!entry.isDirectory() || !entry.name.startsWith(prefix)) {
251857
252276
  continue;
251858
252277
  }
251859
- const destinationStage = path16.join(parentDir, entry.name);
252278
+ const destinationStage = path17.join(parentDir, entry.name);
251860
252279
  try {
251861
- if (Date.now() - fs14.statSync(destinationStage).mtimeMs > staleMs) {
252280
+ if (Date.now() - fs15.statSync(destinationStage).mtimeMs > staleMs) {
251862
252281
  this.removeBestEffort(destinationStage);
251863
252282
  }
251864
252283
  } catch {
@@ -251868,25 +252287,25 @@ var _NodeRuntimeProvisioner = class {
251868
252287
  }
251869
252288
  removeBestEffort(target) {
251870
252289
  try {
251871
- fs14.rmSync(target, { recursive: true, force: true });
252290
+ fs15.rmSync(target, { recursive: true, force: true });
251872
252291
  } catch {
251873
252292
  return;
251874
252293
  }
251875
252294
  }
251876
252295
  moveIntoPlace(source, destination) {
251877
252296
  try {
251878
- fs14.renameSync(source, destination);
252297
+ fs15.renameSync(source, destination);
251879
252298
  } catch (error52) {
251880
252299
  if (error52.code !== "EXDEV") {
251881
252300
  throw error52;
251882
252301
  }
251883
252302
  let destinationStage;
251884
252303
  try {
251885
- destinationStage = fs14.mkdtempSync(
251886
- path16.join(path16.dirname(destination), `.${path16.basename(destination)}-tmp-`)
252304
+ destinationStage = fs15.mkdtempSync(
252305
+ path17.join(path17.dirname(destination), `.${path17.basename(destination)}-tmp-`)
251887
252306
  );
251888
- fs14.cpSync(source, destinationStage, { recursive: true });
251889
- fs14.renameSync(destinationStage, destination);
252307
+ fs15.cpSync(source, destinationStage, { recursive: true });
252308
+ fs15.renameSync(destinationStage, destination);
251890
252309
  destinationStage = void 0;
251891
252310
  this.removeBestEffort(source);
251892
252311
  } finally {
@@ -251946,15 +252365,15 @@ function generateLaunchAgent(descriptor) {
251946
252365
  }
251947
252366
 
251948
252367
  // src/server/install/launcher.ts
251949
- var path18 = __toESM(require("path"));
252368
+ var path19 = __toESM(require("path"));
251950
252369
  init_protocolVersion();
251951
252370
 
251952
252371
  // src/server/install/launchFailureMarker.ts
251953
- var fs15 = __toESM(require("fs"));
251954
- var path17 = __toESM(require("path"));
252372
+ var fs16 = __toESM(require("fs"));
252373
+ var path18 = __toESM(require("path"));
251955
252374
  var LAUNCH_FAILURE_MARKER_FILENAME = "grain-launch-failure.json";
251956
252375
  function launchFailureMarkerPath(configHome) {
251957
- return path17.join(configHome, LAUNCH_FAILURE_MARKER_FILENAME);
252376
+ return path18.join(configHome, LAUNCH_FAILURE_MARKER_FILENAME);
251958
252377
  }
251959
252378
  function isLaunchFailureReason(value) {
251960
252379
  return value === "no_payload" || value === "spawn_failed" || value === "launch_attempt";
@@ -251966,7 +252385,7 @@ function isLaunchFailureMarker(value) {
251966
252385
  const entry = value;
251967
252386
  return isLaunchFailureReason(entry["reason"]) && typeof entry["message"] === "string" && typeof entry["at"] === "number" && Number.isFinite(entry["at"]) && (entry["version"] === void 0 || typeof entry["version"] === "string") && (entry["recoveredFrom"] === void 0 || typeof entry["recoveredFrom"] === "string");
251968
252387
  }
251969
- function readAndClearLaunchFailureMarker(configHome, fileSystem = fs15) {
252388
+ function readAndClearLaunchFailureMarker(configHome, fileSystem = fs16) {
251970
252389
  const markerPath = launchFailureMarkerPath(configHome);
251971
252390
  if (!fileSystem.existsSync(markerPath)) {
251972
252391
  return void 0;
@@ -251990,7 +252409,7 @@ function readAndClearLaunchFailureMarker(configHome, fileSystem = fs15) {
251990
252409
  // src/server/install/launcher.ts
251991
252410
  var LAUNCHER_FILENAME = "grain-daemon-launcher.js";
251992
252411
  function launcherPath(configHome) {
251993
- return path18.join(configHome, LAUNCHER_FILENAME);
252412
+ return path19.join(configHome, LAUNCHER_FILENAME);
251994
252413
  }
251995
252414
  function launcherSource(configHome) {
251996
252415
  return `#!/usr/bin/env node
@@ -252090,7 +252509,8 @@ const recoveredFrom = recoverFromFailedLaunch(previousMarker);
252090
252509
  const payload = resolvePayload();
252091
252510
  if (!payload) {
252092
252511
  writeLaunchFailureMarker('no_payload', 'No valid daemon payload pointer was found.');
252093
- console.error('[grain] No valid daemon payload pointer was found. Reinstall Grain from VS Code or npx -y grain-tools install.');
252512
+ const installCmd = process.platform === 'win32' ? 'irm https://grain.tools/install.ps1 | iex' : 'curl -fsSL https://grain.tools/install.sh | sh';
252513
+ console.error('[grain] No valid daemon payload pointer was found. Reinstall Grain from VS Code or run: ' + installCmd);
252094
252514
  process.exit(1);
252095
252515
  }
252096
252516
 
@@ -252207,23 +252627,11 @@ function generateWindowsStartupTask(descriptor) {
252207
252627
  };
252208
252628
  }
252209
252629
 
252210
- // src/common/serviceMode.ts
252211
- var path20 = __toESM(require("path"));
252212
- var SERVICE_MODE_FILENAME = "service-mode.json";
252213
- function serviceModePath(configDir) {
252214
- return path20.join(configDir, SERVICE_MODE_FILENAME);
252215
- }
252216
- function writeServiceMode(fileSystem, configDir, record2) {
252217
- fileSystem.writeFileSync(serviceModePath(configDir), `${JSON.stringify(record2, null, 2)}
252218
- `, {
252219
- mode: 384
252220
- });
252221
- }
252222
-
252223
252630
  // src/server/install/installCommand.ts
252631
+ init_serviceMode();
252224
252632
  init_acquisitionChannel();
252225
252633
  init_telemetryConsent();
252226
- var GRAIN_SERVICE_LABEL = `tools.${DAEMON_SERVICE_IDENTITY}`;
252634
+ init_daemonRecordInstance();
252227
252635
  function unitFor(platform2, launcher, configHome, nodePath) {
252228
252636
  const descriptor = {
252229
252637
  launcherPath: launcher,
@@ -252344,15 +252752,19 @@ function registerCliPayload(fileSystem, configHome, standalonePath, writeOutput)
252344
252752
  if (!fileSystem.existsSync(standalonePath)) {
252345
252753
  return;
252346
252754
  }
252347
- const installedEntry = installApplicationPayload({
252348
- configHome,
252349
- version: version3,
252350
- sourceEntry: standalonePath
252351
- });
252755
+ const installedEntry = path21.join(configHome, "app", version3, "standalone.js");
252756
+ const manifestPath = path21.join(configHome, "app", version3, "package.json");
252757
+ const payloadUnchanged = fileSystem.existsSync(installedEntry) && fileSystem.existsSync(manifestPath) && fileSystem.readFileSync(installedEntry).equals(fileSystem.readFileSync(standalonePath));
252758
+ if (!payloadUnchanged) {
252759
+ installApplicationPayload({ configHome, version: version3, sourceEntry: standalonePath });
252760
+ }
252352
252761
  const versionsDir = path21.join(configHome, "versions");
252353
252762
  fileSystem.mkdirSync(versionsDir, { recursive: true });
252354
252763
  const pointerPath2 = path21.join(versionsDir, `${version3}.json`);
252355
- writeAtomicPointer(fileSystem, pointerPath2, JSON.stringify({ path: installedEntry, version: version3 }));
252764
+ const pointerContents = JSON.stringify({ path: installedEntry, version: version3 });
252765
+ if (!fileSystem.existsSync(pointerPath2) || fileSystem.readFileSync(pointerPath2, "utf8") !== pointerContents) {
252766
+ writeAtomicPointer(fileSystem, pointerPath2, pointerContents);
252767
+ }
252356
252768
  } catch (error52) {
252357
252769
  writeOutput(`Warning: could not register this build for the launcher: ${describeError(error52)}`);
252358
252770
  }
@@ -252365,7 +252777,7 @@ async function installCommand(deps = {}) {
252365
252777
  const configHome = deps.configHome ?? resolveGrainHome();
252366
252778
  const homeDirectory = deps.homeDirectory ?? os4.homedir();
252367
252779
  const uid = deps.uid ?? process.getuid?.() ?? 0;
252368
- const fileSystem = deps.fileSystem ?? fs17;
252780
+ const fileSystem = deps.fileSystem ?? fs18;
252369
252781
  const runner = deps.commandRunner ?? createCommandRunner();
252370
252782
  const adapter2 = deps.adapter ?? createSupervisorAdapter(platform2, runner, uid);
252371
252783
  const readStatus = deps.readStatus ?? readGrainServiceStatus;
@@ -252374,11 +252786,11 @@ async function installCommand(deps = {}) {
252374
252786
  const telemetryConsentFlag = deps.telemetryConsent;
252375
252787
  const standalonePath = deps.standalonePath ?? require.main?.filename;
252376
252788
  fileSystem.mkdirSync(configHome, { recursive: true });
252377
- writeGrainCommand(configHome, platform2);
252789
+ writeGrainCommand(configHome, platform2, fileSystem);
252378
252790
  if (standalonePath !== void 0) {
252379
252791
  registerCliPayload(fileSystem, configHome, standalonePath, writeOutput);
252380
252792
  }
252381
- if (readAcquisitionChannelStatus(configHome).type === "missing") {
252793
+ if (readAcquisitionChannelStatus(configHome).type !== "valid") {
252382
252794
  writeAcquisitionChannel(fileSystem, configHome, {
252383
252795
  channel: acquisitionChannelFromEnvironment(process.env)
252384
252796
  });
@@ -252390,10 +252802,22 @@ async function installCommand(deps = {}) {
252390
252802
  flag: telemetryConsentFlag
252391
252803
  });
252392
252804
  const telemetry = deps.telemetry ?? new DaemonTelemetryService({ configDir: configHome });
252393
- const nodePath = deps.nodePath ?? await new NodeRuntimeProvisioner({ sqlPreviewHome: configHome, telemetry }).provision();
252394
252805
  const captureLifecycle = (properties) => {
252395
252806
  telemetry.capture("service_lifecycle", properties);
252396
252807
  };
252808
+ const nodePath = deps.nodePath ?? await new NodeRuntimeProvisioner({ sqlPreviewHome: configHome, telemetry }).provision().catch(async (error52) => {
252809
+ const failure = new AppError("service_runtime_provision_failed", describeError(error52), {
252810
+ cause: error52
252811
+ });
252812
+ captureLifecycle({
252813
+ state: "standalone_mcp",
252814
+ phase: "install",
252815
+ outcome: "failed",
252816
+ error_id: failure.errorId
252817
+ });
252818
+ await flushTelemetry(telemetry);
252819
+ throw error52;
252820
+ });
252397
252821
  const launcher = platformLauncherPath(platform2, configHome);
252398
252822
  const unit = unitFor(platform2, launcher, configHome, nodePath);
252399
252823
  const unitPath = path21.join(homeDirectory, unit.destination);
@@ -252493,7 +252917,7 @@ Check the supervisor logs at ${path21.join(configHome, "grain-daemon.out.log")}
252493
252917
  }
252494
252918
 
252495
252919
  // src/server/install/uninstallCommand.ts
252496
- var fs18 = __toESM(require("fs"));
252920
+ var fs19 = __toESM(require("fs"));
252497
252921
  var os5 = __toESM(require("os"));
252498
252922
  var path22 = __toESM(require("path"));
252499
252923
  init_grainHome();
@@ -252528,7 +252952,7 @@ async function uninstallCommand(deps = {}) {
252528
252952
  const homeDirectory = deps.homeDirectory ?? os5.homedir();
252529
252953
  const uid = deps.uid ?? process.getuid?.() ?? 0;
252530
252954
  const nodePath = deps.nodePath ?? "";
252531
- const fileSystem = deps.fileSystem ?? fs18;
252955
+ const fileSystem = deps.fileSystem ?? fs19;
252532
252956
  const runner = deps.commandRunner ?? createCommandRunner();
252533
252957
  const adapter2 = deps.adapter ?? createSupervisorAdapter(platform2, runner, uid);
252534
252958
  const writeOutput = deps.writeOutput ?? ((message) => console.log(message));
@@ -252952,12 +253376,17 @@ Options:
252952
253376
  init_AppError();
252953
253377
 
252954
253378
  // src/server/bridge/notSetUpNotice.ts
252955
- var NOT_SET_UP_MESSAGE = "Grain is not set up on this machine, so this session is running on its own and will not appear in your other Grain surfaces. Run: npx -y grain-tools install";
252956
- function resolveNotSetUpMessage(hasConnectionsEnv) {
252957
- return hasConnectionsEnv ? void 0 : NOT_SET_UP_MESSAGE;
253379
+ function getNotSetUpMessage(platform2 = process.platform) {
253380
+ const command = platform2 === "win32" ? "irm https://grain.tools/install.ps1 | iex" : "curl -fsSL https://grain.tools/install.sh | sh";
253381
+ return `Grain is not set up on this machine, so this session is running on its own and will not appear in your other Grain surfaces. Run: ${command}`;
253382
+ }
253383
+ function resolveNotSetUpMessage(hasConnectionsEnv, platform2 = process.platform) {
253384
+ return hasConnectionsEnv ? void 0 : getNotSetUpMessage(platform2);
252958
253385
  }
252959
253386
 
252960
253387
  // src/server/standalone.ts
253388
+ init_daemonRecordInstance();
253389
+ init_supervisorAdapter();
252961
253390
  var SERVICE_START_FLUSH_BUDGET_MS = 2e3;
252962
253391
  async function flushWithinBudget(telemetry, budgetMs) {
252963
253392
  let timer;
@@ -253025,41 +253454,124 @@ async function handleLaunchFailureMarker(configDir, telemetry) {
253025
253454
  return;
253026
253455
  }
253027
253456
  }
253028
- async function main() {
253457
+ async function connectStdioToSharedDaemon(args, env2, configDir, embedded, deps = {}) {
253458
+ if (embedded) {
253459
+ return { bridged: false };
253460
+ }
253461
+ const resolve11 = deps.resolveDaemonAddress ?? resolveDaemonAddress;
253462
+ const probeDaemon = deps.probeSharedDaemon ?? probeSharedDaemon;
253463
+ const authToken = deps.readDaemonAuthToken ?? readDaemonAuthToken;
253464
+ const agentToken = deps.readAgentToken ?? readAgentToken;
253465
+ const tokenAccepted = deps.isTokenAccepted ?? isTokenAccepted;
253466
+ const bridge = deps.runStdioBridge ?? runStdioBridge;
253467
+ const launchFailureMarker = deps.handleLaunchFailureMarker ?? handleLaunchFailureMarker;
253468
+ const now = deps.now ?? Date.now;
253469
+ const sleep = deps.sleep ?? ((milliseconds) => new Promise((r) => setTimeout(r, milliseconds)));
253470
+ const resolved = () => resolve11({ args, env: env2, configDir });
253471
+ async function inspect() {
253472
+ const endpoint = resolved();
253473
+ if (!endpoint.address) {
253474
+ return { endpoint };
253475
+ }
253476
+ const accessToken = authToken(configDir);
253477
+ const expected = endpoint.record ? { pid: endpoint.record.pid, startedAt: endpoint.record.startedAt, token: accessToken } : accessToken ? { token: accessToken } : void 0;
253478
+ const probed = await probeDaemon(endpoint.address.port, 500, expected);
253479
+ const token = agentToken(configDir);
253480
+ const foreignReason = !probed.identity ? void 0 : !token ? "no-agent-token" : await tokenAccepted(endpoint.address.port, token, 500) ? void 0 : "agent-token-rejected";
253481
+ const probe2 = foreignReason ? { attempts: probed.attempts, failureReason: foreignReason } : probed;
253482
+ return { endpoint, probe: probe2 };
253483
+ }
253484
+ async function attach(result2, started) {
253485
+ const { address: address2, source: source2 } = result2.endpoint;
253486
+ const identity2 = result2.probe?.identity;
253487
+ if (!address2 || !identity2) {
253488
+ return false;
253489
+ }
253490
+ if (started) {
253491
+ console.error("[grain] started the Grain service and bridged stdio to it");
253492
+ } else {
253493
+ console.error(
253494
+ `[grain] bridging stdio to shared daemon v${identity2.version ?? "?"} on ${address2.host}:${address2.port} (via ${source2}, RFC-082) after ${result2.probe?.attempts} attempt(s)`
253495
+ );
253496
+ }
253497
+ await launchFailureMarker(configDir);
253498
+ await bridge(address2.port);
253499
+ return true;
253500
+ }
253501
+ let result = await inspect();
253502
+ if (await attach(result, false)) {
253503
+ return { bridged: true };
253504
+ }
253505
+ const foreignReasons = ["wrong-instance", "no-agent-token", "agent-token-rejected"];
253506
+ let serviceReason;
253507
+ if (!result.probe?.failureReason || !foreignReasons.includes(result.probe.failureReason)) {
253508
+ try {
253509
+ const adapter2 = deps.adapter ?? createSupervisorAdapter(
253510
+ process.platform,
253511
+ createCommandRunner(),
253512
+ process.getuid?.() ?? 0
253513
+ );
253514
+ if (await adapter2.isRegistered(GRAIN_SERVICE_LABEL)) {
253515
+ await adapter2.start(GRAIN_SERVICE_LABEL);
253516
+ const deadline = now() + 1e4;
253517
+ do {
253518
+ result = await inspect();
253519
+ if (await attach(result, true)) {
253520
+ return { bridged: true };
253521
+ }
253522
+ if (result.probe?.failureReason && foreignReasons.includes(result.probe.failureReason)) {
253523
+ serviceReason = result.probe.failureReason;
253524
+ break;
253525
+ }
253526
+ if (now() >= deadline) {
253527
+ break;
253528
+ }
253529
+ await sleep(Math.min(250, deadline - now()));
253530
+ } while (now() <= deadline);
253531
+ serviceReason ?? (serviceReason = "service did not publish a reachable endpoint within 10 s");
253532
+ } else {
253533
+ serviceReason = "service not registered";
253534
+ }
253535
+ } catch (error52) {
253536
+ serviceReason = `service start failed: ${error52 instanceof Error ? error52.message : String(error52)}`;
253537
+ }
253538
+ }
253539
+ const { address, source, record: record2 } = result.endpoint;
253540
+ const probe = result.probe;
253541
+ if (address && probe) {
253542
+ const reasonStr = probe.failureReason === "stale-record" ? `stale-record pid ${record2?.pid}` : probe.failureReason;
253543
+ const detail = probe.failureReason === "no-agent-token" ? `answered, but ${configDir} has no agent-token for this bridge to present` : probe.failureReason === "wrong-instance" || probe.failureReason === "agent-token-rejected" ? `answered, but it does not accept the tokens in ${configDir}, so it belongs to a different Grain home` : void 0;
253544
+ console.error(
253545
+ (detail ? `[grain] the daemon at ${address.host}:${address.port} (via ${source}) ${detail} (${reasonStr}); check GRAIN_HOME in this MCP server's config. Starting embedded stdio ` : `[grain] no shared daemon at ${address.host}:${address.port} (via ${source}) after ${probe.attempts} attempt(s) (${reasonStr}); starting embedded stdio `) + `daemon \u2014 this session's queries will not appear in the extension's results panel` + (serviceReason ? ` (${serviceReason})` : "")
253546
+ );
253547
+ } else {
253548
+ console.error(
253549
+ `[grain] no daemon endpoint published in ${configDir} and no port pinned; starting embedded stdio daemon \u2014 this session's queries will not appear in the extension's results panel (${serviceReason ?? "no reachable service"})`
253550
+ );
253551
+ }
253552
+ return {
253553
+ bridged: false,
253554
+ notSetUpMessage: resolveNotSetUpMessage(Boolean(env2["GRAIN_CONNECTIONS"]))
253555
+ };
253556
+ }
253557
+ async function main(deps = {}) {
253029
253558
  await dispatchSubcommand(process.argv.slice(2));
253030
253559
  const args = parseArgs();
253031
253560
  const isStdio = args["stdio"] === "true";
253032
253561
  const isEmbedded = args["embedded"] === "true" || process.env["GRAIN_EMBEDDED"] === "1";
253033
253562
  let notSetUpMessage;
253034
253563
  if (isStdio && !isEmbedded) {
253035
- const configDir = defaultDaemonConfigDir();
253036
- const { address, source, record: record2 } = resolveDaemonAddress({ args, env: process.env, configDir });
253037
- if (address) {
253038
- const expected = record2 ? {
253039
- pid: record2.pid,
253040
- startedAt: record2.startedAt,
253041
- token: readDaemonAuthToken(configDir)
253042
- } : void 0;
253043
- const probe = await probeSharedDaemon(address.port, 500, expected);
253044
- if (probe.identity) {
253045
- console.error(
253046
- `[grain] bridging stdio to shared daemon v${probe.identity.version ?? "?"} on ${address.host}:${address.port} (via ${source}, RFC-082) after ${probe.attempts} attempt(s)`
253047
- );
253048
- await handleLaunchFailureMarker(configDir);
253049
- await runStdioBridge(address.port);
253050
- return;
253051
- }
253052
- const reasonStr = probe.failureReason === "stale-record" ? `stale-record pid ${expected?.pid}` : probe.failureReason;
253053
- console.error(
253054
- `[grain] no shared daemon at ${address.host}:${address.port} (via ${source}) after ${probe.attempts} attempt(s) (${reasonStr}); starting embedded stdio daemon \u2014 this session's queries will not appear in the extension's results panel`
253055
- );
253056
- notSetUpMessage = resolveNotSetUpMessage(Boolean(process.env["GRAIN_CONNECTIONS"]));
253057
- } else {
253058
- console.error(
253059
- `[grain] no daemon endpoint published in ${configDir} and no port pinned; starting embedded stdio daemon \u2014 this session's queries will not appear in the extension's results panel`
253060
- );
253061
- notSetUpMessage = resolveNotSetUpMessage(Boolean(process.env["GRAIN_CONNECTIONS"]));
253564
+ const result = await connectStdioToSharedDaemon(
253565
+ args,
253566
+ process.env,
253567
+ defaultDaemonConfigDir(),
253568
+ false,
253569
+ deps
253570
+ );
253571
+ if (result.bridged) {
253572
+ return;
253062
253573
  }
253574
+ notSetUpMessage = result.notSetUpMessage;
253063
253575
  }
253064
253576
  if (!isStdio) {
253065
253577
  console.log("[INFO] Grain daemon process starting...");
@@ -253163,6 +253675,7 @@ if (require.main === module) {
253163
253675
  // Annotate the CommonJS export names for ESM import in node:
253164
253676
  0 && (module.exports = {
253165
253677
  SERVICE_START_FLUSH_BUDGET_MS,
253678
+ connectStdioToSharedDaemon,
253166
253679
  main
253167
253680
  });
253168
253681
  /*! Bundled license information: