grain-tools 0.10.13 → 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";
@@ -19278,6 +19279,19 @@ var init_StdioBridge = __esm({
19278
19279
  }
19279
19280
  async forwardAgentMessage(message, fatal) {
19280
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
+ }
19281
19295
  const isHandshake = isInitialize || "method" in message && message.method === "notifications/initialized";
19282
19296
  if (!isInitialize && this.sessionOpening) {
19283
19297
  await this.sessionOpening;
@@ -19476,6 +19490,48 @@ var init_DaemonAuthToken = __esm({
19476
19490
  }
19477
19491
  });
19478
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
+
19479
19535
  // src/common/localUrl.ts
19480
19536
  function formatUserFacingLocalUrl(host, port) {
19481
19537
  const displayHost = host === "127.0.0.1" || host === "::1" ? "localhost" : host;
@@ -19495,7 +19551,7 @@ async function readGrainServiceStatus(configDir = resolveGrainHome()) {
19495
19551
  let reason = "";
19496
19552
  switch (endpoint.type) {
19497
19553
  case "missing":
19498
- reason = GRAIN_NOT_INSTALLED_MESSAGE;
19554
+ reason = readServiceModeStatus(configDir).type === "valid" ? GRAIN_STARTS_ON_DEMAND_MESSAGE : GRAIN_NOT_INSTALLED_MESSAGE;
19499
19555
  break;
19500
19556
  case "unparseable":
19501
19557
  reason = "Grain's note of where it is listening is damaged, so it cannot be reached. Run `grain install` to rewrite it.";
@@ -19555,15 +19611,17 @@ async function statusCommand() {
19555
19611
  console.log(JSON.stringify(await readGrainServiceStatus(), null, 2));
19556
19612
  return 0;
19557
19613
  }
19558
- var http2;
19614
+ var http2, GRAIN_STARTS_ON_DEMAND_MESSAGE;
19559
19615
  var init_statusCommand = __esm({
19560
19616
  "src/server/cli/statusCommand.ts"() {
19561
19617
  "use strict";
19562
19618
  http2 = __toESM(require("http"));
19563
19619
  init_daemonEndpointFile();
19564
19620
  init_grainHome();
19621
+ init_serviceMode();
19565
19622
  init_daemonRecordInstance();
19566
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.";
19567
19625
  }
19568
19626
  });
19569
19627
 
@@ -19590,6 +19648,206 @@ var init_firstValueStep = __esm({
19590
19648
  }
19591
19649
  });
19592
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
+
19593
19851
  // src/common/telemetry/TelemetrySchema.ts
19594
19852
  function isTelemetryEventName(value) {
19595
19853
  return EVENT_SET.has(value);
@@ -19615,6 +19873,38 @@ function normalizeTelemetryConnector(value) {
19615
19873
  function isTelemetryErrorCode(value) {
19616
19874
  return typeof value === "string" && ERROR_CODE_SET.has(value);
19617
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
+ }
19618
19908
  function normalizeTelemetryToolName(value) {
19619
19909
  return value && TOOL_NAME_SET.has(value) ? value : "unknown";
19620
19910
  }
@@ -19784,6 +20074,10 @@ function sanitizeTelemetryProperty(rule, value) {
19784
20074
  return typeof value === "string" && DISCOVERY_KEY_PATTERN.test(value) ? value : void 0;
19785
20075
  case "errorCode":
19786
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);
19787
20081
  case "loopExecutor":
19788
20082
  return typeof value === "string" && LOOP_EXECUTOR_SET.has(value) ? value : void 0;
19789
20083
  case "mcpClient":
@@ -19836,6 +20130,8 @@ function sanitizeTelemetryProperty(rule, value) {
19836
20130
  return typeof value === "string" && TOOL_NAME_SET.has(value) ? value : void 0;
19837
20131
  case "uiAction":
19838
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;
19839
20135
  case "version":
19840
20136
  return typeof value === "string" && VERSION_PATTERN.test(value) ? value : void 0;
19841
20137
  case "firstValueStep":
@@ -19844,12 +20140,13 @@ function sanitizeTelemetryProperty(rule, value) {
19844
20140
  return isFirstValueOutcome(value) ? value : void 0;
19845
20141
  }
19846
20142
  }
19847
- 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;
19848
20144
  var init_TelemetrySchema = __esm({
19849
20145
  "src/common/telemetry/TelemetrySchema.ts"() {
19850
20146
  "use strict";
19851
20147
  init_firstValueStep();
19852
- TELEMETRY_SCHEMA_VERSION = "2.6";
20148
+ init_toolProfiles();
20149
+ TELEMETRY_SCHEMA_VERSION = "2.7";
19853
20150
  TELEMETRY_EVENTS = [
19854
20151
  "extension_activated",
19855
20152
  "command_invoked",
@@ -19900,8 +20197,16 @@ var init_TelemetrySchema = __esm({
19900
20197
  "unknown"
19901
20198
  ];
19902
20199
  MCP_CLIENT_SET = new Set(TELEMETRY_MCP_CLIENTS);
19903
- 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
+ ];
19904
20208
  UI_ACTION_SET = new Set(TELEMETRY_UI_ACTIONS);
20209
+ UI_ACTION_OUTCOME_SET = /* @__PURE__ */ new Set(["success", "error"]);
19905
20210
  TELEMETRY_CONNECTORS = [
19906
20211
  "trino",
19907
20212
  "postgres",
@@ -19916,29 +20221,7 @@ var init_TelemetrySchema = __esm({
19916
20221
  "custom",
19917
20222
  "unknown"
19918
20223
  ];
19919
- TELEMETRY_TOOL_NAMES = [
19920
- "list_connectors",
19921
- "run_query",
19922
- "get_tab_info",
19923
- "list_sessions",
19924
- "list_connections",
19925
- "save_connection",
19926
- "request_connection_credentials",
19927
- "test_connection",
19928
- "delete_connection",
19929
- "list_schemas",
19930
- "list_tables",
19931
- "describe_table",
19932
- "cancel_query",
19933
- "close_tab",
19934
- "render_chart",
19935
- "save_chart",
19936
- "list_charts",
19937
- "ledger_stats",
19938
- "verify_ledger",
19939
- "record_ui_event",
19940
- "unknown"
19941
- ];
20224
+ TELEMETRY_TOOL_NAMES = [...ALL_TOOLS, "unknown"];
19942
20225
  TELEMETRY_COMMAND_IDS = [
19943
20226
  "grain.showDaemonInfo",
19944
20227
  "grain.mcp.restart",
@@ -19981,6 +20264,7 @@ var init_TelemetrySchema = __esm({
19981
20264
  "extension_host",
19982
20265
  "onboarding",
19983
20266
  "query_editor",
20267
+ "workspace_ready",
19984
20268
  "connection_manager",
19985
20269
  "connection_form",
19986
20270
  "results_grid",
@@ -20316,6 +20600,7 @@ var init_TelemetrySchema = __esm({
20316
20600
  "connection_save_unknown",
20317
20601
  /** The supervisor rejected registration of the installed service. */
20318
20602
  "service_supervisor_registration_failed",
20603
+ "service_runtime_provision_failed",
20319
20604
  /** The supervisor rejected starting the installed service. */
20320
20605
  "service_supervisor_start_failed",
20321
20606
  /** The supervisor accepted the service, but it never published a reachable endpoint. */
@@ -20441,6 +20726,8 @@ var init_TelemetrySchema = __esm({
20441
20726
  success: "boolean",
20442
20727
  duration_bucket: "durationBucket",
20443
20728
  error_kind: "errorKind",
20729
+ error_code: "diagnosticErrorCode",
20730
+ error_class: "diagnosticErrorClass",
20444
20731
  error_id: "errorId",
20445
20732
  connector: "connector"
20446
20733
  },
@@ -20526,7 +20813,8 @@ var init_TelemetrySchema = __esm({
20526
20813
  },
20527
20814
  ui_state_shown: {},
20528
20815
  ui_action_performed: {
20529
- ui_action: "uiAction"
20816
+ ui_action: "uiAction",
20817
+ outcome: "uiActionOutcome"
20530
20818
  },
20531
20819
  first_value_step: {
20532
20820
  step: "firstValueStep",
@@ -20926,7 +21214,7 @@ var init_TelemetryEmitter = __esm({
20926
21214
 
20927
21215
  // src/common/telemetryConsent.ts
20928
21216
  function telemetryConsentPath(configDir) {
20929
- return path9.join(configDir, TELEMETRY_CONSENT_FILENAME);
21217
+ return path10.join(configDir, TELEMETRY_CONSENT_FILENAME);
20930
21218
  }
20931
21219
  function writeTelemetryConsent(fileSystem, configDir, record2) {
20932
21220
  const targetPath = telemetryConsentPath(configDir);
@@ -20946,7 +21234,7 @@ function writeTelemetryConsent(fileSystem, configDir, record2) {
20946
21234
  function readTelemetryConsentStatus(configDir) {
20947
21235
  let raw;
20948
21236
  try {
20949
- raw = fs7.readFileSync(telemetryConsentPath(configDir), "utf8");
21237
+ raw = fs8.readFileSync(telemetryConsentPath(configDir), "utf8");
20950
21238
  } catch {
20951
21239
  return { type: "missing" };
20952
21240
  }
@@ -20982,12 +21270,12 @@ function readTelemetryConsentStatus(configDir) {
20982
21270
  }
20983
21271
  };
20984
21272
  }
20985
- var fs7, path9, TELEMETRY_CONSENT_FILENAME;
21273
+ var fs8, path10, TELEMETRY_CONSENT_FILENAME;
20986
21274
  var init_telemetryConsent = __esm({
20987
21275
  "src/common/telemetryConsent.ts"() {
20988
21276
  "use strict";
20989
- fs7 = __toESM(require("fs"));
20990
- path9 = __toESM(require("path"));
21277
+ fs8 = __toESM(require("fs"));
21278
+ path10 = __toESM(require("path"));
20991
21279
  TELEMETRY_CONSENT_FILENAME = "telemetry-consent.json";
20992
21280
  }
20993
21281
  });
@@ -20997,7 +21285,7 @@ function isAcquisitionChannel(value) {
20997
21285
  return typeof value === "string" && ACQUISITION_CHANNEL_SET2.has(value);
20998
21286
  }
20999
21287
  function acquisitionChannelPath(configDir) {
21000
- return path10.join(configDir, ACQUISITION_CHANNEL_FILENAME);
21288
+ return path11.join(configDir, ACQUISITION_CHANNEL_FILENAME);
21001
21289
  }
21002
21290
  function acquisitionChannelFromEnvironment(env2) {
21003
21291
  const channel = env2["GRAIN_ACQUISITION_CHANNEL"];
@@ -21014,7 +21302,7 @@ function writeAcquisitionChannel(fileSystem, configDir, record2) {
21014
21302
  function readAcquisitionChannelStatus(configDir) {
21015
21303
  let raw;
21016
21304
  try {
21017
- raw = fs8.readFileSync(acquisitionChannelPath(configDir), "utf8");
21305
+ raw = fs9.readFileSync(acquisitionChannelPath(configDir), "utf8");
21018
21306
  } catch {
21019
21307
  return { type: "missing" };
21020
21308
  }
@@ -21033,12 +21321,12 @@ function readAcquisitionChannelStatus(configDir) {
21033
21321
  }
21034
21322
  return { type: "valid", record: { channel: record2["channel"] } };
21035
21323
  }
21036
- var fs8, path10, ACQUISITION_CHANNEL_FILENAME, ACQUISITION_CHANNELS, ACQUISITION_CHANNEL_SET2;
21324
+ var fs9, path11, ACQUISITION_CHANNEL_FILENAME, ACQUISITION_CHANNELS, ACQUISITION_CHANNEL_SET2;
21037
21325
  var init_acquisitionChannel = __esm({
21038
21326
  "src/common/acquisitionChannel.ts"() {
21039
21327
  "use strict";
21040
- fs8 = __toESM(require("fs"));
21041
- path10 = __toESM(require("path"));
21328
+ fs9 = __toESM(require("fs"));
21329
+ path11 = __toESM(require("path"));
21042
21330
  ACQUISITION_CHANNEL_FILENAME = "acquisition-channel.json";
21043
21331
  ACQUISITION_CHANNELS = ["marketplace", "open_vsx", "cli"];
21044
21332
  ACQUISITION_CHANNEL_SET2 = new Set(ACQUISITION_CHANNELS);
@@ -21062,13 +21350,13 @@ function isHumanOrigin(origin2) {
21062
21350
  function isDaemonEmittedOrigin(origin2) {
21063
21351
  return origin2 !== "vscode_extension";
21064
21352
  }
21065
- 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;
21066
21354
  var init_DaemonTelemetryService = __esm({
21067
21355
  "src/server/DaemonTelemetryService.ts"() {
21068
21356
  "use strict";
21069
21357
  crypto5 = __toESM(require("crypto"));
21070
- fs9 = __toESM(require("fs"));
21071
- path11 = __toESM(require("path"));
21358
+ fs10 = __toESM(require("fs"));
21359
+ path12 = __toESM(require("path"));
21072
21360
  init_TelemetryEmitter();
21073
21361
  init_TelemetrySchema();
21074
21362
  init_ConsoleLogger();
@@ -21172,9 +21460,9 @@ var init_DaemonTelemetryService = __esm({
21172
21460
  if (this.cachedInstallId) {
21173
21461
  return this.cachedInstallId;
21174
21462
  }
21175
- const filePath = path11.join(this.configDir, INSTALL_ID_FILENAME);
21463
+ const filePath = path12.join(this.configDir, INSTALL_ID_FILENAME);
21176
21464
  try {
21177
- const existing = fs9.readFileSync(filePath, "utf8").trim();
21465
+ const existing = fs10.readFileSync(filePath, "utf8").trim();
21178
21466
  if (UUID_PATTERN2.test(existing)) {
21179
21467
  this.cachedInstallId = existing;
21180
21468
  return this.cachedInstallId;
@@ -21183,8 +21471,8 @@ var init_DaemonTelemetryService = __esm({
21183
21471
  }
21184
21472
  this.cachedInstallId = crypto5.randomUUID();
21185
21473
  try {
21186
- fs9.mkdirSync(this.configDir, { recursive: true });
21187
- fs9.writeFileSync(filePath, this.cachedInstallId, "utf8");
21474
+ fs10.mkdirSync(this.configDir, { recursive: true });
21475
+ fs10.writeFileSync(filePath, this.cachedInstallId, "utf8");
21188
21476
  } catch (e2) {
21189
21477
  logger.warn("[Daemon] Could not persist telemetry install ID:", e2);
21190
21478
  }
@@ -21211,7 +21499,7 @@ function downloadToFile(url3, destPath, options) {
21211
21499
  const responseTimeoutMs = options?.responseTimeoutMs ?? 1e4;
21212
21500
  const idleTimeoutMs = options?.idleTimeoutMs ?? 3e4;
21213
21501
  return new Promise((resolve11, reject) => {
21214
- fs10.mkdirSync(path12.dirname(destPath), { recursive: true });
21502
+ fs11.mkdirSync(path13.dirname(destPath), { recursive: true });
21215
21503
  let settled = false;
21216
21504
  let file4;
21217
21505
  let responseTimeout = void 0;
@@ -21233,7 +21521,7 @@ function downloadToFile(url3, destPath, options) {
21233
21521
  if (file4) {
21234
21522
  file4.destroy();
21235
21523
  }
21236
- fs10.rm(destPath, { force: true }, () => reject(err));
21524
+ fs11.rm(destPath, { force: true }, () => reject(err));
21237
21525
  };
21238
21526
  const client = clientFor(url3);
21239
21527
  const request2 = client.get(url3, (response) => {
@@ -21254,7 +21542,7 @@ function downloadToFile(url3, destPath, options) {
21254
21542
  };
21255
21543
  response.on("data", resetIdleTimeout);
21256
21544
  resetIdleTimeout();
21257
- file4 = fs10.createWriteStream(destPath);
21545
+ file4 = fs11.createWriteStream(destPath);
21258
21546
  response.pipe(file4);
21259
21547
  response.on("error", failOnce);
21260
21548
  file4.on("finish", () => {
@@ -21279,7 +21567,7 @@ function downloadToFile(url3, destPath, options) {
21279
21567
  function sha512File(filePath) {
21280
21568
  return new Promise((resolve11, reject) => {
21281
21569
  const hash2 = crypto6.createHash("sha512");
21282
- const stream4 = fs10.createReadStream(filePath);
21570
+ const stream4 = fs11.createReadStream(filePath);
21283
21571
  stream4.on("data", (chunk) => hash2.update(chunk));
21284
21572
  stream4.on("end", () => resolve11(hash2.digest("base64")));
21285
21573
  stream4.on("error", reject);
@@ -21288,7 +21576,7 @@ function sha512File(filePath) {
21288
21576
  function sha256File(filePath) {
21289
21577
  return new Promise((resolve11, reject) => {
21290
21578
  const hash2 = crypto6.createHash("sha256");
21291
- const stream4 = fs10.createReadStream(filePath);
21579
+ const stream4 = fs11.createReadStream(filePath);
21292
21580
  stream4.on("data", (chunk) => hash2.update(chunk));
21293
21581
  stream4.on("end", () => resolve11(hash2.digest("hex")));
21294
21582
  stream4.on("error", reject);
@@ -21298,14 +21586,14 @@ function verifyIntegrity(actualBase64Sha512, expectedIntegrity) {
21298
21586
  const expectedBase64 = expectedIntegrity.replace(/^sha512-/, "");
21299
21587
  return actualBase64Sha512 === expectedBase64;
21300
21588
  }
21301
- var http4, https2, fs10, path12, crypto6;
21589
+ var http4, https2, fs11, path13, crypto6;
21302
21590
  var init_ArtifactDownloader = __esm({
21303
21591
  "src/server/runtime/ArtifactDownloader.ts"() {
21304
21592
  "use strict";
21305
21593
  http4 = __toESM(require("http"));
21306
21594
  https2 = __toESM(require("https"));
21307
- fs10 = __toESM(require("fs"));
21308
- path12 = __toESM(require("path"));
21595
+ fs11 = __toESM(require("fs"));
21596
+ path13 = __toESM(require("path"));
21309
21597
  crypto6 = __toESM(require("crypto"));
21310
21598
  }
21311
21599
  });
@@ -21389,37 +21677,37 @@ function parseTar(buffer) {
21389
21677
  return entries;
21390
21678
  }
21391
21679
  async function extractTarGz(tarGzPath, destDir) {
21392
- const compressed = fs11.readFileSync(tarGzPath);
21680
+ const compressed = fs12.readFileSync(tarGzPath);
21393
21681
  const tarBuffer = zlib.gunzipSync(compressed);
21394
21682
  const entries = parseTar(tarBuffer);
21395
- const resolvedDestDir = path13.resolve(destDir);
21396
- fs11.mkdirSync(resolvedDestDir, { recursive: true });
21397
- 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);
21398
21686
  for (const entry of entries) {
21399
21687
  if (!entry.name || entry.name === "." || entry.name === "./") {
21400
21688
  continue;
21401
21689
  }
21402
- const targetPath = path13.resolve(resolvedDestDir, entry.name);
21690
+ const targetPath = path14.resolve(resolvedDestDir, entry.name);
21403
21691
  if (!within(targetPath)) {
21404
21692
  throw new Error(
21405
21693
  `Refusing to extract tar entry that escapes destination directory: ${entry.name}`
21406
21694
  );
21407
21695
  }
21408
21696
  if (entry.typeflag === "5" || entry.name.endsWith("/")) {
21409
- fs11.mkdirSync(targetPath, { recursive: true });
21697
+ fs12.mkdirSync(targetPath, { recursive: true });
21410
21698
  continue;
21411
21699
  }
21412
21700
  if (entry.typeflag === "0" || entry.typeflag === "\0" || entry.typeflag === "7") {
21413
- fs11.mkdirSync(path13.dirname(targetPath), { recursive: true });
21414
- fs11.writeFileSync(targetPath, entry.content);
21701
+ fs12.mkdirSync(path14.dirname(targetPath), { recursive: true });
21702
+ fs12.writeFileSync(targetPath, entry.content);
21415
21703
  continue;
21416
21704
  }
21417
21705
  if (entry.typeflag === "2") {
21418
21706
  if (!entry.linkname) {
21419
21707
  throw new Error(`Tar symlink entry has no target: ${entry.name}`);
21420
21708
  }
21421
- const resolvedLink = path13.resolve(path13.dirname(targetPath), entry.linkname);
21422
- 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)) {
21423
21711
  throw new Error(
21424
21712
  `Refusing to extract tar symlink that escapes destination directory: ${entry.name} -> ${entry.linkname}`
21425
21713
  );
@@ -21427,9 +21715,9 @@ async function extractTarGz(tarGzPath, destDir) {
21427
21715
  if (process.platform === "win32") {
21428
21716
  continue;
21429
21717
  }
21430
- fs11.mkdirSync(path13.dirname(targetPath), { recursive: true });
21431
- fs11.rmSync(targetPath, { force: true });
21432
- 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);
21433
21721
  continue;
21434
21722
  }
21435
21723
  throw new Error(
@@ -21437,12 +21725,12 @@ async function extractTarGz(tarGzPath, destDir) {
21437
21725
  );
21438
21726
  }
21439
21727
  }
21440
- 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;
21441
21729
  var init_MinimalTarExtractor = __esm({
21442
21730
  "src/server/runtime/MinimalTarExtractor.ts"() {
21443
21731
  "use strict";
21444
- fs11 = __toESM(require("fs"));
21445
- path13 = __toESM(require("path"));
21732
+ fs12 = __toESM(require("fs"));
21733
+ path14 = __toESM(require("path"));
21446
21734
  zlib = __toESM(require("zlib"));
21447
21735
  GNU_LONG_NAME = "L";
21448
21736
  GNU_LONG_LINK = "K";
@@ -21462,13 +21750,13 @@ function currentPlatformKey() {
21462
21750
  return key;
21463
21751
  }
21464
21752
  function artifactRuntimeDir(sqlPreviewHome, artifactId) {
21465
- return path14.join(sqlPreviewHome, "runtime", artifactId);
21753
+ return path15.join(sqlPreviewHome, "runtime", artifactId);
21466
21754
  }
21467
21755
  function artifactVersionDir(sqlPreviewHome, artifactId, version3) {
21468
- return path14.join(artifactRuntimeDir(sqlPreviewHome, artifactId), version3);
21756
+ return path15.join(artifactRuntimeDir(sqlPreviewHome, artifactId), version3);
21469
21757
  }
21470
21758
  function artifactManifestPath(versionDir) {
21471
- return path14.join(versionDir, ".provision-manifest.json");
21759
+ return path15.join(versionDir, ".provision-manifest.json");
21472
21760
  }
21473
21761
  function isManifestRecord(value) {
21474
21762
  return typeof value === "object" && value !== null;
@@ -21487,7 +21775,7 @@ function isLegacyDuckDbProvisionManifest(value) {
21487
21775
  }
21488
21776
  function readManifest(manifestPath) {
21489
21777
  try {
21490
- const raw = fs12.readFileSync(manifestPath, "utf8");
21778
+ const raw = fs13.readFileSync(manifestPath, "utf8");
21491
21779
  const parsed = JSON.parse(raw);
21492
21780
  if (isArtifactProvisionManifest(parsed) || isLegacyDuckDbProvisionManifest(parsed)) {
21493
21781
  return parsed;
@@ -21498,15 +21786,15 @@ function readManifest(manifestPath) {
21498
21786
  }
21499
21787
  }
21500
21788
  function writeManifest(manifestPath, manifest) {
21501
- fs12.mkdirSync(path14.dirname(manifestPath), { recursive: true });
21502
- 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");
21503
21791
  }
21504
- var fs12, path14, SUPPORTED_PLATFORMS;
21792
+ var fs13, path15, SUPPORTED_PLATFORMS;
21505
21793
  var init_ManagedArtifactTypes = __esm({
21506
21794
  "src/server/runtime/ManagedArtifactTypes.ts"() {
21507
21795
  "use strict";
21508
- fs12 = __toESM(require("fs"));
21509
- path14 = __toESM(require("path"));
21796
+ fs13 = __toESM(require("fs"));
21797
+ path15 = __toESM(require("path"));
21510
21798
  SUPPORTED_PLATFORMS = [
21511
21799
  "darwin-arm64",
21512
21800
  "darwin-x64",
@@ -21593,18 +21881,18 @@ var init_protocolVersion = __esm({
21593
21881
 
21594
21882
  // src/server/install/applicationPayload.ts
21595
21883
  function applicationDir(configHome, version3) {
21596
- return path19.join(configHome, "app", version3);
21884
+ return path20.join(configHome, "app", version3);
21597
21885
  }
21598
21886
  function isStandaloneApplication(configHome, entryPath) {
21599
21887
  if (!entryPath) {
21600
21888
  return false;
21601
21889
  }
21602
- const appRoot = path19.resolve(configHome, "app") + path19.sep;
21603
- return path19.resolve(entryPath).startsWith(appRoot);
21890
+ const appRoot = path20.resolve(configHome, "app") + path20.sep;
21891
+ return path20.resolve(entryPath).startsWith(appRoot);
21604
21892
  }
21605
21893
  function isWithin(parent, child) {
21606
- const relative5 = path19.relative(path19.resolve(parent), path19.resolve(child));
21607
- 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 !== "..";
21608
21896
  }
21609
21897
  function removeDirectoryBestEffort(fileSystem, directory) {
21610
21898
  try {
@@ -21614,7 +21902,7 @@ function removeDirectoryBestEffort(fileSystem, directory) {
21614
21902
  }
21615
21903
  }
21616
21904
  function writeVersionManifest(fileSystem, directory, version3) {
21617
- const manifestPath = path19.join(directory, "package.json");
21905
+ const manifestPath = path20.join(directory, "package.json");
21618
21906
  let manifest = { name: "grain-daemon", private: true };
21619
21907
  try {
21620
21908
  const existing = JSON.parse(fileSystem.readFileSync(manifestPath, "utf8"));
@@ -21628,10 +21916,10 @@ function writeVersionManifest(fileSystem, directory, version3) {
21628
21916
  `, "utf8");
21629
21917
  }
21630
21918
  function installApplicationPayload(options) {
21631
- const fileSystem = options.fileSystem ?? fs16;
21919
+ const fileSystem = options.fileSystem ?? fs17;
21632
21920
  const { configHome, version: version3, sourceEntry } = options;
21633
21921
  const destinationDir = applicationDir(configHome, version3);
21634
- const applicationRoot = path19.join(configHome, "app");
21922
+ const applicationRoot = path20.join(configHome, "app");
21635
21923
  if (!isWithin(applicationRoot, destinationDir)) {
21636
21924
  throw new Error(`Application version must stay inside ${applicationRoot}`);
21637
21925
  }
@@ -21641,21 +21929,21 @@ function installApplicationPayload(options) {
21641
21929
  fileSystem.rmSync(staging, { recursive: true, force: true });
21642
21930
  fileSystem.mkdirSync(staging, { recursive: true });
21643
21931
  const isDirectory = fileSystem.statSync(sourceEntry).isDirectory();
21644
- const entryName = isDirectory ? "standalone.js" : path19.basename(sourceEntry);
21932
+ const entryName = isDirectory ? "standalone.js" : path20.basename(sourceEntry);
21645
21933
  if (isDirectory) {
21646
21934
  fileSystem.cpSync(sourceEntry, staging, { recursive: true });
21647
21935
  } else {
21648
- fileSystem.copyFileSync(sourceEntry, path19.join(staging, entryName));
21936
+ fileSystem.copyFileSync(sourceEntry, path20.join(staging, entryName));
21649
21937
  const pagesDir = [
21650
- path19.join(path19.dirname(sourceEntry), "dist"),
21651
- path19.join(path19.dirname(sourceEntry), "..", "..", "dist")
21652
- ].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")));
21653
21941
  if (pagesDir) {
21654
- fileSystem.mkdirSync(path19.join(staging, "dist"), { recursive: true });
21942
+ fileSystem.mkdirSync(path20.join(staging, "dist"), { recursive: true });
21655
21943
  for (const page of ["web-app.html", "mcp-app.html"]) {
21656
- const pagePath = path19.join(pagesDir, page);
21944
+ const pagePath = path20.join(pagesDir, page);
21657
21945
  if (fileSystem.existsSync(pagePath)) {
21658
- fileSystem.copyFileSync(pagePath, path19.join(staging, "dist", page));
21946
+ fileSystem.copyFileSync(pagePath, path20.join(staging, "dist", page));
21659
21947
  }
21660
21948
  }
21661
21949
  }
@@ -21682,23 +21970,23 @@ function installApplicationPayload(options) {
21682
21970
  throw error52;
21683
21971
  }
21684
21972
  removeDirectoryBestEffort(fileSystem, backup);
21685
- return path19.join(destinationDir, entryName);
21973
+ return path20.join(destinationDir, entryName);
21686
21974
  }
21687
21975
  function retainedApplicationVersions(configHome) {
21688
21976
  try {
21689
- return fs16.readdirSync(path19.join(configHome, "app"), { withFileTypes: true }).filter(
21977
+ return fs17.readdirSync(path20.join(configHome, "app"), { withFileTypes: true }).filter(
21690
21978
  (entry) => entry.isDirectory() && !entry.name.includes(".staging-") && !entry.name.includes(".backup-")
21691
21979
  ).map((entry) => entry.name).sort((left, right) => compareSemver(right, left));
21692
21980
  } catch {
21693
21981
  return [];
21694
21982
  }
21695
21983
  }
21696
- var fs16, path19;
21984
+ var fs17, path20;
21697
21985
  var init_applicationPayload = __esm({
21698
21986
  "src/server/install/applicationPayload.ts"() {
21699
21987
  "use strict";
21700
- fs16 = __toESM(require("fs"));
21701
- path19 = __toESM(require("path"));
21988
+ fs17 = __toESM(require("fs"));
21989
+ path20 = __toESM(require("path"));
21702
21990
  init_protocolVersion();
21703
21991
  }
21704
21992
  });
@@ -21742,7 +22030,7 @@ async function runRegistration(platform2, runner, command, args) {
21742
22030
  if (isUserServicesForbidden(platform2, result.output)) {
21743
22031
  throw new UserServicesForbiddenError(result.output);
21744
22032
  }
21745
- throw new Error(`${command} ${args.join(" ")} failed: ${result.output.trim()}`);
22033
+ throw new RegistrationError(command, args, result.exitCode, result.output);
21746
22034
  }
21747
22035
  async function runStart(runner, command, args) {
21748
22036
  const result = await runner.run(command, args);
@@ -21759,12 +22047,45 @@ function isCommandMissing(error52) {
21759
22047
  }
21760
22048
  function createSupervisorAdapter(platform2, runner, uid) {
21761
22049
  if (platform2 === "darwin") {
21762
- 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
+ };
21763
22060
  return {
21764
- isRegistered: (identifier) => probeRegistration(runner, "launchctl", ["print", target(identifier)]),
21765
- register: (unitPath) => runRegistration(platform2, runner, "launchctl", ["bootstrap", `gui/${uid}`, unitPath]),
21766
- unregister: (identifier) => runRegistration(platform2, runner, "launchctl", ["bootout", target(identifier)]),
21767
- 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
+ ])
21768
22089
  };
21769
22090
  }
21770
22091
  if (platform2 === "linux") {
@@ -21815,7 +22136,7 @@ function createSupervisorAdapter(platform2, runner, uid) {
21815
22136
  start: (identifier) => runStart(runner, "schtasks", ["/Run", "/TN", identifier])
21816
22137
  };
21817
22138
  }
21818
- var import_child_process3, UserServicesForbiddenError, ServiceManagerMissingError;
22139
+ var import_child_process3, UserServicesForbiddenError, ServiceManagerMissingError, RegistrationError;
21819
22140
  var init_supervisorAdapter = __esm({
21820
22141
  "src/server/install/supervisorAdapter.ts"() {
21821
22142
  "use strict";
@@ -21824,6 +22145,13 @@ var init_supervisorAdapter = __esm({
21824
22145
  };
21825
22146
  ServiceManagerMissingError = class extends UserServicesForbiddenError {
21826
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
+ };
21827
22155
  }
21828
22156
  });
21829
22157
 
@@ -21834,7 +22162,7 @@ var require_package = __commonJS({
21834
22162
  name: "grain",
21835
22163
  displayName: "Grain SQL",
21836
22164
  description: "Run SQL in VS Code and expose safe, visible MCP database tools for Claude, Cursor, and other AI agents.",
21837
- version: "0.10.13",
22165
+ version: "0.10.14",
21838
22166
  license: "UNLICENSED",
21839
22167
  mcpName: "io.github.pattrnlabs/grain",
21840
22168
  publisher: "pattrnlabs",
@@ -21887,7 +22215,8 @@ var require_package = __commonJS({
21887
22215
  "Other"
21888
22216
  ],
21889
22217
  activationEvents: [
21890
- "onLanguage:sql"
22218
+ "onLanguage:sql",
22219
+ "onStartupFinished"
21891
22220
  ],
21892
22221
  main: "./out/extension.js",
21893
22222
  contributes: {
@@ -22184,6 +22513,22 @@ var require_package = __commonJS({
22184
22513
  maximum: 20,
22185
22514
  order: 10
22186
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
+ },
22187
22532
  "grain.filterResultsByActiveFile": {
22188
22533
  type: "boolean",
22189
22534
  default: true,
@@ -22239,7 +22584,7 @@ var require_package = __commonJS({
22239
22584
  },
22240
22585
  "grain.mcpEnabled": {
22241
22586
  type: "boolean",
22242
- default: false,
22587
+ default: true,
22243
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.",
22244
22589
  order: 20
22245
22590
  },
@@ -22380,11 +22725,17 @@ var require_package = __commonJS({
22380
22725
  watch: "tsc -watch -p ./",
22381
22726
  package: "node scripts/package-vsix.js",
22382
22727
  "ci:burn": "node scripts/ci-burn.mjs",
22383
- lint: 'eslint "src/**/*.ts" "scripts/**/*.js" "scripts/**/*.mjs" --cache',
22384
- "lint:fix": 'eslint "src/**/*.ts" "scripts/**/*.js" --fix --cache',
22385
- format: 'prettier --write "src/**/*.{ts,js,json}"',
22386
- "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}"',
22387
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",
22388
22739
  "check:ui-contract": "node scripts/check-ui-token-contract.js",
22389
22740
  "check:brand-tokens": "node scripts/check-brand-tokens.js",
22390
22741
  "check:identity": "node scripts/check-identity.js",
@@ -22392,7 +22743,7 @@ var require_package = __commonJS({
22392
22743
  "check:token-theme-parity": "node scripts/check-token-theme-parity.js",
22393
22744
  "generate:duckdb-pins": "node scripts/generate-duckdb-pins.js",
22394
22745
  "generate:artifact-pins": "node scripts/generate-artifact-pins.js",
22395
- "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",
22396
22747
  "check:duckdb-pins": "node scripts/check-duckdb-pins.js",
22397
22748
  "rfc:check": "node scripts/validate-rfcs.js",
22398
22749
  "docs:coverage-manifest": "node scripts/generate-coverage-manifest.js",
@@ -22407,7 +22758,11 @@ var require_package = __commonJS({
22407
22758
  "check:no-execpath-units": "node scripts/check-no-execpath-units.js",
22408
22759
  "check:gates": "node scripts/check-gates.js",
22409
22760
  "rfc:new": "node scripts/new-rfc.js",
22410
- "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",
22411
22766
  "esbuild-base": "esbuild ./src/extension.ts --bundle --outfile=out/extension.js --external:vscode --external:ws --format=cjs --platform=node",
22412
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",
22413
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',
@@ -22464,7 +22819,7 @@ var require_package = __commonJS({
22464
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',
22465
22820
  "test:medium:rfc-baseline": "jest --config jest.medium.config.js --runInBand --runTestsByPath src/test/medium/rfcBaselineResolution.medium.test.js",
22466
22821
  "test:integration": "node ./out/test/runTest.js",
22467
- prewalkthrough: "npm run compile",
22822
+ prewalkthrough: "npm run compile && node scripts/build-daemon.js --entry=standalone",
22468
22823
  walkthrough: "node scripts/walkthrough-runner/run.js",
22469
22824
  "pretest:mcp-conformance": "npm run build:packages:dev && node scripts/build-daemon.js --entry=standalone",
22470
22825
  "test:mcp-conformance": "node scripts/run-mcp-conformance.js",
@@ -22503,7 +22858,6 @@ var require_package = __commonJS({
22503
22858
  "check:release-notes": "node scripts/release-note-fragments.js validate",
22504
22859
  "check:release-note-range": "node scripts/release-note-fragments.js check",
22505
22860
  "changelog:draft": "node scripts/release-note-fragments.js draft",
22506
- typecheck: "npm run type-check",
22507
22861
  "docs:graph": "node scripts/generate-architecture-graph.js",
22508
22862
  "docs:api": "typedoc",
22509
22863
  "docs:gen": "npm run docs:graph && npm run docs:api",
@@ -22547,6 +22901,7 @@ var require_package = __commonJS({
22547
22901
  "@types/vscode": "^1.80.0",
22548
22902
  "@typescript-eslint/eslint-plugin": "^5.59.8",
22549
22903
  "@typescript-eslint/parser": "^5.59.8",
22904
+ "@typescript/native-preview": "^7.0.0-dev.20260707.2",
22550
22905
  "@vitejs/plugin-react-swc": "^4.3.0",
22551
22906
  "@vscode/test-electron": "^2.5.2",
22552
22907
  "@vscode/vsce": "^3.9.1",
@@ -22555,8 +22910,6 @@ var require_package = __commonJS({
22555
22910
  "dotenv-cli": "^7.4.1",
22556
22911
  esbuild: "^0.17.19",
22557
22912
  eslint: "^8.41.0",
22558
- "eslint-config-prettier": "^9.1.2",
22559
- "eslint-plugin-prettier": "^5.5.3",
22560
22913
  glob: "^11.0.1",
22561
22914
  husky: "^8.0.3",
22562
22915
  jest: "^29.7.0",
@@ -22565,9 +22918,11 @@ var require_package = __commonJS({
22565
22918
  "lint-staged": "^15.5.2",
22566
22919
  madge: "^8.0.0",
22567
22920
  mocha: "^11.1.0",
22921
+ oxfmt: "^0.70.0",
22922
+ oxlint: "^1.85.0",
22568
22923
  "patch-package": "^8.0.1",
22569
22924
  pg: "^8.17.2",
22570
- prettier: "^3.6.2",
22925
+ "playwright-core": "1.62.1",
22571
22926
  secretlint: "^11.3.1",
22572
22927
  semver: "^7.8.5",
22573
22928
  sinon: "^20.0.0",
@@ -22577,6 +22932,7 @@ var require_package = __commonJS({
22577
22932
  typescript: "^5.1.3",
22578
22933
  vite: "^5.4.21",
22579
22934
  "vite-plugin-singlefile": "^2.3.0",
22935
+ vitest: "^3.2.7",
22580
22936
  yaml: "^2.8.3"
22581
22937
  },
22582
22938
  dependencies: {
@@ -22611,11 +22967,11 @@ var require_package = __commonJS({
22611
22967
  },
22612
22968
  "lint-staged": {
22613
22969
  "*.{ts,js,mjs}": [
22614
- "eslint --fix",
22615
- "prettier --write"
22970
+ "oxlint -c .oxlintrc.json --fix",
22971
+ "oxfmt"
22616
22972
  ],
22617
22973
  "*.{json,md}": [
22618
- "prettier --write"
22974
+ "oxfmt"
22619
22975
  ],
22620
22976
  "*.{ts,js,mjs,cjs,json,env,yaml,yml,sh,toml,ini,cfg,conf,pem,key,crt}": [
22621
22977
  "secretlint"
@@ -22630,206 +22986,6 @@ var require_package = __commonJS({
22630
22986
  }
22631
22987
  });
22632
22988
 
22633
- // src/common/toolProfiles.ts
22634
- function toolRuleFor(profile, tool) {
22635
- return profile.policy?.rules?.[TOOL_RESOURCE_CLASS[tool]] ?? "allow";
22636
- }
22637
- function toolRefusalMessage(profile, tool) {
22638
- 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.`;
22639
- }
22640
- function toolRefusalResult(profile, tool) {
22641
- return {
22642
- isError: true,
22643
- content: [{ type: "text", text: toolRefusalMessage(profile, tool) }],
22644
- structuredContent: { errorKind: "permission", errorId: "tool_not_permitted_for_profile" }
22645
- };
22646
- }
22647
- function refuseIfNotPermitted(profile, tool) {
22648
- const name = tool;
22649
- if (TOOL_RESOURCE_CLASS[name] === void 0)
22650
- return void 0;
22651
- if (toolRuleFor(profile, name) === "allow")
22652
- return void 0;
22653
- return toolRefusalResult(profile, name);
22654
- }
22655
- function isToolProfileName(value) {
22656
- return value === "vscode" || value === "headless" || value === "readonly" || value === "agent";
22657
- }
22658
- function operatorProfileOverride(onUnknownEnvValue) {
22659
- const fromEnv = process.env["MCP_PROFILE"];
22660
- if (fromEnv === void 0)
22661
- return void 0;
22662
- if (isToolProfileName(fromEnv))
22663
- return TOOL_PROFILES[fromEnv];
22664
- onUnknownEnvValue?.(fromEnv);
22665
- return void 0;
22666
- }
22667
- function resolveToolProfile(explicit, onUnknownEnvValue) {
22668
- if (explicit) {
22669
- return TOOL_PROFILES[explicit];
22670
- }
22671
- const fromEnv = process.env["MCP_PROFILE"];
22672
- if (fromEnv !== void 0) {
22673
- if (isToolProfileName(fromEnv)) {
22674
- return TOOL_PROFILES[fromEnv];
22675
- }
22676
- onUnknownEnvValue?.(fromEnv);
22677
- }
22678
- return TOOL_PROFILES.vscode;
22679
- }
22680
- function isSafeModeActive(profile, liveSafeMode) {
22681
- return profile.forceSafeMode || liveSafeMode;
22682
- }
22683
- function toolNamesForProfile(profile) {
22684
- const cached2 = toolNameSets.get(profile);
22685
- if (cached2)
22686
- return cached2;
22687
- const names = new Set(profile.tools);
22688
- toolNameSets.set(profile, names);
22689
- return names;
22690
- }
22691
- function composeToolProfiles(...profiles) {
22692
- const present = profiles.filter((p) => p !== void 0);
22693
- if (present.length === 0)
22694
- return TOOL_PROFILES.vscode;
22695
- if (present.length === 1)
22696
- return present[0];
22697
- const sets = present.map((p) => new Set(p.tools));
22698
- const rules = {};
22699
- for (const p of present) {
22700
- for (const [cls, rule] of Object.entries(p.policy?.rules ?? {})) {
22701
- if (rule === "refuse")
22702
- rules[cls] = "refuse";
22703
- }
22704
- }
22705
- const refusalCount = (p) => Object.keys(p.policy?.rules ?? {}).length;
22706
- const narrowest = present.reduce((a, b) => {
22707
- if (b.tools.length !== a.tools.length)
22708
- return b.tools.length < a.tools.length ? b : a;
22709
- return refusalCount(b) > refusalCount(a) ? b : a;
22710
- });
22711
- return {
22712
- name: narrowest.name,
22713
- tools: ALL_TOOLS.filter((tool) => sets.every((s) => s.has(tool))),
22714
- forceSafeMode: present.some((p) => p.forceSafeMode),
22715
- ...Object.keys(rules).length > 0 ? { policy: { rules } } : {}
22716
- };
22717
- }
22718
- function createToolProfileResolver(explicit, onUnknownEnvValue) {
22719
- const defaultProfile = resolveToolProfile(explicit, onUnknownEnvValue);
22720
- const pinned = explicit === void 0 ? void 0 : TOOL_PROFILES[explicit];
22721
- const fromEnv = operatorProfileOverride(onUnknownEnvValue);
22722
- return {
22723
- defaultProfile,
22724
- forCall(profile) {
22725
- const declared = profile === void 0 ? void 0 : TOOL_PROFILES[profile];
22726
- if (pinned === void 0 && fromEnv === void 0 && declared === void 0) {
22727
- return defaultProfile;
22728
- }
22729
- return composeToolProfiles(pinned, fromEnv, declared);
22730
- }
22731
- };
22732
- }
22733
- var ALL_TOOLS, READ_ONLY_TOOLS, TOOL_RESOURCE_CLASS, TOOL_PROFILES, WEB_PROXIED_TOOLS, toolNameSets;
22734
- var init_toolProfiles = __esm({
22735
- "src/common/toolProfiles.ts"() {
22736
- "use strict";
22737
- ALL_TOOLS = [
22738
- "list_connectors",
22739
- "run_query",
22740
- "get_tab_info",
22741
- "list_sessions",
22742
- "list_connections",
22743
- "save_connection",
22744
- "request_connection_credentials",
22745
- "test_connection",
22746
- "delete_connection",
22747
- "list_schemas",
22748
- "list_tables",
22749
- "describe_table",
22750
- "cancel_query",
22751
- "close_tab",
22752
- "render_chart",
22753
- "save_chart",
22754
- "list_charts",
22755
- "ledger_stats",
22756
- "verify_ledger",
22757
- "record_ui_event"
22758
- ];
22759
- READ_ONLY_TOOLS = [
22760
- "list_connectors",
22761
- "run_query",
22762
- "get_tab_info",
22763
- "list_sessions",
22764
- "list_connections",
22765
- "test_connection",
22766
- "list_schemas",
22767
- "list_tables",
22768
- "describe_table",
22769
- "cancel_query",
22770
- "close_tab",
22771
- "render_chart",
22772
- "list_charts",
22773
- "ledger_stats",
22774
- "verify_ledger",
22775
- "record_ui_event"
22776
- ];
22777
- TOOL_RESOURCE_CLASS = {
22778
- list_connectors: "read",
22779
- list_connections: "read",
22780
- list_sessions: "read",
22781
- get_tab_info: "read",
22782
- list_schemas: "read",
22783
- list_tables: "read",
22784
- describe_table: "read",
22785
- list_charts: "read",
22786
- ledger_stats: "read",
22787
- verify_ledger: "read",
22788
- test_connection: "read",
22789
- cancel_query: "session",
22790
- close_tab: "session",
22791
- render_chart: "session",
22792
- run_query: "query",
22793
- save_connection: "connection-config",
22794
- delete_connection: "connection-config",
22795
- request_connection_credentials: "credential",
22796
- save_chart: "workspace-write",
22797
- record_ui_event: "app-telemetry"
22798
- };
22799
- TOOL_PROFILES = {
22800
- // Human-in-the-loop VS Code surface: full toolset, safe mode from settings.
22801
- vscode: { name: "vscode", tools: ALL_TOOLS, forceSafeMode: false },
22802
- // Autonomous agents: starts as the full current toolset (RFC-062); will
22803
- // diverge toward synchronous/structured tools without breaking clients.
22804
- headless: { name: "headless", tools: ALL_TOOLS, forceSafeMode: false },
22805
- // Safe exploration: no profile/credential mutation, SQL gating always on.
22806
- readonly: { name: "readonly", tools: READ_ONLY_TOOLS, forceSafeMode: true },
22807
- // RFC-134: intended as the default for an attached AI agent surface — may read,
22808
- // query and chart, may not change saved connections or ask for stored credentials.
22809
- // This profile is assigned to the local agent identity and enforced on the stdio bridge.
22810
- // End-to-end enforcement is proven by the 'bridged client (agent profile) is permitted
22811
- // read tools but refused config/credential tools' test in stdio_bridge.test.ts.
22812
- // SQL restriction is deliberately not forced here: `grain.mcpSafeMode`
22813
- // already defaults to on, and a ceiling would make that setting silently stop
22814
- // working for the recommended agent path.
22815
- agent: {
22816
- name: "agent",
22817
- tools: ALL_TOOLS,
22818
- forceSafeMode: false,
22819
- policy: { rules: { "connection-config": "refuse", credential: "refuse" } }
22820
- }
22821
- };
22822
- WEB_PROXIED_TOOLS = [
22823
- "list_connectors",
22824
- "list_connections",
22825
- "save_connection",
22826
- "test_connection",
22827
- "delete_connection"
22828
- ];
22829
- toolNameSets = /* @__PURE__ */ new WeakMap();
22830
- }
22831
- });
22832
-
22833
22989
  // src/server/auth/ClientRegistry.ts
22834
22990
  function clientRegistryPath(configDir) {
22835
22991
  return import_path3.default.join(configDir, CLIENT_REGISTRY_FILENAME);
@@ -23035,32 +23191,32 @@ async function startCommand(configDir = resolveGrainHome(), spawner = import_chi
23035
23191
  const lockPath = path24.join(configDir, "start.lock");
23036
23192
  let claimedLock = false;
23037
23193
  try {
23038
- const content = fs20.readFileSync(lockPath, "utf8");
23194
+ const content = fs21.readFileSync(lockPath, "utf8");
23039
23195
  const parts = content.split("\n");
23040
23196
  const pidStr = parts[0];
23041
23197
  const tsStr = parts[1];
23042
23198
  if (pidStr === void 0 || tsStr === void 0) {
23043
- fs20.unlinkSync(lockPath);
23199
+ fs21.unlinkSync(lockPath);
23044
23200
  } else {
23045
23201
  const lockPid = parseInt(pidStr, 10);
23046
23202
  const lockTs = parseInt(tsStr, 10);
23047
23203
  if (!isNaN(lockTs) && clock.now() - lockTs > 2e4) {
23048
- fs20.unlinkSync(lockPath);
23204
+ fs21.unlinkSync(lockPath);
23049
23205
  } else if (!isNaN(lockPid)) {
23050
23206
  try {
23051
23207
  process.kill(lockPid, 0);
23052
23208
  } catch {
23053
- fs20.unlinkSync(lockPath);
23209
+ fs21.unlinkSync(lockPath);
23054
23210
  }
23055
23211
  }
23056
23212
  }
23057
23213
  } catch {
23058
23214
  }
23059
23215
  try {
23060
- const fd = fs20.openSync(lockPath, "wx");
23061
- fs20.writeSync(fd, `${process.pid}
23216
+ const fd = fs21.openSync(lockPath, "wx");
23217
+ fs21.writeSync(fd, `${process.pid}
23062
23218
  ${clock.now()}`);
23063
- fs20.closeSync(fd);
23219
+ fs21.closeSync(fd);
23064
23220
  claimedLock = true;
23065
23221
  } catch (e2) {
23066
23222
  if (e2.code !== "EEXIST") {
@@ -23069,8 +23225,8 @@ ${clock.now()}`);
23069
23225
  }
23070
23226
  const logPath = path24.join(configDir, "daemon.log");
23071
23227
  if (claimedLock) {
23072
- const out2 = fs20.openSync(logPath, "a");
23073
- const err = fs20.openSync(logPath, "a");
23228
+ const out2 = fs21.openSync(logPath, "a");
23229
+ const err = fs21.openSync(logPath, "a");
23074
23230
  const child = spawner(process.execPath, [process.argv[1] ?? ""], {
23075
23231
  detached: true,
23076
23232
  stdio: ["ignore", out2, err],
@@ -23105,18 +23261,18 @@ ${clock.now()}`);
23105
23261
  } finally {
23106
23262
  if (claimedLock) {
23107
23263
  try {
23108
- fs20.unlinkSync(lockPath);
23264
+ fs21.unlinkSync(lockPath);
23109
23265
  } catch {
23110
23266
  }
23111
23267
  }
23112
23268
  }
23113
23269
  }
23114
- var import_child_process4, fs20, path24, http5, OWNERSHIP_PROBE_PATH;
23270
+ var import_child_process4, fs21, path24, http5, OWNERSHIP_PROBE_PATH;
23115
23271
  var init_startCommand = __esm({
23116
23272
  "src/server/cli/startCommand.ts"() {
23117
23273
  "use strict";
23118
23274
  import_child_process4 = require("child_process");
23119
- fs20 = __toESM(require("fs"));
23275
+ fs21 = __toESM(require("fs"));
23120
23276
  path24 = __toESM(require("path"));
23121
23277
  http5 = __toESM(require("http"));
23122
23278
  init_grainHome();
@@ -23158,7 +23314,7 @@ var init_localBrowserPaths = __esm({
23158
23314
  function findPackageRoot(startDir) {
23159
23315
  let dir3 = startDir;
23160
23316
  for (let i = 0; i < 8; i++) {
23161
- if (fs21.existsSync(path25.join(dir3, "package.json"))) {
23317
+ if (fs22.existsSync(path25.join(dir3, "package.json"))) {
23162
23318
  return dir3;
23163
23319
  }
23164
23320
  const parent = path25.dirname(dir3);
@@ -23172,17 +23328,17 @@ function findPackageRoot(startDir) {
23172
23328
  function readDaemonVersion() {
23173
23329
  try {
23174
23330
  const pkgPath = path25.join(findPackageRoot(__dirname), "package.json");
23175
- const pkg = JSON.parse(fs21.readFileSync(pkgPath, "utf8"));
23331
+ const pkg = JSON.parse(fs22.readFileSync(pkgPath, "utf8"));
23176
23332
  return pkg.version ?? null;
23177
23333
  } catch {
23178
23334
  return null;
23179
23335
  }
23180
23336
  }
23181
- var fs21, path25;
23337
+ var fs22, path25;
23182
23338
  var init_daemonVersion = __esm({
23183
23339
  "src/server/daemonVersion.ts"() {
23184
23340
  "use strict";
23185
- fs21 = __toESM(require("fs"));
23341
+ fs22 = __toESM(require("fs"));
23186
23342
  path25 = __toESM(require("path"));
23187
23343
  }
23188
23344
  });
@@ -45719,7 +45875,7 @@ var require_view = __commonJS({
45719
45875
  "use strict";
45720
45876
  var debug = require_src()("express:view");
45721
45877
  var path46 = require("node:path");
45722
- var fs44 = require("node:fs");
45878
+ var fs45 = require("node:fs");
45723
45879
  var dirname16 = path46.dirname;
45724
45880
  var basename5 = path46.basename;
45725
45881
  var extname = path46.extname;
@@ -45799,7 +45955,7 @@ var require_view = __commonJS({
45799
45955
  function tryStat(path47) {
45800
45956
  debug('stat "%s"', path47);
45801
45957
  try {
45802
- return fs44.statSync(path47);
45958
+ return fs45.statSync(path47);
45803
45959
  } catch (e2) {
45804
45960
  return void 0;
45805
45961
  }
@@ -77986,7 +78142,7 @@ var require_send = __commonJS({
77986
78142
  var escapeHtml2 = require_escape_html();
77987
78143
  var etag = require_etag();
77988
78144
  var fresh = require_fresh();
77989
- var fs44 = require("fs");
78145
+ var fs45 = require("fs");
77990
78146
  var mime = require_mime_types4();
77991
78147
  var ms = require_ms();
77992
78148
  var onFinished = require_on_finished();
@@ -78269,7 +78425,7 @@ var require_send = __commonJS({
78269
78425
  var i = 0;
78270
78426
  var self2 = this;
78271
78427
  debug('stat "%s"', path47);
78272
- fs44.stat(path47, function onstat(err, stat) {
78428
+ fs45.stat(path47, function onstat(err, stat) {
78273
78429
  var pathEndsWithSep = path47[path47.length - 1] === sep7;
78274
78430
  if (err && err.code === "ENOENT" && !extname(path47) && !pathEndsWithSep) {
78275
78431
  return next(err);
@@ -78289,7 +78445,7 @@ var require_send = __commonJS({
78289
78445
  }
78290
78446
  var p = path47 + "." + self2._extensions[i++];
78291
78447
  debug('stat "%s"', p);
78292
- fs44.stat(p, function(err2, stat) {
78448
+ fs45.stat(p, function(err2, stat) {
78293
78449
  if (err2)
78294
78450
  return next(err2);
78295
78451
  if (stat.isDirectory())
@@ -78310,7 +78466,7 @@ var require_send = __commonJS({
78310
78466
  }
78311
78467
  var p = join37(path47, self2._index[i]);
78312
78468
  debug('stat "%s"', p);
78313
- fs44.stat(p, function(err2, stat) {
78469
+ fs45.stat(p, function(err2, stat) {
78314
78470
  if (err2)
78315
78471
  return next(err2);
78316
78472
  if (stat.isDirectory())
@@ -78324,7 +78480,7 @@ var require_send = __commonJS({
78324
78480
  SendStream.prototype.stream = function stream4(path47, options) {
78325
78481
  var self2 = this;
78326
78482
  var res = this.res;
78327
- var stream5 = fs44.createReadStream(path47, options);
78483
+ var stream5 = fs45.createReadStream(path47, options);
78328
78484
  this.emit("stream", stream5);
78329
78485
  stream5.pipe(res);
78330
78486
  function cleanup() {
@@ -79216,13 +79372,13 @@ function endpointExists(endpoint) {
79216
79372
  if (isWindowsNamedPipe(endpoint)) {
79217
79373
  return true;
79218
79374
  }
79219
- return fs22.existsSync(endpoint);
79375
+ return fs23.existsSync(endpoint);
79220
79376
  }
79221
- 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;
79222
79378
  var init_ipcEndpoint = __esm({
79223
79379
  "src/common/ipcEndpoint.ts"() {
79224
79380
  "use strict";
79225
- fs22 = __toESM(require("fs"));
79381
+ fs23 = __toESM(require("fs"));
79226
79382
  os6 = __toESM(require("os"));
79227
79383
  path26 = __toESM(require("path"));
79228
79384
  import_crypto5 = require("crypto");
@@ -79362,11 +79518,11 @@ var init_ConnectorRegistry = __esm({
79362
79518
  });
79363
79519
 
79364
79520
  // src/services/DriverManager.ts
79365
- var fs23, path27, DriverManager;
79521
+ var fs24, path27, DriverManager;
79366
79522
  var init_DriverManager = __esm({
79367
79523
  "src/services/DriverManager.ts"() {
79368
79524
  "use strict";
79369
- fs23 = __toESM(require("fs"));
79525
+ fs24 = __toESM(require("fs"));
79370
79526
  path27 = __toESM(require("path"));
79371
79527
  DriverManager = class {
79372
79528
  constructor(configDir, driverResolver) {
@@ -79385,7 +79541,7 @@ var init_DriverManager = __esm({
79385
79541
  }
79386
79542
  if (this.configDir) {
79387
79543
  const driverPath = path27.join(this.configDir, "drivers", "node_modules", driverName);
79388
- if (fs23.existsSync(driverPath)) {
79544
+ if (fs24.existsSync(driverPath)) {
79389
79545
  return driverPath;
79390
79546
  }
79391
79547
  }
@@ -79396,7 +79552,7 @@ var init_DriverManager = __esm({
79396
79552
  */
79397
79553
  async getConnectorExecutablePath(connectorType, customPath) {
79398
79554
  if (customPath) {
79399
- if (path27.isAbsolute(customPath) && fs23.existsSync(customPath)) {
79555
+ if (path27.isAbsolute(customPath) && fs24.existsSync(customPath)) {
79400
79556
  return customPath;
79401
79557
  }
79402
79558
  throw new Error(`Custom connector executable not found at path: ${customPath}`);
@@ -79422,7 +79578,7 @@ var init_DriverManager = __esm({
79422
79578
  path27.join(__dirname, "..", "..", "..", "packages", executableName, "dist", "cli.js")
79423
79579
  ];
79424
79580
  for (const p of possiblePaths) {
79425
- if (fs23.existsSync(p)) {
79581
+ if (fs24.existsSync(p)) {
79426
79582
  return p;
79427
79583
  }
79428
79584
  }
@@ -79833,11 +79989,11 @@ var src_exports = {};
79833
79989
  __export(src_exports, {
79834
79990
  default: () => DuckDbConnector
79835
79991
  });
79836
- var fs24, import_connector_api, DuckDbConnector;
79992
+ var fs25, import_connector_api, DuckDbConnector;
79837
79993
  var init_src = __esm({
79838
79994
  "packages/sql-preview-duckdb/src/index.ts"() {
79839
79995
  "use strict";
79840
- fs24 = __toESM(require("fs"));
79996
+ fs25 = __toESM(require("fs"));
79841
79997
  import_connector_api = __toESM(require_dist2());
79842
79998
  init_descriptor();
79843
79999
  DuckDbConnector = class {
@@ -79908,7 +80064,7 @@ var init_src = __esm({
79908
80064
  }
79909
80065
  if (config2.mounts) {
79910
80066
  for (const filePath of Object.values(config2.mounts)) {
79911
- if (!fs24.existsSync(filePath)) {
80067
+ if (!fs25.existsSync(filePath)) {
79912
80068
  }
79913
80069
  }
79914
80070
  }
@@ -79955,12 +80111,18 @@ var init_src = __esm({
79955
80111
  }
79956
80112
  if (cell !== null && typeof cell === "object") {
79957
80113
  const c = cell;
80114
+ if (typeof c.toDouble === "function" && typeof c.width === "number") {
80115
+ return c.width <= 15 ? c.toDouble() : c.toString();
80116
+ }
79958
80117
  if (typeof c.days === "number") {
79959
80118
  return typeof c.toString === "function" ? c.toString() : new Date(c.days * 864e5).toISOString().slice(0, 10);
79960
80119
  }
79961
80120
  if (c.micros !== void 0) {
79962
80121
  return typeof c.toString === "function" ? c.toString() : new Date(Number(c.micros) / 1e3).toISOString().replace("T", " ").slice(0, 19);
79963
80122
  }
80123
+ if (typeof c.toString === "function" && c.toString !== Object.prototype.toString) {
80124
+ return c.toString();
80125
+ }
79964
80126
  }
79965
80127
  return cell;
79966
80128
  })
@@ -90214,7 +90376,7 @@ var require_form_data = __commonJS({
90214
90376
  var http9 = require("http");
90215
90377
  var https6 = require("https");
90216
90378
  var parseUrl2 = require("url").parse;
90217
- var fs44 = require("fs");
90379
+ var fs45 = require("fs");
90218
90380
  var Stream = require("stream").Stream;
90219
90381
  var crypto19 = require("crypto");
90220
90382
  var mime = require_mime_types5();
@@ -90281,7 +90443,7 @@ var require_form_data = __commonJS({
90281
90443
  if (value.end != void 0 && value.end != Infinity && value.start != void 0) {
90282
90444
  callback(null, value.end + 1 - (value.start ? value.start : 0));
90283
90445
  } else {
90284
- fs44.stat(value.path, function(err, stat) {
90446
+ fs45.stat(value.path, function(err, stat) {
90285
90447
  if (err) {
90286
90448
  callback(err);
90287
90449
  return;
@@ -97692,11 +97854,11 @@ var src_exports4 = {};
97692
97854
  __export(src_exports4, {
97693
97855
  default: () => SQLiteConnector
97694
97856
  });
97695
- var fs25, import_connector_api4, SQLiteConnector;
97857
+ var fs26, import_connector_api4, SQLiteConnector;
97696
97858
  var init_src4 = __esm({
97697
97859
  "packages/sql-preview-sqlite/src/index.ts"() {
97698
97860
  "use strict";
97699
- fs25 = __toESM(require("fs"));
97861
+ fs26 = __toESM(require("fs"));
97700
97862
  import_connector_api4 = __toESM(require_dist2());
97701
97863
  init_descriptor4();
97702
97864
  SQLiteConnector = class {
@@ -97730,7 +97892,7 @@ var init_src4 = __esm({
97730
97892
  if (!this.db) {
97731
97893
  let fileBuffer;
97732
97894
  try {
97733
- fileBuffer = await fs25.promises.readFile(databasePath);
97895
+ fileBuffer = await fs26.promises.readFile(databasePath);
97734
97896
  } catch (err) {
97735
97897
  throw new import_connector_api4.ConnectionError(`Failed to load SQLite file at ${databasePath}: ${err.message}`);
97736
97898
  }
@@ -99934,11 +100096,11 @@ var init_BuiltInProfileStore = __esm({
99934
100096
  });
99935
100097
 
99936
100098
  // src/server/connection/FileProfileStore.ts
99937
- var fs26, path28, FileProfileStore;
100099
+ var fs27, path28, FileProfileStore;
99938
100100
  var init_FileProfileStore = __esm({
99939
100101
  "src/server/connection/FileProfileStore.ts"() {
99940
100102
  "use strict";
99941
- fs26 = __toESM(require("fs"));
100103
+ fs27 = __toESM(require("fs"));
99942
100104
  path28 = __toESM(require("path"));
99943
100105
  init_ConsoleLogger();
99944
100106
  init_grainHome();
@@ -99950,20 +100112,20 @@ var init_FileProfileStore = __esm({
99950
100112
  this.ensureConfigExists();
99951
100113
  }
99952
100114
  ensureConfigExists() {
99953
- if (!fs26.existsSync(this.configPath)) {
100115
+ if (!fs27.existsSync(this.configPath)) {
99954
100116
  const dir3 = path28.dirname(this.configPath);
99955
- if (!fs26.existsSync(dir3)) {
99956
- fs26.mkdirSync(dir3, { recursive: true });
100117
+ if (!fs27.existsSync(dir3)) {
100118
+ fs27.mkdirSync(dir3, { recursive: true });
99957
100119
  }
99958
100120
  this.writeConfig({ connections: [] });
99959
100121
  }
99960
100122
  }
99961
100123
  readConfig() {
99962
100124
  try {
99963
- if (!fs26.existsSync(this.configPath)) {
100125
+ if (!fs27.existsSync(this.configPath)) {
99964
100126
  return { connections: [] };
99965
100127
  }
99966
- const raw = fs26.readFileSync(this.configPath, "utf8");
100128
+ const raw = fs27.readFileSync(this.configPath, "utf8");
99967
100129
  return JSON.parse(raw);
99968
100130
  } catch (error52) {
99969
100131
  logger.error("Failed to read config:", error52);
@@ -99971,7 +100133,7 @@ var init_FileProfileStore = __esm({
99971
100133
  }
99972
100134
  }
99973
100135
  writeConfig(config2) {
99974
- fs26.writeFileSync(this.configPath, JSON.stringify(config2, null, 2), "utf8");
100136
+ fs27.writeFileSync(this.configPath, JSON.stringify(config2, null, 2), "utf8");
99975
100137
  }
99976
100138
  async loadProfiles() {
99977
100139
  const config2 = this.readConfig();
@@ -100023,18 +100185,18 @@ var init_MemoryCredentialStore = __esm({
100023
100185
  });
100024
100186
 
100025
100187
  // src/server/connection/FileCredentialStore.ts
100026
- var fs27, path29, FileCredentialStore;
100188
+ var fs28, path29, FileCredentialStore;
100027
100189
  var init_FileCredentialStore = __esm({
100028
100190
  "src/server/connection/FileCredentialStore.ts"() {
100029
100191
  "use strict";
100030
- fs27 = __toESM(require("fs"));
100192
+ fs28 = __toESM(require("fs"));
100031
100193
  path29 = __toESM(require("path"));
100032
100194
  init_ConsoleLogger();
100033
100195
  FileCredentialStore = class {
100034
100196
  constructor(configDir) {
100035
100197
  this.credentialsPath = path29.join(configDir, "credentials.json");
100036
- if (!fs27.existsSync(configDir)) {
100037
- fs27.mkdirSync(configDir, { recursive: true });
100198
+ if (!fs28.existsSync(configDir)) {
100199
+ fs28.mkdirSync(configDir, { recursive: true });
100038
100200
  }
100039
100201
  }
100040
100202
  async getPassword(profileId) {
@@ -100055,10 +100217,10 @@ var init_FileCredentialStore = __esm({
100055
100217
  }
100056
100218
  readMap() {
100057
100219
  try {
100058
- if (!fs27.existsSync(this.credentialsPath)) {
100220
+ if (!fs28.existsSync(this.credentialsPath)) {
100059
100221
  return {};
100060
100222
  }
100061
- const raw = fs27.readFileSync(this.credentialsPath, "utf8");
100223
+ const raw = fs28.readFileSync(this.credentialsPath, "utf8");
100062
100224
  const parsed = JSON.parse(raw);
100063
100225
  return parsed && typeof parsed === "object" ? parsed : {};
100064
100226
  } catch (error52) {
@@ -100071,9 +100233,9 @@ var init_FileCredentialStore = __esm({
100071
100233
  }
100072
100234
  writeMap(map4) {
100073
100235
  const tmpPath = `${this.credentialsPath}.tmp-${process.pid}-${Date.now()}`;
100074
- fs27.writeFileSync(tmpPath, JSON.stringify(map4, null, 2), { mode: 384 });
100075
- fs27.renameSync(tmpPath, this.credentialsPath);
100076
- 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);
100077
100239
  }
100078
100240
  };
100079
100241
  }
@@ -100132,7 +100294,7 @@ var init_ExtensionCredentialStore = __esm({
100132
100294
  { method: CREDENTIAL_GET_METHOD, params: { profileId } },
100133
100295
  CredentialGetResultSchema
100134
100296
  );
100135
- return result.password;
100297
+ return result.password ?? this.fallback.getPassword(profileId);
100136
100298
  } catch (error52) {
100137
100299
  logger.warn(
100138
100300
  `[ExtensionCredentialStore] Channel unavailable for getPassword(${profileId}); falling back to file store`,
@@ -100347,7 +100509,7 @@ var init_KeychainCredentialStore = __esm({
100347
100509
  [SERVICE_NAME, profileId],
100348
100510
  this.timeoutMs
100349
100511
  );
100350
- return typeof password === "string" ? password : void 0;
100512
+ return typeof password === "string" ? password : this.fallback.getPassword(profileId);
100351
100513
  } catch (error52) {
100352
100514
  if (error52 instanceof KeychainTimeoutError) {
100353
100515
  throw error52;
@@ -101087,6 +101249,7 @@ var init_classifyQueryError = __esm({
101087
101249
  /configuration error/,
101088
101250
  /no valid connection profile/,
101089
101251
  /connection ['"].*['"] not found/,
101252
+ /connection ['"].*['"] no longer exists/,
101090
101253
  /invalid connection/,
101091
101254
  /missing required (?:field|option|setting)/,
101092
101255
  /databasepath .*(?:required|missing|empty)/
@@ -102853,6 +103016,29 @@ function classifyForHumanGate(sql, dialect) {
102853
103016
  const classification = classifyStatement(sql, dialect);
102854
103017
  return classification.kind === "write" || classification.kind === "multi_statement" ? { kind: "confirm", classification } : { kind: "allow", classification };
102855
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
+ }
102856
103042
  var WRITE_KEYWORDS, READ_ONLY_START_KEYWORDS;
102857
103043
  var init_sqlPolicy = __esm({
102858
103044
  "src/common/sqlPolicy.ts"() {
@@ -115881,7 +116067,7 @@ function vRatio(u, v) {
115881
116067
  function vAngle(u, v) {
115882
116068
  return (u[0] * v[1] < u[1] * v[0] ? -1 : 1) * Math.acos(vRatio(u, v));
115883
116069
  }
115884
- 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) {
115885
116071
  var psi = psiDeg * (PI3 / 180);
115886
116072
  var xp = mathCos3(psi) * (x1 - x2) / 2 + mathSin3(psi) * (y1 - y2) / 2;
115887
116073
  var yp = -1 * mathSin3(psi) * (x1 - x2) / 2 + mathCos3(psi) * (y1 - y2) / 2;
@@ -115890,7 +116076,7 @@ function processArc(x1, y1, x2, y2, fa, fs44, rx, ry, psiDeg, cmd, path46) {
115890
116076
  rx *= mathSqrt3(lambda);
115891
116077
  ry *= mathSqrt3(lambda);
115892
116078
  }
115893
- 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;
115894
116080
  var cxp = f * rx * yp / ry;
115895
116081
  var cyp = f * -ry * xp / rx;
115896
116082
  var cx = (x1 + x2) / 2 + mathCos3(psi) * cxp - mathSin3(psi) * cyp;
@@ -115909,7 +116095,7 @@ function processArc(x1, y1, x2, y2, fa, fs44, rx, ry, psiDeg, cmd, path46) {
115909
116095
  var n = Math.round(dTheta / PI3 * 1e6) / 1e6;
115910
116096
  dTheta = PI3 * 2 + n % 2 * PI3;
115911
116097
  }
115912
- path46.addData(cmd, cx, cy, rx, ry, theta, dTheta, psi, fs44);
116098
+ path46.addData(cmd, cx, cy, rx, ry, theta, dTheta, psi, fs45);
115913
116099
  }
115914
116100
  function createPathProxyFromString(data) {
115915
116101
  var path46 = new PathProxy_default();
@@ -115943,7 +116129,7 @@ function createPathProxyFromString(data) {
115943
116129
  var ry = void 0;
115944
116130
  var psi = void 0;
115945
116131
  var fa = void 0;
115946
- var fs44 = void 0;
116132
+ var fs45 = void 0;
115947
116133
  var x1 = cpx;
115948
116134
  var y1 = cpy;
115949
116135
  var len2 = void 0;
@@ -116092,24 +116278,24 @@ function createPathProxyFromString(data) {
116092
116278
  ry = p[off++];
116093
116279
  psi = p[off++];
116094
116280
  fa = p[off++];
116095
- fs44 = p[off++];
116281
+ fs45 = p[off++];
116096
116282
  x1 = cpx, y1 = cpy;
116097
116283
  cpx = p[off++];
116098
116284
  cpy = p[off++];
116099
116285
  cmd = CMD6.A;
116100
- 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);
116101
116287
  break;
116102
116288
  case "a":
116103
116289
  rx = p[off++];
116104
116290
  ry = p[off++];
116105
116291
  psi = p[off++];
116106
116292
  fa = p[off++];
116107
- fs44 = p[off++];
116293
+ fs45 = p[off++];
116108
116294
  x1 = cpx, y1 = cpy;
116109
116295
  cpx += p[off++];
116110
116296
  cpy += p[off++];
116111
116297
  cmd = CMD6.A;
116112
- 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);
116113
116299
  break;
116114
116300
  }
116115
116301
  }
@@ -183002,11 +183188,11 @@ var init_ChartSsrRenderer = __esm({
183002
183188
  });
183003
183189
 
183004
183190
  // src/server/charts/ChartDocumentStore.ts
183005
- var fs28, path31, ChartDocumentStore;
183191
+ var fs29, path31, ChartDocumentStore;
183006
183192
  var init_ChartDocumentStore = __esm({
183007
183193
  "src/server/charts/ChartDocumentStore.ts"() {
183008
183194
  "use strict";
183009
- fs28 = __toESM(require("fs/promises"));
183195
+ fs29 = __toESM(require("fs/promises"));
183010
183196
  path31 = __toESM(require("path"));
183011
183197
  init_ChartSpecV1();
183012
183198
  ChartDocumentStore = class {
@@ -183043,8 +183229,8 @@ var init_ChartDocumentStore = __esm({
183043
183229
  if (!target.endsWith(".chart.yml") && !target.endsWith(".chart.yaml")) {
183044
183230
  throw new Error("Chart path must end in .chart.yml or .chart.yaml");
183045
183231
  }
183046
- await fs28.mkdir(path31.dirname(target), { recursive: true });
183047
- 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)}
183048
183234
  `, "utf8");
183049
183235
  return path31.relative(this.workspaceRoot, target);
183050
183236
  }
@@ -183065,7 +183251,7 @@ var init_ChartDocumentStore = __esm({
183065
183251
  async readDirectory(directory) {
183066
183252
  let entries;
183067
183253
  try {
183068
- entries = await fs28.readdir(directory, { withFileTypes: true });
183254
+ entries = await fs29.readdir(directory, { withFileTypes: true });
183069
183255
  } catch (error52) {
183070
183256
  if (error52.code === "ENOENT") {
183071
183257
  return [];
@@ -183078,7 +183264,7 @@ var init_ChartDocumentStore = __esm({
183078
183264
  if (entry.isDirectory()) {
183079
183265
  results.push(...await this.readDirectory(child));
183080
183266
  } else if (/\.chart\.ya?ml$/i.test(entry.name)) {
183081
- const validation = validateChartSpec(JSON.parse(await fs28.readFile(child, "utf8")));
183267
+ const validation = validateChartSpec(JSON.parse(await fs29.readFile(child, "utf8")));
183082
183268
  if (validation.valid) {
183083
183269
  results.push({
183084
183270
  path: path31.relative(this.workspaceRoot, child),
@@ -183202,6 +183388,24 @@ var init_DaemonMcpToolManager = __esm({
183202
183388
  get isConfirmWrites() {
183203
183389
  return this.confirmWrites;
183204
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
+ }
183205
183409
  /** Updates human write confirmation requirement live (e.g. from a settings-panel save). */
183206
183410
  setConfirmWrites(value) {
183207
183411
  this.confirmWrites = value;
@@ -183230,7 +183434,7 @@ var init_DaemonMcpToolManager = __esm({
183230
183434
  * received from the client.
183231
183435
  */
183232
183436
  captureUiEvent(event, properties, clientConsent) {
183233
- this.options.telemetry?.capture(event, properties, clientConsent);
183437
+ this.options.telemetry?.capture(event, { state: "unknown", ...properties }, clientConsent);
183234
183438
  }
183235
183439
  /** False for an alpha tool whose feature flag is off; such a tool is unlisted and uncallable. */
183236
183440
  isToolEnabled(name) {
@@ -183296,7 +183500,11 @@ var init_DaemonMcpToolManager = __esm({
183296
183500
  const success2 = thrown === void 0 && resultRecord?.isError !== true;
183297
183501
  let errorKind;
183298
183502
  let errorId;
183503
+ let errorCode;
183504
+ let errorClass;
183299
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);
183300
183508
  errorKind = thrown !== void 0 ? classifyErrorLike(thrown) : typeof resultRecord?.structuredContent?.errorKind === "string" ? resultRecord.structuredContent.errorKind : "unknown";
183301
183509
  if (typeof resultRecord?.structuredContent?.errorId === "string") {
183302
183510
  errorId = resultRecord.structuredContent.errorId;
@@ -183304,21 +183512,26 @@ var init_DaemonMcpToolManager = __esm({
183304
183512
  }
183305
183513
  const profileType = args;
183306
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
+ };
183307
183527
  telemetry.capture(
183308
183528
  "mcp_tool_invoked",
183309
- {
183310
- state: "mcp_server",
183311
- source: "mcp",
183312
- // Which agent transport this arrived on. Gating emission on origin without
183313
- // recording it left RFC-082's rollout unmeasurable (#113).
183314
- origin: origin2,
183315
- mcp_client: clientLabel,
183316
- tool_name: normalizeTelemetryToolName(name),
183317
- success: success2,
183318
- duration_bucket: bucketDurationMs(Date.now() - startedAt),
183319
- ...errorKind !== void 0 ? { error_kind: errorKind } : {},
183320
- ...errorId !== void 0 ? { error_id: errorId } : {},
183321
- ...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 } : {}
183322
183535
  },
183323
183536
  clientConsent
183324
183537
  );
@@ -183342,50 +183555,33 @@ var init_DaemonMcpToolManager = __esm({
183342
183555
  const refusal = admitToolCall(profile, name, this.isToolEnabled(name));
183343
183556
  if (refusal)
183344
183557
  return refusal;
183345
- switch (name) {
183346
- case "run_query":
183347
- return this.handleRunQuery(args, origin2, profile, clientConsent);
183348
- case "get_tab_info":
183349
- return this.handleGetTabInfo(args);
183350
- case "list_sessions":
183351
- return this.handleListSessions();
183352
- case "list_connectors":
183353
- return this.handleListConnectors();
183354
- case "list_connections":
183355
- return this.handleListConnections();
183356
- case "save_connection":
183357
- return this.handleSaveConnection(args, clientConsent);
183358
- case "request_connection_credentials":
183359
- return this.handleRequestConnectionCredentials(args, clientConsent);
183360
- case "test_connection":
183361
- return this.handleTestConnection(args, origin2, clientConsent);
183362
- case "delete_connection":
183363
- return this.handleDeleteConnection(args);
183364
- case "list_schemas":
183365
- return this.handleListSchemas(args, clientConsent);
183366
- case "list_tables":
183367
- return this.handleListTables(args, clientConsent);
183368
- case "describe_table":
183369
- return this.handleDescribeTable(args, clientConsent);
183370
- case "cancel_query":
183371
- return this.handleCancelQuery(args);
183372
- case "close_tab":
183373
- return this.handleCloseTab(args);
183374
- case "render_chart":
183375
- return this.handleRenderChart(args);
183376
- case "save_chart":
183377
- return this.handleSaveChart(args, workspaceRoot);
183378
- case "list_charts":
183379
- return this.handleListCharts(workspaceRoot);
183380
- case "ledger_stats":
183381
- return this.handleLedgerStats(clientConsent);
183382
- case "verify_ledger":
183383
- return this.handleVerifyLedger(clientConsent);
183384
- case "record_ui_event":
183385
- return this.handleRecordUiEvent(args, clientConsent);
183386
- default:
183387
- throw new Error("Unknown tool");
183388
- }
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]();
183389
183585
  }
183390
183586
  /**
183391
183587
  * RFC-088 Rung 2. The MCP app renders in an opaque-origin sandbox that cannot
@@ -183440,7 +183636,11 @@ var init_DaemonMcpToolManager = __esm({
183440
183636
  return {
183441
183637
  isError: true,
183442
183638
  content: [{ type: "text", text: e2 instanceof Error ? e2.message : String(e2) }],
183443
- structuredContent: { errorKind: classifyErrorLike(e2) }
183639
+ structuredContent: {
183640
+ errorKind: classifyErrorLike(e2),
183641
+ errorCode: diagnosticErrorCodeOf(e2),
183642
+ errorClass: diagnosticErrorClassOf(e2)
183643
+ }
183444
183644
  };
183445
183645
  }
183446
183646
  }
@@ -183462,7 +183662,11 @@ var init_DaemonMcpToolManager = __esm({
183462
183662
  return {
183463
183663
  isError: true,
183464
183664
  content: [{ type: "text", text: e2 instanceof Error ? e2.message : String(e2) }],
183465
- structuredContent: { errorKind: classifyErrorLike(e2) }
183665
+ structuredContent: {
183666
+ errorKind: classifyErrorLike(e2),
183667
+ errorCode: diagnosticErrorCodeOf(e2),
183668
+ errorClass: diagnosticErrorClassOf(e2)
183669
+ }
183466
183670
  };
183467
183671
  }
183468
183672
  }
@@ -183485,7 +183689,11 @@ var init_DaemonMcpToolManager = __esm({
183485
183689
  return {
183486
183690
  isError: true,
183487
183691
  content: [{ type: "text", text: e2 instanceof Error ? e2.message : String(e2) }],
183488
- structuredContent: { errorKind: classifyErrorLike(e2) }
183692
+ structuredContent: {
183693
+ errorKind: classifyErrorLike(e2),
183694
+ errorCode: diagnosticErrorCodeOf(e2),
183695
+ errorClass: diagnosticErrorClassOf(e2)
183696
+ }
183489
183697
  };
183490
183698
  }
183491
183699
  }
@@ -183751,9 +183959,16 @@ This link expires at ${new Date(
183751
183959
  } catch (error52) {
183752
183960
  const errorKind = classifyErrorLike(error52, typeToTest);
183753
183961
  const message = error52 instanceof Error ? error52.message : String(error52);
183962
+ const errorCode = diagnosticErrorCodeOf(error52);
183963
+ const errorClass = diagnosticErrorClassOf(error52);
183754
183964
  return this.failConnectionTest(
183755
183965
  `Connection Test Failed: ${message}`,
183756
- { 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
+ },
183757
183972
  clientConsent
183758
183973
  );
183759
183974
  }
@@ -183772,13 +183987,21 @@ This link expires at ${new Date(
183772
183987
  if (errorKind === "config") {
183773
183988
  return this.failConnectionTest(
183774
183989
  message,
183775
- { errorKind, errorId: "connection_test_configuration_invalid" },
183990
+ {
183991
+ errorKind,
183992
+ errorId: "connection_test_configuration_invalid",
183993
+ ...result.errorCode !== void 0 ? { errorCode: result.errorCode } : {}
183994
+ },
183776
183995
  clientConsent
183777
183996
  );
183778
183997
  }
183779
183998
  return this.failConnectionTest(
183780
183999
  message,
183781
- { errorKind, errorId: "connection_test_connection_failed" },
184000
+ {
184001
+ errorKind,
184002
+ errorId: "connection_test_connection_failed",
184003
+ ...result.errorCode !== void 0 ? { errorCode: result.errorCode } : {}
184004
+ },
183782
184005
  clientConsent
183783
184006
  );
183784
184007
  }
@@ -183876,11 +184099,9 @@ This link expires at ${new Date(
183876
184099
  }
183877
184100
  }
183878
184101
  if (isHumanOrigin(origin2) && this.confirmWrites && !confirmWrite) {
183879
- const verdict = classifyForHumanGate(sql, dialect);
183880
- if (verdict.kind === "confirm") {
183881
- const classification = verdict.classification;
183882
- 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.";
183883
- 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;
183884
184105
  return withQueryCallKey(
183885
184106
  {
183886
184107
  isError: true,
@@ -183943,7 +184164,9 @@ This link expires at ${new Date(
183943
184164
  status: "error",
183944
184165
  sessionId,
183945
184166
  error: message,
183946
- errorKind: classifyErrorLike(error52)
184167
+ errorKind: classifyErrorLike(error52),
184168
+ errorCode: diagnosticErrorCodeOf(error52),
184169
+ errorClass: diagnosticErrorClassOf(error52)
183947
184170
  }
183948
184171
  },
183949
184172
  callKey
@@ -184738,6 +184961,7 @@ var init_DaemonQueryExecutor = __esm({
184738
184961
  init_optionalDrivers();
184739
184962
  init_sqlPolicy();
184740
184963
  init_classifyQueryError();
184964
+ init_TelemetrySchema();
184741
184965
  init_DaemonConfig();
184742
184966
  init_SubProcessConnectorClient();
184743
184967
  init_ConnectorProcessPool();
@@ -184926,6 +185150,15 @@ var init_DaemonQueryExecutor = __esm({
184926
185150
  }
184927
185151
  if (!profile && connectionId) {
184928
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
+ }
184929
185162
  }
184930
185163
  if (!profile) {
184931
185164
  this.logger.info(`Fetching connections for fallback...`);
@@ -185089,7 +185322,13 @@ var init_DaemonQueryExecutor = __esm({
185089
185322
  return { success: true };
185090
185323
  } catch (e2) {
185091
185324
  const message = e2 instanceof Error ? e2.message : String(e2);
185092
- 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
+ };
185093
185332
  }
185094
185333
  }
185095
185334
  };
@@ -192673,9 +192912,9 @@ var init_requireDaemonAuth = __esm({
192673
192912
  // src/server/surfaces/DaemonSettingsRoute.ts
192674
192913
  function persistConfigPatch(configPath, patch2) {
192675
192914
  let onDisk = {};
192676
- if (fs29.existsSync(configPath)) {
192915
+ if (fs30.existsSync(configPath)) {
192677
192916
  try {
192678
- onDisk = JSON.parse(fs29.readFileSync(configPath, "utf8"));
192917
+ onDisk = JSON.parse(fs30.readFileSync(configPath, "utf8"));
192679
192918
  } catch (err) {
192680
192919
  logger.warn(`[Daemon] Could not parse existing config at ${configPath}, overwriting:`, err);
192681
192920
  onDisk = {};
@@ -192687,7 +192926,7 @@ function persistConfigPatch(configPath, patch2) {
192687
192926
  if (patch2.mcp) {
192688
192927
  onDisk["mcp"] = { ...onDisk["mcp"], ...patch2.mcp };
192689
192928
  }
192690
- fs29.writeFileSync(configPath, JSON.stringify(onDisk, null, 2) + "\n");
192929
+ fs30.writeFileSync(configPath, JSON.stringify(onDisk, null, 2) + "\n");
192691
192930
  }
192692
192931
  function createSettingsUpdateHandler(context2) {
192693
192932
  return (req, res) => {
@@ -192749,11 +192988,11 @@ function createSettingsUpdateHandler(context2) {
192749
192988
  }
192750
192989
  };
192751
192990
  }
192752
- 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;
192753
192992
  var init_DaemonSettingsRoute = __esm({
192754
192993
  "src/server/surfaces/DaemonSettingsRoute.ts"() {
192755
192994
  "use strict";
192756
- fs29 = __toESM(require("fs"));
192995
+ fs30 = __toESM(require("fs"));
192757
192996
  init_ConsoleLogger();
192758
192997
  init_requireDaemonAuth();
192759
192998
  init_ClientIdentity();
@@ -192804,13 +193043,13 @@ function distFileCandidates(fileName, baseDir = __dirname) {
192804
193043
  }
192805
193044
  function findDistFile(fileName, baseDir = __dirname) {
192806
193045
  const candidates = distFileCandidates(fileName, baseDir);
192807
- return candidates.find((candidate) => fs30.existsSync(candidate)) ?? candidates[1] ?? fileName;
193046
+ return candidates.find((candidate) => fs31.existsSync(candidate)) ?? candidates[1] ?? fileName;
192808
193047
  }
192809
- var fs30, path33;
193048
+ var fs31, path33;
192810
193049
  var init_distFiles = __esm({
192811
193050
  "src/server/surfaces/distFiles.ts"() {
192812
193051
  "use strict";
192813
- fs30 = __toESM(require("fs"));
193052
+ fs31 = __toESM(require("fs"));
192814
193053
  path33 = __toESM(require("path"));
192815
193054
  }
192816
193055
  });
@@ -193381,6 +193620,22 @@ async function handleQueryRoute(context2, req, res, options) {
193381
193620
  res.status(400).json({ error: options.missingQueryMessage });
193382
193621
  return;
193383
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
+ }
193384
193639
  const sessionId = typeof body.sessionId === "string" && body.sessionId.length > 0 ? body.sessionId : `${options.sessionPrefix}-${import_crypto11.default.randomUUID()}`;
193385
193640
  const controller = new AbortController();
193386
193641
  const cleanupDisconnectAbort = attachAbortOnHttpDisconnect(
@@ -193401,7 +193656,7 @@ async function handleQueryRoute(context2, req, res, options) {
193401
193656
  origin: "http_api",
193402
193657
  ...isSafeModeActive(policy.profile, context2.resolvedConfig.config.mcp.safeMode) ? { enforceReadOnly: true } : {},
193403
193658
  ...typeof body.tabId === "string" ? { tabId: body.tabId } : {},
193404
- ...options.supportsConnectionId && typeof body.connectionId === "string" ? { connectionId: body.connectionId } : {},
193659
+ ...connectionId !== void 0 ? { connectionId } : {},
193405
193660
  clientConsent: profiles.consent
193406
193661
  })
193407
193662
  );
@@ -193454,12 +193709,12 @@ function sendQueryResult(res, result) {
193454
193709
  function serveHtmlFile(res, fileName, notFoundMessage) {
193455
193710
  try {
193456
193711
  const htmlPath = findDistFile(fileName);
193457
- if (!fs31.existsSync(htmlPath)) {
193712
+ if (!fs32.existsSync(htmlPath)) {
193458
193713
  res.status(404).send(notFoundMessage);
193459
193714
  return;
193460
193715
  }
193461
193716
  res.setHeader("Content-Type", "text/html");
193462
- fs31.createReadStream(htmlPath).pipe(res);
193717
+ fs32.createReadStream(htmlPath).pipe(res);
193463
193718
  } catch (err) {
193464
193719
  logger.error(`[Daemon] Failed to serve ${fileName}:`, err);
193465
193720
  res.status(500).send("Internal Server Error");
@@ -193531,13 +193786,13 @@ function escapeHtml(value) {
193531
193786
  }
193532
193787
  });
193533
193788
  }
193534
- var import_crypto11, import_express, fs31, WEB_APP_CSP_DIRECTIVES, webProxiedTools;
193789
+ var import_crypto11, import_express, fs32, WEB_APP_CSP_DIRECTIVES, webProxiedTools;
193535
193790
  var init_DaemonHttpRoutes = __esm({
193536
193791
  "src/server/surfaces/DaemonHttpRoutes.ts"() {
193537
193792
  "use strict";
193538
193793
  import_crypto11 = __toESM(require("crypto"));
193539
193794
  import_express = __toESM(require_express2());
193540
- fs31 = __toESM(require("fs"));
193795
+ fs32 = __toESM(require("fs"));
193541
193796
  init_ConsoleLogger();
193542
193797
  init_httpAbort();
193543
193798
  init_toolProfiles();
@@ -203382,12 +203637,12 @@ var require_dist3 = __commonJS({
203382
203637
  throw new Error(`Unknown format "${name}"`);
203383
203638
  return f;
203384
203639
  };
203385
- function addFormats(ajv, list, fs44, exportName) {
203640
+ function addFormats(ajv, list, fs45, exportName) {
203386
203641
  var _a4;
203387
203642
  var _b2;
203388
203643
  (_a4 = (_b2 = ajv.opts.code).formats) !== null && _a4 !== void 0 ? _a4 : _b2.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
203389
203644
  for (const f of list)
203390
- ajv.addFormat(f, fs44[f]);
203645
+ ajv.addFormat(f, fs45[f]);
203391
203646
  }
203392
203647
  module2.exports = exports = formatsPlugin;
203393
203648
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -228738,7 +228993,7 @@ function readFileFromEnv(signalSpecificEnvVar, nonSignalSpecificEnvVar, warningM
228738
228993
  const filePath = signalSpecificPath ?? nonSignalSpecificPath;
228739
228994
  if (filePath != null) {
228740
228995
  try {
228741
- return fs32.readFileSync(path34.resolve(process.cwd(), filePath));
228996
+ return fs33.readFileSync(path34.resolve(process.cwd(), filePath));
228742
228997
  } catch {
228743
228998
  diag2.warn(warningMessage);
228744
228999
  return void 0;
@@ -228769,10 +229024,10 @@ function getNodeHttpConfigurationFromEnvironment(signalIdentifier, signalResourc
228769
229024
  })
228770
229025
  };
228771
229026
  }
228772
- var fs32, path34, import_core24;
229027
+ var fs33, path34, import_core24;
228773
229028
  var init_otlp_node_http_env_configuration = __esm({
228774
229029
  "node_modules/@opentelemetry/otlp-exporter-base/build/esm/configuration/otlp-node-http-env-configuration.js"() {
228775
- fs32 = __toESM(require("fs"));
229030
+ fs33 = __toESM(require("fs"));
228776
229031
  path34 = __toESM(require("path"));
228777
229032
  import_core24 = __toESM(require_src2());
228778
229033
  init_esm2();
@@ -230476,7 +230731,7 @@ var require_utils14 = __commonJS({
230476
230731
  var exporter_metrics_otlp_http_1 = require_src20();
230477
230732
  var exporter_metrics_otlp_proto_1 = require_src21();
230478
230733
  var sdk_logs_1 = require_src5();
230479
- var fs44 = require("fs");
230734
+ var fs45 = require("fs");
230480
230735
  var RESOURCE_DETECTOR_ENVIRONMENT = "env";
230481
230736
  var RESOURCE_DETECTOR_HOST = "host";
230482
230737
  var RESOURCE_DETECTOR_OS = "os";
@@ -230899,21 +231154,21 @@ var require_utils14 = __commonJS({
230899
231154
  const httpsAgentOptions = {};
230900
231155
  if (tls.ca_file) {
230901
231156
  try {
230902
- httpsAgentOptions.ca = fs44.readFileSync(tls.ca_file);
231157
+ httpsAgentOptions.ca = fs45.readFileSync(tls.ca_file);
230903
231158
  } catch (e2) {
230904
231159
  api_1.diag.warn(`Failed to read TLS CA file at ${tls.ca_file}: ${e2}`);
230905
231160
  }
230906
231161
  }
230907
231162
  if (tls.cert_file) {
230908
231163
  try {
230909
- httpsAgentOptions.cert = fs44.readFileSync(tls.cert_file);
231164
+ httpsAgentOptions.cert = fs45.readFileSync(tls.cert_file);
230910
231165
  } catch (e2) {
230911
231166
  api_1.diag.warn(`Failed to read TLS cert file at ${tls.cert_file}: ${e2}`);
230912
231167
  }
230913
231168
  }
230914
231169
  if (tls.key_file) {
230915
231170
  try {
230916
- httpsAgentOptions.key = fs44.readFileSync(tls.key_file);
231171
+ httpsAgentOptions.key = fs45.readFileSync(tls.key_file);
230917
231172
  } catch (e2) {
230918
231173
  api_1.diag.warn(`Failed to read TLS key file at ${tls.key_file}: ${e2}`);
230919
231174
  }
@@ -231892,12 +232147,12 @@ var init_guideHub = __esm({
231892
232147
  });
231893
232148
 
231894
232149
  // src/server/DaemonMcpServer.ts
231895
- 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;
231896
232151
  var init_DaemonMcpServer = __esm({
231897
232152
  "src/server/DaemonMcpServer.ts"() {
231898
232153
  "use strict";
231899
232154
  init_types();
231900
- fs33 = __toESM(require("fs"));
232155
+ fs34 = __toESM(require("fs"));
231901
232156
  import_crypto13 = require("crypto");
231902
232157
  init_telemetry();
231903
232158
  init_esm2();
@@ -232076,7 +232331,7 @@ var init_DaemonMcpServer = __esm({
232076
232331
  if (uri === UI_RESOURCE_URI) {
232077
232332
  try {
232078
232333
  const htmlPath = findDistFile("mcp-app.html");
232079
- const html = await fs33.promises.readFile(htmlPath, "utf-8");
232334
+ const html = await fs34.promises.readFile(htmlPath, "utf-8");
232080
232335
  const result2 = {
232081
232336
  contents: [
232082
232337
  {
@@ -232535,11 +232790,11 @@ var init_ExtensionConnectionTracker = __esm({
232535
232790
  });
232536
232791
 
232537
232792
  // src/server/surfaces/DaemonSocketSurface.ts
232538
- var fs34, net2, path35, bindSequence, DaemonSocketSurface;
232793
+ var fs35, net2, path35, bindSequence, DaemonSocketSurface;
232539
232794
  var init_DaemonSocketSurface = __esm({
232540
232795
  "src/server/surfaces/DaemonSocketSurface.ts"() {
232541
232796
  "use strict";
232542
- fs34 = __toESM(require("fs"));
232797
+ fs35 = __toESM(require("fs"));
232543
232798
  net2 = __toESM(require("net"));
232544
232799
  path35 = __toESM(require("path"));
232545
232800
  init_ipcEndpoint();
@@ -232575,8 +232830,8 @@ var init_DaemonSocketSurface = __esm({
232575
232830
  return;
232576
232831
  }
232577
232832
  if (isRelocatedDaemonIpcEndpoint(this.options.configDir, this.options.socketPath)) {
232578
- fs34.mkdirSync(path35.dirname(this.options.socketPath), { recursive: true, mode: 448 });
232579
- 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);
232580
232835
  logger.warn(
232581
232836
  `[Daemon] Relocated IPC endpoint from ${path35.join(this.options.configDir, "srv.sock")} to ${this.options.socketPath}.`
232582
232837
  );
@@ -232592,9 +232847,9 @@ var init_DaemonSocketSurface = __esm({
232592
232847
  );
232593
232848
  }
232594
232849
  const bindPath = canPublishByRename ? privatePath : this.options.socketPath;
232595
- if (usesFilesystemPath && fs34.existsSync(bindPath)) {
232850
+ if (usesFilesystemPath && fs35.existsSync(bindPath)) {
232596
232851
  try {
232597
- fs34.unlinkSync(bindPath);
232852
+ fs35.unlinkSync(bindPath);
232598
232853
  } catch (e2) {
232599
232854
  logger.warn("Failed to clean up socket:", e2);
232600
232855
  }
@@ -232648,8 +232903,8 @@ var init_DaemonSocketSurface = __esm({
232648
232903
  const onListen = () => {
232649
232904
  if (canPublishByRename) {
232650
232905
  try {
232651
- fs34.renameSync(bindPath, this.options.socketPath);
232652
- this.ownedEndpointInode = fs34.statSync(this.options.socketPath).ino;
232906
+ fs35.renameSync(bindPath, this.options.socketPath);
232907
+ this.ownedEndpointInode = fs35.statSync(this.options.socketPath).ino;
232653
232908
  } catch (error52) {
232654
232909
  cleanup();
232655
232910
  reject(error52);
@@ -232732,10 +232987,10 @@ var init_DaemonSocketSurface = __esm({
232732
232987
  return;
232733
232988
  }
232734
232989
  try {
232735
- if (fs34.statSync(this.options.socketPath).ino !== owned) {
232990
+ if (fs35.statSync(this.options.socketPath).ino !== owned) {
232736
232991
  return;
232737
232992
  }
232738
- fs34.unlinkSync(this.options.socketPath);
232993
+ fs35.unlinkSync(this.options.socketPath);
232739
232994
  } catch {
232740
232995
  }
232741
232996
  }
@@ -247447,12 +247702,12 @@ var init_artifactPins_generated = __esm({
247447
247702
  });
247448
247703
 
247449
247704
  // src/server/runtime/ManagedArtifactRuntime.ts
247450
- 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;
247451
247706
  var init_ManagedArtifactRuntime = __esm({
247452
247707
  "src/server/runtime/ManagedArtifactRuntime.ts"() {
247453
247708
  "use strict";
247454
247709
  crypto18 = __toESM(require("crypto"));
247455
- fs35 = __toESM(require("fs"));
247710
+ fs36 = __toESM(require("fs"));
247456
247711
  import_module = require("module");
247457
247712
  os7 = __toESM(require("os"));
247458
247713
  path36 = __toESM(require("path"));
@@ -247531,7 +247786,7 @@ var init_ManagedArtifactRuntime = __esm({
247531
247786
  const manifestPath = artifactManifestPath(versionDir);
247532
247787
  const existing = readManifest(manifestPath);
247533
247788
  if (existing && existing.layoutVersion === 2 && existing.platform === platform2 && this.manifestVersion(existing) === pins.artifactVersion) {
247534
- if (fs35.existsSync(versionDir)) {
247789
+ if (fs36.existsSync(versionDir)) {
247535
247790
  return versionDir;
247536
247791
  }
247537
247792
  }
@@ -247636,7 +247891,7 @@ var init_ManagedArtifactRuntime = __esm({
247636
247891
  }
247637
247892
  }
247638
247893
  const lockDir = `${versionDir}.provision-lock`;
247639
- fs35.mkdirSync(path36.dirname(lockDir), { recursive: true });
247894
+ fs36.mkdirSync(path36.dirname(lockDir), { recursive: true });
247640
247895
  const lockWaitStartMs = Date.now();
247641
247896
  const staleMs = this.options.provisionLockStaleMs ?? 5 * 60 * 1e3;
247642
247897
  const maxWaitMs = this.options.provisionLockMaxWaitMs ?? 10 * 60 * 1e3;
@@ -247676,13 +247931,13 @@ var init_ManagedArtifactRuntime = __esm({
247676
247931
  );
247677
247932
  }
247678
247933
  try {
247679
- const stats = fs35.statSync(lockDir);
247934
+ const stats = fs36.statSync(lockDir);
247680
247935
  const ageMs = Date.now() - stats.mtimeMs;
247681
247936
  if (ageMs > staleMs) {
247682
247937
  logger.warn(
247683
247938
  `[${this.logTag()}] Breaking stale provisioning lock: ${lockDir}, ageMs=${ageMs}`
247684
247939
  );
247685
- fs35.rmSync(lockDir, { recursive: true, force: true });
247940
+ fs36.rmSync(lockDir, { recursive: true, force: true });
247686
247941
  continue;
247687
247942
  }
247688
247943
  } catch (error52) {
@@ -247695,7 +247950,7 @@ var init_ManagedArtifactRuntime = __esm({
247695
247950
  heartbeatTimer = setInterval(() => {
247696
247951
  try {
247697
247952
  const now = Date.now() / 1e3;
247698
- fs35.utimesSync(lockDir, now, now);
247953
+ fs36.utimesSync(lockDir, now, now);
247699
247954
  } catch (error52) {
247700
247955
  }
247701
247956
  }, heartbeatIntervalMs);
@@ -247708,9 +247963,9 @@ var init_ManagedArtifactRuntime = __esm({
247708
247963
  }
247709
247964
  if (provisionToken) {
247710
247965
  try {
247711
- const currentToken = fs35.readFileSync(path36.join(lockDir, "owner"), "utf-8");
247966
+ const currentToken = fs36.readFileSync(path36.join(lockDir, "owner"), "utf-8");
247712
247967
  if (currentToken === provisionToken) {
247713
- fs35.rmSync(lockDir, { recursive: true, force: true });
247968
+ fs36.rmSync(lockDir, { recursive: true, force: true });
247714
247969
  }
247715
247970
  } catch (error52) {
247716
247971
  }
@@ -247723,8 +247978,8 @@ var init_ManagedArtifactRuntime = __esm({
247723
247978
  }
247724
247979
  this.reapOrphans(versionDir);
247725
247980
  const tempDir = `${versionDir}-tmp-${process.pid}-${Date.now()}`;
247726
- fs35.rmSync(tempDir, { recursive: true, force: true });
247727
- fs35.mkdirSync(tempDir, { recursive: true });
247981
+ fs36.rmSync(tempDir, { recursive: true, force: true });
247982
+ fs36.mkdirSync(tempDir, { recursive: true });
247728
247983
  const downloadPaths = [];
247729
247984
  const downloadPrefix = `sql-preview-${this.options.artifactId}-`;
247730
247985
  try {
@@ -247746,7 +248001,7 @@ var init_ManagedArtifactRuntime = __esm({
247746
248001
  }
247747
248002
  const actualHash = await sha512File(downloadPath);
247748
248003
  if (!verifyIntegrity(actualHash, tarball.integrity)) {
247749
- fs35.rmSync(downloadPath, { force: true });
248004
+ fs36.rmSync(downloadPath, { force: true });
247750
248005
  return this.fail("checksum_failed", `Integrity check failed for ${tarball.name}.`);
247751
248006
  }
247752
248007
  const packageDestDir = path36.join(
@@ -247755,10 +248010,10 @@ var init_ManagedArtifactRuntime = __esm({
247755
248010
  );
247756
248011
  await extractTarGz(downloadPath, packageDestDir);
247757
248012
  this.flattenNpmPackage(packageDestDir);
247758
- fs35.rmSync(downloadPath, { force: true });
248013
+ fs36.rmSync(downloadPath, { force: true });
247759
248014
  }
247760
- fs35.rmSync(versionDir, { recursive: true, force: true });
247761
- fs35.renameSync(tempDir, versionDir);
248015
+ fs36.rmSync(versionDir, { recursive: true, force: true });
248016
+ fs36.renameSync(tempDir, versionDir);
247762
248017
  const manifestBase = {
247763
248018
  layoutVersion: 2,
247764
248019
  platform: platform2,
@@ -247789,12 +248044,12 @@ var init_ManagedArtifactRuntime = __esm({
247789
248044
  );
247790
248045
  } finally {
247791
248046
  try {
247792
- fs35.rmSync(tempDir, { recursive: true, force: true });
248047
+ fs36.rmSync(tempDir, { recursive: true, force: true });
247793
248048
  } catch (error52) {
247794
248049
  }
247795
248050
  for (const downloadPath of downloadPaths) {
247796
248051
  try {
247797
- fs35.rmSync(downloadPath, { force: true });
248052
+ fs36.rmSync(downloadPath, { force: true });
247798
248053
  } catch (error52) {
247799
248054
  }
247800
248055
  }
@@ -247803,9 +248058,9 @@ var init_ManagedArtifactRuntime = __esm({
247803
248058
  }
247804
248059
  if (provisionToken) {
247805
248060
  try {
247806
- const currentToken = fs35.readFileSync(path36.join(lockDir, "owner"), "utf-8");
248061
+ const currentToken = fs36.readFileSync(path36.join(lockDir, "owner"), "utf-8");
247807
248062
  if (currentToken === provisionToken) {
247808
- fs35.rmSync(lockDir, { recursive: true, force: true });
248063
+ fs36.rmSync(lockDir, { recursive: true, force: true });
247809
248064
  }
247810
248065
  } catch (error52) {
247811
248066
  }
@@ -247820,12 +248075,12 @@ var init_ManagedArtifactRuntime = __esm({
247820
248075
  const versionBase = path36.basename(versionDir);
247821
248076
  const prefix = `${versionBase}-tmp-`;
247822
248077
  try {
247823
- const siblings = fs35.readdirSync(parentDir);
248078
+ const siblings = fs36.readdirSync(parentDir);
247824
248079
  for (const sibling of siblings) {
247825
248080
  if (sibling.startsWith(prefix)) {
247826
248081
  const siblingPath = path36.join(parentDir, sibling);
247827
248082
  try {
247828
- fs35.rmSync(siblingPath, { recursive: true, force: true });
248083
+ fs36.rmSync(siblingPath, { recursive: true, force: true });
247829
248084
  } catch (error52) {
247830
248085
  }
247831
248086
  }
@@ -247834,16 +248089,16 @@ var init_ManagedArtifactRuntime = __esm({
247834
248089
  }
247835
248090
  try {
247836
248091
  const downloadDir = this.downloadDir();
247837
- const files = fs35.readdirSync(downloadDir);
248092
+ const files = fs36.readdirSync(downloadDir);
247838
248093
  const now = Date.now();
247839
248094
  const downloadPrefix = `sql-preview-${this.options.artifactId}-`;
247840
248095
  for (const file4 of files) {
247841
248096
  if (file4.startsWith(downloadPrefix) && file4.endsWith(".tgz")) {
247842
248097
  const filePath = path36.join(downloadDir, file4);
247843
248098
  try {
247844
- const stats = fs35.statSync(filePath);
248099
+ const stats = fs36.statSync(filePath);
247845
248100
  if (now - stats.mtimeMs > ORPHAN_DOWNLOAD_MIN_AGE_MS) {
247846
- fs35.rmSync(filePath, { force: true });
248101
+ fs36.rmSync(filePath, { force: true });
247847
248102
  }
247848
248103
  } catch (error52) {
247849
248104
  }
@@ -247854,9 +248109,9 @@ var init_ManagedArtifactRuntime = __esm({
247854
248109
  }
247855
248110
  tryAcquireProvisionLock(lockDir) {
247856
248111
  try {
247857
- fs35.mkdirSync(lockDir, { recursive: false });
248112
+ fs36.mkdirSync(lockDir, { recursive: false });
247858
248113
  const token = `${process.pid}-${crypto18.randomUUID()}`;
247859
- fs35.writeFileSync(path36.join(lockDir, "owner"), token, "utf-8");
248114
+ fs36.writeFileSync(path36.join(lockDir, "owner"), token, "utf-8");
247860
248115
  return { acquired: true, token };
247861
248116
  } catch (error52) {
247862
248117
  if (error52.code === "EEXIST") {
@@ -247894,11 +248149,11 @@ var init_ManagedArtifactRuntime = __esm({
247894
248149
  }
247895
248150
  flattenNpmPackage(packageDestDir) {
247896
248151
  let archiveRoot = path36.join(packageDestDir, "package");
247897
- if (!fs35.statSync(archiveRoot, { throwIfNoEntry: false })?.isDirectory()) {
247898
- const entries = fs35.readdirSync(packageDestDir);
248152
+ if (!fs36.statSync(archiveRoot, { throwIfNoEntry: false })?.isDirectory()) {
248153
+ const entries = fs36.readdirSync(packageDestDir);
247899
248154
  if (entries.length === 1 && entries[0]) {
247900
248155
  const singleEntry = entries[0];
247901
- if (fs35.statSync(path36.join(packageDestDir, singleEntry)).isDirectory()) {
248156
+ if (fs36.statSync(path36.join(packageDestDir, singleEntry)).isDirectory()) {
247902
248157
  archiveRoot = path36.join(packageDestDir, singleEntry);
247903
248158
  } else {
247904
248159
  throw new Error(
@@ -247911,10 +248166,10 @@ var init_ManagedArtifactRuntime = __esm({
247911
248166
  );
247912
248167
  }
247913
248168
  }
247914
- for (const entry of fs35.readdirSync(archiveRoot)) {
247915
- 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));
247916
248171
  }
247917
- fs35.rmdirSync(archiveRoot);
248172
+ fs36.rmdirSync(archiveRoot);
247918
248173
  }
247919
248174
  };
247920
248175
  }
@@ -248110,11 +248365,11 @@ var init_DuckDbRuntime = __esm({
248110
248365
  });
248111
248366
 
248112
248367
  // src/server/runtime/DriverArtifactProvisioner.ts
248113
- var fs36, path37, DRIVER_ARTIFACTS, DriverArtifactProvisioner;
248368
+ var fs37, path37, DRIVER_ARTIFACTS, DriverArtifactProvisioner;
248114
248369
  var init_DriverArtifactProvisioner = __esm({
248115
248370
  "src/server/runtime/DriverArtifactProvisioner.ts"() {
248116
248371
  "use strict";
248117
- fs36 = __toESM(require("fs"));
248372
+ fs37 = __toESM(require("fs"));
248118
248373
  path37 = __toESM(require("path"));
248119
248374
  init_optionalDrivers();
248120
248375
  init_ManagedArtifactTypes();
@@ -248150,7 +248405,7 @@ var init_DriverArtifactProvisioner = __esm({
248150
248405
  pins.artifactVersion
248151
248406
  );
248152
248407
  const depPath = path37.join(versionDir, "node_modules", ...dependency.split("/"));
248153
- if (fs36.existsSync(depPath)) {
248408
+ if (fs37.existsSync(depPath)) {
248154
248409
  return depPath;
248155
248410
  }
248156
248411
  return null;
@@ -248280,11 +248535,11 @@ function rowToLedgerEntry(row) {
248280
248535
  function describeError3(error52) {
248281
248536
  return error52 instanceof Error ? error52.message : String(error52);
248282
248537
  }
248283
- 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;
248284
248539
  var init_JournalStore = __esm({
248285
248540
  "src/server/ledger/JournalStore.ts"() {
248286
248541
  "use strict";
248287
- fs37 = __toESM(require("fs"));
248542
+ fs38 = __toESM(require("fs"));
248288
248543
  path38 = __toESM(require("path"));
248289
248544
  init_canonicalSerialize();
248290
248545
  init_LedgerTypes();
@@ -248333,7 +248588,7 @@ var init_JournalStore = __esm({
248333
248588
  const lockPath = path38.join(options.storageDir, "execution-ledger.lock");
248334
248589
  let ownsLockfile = false;
248335
248590
  try {
248336
- fs37.mkdirSync(options.storageDir, { recursive: true });
248591
+ fs38.mkdirSync(options.storageDir, { recursive: true });
248337
248592
  } catch (error52) {
248338
248593
  throw new JournalStoreOpenError(
248339
248594
  "io-error",
@@ -248344,9 +248599,9 @@ var init_JournalStore = __esm({
248344
248599
  while (attempts < 2) {
248345
248600
  attempts++;
248346
248601
  try {
248347
- const fd = fs37.openSync(lockPath, "wx");
248348
- fs37.writeSync(fd, process.pid.toString());
248349
- fs37.closeSync(fd);
248602
+ const fd = fs38.openSync(lockPath, "wx");
248603
+ fs38.writeSync(fd, process.pid.toString());
248604
+ fs38.closeSync(fd);
248350
248605
  ownsLockfile = true;
248351
248606
  break;
248352
248607
  } catch (error52) {
@@ -248358,7 +248613,7 @@ var init_JournalStore = __esm({
248358
248613
  }
248359
248614
  let existingPid;
248360
248615
  try {
248361
- const pidContent = fs37.readFileSync(lockPath, "utf8");
248616
+ const pidContent = fs38.readFileSync(lockPath, "utf8");
248362
248617
  existingPid = parseInt(pidContent, 10);
248363
248618
  } catch (readError) {
248364
248619
  if (readError.code === "ENOENT") {
@@ -248390,7 +248645,7 @@ var init_JournalStore = __esm({
248390
248645
  );
248391
248646
  }
248392
248647
  try {
248393
- fs37.unlinkSync(lockPath);
248648
+ fs38.unlinkSync(lockPath);
248394
248649
  } catch (unlinkError) {
248395
248650
  if (unlinkError.code !== "ENOENT") {
248396
248651
  throw new JournalStoreOpenError(
@@ -248410,7 +248665,7 @@ var init_JournalStore = __esm({
248410
248665
  } catch (error52) {
248411
248666
  if (ownsLockfile) {
248412
248667
  try {
248413
- fs37.unlinkSync(lockPath);
248668
+ fs38.unlinkSync(lockPath);
248414
248669
  } catch {
248415
248670
  }
248416
248671
  }
@@ -248429,7 +248684,7 @@ var init_JournalStore = __esm({
248429
248684
  } catch (error52) {
248430
248685
  if (ownsLockfile) {
248431
248686
  try {
248432
- fs37.unlinkSync(lockPath);
248687
+ fs38.unlinkSync(lockPath);
248433
248688
  } catch {
248434
248689
  }
248435
248690
  }
@@ -248538,7 +248793,7 @@ var init_JournalStore = __esm({
248538
248793
  this.connection.closeSync();
248539
248794
  this.instance.closeSync();
248540
248795
  try {
248541
- fs37.unlinkSync(this.lockPath);
248796
+ fs38.unlinkSync(this.lockPath);
248542
248797
  } catch {
248543
248798
  }
248544
248799
  }
@@ -248985,11 +249240,11 @@ var init_LedgerService = __esm({
248985
249240
  function redactFatalText(text) {
248986
249241
  return text.replace(AUTHORIZATION_VALUE2, "$1 [redacted]").replace(SENSITIVE_ASSIGNMENT2, "$1[redacted]").replace(QUERY_ASSIGNMENT2, "$1[redacted]").replace(URL_SECRET2, "$1[redacted]");
248987
249242
  }
248988
- 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;
248989
249244
  var init_FatalJournal = __esm({
248990
249245
  "src/server/FatalJournal.ts"() {
248991
249246
  "use strict";
248992
- fs38 = __toESM(require("fs"));
249247
+ fs39 = __toESM(require("fs"));
248993
249248
  path39 = __toESM(require("path"));
248994
249249
  MAX_BYTES = 5 * 1024 * 1024;
248995
249250
  RETAINED_FILES = 5;
@@ -249024,23 +249279,23 @@ ${redactFatalText(detail)}
249024
249279
  return;
249025
249280
  }
249026
249281
  try {
249027
- fs38.mkdirSync(this.logDir, { recursive: true, mode: 448 });
249028
- fs38.chmodSync(this.logDir, 448);
249282
+ fs39.mkdirSync(this.logDir, { recursive: true, mode: 448 });
249283
+ fs39.chmodSync(this.logDir, 448);
249029
249284
  const bytes = Buffer.byteLength(text);
249030
249285
  this.rotateIfNeeded(bytes);
249031
249286
  this.assertNotSymlink(this.logPath);
249032
- const noFollow = fs38.constants.O_NOFOLLOW ?? 0;
249033
- const fd = fs38.openSync(
249287
+ const noFollow = fs39.constants.O_NOFOLLOW ?? 0;
249288
+ const fd = fs39.openSync(
249034
249289
  this.logPath,
249035
- 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,
249036
249291
  384
249037
249292
  );
249038
249293
  try {
249039
- fs38.writeSync(fd, text);
249040
- fs38.fsyncSync(fd);
249041
- fs38.fchmodSync(fd, 384);
249294
+ fs39.writeSync(fd, text);
249295
+ fs39.fsyncSync(fd);
249296
+ fs39.fchmodSync(fd, 384);
249042
249297
  } finally {
249043
- fs38.closeSync(fd);
249298
+ fs39.closeSync(fd);
249044
249299
  }
249045
249300
  } catch {
249046
249301
  this.disabled = true;
@@ -249051,7 +249306,7 @@ ${redactFatalText(detail)}
249051
249306
  let currentBytes = 0;
249052
249307
  try {
249053
249308
  this.assertNotSymlink(this.logPath);
249054
- currentBytes = fs38.statSync(this.logPath).size;
249309
+ currentBytes = fs39.statSync(this.logPath).size;
249055
249310
  } catch (error52) {
249056
249311
  if (error52.code !== "ENOENT") {
249057
249312
  throw error52;
@@ -249061,27 +249316,27 @@ ${redactFatalText(detail)}
249061
249316
  return;
249062
249317
  }
249063
249318
  const oldest = `${this.logPath}.${RETAINED_FILES}`;
249064
- if (fs38.existsSync(oldest)) {
249319
+ if (fs39.existsSync(oldest)) {
249065
249320
  this.assertNotSymlink(oldest);
249066
- fs38.unlinkSync(oldest);
249321
+ fs39.unlinkSync(oldest);
249067
249322
  }
249068
249323
  for (let index = RETAINED_FILES - 1; index >= 1; index--) {
249069
249324
  const source = `${this.logPath}.${index}`;
249070
- if (!fs38.existsSync(source)) {
249325
+ if (!fs39.existsSync(source)) {
249071
249326
  continue;
249072
249327
  }
249073
249328
  this.assertNotSymlink(source);
249074
- fs38.renameSync(source, `${this.logPath}.${index + 1}`);
249329
+ fs39.renameSync(source, `${this.logPath}.${index + 1}`);
249075
249330
  }
249076
- if (fs38.existsSync(this.logPath)) {
249331
+ if (fs39.existsSync(this.logPath)) {
249077
249332
  this.assertNotSymlink(this.logPath);
249078
- fs38.renameSync(this.logPath, `${this.logPath}.1`);
249079
- fs38.chmodSync(`${this.logPath}.1`, 384);
249333
+ fs39.renameSync(this.logPath, `${this.logPath}.1`);
249334
+ fs39.chmodSync(`${this.logPath}.1`, 384);
249080
249335
  }
249081
249336
  }
249082
249337
  assertNotSymlink(target) {
249083
249338
  try {
249084
- if (fs38.lstatSync(target).isSymbolicLink()) {
249339
+ if (fs39.lstatSync(target).isSymbolicLink()) {
249085
249340
  throw new Error("Refusing to write fatal journal through a symbolic link");
249086
249341
  }
249087
249342
  } catch (error52) {
@@ -249154,11 +249409,11 @@ var init_registerDriverModulePath = __esm({
249154
249409
  function faultIdentity(daemonVersion, kind, errorName) {
249155
249410
  return `${daemonVersion}:${kind}:${errorName}`;
249156
249411
  }
249157
- 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;
249158
249413
  var init_DiagnosticsBudget = __esm({
249159
249414
  "src/server/DiagnosticsBudget.ts"() {
249160
249415
  "use strict";
249161
- fs39 = __toESM(require("fs"));
249416
+ fs40 = __toESM(require("fs"));
249162
249417
  path41 = __toESM(require("path"));
249163
249418
  DIAGNOSTICS_REPORT_BUDGET = 3;
249164
249419
  DIAGNOSTICS_BUDGET_WINDOW_MS = 60 * 6e4;
@@ -249172,10 +249427,10 @@ var init_DiagnosticsBudget = __esm({
249172
249427
  }
249173
249428
  read() {
249174
249429
  try {
249175
- if (!fs39.existsSync(this.filePath)) {
249430
+ if (!fs40.existsSync(this.filePath)) {
249176
249431
  return { version: BUDGET_VERSION, entries: {} };
249177
249432
  }
249178
- const content = fs39.readFileSync(this.filePath, "utf8");
249433
+ const content = fs40.readFileSync(this.filePath, "utf8");
249179
249434
  const parsed = JSON.parse(content);
249180
249435
  if (!parsed || typeof parsed !== "object" || parsed.version !== BUDGET_VERSION || typeof parsed.entries !== "object" || parsed.entries === null || Array.isArray(parsed.entries)) {
249181
249436
  return { version: BUDGET_VERSION, entries: {} };
@@ -249188,12 +249443,12 @@ var init_DiagnosticsBudget = __esm({
249188
249443
  write(file4) {
249189
249444
  try {
249190
249445
  const dir3 = path41.dirname(this.filePath);
249191
- if (!fs39.existsSync(dir3)) {
249192
- fs39.mkdirSync(dir3, { recursive: true });
249446
+ if (!fs40.existsSync(dir3)) {
249447
+ fs40.mkdirSync(dir3, { recursive: true });
249193
249448
  }
249194
249449
  const tempPath = `${this.filePath}.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`;
249195
- fs39.writeFileSync(tempPath, JSON.stringify(file4, null, 2), "utf8");
249196
- fs39.renameSync(tempPath, this.filePath);
249450
+ fs40.writeFileSync(tempPath, JSON.stringify(file4, null, 2), "utf8");
249451
+ fs40.renameSync(tempPath, this.filePath);
249197
249452
  } catch (error52) {
249198
249453
  if (!this.hasLoggedWriteError) {
249199
249454
  this.hasLoggedWriteError = true;
@@ -249592,8 +249847,8 @@ function pointerPath(configHome, version3) {
249592
249847
  function removeVersion(configHome, version3) {
249593
249848
  const appPath = applicationDir(configHome, version3);
249594
249849
  try {
249595
- fs40.rmSync(appPath, { recursive: true, force: true });
249596
- fs40.rmSync(pointerPath(configHome, version3), { force: true });
249850
+ fs41.rmSync(appPath, { recursive: true, force: true });
249851
+ fs41.rmSync(pointerPath(configHome, version3), { force: true });
249597
249852
  return true;
249598
249853
  } catch {
249599
249854
  return false;
@@ -249610,11 +249865,11 @@ function pruneOldVersions(configHome, keep) {
249610
249865
  }
249611
249866
  return removed;
249612
249867
  }
249613
- var fs40, path42, SEMVER_PATTERN2;
249868
+ var fs41, path42, SEMVER_PATTERN2;
249614
249869
  var init_VersionRetention = __esm({
249615
249870
  "src/server/update/VersionRetention.ts"() {
249616
249871
  "use strict";
249617
- fs40 = __toESM(require("fs"));
249872
+ fs41 = __toESM(require("fs"));
249618
249873
  path42 = __toESM(require("path"));
249619
249874
  init_applicationPayload();
249620
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-]+)*)?$/;
@@ -249646,7 +249901,7 @@ function removeBestEffort(fileSystem, target) {
249646
249901
  function findPayloadEntry(root) {
249647
249902
  const entries = [];
249648
249903
  const visit = (directory) => {
249649
- for (const entry2 of fs41.readdirSync(directory, { withFileTypes: true })) {
249904
+ for (const entry2 of fs42.readdirSync(directory, { withFileTypes: true })) {
249650
249905
  const entryPath = path43.join(directory, entry2.name);
249651
249906
  if (entry2.isDirectory()) {
249652
249907
  visit(entryPath);
@@ -249693,11 +249948,11 @@ function atomicWritePointer(fileSystem, pointerPath2, pointer) {
249693
249948
  }
249694
249949
  removeBestEffort(fileSystem, backupPath);
249695
249950
  }
249696
- var fs41, os8, path43, SEMVER_PATTERN3, UpdateStager;
249951
+ var fs42, os8, path43, SEMVER_PATTERN3, UpdateStager;
249697
249952
  var init_UpdateStager = __esm({
249698
249953
  "src/server/update/UpdateStager.ts"() {
249699
249954
  "use strict";
249700
- fs41 = __toESM(require("fs"));
249955
+ fs42 = __toESM(require("fs"));
249701
249956
  os8 = __toESM(require("os"));
249702
249957
  path43 = __toESM(require("path"));
249703
249958
  init_protocolVersion();
@@ -249713,7 +249968,7 @@ var init_UpdateStager = __esm({
249713
249968
  this.configHome = options.configHome;
249714
249969
  this.currentVersion = options.currentVersion;
249715
249970
  this.downloadDir = options.downloadDir ?? os8.tmpdir();
249716
- this.fileSystem = options.fileSystem ?? fs41;
249971
+ this.fileSystem = options.fileSystem ?? fs42;
249717
249972
  }
249718
249973
  stagedVersion() {
249719
249974
  const versionsDir = path43.join(this.configHome, "versions");
@@ -249841,7 +250096,7 @@ var init_UpdateStager = __esm({
249841
250096
  function namesADeadProcess(pidPath) {
249842
250097
  let pid;
249843
250098
  try {
249844
- pid = parseInt(fs42.readFileSync(pidPath, "utf8"), 10);
250099
+ pid = parseInt(fs43.readFileSync(pidPath, "utf8"), 10);
249845
250100
  } catch {
249846
250101
  return true;
249847
250102
  }
@@ -249858,7 +250113,7 @@ function namesADeadProcess(pidPath) {
249858
250113
  function pruneDeadPidFiles(configDir, ownPidPath) {
249859
250114
  let entries;
249860
250115
  try {
249861
- entries = fs42.readdirSync(configDir);
250116
+ entries = fs43.readdirSync(configDir);
249862
250117
  } catch {
249863
250118
  return [];
249864
250119
  }
@@ -249875,7 +250130,7 @@ function pruneDeadPidFiles(configDir, ownPidPath) {
249875
250130
  continue;
249876
250131
  }
249877
250132
  try {
249878
- fs42.unlinkSync(candidate);
250133
+ fs43.unlinkSync(candidate);
249879
250134
  pruned.push(entry);
249880
250135
  } catch {
249881
250136
  continue;
@@ -249883,11 +250138,11 @@ function pruneDeadPidFiles(configDir, ownPidPath) {
249883
250138
  }
249884
250139
  return pruned;
249885
250140
  }
249886
- var fs42, path44, PID_FILE_PATTERN;
250141
+ var fs43, path44, PID_FILE_PATTERN;
249887
250142
  var init_pidFilePruning = __esm({
249888
250143
  "src/server/pidFilePruning.ts"() {
249889
250144
  "use strict";
249890
- fs42 = __toESM(require("fs"));
250145
+ fs43 = __toESM(require("fs"));
249891
250146
  path44 = __toESM(require("path"));
249892
250147
  PID_FILE_PATTERN = /^server-\d+\.pid$/;
249893
250148
  }
@@ -249936,7 +250191,7 @@ function createDaemonActivationGate(sources) {
249936
250191
  })
249937
250192
  });
249938
250193
  }
249939
- function readInstalledApplicationVersion(configHome, entryPath, fileSystem = fs43) {
250194
+ function readInstalledApplicationVersion(configHome, entryPath, fileSystem = fs44) {
249940
250195
  if (!entryPath) {
249941
250196
  return null;
249942
250197
  }
@@ -249967,7 +250222,7 @@ function readInstalledApplicationVersion(configHome, entryPath, fileSystem = fs4
249967
250222
  function writePidFileAtomically(pidPath, pid) {
249968
250223
  const tempPath = `${pidPath}.${pid}.${Math.random().toString(36).slice(2)}.tmp`;
249969
250224
  try {
249970
- fs43.writeFileSync(tempPath, pid.toString());
250225
+ fs44.writeFileSync(tempPath, pid.toString());
249971
250226
  } catch {
249972
250227
  return false;
249973
250228
  }
@@ -249977,7 +250232,7 @@ function writePidFileAtomically(pidPath, pid) {
249977
250232
  let lastErrorCode;
249978
250233
  for (let attempt = 1; attempt <= MAX_RENAME_ATTEMPTS; attempt++) {
249979
250234
  try {
249980
- fs43.renameSync(tempPath, pidPath);
250235
+ fs44.renameSync(tempPath, pidPath);
249981
250236
  renameSuccess = true;
249982
250237
  break;
249983
250238
  } catch (e2) {
@@ -249996,28 +250251,28 @@ function writePidFileAtomically(pidPath, pid) {
249996
250251
  }
249997
250252
  let directWriteSuccess = false;
249998
250253
  try {
249999
- if (!fs43.existsSync(pidPath)) {
250000
- fs43.writeFileSync(pidPath, pid.toString());
250254
+ if (!fs44.existsSync(pidPath)) {
250255
+ fs44.writeFileSync(pidPath, pid.toString());
250001
250256
  directWriteSuccess = true;
250002
250257
  } else {
250003
250258
  logger.warn(`[Daemon] Failed to write PID file ${pidPath}: ${lastErrorCode || "unknown"}`);
250004
250259
  }
250005
250260
  } finally {
250006
250261
  try {
250007
- if (fs43.existsSync(tempPath)) {
250008
- fs43.unlinkSync(tempPath);
250262
+ if (fs44.existsSync(tempPath)) {
250263
+ fs44.unlinkSync(tempPath);
250009
250264
  }
250010
250265
  } catch {
250011
250266
  }
250012
250267
  }
250013
250268
  return directWriteSuccess;
250014
250269
  }
250015
- 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;
250016
250271
  var init_Daemon = __esm({
250017
250272
  "src/server/Daemon.ts"() {
250018
250273
  "use strict";
250019
250274
  import_express4 = __toESM(require_express2());
250020
- fs43 = __toESM(require("fs"));
250275
+ fs44 = __toESM(require("fs"));
250021
250276
  http8 = __toESM(require("http"));
250022
250277
  path45 = __toESM(require("path"));
250023
250278
  init_ipcEndpoint();
@@ -250646,8 +250901,8 @@ var init_Daemon = __esm({
250646
250901
  }
250647
250902
  return this.ingressClosePromise;
250648
250903
  }
250649
- async terminateExistingDaemonProcess(existingPid) {
250650
- const isSqlPreviewDaemon = await this.isSqlPreviewDaemonProcess(existingPid);
250904
+ async terminateExistingDaemonProcess(existingPid, host, port) {
250905
+ const isSqlPreviewDaemon = await this.isSqlPreviewDaemonProcess(existingPid, host, port);
250651
250906
  if (!isSqlPreviewDaemon) {
250652
250907
  logger.warn(
250653
250908
  `[Daemon] Could not confirm live process ${existingPid} is a Grain daemon (its /status did not report a matching pid); leaving process untouched.`
@@ -250732,17 +250987,17 @@ var init_Daemon = __esm({
250732
250987
  return;
250733
250988
  }
250734
250989
  for (let attempt = 0; attempt < 20; attempt++) {
250735
- if (!fs43.existsSync(this.SOCKET_PATH)) {
250990
+ if (!fs44.existsSync(this.SOCKET_PATH)) {
250736
250991
  await new Promise((resolve11) => setTimeout(resolve11, 100));
250737
- if (!fs43.existsSync(this.SOCKET_PATH)) {
250992
+ if (!fs44.existsSync(this.SOCKET_PATH)) {
250738
250993
  return;
250739
250994
  }
250740
250995
  }
250741
250996
  await new Promise((resolve11) => setTimeout(resolve11, 50));
250742
250997
  }
250743
250998
  }
250744
- async isSqlPreviewDaemonProcess(pid) {
250745
- const status = await this.readExistingDaemonStatus();
250999
+ async isSqlPreviewDaemonProcess(pid, host, port) {
251000
+ const status = await this.readExistingDaemonStatus(host, port);
250746
251001
  return status?.service === DAEMON_SERVICE_IDENTITY && status.pid === pid;
250747
251002
  }
250748
251003
  async readExistingDaemonStatus(host = this.config.server.host, port = this.HTTP_PORT) {
@@ -250760,7 +251015,7 @@ var init_Daemon = __esm({
250760
251015
  host,
250761
251016
  port,
250762
251017
  path: "/status",
250763
- timeout: 500,
251018
+ timeout: 2e3,
250764
251019
  headers: this.authToken ? { Authorization: `Bearer ${this.authToken}` } : void 0
250765
251020
  },
250766
251021
  (res) => {
@@ -250810,25 +251065,66 @@ var init_Daemon = __esm({
250810
251065
  await new Promise((resolve11) => setTimeout(resolve11, 50));
250811
251066
  }
250812
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
+ }
250813
251109
  async resolveEndpointOccupant() {
250814
251110
  const endpoint = `${this.config.server.host}:${this.HTTP_PORT}`;
250815
251111
  if (await isTcpPortAvailable(this.HTTP_PORT, this.config.server.host)) {
250816
251112
  return { action: "proceed" };
250817
251113
  }
250818
251114
  const status = await this.readExistingDaemonStatus();
250819
- 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) {
250820
251117
  logger.error(
250821
- `[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.`
250822
251119
  );
250823
251120
  return { action: "exit", code: EXIT_UNIDENTIFIED_ENDPOINT_OCCUPIED };
250824
251121
  }
250825
251122
  if (status.version) {
250826
- const myVersion = require_package().version;
250827
- const cmp = compareSemver(status.version, myVersion);
250828
- if (cmp > 0 || cmp === 0 && status.state !== "draining" && status.state !== "refusing") {
251123
+ const evalResult = this.evaluateOccupantVersion(status.version, status.state);
251124
+ if (evalResult.yield) {
250829
251125
  if (await this.waitForOccupantEndpoint(OCCUPANT_ENDPOINT_GRACE_MS)) {
250830
251126
  logger.info(
250831
- `[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.`
250832
251128
  );
250833
251129
  return { action: "exit", code: 42 };
250834
251130
  }
@@ -250859,10 +251155,10 @@ var init_Daemon = __esm({
250859
251155
  let deferPidClaimUntilAfterBind = this.HTTP_PORT === 0 || shouldFallbackToEphemeral;
250860
251156
  try {
250861
251157
  pruneDeadPidFiles(this.CONFIG_DIR, pidPath);
250862
- if (!shouldFallbackToEphemeral && fs43.existsSync(pidPath)) {
251158
+ if (!shouldFallbackToEphemeral && fs44.existsSync(pidPath)) {
250863
251159
  let pidContent = null;
250864
251160
  try {
250865
- pidContent = fs43.readFileSync(pidPath, "utf8");
251161
+ pidContent = fs44.readFileSync(pidPath, "utf8");
250866
251162
  } catch (error52) {
250867
251163
  logger.info(
250868
251164
  `[Daemon] PID file at ${pidPath} could not be read (${error52.code ?? "unknown"}); treating it as unclaimed and checking the endpoint instead.`
@@ -250874,13 +251170,12 @@ var init_Daemon = __esm({
250874
251170
  process.kill(existingPid, 0);
250875
251171
  const status = await this.readExistingDaemonStatus();
250876
251172
  if (status?.service === DAEMON_SERVICE_IDENTITY && status.pid === existingPid && status.version) {
250877
- const myVersion = require_package().version;
250878
- const cmp = compareSemver(status.version, myVersion);
250879
- if (cmp > 0 || cmp === 0 && status.state !== "draining" && status.state !== "refusing") {
251173
+ const evalResult = this.evaluateOccupantVersion(status.version, status.state);
251174
+ if (evalResult.yield) {
250880
251175
  logger.info(
250881
- `[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})`
250882
251177
  );
250883
- process.exit(42);
251178
+ return process.exit(42);
250884
251179
  }
250885
251180
  }
250886
251181
  const termination = await this.terminateExistingDaemonProcess(existingPid);
@@ -250894,31 +251189,14 @@ var init_Daemon = __esm({
250894
251189
  deferPidClaimUntilAfterBind = true;
250895
251190
  }
250896
251191
  } catch (e2) {
250897
- const err = e2;
250898
- if (err.code === "ESRCH") {
250899
- logger.info(`[Daemon] Cleaning up stale PID file for ${existingPid}`);
250900
- } else if (err.code === "EPERM") {
250901
- logger.info(
250902
- `[Daemon] PID file names live process ${existingPid} owned by another user (EPERM); cleaning up stale PID file.`
250903
- );
250904
- } else if (e2 instanceof TakeoverRefusalError && e2.code === "UNIDENTIFIED_OCCUPANT") {
250905
- logger.error(
250906
- `[Daemon] Endpoint ${this.config.server.host}:${this.HTTP_PORT} is occupied by live unidentified process ${existingPid}; refusing startup.`
250907
- );
250908
- return process.exit(EXIT_UNIDENTIFIED_ENDPOINT_OCCUPIED);
250909
- } else if (e2 instanceof TakeoverRefusalError && e2.code === "PREDECESSOR_DID_NOT_DRAIN") {
250910
- logger.error(
250911
- `[Daemon] Predecessor daemon PID ${existingPid} did not exit after its drain window; refusing takeover.`
250912
- );
250913
- return process.exit(EXIT_PREDECESSOR_DRAIN_TIMEOUT);
250914
- } else {
250915
- logger.error(`[Daemon] Failed to terminate existing process ${existingPid}: ${e2}`);
250916
- return process.exit(1);
251192
+ const exitCode = this.takeoverFailureExitCode(e2, existingPid);
251193
+ if (exitCode !== void 0) {
251194
+ return process.exit(exitCode);
250917
251195
  }
250918
251196
  }
250919
251197
  }
250920
- if (!deferPidClaimUntilAfterBind && !isNaN(existingPid) && fs43.existsSync(pidPath)) {
250921
- fs43.unlinkSync(pidPath);
251198
+ if (!deferPidClaimUntilAfterBind && !isNaN(existingPid) && fs44.existsSync(pidPath)) {
251199
+ fs44.unlinkSync(pidPath);
250922
251200
  }
250923
251201
  }
250924
251202
  if (!deferPidClaimUntilAfterBind && !shouldFallbackToEphemeral) {
@@ -250930,7 +251208,7 @@ var init_Daemon = __esm({
250930
251208
  deferPidClaimUntilAfterBind = true;
250931
251209
  }
250932
251210
  }
250933
- if (shouldFallbackToEphemeral) {
251211
+ if (deferPidClaimUntilAfterBind || shouldFallbackToEphemeral) {
250934
251212
  const record2 = readDaemonEndpoint(this.CONFIG_DIR);
250935
251213
  if (record2) {
250936
251214
  let alive = false;
@@ -250942,10 +251220,34 @@ var init_Daemon = __esm({
250942
251220
  if (alive) {
250943
251221
  const status = await this.readExistingDaemonStatus(record2.host, record2.port);
250944
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
+ }
250945
251230
  logger.info(
250946
- `[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.`
250947
251232
  );
250948
- 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
+ }
250949
251251
  }
250950
251252
  }
250951
251253
  }
@@ -251248,11 +251550,11 @@ var init_Daemon = __esm({
251248
251550
  if (this.ownsPidAndSocket && !this.preserveOwnershipArtifactsOnStop) {
251249
251551
  const pidPath = this.pidFilePath();
251250
251552
  removeDaemonEndpoint(this.CONFIG_DIR);
251251
- if (fs43.existsSync(pidPath)) {
251553
+ if (fs44.existsSync(pidPath)) {
251252
251554
  try {
251253
- const recordedPid = Number(fs43.readFileSync(pidPath, "utf8"));
251555
+ const recordedPid = Number(fs44.readFileSync(pidPath, "utf8"));
251254
251556
  if (recordedPid === process.pid) {
251255
- fs43.unlinkSync(pidPath);
251557
+ fs44.unlinkSync(pidPath);
251256
251558
  }
251257
251559
  } catch {
251258
251560
  }
@@ -251288,6 +251590,7 @@ var init_Daemon = __esm({
251288
251590
  var standalone_exports = {};
251289
251591
  __export(standalone_exports, {
251290
251592
  SERVICE_START_FLUSH_BUDGET_MS: () => SERVICE_START_FLUSH_BUDGET_MS,
251593
+ connectStdioToSharedDaemon: () => connectStdioToSharedDaemon,
251291
251594
  main: () => main
251292
251595
  });
251293
251596
  module.exports = __toCommonJS(standalone_exports);
@@ -251457,30 +251760,45 @@ init_ConfigLoader();
251457
251760
  init_statusCommand();
251458
251761
 
251459
251762
  // src/server/install/addToPathCommand.ts
251460
- var fs6 = __toESM(require("fs"));
251763
+ var fs7 = __toESM(require("fs"));
251461
251764
  var os2 = __toESM(require("os"));
251462
- var path8 = __toESM(require("path"));
251765
+ var path9 = __toESM(require("path"));
251463
251766
  var import_child_process = require("child_process");
251464
251767
  init_grainHome();
251465
251768
 
251466
251769
  // src/server/install/grainCommand.ts
251467
- var fs5 = __toESM(require("fs"));
251468
- var path7 = __toESM(require("path"));
251469
- function writeGrainCommand(home, platform2 = process.platform) {
251470
- const bin = path7.join(home, "bin");
251471
- 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 });
251472
251775
  if (platform2 === "win32") {
251473
- const libexec = path7.join(home, "libexec");
251474
- fs5.mkdirSync(libexec, { recursive: true });
251776
+ const libexec = path8.join(home, "libexec");
251777
+ fileSystem.mkdirSync(libexec, { recursive: true });
251475
251778
  const script2 = WIN_SCRIPT.replace("__GRAIN_HOME__", home);
251476
- fs5.writeFileSync(path7.join(libexec, "grain.ps1"), "\uFEFF" + script2 + "\r\n", "utf8");
251477
- fs5.writeFileSync(path7.join(bin, "grain.cmd"), CMD_SCRIPT, "ascii");
251478
- 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
+ }
251479
251792
  return;
251480
251793
  }
251481
251794
  const script = POSIX_SCRIPT.replace("__GRAIN_HOME__", home);
251482
- fs5.writeFileSync(path7.join(bin, "grain"), script, { mode: 493 });
251483
- 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
+ }
251484
251802
  }
251485
251803
  var POSIX_SCRIPT = `#!/bin/sh
251486
251804
  GRAIN_HOME="\${GRAIN_HOME:-__GRAIN_HOME__}"
@@ -251521,21 +251839,21 @@ var CMD_SCRIPT = '@echo off\r\npowershell -NoProfile -ExecutionPolicy Bypass -Fi
251521
251839
  // src/server/install/addToPathCommand.ts
251522
251840
  function profileForShell(deps) {
251523
251841
  const home = deps.home ?? os2.homedir();
251524
- switch (path8.basename(deps.shell ?? process.env["SHELL"] ?? "sh")) {
251842
+ switch (path9.basename(deps.shell ?? process.env["SHELL"] ?? "sh")) {
251525
251843
  case "zsh":
251526
- return path8.join(deps.zdotdir ?? process.env["ZDOTDIR"] ?? home, ".zshrc");
251844
+ return path9.join(deps.zdotdir ?? process.env["ZDOTDIR"] ?? home, ".zshrc");
251527
251845
  case "bash":
251528
- return path8.join(home, deps.platform === "darwin" ? ".bash_profile" : ".bashrc");
251846
+ return path9.join(home, deps.platform === "darwin" ? ".bash_profile" : ".bashrc");
251529
251847
  case "fish":
251530
- return path8.join(home, ".config/fish/conf.d/grain.fish");
251848
+ return path9.join(home, ".config/fish/conf.d/grain.fish");
251531
251849
  default:
251532
- return path8.join(home, ".profile");
251850
+ return path9.join(home, ".profile");
251533
251851
  }
251534
251852
  }
251535
251853
  function addToPathCommand(deps = {}) {
251536
251854
  const platform2 = deps.platform ?? process.platform;
251537
251855
  const grainHome = deps.grainHome ?? resolveGrainHome();
251538
- const bin = path8.join(grainHome, "bin");
251856
+ const bin = path9.join(grainHome, "bin");
251539
251857
  const output = deps.writeOutput ?? console.log;
251540
251858
  writeGrainCommand(grainHome, platform2);
251541
251859
  if ((deps.noModifyPath ?? process.env["GRAIN_NO_MODIFY_PATH"]) === "1") {
@@ -251559,25 +251877,42 @@ function addToPathCommand(deps = {}) {
251559
251877
  { input: value }
251560
251878
  );
251561
251879
  });
251562
- const current = read();
251563
- if (!current.split(";").some((entry) => entry.toLowerCase() === bin.toLowerCase())) {
251564
- write(current ? `${bin};${current}` : bin);
251565
- output(`Added ${bin} to your user PATH.`);
251566
- } else {
251567
- 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;
251568
251894
  }
251569
251895
  } else {
251570
251896
  const profile = profileForShell({ ...deps, platform: platform2 });
251571
- if (!fs6.existsSync(profile) || !fs6.readFileSync(profile, "utf8").includes(bin)) {
251572
- fs6.mkdirSync(path8.dirname(profile), { recursive: true });
251573
- const line = profile.endsWith(".fish") ? `fish_add_path "${bin}"` : `export PATH="${bin}:$PATH"`;
251574
- 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, `
251575
251902
  # Added by the Grain installer
251576
251903
  ${line}
251577
251904
  `);
251578
- output(`Added ${bin} to your PATH in ${profile}`);
251579
- } else {
251580
- 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;
251581
251916
  }
251582
251917
  }
251583
251918
  output("Open a new terminal, then run: grain");
@@ -251586,7 +251921,7 @@ ${line}
251586
251921
 
251587
251922
  // src/server/install/installCommand.ts
251588
251923
  var crypto8 = __toESM(require("crypto"));
251589
- var fs17 = __toESM(require("fs"));
251924
+ var fs18 = __toESM(require("fs"));
251590
251925
  var os4 = __toESM(require("os"));
251591
251926
  var path21 = __toESM(require("path"));
251592
251927
  init_grainHome();
@@ -251596,9 +251931,9 @@ init_DaemonTelemetryService();
251596
251931
 
251597
251932
  // src/server/runtime/NodeRuntimeProvisioner.ts
251598
251933
  var crypto7 = __toESM(require("crypto"));
251599
- var fs14 = __toESM(require("fs"));
251934
+ var fs15 = __toESM(require("fs"));
251600
251935
  var os3 = __toESM(require("os"));
251601
- var path16 = __toESM(require("path"));
251936
+ var path17 = __toESM(require("path"));
251602
251937
  init_ArtifactDownloader();
251603
251938
  init_MinimalTarExtractor();
251604
251939
  init_ManagedArtifactTypes();
@@ -251652,8 +251987,8 @@ var NODE_PLATFORM_PINS = {
251652
251987
 
251653
251988
  // src/server/runtime/daemonRuntimeIdentity.ts
251654
251989
  var import_child_process2 = require("child_process");
251655
- var fs13 = __toESM(require("fs"));
251656
- var path15 = __toESM(require("path"));
251990
+ var fs14 = __toESM(require("fs"));
251991
+ var path16 = __toESM(require("path"));
251657
251992
  var DAEMON_RUNTIME_SIGNING_IDENTIFIER = "tools.grain-daemon";
251658
251993
  function runtimeBinaryName(kind) {
251659
251994
  return kind === "exe" ? "grain-daemon.exe" : "grain-daemon";
@@ -251662,22 +251997,22 @@ function legacyRuntimeBinaryName(kind) {
251662
251997
  return kind === "exe" ? "node.exe" : "node";
251663
251998
  }
251664
251999
  function binaryDir(versionDir, kind) {
251665
- return kind === "exe" ? versionDir : path15.join(versionDir, "bin");
252000
+ return kind === "exe" ? versionDir : path16.join(versionDir, "bin");
251666
252001
  }
251667
252002
  function runtimeBinaryPath(versionDir, kind) {
251668
- return path15.join(binaryDir(versionDir, kind), runtimeBinaryName(kind));
252003
+ return path16.join(binaryDir(versionDir, kind), runtimeBinaryName(kind));
251669
252004
  }
251670
252005
  function legacyRuntimeBinaryPath(versionDir, kind) {
251671
- return path15.join(binaryDir(versionDir, kind), legacyRuntimeBinaryName(kind));
252006
+ return path16.join(binaryDir(versionDir, kind), legacyRuntimeBinaryName(kind));
251672
252007
  }
251673
252008
  function adoptRuntimeBinary(versionDir, kind, platform2 = process.platform) {
251674
252009
  const target = runtimeBinaryPath(versionDir, kind);
251675
252010
  const legacy = legacyRuntimeBinaryPath(versionDir, kind);
251676
252011
  let outcome;
251677
- if (fs13.existsSync(target)) {
252012
+ if (fs14.existsSync(target)) {
251678
252013
  outcome = "already-adopted";
251679
- } else if (fs13.existsSync(legacy)) {
251680
- fs13.renameSync(legacy, target);
252014
+ } else if (fs14.existsSync(legacy)) {
252015
+ fs14.renameSync(legacy, target);
251681
252016
  outcome = "renamed";
251682
252017
  } else {
251683
252018
  return "nothing-to-adopt";
@@ -251740,7 +252075,7 @@ var _NodeRuntimeProvisioner = class {
251740
252075
  installedNodePath() {
251741
252076
  const binary = this.binaryPath();
251742
252077
  try {
251743
- fs14.accessSync(binary, fs14.constants.X_OK);
252078
+ fs15.accessSync(binary, fs15.constants.X_OK);
251744
252079
  return binary;
251745
252080
  } catch {
251746
252081
  return this.adoptLegacyInstall();
@@ -251757,7 +252092,7 @@ var _NodeRuntimeProvisioner = class {
251757
252092
  return null;
251758
252093
  }
251759
252094
  try {
251760
- fs14.accessSync(this.binaryPath(), fs14.constants.X_OK);
252095
+ fs15.accessSync(this.binaryPath(), fs15.constants.X_OK);
251761
252096
  return this.binaryPath();
251762
252097
  } catch {
251763
252098
  return null;
@@ -251769,7 +252104,7 @@ var _NodeRuntimeProvisioner = class {
251769
252104
  if (existing) {
251770
252105
  return existing;
251771
252106
  }
251772
- const key = path16.resolve(this.versionDir());
252107
+ const key = path17.resolve(this.versionDir());
251773
252108
  const pending = _NodeRuntimeProvisioner.inFlight.get(key);
251774
252109
  if (pending) {
251775
252110
  return pending;
@@ -251787,7 +252122,7 @@ var _NodeRuntimeProvisioner = class {
251787
252122
  async provisionWithLock() {
251788
252123
  const pin = this.pin();
251789
252124
  const downloadDir = this.options.downloadDir ?? os3.tmpdir();
251790
- fs14.mkdirSync(downloadDir, { recursive: true });
252125
+ fs15.mkdirSync(downloadDir, { recursive: true });
251791
252126
  const finalDir = this.versionDir();
251792
252127
  const lock = await this.acquireProvisionLock(`${finalDir}.provision-lock`);
251793
252128
  try {
@@ -251797,9 +252132,9 @@ var _NodeRuntimeProvisioner = class {
251797
252132
  if (lockedExisting) {
251798
252133
  return lockedExisting;
251799
252134
  }
251800
- fs14.rmSync(finalDir, { recursive: true, force: true });
251801
- const stagingDir = fs14.mkdtempSync(path16.join(downloadDir, "grain-node-"));
251802
- 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");
251803
252138
  try {
251804
252139
  await downloadToFile(pin.url, downloadPath);
251805
252140
  const actual = await sha256File(downloadPath);
@@ -251808,24 +252143,24 @@ var _NodeRuntimeProvisioner = class {
251808
252143
  `Node runtime checksum mismatch for ${pin.platform}: expected ${pin.sha256}, got ${actual}`
251809
252144
  );
251810
252145
  }
251811
- const unpackDir = path16.join(stagingDir, "unpacked");
251812
- fs14.mkdirSync(unpackDir, { recursive: true });
252146
+ const unpackDir = path17.join(stagingDir, "unpacked");
252147
+ fs15.mkdirSync(unpackDir, { recursive: true });
251813
252148
  if (pin.kind === "exe") {
251814
- fs14.copyFileSync(downloadPath, path16.join(unpackDir, "node.exe"));
252149
+ fs15.copyFileSync(downloadPath, path17.join(unpackDir, "node.exe"));
251815
252150
  } else {
251816
252151
  await extractTarGz(downloadPath, unpackDir);
251817
252152
  }
251818
- const extractedBinary = path16.join(unpackDir, pin.binaryPathInArchive);
251819
- if (!fs14.existsSync(extractedBinary)) {
252153
+ const extractedBinary = path17.join(unpackDir, pin.binaryPathInArchive);
252154
+ if (!fs15.existsSync(extractedBinary)) {
251820
252155
  throw new Error(`Node artifact did not contain ${pin.binaryPathInArchive}`);
251821
252156
  }
251822
- fs14.chmodSync(extractedBinary, 493);
251823
- fs14.mkdirSync(path16.dirname(finalDir), { recursive: true });
252157
+ fs15.chmodSync(extractedBinary, 493);
252158
+ fs15.mkdirSync(path17.dirname(finalDir), { recursive: true });
251824
252159
  const archiveRoot = pin.binaryPathInArchive.split("/")[0];
251825
252160
  if (!archiveRoot && pin.kind !== "exe") {
251826
252161
  throw new Error(`Node artifact has an invalid binary path: ${pin.binaryPathInArchive}`);
251827
252162
  }
251828
- const sourceRoot = pin.kind === "exe" ? unpackDir : path16.join(unpackDir, archiveRoot ?? "");
252163
+ const sourceRoot = pin.kind === "exe" ? unpackDir : path17.join(unpackDir, archiveRoot ?? "");
251829
252164
  this.moveIntoPlace(sourceRoot, finalDir);
251830
252165
  adoptRuntimeBinary(finalDir, pin.kind);
251831
252166
  const provisioned = this.installedNodePath();
@@ -251845,16 +252180,16 @@ var _NodeRuntimeProvisioner = class {
251845
252180
  }
251846
252181
  }
251847
252182
  async acquireProvisionLock(lockDir) {
251848
- fs14.mkdirSync(path16.dirname(lockDir), { recursive: true });
252183
+ fs15.mkdirSync(path17.dirname(lockDir), { recursive: true });
251849
252184
  const startedAt = Date.now();
251850
252185
  const staleMs = this.options.provisionLockStaleMs ?? PROVISION_LOCK_STALE_MS;
251851
252186
  const maxWaitMs = this.options.provisionLockMaxWaitMs ?? PROVISION_LOCK_MAX_WAIT_MS;
251852
252187
  const token = `${process.pid}-${crypto7.randomUUID()}`;
251853
252188
  for (; ; ) {
251854
252189
  try {
251855
- fs14.mkdirSync(lockDir);
252190
+ fs15.mkdirSync(lockDir);
251856
252191
  try {
251857
- fs14.writeFileSync(path16.join(lockDir, "owner"), token, "utf8");
252192
+ fs15.writeFileSync(path17.join(lockDir, "owner"), token, "utf8");
251858
252193
  } catch (error52) {
251859
252194
  this.removeBestEffort(lockDir);
251860
252195
  throw error52;
@@ -251863,7 +252198,7 @@ var _NodeRuntimeProvisioner = class {
251863
252198
  () => {
251864
252199
  try {
251865
252200
  const now = Date.now() / 1e3;
251866
- fs14.utimesSync(lockDir, now, now);
252201
+ fs15.utimesSync(lockDir, now, now);
251867
252202
  } catch {
251868
252203
  return;
251869
252204
  }
@@ -251889,7 +252224,7 @@ var _NodeRuntimeProvisioner = class {
251889
252224
  }
251890
252225
  isStaleLock(lockDir, staleMs) {
251891
252226
  try {
251892
- return Date.now() - fs14.statSync(lockDir).mtimeMs > staleMs;
252227
+ return Date.now() - fs15.statSync(lockDir).mtimeMs > staleMs;
251893
252228
  } catch {
251894
252229
  return false;
251895
252230
  }
@@ -251897,8 +252232,8 @@ var _NodeRuntimeProvisioner = class {
251897
252232
  releaseProvisionLock(lock) {
251898
252233
  clearInterval(lock.heartbeat);
251899
252234
  try {
251900
- if (fs14.readFileSync(path16.join(lock.directory, "owner"), "utf8") === lock.token) {
251901
- 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 });
251902
252237
  }
251903
252238
  } catch {
251904
252239
  return;
@@ -251908,7 +252243,7 @@ var _NodeRuntimeProvisioner = class {
251908
252243
  const staleMs = this.options.stagingDirStaleMs ?? STAGING_DIR_STALE_MS;
251909
252244
  let entries;
251910
252245
  try {
251911
- entries = fs14.readdirSync(downloadDir, { withFileTypes: true });
252246
+ entries = fs15.readdirSync(downloadDir, { withFileTypes: true });
251912
252247
  } catch {
251913
252248
  return;
251914
252249
  }
@@ -251916,9 +252251,9 @@ var _NodeRuntimeProvisioner = class {
251916
252251
  if (!entry.isDirectory() || !entry.name.startsWith("grain-node-")) {
251917
252252
  continue;
251918
252253
  }
251919
- const stagingDir = path16.join(downloadDir, entry.name);
252254
+ const stagingDir = path17.join(downloadDir, entry.name);
251920
252255
  try {
251921
- if (Date.now() - fs14.statSync(stagingDir).mtimeMs > staleMs) {
252256
+ if (Date.now() - fs15.statSync(stagingDir).mtimeMs > staleMs) {
251922
252257
  this.removeBestEffort(stagingDir);
251923
252258
  }
251924
252259
  } catch {
@@ -251927,12 +252262,12 @@ var _NodeRuntimeProvisioner = class {
251927
252262
  }
251928
252263
  }
251929
252264
  reapDestinationStages(finalDir) {
251930
- const parentDir = path16.dirname(finalDir);
251931
- const prefix = `.${path16.basename(finalDir)}-tmp-`;
252265
+ const parentDir = path17.dirname(finalDir);
252266
+ const prefix = `.${path17.basename(finalDir)}-tmp-`;
251932
252267
  const staleMs = this.options.stagingDirStaleMs ?? STAGING_DIR_STALE_MS;
251933
252268
  let entries;
251934
252269
  try {
251935
- entries = fs14.readdirSync(parentDir, { withFileTypes: true });
252270
+ entries = fs15.readdirSync(parentDir, { withFileTypes: true });
251936
252271
  } catch {
251937
252272
  return;
251938
252273
  }
@@ -251940,9 +252275,9 @@ var _NodeRuntimeProvisioner = class {
251940
252275
  if (!entry.isDirectory() || !entry.name.startsWith(prefix)) {
251941
252276
  continue;
251942
252277
  }
251943
- const destinationStage = path16.join(parentDir, entry.name);
252278
+ const destinationStage = path17.join(parentDir, entry.name);
251944
252279
  try {
251945
- if (Date.now() - fs14.statSync(destinationStage).mtimeMs > staleMs) {
252280
+ if (Date.now() - fs15.statSync(destinationStage).mtimeMs > staleMs) {
251946
252281
  this.removeBestEffort(destinationStage);
251947
252282
  }
251948
252283
  } catch {
@@ -251952,25 +252287,25 @@ var _NodeRuntimeProvisioner = class {
251952
252287
  }
251953
252288
  removeBestEffort(target) {
251954
252289
  try {
251955
- fs14.rmSync(target, { recursive: true, force: true });
252290
+ fs15.rmSync(target, { recursive: true, force: true });
251956
252291
  } catch {
251957
252292
  return;
251958
252293
  }
251959
252294
  }
251960
252295
  moveIntoPlace(source, destination) {
251961
252296
  try {
251962
- fs14.renameSync(source, destination);
252297
+ fs15.renameSync(source, destination);
251963
252298
  } catch (error52) {
251964
252299
  if (error52.code !== "EXDEV") {
251965
252300
  throw error52;
251966
252301
  }
251967
252302
  let destinationStage;
251968
252303
  try {
251969
- destinationStage = fs14.mkdtempSync(
251970
- path16.join(path16.dirname(destination), `.${path16.basename(destination)}-tmp-`)
252304
+ destinationStage = fs15.mkdtempSync(
252305
+ path17.join(path17.dirname(destination), `.${path17.basename(destination)}-tmp-`)
251971
252306
  );
251972
- fs14.cpSync(source, destinationStage, { recursive: true });
251973
- fs14.renameSync(destinationStage, destination);
252307
+ fs15.cpSync(source, destinationStage, { recursive: true });
252308
+ fs15.renameSync(destinationStage, destination);
251974
252309
  destinationStage = void 0;
251975
252310
  this.removeBestEffort(source);
251976
252311
  } finally {
@@ -252030,15 +252365,15 @@ function generateLaunchAgent(descriptor) {
252030
252365
  }
252031
252366
 
252032
252367
  // src/server/install/launcher.ts
252033
- var path18 = __toESM(require("path"));
252368
+ var path19 = __toESM(require("path"));
252034
252369
  init_protocolVersion();
252035
252370
 
252036
252371
  // src/server/install/launchFailureMarker.ts
252037
- var fs15 = __toESM(require("fs"));
252038
- var path17 = __toESM(require("path"));
252372
+ var fs16 = __toESM(require("fs"));
252373
+ var path18 = __toESM(require("path"));
252039
252374
  var LAUNCH_FAILURE_MARKER_FILENAME = "grain-launch-failure.json";
252040
252375
  function launchFailureMarkerPath(configHome) {
252041
- return path17.join(configHome, LAUNCH_FAILURE_MARKER_FILENAME);
252376
+ return path18.join(configHome, LAUNCH_FAILURE_MARKER_FILENAME);
252042
252377
  }
252043
252378
  function isLaunchFailureReason(value) {
252044
252379
  return value === "no_payload" || value === "spawn_failed" || value === "launch_attempt";
@@ -252050,7 +252385,7 @@ function isLaunchFailureMarker(value) {
252050
252385
  const entry = value;
252051
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");
252052
252387
  }
252053
- function readAndClearLaunchFailureMarker(configHome, fileSystem = fs15) {
252388
+ function readAndClearLaunchFailureMarker(configHome, fileSystem = fs16) {
252054
252389
  const markerPath = launchFailureMarkerPath(configHome);
252055
252390
  if (!fileSystem.existsSync(markerPath)) {
252056
252391
  return void 0;
@@ -252074,7 +252409,7 @@ function readAndClearLaunchFailureMarker(configHome, fileSystem = fs15) {
252074
252409
  // src/server/install/launcher.ts
252075
252410
  var LAUNCHER_FILENAME = "grain-daemon-launcher.js";
252076
252411
  function launcherPath(configHome) {
252077
- return path18.join(configHome, LAUNCHER_FILENAME);
252412
+ return path19.join(configHome, LAUNCHER_FILENAME);
252078
252413
  }
252079
252414
  function launcherSource(configHome) {
252080
252415
  return `#!/usr/bin/env node
@@ -252174,7 +252509,8 @@ const recoveredFrom = recoverFromFailedLaunch(previousMarker);
252174
252509
  const payload = resolvePayload();
252175
252510
  if (!payload) {
252176
252511
  writeLaunchFailureMarker('no_payload', 'No valid daemon payload pointer was found.');
252177
- 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);
252178
252514
  process.exit(1);
252179
252515
  }
252180
252516
 
@@ -252291,23 +252627,11 @@ function generateWindowsStartupTask(descriptor) {
252291
252627
  };
252292
252628
  }
252293
252629
 
252294
- // src/common/serviceMode.ts
252295
- var path20 = __toESM(require("path"));
252296
- var SERVICE_MODE_FILENAME = "service-mode.json";
252297
- function serviceModePath(configDir) {
252298
- return path20.join(configDir, SERVICE_MODE_FILENAME);
252299
- }
252300
- function writeServiceMode(fileSystem, configDir, record2) {
252301
- fileSystem.writeFileSync(serviceModePath(configDir), `${JSON.stringify(record2, null, 2)}
252302
- `, {
252303
- mode: 384
252304
- });
252305
- }
252306
-
252307
252630
  // src/server/install/installCommand.ts
252631
+ init_serviceMode();
252308
252632
  init_acquisitionChannel();
252309
252633
  init_telemetryConsent();
252310
- var GRAIN_SERVICE_LABEL = `tools.${DAEMON_SERVICE_IDENTITY}`;
252634
+ init_daemonRecordInstance();
252311
252635
  function unitFor(platform2, launcher, configHome, nodePath) {
252312
252636
  const descriptor = {
252313
252637
  launcherPath: launcher,
@@ -252428,15 +252752,19 @@ function registerCliPayload(fileSystem, configHome, standalonePath, writeOutput)
252428
252752
  if (!fileSystem.existsSync(standalonePath)) {
252429
252753
  return;
252430
252754
  }
252431
- const installedEntry = installApplicationPayload({
252432
- configHome,
252433
- version: version3,
252434
- sourceEntry: standalonePath
252435
- });
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
+ }
252436
252761
  const versionsDir = path21.join(configHome, "versions");
252437
252762
  fileSystem.mkdirSync(versionsDir, { recursive: true });
252438
252763
  const pointerPath2 = path21.join(versionsDir, `${version3}.json`);
252439
- 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
+ }
252440
252768
  } catch (error52) {
252441
252769
  writeOutput(`Warning: could not register this build for the launcher: ${describeError(error52)}`);
252442
252770
  }
@@ -252449,7 +252777,7 @@ async function installCommand(deps = {}) {
252449
252777
  const configHome = deps.configHome ?? resolveGrainHome();
252450
252778
  const homeDirectory = deps.homeDirectory ?? os4.homedir();
252451
252779
  const uid = deps.uid ?? process.getuid?.() ?? 0;
252452
- const fileSystem = deps.fileSystem ?? fs17;
252780
+ const fileSystem = deps.fileSystem ?? fs18;
252453
252781
  const runner = deps.commandRunner ?? createCommandRunner();
252454
252782
  const adapter2 = deps.adapter ?? createSupervisorAdapter(platform2, runner, uid);
252455
252783
  const readStatus = deps.readStatus ?? readGrainServiceStatus;
@@ -252458,11 +252786,11 @@ async function installCommand(deps = {}) {
252458
252786
  const telemetryConsentFlag = deps.telemetryConsent;
252459
252787
  const standalonePath = deps.standalonePath ?? require.main?.filename;
252460
252788
  fileSystem.mkdirSync(configHome, { recursive: true });
252461
- writeGrainCommand(configHome, platform2);
252789
+ writeGrainCommand(configHome, platform2, fileSystem);
252462
252790
  if (standalonePath !== void 0) {
252463
252791
  registerCliPayload(fileSystem, configHome, standalonePath, writeOutput);
252464
252792
  }
252465
- if (readAcquisitionChannelStatus(configHome).type === "missing") {
252793
+ if (readAcquisitionChannelStatus(configHome).type !== "valid") {
252466
252794
  writeAcquisitionChannel(fileSystem, configHome, {
252467
252795
  channel: acquisitionChannelFromEnvironment(process.env)
252468
252796
  });
@@ -252474,10 +252802,22 @@ async function installCommand(deps = {}) {
252474
252802
  flag: telemetryConsentFlag
252475
252803
  });
252476
252804
  const telemetry = deps.telemetry ?? new DaemonTelemetryService({ configDir: configHome });
252477
- const nodePath = deps.nodePath ?? await new NodeRuntimeProvisioner({ sqlPreviewHome: configHome, telemetry }).provision();
252478
252805
  const captureLifecycle = (properties) => {
252479
252806
  telemetry.capture("service_lifecycle", properties);
252480
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
+ });
252481
252821
  const launcher = platformLauncherPath(platform2, configHome);
252482
252822
  const unit = unitFor(platform2, launcher, configHome, nodePath);
252483
252823
  const unitPath = path21.join(homeDirectory, unit.destination);
@@ -252577,7 +252917,7 @@ Check the supervisor logs at ${path21.join(configHome, "grain-daemon.out.log")}
252577
252917
  }
252578
252918
 
252579
252919
  // src/server/install/uninstallCommand.ts
252580
- var fs18 = __toESM(require("fs"));
252920
+ var fs19 = __toESM(require("fs"));
252581
252921
  var os5 = __toESM(require("os"));
252582
252922
  var path22 = __toESM(require("path"));
252583
252923
  init_grainHome();
@@ -252612,7 +252952,7 @@ async function uninstallCommand(deps = {}) {
252612
252952
  const homeDirectory = deps.homeDirectory ?? os5.homedir();
252613
252953
  const uid = deps.uid ?? process.getuid?.() ?? 0;
252614
252954
  const nodePath = deps.nodePath ?? "";
252615
- const fileSystem = deps.fileSystem ?? fs18;
252955
+ const fileSystem = deps.fileSystem ?? fs19;
252616
252956
  const runner = deps.commandRunner ?? createCommandRunner();
252617
252957
  const adapter2 = deps.adapter ?? createSupervisorAdapter(platform2, runner, uid);
252618
252958
  const writeOutput = deps.writeOutput ?? ((message) => console.log(message));
@@ -253036,12 +253376,17 @@ Options:
253036
253376
  init_AppError();
253037
253377
 
253038
253378
  // src/server/bridge/notSetUpNotice.ts
253039
- 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";
253040
- function resolveNotSetUpMessage(hasConnectionsEnv) {
253041
- 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);
253042
253385
  }
253043
253386
 
253044
253387
  // src/server/standalone.ts
253388
+ init_daemonRecordInstance();
253389
+ init_supervisorAdapter();
253045
253390
  var SERVICE_START_FLUSH_BUDGET_MS = 2e3;
253046
253391
  async function flushWithinBudget(telemetry, budgetMs) {
253047
253392
  let timer;
@@ -253109,42 +253454,124 @@ async function handleLaunchFailureMarker(configDir, telemetry) {
253109
253454
  return;
253110
253455
  }
253111
253456
  }
253112
- 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 = {}) {
253113
253558
  await dispatchSubcommand(process.argv.slice(2));
253114
253559
  const args = parseArgs();
253115
253560
  const isStdio = args["stdio"] === "true";
253116
253561
  const isEmbedded = args["embedded"] === "true" || process.env["GRAIN_EMBEDDED"] === "1";
253117
253562
  let notSetUpMessage;
253118
253563
  if (isStdio && !isEmbedded) {
253119
- const configDir = defaultDaemonConfigDir();
253120
- const { address, source, record: record2 } = resolveDaemonAddress({ args, env: process.env, configDir });
253121
- if (address) {
253122
- const accessToken = readDaemonAuthToken(configDir);
253123
- const expected = record2 ? { pid: record2.pid, startedAt: record2.startedAt, token: accessToken } : accessToken ? { token: accessToken } : void 0;
253124
- const probed = await probeSharedDaemon(address.port, 500, expected);
253125
- const agentToken = readAgentToken(configDir);
253126
- const foreignReason = !probed.identity ? void 0 : !agentToken ? "no-agent-token" : await isTokenAccepted(address.port, agentToken, 500) ? void 0 : "agent-token-rejected";
253127
- const probe = foreignReason ? { attempts: probed.attempts, failureReason: foreignReason } : probed;
253128
- if (probe.identity) {
253129
- console.error(
253130
- `[grain] bridging stdio to shared daemon v${probe.identity.version ?? "?"} on ${address.host}:${address.port} (via ${source}, RFC-082) after ${probe.attempts} attempt(s)`
253131
- );
253132
- await handleLaunchFailureMarker(configDir);
253133
- await runStdioBridge(address.port);
253134
- return;
253135
- }
253136
- const reasonStr = probe.failureReason === "stale-record" ? `stale-record pid ${expected?.pid}` : probe.failureReason;
253137
- 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;
253138
- console.error(
253139
- (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`
253140
- );
253141
- notSetUpMessage = resolveNotSetUpMessage(Boolean(process.env["GRAIN_CONNECTIONS"]));
253142
- } else {
253143
- console.error(
253144
- `[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`
253145
- );
253146
- 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;
253147
253573
  }
253574
+ notSetUpMessage = result.notSetUpMessage;
253148
253575
  }
253149
253576
  if (!isStdio) {
253150
253577
  console.log("[INFO] Grain daemon process starting...");
@@ -253248,6 +253675,7 @@ if (require.main === module) {
253248
253675
  // Annotate the CommonJS export names for ESM import in node:
253249
253676
  0 && (module.exports = {
253250
253677
  SERVICE_START_FLUSH_BUDGET_MS,
253678
+ connectStdioToSharedDaemon,
253251
253679
  main
253252
253680
  });
253253
253681
  /*! Bundled license information: