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