@spencer-kit/coder-studio 0.4.6 → 0.4.8
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/CHANGELOG.md +16 -0
- package/dist/esm/bin.mjs +2647 -875
- package/dist/esm/bin.mjs.map +4 -4
- package/dist/esm/server-runner.mjs +2619 -847
- package/dist/esm/server-runner.mjs.map +4 -4
- package/dist/web/assets/components-D5qT9_xF.css +1 -0
- package/dist/web/assets/components-DmD8Ga_M.js +109 -0
- package/dist/web/assets/components-DmD8Ga_M.js.map +1 -0
- package/dist/web/assets/{main-DZPwC4NB.js → main-C9Cqb7HD.js} +2 -2
- package/dist/web/assets/{main-DZPwC4NB.js.map → main-C9Cqb7HD.js.map} +1 -1
- package/dist/web/assets/{ui-preview-BzE9924q.js → ui-preview-DOaeyhSh.js} +2 -2
- package/dist/web/assets/{ui-preview-BzE9924q.js.map → ui-preview-DOaeyhSh.js.map} +1 -1
- package/dist/web/index.html +3 -3
- package/dist/web/ui-preview.html +3 -3
- package/package.json +3 -3
- package/src/update-worker.test.ts +25 -12
- package/dist/web/assets/components-BGEBLvHB.css +0 -1
- package/dist/web/assets/components-BuRmXlh8.js +0 -109
- package/dist/web/assets/components-BuRmXlh8.js.map +0 -1
|
@@ -625,7 +625,15 @@ var init_definition = __esm({
|
|
|
625
625
|
id: "claude",
|
|
626
626
|
displayName: "Claude Code",
|
|
627
627
|
badge: "Claude",
|
|
628
|
+
kind: "built_in",
|
|
628
629
|
capability: "full",
|
|
630
|
+
capabilities: [
|
|
631
|
+
{ key: "interactive_session", supported: true, label: "Interactive session" },
|
|
632
|
+
{ key: "supervisor_eval", supported: true, label: "Supervisor evaluation" },
|
|
633
|
+
{ key: "idle_detection", supported: true, label: "Idle detection" },
|
|
634
|
+
{ key: "context_attach", supported: false, label: "Context attach" },
|
|
635
|
+
{ key: "review", supported: false, label: "Review" }
|
|
636
|
+
],
|
|
629
637
|
install: claudeInstallMetadata,
|
|
630
638
|
// ===== Command construction =====
|
|
631
639
|
buildCommand(config, ctx) {
|
|
@@ -795,7 +803,15 @@ var init_definition2 = __esm({
|
|
|
795
803
|
id: "codex",
|
|
796
804
|
displayName: "Codex",
|
|
797
805
|
badge: "Codex",
|
|
806
|
+
kind: "built_in",
|
|
798
807
|
capability: "full",
|
|
808
|
+
capabilities: [
|
|
809
|
+
{ key: "interactive_session", supported: true, label: "Interactive session" },
|
|
810
|
+
{ key: "supervisor_eval", supported: true, label: "Supervisor evaluation" },
|
|
811
|
+
{ key: "idle_detection", supported: true, label: "Idle detection" },
|
|
812
|
+
{ key: "context_attach", supported: false, label: "Context attach" },
|
|
813
|
+
{ key: "review", supported: false, label: "Review" }
|
|
814
|
+
],
|
|
799
815
|
install: codexInstallMetadata,
|
|
800
816
|
// ===== Command construction =====
|
|
801
817
|
buildCommand(config, ctx) {
|
|
@@ -828,7 +844,78 @@ var init_definition2 = __esm({
|
|
|
828
844
|
}
|
|
829
845
|
});
|
|
830
846
|
|
|
847
|
+
// packages/providers/src/presets.ts
|
|
848
|
+
function cloneCapabilities(capabilities) {
|
|
849
|
+
return capabilities.map((capability) => ({ ...capability }));
|
|
850
|
+
}
|
|
851
|
+
var defaultCapabilities, providerPresets;
|
|
852
|
+
var init_presets = __esm({
|
|
853
|
+
"packages/providers/src/presets.ts"() {
|
|
854
|
+
"use strict";
|
|
855
|
+
defaultCapabilities = [
|
|
856
|
+
{ key: "interactive_session", supported: true, label: "Interactive session" },
|
|
857
|
+
{ key: "context_attach", supported: true, label: "Context attach" },
|
|
858
|
+
{ key: "review", supported: true, label: "Review" }
|
|
859
|
+
];
|
|
860
|
+
providerPresets = [
|
|
861
|
+
{
|
|
862
|
+
id: "gemini-cli",
|
|
863
|
+
displayName: "Gemini CLI",
|
|
864
|
+
kind: "preset",
|
|
865
|
+
description: "Preset metadata for launching Google's Gemini CLI through the custom provider flow.",
|
|
866
|
+
command: "gemini",
|
|
867
|
+
args: [],
|
|
868
|
+
env: {},
|
|
869
|
+
cwdMode: "workspace_root",
|
|
870
|
+
sessionMode: "interactive",
|
|
871
|
+
startupPrompt: "Follow the workspace instructions and explain important tradeoffs.",
|
|
872
|
+
capabilities: cloneCapabilities(defaultCapabilities),
|
|
873
|
+
requiredCommands: ["gemini"]
|
|
874
|
+
},
|
|
875
|
+
{
|
|
876
|
+
id: "aider",
|
|
877
|
+
displayName: "Aider",
|
|
878
|
+
kind: "preset",
|
|
879
|
+
description: "Preset metadata for launching Aider as a workspace-root interactive coding agent.",
|
|
880
|
+
command: "aider",
|
|
881
|
+
args: [],
|
|
882
|
+
env: {},
|
|
883
|
+
cwdMode: "workspace_root",
|
|
884
|
+
sessionMode: "interactive",
|
|
885
|
+
startupPrompt: "Review the current workspace state before making edits.",
|
|
886
|
+
capabilities: cloneCapabilities(defaultCapabilities),
|
|
887
|
+
requiredCommands: ["aider"]
|
|
888
|
+
},
|
|
889
|
+
{
|
|
890
|
+
id: "opencode",
|
|
891
|
+
displayName: "OpenCode",
|
|
892
|
+
kind: "preset",
|
|
893
|
+
description: "Preset metadata for launching OpenCode from the workspace root.",
|
|
894
|
+
command: "opencode",
|
|
895
|
+
args: [],
|
|
896
|
+
env: {},
|
|
897
|
+
cwdMode: "workspace_root",
|
|
898
|
+
sessionMode: "interactive",
|
|
899
|
+
startupPrompt: "Use the repository instructions and verify changes before finishing.",
|
|
900
|
+
capabilities: cloneCapabilities(defaultCapabilities),
|
|
901
|
+
requiredCommands: ["opencode"]
|
|
902
|
+
}
|
|
903
|
+
];
|
|
904
|
+
}
|
|
905
|
+
});
|
|
906
|
+
|
|
831
907
|
// packages/providers/src/registry.ts
|
|
908
|
+
function toProviderListItem(provider) {
|
|
909
|
+
return {
|
|
910
|
+
id: provider.id,
|
|
911
|
+
displayName: provider.displayName,
|
|
912
|
+
badge: provider.badge,
|
|
913
|
+
kind: provider.kind,
|
|
914
|
+
capability: provider.capability,
|
|
915
|
+
capabilities: provider.capabilities.map((capability) => ({ ...capability })),
|
|
916
|
+
requiredCommands: [...provider.requiredCommands]
|
|
917
|
+
};
|
|
918
|
+
}
|
|
832
919
|
var providerRegistry;
|
|
833
920
|
var init_registry = __esm({
|
|
834
921
|
"packages/providers/src/registry.ts"() {
|
|
@@ -848,6 +935,7 @@ var init_src = __esm({
|
|
|
848
935
|
init_config_schema2();
|
|
849
936
|
init_definition2();
|
|
850
937
|
init_stdout_heuristics();
|
|
938
|
+
init_presets();
|
|
851
939
|
init_registry();
|
|
852
940
|
}
|
|
853
941
|
});
|
|
@@ -1690,7 +1778,7 @@ import { mkdir as mkdir3, mkdtemp, rm as rm3, writeFile as writeFile2 } from "fs
|
|
|
1690
1778
|
import os2 from "os";
|
|
1691
1779
|
import path7 from "path";
|
|
1692
1780
|
async function runGit(cwd, args, options = {}) {
|
|
1693
|
-
return new Promise((
|
|
1781
|
+
return new Promise((resolve8, reject) => {
|
|
1694
1782
|
const gitArgs = [
|
|
1695
1783
|
...options.config?.flatMap(([key, value]) => ["-c", `${key}=${value}`]) ?? [],
|
|
1696
1784
|
...args
|
|
@@ -1717,7 +1805,7 @@ async function runGit(cwd, args, options = {}) {
|
|
|
1717
1805
|
if (err) {
|
|
1718
1806
|
reject(new GitError(err.message, stderr));
|
|
1719
1807
|
} else {
|
|
1720
|
-
|
|
1808
|
+
resolve8({ stdout, stderr });
|
|
1721
1809
|
}
|
|
1722
1810
|
}
|
|
1723
1811
|
);
|
|
@@ -3598,12 +3686,12 @@ var init_auto_fetch = __esm({
|
|
|
3598
3686
|
}
|
|
3599
3687
|
acquireWorkspaceOperation(workspaceId) {
|
|
3600
3688
|
const state = this.getOrCreateState(workspaceId);
|
|
3601
|
-
return new Promise((
|
|
3689
|
+
return new Promise((resolve8) => {
|
|
3602
3690
|
const grant = () => {
|
|
3603
3691
|
state.inFlight = true;
|
|
3604
3692
|
state.nextFetchAt = void 0;
|
|
3605
3693
|
let released = false;
|
|
3606
|
-
|
|
3694
|
+
resolve8(() => {
|
|
3607
3695
|
if (released) {
|
|
3608
3696
|
return;
|
|
3609
3697
|
}
|
|
@@ -4606,7 +4694,7 @@ var init_manager = __esm({
|
|
|
4606
4694
|
// packages/server/src/provider-runtime/command-runner.ts
|
|
4607
4695
|
import { spawn as spawn2 } from "node:child_process";
|
|
4608
4696
|
async function runCommandAsString(file, args, options) {
|
|
4609
|
-
return new Promise((
|
|
4697
|
+
return new Promise((resolve8, reject) => {
|
|
4610
4698
|
const child = spawn2(file, args, {
|
|
4611
4699
|
cwd: options?.cwd,
|
|
4612
4700
|
env: options?.env,
|
|
@@ -4633,7 +4721,7 @@ async function runCommandAsString(file, args, options) {
|
|
|
4633
4721
|
const stdout = Buffer.concat(stdoutChunks).toString("utf8");
|
|
4634
4722
|
const stderr = Buffer.concat(stderrChunks).toString("utf8");
|
|
4635
4723
|
if (code === 0) {
|
|
4636
|
-
|
|
4724
|
+
resolve8({ stdout, stderr });
|
|
4637
4725
|
return;
|
|
4638
4726
|
}
|
|
4639
4727
|
reject(
|
|
@@ -5433,6 +5521,66 @@ var init_tool_root = __esm({
|
|
|
5433
5521
|
}
|
|
5434
5522
|
});
|
|
5435
5523
|
|
|
5524
|
+
// packages/server/src/provider-runtime/custom-provider.ts
|
|
5525
|
+
import { z as z4 } from "zod";
|
|
5526
|
+
function deriveProviderCapability(capabilities) {
|
|
5527
|
+
const interactive = capabilities.find((capability) => capability.key === "interactive_session");
|
|
5528
|
+
if (!interactive?.supported) {
|
|
5529
|
+
return "unsupported";
|
|
5530
|
+
}
|
|
5531
|
+
const allSupported = capabilities.length > 0 && capabilities.every((capability) => capability.supported);
|
|
5532
|
+
return allSupported ? "full" : "limited";
|
|
5533
|
+
}
|
|
5534
|
+
function buildCustomProviderDefinition(config) {
|
|
5535
|
+
const command = config.command.trim();
|
|
5536
|
+
const requiredCommand = command.split(/\s+/)[0] ?? command;
|
|
5537
|
+
return {
|
|
5538
|
+
id: config.id,
|
|
5539
|
+
displayName: config.displayName,
|
|
5540
|
+
badge: "Custom",
|
|
5541
|
+
kind: "custom",
|
|
5542
|
+
capability: deriveProviderCapability(config.capabilities),
|
|
5543
|
+
capabilities: config.capabilities.map((capability) => ({ ...capability })),
|
|
5544
|
+
install: {
|
|
5545
|
+
prerequisites: [],
|
|
5546
|
+
manualGuideKeys: [],
|
|
5547
|
+
docUrls: {
|
|
5548
|
+
provider: "",
|
|
5549
|
+
prerequisites: {}
|
|
5550
|
+
},
|
|
5551
|
+
strategies: {}
|
|
5552
|
+
},
|
|
5553
|
+
buildCommand(_providerConfig, ctx) {
|
|
5554
|
+
return {
|
|
5555
|
+
argv: [command, ...config.args],
|
|
5556
|
+
env: {
|
|
5557
|
+
...config.env,
|
|
5558
|
+
CODER_STUDIO_SESSION_ID: ctx.sessionId
|
|
5559
|
+
},
|
|
5560
|
+
cwd: ctx.workspacePath
|
|
5561
|
+
};
|
|
5562
|
+
},
|
|
5563
|
+
configSchema: CUSTOM_PROVIDER_CONFIG_SCHEMA,
|
|
5564
|
+
defaultConfig: {},
|
|
5565
|
+
requiredCommands: requiredCommand ? [requiredCommand] : []
|
|
5566
|
+
};
|
|
5567
|
+
}
|
|
5568
|
+
function upsertProviderDefinition(registry, provider) {
|
|
5569
|
+
const next = registry.filter((item) => item.id !== provider.id);
|
|
5570
|
+
next.push(provider);
|
|
5571
|
+
return next;
|
|
5572
|
+
}
|
|
5573
|
+
function removeProviderDefinition(registry, providerId) {
|
|
5574
|
+
return registry.filter((item) => item.id !== providerId);
|
|
5575
|
+
}
|
|
5576
|
+
var CUSTOM_PROVIDER_CONFIG_SCHEMA;
|
|
5577
|
+
var init_custom_provider = __esm({
|
|
5578
|
+
"packages/server/src/provider-runtime/custom-provider.ts"() {
|
|
5579
|
+
"use strict";
|
|
5580
|
+
CUSTOM_PROVIDER_CONFIG_SCHEMA = z4.object({}).passthrough();
|
|
5581
|
+
}
|
|
5582
|
+
});
|
|
5583
|
+
|
|
5436
5584
|
// packages/server/src/provider-runtime/e2e-provider-mock.ts
|
|
5437
5585
|
import { chmodSync, existsSync as existsSync5, mkdirSync as mkdirSync6, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "node:fs";
|
|
5438
5586
|
import { dirname as dirname5, join as join8 } from "node:path";
|
|
@@ -5675,9 +5823,24 @@ var init_install_manager2 = __esm({
|
|
|
5675
5823
|
deps;
|
|
5676
5824
|
constructor(providers, deps = {}) {
|
|
5677
5825
|
this.deps = deps;
|
|
5826
|
+
this.setProviders(providers);
|
|
5827
|
+
}
|
|
5828
|
+
setProviders(providers) {
|
|
5829
|
+
const nextIds = new Set(providers.map((provider) => provider.id));
|
|
5830
|
+
this.providers.clear();
|
|
5678
5831
|
for (const provider of providers) {
|
|
5679
5832
|
this.providers.set(provider.id, provider);
|
|
5680
5833
|
}
|
|
5834
|
+
for (const providerId of this.activeJobIdsByProviderId.keys()) {
|
|
5835
|
+
if (!nextIds.has(providerId)) {
|
|
5836
|
+
this.activeJobIdsByProviderId.delete(providerId);
|
|
5837
|
+
}
|
|
5838
|
+
}
|
|
5839
|
+
for (const providerId of this.inFlightStartsByProviderId.keys()) {
|
|
5840
|
+
if (!nextIds.has(providerId)) {
|
|
5841
|
+
this.inFlightStartsByProviderId.delete(providerId);
|
|
5842
|
+
}
|
|
5843
|
+
}
|
|
5681
5844
|
}
|
|
5682
5845
|
async start(providerId) {
|
|
5683
5846
|
const activeJob = this.getActiveJob(providerId);
|
|
@@ -6147,7 +6310,7 @@ var init_update = __esm({
|
|
|
6147
6310
|
});
|
|
6148
6311
|
|
|
6149
6312
|
// packages/core/src/protocol/messages.ts
|
|
6150
|
-
import { z as
|
|
6313
|
+
import { z as z5 } from "zod";
|
|
6151
6314
|
var TERMINAL_BINARY_PROTOCOL_VERSION, TERMINAL_BINARY_HEADER_SIZE, TerminalBinaryFrameType, RECOVERY_REASONS, TERMINAL_INPUT_ACTIVITIES, encodeTerminalBinaryFrame, TERMINAL_BINARY_OUTPUT_VERSION, encodeTerminalOutputFrame, CommandMessage, ResultMessage, EventMessage, SubscribeMessage, UnsubscribeMessage, ResyncMessage, ClientMessage, ServerMessage;
|
|
6152
6315
|
var init_messages = __esm({
|
|
6153
6316
|
"packages/core/src/protocol/messages.ts"() {
|
|
@@ -6210,49 +6373,49 @@ var init_messages = __esm({
|
|
|
6210
6373
|
frame.set(payload, TERMINAL_BINARY_HEADER_SIZE + topicBytes.length);
|
|
6211
6374
|
return frame;
|
|
6212
6375
|
};
|
|
6213
|
-
CommandMessage =
|
|
6214
|
-
kind:
|
|
6215
|
-
id:
|
|
6216
|
-
op:
|
|
6217
|
-
args:
|
|
6376
|
+
CommandMessage = z5.object({
|
|
6377
|
+
kind: z5.literal("command"),
|
|
6378
|
+
id: z5.string().uuid(),
|
|
6379
|
+
op: z5.string(),
|
|
6380
|
+
args: z5.unknown()
|
|
6218
6381
|
});
|
|
6219
|
-
ResultMessage =
|
|
6220
|
-
kind:
|
|
6221
|
-
id:
|
|
6222
|
-
ok:
|
|
6223
|
-
data:
|
|
6224
|
-
error:
|
|
6225
|
-
code:
|
|
6226
|
-
message:
|
|
6227
|
-
details:
|
|
6382
|
+
ResultMessage = z5.object({
|
|
6383
|
+
kind: z5.literal("result"),
|
|
6384
|
+
id: z5.string().uuid(),
|
|
6385
|
+
ok: z5.boolean(),
|
|
6386
|
+
data: z5.unknown().optional(),
|
|
6387
|
+
error: z5.object({
|
|
6388
|
+
code: z5.string(),
|
|
6389
|
+
message: z5.string(),
|
|
6390
|
+
details: z5.unknown().optional()
|
|
6228
6391
|
}).optional()
|
|
6229
6392
|
});
|
|
6230
|
-
EventMessage =
|
|
6231
|
-
kind:
|
|
6232
|
-
topic:
|
|
6233
|
-
seq:
|
|
6234
|
-
timestamp:
|
|
6235
|
-
data:
|
|
6393
|
+
EventMessage = z5.object({
|
|
6394
|
+
kind: z5.literal("event"),
|
|
6395
|
+
topic: z5.string(),
|
|
6396
|
+
seq: z5.number().int().nonnegative(),
|
|
6397
|
+
timestamp: z5.number().int().positive(),
|
|
6398
|
+
data: z5.unknown()
|
|
6236
6399
|
});
|
|
6237
|
-
SubscribeMessage =
|
|
6238
|
-
kind:
|
|
6239
|
-
topics:
|
|
6400
|
+
SubscribeMessage = z5.object({
|
|
6401
|
+
kind: z5.literal("subscribe"),
|
|
6402
|
+
topics: z5.array(z5.string())
|
|
6240
6403
|
});
|
|
6241
|
-
UnsubscribeMessage =
|
|
6242
|
-
kind:
|
|
6243
|
-
topics:
|
|
6404
|
+
UnsubscribeMessage = z5.object({
|
|
6405
|
+
kind: z5.literal("unsubscribe"),
|
|
6406
|
+
topics: z5.array(z5.string())
|
|
6244
6407
|
});
|
|
6245
|
-
ResyncMessage =
|
|
6246
|
-
kind:
|
|
6247
|
-
lastSeen:
|
|
6408
|
+
ResyncMessage = z5.object({
|
|
6409
|
+
kind: z5.literal("resync"),
|
|
6410
|
+
lastSeen: z5.record(z5.string(), z5.number())
|
|
6248
6411
|
});
|
|
6249
|
-
ClientMessage =
|
|
6412
|
+
ClientMessage = z5.discriminatedUnion("kind", [
|
|
6250
6413
|
CommandMessage,
|
|
6251
6414
|
SubscribeMessage,
|
|
6252
6415
|
UnsubscribeMessage,
|
|
6253
6416
|
ResyncMessage
|
|
6254
6417
|
]);
|
|
6255
|
-
ServerMessage =
|
|
6418
|
+
ServerMessage = z5.discriminatedUnion("kind", [ResultMessage, EventMessage]);
|
|
6256
6419
|
}
|
|
6257
6420
|
});
|
|
6258
6421
|
|
|
@@ -6325,7 +6488,7 @@ var init_src3 = __esm({
|
|
|
6325
6488
|
});
|
|
6326
6489
|
|
|
6327
6490
|
// packages/server/src/provider-config.ts
|
|
6328
|
-
import { z as
|
|
6491
|
+
import { z as z6 } from "zod";
|
|
6329
6492
|
function isSupportedProviderId(providerId) {
|
|
6330
6493
|
return supportedProviderIds.has(providerId);
|
|
6331
6494
|
}
|
|
@@ -6345,17 +6508,17 @@ var init_provider_config = __esm({
|
|
|
6345
6508
|
"use strict";
|
|
6346
6509
|
SUPPORTED_PROVIDER_IDS = ["claude", "codex"];
|
|
6347
6510
|
supportedProviderIds = new Set(SUPPORTED_PROVIDER_IDS);
|
|
6348
|
-
ProviderLaunchConfigInputSchema =
|
|
6349
|
-
additionalArgs:
|
|
6350
|
-
envVars:
|
|
6511
|
+
ProviderLaunchConfigInputSchema = z6.object({
|
|
6512
|
+
additionalArgs: z6.array(z6.string()).optional(),
|
|
6513
|
+
envVars: z6.record(z6.string(), z6.string()).optional()
|
|
6351
6514
|
}).strict();
|
|
6352
|
-
ProviderSettingsSchema =
|
|
6515
|
+
ProviderSettingsSchema = z6.object({
|
|
6353
6516
|
claude: ProviderLaunchConfigInputSchema.optional(),
|
|
6354
6517
|
codex: ProviderLaunchConfigInputSchema.optional()
|
|
6355
6518
|
}).strict();
|
|
6356
|
-
ProviderLaunchConfigSchema =
|
|
6357
|
-
additionalArgs:
|
|
6358
|
-
envVars:
|
|
6519
|
+
ProviderLaunchConfigSchema = z6.object({
|
|
6520
|
+
additionalArgs: z6.array(z6.string()).default([]),
|
|
6521
|
+
envVars: z6.record(z6.string(), z6.string()).optional()
|
|
6359
6522
|
});
|
|
6360
6523
|
}
|
|
6361
6524
|
});
|
|
@@ -6851,6 +7014,9 @@ var init_manager3 = __esm({
|
|
|
6851
7014
|
comparators = /* @__PURE__ */ new Map();
|
|
6852
7015
|
detectorUnsubscribes = /* @__PURE__ */ new Map();
|
|
6853
7016
|
logger;
|
|
7017
|
+
setProviderRegistry(providerRegistry2) {
|
|
7018
|
+
this.deps.providerRegistry = providerRegistry2;
|
|
7019
|
+
}
|
|
6854
7020
|
/**
|
|
6855
7021
|
* Create a new session with provider
|
|
6856
7022
|
*/
|
|
@@ -7815,15 +7981,104 @@ var init_auth_session_repo = __esm({
|
|
|
7815
7981
|
}
|
|
7816
7982
|
});
|
|
7817
7983
|
|
|
7818
|
-
// packages/server/src/storage/repositories/provider-
|
|
7984
|
+
// packages/server/src/storage/repositories/custom-provider-repo.ts
|
|
7819
7985
|
function isRecord5(value) {
|
|
7820
7986
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
7821
7987
|
}
|
|
7822
|
-
function
|
|
7988
|
+
function normalizeConfig(config) {
|
|
7989
|
+
return {
|
|
7990
|
+
...config,
|
|
7991
|
+
args: [...config.args],
|
|
7992
|
+
env: { ...config.env },
|
|
7993
|
+
capabilities: config.capabilities.map((capability) => ({ ...capability }))
|
|
7994
|
+
};
|
|
7995
|
+
}
|
|
7996
|
+
function normalizeFileConfigs(value) {
|
|
7823
7997
|
if (isRecord5(value) && value.version === 1 && isRecord5(value.providers)) {
|
|
7824
|
-
return
|
|
7998
|
+
return Object.fromEntries(
|
|
7999
|
+
Object.entries(value.providers).map(([id, config]) => [
|
|
8000
|
+
id,
|
|
8001
|
+
normalizeConfig(config)
|
|
8002
|
+
])
|
|
8003
|
+
);
|
|
7825
8004
|
}
|
|
7826
8005
|
if (isRecord5(value)) {
|
|
8006
|
+
return Object.fromEntries(
|
|
8007
|
+
Object.entries(value).map(([id, config]) => [
|
|
8008
|
+
id,
|
|
8009
|
+
normalizeConfig(config)
|
|
8010
|
+
])
|
|
8011
|
+
);
|
|
8012
|
+
}
|
|
8013
|
+
return {};
|
|
8014
|
+
}
|
|
8015
|
+
var CustomProviderRepo;
|
|
8016
|
+
var init_custom_provider_repo = __esm({
|
|
8017
|
+
"packages/server/src/storage/repositories/custom-provider-repo.ts"() {
|
|
8018
|
+
"use strict";
|
|
8019
|
+
init_json_file_store();
|
|
8020
|
+
CustomProviderRepo = class {
|
|
8021
|
+
filePath;
|
|
8022
|
+
constructor(input) {
|
|
8023
|
+
this.filePath = input.filePath;
|
|
8024
|
+
}
|
|
8025
|
+
list() {
|
|
8026
|
+
return Object.values(this.loadFileConfigs()).sort(
|
|
8027
|
+
(left, right) => right.updatedAt - left.updatedAt || left.id.localeCompare(right.id)
|
|
8028
|
+
);
|
|
8029
|
+
}
|
|
8030
|
+
get(id) {
|
|
8031
|
+
return this.loadFileConfigs()[id];
|
|
8032
|
+
}
|
|
8033
|
+
set(config) {
|
|
8034
|
+
const existing = this.get(config.id);
|
|
8035
|
+
const createdAt = existing?.createdAt ?? config.createdAt;
|
|
8036
|
+
const normalized = normalizeConfig({
|
|
8037
|
+
...config,
|
|
8038
|
+
createdAt
|
|
8039
|
+
});
|
|
8040
|
+
const next = this.loadFileConfigs();
|
|
8041
|
+
next[normalized.id] = normalized;
|
|
8042
|
+
this.saveFileConfigs(next);
|
|
8043
|
+
return next[normalized.id];
|
|
8044
|
+
}
|
|
8045
|
+
delete(id) {
|
|
8046
|
+
const next = this.loadFileConfigs();
|
|
8047
|
+
if (!Object.prototype.hasOwnProperty.call(next, id)) {
|
|
8048
|
+
return;
|
|
8049
|
+
}
|
|
8050
|
+
delete next[id];
|
|
8051
|
+
this.saveFileConfigs(next);
|
|
8052
|
+
}
|
|
8053
|
+
loadFileConfigs() {
|
|
8054
|
+
const parsed = readJsonFile(
|
|
8055
|
+
this.filePath
|
|
8056
|
+
);
|
|
8057
|
+
if (parsed !== void 0) {
|
|
8058
|
+
return normalizeFileConfigs(parsed);
|
|
8059
|
+
}
|
|
8060
|
+
return {};
|
|
8061
|
+
}
|
|
8062
|
+
saveFileConfigs(configs) {
|
|
8063
|
+
const payload = {
|
|
8064
|
+
version: 1,
|
|
8065
|
+
providers: configs
|
|
8066
|
+
};
|
|
8067
|
+
writeJsonFileAtomic(this.filePath, payload);
|
|
8068
|
+
}
|
|
8069
|
+
};
|
|
8070
|
+
}
|
|
8071
|
+
});
|
|
8072
|
+
|
|
8073
|
+
// packages/server/src/storage/repositories/provider-config-repo.ts
|
|
8074
|
+
function isRecord6(value) {
|
|
8075
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
8076
|
+
}
|
|
8077
|
+
function normalizeProviderConfigFile(value) {
|
|
8078
|
+
if (isRecord6(value) && value.version === 1 && isRecord6(value.providers)) {
|
|
8079
|
+
return value.providers;
|
|
8080
|
+
}
|
|
8081
|
+
if (isRecord6(value)) {
|
|
7827
8082
|
return value;
|
|
7828
8083
|
}
|
|
7829
8084
|
return {};
|
|
@@ -7896,15 +8151,159 @@ var init_provider_config_repo = __esm({
|
|
|
7896
8151
|
}
|
|
7897
8152
|
});
|
|
7898
8153
|
|
|
8154
|
+
// packages/server/src/workspace/workspace-state.ts
|
|
8155
|
+
import { join as join9 } from "node:path";
|
|
8156
|
+
function resolveWorkspaceStateFilePath(workspacePath, fileName) {
|
|
8157
|
+
return join9(workspacePath, WORKSPACE_STATE_DIR, fileName);
|
|
8158
|
+
}
|
|
8159
|
+
var WORKSPACE_STATE_DIR, AGENT_INSTRUCTIONS_RELATIVE_PATH, SESSION_METADATA_FILE_NAME, SESSION_METADATA_RELATIVE_PATH;
|
|
8160
|
+
var init_workspace_state = __esm({
|
|
8161
|
+
"packages/server/src/workspace/workspace-state.ts"() {
|
|
8162
|
+
"use strict";
|
|
8163
|
+
WORKSPACE_STATE_DIR = ".coder-studio";
|
|
8164
|
+
AGENT_INSTRUCTIONS_RELATIVE_PATH = `${WORKSPACE_STATE_DIR}/AGENTS.md`;
|
|
8165
|
+
SESSION_METADATA_FILE_NAME = "session-metadata.json";
|
|
8166
|
+
SESSION_METADATA_RELATIVE_PATH = `${WORKSPACE_STATE_DIR}/${SESSION_METADATA_FILE_NAME}`;
|
|
8167
|
+
}
|
|
8168
|
+
});
|
|
8169
|
+
|
|
8170
|
+
// packages/server/src/storage/repositories/session-metadata-repo.ts
|
|
8171
|
+
function isRecord7(value) {
|
|
8172
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
8173
|
+
}
|
|
8174
|
+
function normalizeRun(run) {
|
|
8175
|
+
return {
|
|
8176
|
+
...run
|
|
8177
|
+
};
|
|
8178
|
+
}
|
|
8179
|
+
function normalizeMetadata(metadata) {
|
|
8180
|
+
return {
|
|
8181
|
+
sessionId: metadata.sessionId,
|
|
8182
|
+
workspaceId: metadata.workspaceId,
|
|
8183
|
+
providerId: metadata.providerId,
|
|
8184
|
+
objective: metadata.objective ?? void 0,
|
|
8185
|
+
baselineGitHead: metadata.baselineGitHead ?? void 0,
|
|
8186
|
+
baselineCapturedAt: metadata.baselineCapturedAt ?? void 0,
|
|
8187
|
+
verificationRuns: metadata.verificationRuns.map(normalizeRun)
|
|
8188
|
+
};
|
|
8189
|
+
}
|
|
8190
|
+
function normalizeFileMetadata(value) {
|
|
8191
|
+
if (isRecord7(value) && value.version === 1 && isRecord7(value.metadata)) {
|
|
8192
|
+
return Object.fromEntries(
|
|
8193
|
+
Object.entries(value.metadata).map(([sessionId, metadata]) => [
|
|
8194
|
+
sessionId,
|
|
8195
|
+
normalizeMetadata(metadata)
|
|
8196
|
+
])
|
|
8197
|
+
);
|
|
8198
|
+
}
|
|
8199
|
+
if (isRecord7(value)) {
|
|
8200
|
+
return Object.fromEntries(
|
|
8201
|
+
Object.entries(value).map(([sessionId, metadata]) => [
|
|
8202
|
+
sessionId,
|
|
8203
|
+
normalizeMetadata(metadata)
|
|
8204
|
+
])
|
|
8205
|
+
);
|
|
8206
|
+
}
|
|
8207
|
+
return {};
|
|
8208
|
+
}
|
|
8209
|
+
var SessionMetadataRepo;
|
|
8210
|
+
var init_session_metadata_repo = __esm({
|
|
8211
|
+
"packages/server/src/storage/repositories/session-metadata-repo.ts"() {
|
|
8212
|
+
"use strict";
|
|
8213
|
+
init_workspace_state();
|
|
8214
|
+
init_json_file_store();
|
|
8215
|
+
SessionMetadataRepo = class {
|
|
8216
|
+
workspaceRepo;
|
|
8217
|
+
constructor(input) {
|
|
8218
|
+
this.workspaceRepo = input.workspaceRepo;
|
|
8219
|
+
}
|
|
8220
|
+
upsert(metadata) {
|
|
8221
|
+
const normalized = normalizeMetadata(metadata);
|
|
8222
|
+
const workspace = this.workspaceRepo.findById(normalized.workspaceId);
|
|
8223
|
+
if (!workspace) {
|
|
8224
|
+
throw new Error(`Workspace not found for session metadata: ${normalized.workspaceId}`);
|
|
8225
|
+
}
|
|
8226
|
+
const existing = this.findSessionLocation(normalized.sessionId);
|
|
8227
|
+
if (existing && existing.workspace.id !== workspace.id) {
|
|
8228
|
+
delete existing.fileMetadata[normalized.sessionId];
|
|
8229
|
+
this.saveWorkspaceFileMetadata(existing.workspace.path, existing.fileMetadata);
|
|
8230
|
+
}
|
|
8231
|
+
const next = existing && existing.workspace.id === workspace.id ? existing.fileMetadata : this.loadWorkspaceFileMetadata(workspace.path);
|
|
8232
|
+
next[normalized.sessionId] = normalized;
|
|
8233
|
+
this.saveWorkspaceFileMetadata(workspace.path, next);
|
|
8234
|
+
return next[normalized.sessionId];
|
|
8235
|
+
}
|
|
8236
|
+
get(sessionId) {
|
|
8237
|
+
return this.findSessionLocation(sessionId)?.fileMetadata[sessionId];
|
|
8238
|
+
}
|
|
8239
|
+
addVerificationRun(sessionId, run) {
|
|
8240
|
+
const existing = this.findSessionLocation(sessionId);
|
|
8241
|
+
if (!existing) {
|
|
8242
|
+
throw new Error(`Session metadata not found: ${sessionId}`);
|
|
8243
|
+
}
|
|
8244
|
+
existing.fileMetadata[sessionId] = normalizeMetadata({
|
|
8245
|
+
...existing.fileMetadata[sessionId],
|
|
8246
|
+
verificationRuns: [...existing.fileMetadata[sessionId].verificationRuns, normalizeRun(run)]
|
|
8247
|
+
});
|
|
8248
|
+
this.saveWorkspaceFileMetadata(existing.workspace.path, existing.fileMetadata);
|
|
8249
|
+
return existing.fileMetadata[sessionId];
|
|
8250
|
+
}
|
|
8251
|
+
delete(sessionId) {
|
|
8252
|
+
this.deleteFromAnyWorkspace(sessionId);
|
|
8253
|
+
}
|
|
8254
|
+
findSessionLocation(sessionId) {
|
|
8255
|
+
for (const workspace of this.workspaceRepo.list()) {
|
|
8256
|
+
const fileMetadata = this.loadWorkspaceFileMetadata(workspace.path);
|
|
8257
|
+
if (Object.prototype.hasOwnProperty.call(fileMetadata, sessionId)) {
|
|
8258
|
+
return {
|
|
8259
|
+
workspace,
|
|
8260
|
+
fileMetadata
|
|
8261
|
+
};
|
|
8262
|
+
}
|
|
8263
|
+
}
|
|
8264
|
+
return void 0;
|
|
8265
|
+
}
|
|
8266
|
+
deleteFromAnyWorkspace(sessionId) {
|
|
8267
|
+
const existing = this.findSessionLocation(sessionId);
|
|
8268
|
+
if (!existing) {
|
|
8269
|
+
return false;
|
|
8270
|
+
}
|
|
8271
|
+
delete existing.fileMetadata[sessionId];
|
|
8272
|
+
this.saveWorkspaceFileMetadata(existing.workspace.path, existing.fileMetadata);
|
|
8273
|
+
return true;
|
|
8274
|
+
}
|
|
8275
|
+
loadWorkspaceFileMetadata(workspacePath) {
|
|
8276
|
+
const parsed = readJsonFile(
|
|
8277
|
+
resolveWorkspaceStateFilePath(workspacePath, SESSION_METADATA_FILE_NAME)
|
|
8278
|
+
);
|
|
8279
|
+
if (parsed !== void 0) {
|
|
8280
|
+
return normalizeFileMetadata(parsed);
|
|
8281
|
+
}
|
|
8282
|
+
return {};
|
|
8283
|
+
}
|
|
8284
|
+
saveWorkspaceFileMetadata(workspacePath, metadata) {
|
|
8285
|
+
const payload = {
|
|
8286
|
+
version: 1,
|
|
8287
|
+
metadata
|
|
8288
|
+
};
|
|
8289
|
+
writeJsonFileAtomic(
|
|
8290
|
+
resolveWorkspaceStateFilePath(workspacePath, SESSION_METADATA_FILE_NAME),
|
|
8291
|
+
payload
|
|
8292
|
+
);
|
|
8293
|
+
}
|
|
8294
|
+
};
|
|
8295
|
+
}
|
|
8296
|
+
});
|
|
8297
|
+
|
|
7899
8298
|
// packages/server/src/storage/repositories/settings-repo.ts
|
|
7900
|
-
function
|
|
8299
|
+
function isRecord8(value) {
|
|
7901
8300
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
7902
8301
|
}
|
|
7903
8302
|
function normalizeSettingsFile(value) {
|
|
7904
|
-
if (
|
|
8303
|
+
if (isRecord8(value) && value.version === 1 && isRecord8(value.settings)) {
|
|
7905
8304
|
return { ...value.settings };
|
|
7906
8305
|
}
|
|
7907
|
-
if (
|
|
8306
|
+
if (isRecord8(value)) {
|
|
7908
8307
|
return { ...value };
|
|
7909
8308
|
}
|
|
7910
8309
|
return {};
|
|
@@ -8055,11 +8454,11 @@ var init_supervisor_repo = __esm({
|
|
|
8055
8454
|
});
|
|
8056
8455
|
|
|
8057
8456
|
// packages/server/src/storage/repositories/terminal-repo.ts
|
|
8058
|
-
function
|
|
8457
|
+
function isRecord9(value) {
|
|
8059
8458
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
8060
8459
|
}
|
|
8061
8460
|
function isTerminal(value) {
|
|
8062
|
-
if (!
|
|
8461
|
+
if (!isRecord9(value)) {
|
|
8063
8462
|
return false;
|
|
8064
8463
|
}
|
|
8065
8464
|
return typeof value.id === "string" && typeof value.workspaceId === "string" && (value.kind === "agent" || value.kind === "shell") && typeof value.cwd === "string" && Array.isArray(value.argv) && typeof value.cols === "number" && typeof value.rows === "number" && typeof value.alive === "boolean" && typeof value.createdAt === "number";
|
|
@@ -8071,7 +8470,7 @@ function normalizeTerminal(value) {
|
|
|
8071
8470
|
};
|
|
8072
8471
|
}
|
|
8073
8472
|
function normalizeTerminalFile(value) {
|
|
8074
|
-
if (
|
|
8473
|
+
if (isRecord9(value) && value.version === 1 && isRecord9(value.terminals)) {
|
|
8075
8474
|
const normalized = {};
|
|
8076
8475
|
for (const entry of Object.values(value.terminals)) {
|
|
8077
8476
|
if (isTerminal(entry)) {
|
|
@@ -8089,7 +8488,7 @@ function normalizeTerminalFile(value) {
|
|
|
8089
8488
|
}
|
|
8090
8489
|
return normalized;
|
|
8091
8490
|
}
|
|
8092
|
-
if (
|
|
8491
|
+
if (isRecord9(value)) {
|
|
8093
8492
|
const normalized = {};
|
|
8094
8493
|
for (const [terminalId, entry] of Object.entries(value)) {
|
|
8095
8494
|
if (isTerminal(entry)) {
|
|
@@ -8255,12 +8654,12 @@ var init_terminal_repo = __esm({
|
|
|
8255
8654
|
});
|
|
8256
8655
|
|
|
8257
8656
|
// packages/server/src/storage/repositories/update-state-repo.ts
|
|
8258
|
-
function
|
|
8657
|
+
function isRecord10(value) {
|
|
8259
8658
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
8260
8659
|
}
|
|
8261
8660
|
function normalizeUpdateState(value, currentVersion) {
|
|
8262
8661
|
const defaults = createDefaultUpdateState(currentVersion);
|
|
8263
|
-
if (!
|
|
8662
|
+
if (!isRecord10(value)) {
|
|
8264
8663
|
return defaults;
|
|
8265
8664
|
}
|
|
8266
8665
|
return {
|
|
@@ -8323,17 +8722,17 @@ var init_update_state_repo = __esm({
|
|
|
8323
8722
|
});
|
|
8324
8723
|
|
|
8325
8724
|
// packages/server/src/storage/repositories/workspace-repo.ts
|
|
8326
|
-
function
|
|
8725
|
+
function isRecord11(value) {
|
|
8327
8726
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
8328
8727
|
}
|
|
8329
8728
|
function isWorkspace(value) {
|
|
8330
|
-
if (!
|
|
8729
|
+
if (!isRecord11(value)) {
|
|
8331
8730
|
return false;
|
|
8332
8731
|
}
|
|
8333
|
-
return typeof value.id === "string" && typeof value.path === "string" && (value.targetRuntime === "native" || value.targetRuntime === "wsl") && typeof value.openedAt === "number" && typeof value.lastActiveAt === "number" &&
|
|
8732
|
+
return typeof value.id === "string" && typeof value.path === "string" && (value.targetRuntime === "native" || value.targetRuntime === "wsl") && typeof value.openedAt === "number" && typeof value.lastActiveAt === "number" && isRecord11(value.uiState);
|
|
8334
8733
|
}
|
|
8335
8734
|
function normalizeWorkspaceFile(value) {
|
|
8336
|
-
if (
|
|
8735
|
+
if (isRecord11(value) && value.version === 1 && isRecord11(value.workspaces)) {
|
|
8337
8736
|
const normalized = {};
|
|
8338
8737
|
for (const entry of Object.values(value.workspaces)) {
|
|
8339
8738
|
if (isWorkspace(entry)) {
|
|
@@ -8351,7 +8750,7 @@ function normalizeWorkspaceFile(value) {
|
|
|
8351
8750
|
}
|
|
8352
8751
|
return normalized;
|
|
8353
8752
|
}
|
|
8354
|
-
if (
|
|
8753
|
+
if (isRecord11(value)) {
|
|
8355
8754
|
const normalized = {};
|
|
8356
8755
|
for (const [workspaceId, entry] of Object.entries(value)) {
|
|
8357
8756
|
if (isWorkspace(entry)) {
|
|
@@ -8596,13 +8995,13 @@ function ensureNodePtySpawnHelperExecutable(deps = {}) {
|
|
|
8596
8995
|
return;
|
|
8597
8996
|
}
|
|
8598
8997
|
const arch = deps.arch ?? process.arch;
|
|
8599
|
-
const
|
|
8998
|
+
const resolve8 = deps.resolve ?? ((id) => require4.resolve(id));
|
|
8600
8999
|
const fileExists = deps.existsSync ?? existsSync6;
|
|
8601
|
-
const
|
|
9000
|
+
const stat12 = deps.statSync ?? statSync;
|
|
8602
9001
|
const chmod = deps.chmodSync ?? chmodSync2;
|
|
8603
9002
|
let packageJsonPath;
|
|
8604
9003
|
try {
|
|
8605
|
-
packageJsonPath =
|
|
9004
|
+
packageJsonPath = resolve8(NODE_PTY_PKG);
|
|
8606
9005
|
} catch {
|
|
8607
9006
|
return;
|
|
8608
9007
|
}
|
|
@@ -8616,7 +9015,7 @@ function ensureNodePtySpawnHelperExecutable(deps = {}) {
|
|
|
8616
9015
|
if (!fileExists(helperPath)) {
|
|
8617
9016
|
return;
|
|
8618
9017
|
}
|
|
8619
|
-
const currentMode =
|
|
9018
|
+
const currentMode = stat12(helperPath).mode;
|
|
8620
9019
|
const executableMode = currentMode | 73;
|
|
8621
9020
|
if (executableMode === currentMode) {
|
|
8622
9021
|
return;
|
|
@@ -8667,7 +9066,7 @@ async function escalateKillWithPolling(pid, signal, options) {
|
|
|
8667
9066
|
const startTime = Date.now();
|
|
8668
9067
|
const deadline = startTime + timeoutMs;
|
|
8669
9068
|
while (Date.now() < deadline) {
|
|
8670
|
-
await new Promise((
|
|
9069
|
+
await new Promise((resolve8) => setTimeout(resolve8, pollIntervalMs));
|
|
8671
9070
|
if (!isProcessAlive(pid)) {
|
|
8672
9071
|
return true;
|
|
8673
9072
|
}
|
|
@@ -9031,7 +9430,7 @@ async function runCommand(command, timeoutMs, options = {}) {
|
|
|
9031
9430
|
if (options.signal?.aborted) {
|
|
9032
9431
|
throw createSupervisorEvalAbortedError();
|
|
9033
9432
|
}
|
|
9034
|
-
return await new Promise((
|
|
9433
|
+
return await new Promise((resolve8, reject) => {
|
|
9035
9434
|
const child = spawn3(command.argv[0], command.argv.slice(1), {
|
|
9036
9435
|
cwd: command.cwd,
|
|
9037
9436
|
detached: process.platform !== "win32",
|
|
@@ -9061,7 +9460,7 @@ async function runCommand(command, timeoutMs, options = {}) {
|
|
|
9061
9460
|
}
|
|
9062
9461
|
settled = true;
|
|
9063
9462
|
cleanup();
|
|
9064
|
-
|
|
9463
|
+
resolve8(value);
|
|
9065
9464
|
};
|
|
9066
9465
|
const terminate = (error) => {
|
|
9067
9466
|
if (terminationError) {
|
|
@@ -9889,12 +10288,12 @@ var init_scheduler = __esm({
|
|
|
9889
10288
|
|
|
9890
10289
|
// packages/server/src/supervisor/manager.ts
|
|
9891
10290
|
function createDeferredCompletion() {
|
|
9892
|
-
let
|
|
10291
|
+
let resolve8 = () => {
|
|
9893
10292
|
};
|
|
9894
10293
|
const promise = new Promise((innerResolve) => {
|
|
9895
|
-
|
|
10294
|
+
resolve8 = innerResolve;
|
|
9896
10295
|
});
|
|
9897
|
-
return { promise, resolve:
|
|
10296
|
+
return { promise, resolve: resolve8 };
|
|
9898
10297
|
}
|
|
9899
10298
|
function generateSupervisorId() {
|
|
9900
10299
|
return `sup_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
|
|
@@ -10015,6 +10414,9 @@ var init_manager4 = __esm({
|
|
|
10015
10414
|
logger;
|
|
10016
10415
|
config;
|
|
10017
10416
|
lifecycleUnsubscribe = null;
|
|
10417
|
+
setProviderRegistry(providerRegistry2) {
|
|
10418
|
+
this.deps.providerRegistry = providerRegistry2;
|
|
10419
|
+
}
|
|
10018
10420
|
start() {
|
|
10019
10421
|
this.lifecycleUnsubscribe?.();
|
|
10020
10422
|
this.lifecycleUnsubscribe = this.deps.eventBus.on(
|
|
@@ -11249,10 +11651,10 @@ var init_manager4 = __esm({
|
|
|
11249
11651
|
if (signal?.aborted) {
|
|
11250
11652
|
throw { code: "supervisor_eval_aborted", message: "Supervisor evaluator aborted" };
|
|
11251
11653
|
}
|
|
11252
|
-
await new Promise((
|
|
11654
|
+
await new Promise((resolve8, reject) => {
|
|
11253
11655
|
const timer = setTimeout(() => {
|
|
11254
11656
|
signal?.removeEventListener("abort", onAbort);
|
|
11255
|
-
|
|
11657
|
+
resolve8();
|
|
11256
11658
|
}, delayMs);
|
|
11257
11659
|
timer.unref?.();
|
|
11258
11660
|
const onAbort = () => {
|
|
@@ -11284,30 +11686,30 @@ __export(target_store_exports, {
|
|
|
11284
11686
|
saveTargetMeta: () => saveTargetMeta
|
|
11285
11687
|
});
|
|
11286
11688
|
import { mkdir as mkdir4, mkdtemp as mkdtemp2, readdir as readdir2, readFile as readFile3, rename, rm as rm6, writeFile as writeFile4 } from "node:fs/promises";
|
|
11287
|
-
import { dirname as dirname6, join as
|
|
11689
|
+
import { dirname as dirname6, join as join10 } from "node:path";
|
|
11288
11690
|
function targetDir(workspacePath, targetId) {
|
|
11289
|
-
return
|
|
11691
|
+
return join10(workspacePath, ".coder-studio", "supervisor", "targets", targetId);
|
|
11290
11692
|
}
|
|
11291
11693
|
function metaPath(workspacePath, targetId) {
|
|
11292
|
-
return
|
|
11694
|
+
return join10(targetDir(workspacePath, targetId), "meta.json");
|
|
11293
11695
|
}
|
|
11294
11696
|
function memoryPath(workspacePath, targetId) {
|
|
11295
|
-
return
|
|
11697
|
+
return join10(targetDir(workspacePath, targetId), "memory.json");
|
|
11296
11698
|
}
|
|
11297
11699
|
function cyclesPath(workspacePath, targetId) {
|
|
11298
|
-
return
|
|
11700
|
+
return join10(targetDir(workspacePath, targetId), "cycles.jsonl");
|
|
11299
11701
|
}
|
|
11300
11702
|
function targetsRoot(workspacePath) {
|
|
11301
|
-
return
|
|
11703
|
+
return join10(workspacePath, ".coder-studio", "supervisor", "targets");
|
|
11302
11704
|
}
|
|
11303
11705
|
function metaFilePath(dirPath) {
|
|
11304
|
-
return
|
|
11706
|
+
return join10(dirPath, "meta.json");
|
|
11305
11707
|
}
|
|
11306
11708
|
function memoryFilePath(dirPath) {
|
|
11307
|
-
return
|
|
11709
|
+
return join10(dirPath, "memory.json");
|
|
11308
11710
|
}
|
|
11309
11711
|
function cyclesFilePath(dirPath) {
|
|
11310
|
-
return
|
|
11712
|
+
return join10(dirPath, "cycles.jsonl");
|
|
11311
11713
|
}
|
|
11312
11714
|
function hasCode2(error, code) {
|
|
11313
11715
|
return Boolean(
|
|
@@ -11326,7 +11728,7 @@ function errorMessage(error, fallback) {
|
|
|
11326
11728
|
}
|
|
11327
11729
|
return fallback;
|
|
11328
11730
|
}
|
|
11329
|
-
function
|
|
11731
|
+
function isRecord12(value) {
|
|
11330
11732
|
return Boolean(value) && typeof value === "object";
|
|
11331
11733
|
}
|
|
11332
11734
|
function readNonEmptyString(value) {
|
|
@@ -11370,7 +11772,7 @@ function fallbackAcceptanceCriteria(title) {
|
|
|
11370
11772
|
return [`${title} is complete`];
|
|
11371
11773
|
}
|
|
11372
11774
|
function normalizeItem(value, fallbackKind) {
|
|
11373
|
-
if (!
|
|
11775
|
+
if (!isRecord12(value)) {
|
|
11374
11776
|
return null;
|
|
11375
11777
|
}
|
|
11376
11778
|
const id = readNonEmptyString(value.id);
|
|
@@ -11401,7 +11803,7 @@ function normalizeLegacyPlanItems(plan) {
|
|
|
11401
11803
|
}
|
|
11402
11804
|
return plan.flatMap((value) => {
|
|
11403
11805
|
const item = normalizeItem(
|
|
11404
|
-
|
|
11806
|
+
isRecord12(value) ? {
|
|
11405
11807
|
id: value.id,
|
|
11406
11808
|
kind: "stage",
|
|
11407
11809
|
title: value.title,
|
|
@@ -11425,7 +11827,7 @@ function resolveActiveItemId(items, candidate) {
|
|
|
11425
11827
|
return items.find((item) => item.status === "in_progress")?.id ?? items.find((item) => item.status === "pending")?.id ?? items[0]?.id;
|
|
11426
11828
|
}
|
|
11427
11829
|
function normalizeTargetMemory(raw, targetId) {
|
|
11428
|
-
if (!
|
|
11830
|
+
if (!isRecord12(raw)) {
|
|
11429
11831
|
return buildTargetMemory(targetId, 0);
|
|
11430
11832
|
}
|
|
11431
11833
|
const updatedAt = readTimestamp(raw.updatedAt, 0);
|
|
@@ -11452,7 +11854,7 @@ function normalizeTargetMemory(raw, targetId) {
|
|
|
11452
11854
|
};
|
|
11453
11855
|
}
|
|
11454
11856
|
function normalizePersistedSupervisor(raw, fallback) {
|
|
11455
|
-
if (!
|
|
11857
|
+
if (!isRecord12(raw)) {
|
|
11456
11858
|
return void 0;
|
|
11457
11859
|
}
|
|
11458
11860
|
const id = readNonEmptyString(raw.id) ?? fallback.targetId;
|
|
@@ -11488,7 +11890,7 @@ function normalizePersistedSupervisor(raw, fallback) {
|
|
|
11488
11890
|
};
|
|
11489
11891
|
}
|
|
11490
11892
|
function normalizeTargetMeta(raw, fallbackTargetId) {
|
|
11491
|
-
if (!
|
|
11893
|
+
if (!isRecord12(raw)) {
|
|
11492
11894
|
const targetId2 = fallbackTargetId ?? "";
|
|
11493
11895
|
return {
|
|
11494
11896
|
targetId: targetId2,
|
|
@@ -11609,7 +12011,7 @@ async function resetTargetFiles(workspacePath, input) {
|
|
|
11609
12011
|
const parentDir = dirname6(dir);
|
|
11610
12012
|
const backupDir = `${dir}.backup-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
11611
12013
|
await mkdir4(parentDir, { recursive: true });
|
|
11612
|
-
const stagingDir = await mkdtemp2(
|
|
12014
|
+
const stagingDir = await mkdtemp2(join10(parentDir, `${input.targetId}.reset-`));
|
|
11613
12015
|
let backupCreated = false;
|
|
11614
12016
|
let promoted = false;
|
|
11615
12017
|
let restored = false;
|
|
@@ -12066,8 +12468,8 @@ var init_terminal_snapshot_buffer = __esm({
|
|
|
12066
12468
|
if (this.pendingWriteCount === 0) {
|
|
12067
12469
|
return Promise.resolve();
|
|
12068
12470
|
}
|
|
12069
|
-
return new Promise((
|
|
12070
|
-
this.drainResolvers.push(
|
|
12471
|
+
return new Promise((resolve8) => {
|
|
12472
|
+
this.drainResolvers.push(resolve8);
|
|
12071
12473
|
});
|
|
12072
12474
|
}
|
|
12073
12475
|
resolveDrainIfIdle() {
|
|
@@ -12076,8 +12478,8 @@ var init_terminal_snapshot_buffer = __esm({
|
|
|
12076
12478
|
}
|
|
12077
12479
|
const resolvers = this.drainResolvers;
|
|
12078
12480
|
this.drainResolvers = [];
|
|
12079
|
-
for (const
|
|
12080
|
-
|
|
12481
|
+
for (const resolve8 of resolvers) {
|
|
12482
|
+
resolve8();
|
|
12081
12483
|
}
|
|
12082
12484
|
}
|
|
12083
12485
|
requireTerminal() {
|
|
@@ -12231,6 +12633,13 @@ var init_manager5 = __esm({
|
|
|
12231
12633
|
...derivedColorFgBg ? { COLORFGBG: derivedColorFgBg } : {},
|
|
12232
12634
|
...spec.env
|
|
12233
12635
|
};
|
|
12636
|
+
delete terminalEnv.COLORFGBG;
|
|
12637
|
+
if (derivedColorFgBg) {
|
|
12638
|
+
terminalEnv.COLORFGBG = derivedColorFgBg;
|
|
12639
|
+
}
|
|
12640
|
+
if (spec.env?.COLORFGBG) {
|
|
12641
|
+
terminalEnv.COLORFGBG = spec.env.COLORFGBG;
|
|
12642
|
+
}
|
|
12234
12643
|
let pty;
|
|
12235
12644
|
try {
|
|
12236
12645
|
pty = this.deps.ptyHost.spawn(spec.argv, {
|
|
@@ -12431,10 +12840,10 @@ var init_manager5 = __esm({
|
|
|
12431
12840
|
}
|
|
12432
12841
|
return existing.promise;
|
|
12433
12842
|
}
|
|
12434
|
-
let
|
|
12843
|
+
let resolve8 = () => {
|
|
12435
12844
|
};
|
|
12436
12845
|
const promise = new Promise((innerResolve) => {
|
|
12437
|
-
|
|
12846
|
+
resolve8 = innerResolve;
|
|
12438
12847
|
});
|
|
12439
12848
|
let markKillCompleted = () => {
|
|
12440
12849
|
};
|
|
@@ -12447,7 +12856,7 @@ var init_manager5 = __esm({
|
|
|
12447
12856
|
markKillCompleted,
|
|
12448
12857
|
finalized: false,
|
|
12449
12858
|
promise,
|
|
12450
|
-
resolve:
|
|
12859
|
+
resolve: resolve8
|
|
12451
12860
|
});
|
|
12452
12861
|
void terminal.pty.kill(signal).finally(() => {
|
|
12453
12862
|
const waiter = this.explicitCloseWaiters.get(terminalId);
|
|
@@ -12630,7 +13039,7 @@ var init_update_service = __esm({
|
|
|
12630
13039
|
"packages/server/src/update/update-service.ts"() {
|
|
12631
13040
|
"use strict";
|
|
12632
13041
|
init_src3();
|
|
12633
|
-
UpdateService = class {
|
|
13042
|
+
UpdateService = class _UpdateService {
|
|
12634
13043
|
constructor(deps) {
|
|
12635
13044
|
this.deps = deps;
|
|
12636
13045
|
this.now = deps.now ?? Date.now;
|
|
@@ -12652,12 +13061,14 @@ var init_update_service = __esm({
|
|
|
12652
13061
|
this.spawnDetachedWorkerImpl = deps.spawnDetachedWorker;
|
|
12653
13062
|
}
|
|
12654
13063
|
deps;
|
|
13064
|
+
static CHECK_TIMEOUT_MS = 15e3;
|
|
12655
13065
|
now;
|
|
12656
13066
|
runtime;
|
|
12657
13067
|
updateWorkerLogFilePath;
|
|
12658
13068
|
runLatestVersionLookup;
|
|
12659
13069
|
spawnDetachedWorkerImpl;
|
|
12660
13070
|
scheduleTimer = null;
|
|
13071
|
+
inFlightCheck = null;
|
|
12661
13072
|
start() {
|
|
12662
13073
|
this.reconcileOnStartup();
|
|
12663
13074
|
this.reloadScheduleFromSettings();
|
|
@@ -12688,10 +13099,8 @@ var init_update_service = __esm({
|
|
|
12688
13099
|
this.scheduleTimer.unref?.();
|
|
12689
13100
|
}
|
|
12690
13101
|
getStateView() {
|
|
12691
|
-
|
|
12692
|
-
|
|
12693
|
-
...this.getSupportInfo()
|
|
12694
|
-
};
|
|
13102
|
+
const persisted = this.deps.updateStateRepo.get();
|
|
13103
|
+
return this.composeStateView(persisted);
|
|
12695
13104
|
}
|
|
12696
13105
|
getPrepareInstallState() {
|
|
12697
13106
|
const state = this.getStateView();
|
|
@@ -12708,36 +13117,15 @@ var init_update_service = __esm({
|
|
|
12708
13117
|
if (current.updateStatus === "installing" || current.updateStatus === "restarting") {
|
|
12709
13118
|
throw createBusyError("Update installation is already in progress");
|
|
12710
13119
|
}
|
|
12711
|
-
if (
|
|
13120
|
+
if (this.inFlightCheck) {
|
|
12712
13121
|
throw createBusyError("Update check is already in progress");
|
|
12713
13122
|
}
|
|
12714
|
-
this.
|
|
12715
|
-
|
|
12716
|
-
finishedAt: null,
|
|
12717
|
-
errorSummary: null
|
|
12718
|
-
});
|
|
13123
|
+
this.inFlightCheck = this.runCheckForUpdates();
|
|
13124
|
+
this.broadcastStateChange();
|
|
12719
13125
|
try {
|
|
12720
|
-
|
|
12721
|
-
|
|
12722
|
-
|
|
12723
|
-
currentVersion: this.runtime.currentVersion,
|
|
12724
|
-
latestVersion,
|
|
12725
|
-
availability,
|
|
12726
|
-
updateStatus: "idle",
|
|
12727
|
-
lastCheckedAt: this.now(),
|
|
12728
|
-
errorSummary: null,
|
|
12729
|
-
requiresManualStep: false,
|
|
12730
|
-
manualCommand: null
|
|
12731
|
-
});
|
|
12732
|
-
} catch (error) {
|
|
12733
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
12734
|
-
return this.persistAndBroadcast({
|
|
12735
|
-
currentVersion: this.runtime.currentVersion,
|
|
12736
|
-
availability: "check_failed",
|
|
12737
|
-
updateStatus: "idle",
|
|
12738
|
-
lastCheckedAt: this.now(),
|
|
12739
|
-
errorSummary: message
|
|
12740
|
-
});
|
|
13126
|
+
return await this.inFlightCheck;
|
|
13127
|
+
} finally {
|
|
13128
|
+
this.inFlightCheck = null;
|
|
12741
13129
|
}
|
|
12742
13130
|
}
|
|
12743
13131
|
prepareInstall() {
|
|
@@ -12752,6 +13140,9 @@ var init_update_service = __esm({
|
|
|
12752
13140
|
if (state.updateStatus === "installing" || state.updateStatus === "restarting") {
|
|
12753
13141
|
throw createBusyError("Update installation is already in progress");
|
|
12754
13142
|
}
|
|
13143
|
+
if (this.inFlightCheck) {
|
|
13144
|
+
throw createBusyError("Update check is already in progress");
|
|
13145
|
+
}
|
|
12755
13146
|
const targetVersion = input.targetVersion ?? state.latestVersion;
|
|
12756
13147
|
if (!targetVersion) {
|
|
12757
13148
|
throw createValidationError("update_no_target", "No target version is available");
|
|
@@ -12826,6 +13217,15 @@ var init_update_service = __esm({
|
|
|
12826
13217
|
errorSummary: null
|
|
12827
13218
|
});
|
|
12828
13219
|
}
|
|
13220
|
+
if (current.updateStatus === "checking") {
|
|
13221
|
+
return this.persistAndBroadcast({
|
|
13222
|
+
currentVersion: this.runtime.currentVersion,
|
|
13223
|
+
availability: "check_failed",
|
|
13224
|
+
updateStatus: "failed",
|
|
13225
|
+
finishedAt: this.now(),
|
|
13226
|
+
errorSummary: "Update check did not complete before the service restarted"
|
|
13227
|
+
});
|
|
13228
|
+
}
|
|
12829
13229
|
if (current.updateStatus === "installing" || current.updateStatus === "restarting") {
|
|
12830
13230
|
return this.persistAndBroadcast({
|
|
12831
13231
|
currentVersion: this.runtime.currentVersion,
|
|
@@ -12876,18 +13276,6 @@ var init_update_service = __esm({
|
|
|
12876
13276
|
hasActiveWork: runningTerminalCount > 0 || runningSessionCount > 0 || runningSupervisorCount > 0
|
|
12877
13277
|
};
|
|
12878
13278
|
}
|
|
12879
|
-
persistAndBroadcast(patch) {
|
|
12880
|
-
const snapshot = this.deps.updateStateRepo.update((current) => ({
|
|
12881
|
-
...patch,
|
|
12882
|
-
currentVersion: patch.currentVersion ?? current.currentVersion
|
|
12883
|
-
}));
|
|
12884
|
-
const view = {
|
|
12885
|
-
...snapshot,
|
|
12886
|
-
...this.getSupportInfo()
|
|
12887
|
-
};
|
|
12888
|
-
this.deps.broadcaster.broadcast("update.state.changed", view);
|
|
12889
|
-
return view;
|
|
12890
|
-
}
|
|
12891
13279
|
buildManualCommand(targetVersion) {
|
|
12892
13280
|
return [
|
|
12893
13281
|
`${this.runtime.npmCommand ?? "npm"} install -g ${this.runtime.packageName}@${targetVersion}`,
|
|
@@ -12917,32 +13305,109 @@ var init_update_service = __esm({
|
|
|
12917
13305
|
});
|
|
12918
13306
|
child.unref();
|
|
12919
13307
|
}
|
|
12920
|
-
|
|
12921
|
-
|
|
12922
|
-
|
|
12923
|
-
|
|
12924
|
-
|
|
12925
|
-
|
|
12926
|
-
|
|
12927
|
-
|
|
12928
|
-
|
|
12929
|
-
|
|
12930
|
-
|
|
12931
|
-
|
|
12932
|
-
|
|
12933
|
-
|
|
12934
|
-
|
|
12935
|
-
|
|
12936
|
-
|
|
12937
|
-
|
|
12938
|
-
|
|
12939
|
-
|
|
12940
|
-
|
|
12941
|
-
|
|
12942
|
-
|
|
12943
|
-
|
|
12944
|
-
|
|
12945
|
-
|
|
13308
|
+
composeStateView(snapshot, options) {
|
|
13309
|
+
if (options?.includeInFlightCheck !== false && this.inFlightCheck) {
|
|
13310
|
+
return {
|
|
13311
|
+
...snapshot,
|
|
13312
|
+
...this.getSupportInfo(),
|
|
13313
|
+
updateStatus: "checking",
|
|
13314
|
+
errorSummary: null
|
|
13315
|
+
};
|
|
13316
|
+
}
|
|
13317
|
+
return {
|
|
13318
|
+
...snapshot,
|
|
13319
|
+
...this.getSupportInfo()
|
|
13320
|
+
};
|
|
13321
|
+
}
|
|
13322
|
+
broadcastStateChange() {
|
|
13323
|
+
this.deps.broadcaster.broadcast("update.state.changed", this.getStateView());
|
|
13324
|
+
}
|
|
13325
|
+
async runCheckForUpdates() {
|
|
13326
|
+
try {
|
|
13327
|
+
const latestVersion = await this.withCheckTimeout(
|
|
13328
|
+
this.runLatestVersionLookup(this.runtime.packageName)
|
|
13329
|
+
);
|
|
13330
|
+
const availability = compareVersions(latestVersion, this.runtime.currentVersion) > 0 ? "update_available" : "up_to_date";
|
|
13331
|
+
return this.persistAndBroadcast(
|
|
13332
|
+
{
|
|
13333
|
+
currentVersion: this.runtime.currentVersion,
|
|
13334
|
+
latestVersion,
|
|
13335
|
+
availability,
|
|
13336
|
+
updateStatus: "idle",
|
|
13337
|
+
lastCheckedAt: this.now(),
|
|
13338
|
+
errorSummary: null,
|
|
13339
|
+
requiresManualStep: false,
|
|
13340
|
+
manualCommand: null
|
|
13341
|
+
},
|
|
13342
|
+
false
|
|
13343
|
+
);
|
|
13344
|
+
} catch (error) {
|
|
13345
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
13346
|
+
return this.persistAndBroadcast(
|
|
13347
|
+
{
|
|
13348
|
+
currentVersion: this.runtime.currentVersion,
|
|
13349
|
+
availability: "check_failed",
|
|
13350
|
+
updateStatus: "idle",
|
|
13351
|
+
lastCheckedAt: this.now(),
|
|
13352
|
+
errorSummary: message
|
|
13353
|
+
},
|
|
13354
|
+
false
|
|
13355
|
+
);
|
|
13356
|
+
}
|
|
13357
|
+
}
|
|
13358
|
+
async withCheckTimeout(promise) {
|
|
13359
|
+
let timeoutHandle = null;
|
|
13360
|
+
try {
|
|
13361
|
+
return await Promise.race([
|
|
13362
|
+
promise,
|
|
13363
|
+
new Promise((_, reject) => {
|
|
13364
|
+
timeoutHandle = setTimeout(() => {
|
|
13365
|
+
reject(new Error(`Update check timed out after ${_UpdateService.CHECK_TIMEOUT_MS}ms`));
|
|
13366
|
+
}, _UpdateService.CHECK_TIMEOUT_MS);
|
|
13367
|
+
timeoutHandle.unref?.();
|
|
13368
|
+
})
|
|
13369
|
+
]);
|
|
13370
|
+
} finally {
|
|
13371
|
+
if (timeoutHandle) {
|
|
13372
|
+
clearTimeout(timeoutHandle);
|
|
13373
|
+
}
|
|
13374
|
+
}
|
|
13375
|
+
}
|
|
13376
|
+
persistAndBroadcast(patch, includeInFlightCheck = true) {
|
|
13377
|
+
const snapshot = this.deps.updateStateRepo.update((current) => ({
|
|
13378
|
+
...patch,
|
|
13379
|
+
currentVersion: patch.currentVersion ?? current.currentVersion
|
|
13380
|
+
}));
|
|
13381
|
+
const view = this.composeStateView(snapshot, { includeInFlightCheck });
|
|
13382
|
+
this.deps.broadcaster.broadcast("update.state.changed", view);
|
|
13383
|
+
return view;
|
|
13384
|
+
}
|
|
13385
|
+
};
|
|
13386
|
+
}
|
|
13387
|
+
});
|
|
13388
|
+
|
|
13389
|
+
// packages/server/src/workspace/validator.ts
|
|
13390
|
+
import { constants } from "fs";
|
|
13391
|
+
import { access, stat as stat7 } from "fs/promises";
|
|
13392
|
+
async function validatePath(path14) {
|
|
13393
|
+
try {
|
|
13394
|
+
const stats = await stat7(path14);
|
|
13395
|
+
if (!stats.isDirectory()) {
|
|
13396
|
+
return { valid: false, error: "Path is not a directory" };
|
|
13397
|
+
}
|
|
13398
|
+
await access(path14, constants.R_OK);
|
|
13399
|
+
await access(path14, constants.W_OK);
|
|
13400
|
+
return { valid: true };
|
|
13401
|
+
} catch (error) {
|
|
13402
|
+
if (error.code === "ENOENT") {
|
|
13403
|
+
return { valid: false, error: "Path does not exist" };
|
|
13404
|
+
}
|
|
13405
|
+
if (error.code === "EACCES") {
|
|
13406
|
+
return { valid: false, error: "Permission denied" };
|
|
13407
|
+
}
|
|
13408
|
+
return { valid: false, error: `Validation failed: ${error.message}` };
|
|
13409
|
+
}
|
|
13410
|
+
}
|
|
12946
13411
|
var WorkspaceValidator;
|
|
12947
13412
|
var init_validator = __esm({
|
|
12948
13413
|
"packages/server/src/workspace/validator.ts"() {
|
|
@@ -12961,7 +13426,7 @@ var init_validator = __esm({
|
|
|
12961
13426
|
// packages/server/src/fs/gitignore.ts
|
|
12962
13427
|
import { existsSync as existsSync7, readFileSync as readFileSync6 } from "fs";
|
|
12963
13428
|
import ignore from "ignore";
|
|
12964
|
-
import { join as
|
|
13429
|
+
import { join as join11, relative as relative2 } from "path";
|
|
12965
13430
|
function normalizePath(path14) {
|
|
12966
13431
|
return path14.replace(/\\/g, "/");
|
|
12967
13432
|
}
|
|
@@ -12984,7 +13449,7 @@ function isIgnoredByGitignore(ig, path14) {
|
|
|
12984
13449
|
return ig.ignores(path14) || ig.ignores(`${path14}/`);
|
|
12985
13450
|
}
|
|
12986
13451
|
function createGitignoreFilter(rootPath, dirPath) {
|
|
12987
|
-
const gitignorePath =
|
|
13452
|
+
const gitignorePath = join11(rootPath, ".gitignore");
|
|
12988
13453
|
if (!existsSync7(gitignorePath)) {
|
|
12989
13454
|
return (name) => !isDefaultTreeIgnored(name);
|
|
12990
13455
|
}
|
|
@@ -12994,7 +13459,7 @@ function createGitignoreFilter(rootPath, dirPath) {
|
|
|
12994
13459
|
if (isAlwaysTreeIgnored(name)) {
|
|
12995
13460
|
return false;
|
|
12996
13461
|
}
|
|
12997
|
-
const relativePath = relativeToRoot(rootPath,
|
|
13462
|
+
const relativePath = relativeToRoot(rootPath, join11(dirPath, name));
|
|
12998
13463
|
return !isIgnoredByGitignore(ig, relativePath);
|
|
12999
13464
|
};
|
|
13000
13465
|
}
|
|
@@ -13667,7 +14132,7 @@ var init_fencing = __esm({
|
|
|
13667
14132
|
// packages/server/src/commands/terminal.ts
|
|
13668
14133
|
import { stat as stat8 } from "node:fs/promises";
|
|
13669
14134
|
import { basename, isAbsolute as isAbsolute2 } from "node:path";
|
|
13670
|
-
import { z as
|
|
14135
|
+
import { z as z7 } from "zod";
|
|
13671
14136
|
function decodeTerminalInput(args) {
|
|
13672
14137
|
if ("bytes" in args) {
|
|
13673
14138
|
return Buffer.from(args.bytes, "base64");
|
|
@@ -13739,29 +14204,29 @@ var init_terminal = __esm({
|
|
|
13739
14204
|
init_src3();
|
|
13740
14205
|
init_file_io();
|
|
13741
14206
|
init_dispatch();
|
|
13742
|
-
TerminalInputActivitySchema =
|
|
13743
|
-
TerminalInputSchema =
|
|
13744
|
-
|
|
13745
|
-
terminalId:
|
|
13746
|
-
bytes:
|
|
14207
|
+
TerminalInputActivitySchema = z7.enum(TERMINAL_INPUT_ACTIVITIES).optional();
|
|
14208
|
+
TerminalInputSchema = z7.union([
|
|
14209
|
+
z7.object({
|
|
14210
|
+
terminalId: z7.string(),
|
|
14211
|
+
bytes: z7.string(),
|
|
13747
14212
|
activity: TerminalInputActivitySchema,
|
|
13748
|
-
submittedText:
|
|
14213
|
+
submittedText: z7.string().optional()
|
|
13749
14214
|
}),
|
|
13750
|
-
|
|
13751
|
-
terminalId:
|
|
13752
|
-
transport:
|
|
13753
|
-
streamId:
|
|
13754
|
-
size:
|
|
14215
|
+
z7.object({
|
|
14216
|
+
terminalId: z7.string(),
|
|
14217
|
+
transport: z7.literal("binary"),
|
|
14218
|
+
streamId: z7.number().int().nonnegative(),
|
|
14219
|
+
size: z7.number().int().nonnegative(),
|
|
13755
14220
|
activity: TerminalInputActivitySchema,
|
|
13756
|
-
submittedText:
|
|
14221
|
+
submittedText: z7.string().optional()
|
|
13757
14222
|
})
|
|
13758
14223
|
]);
|
|
13759
14224
|
pendingTerminalInput = /* @__PURE__ */ new Map();
|
|
13760
14225
|
nextOutboundBinaryStreamId = 0;
|
|
13761
14226
|
registerCommand(
|
|
13762
14227
|
"terminal.list",
|
|
13763
|
-
|
|
13764
|
-
workspaceId:
|
|
14228
|
+
z7.object({
|
|
14229
|
+
workspaceId: z7.string()
|
|
13765
14230
|
}),
|
|
13766
14231
|
async (args, ctx) => {
|
|
13767
14232
|
return ctx.terminalMgr.getAll().map((terminal) => terminal.toDTO()).filter((terminal) => terminal.workspaceId === args.workspaceId);
|
|
@@ -13769,12 +14234,12 @@ var init_terminal = __esm({
|
|
|
13769
14234
|
);
|
|
13770
14235
|
registerCommand(
|
|
13771
14236
|
"terminal.create",
|
|
13772
|
-
|
|
13773
|
-
workspaceId:
|
|
13774
|
-
cols:
|
|
13775
|
-
rows:
|
|
13776
|
-
cwdPath:
|
|
13777
|
-
themeBackground:
|
|
14237
|
+
z7.object({
|
|
14238
|
+
workspaceId: z7.string(),
|
|
14239
|
+
cols: z7.number().int().positive().optional(),
|
|
14240
|
+
rows: z7.number().int().positive().optional(),
|
|
14241
|
+
cwdPath: z7.string().optional(),
|
|
14242
|
+
themeBackground: z7.string().regex(/^#[0-9a-fA-F]{3,8}$/).optional()
|
|
13778
14243
|
}),
|
|
13779
14244
|
async (args, ctx) => {
|
|
13780
14245
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -13820,9 +14285,9 @@ var init_terminal = __esm({
|
|
|
13820
14285
|
);
|
|
13821
14286
|
registerCommand(
|
|
13822
14287
|
"terminal.replay",
|
|
13823
|
-
|
|
13824
|
-
terminalId:
|
|
13825
|
-
lastSeq:
|
|
14288
|
+
z7.object({
|
|
14289
|
+
terminalId: z7.string(),
|
|
14290
|
+
lastSeq: z7.number().int().nonnegative().optional()
|
|
13826
14291
|
}),
|
|
13827
14292
|
async (args, ctx, clientId) => {
|
|
13828
14293
|
const replay = ctx.terminalMgr.replay(args.terminalId, args.lastSeq ?? 0);
|
|
@@ -13847,8 +14312,8 @@ var init_terminal = __esm({
|
|
|
13847
14312
|
);
|
|
13848
14313
|
registerCommand(
|
|
13849
14314
|
"terminal.snapshot",
|
|
13850
|
-
|
|
13851
|
-
terminalId:
|
|
14315
|
+
z7.object({
|
|
14316
|
+
terminalId: z7.string()
|
|
13852
14317
|
}),
|
|
13853
14318
|
async (args, ctx, clientId) => {
|
|
13854
14319
|
const snapshot = await ctx.terminalMgr.snapshot(args.terminalId);
|
|
@@ -13876,8 +14341,8 @@ var init_terminal = __esm({
|
|
|
13876
14341
|
);
|
|
13877
14342
|
registerCommand(
|
|
13878
14343
|
"terminal.close",
|
|
13879
|
-
|
|
13880
|
-
terminalId:
|
|
14344
|
+
z7.object({
|
|
14345
|
+
terminalId: z7.string()
|
|
13881
14346
|
}),
|
|
13882
14347
|
async (args, ctx) => {
|
|
13883
14348
|
await ctx.terminalMgr.close(args.terminalId);
|
|
@@ -13899,10 +14364,10 @@ var init_terminal = __esm({
|
|
|
13899
14364
|
});
|
|
13900
14365
|
registerCommand(
|
|
13901
14366
|
"terminal.resize",
|
|
13902
|
-
|
|
13903
|
-
terminalId:
|
|
13904
|
-
cols:
|
|
13905
|
-
rows:
|
|
14367
|
+
z7.object({
|
|
14368
|
+
terminalId: z7.string(),
|
|
14369
|
+
cols: z7.number().int().positive(),
|
|
14370
|
+
rows: z7.number().int().positive()
|
|
13906
14371
|
}),
|
|
13907
14372
|
async (args, ctx) => {
|
|
13908
14373
|
const sessionId = ctx.sessionMgr.findSessionIdByTerminal(args.terminalId);
|
|
@@ -14525,7 +14990,7 @@ var init_hub = __esm({
|
|
|
14525
14990
|
}
|
|
14526
14991
|
}
|
|
14527
14992
|
awaitBinaryPayload(clientId) {
|
|
14528
|
-
return new Promise((
|
|
14993
|
+
return new Promise((resolve8, reject) => {
|
|
14529
14994
|
const timer = setTimeout(() => {
|
|
14530
14995
|
const waiters = this.pendingBinaryWaiters.get(clientId);
|
|
14531
14996
|
if (!waiters) return;
|
|
@@ -14537,7 +15002,7 @@ var init_hub = __esm({
|
|
|
14537
15002
|
}
|
|
14538
15003
|
reject(new Error("Timeout waiting for terminal input binary payload"));
|
|
14539
15004
|
}, BINARY_PAYLOAD_TIMEOUT_MS);
|
|
14540
|
-
const waiter = { resolve:
|
|
15005
|
+
const waiter = { resolve: resolve8, reject, timer };
|
|
14541
15006
|
const queue = this.pendingBinaryWaiters.get(clientId);
|
|
14542
15007
|
if (queue) {
|
|
14543
15008
|
queue.push(waiter);
|
|
@@ -14841,20 +15306,232 @@ var init_hub = __esm({
|
|
|
14841
15306
|
}
|
|
14842
15307
|
});
|
|
14843
15308
|
|
|
15309
|
+
// packages/server/src/workspace/intelligence.ts
|
|
15310
|
+
import { access as access2, lstat as lstat2, readFile as readFile4, stat as stat9 } from "node:fs/promises";
|
|
15311
|
+
import { join as join12, resolve as resolve4 } from "node:path";
|
|
15312
|
+
async function inspectWorkspaceIntelligence(input) {
|
|
15313
|
+
const [packageManager, manifest, git, docsExistence, agentsExists, frameworks] = await Promise.all([
|
|
15314
|
+
detectPackageManager(input.rootPath),
|
|
15315
|
+
readPackageJson(input.rootPath),
|
|
15316
|
+
detectGitState(input.rootPath),
|
|
15317
|
+
detectDocs(input.rootPath),
|
|
15318
|
+
pathExists(join12(input.rootPath, AGENT_INSTRUCTIONS_RELATIVE_PATH)),
|
|
15319
|
+
detectFrameworks(input.rootPath)
|
|
15320
|
+
]);
|
|
15321
|
+
const scripts = extractScripts(manifest);
|
|
15322
|
+
return {
|
|
15323
|
+
workspaceId: input.workspaceId,
|
|
15324
|
+
rootPath: input.rootPath,
|
|
15325
|
+
git,
|
|
15326
|
+
packageManager,
|
|
15327
|
+
frameworks,
|
|
15328
|
+
scripts,
|
|
15329
|
+
recommendedCommands: buildRecommendedCommands(packageManager, scripts),
|
|
15330
|
+
docs: docsExistence,
|
|
15331
|
+
agentInstructions: {
|
|
15332
|
+
exists: agentsExists,
|
|
15333
|
+
path: AGENT_INSTRUCTIONS_RELATIVE_PATH
|
|
15334
|
+
}
|
|
15335
|
+
};
|
|
15336
|
+
}
|
|
15337
|
+
async function detectPackageManager(rootPath) {
|
|
15338
|
+
for (const candidate of packageManagerCandidates) {
|
|
15339
|
+
if (await pathExists(join12(rootPath, candidate.file))) {
|
|
15340
|
+
return candidate.manager;
|
|
15341
|
+
}
|
|
15342
|
+
}
|
|
15343
|
+
if (await pathExists(join12(rootPath, "package.json"))) {
|
|
15344
|
+
return "npm";
|
|
15345
|
+
}
|
|
15346
|
+
return void 0;
|
|
15347
|
+
}
|
|
15348
|
+
async function readPackageJson(rootPath) {
|
|
15349
|
+
const packageJsonPath = join12(rootPath, "package.json");
|
|
15350
|
+
if (!await pathExists(packageJsonPath)) {
|
|
15351
|
+
return null;
|
|
15352
|
+
}
|
|
15353
|
+
try {
|
|
15354
|
+
const raw = await readFile4(packageJsonPath, "utf8");
|
|
15355
|
+
const parsed = JSON.parse(raw);
|
|
15356
|
+
return parsed && typeof parsed === "object" ? parsed : null;
|
|
15357
|
+
} catch {
|
|
15358
|
+
return null;
|
|
15359
|
+
}
|
|
15360
|
+
}
|
|
15361
|
+
function extractScripts(manifest) {
|
|
15362
|
+
const scripts = manifest?.scripts ?? {};
|
|
15363
|
+
return {
|
|
15364
|
+
dev: normalizeScript(scripts.dev),
|
|
15365
|
+
test: normalizeScript(scripts.test),
|
|
15366
|
+
build: normalizeScript(scripts.build),
|
|
15367
|
+
lint: normalizeScript(scripts.lint)
|
|
15368
|
+
};
|
|
15369
|
+
}
|
|
15370
|
+
function normalizeScript(value) {
|
|
15371
|
+
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
15372
|
+
}
|
|
15373
|
+
function buildRecommendedCommands(packageManager, scripts) {
|
|
15374
|
+
if (!packageManager) {
|
|
15375
|
+
return [];
|
|
15376
|
+
}
|
|
15377
|
+
return packageScriptKeys.flatMap((key) => {
|
|
15378
|
+
if (!scripts[key]) {
|
|
15379
|
+
return [];
|
|
15380
|
+
}
|
|
15381
|
+
return [
|
|
15382
|
+
{
|
|
15383
|
+
key,
|
|
15384
|
+
command: buildPackageCommand(packageManager, key),
|
|
15385
|
+
source: "package_json"
|
|
15386
|
+
}
|
|
15387
|
+
];
|
|
15388
|
+
});
|
|
15389
|
+
}
|
|
15390
|
+
function buildPackageCommand(packageManager, scriptName) {
|
|
15391
|
+
switch (packageManager) {
|
|
15392
|
+
case "pnpm":
|
|
15393
|
+
return `pnpm ${scriptName}`;
|
|
15394
|
+
case "yarn":
|
|
15395
|
+
return `yarn ${scriptName}`;
|
|
15396
|
+
case "bun":
|
|
15397
|
+
return `bun run ${scriptName}`;
|
|
15398
|
+
case "npm":
|
|
15399
|
+
default:
|
|
15400
|
+
return `npm run ${scriptName}`;
|
|
15401
|
+
}
|
|
15402
|
+
}
|
|
15403
|
+
async function detectFrameworks(rootPath) {
|
|
15404
|
+
const manifest = await readPackageJson(rootPath);
|
|
15405
|
+
const deps = {
|
|
15406
|
+
...manifest?.dependencies ?? {},
|
|
15407
|
+
...manifest?.devDependencies ?? {}
|
|
15408
|
+
};
|
|
15409
|
+
const frameworks = /* @__PURE__ */ new Set();
|
|
15410
|
+
if ("next" in deps) {
|
|
15411
|
+
frameworks.add("Next.js");
|
|
15412
|
+
}
|
|
15413
|
+
if ("react" in deps) {
|
|
15414
|
+
frameworks.add("React");
|
|
15415
|
+
}
|
|
15416
|
+
if ("vite" in deps || await hasAnyPath(rootPath, viteConfigFiles)) {
|
|
15417
|
+
frameworks.add("Vite");
|
|
15418
|
+
}
|
|
15419
|
+
if (manifest) {
|
|
15420
|
+
frameworks.add("Node");
|
|
15421
|
+
}
|
|
15422
|
+
if (await hasAnyPath(rootPath, ["pnpm-workspace.yaml", "turbo.json", "nx.json"])) {
|
|
15423
|
+
frameworks.add("Monorepo");
|
|
15424
|
+
}
|
|
15425
|
+
return frameworkOrder.filter((framework) => frameworks.has(framework));
|
|
15426
|
+
}
|
|
15427
|
+
async function detectGitState(rootPath) {
|
|
15428
|
+
const gitPath = join12(rootPath, ".git");
|
|
15429
|
+
let stats;
|
|
15430
|
+
try {
|
|
15431
|
+
stats = await lstat2(gitPath);
|
|
15432
|
+
} catch {
|
|
15433
|
+
return { isRepo: false };
|
|
15434
|
+
}
|
|
15435
|
+
const gitDir = stats.isDirectory() ? gitPath : stats.isFile() ? await resolveGitDirFromFile(rootPath, gitPath) : null;
|
|
15436
|
+
if (!gitDir) {
|
|
15437
|
+
return { isRepo: false };
|
|
15438
|
+
}
|
|
15439
|
+
const branch = await readGitBranch(gitDir);
|
|
15440
|
+
return branch ? { isRepo: true, branch } : { isRepo: true };
|
|
15441
|
+
}
|
|
15442
|
+
async function resolveGitDirFromFile(rootPath, gitFilePath) {
|
|
15443
|
+
try {
|
|
15444
|
+
const raw = await readFile4(gitFilePath, "utf8");
|
|
15445
|
+
const match = raw.match(/^gitdir:\s*(.+)\s*$/m);
|
|
15446
|
+
if (!match) {
|
|
15447
|
+
return null;
|
|
15448
|
+
}
|
|
15449
|
+
const gitDirPath = match[1];
|
|
15450
|
+
if (!gitDirPath) {
|
|
15451
|
+
return null;
|
|
15452
|
+
}
|
|
15453
|
+
return resolve4(rootPath, gitDirPath);
|
|
15454
|
+
} catch {
|
|
15455
|
+
return null;
|
|
15456
|
+
}
|
|
15457
|
+
}
|
|
15458
|
+
async function readGitBranch(gitDir) {
|
|
15459
|
+
try {
|
|
15460
|
+
const head = await readFile4(join12(gitDir, "HEAD"), "utf8");
|
|
15461
|
+
const refMatch = head.match(/^ref:\s*refs\/heads\/(.+)\s*$/);
|
|
15462
|
+
return refMatch?.[1];
|
|
15463
|
+
} catch {
|
|
15464
|
+
return void 0;
|
|
15465
|
+
}
|
|
15466
|
+
}
|
|
15467
|
+
async function detectDocs(rootPath) {
|
|
15468
|
+
const docs = [];
|
|
15469
|
+
if (await pathExists(join12(rootPath, "README.md"))) {
|
|
15470
|
+
docs.push({ path: "README.md", kind: "readme" });
|
|
15471
|
+
}
|
|
15472
|
+
if (await pathExists(join12(rootPath, "docs"))) {
|
|
15473
|
+
try {
|
|
15474
|
+
const docsStats = await stat9(join12(rootPath, "docs"));
|
|
15475
|
+
if (docsStats.isDirectory()) {
|
|
15476
|
+
docs.push({ path: "docs", kind: "docs" });
|
|
15477
|
+
}
|
|
15478
|
+
} catch {
|
|
15479
|
+
}
|
|
15480
|
+
}
|
|
15481
|
+
return docs;
|
|
15482
|
+
}
|
|
15483
|
+
async function hasAnyPath(rootPath, relativePaths) {
|
|
15484
|
+
for (const relativePath of relativePaths) {
|
|
15485
|
+
if (await pathExists(join12(rootPath, relativePath))) {
|
|
15486
|
+
return true;
|
|
15487
|
+
}
|
|
15488
|
+
}
|
|
15489
|
+
return false;
|
|
15490
|
+
}
|
|
15491
|
+
async function pathExists(path14) {
|
|
15492
|
+
try {
|
|
15493
|
+
await access2(path14);
|
|
15494
|
+
return true;
|
|
15495
|
+
} catch {
|
|
15496
|
+
return false;
|
|
15497
|
+
}
|
|
15498
|
+
}
|
|
15499
|
+
var frameworkOrder, packageManagerCandidates, packageScriptKeys, viteConfigFiles;
|
|
15500
|
+
var init_intelligence = __esm({
|
|
15501
|
+
"packages/server/src/workspace/intelligence.ts"() {
|
|
15502
|
+
"use strict";
|
|
15503
|
+
init_workspace_state();
|
|
15504
|
+
frameworkOrder = ["Next.js", "React", "Vite", "Node", "Monorepo"];
|
|
15505
|
+
packageManagerCandidates = [
|
|
15506
|
+
{ file: "pnpm-lock.yaml", manager: "pnpm" },
|
|
15507
|
+
{ file: "yarn.lock", manager: "yarn" },
|
|
15508
|
+
{ file: "bun.lockb", manager: "bun" },
|
|
15509
|
+
{ file: "package-lock.json", manager: "npm" }
|
|
15510
|
+
];
|
|
15511
|
+
packageScriptKeys = ["dev", "test", "build", "lint"];
|
|
15512
|
+
viteConfigFiles = [
|
|
15513
|
+
"vite.config.ts",
|
|
15514
|
+
"vite.config.js",
|
|
15515
|
+
"vite.config.mjs",
|
|
15516
|
+
"vite.config.cjs"
|
|
15517
|
+
];
|
|
15518
|
+
}
|
|
15519
|
+
});
|
|
15520
|
+
|
|
14844
15521
|
// packages/server/src/commands/workspace.ts
|
|
14845
15522
|
import { readdir as readdir3, realpath as realpath3 } from "node:fs/promises";
|
|
14846
15523
|
import { homedir as homedir2 } from "node:os";
|
|
14847
|
-
import { isAbsolute as isAbsolute3, join as
|
|
14848
|
-
import { z as
|
|
15524
|
+
import { isAbsolute as isAbsolute3, join as join13, resolve as resolve5 } from "node:path";
|
|
15525
|
+
import { z as z8 } from "zod";
|
|
14849
15526
|
function resolveBrowsePath(path14) {
|
|
14850
15527
|
const home = homedir2();
|
|
14851
15528
|
if (!path14 || path14 === "~") {
|
|
14852
15529
|
return home;
|
|
14853
15530
|
}
|
|
14854
15531
|
if (path14.startsWith("~/")) {
|
|
14855
|
-
return
|
|
15532
|
+
return join13(home, path14.slice(2));
|
|
14856
15533
|
}
|
|
14857
|
-
return isAbsolute3(path14) ? path14 :
|
|
15534
|
+
return isAbsolute3(path14) ? path14 : resolve5(home, path14);
|
|
14858
15535
|
}
|
|
14859
15536
|
async function buildRootPaths(currentPath) {
|
|
14860
15537
|
const roots = /* @__PURE__ */ new Set(["/"]);
|
|
@@ -14873,25 +15550,26 @@ async function buildRootPaths(currentPath) {
|
|
|
14873
15550
|
var init_workspace = __esm({
|
|
14874
15551
|
"packages/server/src/commands/workspace.ts"() {
|
|
14875
15552
|
"use strict";
|
|
15553
|
+
init_intelligence();
|
|
14876
15554
|
init_dispatch();
|
|
14877
|
-
registerCommand("workspace.list",
|
|
15555
|
+
registerCommand("workspace.list", z8.object({}), async (_args, ctx) => {
|
|
14878
15556
|
return ctx.workspaceMgr.list();
|
|
14879
15557
|
});
|
|
14880
15558
|
registerCommand(
|
|
14881
15559
|
"workspace.browse",
|
|
14882
|
-
|
|
14883
|
-
path:
|
|
15560
|
+
z8.object({
|
|
15561
|
+
path: z8.string().optional()
|
|
14884
15562
|
}),
|
|
14885
15563
|
async (args) => {
|
|
14886
15564
|
const basePath = resolveBrowsePath(args.path);
|
|
14887
15565
|
const entries = await readdir3(basePath, { withFileTypes: true });
|
|
14888
15566
|
const directories = entries.filter((entry) => entry.isDirectory()).map((entry) => ({
|
|
14889
15567
|
name: entry.name,
|
|
14890
|
-
path:
|
|
15568
|
+
path: join13(basePath, entry.name)
|
|
14891
15569
|
})).sort((a, b) => a.name.localeCompare(b.name));
|
|
14892
15570
|
return {
|
|
14893
15571
|
currentPath: basePath,
|
|
14894
|
-
parentPath: basePath !== "/" ?
|
|
15572
|
+
parentPath: basePath !== "/" ? join13(basePath, "..") : null,
|
|
14895
15573
|
directories,
|
|
14896
15574
|
rootPaths: await buildRootPaths(basePath)
|
|
14897
15575
|
};
|
|
@@ -14899,8 +15577,8 @@ var init_workspace = __esm({
|
|
|
14899
15577
|
);
|
|
14900
15578
|
registerCommand(
|
|
14901
15579
|
"workspace.open",
|
|
14902
|
-
|
|
14903
|
-
path:
|
|
15580
|
+
z8.object({
|
|
15581
|
+
path: z8.string()
|
|
14904
15582
|
}),
|
|
14905
15583
|
async (args, ctx) => {
|
|
14906
15584
|
return ctx.workspaceMgr.open({
|
|
@@ -14908,10 +15586,26 @@ var init_workspace = __esm({
|
|
|
14908
15586
|
});
|
|
14909
15587
|
}
|
|
14910
15588
|
);
|
|
15589
|
+
registerCommand(
|
|
15590
|
+
"workspace.intelligence",
|
|
15591
|
+
z8.object({
|
|
15592
|
+
workspaceId: z8.string()
|
|
15593
|
+
}),
|
|
15594
|
+
async (args, ctx) => {
|
|
15595
|
+
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
15596
|
+
if (!workspace) {
|
|
15597
|
+
throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
|
|
15598
|
+
}
|
|
15599
|
+
return inspectWorkspaceIntelligence({
|
|
15600
|
+
workspaceId: workspace.id,
|
|
15601
|
+
rootPath: workspace.path
|
|
15602
|
+
});
|
|
15603
|
+
}
|
|
15604
|
+
);
|
|
14911
15605
|
registerCommand(
|
|
14912
15606
|
"workspace.close",
|
|
14913
|
-
|
|
14914
|
-
id:
|
|
15607
|
+
z8.object({
|
|
15608
|
+
id: z8.string()
|
|
14915
15609
|
}),
|
|
14916
15610
|
async (args, ctx) => {
|
|
14917
15611
|
await ctx.workspaceMgr.close(args.id);
|
|
@@ -14919,27 +15613,27 @@ var init_workspace = __esm({
|
|
|
14919
15613
|
);
|
|
14920
15614
|
registerCommand(
|
|
14921
15615
|
"workspace.uiState.set",
|
|
14922
|
-
|
|
14923
|
-
workspaceId:
|
|
14924
|
-
uiState:
|
|
14925
|
-
leftPanelWidth:
|
|
14926
|
-
bottomPanelHeight:
|
|
14927
|
-
focusMode:
|
|
14928
|
-
activeSessionId:
|
|
14929
|
-
fileTreeExpandedDirs:
|
|
14930
|
-
paneLayout:
|
|
14931
|
-
id:
|
|
14932
|
-
type:
|
|
14933
|
-
sessionId:
|
|
14934
|
-
direction:
|
|
14935
|
-
children:
|
|
14936
|
-
() =>
|
|
14937
|
-
|
|
14938
|
-
id:
|
|
14939
|
-
type:
|
|
14940
|
-
sessionId:
|
|
14941
|
-
direction:
|
|
14942
|
-
children:
|
|
15616
|
+
z8.object({
|
|
15617
|
+
workspaceId: z8.string(),
|
|
15618
|
+
uiState: z8.object({
|
|
15619
|
+
leftPanelWidth: z8.number(),
|
|
15620
|
+
bottomPanelHeight: z8.number(),
|
|
15621
|
+
focusMode: z8.boolean(),
|
|
15622
|
+
activeSessionId: z8.string().optional(),
|
|
15623
|
+
fileTreeExpandedDirs: z8.array(z8.string()).optional(),
|
|
15624
|
+
paneLayout: z8.object({
|
|
15625
|
+
id: z8.string(),
|
|
15626
|
+
type: z8.enum(["leaf", "split"]),
|
|
15627
|
+
sessionId: z8.string().optional(),
|
|
15628
|
+
direction: z8.enum(["horizontal", "vertical"]).optional(),
|
|
15629
|
+
children: z8.lazy(
|
|
15630
|
+
() => z8.array(
|
|
15631
|
+
z8.object({
|
|
15632
|
+
id: z8.string(),
|
|
15633
|
+
type: z8.enum(["leaf", "split"]),
|
|
15634
|
+
sessionId: z8.string().optional(),
|
|
15635
|
+
direction: z8.enum(["horizontal", "vertical"]).optional(),
|
|
15636
|
+
children: z8.any().optional()
|
|
14943
15637
|
})
|
|
14944
15638
|
)
|
|
14945
15639
|
).optional()
|
|
@@ -14959,7 +15653,7 @@ var init_workspace = __esm({
|
|
|
14959
15653
|
});
|
|
14960
15654
|
|
|
14961
15655
|
// packages/server/src/commands/workspace-activity.ts
|
|
14962
|
-
import { z as
|
|
15656
|
+
import { z as z9 } from "zod";
|
|
14963
15657
|
function parseWorkspaceLastViewedTarget(value) {
|
|
14964
15658
|
try {
|
|
14965
15659
|
const parsed = JSON.parse(value);
|
|
@@ -14975,15 +15669,15 @@ var init_workspace_activity = __esm({
|
|
|
14975
15669
|
"use strict";
|
|
14976
15670
|
init_dispatch();
|
|
14977
15671
|
WORKSPACE_LAST_VIEWED_TARGET_KEY = "workspace.lastViewedTarget";
|
|
14978
|
-
workspaceLastViewedTargetSchema =
|
|
14979
|
-
workspaceId:
|
|
14980
|
-
sessionId:
|
|
14981
|
-
updatedAt:
|
|
15672
|
+
workspaceLastViewedTargetSchema = z9.object({
|
|
15673
|
+
workspaceId: z9.string(),
|
|
15674
|
+
sessionId: z9.string().optional(),
|
|
15675
|
+
updatedAt: z9.number()
|
|
14982
15676
|
});
|
|
14983
15677
|
registerCommand(
|
|
14984
15678
|
"workspace.activate",
|
|
14985
|
-
|
|
14986
|
-
workspaceId:
|
|
15679
|
+
z9.object({
|
|
15680
|
+
workspaceId: z9.string()
|
|
14987
15681
|
}),
|
|
14988
15682
|
async (args, ctx, clientId) => {
|
|
14989
15683
|
if (!clientId) {
|
|
@@ -14993,14 +15687,14 @@ var init_workspace_activity = __esm({
|
|
|
14993
15687
|
return {};
|
|
14994
15688
|
}
|
|
14995
15689
|
);
|
|
14996
|
-
registerCommand("workspace.deactivate",
|
|
15690
|
+
registerCommand("workspace.deactivate", z9.object({}), async (_args, ctx, clientId) => {
|
|
14997
15691
|
if (!clientId) {
|
|
14998
15692
|
return {};
|
|
14999
15693
|
}
|
|
15000
15694
|
ctx.autoFetch.unregisterViewer(clientId);
|
|
15001
15695
|
return {};
|
|
15002
15696
|
});
|
|
15003
|
-
registerCommand("workspace.lastViewedTarget.get",
|
|
15697
|
+
registerCommand("workspace.lastViewedTarget.get", z9.object({}), async (_args, ctx) => {
|
|
15004
15698
|
const value = ctx.settingsRepo.get(WORKSPACE_LAST_VIEWED_TARGET_KEY);
|
|
15005
15699
|
if (value === void 0) {
|
|
15006
15700
|
return null;
|
|
@@ -15009,9 +15703,9 @@ var init_workspace_activity = __esm({
|
|
|
15009
15703
|
});
|
|
15010
15704
|
registerCommand(
|
|
15011
15705
|
"workspace.lastViewedTarget.set",
|
|
15012
|
-
|
|
15013
|
-
workspaceId:
|
|
15014
|
-
sessionId:
|
|
15706
|
+
z9.object({
|
|
15707
|
+
workspaceId: z9.string(),
|
|
15708
|
+
sessionId: z9.string().optional()
|
|
15015
15709
|
}),
|
|
15016
15710
|
async (args, ctx) => {
|
|
15017
15711
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -15035,14 +15729,14 @@ var init_workspace_activity = __esm({
|
|
|
15035
15729
|
});
|
|
15036
15730
|
|
|
15037
15731
|
// packages/server/src/commands/activation.ts
|
|
15038
|
-
import { z as
|
|
15732
|
+
import { z as z10 } from "zod";
|
|
15039
15733
|
var init_activation2 = __esm({
|
|
15040
15734
|
"packages/server/src/commands/activation.ts"() {
|
|
15041
15735
|
"use strict";
|
|
15042
15736
|
init_dispatch();
|
|
15043
15737
|
registerCommand(
|
|
15044
15738
|
"activation.claim",
|
|
15045
|
-
|
|
15739
|
+
z10.object({ clientInstanceId: z10.string().min(1) }),
|
|
15046
15740
|
async (args, ctx, clientId) => {
|
|
15047
15741
|
if (!clientId) {
|
|
15048
15742
|
throw {
|
|
@@ -15066,7 +15760,7 @@ var init_activation2 = __esm({
|
|
|
15066
15760
|
);
|
|
15067
15761
|
registerCommand(
|
|
15068
15762
|
"activation.release",
|
|
15069
|
-
|
|
15763
|
+
z10.object({ clientInstanceId: z10.string(), generation: z10.number().int().positive() }),
|
|
15070
15764
|
async (args, ctx, clientId) => {
|
|
15071
15765
|
const lease = ctx.activationMgr.getLease();
|
|
15072
15766
|
if (!clientId || !lease || lease.wsClientId !== clientId) {
|
|
@@ -15080,34 +15774,34 @@ var init_activation2 = __esm({
|
|
|
15080
15774
|
});
|
|
15081
15775
|
|
|
15082
15776
|
// packages/server/src/commands/connection.ts
|
|
15083
|
-
import { z as
|
|
15777
|
+
import { z as z11 } from "zod";
|
|
15084
15778
|
var init_connection = __esm({
|
|
15085
15779
|
"packages/server/src/commands/connection.ts"() {
|
|
15086
15780
|
"use strict";
|
|
15087
15781
|
init_dispatch();
|
|
15088
|
-
registerCommand("connection.probe",
|
|
15782
|
+
registerCommand("connection.probe", z11.object({}).default({}), async () => {
|
|
15089
15783
|
return { ok: true };
|
|
15090
15784
|
});
|
|
15091
15785
|
}
|
|
15092
15786
|
});
|
|
15093
15787
|
|
|
15094
15788
|
// packages/server/src/commands/recovery.ts
|
|
15095
|
-
import { z as
|
|
15789
|
+
import { z as z12 } from "zod";
|
|
15096
15790
|
var RecoveryReasonSchema;
|
|
15097
15791
|
var init_recovery = __esm({
|
|
15098
15792
|
"packages/server/src/commands/recovery.ts"() {
|
|
15099
15793
|
"use strict";
|
|
15100
15794
|
init_src3();
|
|
15101
15795
|
init_dispatch();
|
|
15102
|
-
RecoveryReasonSchema =
|
|
15796
|
+
RecoveryReasonSchema = z12.enum(RECOVERY_REASONS);
|
|
15103
15797
|
registerCommand(
|
|
15104
15798
|
"recovery.reconcile",
|
|
15105
|
-
|
|
15799
|
+
z12.object({
|
|
15106
15800
|
reason: RecoveryReasonSchema,
|
|
15107
|
-
terminals:
|
|
15108
|
-
|
|
15109
|
-
terminalId:
|
|
15110
|
-
renderedSeq:
|
|
15801
|
+
terminals: z12.array(
|
|
15802
|
+
z12.object({
|
|
15803
|
+
terminalId: z12.string(),
|
|
15804
|
+
renderedSeq: z12.number().int().nonnegative()
|
|
15111
15805
|
})
|
|
15112
15806
|
)
|
|
15113
15807
|
}),
|
|
@@ -15353,15 +16047,33 @@ var init_pane_layout = __esm({
|
|
|
15353
16047
|
});
|
|
15354
16048
|
|
|
15355
16049
|
// packages/server/src/commands/session.ts
|
|
15356
|
-
import {
|
|
16050
|
+
import { readFile as readFile5 } from "node:fs/promises";
|
|
16051
|
+
import { join as join14, resolve as resolve6 } from "node:path";
|
|
16052
|
+
import { z as z13 } from "zod";
|
|
15357
16053
|
function delay(ms) {
|
|
15358
|
-
return new Promise((
|
|
15359
|
-
setTimeout(
|
|
16054
|
+
return new Promise((resolve8) => {
|
|
16055
|
+
setTimeout(resolve8, ms);
|
|
15360
16056
|
});
|
|
15361
16057
|
}
|
|
15362
16058
|
function getProviderFromRegistry(providerId, registry) {
|
|
15363
16059
|
return registry.find((provider) => provider.id === providerId);
|
|
15364
16060
|
}
|
|
16061
|
+
async function tryReadGitHead(workspacePath) {
|
|
16062
|
+
try {
|
|
16063
|
+
const gitEntryPath = join14(workspacePath, ".git");
|
|
16064
|
+
const gitEntry = await readFile5(gitEntryPath, "utf8").catch(() => null);
|
|
16065
|
+
let gitDir = gitEntryPath;
|
|
16066
|
+
if (gitEntry && gitEntry.startsWith("gitdir:")) {
|
|
16067
|
+
const relativeGitDir = gitEntry.slice("gitdir:".length).trim();
|
|
16068
|
+
gitDir = resolve6(workspacePath, relativeGitDir);
|
|
16069
|
+
}
|
|
16070
|
+
const head = await readFile5(join14(gitDir, "HEAD"), "utf8");
|
|
16071
|
+
const trimmed = head.trim();
|
|
16072
|
+
return trimmed.length > 0 && !trimmed.startsWith("ref:") ? trimmed : void 0;
|
|
16073
|
+
} catch {
|
|
16074
|
+
return void 0;
|
|
16075
|
+
}
|
|
16076
|
+
}
|
|
15365
16077
|
var SESSION_CLOSE_POLL_INTERVAL_MS, SESSION_CLOSE_TIMEOUT_MS;
|
|
15366
16078
|
var init_session2 = __esm({
|
|
15367
16079
|
"packages/server/src/commands/session.ts"() {
|
|
@@ -15373,8 +16085,8 @@ var init_session2 = __esm({
|
|
|
15373
16085
|
SESSION_CLOSE_TIMEOUT_MS = 5e3;
|
|
15374
16086
|
registerCommand(
|
|
15375
16087
|
"session.list",
|
|
15376
|
-
|
|
15377
|
-
workspaceId:
|
|
16088
|
+
z13.object({
|
|
16089
|
+
workspaceId: z13.string()
|
|
15378
16090
|
}),
|
|
15379
16091
|
async (args, ctx) => {
|
|
15380
16092
|
return ctx.sessionMgr.getForWorkspace(args.workspaceId);
|
|
@@ -15382,11 +16094,11 @@ var init_session2 = __esm({
|
|
|
15382
16094
|
);
|
|
15383
16095
|
registerCommand(
|
|
15384
16096
|
"session.create",
|
|
15385
|
-
|
|
15386
|
-
workspaceId:
|
|
15387
|
-
providerId:
|
|
15388
|
-
draft:
|
|
15389
|
-
themeBackground:
|
|
16097
|
+
z13.object({
|
|
16098
|
+
workspaceId: z13.string(),
|
|
16099
|
+
providerId: z13.string(),
|
|
16100
|
+
draft: z13.string().optional(),
|
|
16101
|
+
themeBackground: z13.string().regex(/^#[0-9a-fA-F]{3,8}$/).optional()
|
|
15390
16102
|
}),
|
|
15391
16103
|
async (args, ctx) => {
|
|
15392
16104
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -15409,7 +16121,7 @@ var init_session2 = __esm({
|
|
|
15409
16121
|
}
|
|
15410
16122
|
};
|
|
15411
16123
|
}
|
|
15412
|
-
|
|
16124
|
+
const session = await ctx.sessionMgr.create({
|
|
15413
16125
|
workspaceId: args.workspaceId,
|
|
15414
16126
|
workspacePath: workspace.path,
|
|
15415
16127
|
providerId: args.providerId,
|
|
@@ -15417,12 +16129,22 @@ var init_session2 = __esm({
|
|
|
15417
16129
|
draft: args.draft,
|
|
15418
16130
|
themeBackground: args.themeBackground
|
|
15419
16131
|
});
|
|
16132
|
+
ctx.sessionMetadataRepo?.upsert({
|
|
16133
|
+
sessionId: session.id,
|
|
16134
|
+
workspaceId: args.workspaceId,
|
|
16135
|
+
providerId: args.providerId,
|
|
16136
|
+
objective: args.draft?.trim() || void 0,
|
|
16137
|
+
baselineGitHead: await tryReadGitHead(workspace.path),
|
|
16138
|
+
baselineCapturedAt: Date.now(),
|
|
16139
|
+
verificationRuns: []
|
|
16140
|
+
});
|
|
16141
|
+
return session;
|
|
15420
16142
|
}
|
|
15421
16143
|
);
|
|
15422
16144
|
registerCommand(
|
|
15423
16145
|
"session.stop",
|
|
15424
|
-
|
|
15425
|
-
sessionId:
|
|
16146
|
+
z13.object({
|
|
16147
|
+
sessionId: z13.string()
|
|
15426
16148
|
}),
|
|
15427
16149
|
async (args, ctx) => {
|
|
15428
16150
|
await ctx.sessionMgr.stop(args.sessionId);
|
|
@@ -15430,8 +16152,8 @@ var init_session2 = __esm({
|
|
|
15430
16152
|
);
|
|
15431
16153
|
registerCommand(
|
|
15432
16154
|
"session.remove",
|
|
15433
|
-
|
|
15434
|
-
sessionId:
|
|
16155
|
+
z13.object({
|
|
16156
|
+
sessionId: z13.string()
|
|
15435
16157
|
}),
|
|
15436
16158
|
async (args, ctx) => {
|
|
15437
16159
|
const session = ctx.sessionMgr.get(args.sessionId);
|
|
@@ -15442,13 +16164,14 @@ var init_session2 = __esm({
|
|
|
15442
16164
|
throw { code: "invalid_state", message: `Cannot remove session in state: ${session.state}` };
|
|
15443
16165
|
}
|
|
15444
16166
|
ctx.sessionMgr.delete(args.sessionId);
|
|
16167
|
+
ctx.sessionMetadataRepo?.delete(args.sessionId);
|
|
15445
16168
|
}
|
|
15446
16169
|
);
|
|
15447
16170
|
registerCommand(
|
|
15448
16171
|
"session.close",
|
|
15449
|
-
|
|
15450
|
-
sessionId:
|
|
15451
|
-
paneDisposition:
|
|
16172
|
+
z13.object({
|
|
16173
|
+
sessionId: z13.string(),
|
|
16174
|
+
paneDisposition: z13.enum(["draft", "remove"]).default("draft")
|
|
15452
16175
|
}),
|
|
15453
16176
|
async (args, ctx) => {
|
|
15454
16177
|
let session = ctx.sessionMgr.get(args.sessionId);
|
|
@@ -15504,46 +16227,487 @@ var init_session2 = __esm({
|
|
|
15504
16227
|
};
|
|
15505
16228
|
ctx.workspaceMgr.updateUiState(session.workspaceId, nextUiState);
|
|
15506
16229
|
ctx.sessionMgr.delete(args.sessionId);
|
|
16230
|
+
ctx.sessionMetadataRepo?.delete(args.sessionId);
|
|
15507
16231
|
}
|
|
15508
16232
|
);
|
|
15509
16233
|
}
|
|
15510
16234
|
});
|
|
15511
16235
|
|
|
15512
|
-
// packages/server/src/
|
|
15513
|
-
import {
|
|
15514
|
-
import {
|
|
15515
|
-
|
|
15516
|
-
|
|
15517
|
-
|
|
15518
|
-
|
|
15519
|
-
|
|
15520
|
-
if (!query) {
|
|
15521
|
-
return {
|
|
15522
|
-
files: [],
|
|
15523
|
-
totalMatchCount: 0,
|
|
15524
|
-
hasMoreFiles: false,
|
|
15525
|
-
truncatedMatchFileCount: 0
|
|
16236
|
+
// packages/server/src/commands/session-metadata.ts
|
|
16237
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
16238
|
+
import { z as z14 } from "zod";
|
|
16239
|
+
function requireSessionMetadataRepo(ctx) {
|
|
16240
|
+
if (!ctx.sessionMetadataRepo) {
|
|
16241
|
+
throw {
|
|
16242
|
+
code: "session_metadata_unavailable",
|
|
16243
|
+
message: "Session metadata repository is not configured"
|
|
15526
16244
|
};
|
|
15527
16245
|
}
|
|
15528
|
-
const result = await searchWithRipgrep(rootPath, query, options.maxFiles).catch(
|
|
15529
|
-
async (error) => {
|
|
15530
|
-
if (error.code === "ENOENT") {
|
|
15531
|
-
return searchWithNode(rootPath, query, options.maxFiles);
|
|
15532
|
-
}
|
|
15533
|
-
throw error;
|
|
15534
|
-
}
|
|
15535
|
-
);
|
|
15536
|
-
return finalizeResults(result, options.maxFiles, options.maxMatchesPerFile);
|
|
15537
16246
|
}
|
|
15538
|
-
|
|
15539
|
-
|
|
15540
|
-
|
|
15541
|
-
|
|
15542
|
-
|
|
15543
|
-
|
|
15544
|
-
|
|
15545
|
-
|
|
15546
|
-
|
|
16247
|
+
var init_session_metadata = __esm({
|
|
16248
|
+
"packages/server/src/commands/session-metadata.ts"() {
|
|
16249
|
+
"use strict";
|
|
16250
|
+
init_dispatch();
|
|
16251
|
+
registerCommand(
|
|
16252
|
+
"session.metadata.get",
|
|
16253
|
+
z14.object({
|
|
16254
|
+
sessionId: z14.string()
|
|
16255
|
+
}),
|
|
16256
|
+
async (args, ctx) => {
|
|
16257
|
+
requireSessionMetadataRepo(ctx);
|
|
16258
|
+
const metadata = ctx.sessionMetadataRepo.get(args.sessionId);
|
|
16259
|
+
if (!metadata) {
|
|
16260
|
+
throw {
|
|
16261
|
+
code: "session_metadata_not_found",
|
|
16262
|
+
message: `Session metadata not found: ${args.sessionId}`
|
|
16263
|
+
};
|
|
16264
|
+
}
|
|
16265
|
+
return metadata;
|
|
16266
|
+
}
|
|
16267
|
+
);
|
|
16268
|
+
registerCommand(
|
|
16269
|
+
"session.verification.add",
|
|
16270
|
+
z14.object({
|
|
16271
|
+
sessionId: z14.string(),
|
|
16272
|
+
command: z14.string().trim().min(1),
|
|
16273
|
+
status: z14.enum(["passed", "failed", "unknown"]),
|
|
16274
|
+
exitCode: z14.number().int().optional(),
|
|
16275
|
+
summary: z14.string().optional()
|
|
16276
|
+
}),
|
|
16277
|
+
async (args, ctx) => {
|
|
16278
|
+
requireSessionMetadataRepo(ctx);
|
|
16279
|
+
return ctx.sessionMetadataRepo.addVerificationRun(args.sessionId, {
|
|
16280
|
+
id: randomUUID6(),
|
|
16281
|
+
command: args.command,
|
|
16282
|
+
status: args.status,
|
|
16283
|
+
exitCode: args.exitCode,
|
|
16284
|
+
summary: args.summary?.trim() || void 0,
|
|
16285
|
+
createdAt: Date.now()
|
|
16286
|
+
});
|
|
16287
|
+
}
|
|
16288
|
+
);
|
|
16289
|
+
}
|
|
16290
|
+
});
|
|
16291
|
+
|
|
16292
|
+
// packages/server/src/git/diff.ts
|
|
16293
|
+
import { mkdtemp as mkdtemp3, readFile as readFile6, rm as rm7 } from "fs/promises";
|
|
16294
|
+
import os3 from "os";
|
|
16295
|
+
import path11 from "path";
|
|
16296
|
+
async function isTrackedPath(cwd, filePath) {
|
|
16297
|
+
try {
|
|
16298
|
+
await runGit(cwd, ["ls-files", "--error-unmatch", "--", filePath]);
|
|
16299
|
+
return true;
|
|
16300
|
+
} catch {
|
|
16301
|
+
return false;
|
|
16302
|
+
}
|
|
16303
|
+
}
|
|
16304
|
+
async function getUntrackedFileDiff(cwd, filePath) {
|
|
16305
|
+
const tempDir = await mkdtemp3(path11.join(os3.tmpdir(), "coder-studio-git-diff-"));
|
|
16306
|
+
const tempIndex = path11.join(tempDir, "index");
|
|
16307
|
+
try {
|
|
16308
|
+
try {
|
|
16309
|
+
await runGit(cwd, ["read-tree", "HEAD"], {
|
|
16310
|
+
env: { GIT_INDEX_FILE: tempIndex }
|
|
16311
|
+
});
|
|
16312
|
+
} catch (error) {
|
|
16313
|
+
if (!(error instanceof GitError)) {
|
|
16314
|
+
throw error;
|
|
16315
|
+
}
|
|
16316
|
+
await runGit(cwd, ["read-tree", "--empty"], {
|
|
16317
|
+
env: { GIT_INDEX_FILE: tempIndex }
|
|
16318
|
+
});
|
|
16319
|
+
}
|
|
16320
|
+
await runGit(cwd, ["add", "-N", "--", filePath], {
|
|
16321
|
+
env: { GIT_INDEX_FILE: tempIndex }
|
|
16322
|
+
});
|
|
16323
|
+
const result = await runGit(cwd, ["diff", "--", filePath], {
|
|
16324
|
+
env: { GIT_INDEX_FILE: tempIndex }
|
|
16325
|
+
});
|
|
16326
|
+
return result.stdout;
|
|
16327
|
+
} finally {
|
|
16328
|
+
await rm7(tempDir, { recursive: true, force: true });
|
|
16329
|
+
}
|
|
16330
|
+
}
|
|
16331
|
+
async function pathExists2(cwd, filePath) {
|
|
16332
|
+
try {
|
|
16333
|
+
await readFile6(resolveSafe(cwd, filePath));
|
|
16334
|
+
return true;
|
|
16335
|
+
} catch {
|
|
16336
|
+
return false;
|
|
16337
|
+
}
|
|
16338
|
+
}
|
|
16339
|
+
async function readTextAtRevision(cwd, revision, filePath) {
|
|
16340
|
+
if (revision === "WORKTREE") {
|
|
16341
|
+
return readFile6(resolveSafe(cwd, filePath), "utf-8");
|
|
16342
|
+
}
|
|
16343
|
+
try {
|
|
16344
|
+
const gitSpec = revision === "INDEX" ? `:${filePath}` : `${revision}:${filePath}`;
|
|
16345
|
+
const result = await runGit(cwd, ["show", gitSpec]);
|
|
16346
|
+
return result.stdout;
|
|
16347
|
+
} catch {
|
|
16348
|
+
return "";
|
|
16349
|
+
}
|
|
16350
|
+
}
|
|
16351
|
+
async function deriveFileDiffStatus(cwd, filePath, staged) {
|
|
16352
|
+
const tracked = await isTrackedPath(cwd, filePath);
|
|
16353
|
+
const existsOnDisk = await pathExists2(cwd, filePath);
|
|
16354
|
+
if (!staged && !tracked) {
|
|
16355
|
+
return "added";
|
|
16356
|
+
}
|
|
16357
|
+
if (staged) {
|
|
16358
|
+
try {
|
|
16359
|
+
await runGit(cwd, ["cat-file", "-e", `HEAD:${filePath}`]);
|
|
16360
|
+
return existsOnDisk ? "modified" : "deleted";
|
|
16361
|
+
} catch {
|
|
16362
|
+
return "added";
|
|
16363
|
+
}
|
|
16364
|
+
}
|
|
16365
|
+
return existsOnDisk ? "modified" : "deleted";
|
|
16366
|
+
}
|
|
16367
|
+
async function buildTextDiffResult(cwd, filePath, staged, diff) {
|
|
16368
|
+
const status = await deriveFileDiffStatus(cwd, filePath, staged);
|
|
16369
|
+
if (status === "added") {
|
|
16370
|
+
return {
|
|
16371
|
+
diff,
|
|
16372
|
+
renderAs: "text",
|
|
16373
|
+
status,
|
|
16374
|
+
originalContent: "",
|
|
16375
|
+
modifiedContent: await readTextAtRevision(cwd, staged ? "INDEX" : "WORKTREE", filePath)
|
|
16376
|
+
};
|
|
16377
|
+
}
|
|
16378
|
+
if (status === "deleted") {
|
|
16379
|
+
return {
|
|
16380
|
+
diff,
|
|
16381
|
+
renderAs: "text",
|
|
16382
|
+
status,
|
|
16383
|
+
originalContent: await readTextAtRevision(cwd, staged ? "HEAD" : "INDEX", filePath),
|
|
16384
|
+
modifiedContent: ""
|
|
16385
|
+
};
|
|
16386
|
+
}
|
|
16387
|
+
return {
|
|
16388
|
+
diff,
|
|
16389
|
+
renderAs: "text",
|
|
16390
|
+
status,
|
|
16391
|
+
originalContent: await readTextAtRevision(cwd, staged ? "HEAD" : "INDEX", filePath),
|
|
16392
|
+
modifiedContent: await readTextAtRevision(cwd, staged ? "INDEX" : "WORKTREE", filePath)
|
|
16393
|
+
};
|
|
16394
|
+
}
|
|
16395
|
+
async function getFileDiff(cwd, path14, staged = false) {
|
|
16396
|
+
const imageType = getImageTypeInfo(path14);
|
|
16397
|
+
if (!staged && !await isTrackedPath(cwd, path14)) {
|
|
16398
|
+
const diff = await getUntrackedFileDiff(cwd, path14);
|
|
16399
|
+
if (imageType) {
|
|
16400
|
+
return {
|
|
16401
|
+
diff,
|
|
16402
|
+
renderAs: "image",
|
|
16403
|
+
status: "added",
|
|
16404
|
+
originalRevision: "HEAD",
|
|
16405
|
+
modifiedRevision: "WORKTREE"
|
|
16406
|
+
};
|
|
16407
|
+
}
|
|
16408
|
+
return buildTextDiffResult(cwd, path14, staged, diff);
|
|
16409
|
+
}
|
|
16410
|
+
const args = staged ? ["diff", "--staged", "--", path14] : ["diff", "--", path14];
|
|
16411
|
+
const result = await runGit(cwd, args);
|
|
16412
|
+
if (imageType && /Binary files .* differ/.test(result.stdout)) {
|
|
16413
|
+
return {
|
|
16414
|
+
diff: result.stdout,
|
|
16415
|
+
renderAs: "image",
|
|
16416
|
+
status: await deriveFileDiffStatus(cwd, path14, staged),
|
|
16417
|
+
originalRevision: staged ? "HEAD" : "INDEX",
|
|
16418
|
+
modifiedRevision: staged ? "INDEX" : "WORKTREE"
|
|
16419
|
+
};
|
|
16420
|
+
}
|
|
16421
|
+
return buildTextDiffResult(cwd, path14, staged, result.stdout);
|
|
16422
|
+
}
|
|
16423
|
+
var init_diff = __esm({
|
|
16424
|
+
"packages/server/src/git/diff.ts"() {
|
|
16425
|
+
"use strict";
|
|
16426
|
+
init_file_io();
|
|
16427
|
+
init_image();
|
|
16428
|
+
init_cli();
|
|
16429
|
+
}
|
|
16430
|
+
});
|
|
16431
|
+
|
|
16432
|
+
// packages/server/src/session-review/review.ts
|
|
16433
|
+
function isWorkspaceStatePath(path14) {
|
|
16434
|
+
return path14 === WORKSPACE_STATE_DIR || path14.startsWith(`${WORKSPACE_STATE_DIR}/`);
|
|
16435
|
+
}
|
|
16436
|
+
function requireSessionMetadata(metadataRepo, sessionId) {
|
|
16437
|
+
const metadata = metadataRepo.get(sessionId);
|
|
16438
|
+
if (!metadata) {
|
|
16439
|
+
throw {
|
|
16440
|
+
code: "session_metadata_not_found",
|
|
16441
|
+
message: `Session metadata not found: ${sessionId}`
|
|
16442
|
+
};
|
|
16443
|
+
}
|
|
16444
|
+
return metadata;
|
|
16445
|
+
}
|
|
16446
|
+
async function isGitRepository(workspacePath) {
|
|
16447
|
+
try {
|
|
16448
|
+
await runGit(workspacePath, ["rev-parse", "--git-dir"]);
|
|
16449
|
+
return true;
|
|
16450
|
+
} catch (error) {
|
|
16451
|
+
if (error instanceof GitError) {
|
|
16452
|
+
return false;
|
|
16453
|
+
}
|
|
16454
|
+
throw error;
|
|
16455
|
+
}
|
|
16456
|
+
}
|
|
16457
|
+
function compareGitChanges(a, b) {
|
|
16458
|
+
const pathCompare = a.path.localeCompare(b.path);
|
|
16459
|
+
if (pathCompare !== 0) {
|
|
16460
|
+
return pathCompare;
|
|
16461
|
+
}
|
|
16462
|
+
return (a.oldPath ?? "").localeCompare(b.oldPath ?? "");
|
|
16463
|
+
}
|
|
16464
|
+
function mapGitStatus(code) {
|
|
16465
|
+
switch (code[0]) {
|
|
16466
|
+
case "A":
|
|
16467
|
+
return "added";
|
|
16468
|
+
case "D":
|
|
16469
|
+
return "deleted";
|
|
16470
|
+
case "M":
|
|
16471
|
+
default:
|
|
16472
|
+
return "modified";
|
|
16473
|
+
}
|
|
16474
|
+
}
|
|
16475
|
+
async function listTrackedChangesSinceBaseline(workspacePath, baselineGitHead) {
|
|
16476
|
+
const { stdout } = await runGit(workspacePath, [
|
|
16477
|
+
"diff",
|
|
16478
|
+
"--name-status",
|
|
16479
|
+
"--find-renames",
|
|
16480
|
+
baselineGitHead,
|
|
16481
|
+
"--"
|
|
16482
|
+
]);
|
|
16483
|
+
const changes = stdout.split("\n").map((line) => line.trim()).filter((line) => line.length > 0).map((line) => {
|
|
16484
|
+
const parts = line.split(" ");
|
|
16485
|
+
const statusCode = parts[0] ?? "M";
|
|
16486
|
+
if (statusCode.startsWith("R")) {
|
|
16487
|
+
const oldPath = parts[1];
|
|
16488
|
+
const path15 = parts[2];
|
|
16489
|
+
if (!oldPath || !path15) {
|
|
16490
|
+
return null;
|
|
16491
|
+
}
|
|
16492
|
+
return {
|
|
16493
|
+
oldPath,
|
|
16494
|
+
path: path15,
|
|
16495
|
+
status: "renamed"
|
|
16496
|
+
};
|
|
16497
|
+
}
|
|
16498
|
+
const path14 = parts[1];
|
|
16499
|
+
if (!path14) {
|
|
16500
|
+
return null;
|
|
16501
|
+
}
|
|
16502
|
+
return {
|
|
16503
|
+
path: path14,
|
|
16504
|
+
status: mapGitStatus(statusCode)
|
|
16505
|
+
};
|
|
16506
|
+
});
|
|
16507
|
+
return changes.filter((change) => change !== null).filter((change) => !isWorkspaceStatePath(change.path)).sort(compareGitChanges);
|
|
16508
|
+
}
|
|
16509
|
+
async function listUntrackedChanges(workspacePath) {
|
|
16510
|
+
const { stdout } = await runGit(workspacePath, ["ls-files", "--others", "--exclude-standard"]);
|
|
16511
|
+
return stdout.split("\n").map((line) => line.trim()).filter((line) => line.length > 0).map((path14) => ({
|
|
16512
|
+
path: path14,
|
|
16513
|
+
status: "untracked"
|
|
16514
|
+
})).filter((change) => !isWorkspaceStatePath(change.path)).sort(compareGitChanges);
|
|
16515
|
+
}
|
|
16516
|
+
async function isUntrackedPath(workspacePath, filePath) {
|
|
16517
|
+
const { stdout } = await runGit(workspacePath, [
|
|
16518
|
+
"ls-files",
|
|
16519
|
+
"--others",
|
|
16520
|
+
"--exclude-standard",
|
|
16521
|
+
"--",
|
|
16522
|
+
filePath
|
|
16523
|
+
]);
|
|
16524
|
+
return stdout.trim().length > 0;
|
|
16525
|
+
}
|
|
16526
|
+
async function buildSessionReviewSummary(input) {
|
|
16527
|
+
const metadata = requireSessionMetadata(input.metadataRepo, input.sessionId);
|
|
16528
|
+
if (!metadata.baselineGitHead) {
|
|
16529
|
+
return {
|
|
16530
|
+
sessionId: metadata.sessionId,
|
|
16531
|
+
workspaceId: metadata.workspaceId,
|
|
16532
|
+
baselineGitHead: metadata.baselineGitHead,
|
|
16533
|
+
changedFiles: [],
|
|
16534
|
+
verificationRuns: metadata.verificationRuns,
|
|
16535
|
+
warnings: [MISSING_BASELINE_WARNING]
|
|
16536
|
+
};
|
|
16537
|
+
}
|
|
16538
|
+
if (!await isGitRepository(input.workspacePath)) {
|
|
16539
|
+
return {
|
|
16540
|
+
sessionId: metadata.sessionId,
|
|
16541
|
+
workspaceId: metadata.workspaceId,
|
|
16542
|
+
baselineGitHead: metadata.baselineGitHead,
|
|
16543
|
+
changedFiles: [],
|
|
16544
|
+
verificationRuns: metadata.verificationRuns,
|
|
16545
|
+
warnings: [NOT_GIT_REPO_WARNING]
|
|
16546
|
+
};
|
|
16547
|
+
}
|
|
16548
|
+
const trackedChanges = await listTrackedChangesSinceBaseline(
|
|
16549
|
+
input.workspacePath,
|
|
16550
|
+
metadata.baselineGitHead
|
|
16551
|
+
);
|
|
16552
|
+
const trackedPaths = new Set(trackedChanges.map((change) => change.path));
|
|
16553
|
+
const untrackedChanges = (await listUntrackedChanges(input.workspacePath)).filter(
|
|
16554
|
+
(change) => !trackedPaths.has(change.path)
|
|
16555
|
+
);
|
|
16556
|
+
return {
|
|
16557
|
+
sessionId: metadata.sessionId,
|
|
16558
|
+
workspaceId: metadata.workspaceId,
|
|
16559
|
+
baselineGitHead: metadata.baselineGitHead,
|
|
16560
|
+
changedFiles: [...trackedChanges, ...untrackedChanges],
|
|
16561
|
+
verificationRuns: metadata.verificationRuns,
|
|
16562
|
+
warnings: []
|
|
16563
|
+
};
|
|
16564
|
+
}
|
|
16565
|
+
async function getSessionReviewDiff(input) {
|
|
16566
|
+
const metadata = requireSessionMetadata(input.metadataRepo, input.sessionId);
|
|
16567
|
+
if (!metadata.baselineGitHead) {
|
|
16568
|
+
return "";
|
|
16569
|
+
}
|
|
16570
|
+
if (!await isGitRepository(input.workspacePath)) {
|
|
16571
|
+
return "";
|
|
16572
|
+
}
|
|
16573
|
+
if (await isUntrackedPath(input.workspacePath, input.path)) {
|
|
16574
|
+
return (await getFileDiff(input.workspacePath, input.path)).diff;
|
|
16575
|
+
}
|
|
16576
|
+
const { stdout } = await runGit(input.workspacePath, [
|
|
16577
|
+
"diff",
|
|
16578
|
+
metadata.baselineGitHead,
|
|
16579
|
+
"--",
|
|
16580
|
+
input.path
|
|
16581
|
+
]);
|
|
16582
|
+
return stdout;
|
|
16583
|
+
}
|
|
16584
|
+
var MISSING_BASELINE_WARNING, NOT_GIT_REPO_WARNING;
|
|
16585
|
+
var init_review = __esm({
|
|
16586
|
+
"packages/server/src/session-review/review.ts"() {
|
|
16587
|
+
"use strict";
|
|
16588
|
+
init_cli();
|
|
16589
|
+
init_diff();
|
|
16590
|
+
init_workspace_state();
|
|
16591
|
+
MISSING_BASELINE_WARNING = {
|
|
16592
|
+
code: "missing_baseline",
|
|
16593
|
+
message: "Session baseline is missing."
|
|
16594
|
+
};
|
|
16595
|
+
NOT_GIT_REPO_WARNING = {
|
|
16596
|
+
code: "not_git_repo",
|
|
16597
|
+
message: "Workspace is not a Git repository."
|
|
16598
|
+
};
|
|
16599
|
+
}
|
|
16600
|
+
});
|
|
16601
|
+
|
|
16602
|
+
// packages/server/src/commands/session-review.ts
|
|
16603
|
+
import { z as z15 } from "zod";
|
|
16604
|
+
function requireSessionMetadataRepo2(ctx) {
|
|
16605
|
+
if (!ctx.sessionMetadataRepo) {
|
|
16606
|
+
throw {
|
|
16607
|
+
code: "session_metadata_unavailable",
|
|
16608
|
+
message: "Session metadata repository is not configured"
|
|
16609
|
+
};
|
|
16610
|
+
}
|
|
16611
|
+
}
|
|
16612
|
+
function requireWorkspace(ctx, workspaceId) {
|
|
16613
|
+
const workspace = ctx.workspaceMgr.get(workspaceId);
|
|
16614
|
+
if (!workspace) {
|
|
16615
|
+
throw { code: "workspace_not_found", message: `Workspace not found: ${workspaceId}` };
|
|
16616
|
+
}
|
|
16617
|
+
return workspace;
|
|
16618
|
+
}
|
|
16619
|
+
var init_session_review = __esm({
|
|
16620
|
+
"packages/server/src/commands/session-review.ts"() {
|
|
16621
|
+
"use strict";
|
|
16622
|
+
init_review();
|
|
16623
|
+
init_dispatch();
|
|
16624
|
+
registerCommand(
|
|
16625
|
+
"sessionReview.summary",
|
|
16626
|
+
z15.object({
|
|
16627
|
+
sessionId: z15.string()
|
|
16628
|
+
}),
|
|
16629
|
+
async (args, ctx) => {
|
|
16630
|
+
requireSessionMetadataRepo2(ctx);
|
|
16631
|
+
const metadata = ctx.sessionMetadataRepo.get(args.sessionId);
|
|
16632
|
+
if (!metadata) {
|
|
16633
|
+
throw {
|
|
16634
|
+
code: "session_metadata_not_found",
|
|
16635
|
+
message: `Session metadata not found: ${args.sessionId}`
|
|
16636
|
+
};
|
|
16637
|
+
}
|
|
16638
|
+
const workspace = requireWorkspace(ctx, metadata.workspaceId);
|
|
16639
|
+
return buildSessionReviewSummary({
|
|
16640
|
+
sessionId: args.sessionId,
|
|
16641
|
+
workspacePath: workspace.path,
|
|
16642
|
+
metadataRepo: ctx.sessionMetadataRepo
|
|
16643
|
+
});
|
|
16644
|
+
}
|
|
16645
|
+
);
|
|
16646
|
+
registerCommand(
|
|
16647
|
+
"sessionReview.diff",
|
|
16648
|
+
z15.object({
|
|
16649
|
+
sessionId: z15.string(),
|
|
16650
|
+
path: z15.string().trim().min(1)
|
|
16651
|
+
}),
|
|
16652
|
+
async (args, ctx) => {
|
|
16653
|
+
requireSessionMetadataRepo2(ctx);
|
|
16654
|
+
const metadata = ctx.sessionMetadataRepo.get(args.sessionId);
|
|
16655
|
+
if (!metadata) {
|
|
16656
|
+
throw {
|
|
16657
|
+
code: "session_metadata_not_found",
|
|
16658
|
+
message: `Session metadata not found: ${args.sessionId}`
|
|
16659
|
+
};
|
|
16660
|
+
}
|
|
16661
|
+
const workspace = requireWorkspace(ctx, metadata.workspaceId);
|
|
16662
|
+
return {
|
|
16663
|
+
path: args.path,
|
|
16664
|
+
diff: await getSessionReviewDiff({
|
|
16665
|
+
sessionId: args.sessionId,
|
|
16666
|
+
workspacePath: workspace.path,
|
|
16667
|
+
metadataRepo: ctx.sessionMetadataRepo,
|
|
16668
|
+
path: args.path
|
|
16669
|
+
})
|
|
16670
|
+
};
|
|
16671
|
+
}
|
|
16672
|
+
);
|
|
16673
|
+
}
|
|
16674
|
+
});
|
|
16675
|
+
|
|
16676
|
+
// packages/server/src/fs/content-search.ts
|
|
16677
|
+
import { spawn as spawn5 } from "child_process";
|
|
16678
|
+
import { existsSync as existsSync8 } from "fs";
|
|
16679
|
+
import { readdir as readdir4, readFile as readFile7, stat as stat10 } from "fs/promises";
|
|
16680
|
+
import { basename as basename2, join as join15, relative as relative3 } from "path";
|
|
16681
|
+
import { createInterface } from "readline";
|
|
16682
|
+
async function searchFileContents(rootPath, options) {
|
|
16683
|
+
const query = options.query.trim();
|
|
16684
|
+
if (!query) {
|
|
16685
|
+
return {
|
|
16686
|
+
files: [],
|
|
16687
|
+
totalMatchCount: 0,
|
|
16688
|
+
hasMoreFiles: false,
|
|
16689
|
+
truncatedMatchFileCount: 0
|
|
16690
|
+
};
|
|
16691
|
+
}
|
|
16692
|
+
const result = await searchWithRipgrep(rootPath, query, options.maxFiles).catch(
|
|
16693
|
+
async (error) => {
|
|
16694
|
+
if (error.code === "ENOENT") {
|
|
16695
|
+
return searchWithNode(rootPath, query, options.maxFiles);
|
|
16696
|
+
}
|
|
16697
|
+
throw error;
|
|
16698
|
+
}
|
|
16699
|
+
);
|
|
16700
|
+
return finalizeResults(result, options.maxFiles, options.maxMatchesPerFile);
|
|
16701
|
+
}
|
|
16702
|
+
async function searchWithRipgrep(rootPath, query, maxFiles) {
|
|
16703
|
+
const hasGitignore = existsSync8(join15(rootPath, ".gitignore"));
|
|
16704
|
+
const args = [
|
|
16705
|
+
"--json",
|
|
16706
|
+
"--line-number",
|
|
16707
|
+
"--column",
|
|
16708
|
+
"--fixed-strings",
|
|
16709
|
+
"--sort",
|
|
16710
|
+
"path",
|
|
15547
16711
|
"--with-filename",
|
|
15548
16712
|
"--glob",
|
|
15549
16713
|
"!**/.git/**",
|
|
@@ -15555,7 +16719,7 @@ async function searchWithRipgrep(rootPath, query, maxFiles) {
|
|
|
15555
16719
|
args.push("--no-require-git");
|
|
15556
16720
|
}
|
|
15557
16721
|
args.push(query, ".");
|
|
15558
|
-
return new Promise((
|
|
16722
|
+
return new Promise((resolve8, reject) => {
|
|
15559
16723
|
const child = spawn5("rg", args, { cwd: rootPath, stdio: ["ignore", "pipe", "pipe"] });
|
|
15560
16724
|
const stdout = createInterface({ input: child.stdout });
|
|
15561
16725
|
const files = /* @__PURE__ */ new Map();
|
|
@@ -15574,7 +16738,7 @@ async function searchWithRipgrep(rootPath, query, maxFiles) {
|
|
|
15574
16738
|
if (!rawPath) {
|
|
15575
16739
|
return;
|
|
15576
16740
|
}
|
|
15577
|
-
const relativePath = normalizeRelativePath(relative3(rootPath,
|
|
16741
|
+
const relativePath = normalizeRelativePath(relative3(rootPath, join15(rootPath, rawPath)));
|
|
15578
16742
|
const preview = (event.data?.lines?.text ?? "").replace(/\r?\n$/, "");
|
|
15579
16743
|
const lineNumber = event.data?.line_number ?? 1;
|
|
15580
16744
|
const submatches = event.data?.submatches ?? [];
|
|
@@ -15604,7 +16768,7 @@ async function searchWithRipgrep(rootPath, query, maxFiles) {
|
|
|
15604
16768
|
child.on("close", (code) => {
|
|
15605
16769
|
void stdout.close();
|
|
15606
16770
|
if (code === 0 || code === 1) {
|
|
15607
|
-
|
|
16771
|
+
resolve8({
|
|
15608
16772
|
files: sortAccumulators(files),
|
|
15609
16773
|
totalMatchCount,
|
|
15610
16774
|
hasMoreFiles
|
|
@@ -15627,7 +16791,7 @@ async function searchWithNode(rootPath, query, maxFiles) {
|
|
|
15627
16791
|
const filteredEntries = entries.filter((entry) => filter(entry.name));
|
|
15628
16792
|
filteredEntries.sort((a, b) => a.name.localeCompare(b.name));
|
|
15629
16793
|
for (const entry of filteredEntries) {
|
|
15630
|
-
const fullPath =
|
|
16794
|
+
const fullPath = join15(dirPath, entry.name);
|
|
15631
16795
|
if (entry.isDirectory()) {
|
|
15632
16796
|
await walk(fullPath);
|
|
15633
16797
|
continue;
|
|
@@ -15635,11 +16799,11 @@ async function searchWithNode(rootPath, query, maxFiles) {
|
|
|
15635
16799
|
if (!entry.isFile()) {
|
|
15636
16800
|
continue;
|
|
15637
16801
|
}
|
|
15638
|
-
const fileStat = await
|
|
16802
|
+
const fileStat = await stat10(fullPath);
|
|
15639
16803
|
if (fileStat.size > FALLBACK_MAX_FILE_BYTES) {
|
|
15640
16804
|
continue;
|
|
15641
16805
|
}
|
|
15642
|
-
const buffer = await
|
|
16806
|
+
const buffer = await readFile7(fullPath);
|
|
15643
16807
|
if (isBinaryFile(buffer)) {
|
|
15644
16808
|
continue;
|
|
15645
16809
|
}
|
|
@@ -15750,10 +16914,10 @@ var init_content_search = __esm({
|
|
|
15750
16914
|
});
|
|
15751
16915
|
|
|
15752
16916
|
// packages/server/src/fs/tree.ts
|
|
15753
|
-
import { readdir as readdir5, stat as
|
|
15754
|
-
import { join as
|
|
16917
|
+
import { readdir as readdir5, stat as stat11 } from "fs/promises";
|
|
16918
|
+
import { join as join16, relative as relative4 } from "path";
|
|
15755
16919
|
async function readTree(rootPath, subdir) {
|
|
15756
|
-
const targetPath = subdir ?
|
|
16920
|
+
const targetPath = subdir ? join16(rootPath, subdir) : rootPath;
|
|
15757
16921
|
const filter = createTreeVisibilityFilter();
|
|
15758
16922
|
const entries = await readdir5(targetPath, { withFileTypes: true });
|
|
15759
16923
|
const nodes = [];
|
|
@@ -15761,7 +16925,7 @@ async function readTree(rootPath, subdir) {
|
|
|
15761
16925
|
if (!filter(entry.name)) {
|
|
15762
16926
|
continue;
|
|
15763
16927
|
}
|
|
15764
|
-
const fullPath =
|
|
16928
|
+
const fullPath = join16(targetPath, entry.name);
|
|
15765
16929
|
const relPath = relative4(rootPath, fullPath);
|
|
15766
16930
|
if (entry.isDirectory()) {
|
|
15767
16931
|
nodes.push({
|
|
@@ -15772,7 +16936,7 @@ async function readTree(rootPath, subdir) {
|
|
|
15772
16936
|
// Not loaded yet - client will request on expand
|
|
15773
16937
|
});
|
|
15774
16938
|
} else if (entry.isFile()) {
|
|
15775
|
-
const stats = await
|
|
16939
|
+
const stats = await stat11(fullPath);
|
|
15776
16940
|
nodes.push({
|
|
15777
16941
|
name: entry.name,
|
|
15778
16942
|
path: relPath,
|
|
@@ -15805,7 +16969,7 @@ async function searchFiles(rootPath, query, limit = 10) {
|
|
|
15805
16969
|
const filteredEntries = entries.filter((entry) => filter(entry.name));
|
|
15806
16970
|
filteredEntries.sort((a, b) => a.name.localeCompare(b.name));
|
|
15807
16971
|
for (const entry of filteredEntries) {
|
|
15808
|
-
const fullPath =
|
|
16972
|
+
const fullPath = join16(dirPath, entry.name);
|
|
15809
16973
|
const relPath = relative4(rootPath, fullPath);
|
|
15810
16974
|
if (entry.isDirectory()) {
|
|
15811
16975
|
await walk(fullPath);
|
|
@@ -15841,7 +17005,7 @@ async function searchFiles(rootPath, query, limit = 10) {
|
|
|
15841
17005
|
}
|
|
15842
17006
|
return a.path.toLowerCase().localeCompare(b.path.toLowerCase());
|
|
15843
17007
|
}).slice(0, limit)) {
|
|
15844
|
-
const stats = await
|
|
17008
|
+
const stats = await stat11(match.fullPath);
|
|
15845
17009
|
files.push({
|
|
15846
17010
|
name: match.name,
|
|
15847
17011
|
path: match.path,
|
|
@@ -15921,7 +17085,7 @@ var init_tree = __esm({
|
|
|
15921
17085
|
});
|
|
15922
17086
|
|
|
15923
17087
|
// packages/server/src/commands/file.ts
|
|
15924
|
-
import { z as
|
|
17088
|
+
import { z as z16 } from "zod";
|
|
15925
17089
|
var init_file = __esm({
|
|
15926
17090
|
"packages/server/src/commands/file.ts"() {
|
|
15927
17091
|
"use strict";
|
|
@@ -15931,9 +17095,9 @@ var init_file = __esm({
|
|
|
15931
17095
|
init_dispatch();
|
|
15932
17096
|
registerCommand(
|
|
15933
17097
|
"file.readTree",
|
|
15934
|
-
|
|
15935
|
-
workspaceId:
|
|
15936
|
-
subPath:
|
|
17098
|
+
z16.object({
|
|
17099
|
+
workspaceId: z16.string(),
|
|
17100
|
+
subPath: z16.string().optional()
|
|
15937
17101
|
}),
|
|
15938
17102
|
async (args, ctx) => {
|
|
15939
17103
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -15945,10 +17109,10 @@ var init_file = __esm({
|
|
|
15945
17109
|
);
|
|
15946
17110
|
registerCommand(
|
|
15947
17111
|
"file.search",
|
|
15948
|
-
|
|
15949
|
-
workspaceId:
|
|
15950
|
-
query:
|
|
15951
|
-
limit:
|
|
17112
|
+
z16.object({
|
|
17113
|
+
workspaceId: z16.string(),
|
|
17114
|
+
query: z16.string(),
|
|
17115
|
+
limit: z16.number().int().positive().max(50).optional()
|
|
15952
17116
|
}),
|
|
15953
17117
|
async (args, ctx) => {
|
|
15954
17118
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -15960,11 +17124,11 @@ var init_file = __esm({
|
|
|
15960
17124
|
);
|
|
15961
17125
|
registerCommand(
|
|
15962
17126
|
"file.searchContent",
|
|
15963
|
-
|
|
15964
|
-
workspaceId:
|
|
15965
|
-
query:
|
|
15966
|
-
maxFiles:
|
|
15967
|
-
maxMatchesPerFile:
|
|
17127
|
+
z16.object({
|
|
17128
|
+
workspaceId: z16.string(),
|
|
17129
|
+
query: z16.string(),
|
|
17130
|
+
maxFiles: z16.number().int().positive().max(100),
|
|
17131
|
+
maxMatchesPerFile: z16.number().int().positive().max(100)
|
|
15968
17132
|
}),
|
|
15969
17133
|
async (args, ctx) => {
|
|
15970
17134
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -15980,9 +17144,9 @@ var init_file = __esm({
|
|
|
15980
17144
|
);
|
|
15981
17145
|
registerCommand(
|
|
15982
17146
|
"file.read",
|
|
15983
|
-
|
|
15984
|
-
workspaceId:
|
|
15985
|
-
path:
|
|
17147
|
+
z16.object({
|
|
17148
|
+
workspaceId: z16.string(),
|
|
17149
|
+
path: z16.string()
|
|
15986
17150
|
}),
|
|
15987
17151
|
async (args, ctx) => {
|
|
15988
17152
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -15994,9 +17158,9 @@ var init_file = __esm({
|
|
|
15994
17158
|
);
|
|
15995
17159
|
registerCommand(
|
|
15996
17160
|
"file.create",
|
|
15997
|
-
|
|
15998
|
-
workspaceId:
|
|
15999
|
-
path:
|
|
17161
|
+
z16.object({
|
|
17162
|
+
workspaceId: z16.string(),
|
|
17163
|
+
path: z16.string()
|
|
16000
17164
|
}),
|
|
16001
17165
|
async (args, ctx) => {
|
|
16002
17166
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -16014,9 +17178,9 @@ var init_file = __esm({
|
|
|
16014
17178
|
);
|
|
16015
17179
|
registerCommand(
|
|
16016
17180
|
"file.mkdir",
|
|
16017
|
-
|
|
16018
|
-
workspaceId:
|
|
16019
|
-
path:
|
|
17181
|
+
z16.object({
|
|
17182
|
+
workspaceId: z16.string(),
|
|
17183
|
+
path: z16.string()
|
|
16020
17184
|
}),
|
|
16021
17185
|
async (args, ctx) => {
|
|
16022
17186
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -16034,9 +17198,9 @@ var init_file = __esm({
|
|
|
16034
17198
|
);
|
|
16035
17199
|
registerCommand(
|
|
16036
17200
|
"file.delete",
|
|
16037
|
-
|
|
16038
|
-
workspaceId:
|
|
16039
|
-
path:
|
|
17201
|
+
z16.object({
|
|
17202
|
+
workspaceId: z16.string(),
|
|
17203
|
+
path: z16.string()
|
|
16040
17204
|
}),
|
|
16041
17205
|
async (args, ctx) => {
|
|
16042
17206
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -16054,10 +17218,10 @@ var init_file = __esm({
|
|
|
16054
17218
|
);
|
|
16055
17219
|
registerCommand(
|
|
16056
17220
|
"file.rename",
|
|
16057
|
-
|
|
16058
|
-
workspaceId:
|
|
16059
|
-
fromPath:
|
|
16060
|
-
toPath:
|
|
17221
|
+
z16.object({
|
|
17222
|
+
workspaceId: z16.string(),
|
|
17223
|
+
fromPath: z16.string(),
|
|
17224
|
+
toPath: z16.string()
|
|
16061
17225
|
}),
|
|
16062
17226
|
async (args, ctx) => {
|
|
16063
17227
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -16075,167 +17239,27 @@ var init_file = __esm({
|
|
|
16075
17239
|
);
|
|
16076
17240
|
registerCommand(
|
|
16077
17241
|
"file.write",
|
|
16078
|
-
|
|
16079
|
-
workspaceId:
|
|
16080
|
-
path:
|
|
16081
|
-
content:
|
|
16082
|
-
baseHash:
|
|
17242
|
+
z16.object({
|
|
17243
|
+
workspaceId: z16.string(),
|
|
17244
|
+
path: z16.string(),
|
|
17245
|
+
content: z16.string(),
|
|
17246
|
+
baseHash: z16.string().optional()
|
|
16083
17247
|
// For conflict detection
|
|
16084
17248
|
}),
|
|
16085
|
-
async (args, ctx) => {
|
|
16086
|
-
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
16087
|
-
if (!workspace) {
|
|
16088
|
-
throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
|
|
16089
|
-
}
|
|
16090
|
-
const result = await writeFile(workspace.path, args.path, args.content, args.baseHash);
|
|
16091
|
-
ctx.eventBus.emit({
|
|
16092
|
-
type: "fs.dirty",
|
|
16093
|
-
workspaceId: args.workspaceId,
|
|
16094
|
-
reason: "file_content"
|
|
16095
|
-
});
|
|
16096
|
-
return result;
|
|
16097
|
-
}
|
|
16098
|
-
);
|
|
16099
|
-
}
|
|
16100
|
-
});
|
|
16101
|
-
|
|
16102
|
-
// packages/server/src/git/diff.ts
|
|
16103
|
-
import { mkdtemp as mkdtemp3, readFile as readFile5, rm as rm7 } from "fs/promises";
|
|
16104
|
-
import os3 from "os";
|
|
16105
|
-
import path11 from "path";
|
|
16106
|
-
async function isTrackedPath(cwd, filePath) {
|
|
16107
|
-
try {
|
|
16108
|
-
await runGit(cwd, ["ls-files", "--error-unmatch", "--", filePath]);
|
|
16109
|
-
return true;
|
|
16110
|
-
} catch {
|
|
16111
|
-
return false;
|
|
16112
|
-
}
|
|
16113
|
-
}
|
|
16114
|
-
async function getUntrackedFileDiff(cwd, filePath) {
|
|
16115
|
-
const tempDir = await mkdtemp3(path11.join(os3.tmpdir(), "coder-studio-git-diff-"));
|
|
16116
|
-
const tempIndex = path11.join(tempDir, "index");
|
|
16117
|
-
try {
|
|
16118
|
-
try {
|
|
16119
|
-
await runGit(cwd, ["read-tree", "HEAD"], {
|
|
16120
|
-
env: { GIT_INDEX_FILE: tempIndex }
|
|
16121
|
-
});
|
|
16122
|
-
} catch (error) {
|
|
16123
|
-
if (!(error instanceof GitError)) {
|
|
16124
|
-
throw error;
|
|
16125
|
-
}
|
|
16126
|
-
await runGit(cwd, ["read-tree", "--empty"], {
|
|
16127
|
-
env: { GIT_INDEX_FILE: tempIndex }
|
|
16128
|
-
});
|
|
16129
|
-
}
|
|
16130
|
-
await runGit(cwd, ["add", "-N", "--", filePath], {
|
|
16131
|
-
env: { GIT_INDEX_FILE: tempIndex }
|
|
16132
|
-
});
|
|
16133
|
-
const result = await runGit(cwd, ["diff", "--", filePath], {
|
|
16134
|
-
env: { GIT_INDEX_FILE: tempIndex }
|
|
16135
|
-
});
|
|
16136
|
-
return result.stdout;
|
|
16137
|
-
} finally {
|
|
16138
|
-
await rm7(tempDir, { recursive: true, force: true });
|
|
16139
|
-
}
|
|
16140
|
-
}
|
|
16141
|
-
async function pathExists(cwd, filePath) {
|
|
16142
|
-
try {
|
|
16143
|
-
await readFile5(resolveSafe(cwd, filePath));
|
|
16144
|
-
return true;
|
|
16145
|
-
} catch {
|
|
16146
|
-
return false;
|
|
16147
|
-
}
|
|
16148
|
-
}
|
|
16149
|
-
async function readTextAtRevision(cwd, revision, filePath) {
|
|
16150
|
-
if (revision === "WORKTREE") {
|
|
16151
|
-
return readFile5(resolveSafe(cwd, filePath), "utf-8");
|
|
16152
|
-
}
|
|
16153
|
-
try {
|
|
16154
|
-
const gitSpec = revision === "INDEX" ? `:${filePath}` : `${revision}:${filePath}`;
|
|
16155
|
-
const result = await runGit(cwd, ["show", gitSpec]);
|
|
16156
|
-
return result.stdout;
|
|
16157
|
-
} catch {
|
|
16158
|
-
return "";
|
|
16159
|
-
}
|
|
16160
|
-
}
|
|
16161
|
-
async function deriveFileDiffStatus(cwd, filePath, staged) {
|
|
16162
|
-
const tracked = await isTrackedPath(cwd, filePath);
|
|
16163
|
-
const existsOnDisk = await pathExists(cwd, filePath);
|
|
16164
|
-
if (!staged && !tracked) {
|
|
16165
|
-
return "added";
|
|
16166
|
-
}
|
|
16167
|
-
if (staged) {
|
|
16168
|
-
try {
|
|
16169
|
-
await runGit(cwd, ["cat-file", "-e", `HEAD:${filePath}`]);
|
|
16170
|
-
return existsOnDisk ? "modified" : "deleted";
|
|
16171
|
-
} catch {
|
|
16172
|
-
return "added";
|
|
16173
|
-
}
|
|
16174
|
-
}
|
|
16175
|
-
return existsOnDisk ? "modified" : "deleted";
|
|
16176
|
-
}
|
|
16177
|
-
async function buildTextDiffResult(cwd, filePath, staged, diff) {
|
|
16178
|
-
const status = await deriveFileDiffStatus(cwd, filePath, staged);
|
|
16179
|
-
if (status === "added") {
|
|
16180
|
-
return {
|
|
16181
|
-
diff,
|
|
16182
|
-
renderAs: "text",
|
|
16183
|
-
status,
|
|
16184
|
-
originalContent: "",
|
|
16185
|
-
modifiedContent: await readTextAtRevision(cwd, staged ? "INDEX" : "WORKTREE", filePath)
|
|
16186
|
-
};
|
|
16187
|
-
}
|
|
16188
|
-
if (status === "deleted") {
|
|
16189
|
-
return {
|
|
16190
|
-
diff,
|
|
16191
|
-
renderAs: "text",
|
|
16192
|
-
status,
|
|
16193
|
-
originalContent: await readTextAtRevision(cwd, staged ? "HEAD" : "INDEX", filePath),
|
|
16194
|
-
modifiedContent: ""
|
|
16195
|
-
};
|
|
16196
|
-
}
|
|
16197
|
-
return {
|
|
16198
|
-
diff,
|
|
16199
|
-
renderAs: "text",
|
|
16200
|
-
status,
|
|
16201
|
-
originalContent: await readTextAtRevision(cwd, staged ? "HEAD" : "INDEX", filePath),
|
|
16202
|
-
modifiedContent: await readTextAtRevision(cwd, staged ? "INDEX" : "WORKTREE", filePath)
|
|
16203
|
-
};
|
|
16204
|
-
}
|
|
16205
|
-
async function getFileDiff(cwd, path14, staged = false) {
|
|
16206
|
-
const imageType = getImageTypeInfo(path14);
|
|
16207
|
-
if (!staged && !await isTrackedPath(cwd, path14)) {
|
|
16208
|
-
const diff = await getUntrackedFileDiff(cwd, path14);
|
|
16209
|
-
if (imageType) {
|
|
16210
|
-
return {
|
|
16211
|
-
diff,
|
|
16212
|
-
renderAs: "image",
|
|
16213
|
-
status: "added",
|
|
16214
|
-
originalRevision: "HEAD",
|
|
16215
|
-
modifiedRevision: "WORKTREE"
|
|
16216
|
-
};
|
|
16217
|
-
}
|
|
16218
|
-
return buildTextDiffResult(cwd, path14, staged, diff);
|
|
16219
|
-
}
|
|
16220
|
-
const args = staged ? ["diff", "--staged", "--", path14] : ["diff", "--", path14];
|
|
16221
|
-
const result = await runGit(cwd, args);
|
|
16222
|
-
if (imageType && /Binary files .* differ/.test(result.stdout)) {
|
|
16223
|
-
return {
|
|
16224
|
-
diff: result.stdout,
|
|
16225
|
-
renderAs: "image",
|
|
16226
|
-
status: await deriveFileDiffStatus(cwd, path14, staged),
|
|
16227
|
-
originalRevision: staged ? "HEAD" : "INDEX",
|
|
16228
|
-
modifiedRevision: staged ? "INDEX" : "WORKTREE"
|
|
16229
|
-
};
|
|
16230
|
-
}
|
|
16231
|
-
return buildTextDiffResult(cwd, path14, staged, result.stdout);
|
|
16232
|
-
}
|
|
16233
|
-
var init_diff = __esm({
|
|
16234
|
-
"packages/server/src/git/diff.ts"() {
|
|
16235
|
-
"use strict";
|
|
16236
|
-
init_file_io();
|
|
16237
|
-
init_image();
|
|
16238
|
-
init_cli();
|
|
17249
|
+
async (args, ctx) => {
|
|
17250
|
+
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
17251
|
+
if (!workspace) {
|
|
17252
|
+
throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
|
|
17253
|
+
}
|
|
17254
|
+
const result = await writeFile(workspace.path, args.path, args.content, args.baseHash);
|
|
17255
|
+
ctx.eventBus.emit({
|
|
17256
|
+
type: "fs.dirty",
|
|
17257
|
+
workspaceId: args.workspaceId,
|
|
17258
|
+
reason: "file_content"
|
|
17259
|
+
});
|
|
17260
|
+
return result;
|
|
17261
|
+
}
|
|
17262
|
+
);
|
|
16239
17263
|
}
|
|
16240
17264
|
});
|
|
16241
17265
|
|
|
@@ -16256,7 +17280,7 @@ var init_git_events = __esm({
|
|
|
16256
17280
|
});
|
|
16257
17281
|
|
|
16258
17282
|
// packages/server/src/commands/git.ts
|
|
16259
|
-
import { z as
|
|
17283
|
+
import { z as z17 } from "zod";
|
|
16260
17284
|
async function runGitNetworkOperation(ctx, workspaceId, op) {
|
|
16261
17285
|
if (!ctx.autoFetch?.runExclusive) {
|
|
16262
17286
|
return op();
|
|
@@ -16271,16 +17295,16 @@ var init_git2 = __esm({
|
|
|
16271
17295
|
init_diff();
|
|
16272
17296
|
init_dispatch();
|
|
16273
17297
|
init_git_events();
|
|
16274
|
-
gitHttpAuthSchema =
|
|
16275
|
-
username:
|
|
16276
|
-
password:
|
|
17298
|
+
gitHttpAuthSchema = z17.object({
|
|
17299
|
+
username: z17.string(),
|
|
17300
|
+
password: z17.string()
|
|
16277
17301
|
});
|
|
16278
|
-
gitCommitRevisionSchema =
|
|
17302
|
+
gitCommitRevisionSchema = z17.string().regex(/^[0-9a-fA-F]{7,64}$/, "Invalid git commit revision");
|
|
16279
17303
|
GIT_BACKGROUND_FETCH_TIMEOUT_MS = 30 * 1e3;
|
|
16280
17304
|
registerCommand(
|
|
16281
17305
|
"git.status",
|
|
16282
|
-
|
|
16283
|
-
workspaceId:
|
|
17306
|
+
z17.object({
|
|
17307
|
+
workspaceId: z17.string()
|
|
16284
17308
|
}),
|
|
16285
17309
|
async (args, ctx) => {
|
|
16286
17310
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -16292,9 +17316,9 @@ var init_git2 = __esm({
|
|
|
16292
17316
|
);
|
|
16293
17317
|
registerCommand(
|
|
16294
17318
|
"git.stage",
|
|
16295
|
-
|
|
16296
|
-
workspaceId:
|
|
16297
|
-
paths:
|
|
17319
|
+
z17.object({
|
|
17320
|
+
workspaceId: z17.string(),
|
|
17321
|
+
paths: z17.array(z17.string())
|
|
16298
17322
|
}),
|
|
16299
17323
|
async (args, ctx) => {
|
|
16300
17324
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -16308,10 +17332,10 @@ var init_git2 = __esm({
|
|
|
16308
17332
|
);
|
|
16309
17333
|
registerCommand(
|
|
16310
17334
|
"git.diff",
|
|
16311
|
-
|
|
16312
|
-
workspaceId:
|
|
16313
|
-
path:
|
|
16314
|
-
staged:
|
|
17335
|
+
z17.object({
|
|
17336
|
+
workspaceId: z17.string(),
|
|
17337
|
+
path: z17.string(),
|
|
17338
|
+
staged: z17.boolean().optional()
|
|
16315
17339
|
}),
|
|
16316
17340
|
async (args, ctx) => {
|
|
16317
17341
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -16323,9 +17347,9 @@ var init_git2 = __esm({
|
|
|
16323
17347
|
);
|
|
16324
17348
|
registerCommand(
|
|
16325
17349
|
"git.log",
|
|
16326
|
-
|
|
16327
|
-
workspaceId:
|
|
16328
|
-
limit:
|
|
17350
|
+
z17.object({
|
|
17351
|
+
workspaceId: z17.string(),
|
|
17352
|
+
limit: z17.number().int().min(1).max(50).optional()
|
|
16329
17353
|
}),
|
|
16330
17354
|
async (args, ctx) => {
|
|
16331
17355
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -16339,8 +17363,8 @@ var init_git2 = __esm({
|
|
|
16339
17363
|
);
|
|
16340
17364
|
registerCommand(
|
|
16341
17365
|
"git.show",
|
|
16342
|
-
|
|
16343
|
-
workspaceId:
|
|
17366
|
+
z17.object({
|
|
17367
|
+
workspaceId: z17.string(),
|
|
16344
17368
|
sha: gitCommitRevisionSchema
|
|
16345
17369
|
}),
|
|
16346
17370
|
async (args, ctx) => {
|
|
@@ -16355,9 +17379,9 @@ var init_git2 = __esm({
|
|
|
16355
17379
|
);
|
|
16356
17380
|
registerCommand(
|
|
16357
17381
|
"git.unstage",
|
|
16358
|
-
|
|
16359
|
-
workspaceId:
|
|
16360
|
-
paths:
|
|
17382
|
+
z17.object({
|
|
17383
|
+
workspaceId: z17.string(),
|
|
17384
|
+
paths: z17.array(z17.string())
|
|
16361
17385
|
}),
|
|
16362
17386
|
async (args, ctx) => {
|
|
16363
17387
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -16371,9 +17395,9 @@ var init_git2 = __esm({
|
|
|
16371
17395
|
);
|
|
16372
17396
|
registerCommand(
|
|
16373
17397
|
"git.discard",
|
|
16374
|
-
|
|
16375
|
-
workspaceId:
|
|
16376
|
-
paths:
|
|
17398
|
+
z17.object({
|
|
17399
|
+
workspaceId: z17.string(),
|
|
17400
|
+
paths: z17.array(z17.string())
|
|
16377
17401
|
}),
|
|
16378
17402
|
async (args, ctx) => {
|
|
16379
17403
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -16389,9 +17413,9 @@ var init_git2 = __esm({
|
|
|
16389
17413
|
);
|
|
16390
17414
|
registerCommand(
|
|
16391
17415
|
"git.commit",
|
|
16392
|
-
|
|
16393
|
-
workspaceId:
|
|
16394
|
-
message:
|
|
17416
|
+
z17.object({
|
|
17417
|
+
workspaceId: z17.string(),
|
|
17418
|
+
message: z17.string()
|
|
16395
17419
|
}),
|
|
16396
17420
|
async (args, ctx) => {
|
|
16397
17421
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -16408,11 +17432,11 @@ var init_git2 = __esm({
|
|
|
16408
17432
|
);
|
|
16409
17433
|
registerCommand(
|
|
16410
17434
|
"git.push",
|
|
16411
|
-
|
|
16412
|
-
workspaceId:
|
|
16413
|
-
remote:
|
|
16414
|
-
branch:
|
|
16415
|
-
force:
|
|
17435
|
+
z17.object({
|
|
17436
|
+
workspaceId: z17.string(),
|
|
17437
|
+
remote: z17.string().optional(),
|
|
17438
|
+
branch: z17.string().optional(),
|
|
17439
|
+
force: z17.boolean().optional(),
|
|
16416
17440
|
auth: gitHttpAuthSchema.optional()
|
|
16417
17441
|
}),
|
|
16418
17442
|
async (args, ctx) => {
|
|
@@ -16438,128 +17462,737 @@ var init_git2 = __esm({
|
|
|
16438
17462
|
}
|
|
16439
17463
|
);
|
|
16440
17464
|
registerCommand(
|
|
16441
|
-
"git.pull",
|
|
16442
|
-
|
|
16443
|
-
workspaceId:
|
|
16444
|
-
remote:
|
|
16445
|
-
branch:
|
|
16446
|
-
auth: gitHttpAuthSchema.optional()
|
|
17465
|
+
"git.pull",
|
|
17466
|
+
z17.object({
|
|
17467
|
+
workspaceId: z17.string(),
|
|
17468
|
+
remote: z17.string().optional(),
|
|
17469
|
+
branch: z17.string().optional(),
|
|
17470
|
+
auth: gitHttpAuthSchema.optional()
|
|
17471
|
+
}),
|
|
17472
|
+
async (args, ctx) => {
|
|
17473
|
+
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
17474
|
+
if (!workspace) {
|
|
17475
|
+
throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
|
|
17476
|
+
}
|
|
17477
|
+
const result = await runGitNetworkOperation(
|
|
17478
|
+
ctx,
|
|
17479
|
+
args.workspaceId,
|
|
17480
|
+
() => runGitPull(workspace.path, {
|
|
17481
|
+
remote: args.remote,
|
|
17482
|
+
branch: args.branch,
|
|
17483
|
+
auth: args.auth
|
|
17484
|
+
})
|
|
17485
|
+
);
|
|
17486
|
+
ctx.workspaceMgr.recordFetch(args.workspaceId);
|
|
17487
|
+
emitGitStateChanged(ctx, args.workspaceId, {
|
|
17488
|
+
treeChanged: true,
|
|
17489
|
+
branchChanged: true,
|
|
17490
|
+
worktreeChanged: true
|
|
17491
|
+
});
|
|
17492
|
+
return result;
|
|
17493
|
+
}
|
|
17494
|
+
);
|
|
17495
|
+
registerCommand(
|
|
17496
|
+
"git.fetch",
|
|
17497
|
+
z17.object({
|
|
17498
|
+
workspaceId: z17.string(),
|
|
17499
|
+
remote: z17.string().optional(),
|
|
17500
|
+
prune: z17.boolean().optional(),
|
|
17501
|
+
auth: gitHttpAuthSchema.optional(),
|
|
17502
|
+
background: z17.boolean().optional()
|
|
17503
|
+
}),
|
|
17504
|
+
async (args, ctx, clientId) => {
|
|
17505
|
+
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
17506
|
+
if (!workspace) {
|
|
17507
|
+
throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
|
|
17508
|
+
}
|
|
17509
|
+
try {
|
|
17510
|
+
const isInternalBackgroundFetch = args.background === true && !clientId;
|
|
17511
|
+
const runFetch = () => runGitFetch(workspace.path, {
|
|
17512
|
+
remote: args.remote,
|
|
17513
|
+
prune: args.prune,
|
|
17514
|
+
auth: args.auth,
|
|
17515
|
+
timeoutMs: args.background ? GIT_BACKGROUND_FETCH_TIMEOUT_MS : void 0
|
|
17516
|
+
});
|
|
17517
|
+
const result = isInternalBackgroundFetch ? await runFetch() : await runGitNetworkOperation(ctx, args.workspaceId, runFetch);
|
|
17518
|
+
ctx.workspaceMgr.recordFetch(args.workspaceId);
|
|
17519
|
+
emitGitStateChanged(ctx, args.workspaceId, { branchChanged: true });
|
|
17520
|
+
return result;
|
|
17521
|
+
} catch (err) {
|
|
17522
|
+
if (args.background && err instanceof GitAuthError) {
|
|
17523
|
+
return { success: false, message: err.message, updatedRefs: [] };
|
|
17524
|
+
}
|
|
17525
|
+
throw err;
|
|
17526
|
+
}
|
|
17527
|
+
}
|
|
17528
|
+
);
|
|
17529
|
+
registerCommand(
|
|
17530
|
+
"git.checkout",
|
|
17531
|
+
z17.object({
|
|
17532
|
+
workspaceId: z17.string(),
|
|
17533
|
+
ref: z17.string(),
|
|
17534
|
+
createBranch: z17.boolean().optional()
|
|
17535
|
+
}),
|
|
17536
|
+
async (args, ctx) => {
|
|
17537
|
+
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
17538
|
+
if (!workspace) {
|
|
17539
|
+
throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
|
|
17540
|
+
}
|
|
17541
|
+
const result = await runGitCheckout(workspace.path, args.ref, {
|
|
17542
|
+
createBranch: args.createBranch
|
|
17543
|
+
});
|
|
17544
|
+
if (result.success) {
|
|
17545
|
+
emitGitStateChanged(ctx, args.workspaceId, {
|
|
17546
|
+
treeChanged: true,
|
|
17547
|
+
branchChanged: true,
|
|
17548
|
+
worktreeChanged: true
|
|
17549
|
+
});
|
|
17550
|
+
}
|
|
17551
|
+
return result;
|
|
17552
|
+
}
|
|
17553
|
+
);
|
|
17554
|
+
registerCommand(
|
|
17555
|
+
"git.branch",
|
|
17556
|
+
z17.object({
|
|
17557
|
+
workspaceId: z17.string(),
|
|
17558
|
+
name: z17.string(),
|
|
17559
|
+
startPoint: z17.string().optional()
|
|
17560
|
+
}),
|
|
17561
|
+
async (args, ctx) => {
|
|
17562
|
+
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
17563
|
+
if (!workspace) {
|
|
17564
|
+
throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
|
|
17565
|
+
}
|
|
17566
|
+
const result = await runGitCreateBranch(workspace.path, args.name, {
|
|
17567
|
+
startPoint: args.startPoint
|
|
17568
|
+
});
|
|
17569
|
+
emitGitStateChanged(ctx, args.workspaceId, {
|
|
17570
|
+
branchChanged: true,
|
|
17571
|
+
worktreeChanged: true
|
|
17572
|
+
});
|
|
17573
|
+
return result;
|
|
17574
|
+
}
|
|
17575
|
+
);
|
|
17576
|
+
registerCommand(
|
|
17577
|
+
"git.branches",
|
|
17578
|
+
z17.object({
|
|
17579
|
+
workspaceId: z17.string()
|
|
17580
|
+
}),
|
|
17581
|
+
async (args, ctx) => {
|
|
17582
|
+
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
17583
|
+
if (!workspace) {
|
|
17584
|
+
throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
|
|
17585
|
+
}
|
|
17586
|
+
return runGitListBranches(workspace.path);
|
|
17587
|
+
}
|
|
17588
|
+
);
|
|
17589
|
+
}
|
|
17590
|
+
});
|
|
17591
|
+
|
|
17592
|
+
// packages/server/src/agent-instructions/generator.ts
|
|
17593
|
+
function buildAgentInstructionsMarkdown(summary) {
|
|
17594
|
+
const lines = ["# Agent Instructions", ""];
|
|
17595
|
+
pushSection(lines, "Project Overview", buildProjectOverview(summary));
|
|
17596
|
+
pushSection(lines, "Development Commands", buildDevelopmentCommands(summary));
|
|
17597
|
+
pushSection(lines, "Working Rules", [...WORKING_RULES.map((rule) => `- ${rule}`)]);
|
|
17598
|
+
pushSection(
|
|
17599
|
+
lines,
|
|
17600
|
+
"Review Expectations",
|
|
17601
|
+
REVIEW_EXPECTATIONS.map((rule) => `- ${rule}`)
|
|
17602
|
+
);
|
|
17603
|
+
pushSection(
|
|
17604
|
+
lines,
|
|
17605
|
+
"Provider Notes",
|
|
17606
|
+
PROVIDER_NOTES.map((note) => `- ${note}`)
|
|
17607
|
+
);
|
|
17608
|
+
return lines.join("\n");
|
|
17609
|
+
}
|
|
17610
|
+
function buildProjectOverview(summary) {
|
|
17611
|
+
const lines = [];
|
|
17612
|
+
if (summary.git.isRepo) {
|
|
17613
|
+
if (summary.git.branch) {
|
|
17614
|
+
lines.push(`- Git branch: ${summary.git.branch}`);
|
|
17615
|
+
} else {
|
|
17616
|
+
lines.push("- Git repository: yes");
|
|
17617
|
+
}
|
|
17618
|
+
} else {
|
|
17619
|
+
lines.push("- Git repository: no");
|
|
17620
|
+
}
|
|
17621
|
+
if (summary.packageManager) {
|
|
17622
|
+
lines.push(`- Package manager: ${summary.packageManager}`);
|
|
17623
|
+
}
|
|
17624
|
+
if (summary.frameworks.length > 0) {
|
|
17625
|
+
lines.push(`- Frameworks: ${summary.frameworks.join(", ")}`);
|
|
17626
|
+
}
|
|
17627
|
+
if (summary.docs.length > 0) {
|
|
17628
|
+
lines.push(`- Docs: ${summary.docs.map((doc) => doc.path).join(", ")}`);
|
|
17629
|
+
}
|
|
17630
|
+
lines.push(
|
|
17631
|
+
`- ${summary.agentInstructions.path}: ${summary.agentInstructions.exists ? "exists" : "missing"}`
|
|
17632
|
+
);
|
|
17633
|
+
return lines;
|
|
17634
|
+
}
|
|
17635
|
+
function buildDevelopmentCommands(summary) {
|
|
17636
|
+
const lines = [];
|
|
17637
|
+
const commandLabels = {
|
|
17638
|
+
dev: "Dev",
|
|
17639
|
+
test: "Test",
|
|
17640
|
+
build: "Build",
|
|
17641
|
+
lint: "Lint"
|
|
17642
|
+
};
|
|
17643
|
+
for (const key of ["dev", "test", "build", "lint"]) {
|
|
17644
|
+
const command = summary.recommendedCommands.find((item) => item.key === key)?.command;
|
|
17645
|
+
if (!command) {
|
|
17646
|
+
continue;
|
|
17647
|
+
}
|
|
17648
|
+
lines.push(`- ${commandLabels[key]}: \`${command}\``);
|
|
17649
|
+
}
|
|
17650
|
+
return lines;
|
|
17651
|
+
}
|
|
17652
|
+
function pushSection(lines, heading, body) {
|
|
17653
|
+
lines.push(`## ${heading}`, "");
|
|
17654
|
+
lines.push(...body);
|
|
17655
|
+
lines.push("");
|
|
17656
|
+
}
|
|
17657
|
+
var WORKING_RULES, REVIEW_EXPECTATIONS, PROVIDER_NOTES;
|
|
17658
|
+
var init_generator = __esm({
|
|
17659
|
+
"packages/server/src/agent-instructions/generator.ts"() {
|
|
17660
|
+
"use strict";
|
|
17661
|
+
WORKING_RULES = [
|
|
17662
|
+
"Keep changes focused on the requested task.",
|
|
17663
|
+
"Do not revert user changes unless explicitly asked.",
|
|
17664
|
+
"Prefer the project's existing patterns.",
|
|
17665
|
+
"Run the relevant verification command before reporting completion."
|
|
17666
|
+
];
|
|
17667
|
+
REVIEW_EXPECTATIONS = [
|
|
17668
|
+
"Summarize changed files.",
|
|
17669
|
+
"Report verification commands and results.",
|
|
17670
|
+
"Call out risks, skipped tests, and assumptions."
|
|
17671
|
+
];
|
|
17672
|
+
PROVIDER_NOTES = [
|
|
17673
|
+
"Claude Code: use the project rules above.",
|
|
17674
|
+
"Codex: use the project rules above."
|
|
17675
|
+
];
|
|
17676
|
+
}
|
|
17677
|
+
});
|
|
17678
|
+
|
|
17679
|
+
// packages/server/src/agent-instructions/health.ts
|
|
17680
|
+
function evaluateAgentInstructionsMarkdown(content) {
|
|
17681
|
+
if (!content.trim()) {
|
|
17682
|
+
return {
|
|
17683
|
+
path: AGENT_INSTRUCTIONS_RELATIVE_PATH,
|
|
17684
|
+
exists: false,
|
|
17685
|
+
status: "missing",
|
|
17686
|
+
checks: {
|
|
17687
|
+
projectOverview: false,
|
|
17688
|
+
developmentCommands: false,
|
|
17689
|
+
workingRules: false,
|
|
17690
|
+
reviewExpectations: false,
|
|
17691
|
+
safetyRules: false,
|
|
17692
|
+
providerNotes: false
|
|
17693
|
+
},
|
|
17694
|
+
issues: [
|
|
17695
|
+
{
|
|
17696
|
+
code: "missing_document",
|
|
17697
|
+
message: `${AGENT_INSTRUCTIONS_RELATIVE_PATH} is missing`
|
|
17698
|
+
}
|
|
17699
|
+
]
|
|
17700
|
+
};
|
|
17701
|
+
}
|
|
17702
|
+
const sections = indexSections(content);
|
|
17703
|
+
const projectOverview = sections.has("Project Overview");
|
|
17704
|
+
const developmentCommands = hasAnyBullet(sections.get("Development Commands"));
|
|
17705
|
+
const workingRulesSection = sections.get("Working Rules");
|
|
17706
|
+
const reviewExpectationsSection = sections.get("Review Expectations");
|
|
17707
|
+
const providerNotesSection = sections.get("Provider Notes");
|
|
17708
|
+
const workingRules = hasAnyBullet(workingRulesSection);
|
|
17709
|
+
const reviewExpectations = hasAnyBullet(reviewExpectationsSection) && REQUIRED_REVIEW_EXPECTATIONS.every(
|
|
17710
|
+
(rule) => reviewExpectationsSection?.some((line) => line.includes(rule))
|
|
17711
|
+
);
|
|
17712
|
+
const providerNotes = hasAnyBullet(providerNotesSection) && PROVIDER_NOTE_MARKERS.some(
|
|
17713
|
+
(marker) => providerNotesSection?.some((line) => line.includes(marker))
|
|
17714
|
+
);
|
|
17715
|
+
const safetyRules = REQUIRED_WORKING_RULES.every(
|
|
17716
|
+
(rule) => workingRulesSection?.some((line) => line.includes(rule))
|
|
17717
|
+
);
|
|
17718
|
+
const issues = [];
|
|
17719
|
+
if (!projectOverview) {
|
|
17720
|
+
issues.push({
|
|
17721
|
+
code: "missing_project_overview",
|
|
17722
|
+
message: "Project Overview section is missing"
|
|
17723
|
+
});
|
|
17724
|
+
}
|
|
17725
|
+
if (!developmentCommands) {
|
|
17726
|
+
issues.push({
|
|
17727
|
+
code: "missing_development_commands",
|
|
17728
|
+
message: "Development Commands section is missing"
|
|
17729
|
+
});
|
|
17730
|
+
}
|
|
17731
|
+
if (!workingRules) {
|
|
17732
|
+
issues.push({
|
|
17733
|
+
code: "missing_working_rules",
|
|
17734
|
+
message: "Working Rules section is missing"
|
|
17735
|
+
});
|
|
17736
|
+
}
|
|
17737
|
+
if (!reviewExpectations) {
|
|
17738
|
+
issues.push({
|
|
17739
|
+
code: "missing_review_expectations",
|
|
17740
|
+
message: "Review Expectations section is missing"
|
|
17741
|
+
});
|
|
17742
|
+
}
|
|
17743
|
+
if (!safetyRules) {
|
|
17744
|
+
issues.push({
|
|
17745
|
+
code: "missing_safety_rules",
|
|
17746
|
+
message: "Working rules do not include the required safety rules"
|
|
17747
|
+
});
|
|
17748
|
+
}
|
|
17749
|
+
if (!providerNotes) {
|
|
17750
|
+
issues.push({
|
|
17751
|
+
code: "missing_provider_notes",
|
|
17752
|
+
message: "Provider Notes section is missing"
|
|
17753
|
+
});
|
|
17754
|
+
}
|
|
17755
|
+
const status = issues.length === 0 ? "healthy" : "warning";
|
|
17756
|
+
return {
|
|
17757
|
+
path: AGENT_INSTRUCTIONS_RELATIVE_PATH,
|
|
17758
|
+
exists: true,
|
|
17759
|
+
status,
|
|
17760
|
+
checks: {
|
|
17761
|
+
projectOverview,
|
|
17762
|
+
developmentCommands,
|
|
17763
|
+
workingRules,
|
|
17764
|
+
reviewExpectations,
|
|
17765
|
+
safetyRules,
|
|
17766
|
+
providerNotes
|
|
17767
|
+
},
|
|
17768
|
+
issues
|
|
17769
|
+
};
|
|
17770
|
+
}
|
|
17771
|
+
function indexSections(content) {
|
|
17772
|
+
const sections = /* @__PURE__ */ new Map();
|
|
17773
|
+
const lines = content.split(/\r?\n/);
|
|
17774
|
+
let currentHeading = null;
|
|
17775
|
+
for (const line of lines) {
|
|
17776
|
+
const heading = line.match(/^##\s+(.+?)\s*$/)?.[1];
|
|
17777
|
+
if (heading) {
|
|
17778
|
+
currentHeading = heading;
|
|
17779
|
+
if (!sections.has(heading)) {
|
|
17780
|
+
sections.set(heading, []);
|
|
17781
|
+
}
|
|
17782
|
+
continue;
|
|
17783
|
+
}
|
|
17784
|
+
if (currentHeading) {
|
|
17785
|
+
sections.get(currentHeading)?.push(line);
|
|
17786
|
+
}
|
|
17787
|
+
}
|
|
17788
|
+
return sections;
|
|
17789
|
+
}
|
|
17790
|
+
function hasAnyBullet(lines) {
|
|
17791
|
+
return Boolean(lines?.some((line) => line.trimStart().startsWith("- ")));
|
|
17792
|
+
}
|
|
17793
|
+
var REQUIRED_WORKING_RULES, REQUIRED_REVIEW_EXPECTATIONS, PROVIDER_NOTE_MARKERS;
|
|
17794
|
+
var init_health = __esm({
|
|
17795
|
+
"packages/server/src/agent-instructions/health.ts"() {
|
|
17796
|
+
"use strict";
|
|
17797
|
+
init_workspace_state();
|
|
17798
|
+
REQUIRED_WORKING_RULES = [
|
|
17799
|
+
"Keep changes focused on the requested task.",
|
|
17800
|
+
"Do not revert user changes unless explicitly asked.",
|
|
17801
|
+
"Prefer the project's existing patterns.",
|
|
17802
|
+
"Run the relevant verification command before reporting completion."
|
|
17803
|
+
];
|
|
17804
|
+
REQUIRED_REVIEW_EXPECTATIONS = [
|
|
17805
|
+
"Summarize changed files.",
|
|
17806
|
+
"Report verification commands and results.",
|
|
17807
|
+
"Call out risks, skipped tests, and assumptions."
|
|
17808
|
+
];
|
|
17809
|
+
PROVIDER_NOTE_MARKERS = ["Claude Code:", "Codex:"];
|
|
17810
|
+
}
|
|
17811
|
+
});
|
|
17812
|
+
|
|
17813
|
+
// packages/server/src/commands/agent-instructions.ts
|
|
17814
|
+
import { z as z18 } from "zod";
|
|
17815
|
+
async function readAgentInstructionsDocument(workspaceId, rootPath) {
|
|
17816
|
+
const path14 = AGENT_INSTRUCTIONS_RELATIVE_PATH;
|
|
17817
|
+
try {
|
|
17818
|
+
const result = await readFile(workspaceId, rootPath, path14);
|
|
17819
|
+
if (result.kind !== "text") {
|
|
17820
|
+
return {
|
|
17821
|
+
path: path14,
|
|
17822
|
+
exists: true,
|
|
17823
|
+
content: ""
|
|
17824
|
+
};
|
|
17825
|
+
}
|
|
17826
|
+
return {
|
|
17827
|
+
path: path14,
|
|
17828
|
+
exists: true,
|
|
17829
|
+
content: result.content,
|
|
17830
|
+
baseHash: result.baseHash
|
|
17831
|
+
};
|
|
17832
|
+
} catch {
|
|
17833
|
+
return {
|
|
17834
|
+
path: path14,
|
|
17835
|
+
exists: false,
|
|
17836
|
+
content: ""
|
|
17837
|
+
};
|
|
17838
|
+
}
|
|
17839
|
+
}
|
|
17840
|
+
var init_agent_instructions = __esm({
|
|
17841
|
+
"packages/server/src/commands/agent-instructions.ts"() {
|
|
17842
|
+
"use strict";
|
|
17843
|
+
init_generator();
|
|
17844
|
+
init_health();
|
|
17845
|
+
init_file_io();
|
|
17846
|
+
init_intelligence();
|
|
17847
|
+
init_workspace_state();
|
|
17848
|
+
init_dispatch();
|
|
17849
|
+
registerCommand(
|
|
17850
|
+
"agentInstructions.read",
|
|
17851
|
+
z18.object({
|
|
17852
|
+
workspaceId: z18.string()
|
|
17853
|
+
}),
|
|
17854
|
+
async (args, ctx) => {
|
|
17855
|
+
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
17856
|
+
if (!workspace) {
|
|
17857
|
+
throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
|
|
17858
|
+
}
|
|
17859
|
+
return readAgentInstructionsDocument(workspace.id, workspace.path);
|
|
17860
|
+
}
|
|
17861
|
+
);
|
|
17862
|
+
registerCommand(
|
|
17863
|
+
"agentInstructions.generate",
|
|
17864
|
+
z18.object({
|
|
17865
|
+
workspaceId: z18.string()
|
|
17866
|
+
}),
|
|
17867
|
+
async (args, ctx) => {
|
|
17868
|
+
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
17869
|
+
if (!workspace) {
|
|
17870
|
+
throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
|
|
17871
|
+
}
|
|
17872
|
+
const summary = await inspectWorkspaceIntelligence({
|
|
17873
|
+
workspaceId: workspace.id,
|
|
17874
|
+
rootPath: workspace.path
|
|
17875
|
+
});
|
|
17876
|
+
return {
|
|
17877
|
+
path: AGENT_INSTRUCTIONS_RELATIVE_PATH,
|
|
17878
|
+
exists: false,
|
|
17879
|
+
content: buildAgentInstructionsMarkdown(summary)
|
|
17880
|
+
};
|
|
17881
|
+
}
|
|
17882
|
+
);
|
|
17883
|
+
registerCommand(
|
|
17884
|
+
"agentInstructions.write",
|
|
17885
|
+
z18.object({
|
|
17886
|
+
workspaceId: z18.string(),
|
|
17887
|
+
content: z18.string(),
|
|
17888
|
+
overwrite: z18.boolean().optional(),
|
|
17889
|
+
baseHash: z18.string().optional()
|
|
16447
17890
|
}),
|
|
16448
17891
|
async (args, ctx) => {
|
|
16449
17892
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
16450
17893
|
if (!workspace) {
|
|
16451
17894
|
throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
|
|
16452
17895
|
}
|
|
16453
|
-
const
|
|
16454
|
-
|
|
16455
|
-
|
|
16456
|
-
|
|
16457
|
-
|
|
16458
|
-
|
|
16459
|
-
|
|
16460
|
-
|
|
17896
|
+
const existing = await readAgentInstructionsDocument(workspace.id, workspace.path);
|
|
17897
|
+
if (existing.exists && !args.overwrite) {
|
|
17898
|
+
throw {
|
|
17899
|
+
code: "agent_instructions_exists",
|
|
17900
|
+
message: `${AGENT_INSTRUCTIONS_RELATIVE_PATH} already exists`
|
|
17901
|
+
};
|
|
17902
|
+
}
|
|
17903
|
+
const result = await writeFile(
|
|
17904
|
+
workspace.path,
|
|
17905
|
+
AGENT_INSTRUCTIONS_RELATIVE_PATH,
|
|
17906
|
+
args.content,
|
|
17907
|
+
args.baseHash
|
|
16461
17908
|
);
|
|
16462
|
-
ctx.
|
|
16463
|
-
|
|
16464
|
-
|
|
16465
|
-
|
|
16466
|
-
worktreeChanged: true
|
|
17909
|
+
ctx.eventBus.emit({
|
|
17910
|
+
type: "fs.dirty",
|
|
17911
|
+
workspaceId: args.workspaceId,
|
|
17912
|
+
reason: "file_content"
|
|
16467
17913
|
});
|
|
16468
|
-
return
|
|
17914
|
+
return {
|
|
17915
|
+
path: AGENT_INSTRUCTIONS_RELATIVE_PATH,
|
|
17916
|
+
exists: true,
|
|
17917
|
+
content: args.content,
|
|
17918
|
+
baseHash: result.newHash
|
|
17919
|
+
};
|
|
16469
17920
|
}
|
|
16470
17921
|
);
|
|
16471
17922
|
registerCommand(
|
|
16472
|
-
"
|
|
16473
|
-
|
|
16474
|
-
workspaceId:
|
|
16475
|
-
remote: z14.string().optional(),
|
|
16476
|
-
prune: z14.boolean().optional(),
|
|
16477
|
-
auth: gitHttpAuthSchema.optional(),
|
|
16478
|
-
background: z14.boolean().optional()
|
|
17923
|
+
"agentInstructions.health",
|
|
17924
|
+
z18.object({
|
|
17925
|
+
workspaceId: z18.string()
|
|
16479
17926
|
}),
|
|
16480
|
-
async (args, ctx
|
|
17927
|
+
async (args, ctx) => {
|
|
16481
17928
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
16482
17929
|
if (!workspace) {
|
|
16483
17930
|
throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
|
|
16484
17931
|
}
|
|
16485
|
-
|
|
16486
|
-
|
|
16487
|
-
const runFetch = () => runGitFetch(workspace.path, {
|
|
16488
|
-
remote: args.remote,
|
|
16489
|
-
prune: args.prune,
|
|
16490
|
-
auth: args.auth,
|
|
16491
|
-
timeoutMs: args.background ? GIT_BACKGROUND_FETCH_TIMEOUT_MS : void 0
|
|
16492
|
-
});
|
|
16493
|
-
const result = isInternalBackgroundFetch ? await runFetch() : await runGitNetworkOperation(ctx, args.workspaceId, runFetch);
|
|
16494
|
-
ctx.workspaceMgr.recordFetch(args.workspaceId);
|
|
16495
|
-
emitGitStateChanged(ctx, args.workspaceId, { branchChanged: true });
|
|
16496
|
-
return result;
|
|
16497
|
-
} catch (err) {
|
|
16498
|
-
if (args.background && err instanceof GitAuthError) {
|
|
16499
|
-
return { success: false, message: err.message, updatedRefs: [] };
|
|
16500
|
-
}
|
|
16501
|
-
throw err;
|
|
16502
|
-
}
|
|
17932
|
+
const document = await readAgentInstructionsDocument(workspace.id, workspace.path);
|
|
17933
|
+
return evaluateAgentInstructionsMarkdown(document.content);
|
|
16503
17934
|
}
|
|
16504
17935
|
);
|
|
17936
|
+
}
|
|
17937
|
+
});
|
|
17938
|
+
|
|
17939
|
+
// packages/server/src/agent-context/context-package.ts
|
|
17940
|
+
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
17941
|
+
import { readFile as readFile8 } from "node:fs/promises";
|
|
17942
|
+
function resolveOptions(options) {
|
|
17943
|
+
return {
|
|
17944
|
+
createId: options?.createId ?? randomUUID7,
|
|
17945
|
+
now: options?.now ?? Date.now
|
|
17946
|
+
};
|
|
17947
|
+
}
|
|
17948
|
+
function formatSource(source) {
|
|
17949
|
+
const parts = [`workspace=${source.workspaceId}`];
|
|
17950
|
+
if (source.sessionId) {
|
|
17951
|
+
parts.push(`session=${source.sessionId}`);
|
|
17952
|
+
}
|
|
17953
|
+
if (source.path) {
|
|
17954
|
+
parts.push(`path=${source.path}`);
|
|
17955
|
+
}
|
|
17956
|
+
if (source.terminalId) {
|
|
17957
|
+
parts.push(`terminal=${source.terminalId}`);
|
|
17958
|
+
}
|
|
17959
|
+
return parts.join(" ");
|
|
17960
|
+
}
|
|
17961
|
+
function wrapContext(title, source, body) {
|
|
17962
|
+
return `Context: ${title}
|
|
17963
|
+
Source: ${formatSource(source)}
|
|
17964
|
+
|
|
17965
|
+
${body}`;
|
|
17966
|
+
}
|
|
17967
|
+
function createContextPackage(kind, title, source, body, options) {
|
|
17968
|
+
const resolved = resolveOptions(options);
|
|
17969
|
+
return {
|
|
17970
|
+
id: resolved.createId(),
|
|
17971
|
+
kind,
|
|
17972
|
+
title,
|
|
17973
|
+
body: wrapContext(title, source, body),
|
|
17974
|
+
source,
|
|
17975
|
+
createdAt: resolved.now()
|
|
17976
|
+
};
|
|
17977
|
+
}
|
|
17978
|
+
function requireSessionMetadata2(metadataRepo, sessionId) {
|
|
17979
|
+
const metadata = metadataRepo.get(sessionId);
|
|
17980
|
+
if (!metadata) {
|
|
17981
|
+
throw {
|
|
17982
|
+
code: "session_metadata_not_found",
|
|
17983
|
+
message: `Session metadata not found: ${sessionId}`
|
|
17984
|
+
};
|
|
17985
|
+
}
|
|
17986
|
+
return metadata;
|
|
17987
|
+
}
|
|
17988
|
+
function buildProjectSummaryBody(summary) {
|
|
17989
|
+
const lines = [
|
|
17990
|
+
`Git: ${summary.git.isRepo ? "repository detected" : "no repository detected"}`,
|
|
17991
|
+
`Package manager: ${summary.packageManager ?? "unknown"}`,
|
|
17992
|
+
`Frameworks: ${summary.frameworks.length > 0 ? summary.frameworks.join(", ") : "none"}`
|
|
17993
|
+
];
|
|
17994
|
+
if (summary.recommendedCommands.length > 0) {
|
|
17995
|
+
lines.push("Recommended commands:");
|
|
17996
|
+
for (const command of summary.recommendedCommands) {
|
|
17997
|
+
lines.push(`- ${command.key}: ${command.command}`);
|
|
17998
|
+
}
|
|
17999
|
+
} else {
|
|
18000
|
+
lines.push("Recommended commands: none");
|
|
18001
|
+
}
|
|
18002
|
+
if (summary.docs.length > 0) {
|
|
18003
|
+
lines.push("Docs:");
|
|
18004
|
+
for (const doc of summary.docs) {
|
|
18005
|
+
lines.push(`- ${doc.path}`);
|
|
18006
|
+
}
|
|
18007
|
+
} else {
|
|
18008
|
+
lines.push("Docs: none");
|
|
18009
|
+
}
|
|
18010
|
+
lines.push(
|
|
18011
|
+
`Agent instructions: ${summary.agentInstructions.path} ${summary.agentInstructions.exists ? "present" : "missing"}`
|
|
18012
|
+
);
|
|
18013
|
+
return lines.join("\n");
|
|
18014
|
+
}
|
|
18015
|
+
async function buildFileContextPackage(input, options) {
|
|
18016
|
+
const content = await readFile8(resolveSafe(input.workspacePath, input.path), "utf8");
|
|
18017
|
+
return createContextPackage(
|
|
18018
|
+
"file",
|
|
18019
|
+
`File: ${input.path}`,
|
|
18020
|
+
{
|
|
18021
|
+
workspaceId: input.workspaceId,
|
|
18022
|
+
path: input.path
|
|
18023
|
+
},
|
|
18024
|
+
content,
|
|
18025
|
+
options
|
|
18026
|
+
);
|
|
18027
|
+
}
|
|
18028
|
+
async function buildDiffContextPackage(input, options) {
|
|
18029
|
+
const metadata = requireSessionMetadata2(input.metadataRepo, input.sessionId);
|
|
18030
|
+
const diff = await getSessionReviewDiff({
|
|
18031
|
+
sessionId: input.sessionId,
|
|
18032
|
+
workspacePath: input.workspacePath,
|
|
18033
|
+
metadataRepo: input.metadataRepo,
|
|
18034
|
+
path: input.path
|
|
18035
|
+
});
|
|
18036
|
+
return createContextPackage(
|
|
18037
|
+
"git_diff",
|
|
18038
|
+
`Git Diff: ${input.path}`,
|
|
18039
|
+
{
|
|
18040
|
+
workspaceId: metadata.workspaceId,
|
|
18041
|
+
sessionId: input.sessionId,
|
|
18042
|
+
path: input.path
|
|
18043
|
+
},
|
|
18044
|
+
diff,
|
|
18045
|
+
options
|
|
18046
|
+
);
|
|
18047
|
+
}
|
|
18048
|
+
async function buildProjectSummaryContextPackage(input, options) {
|
|
18049
|
+
const summary = await inspectWorkspaceIntelligence({
|
|
18050
|
+
workspaceId: input.workspaceId,
|
|
18051
|
+
rootPath: input.workspacePath
|
|
18052
|
+
});
|
|
18053
|
+
return createContextPackage(
|
|
18054
|
+
"project_summary",
|
|
18055
|
+
"Project Summary",
|
|
18056
|
+
{
|
|
18057
|
+
workspaceId: input.workspaceId
|
|
18058
|
+
},
|
|
18059
|
+
buildProjectSummaryBody(summary),
|
|
18060
|
+
options
|
|
18061
|
+
);
|
|
18062
|
+
}
|
|
18063
|
+
async function buildSessionReviewContextPackage(input, options) {
|
|
18064
|
+
const metadata = requireSessionMetadata2(input.metadataRepo, input.sessionId);
|
|
18065
|
+
const summary = await buildSessionReviewSummary({
|
|
18066
|
+
sessionId: input.sessionId,
|
|
18067
|
+
workspacePath: input.workspacePath,
|
|
18068
|
+
metadataRepo: input.metadataRepo
|
|
18069
|
+
});
|
|
18070
|
+
const lines = [
|
|
18071
|
+
`Baseline: ${summary.baselineGitHead ?? "missing"}`,
|
|
18072
|
+
"Changed files:",
|
|
18073
|
+
...summary.changedFiles.length > 0 ? summary.changedFiles.map((change) => `- ${change.status ?? "modified"}: ${change.path}`) : ["- none"],
|
|
18074
|
+
"Verification runs:",
|
|
18075
|
+
...summary.verificationRuns.length > 0 ? summary.verificationRuns.map((run) => `- ${run.status}: ${run.command}`) : ["- none"]
|
|
18076
|
+
];
|
|
18077
|
+
if (summary.warnings.length > 0) {
|
|
18078
|
+
lines.push("Warnings:");
|
|
18079
|
+
for (const warning of summary.warnings) {
|
|
18080
|
+
lines.push(`- ${warning.code}: ${warning.message}`);
|
|
18081
|
+
}
|
|
18082
|
+
}
|
|
18083
|
+
return createContextPackage(
|
|
18084
|
+
"session_review",
|
|
18085
|
+
`Session Review: ${summary.sessionId}`,
|
|
18086
|
+
{
|
|
18087
|
+
workspaceId: metadata.workspaceId,
|
|
18088
|
+
sessionId: input.sessionId
|
|
18089
|
+
},
|
|
18090
|
+
lines.join("\n"),
|
|
18091
|
+
options
|
|
18092
|
+
);
|
|
18093
|
+
}
|
|
18094
|
+
var init_context_package = __esm({
|
|
18095
|
+
"packages/server/src/agent-context/context-package.ts"() {
|
|
18096
|
+
"use strict";
|
|
18097
|
+
init_file_io();
|
|
18098
|
+
init_review();
|
|
18099
|
+
init_intelligence();
|
|
18100
|
+
}
|
|
18101
|
+
});
|
|
18102
|
+
|
|
18103
|
+
// packages/server/src/commands/agent-context.ts
|
|
18104
|
+
import { z as z19 } from "zod";
|
|
18105
|
+
function requireWorkspace2(ctx, workspaceId) {
|
|
18106
|
+
const workspace = ctx.workspaceMgr.get(workspaceId);
|
|
18107
|
+
if (!workspace) {
|
|
18108
|
+
throw { code: "workspace_not_found", message: `Workspace not found: ${workspaceId}` };
|
|
18109
|
+
}
|
|
18110
|
+
return workspace;
|
|
18111
|
+
}
|
|
18112
|
+
function requireSessionMetadataRepo3(ctx) {
|
|
18113
|
+
if (!ctx.sessionMetadataRepo) {
|
|
18114
|
+
throw {
|
|
18115
|
+
code: "session_metadata_unavailable",
|
|
18116
|
+
message: "Session metadata repository is not configured"
|
|
18117
|
+
};
|
|
18118
|
+
}
|
|
18119
|
+
}
|
|
18120
|
+
function getSessionWorkspace(ctx, sessionId) {
|
|
18121
|
+
const metadata = ctx.sessionMetadataRepo.get(sessionId);
|
|
18122
|
+
if (!metadata) {
|
|
18123
|
+
throw {
|
|
18124
|
+
code: "session_metadata_not_found",
|
|
18125
|
+
message: `Session metadata not found: ${sessionId}`
|
|
18126
|
+
};
|
|
18127
|
+
}
|
|
18128
|
+
return {
|
|
18129
|
+
metadata,
|
|
18130
|
+
workspace: requireWorkspace2(ctx, metadata.workspaceId)
|
|
18131
|
+
};
|
|
18132
|
+
}
|
|
18133
|
+
var init_agent_context = __esm({
|
|
18134
|
+
"packages/server/src/commands/agent-context.ts"() {
|
|
18135
|
+
"use strict";
|
|
18136
|
+
init_context_package();
|
|
18137
|
+
init_dispatch();
|
|
16505
18138
|
registerCommand(
|
|
16506
|
-
"
|
|
16507
|
-
|
|
16508
|
-
workspaceId:
|
|
16509
|
-
|
|
16510
|
-
createBranch: z14.boolean().optional()
|
|
18139
|
+
"agentContext.fromFile",
|
|
18140
|
+
z19.object({
|
|
18141
|
+
workspaceId: z19.string(),
|
|
18142
|
+
path: z19.string().trim().min(1)
|
|
16511
18143
|
}),
|
|
16512
18144
|
async (args, ctx) => {
|
|
16513
|
-
const workspace = ctx
|
|
16514
|
-
|
|
16515
|
-
|
|
16516
|
-
|
|
16517
|
-
|
|
16518
|
-
createBranch: args.createBranch
|
|
18145
|
+
const workspace = requireWorkspace2(ctx, args.workspaceId);
|
|
18146
|
+
return buildFileContextPackage({
|
|
18147
|
+
workspaceId: workspace.id,
|
|
18148
|
+
workspacePath: workspace.path,
|
|
18149
|
+
path: args.path
|
|
16519
18150
|
});
|
|
16520
|
-
if (result.success) {
|
|
16521
|
-
emitGitStateChanged(ctx, args.workspaceId, {
|
|
16522
|
-
treeChanged: true,
|
|
16523
|
-
branchChanged: true,
|
|
16524
|
-
worktreeChanged: true
|
|
16525
|
-
});
|
|
16526
|
-
}
|
|
16527
|
-
return result;
|
|
16528
18151
|
}
|
|
16529
18152
|
);
|
|
16530
18153
|
registerCommand(
|
|
16531
|
-
"
|
|
16532
|
-
|
|
16533
|
-
|
|
16534
|
-
|
|
16535
|
-
startPoint: z14.string().optional()
|
|
18154
|
+
"agentContext.fromDiff",
|
|
18155
|
+
z19.object({
|
|
18156
|
+
sessionId: z19.string(),
|
|
18157
|
+
path: z19.string().trim().min(1)
|
|
16536
18158
|
}),
|
|
16537
18159
|
async (args, ctx) => {
|
|
16538
|
-
|
|
16539
|
-
|
|
16540
|
-
|
|
16541
|
-
|
|
16542
|
-
|
|
16543
|
-
|
|
18160
|
+
requireSessionMetadataRepo3(ctx);
|
|
18161
|
+
const { workspace } = getSessionWorkspace(ctx, args.sessionId);
|
|
18162
|
+
return buildDiffContextPackage({
|
|
18163
|
+
sessionId: args.sessionId,
|
|
18164
|
+
path: args.path,
|
|
18165
|
+
workspacePath: workspace.path,
|
|
18166
|
+
metadataRepo: ctx.sessionMetadataRepo
|
|
16544
18167
|
});
|
|
16545
|
-
|
|
16546
|
-
|
|
16547
|
-
|
|
18168
|
+
}
|
|
18169
|
+
);
|
|
18170
|
+
registerCommand(
|
|
18171
|
+
"agentContext.fromProjectSummary",
|
|
18172
|
+
z19.object({
|
|
18173
|
+
workspaceId: z19.string()
|
|
18174
|
+
}),
|
|
18175
|
+
async (args, ctx) => {
|
|
18176
|
+
const workspace = requireWorkspace2(ctx, args.workspaceId);
|
|
18177
|
+
return buildProjectSummaryContextPackage({
|
|
18178
|
+
workspaceId: workspace.id,
|
|
18179
|
+
workspacePath: workspace.path
|
|
16548
18180
|
});
|
|
16549
|
-
return result;
|
|
16550
18181
|
}
|
|
16551
18182
|
);
|
|
16552
18183
|
registerCommand(
|
|
16553
|
-
"
|
|
16554
|
-
|
|
16555
|
-
|
|
18184
|
+
"agentContext.fromSessionReview",
|
|
18185
|
+
z19.object({
|
|
18186
|
+
sessionId: z19.string()
|
|
16556
18187
|
}),
|
|
16557
18188
|
async (args, ctx) => {
|
|
16558
|
-
|
|
16559
|
-
|
|
16560
|
-
|
|
16561
|
-
|
|
16562
|
-
|
|
18189
|
+
requireSessionMetadataRepo3(ctx);
|
|
18190
|
+
const { workspace } = getSessionWorkspace(ctx, args.sessionId);
|
|
18191
|
+
return buildSessionReviewContextPackage({
|
|
18192
|
+
sessionId: args.sessionId,
|
|
18193
|
+
workspacePath: workspace.path,
|
|
18194
|
+
metadataRepo: ctx.sessionMetadataRepo
|
|
18195
|
+
});
|
|
16563
18196
|
}
|
|
16564
18197
|
);
|
|
16565
18198
|
}
|
|
@@ -16568,25 +18201,25 @@ var init_git2 = __esm({
|
|
|
16568
18201
|
// packages/server/src/config/config-io.ts
|
|
16569
18202
|
import { existsSync as existsSync9, mkdirSync as mkdirSync7, readFileSync as readFileSync7, renameSync as renameSync2, writeFileSync as writeFileSync5 } from "node:fs";
|
|
16570
18203
|
import { homedir as homedir3 } from "node:os";
|
|
16571
|
-
import { basename as basename3, dirname as dirname7, join as
|
|
18204
|
+
import { basename as basename3, dirname as dirname7, join as join17 } from "node:path";
|
|
16572
18205
|
function resolveConfigPath(configType) {
|
|
16573
18206
|
if (configType === "codex") {
|
|
16574
18207
|
const testHome = process.env.CODER_STUDIO_CODEX_HOME;
|
|
16575
18208
|
if (testHome && testHome.trim()) {
|
|
16576
|
-
return
|
|
18209
|
+
return join17(testHome, "config.toml");
|
|
16577
18210
|
}
|
|
16578
18211
|
const codexHome = process.env.CODEX_HOME;
|
|
16579
18212
|
if (codexHome && codexHome.trim()) {
|
|
16580
|
-
return
|
|
18213
|
+
return join17(codexHome, "config.toml");
|
|
16581
18214
|
}
|
|
16582
|
-
return
|
|
18215
|
+
return join17(homedir3(), ".codex", "config.toml");
|
|
16583
18216
|
}
|
|
16584
18217
|
if (configType === "claude") {
|
|
16585
18218
|
const testHome = process.env.CODER_STUDIO_CLAUDE_HOME;
|
|
16586
18219
|
if (testHome && testHome.trim()) {
|
|
16587
|
-
return
|
|
18220
|
+
return join17(testHome, "settings.json");
|
|
16588
18221
|
}
|
|
16589
|
-
return
|
|
18222
|
+
return join17(homedir3(), ".claude", "settings.json");
|
|
16590
18223
|
}
|
|
16591
18224
|
throw new Error(`Unknown config type: ${configType}`);
|
|
16592
18225
|
}
|
|
@@ -16631,7 +18264,7 @@ function createBackup(filePath) {
|
|
|
16631
18264
|
const base = basename3(filePath, `.${ext}`);
|
|
16632
18265
|
const dir = dirname7(filePath);
|
|
16633
18266
|
const ts = formatTimestamp(/* @__PURE__ */ new Date());
|
|
16634
|
-
const backupPath =
|
|
18267
|
+
const backupPath = join17(dir, `${base}.bak.${ts}.${ext}`);
|
|
16635
18268
|
writeFileSync5(backupPath, original, "utf-8");
|
|
16636
18269
|
return backupPath;
|
|
16637
18270
|
}
|
|
@@ -16646,7 +18279,7 @@ var init_config_io = __esm({
|
|
|
16646
18279
|
});
|
|
16647
18280
|
|
|
16648
18281
|
// packages/server/src/commands/settings.ts
|
|
16649
|
-
import { z as
|
|
18282
|
+
import { z as z20 } from "zod";
|
|
16650
18283
|
function flattenSettings(obj, prefix = "") {
|
|
16651
18284
|
const result = {};
|
|
16652
18285
|
for (const [key, value] of Object.entries(obj)) {
|
|
@@ -16697,13 +18330,13 @@ var init_settings2 = __esm({
|
|
|
16697
18330
|
init_provider_config();
|
|
16698
18331
|
init_settings();
|
|
16699
18332
|
init_dispatch();
|
|
16700
|
-
PersonalizationOverridesSchema =
|
|
16701
|
-
backgroundAssetId:
|
|
16702
|
-
backgroundDimness:
|
|
16703
|
-
backgroundBlur:
|
|
16704
|
-
glassEnabled:
|
|
16705
|
-
glassIntensity:
|
|
16706
|
-
surfaceOpacity:
|
|
18333
|
+
PersonalizationOverridesSchema = z20.object({
|
|
18334
|
+
backgroundAssetId: z20.string().min(1).nullable().optional(),
|
|
18335
|
+
backgroundDimness: z20.number().int().min(0).max(100).optional(),
|
|
18336
|
+
backgroundBlur: z20.number().int().min(0).max(40).optional(),
|
|
18337
|
+
glassEnabled: z20.boolean().optional(),
|
|
18338
|
+
glassIntensity: z20.number().int().min(0).max(100).optional(),
|
|
18339
|
+
surfaceOpacity: z20.number().int().min(0).max(100).optional()
|
|
16707
18340
|
});
|
|
16708
18341
|
PERSONALIZATION_OVERRIDE_BRANCHES = ["desktop", "mobile"];
|
|
16709
18342
|
PERSONALIZATION_OVERRIDE_FIELDS = [
|
|
@@ -16714,59 +18347,59 @@ var init_settings2 = __esm({
|
|
|
16714
18347
|
"glassIntensity",
|
|
16715
18348
|
"surfaceOpacity"
|
|
16716
18349
|
];
|
|
16717
|
-
SettingsSchema =
|
|
16718
|
-
defaultProviderId:
|
|
16719
|
-
notifications:
|
|
16720
|
-
enabled:
|
|
16721
|
-
soundEnabled:
|
|
18350
|
+
SettingsSchema = z20.object({
|
|
18351
|
+
defaultProviderId: z20.string().optional(),
|
|
18352
|
+
notifications: z20.object({
|
|
18353
|
+
enabled: z20.boolean().optional(),
|
|
18354
|
+
soundEnabled: z20.boolean().optional(),
|
|
16722
18355
|
// Legacy field — accepted for backward compat with older clients but
|
|
16723
18356
|
// no longer surfaced in the UI. The web client now picks the channel
|
|
16724
18357
|
// automatically based on workspace focus + page visibility.
|
|
16725
|
-
onlyWhenBackgrounded:
|
|
18358
|
+
onlyWhenBackgrounded: z20.boolean().optional()
|
|
16726
18359
|
}).optional(),
|
|
16727
|
-
supervisor:
|
|
16728
|
-
evaluationTimeoutSec:
|
|
16729
|
-
retryEnabled:
|
|
16730
|
-
retryMaxCount:
|
|
16731
|
-
retryDelaySec:
|
|
16732
|
-
retryOnTimeout:
|
|
16733
|
-
retryOnEvaluatorError:
|
|
18360
|
+
supervisor: z20.object({
|
|
18361
|
+
evaluationTimeoutSec: z20.number().int().min(1).max(MAX_SUPERVISOR_EVALUATION_TIMEOUT_SEC).default(DEFAULT_SUPERVISOR_EVALUATION_TIMEOUT_SEC).optional(),
|
|
18362
|
+
retryEnabled: z20.boolean().optional(),
|
|
18363
|
+
retryMaxCount: z20.number().int().min(0).max(MAX_SUPERVISOR_RETRY_MAX_COUNT).optional(),
|
|
18364
|
+
retryDelaySec: z20.number().int().min(1).max(MAX_SUPERVISOR_RETRY_DELAY_SEC).optional(),
|
|
18365
|
+
retryOnTimeout: z20.boolean().optional(),
|
|
18366
|
+
retryOnEvaluatorError: z20.boolean().optional()
|
|
16734
18367
|
}).optional(),
|
|
16735
|
-
appearance:
|
|
16736
|
-
theme:
|
|
16737
|
-
themeId:
|
|
16738
|
-
terminalRenderer:
|
|
16739
|
-
terminalCopyOnSelect:
|
|
16740
|
-
terminalFontSize:
|
|
16741
|
-
desktopTerminalFontSize:
|
|
16742
|
-
mobileTerminalFontSize:
|
|
16743
|
-
locale:
|
|
16744
|
-
personalization:
|
|
16745
|
-
version:
|
|
16746
|
-
common:
|
|
16747
|
-
backgroundMode:
|
|
16748
|
-
backgroundAssetId:
|
|
16749
|
-
backgroundFit:
|
|
16750
|
-
backgroundDimness:
|
|
16751
|
-
backgroundBlur:
|
|
16752
|
-
glassEnabled:
|
|
16753
|
-
glassIntensity:
|
|
16754
|
-
surfaceOpacity:
|
|
18368
|
+
appearance: z20.object({
|
|
18369
|
+
theme: z20.enum(["dark", "light"]).optional(),
|
|
18370
|
+
themeId: z20.string().optional(),
|
|
18371
|
+
terminalRenderer: z20.enum(["standard", "compatibility"]).optional(),
|
|
18372
|
+
terminalCopyOnSelect: z20.boolean().optional(),
|
|
18373
|
+
terminalFontSize: z20.number().int().min(10).max(18).optional(),
|
|
18374
|
+
desktopTerminalFontSize: z20.number().int().min(10).max(18).optional(),
|
|
18375
|
+
mobileTerminalFontSize: z20.number().int().min(10).max(18).optional(),
|
|
18376
|
+
locale: z20.enum(["zh", "en"]).optional(),
|
|
18377
|
+
personalization: z20.object({
|
|
18378
|
+
version: z20.literal(1).optional(),
|
|
18379
|
+
common: z20.object({
|
|
18380
|
+
backgroundMode: z20.enum(["none", "image"]).optional(),
|
|
18381
|
+
backgroundAssetId: z20.string().min(1).nullable().optional(),
|
|
18382
|
+
backgroundFit: z20.enum(["cover", "contain"]).optional(),
|
|
18383
|
+
backgroundDimness: z20.number().int().min(0).max(100).optional(),
|
|
18384
|
+
backgroundBlur: z20.number().int().min(0).max(40).optional(),
|
|
18385
|
+
glassEnabled: z20.boolean().optional(),
|
|
18386
|
+
glassIntensity: z20.number().int().min(0).max(100).optional(),
|
|
18387
|
+
surfaceOpacity: z20.number().int().min(0).max(100).optional()
|
|
16755
18388
|
}).optional(),
|
|
16756
18389
|
desktop: PersonalizationOverridesSchema.optional(),
|
|
16757
18390
|
mobile: PersonalizationOverridesSchema.optional()
|
|
16758
18391
|
}).optional()
|
|
16759
18392
|
}).optional(),
|
|
16760
|
-
lsp:
|
|
16761
|
-
mode:
|
|
18393
|
+
lsp: z20.object({
|
|
18394
|
+
mode: z20.enum(["auto", "off"]).optional()
|
|
16762
18395
|
}).optional(),
|
|
16763
|
-
updates:
|
|
16764
|
-
autoCheckEnabled:
|
|
16765
|
-
checkIntervalSec:
|
|
18396
|
+
updates: z20.object({
|
|
18397
|
+
autoCheckEnabled: z20.boolean().optional(),
|
|
18398
|
+
checkIntervalSec: z20.number().int().refine(isUpdateCheckIntervalSec).optional()
|
|
16766
18399
|
}).optional(),
|
|
16767
18400
|
providers: ProviderSettingsSchema.optional()
|
|
16768
18401
|
});
|
|
16769
|
-
registerCommand("settings.get",
|
|
18402
|
+
registerCommand("settings.get", z20.object({}), async (_args, ctx) => {
|
|
16770
18403
|
const settings = {};
|
|
16771
18404
|
for (const [key, value] of Object.entries(ctx.settingsRepo.getAll())) {
|
|
16772
18405
|
if (key.startsWith("providers.")) {
|
|
@@ -16818,7 +18451,7 @@ var init_settings2 = __esm({
|
|
|
16818
18451
|
});
|
|
16819
18452
|
registerCommand(
|
|
16820
18453
|
"settings.update",
|
|
16821
|
-
|
|
18454
|
+
z20.object({
|
|
16822
18455
|
settings: SettingsSchema
|
|
16823
18456
|
}),
|
|
16824
18457
|
async (args, ctx) => {
|
|
@@ -16851,10 +18484,10 @@ var init_settings2 = __esm({
|
|
|
16851
18484
|
);
|
|
16852
18485
|
registerCommand(
|
|
16853
18486
|
"settings.previewCommand",
|
|
16854
|
-
|
|
16855
|
-
providerId:
|
|
18487
|
+
z20.object({
|
|
18488
|
+
providerId: z20.string(),
|
|
16856
18489
|
config: ProviderLaunchConfigInputSchema,
|
|
16857
|
-
workspacePath:
|
|
18490
|
+
workspacePath: z20.string().optional()
|
|
16858
18491
|
}),
|
|
16859
18492
|
async (args, ctx) => {
|
|
16860
18493
|
const provider = ctx.providerRegistry.find((item) => item.id === args.providerId);
|
|
@@ -16875,8 +18508,8 @@ var init_settings2 = __esm({
|
|
|
16875
18508
|
);
|
|
16876
18509
|
registerCommand(
|
|
16877
18510
|
"settings.readConfigFile",
|
|
16878
|
-
|
|
16879
|
-
configType:
|
|
18511
|
+
z20.object({
|
|
18512
|
+
configType: z20.enum(["codex", "claude"])
|
|
16880
18513
|
}),
|
|
16881
18514
|
async (args) => {
|
|
16882
18515
|
const result = readConfigFile(args.configType);
|
|
@@ -16885,9 +18518,9 @@ var init_settings2 = __esm({
|
|
|
16885
18518
|
);
|
|
16886
18519
|
registerCommand(
|
|
16887
18520
|
"settings.writeConfigFile",
|
|
16888
|
-
|
|
16889
|
-
configType:
|
|
16890
|
-
content:
|
|
18521
|
+
z20.object({
|
|
18522
|
+
configType: z20.enum(["codex", "claude"]),
|
|
18523
|
+
content: z20.string()
|
|
16891
18524
|
}),
|
|
16892
18525
|
async (args) => {
|
|
16893
18526
|
const result = writeConfigFile(args.configType, args.content);
|
|
@@ -16898,7 +18531,7 @@ var init_settings2 = __esm({
|
|
|
16898
18531
|
});
|
|
16899
18532
|
|
|
16900
18533
|
// packages/server/src/commands/diagnostics.ts
|
|
16901
|
-
import { z as
|
|
18534
|
+
import { z as z21 } from "zod";
|
|
16902
18535
|
function isLoopbackHost(host) {
|
|
16903
18536
|
return host === void 0 || host === "localhost" || host === "127.0.0.1" || host === "::1" || host === "0.0.0.0";
|
|
16904
18537
|
}
|
|
@@ -17268,11 +18901,11 @@ var init_diagnostics2 = __esm({
|
|
|
17268
18901
|
init_runtime_status();
|
|
17269
18902
|
init_validator();
|
|
17270
18903
|
init_dispatch();
|
|
17271
|
-
DiagnosticsRequestSchema =
|
|
17272
|
-
context:
|
|
17273
|
-
workspaceId:
|
|
17274
|
-
workspacePath:
|
|
17275
|
-
providerId:
|
|
18904
|
+
DiagnosticsRequestSchema = z21.object({
|
|
18905
|
+
context: z21.enum(["workspace_open", "session_start", "mobile_continue", "manual_check"]),
|
|
18906
|
+
workspaceId: z21.string().optional(),
|
|
18907
|
+
workspacePath: z21.string().optional(),
|
|
18908
|
+
providerId: z21.string().optional()
|
|
17276
18909
|
});
|
|
17277
18910
|
registerCommand("diagnostics.get", DiagnosticsRequestSchema, async (args, ctx) => {
|
|
17278
18911
|
return buildDiagnostics(args, ctx);
|
|
@@ -17284,19 +18917,23 @@ var init_diagnostics2 = __esm({
|
|
|
17284
18917
|
});
|
|
17285
18918
|
|
|
17286
18919
|
// packages/server/src/commands/provider.ts
|
|
17287
|
-
import { z as
|
|
18920
|
+
import { z as z22 } from "zod";
|
|
17288
18921
|
var init_provider = __esm({
|
|
17289
18922
|
"packages/server/src/commands/provider.ts"() {
|
|
17290
18923
|
"use strict";
|
|
18924
|
+
init_src();
|
|
17291
18925
|
init_runtime_status();
|
|
17292
18926
|
init_dispatch();
|
|
17293
|
-
registerCommand("provider.
|
|
18927
|
+
registerCommand("provider.list", z22.object({}), async (_args, ctx) => {
|
|
18928
|
+
return ctx.providerRegistry.map((provider) => toProviderListItem(provider));
|
|
18929
|
+
});
|
|
18930
|
+
registerCommand("provider.runtimeStatus", z22.object({}), async (_args, ctx) => {
|
|
17294
18931
|
return buildProviderRuntimeStatus(ctx.providerRegistry, ctx.providerRuntimeDeps);
|
|
17295
18932
|
});
|
|
17296
18933
|
registerCommand(
|
|
17297
18934
|
"provider.install.start",
|
|
17298
|
-
|
|
17299
|
-
providerId:
|
|
18935
|
+
z22.object({
|
|
18936
|
+
providerId: z22.string()
|
|
17300
18937
|
}),
|
|
17301
18938
|
async (args, ctx) => {
|
|
17302
18939
|
if (!ctx.providerInstallMgr) {
|
|
@@ -17310,8 +18947,8 @@ var init_provider = __esm({
|
|
|
17310
18947
|
);
|
|
17311
18948
|
registerCommand(
|
|
17312
18949
|
"provider.install.get",
|
|
17313
|
-
|
|
17314
|
-
jobId:
|
|
18950
|
+
z22.object({
|
|
18951
|
+
jobId: z22.string()
|
|
17315
18952
|
}),
|
|
17316
18953
|
async (args, ctx) => {
|
|
17317
18954
|
if (!ctx.providerInstallMgr) {
|
|
@@ -17333,45 +18970,147 @@ var init_provider = __esm({
|
|
|
17333
18970
|
}
|
|
17334
18971
|
});
|
|
17335
18972
|
|
|
18973
|
+
// packages/server/src/commands/custom-provider.ts
|
|
18974
|
+
import { z as z23 } from "zod";
|
|
18975
|
+
function requireCustomProviderSupport(ctx) {
|
|
18976
|
+
if (!ctx.customProviderRepo || !ctx.setProviderRegistry) {
|
|
18977
|
+
throw {
|
|
18978
|
+
code: "custom_provider_unavailable",
|
|
18979
|
+
message: "Custom provider runtime is not configured"
|
|
18980
|
+
};
|
|
18981
|
+
}
|
|
18982
|
+
}
|
|
18983
|
+
function materializeConfig(input, previous) {
|
|
18984
|
+
const now = Date.now();
|
|
18985
|
+
return {
|
|
18986
|
+
...input,
|
|
18987
|
+
startupPrompt: input.startupPrompt?.trim() || void 0,
|
|
18988
|
+
createdAt: previous?.createdAt ?? now,
|
|
18989
|
+
updatedAt: now
|
|
18990
|
+
};
|
|
18991
|
+
}
|
|
18992
|
+
var CapabilitySchema, BaseCustomProviderInputSchema;
|
|
18993
|
+
var init_custom_provider2 = __esm({
|
|
18994
|
+
"packages/server/src/commands/custom-provider.ts"() {
|
|
18995
|
+
"use strict";
|
|
18996
|
+
init_src();
|
|
18997
|
+
init_custom_provider();
|
|
18998
|
+
init_dispatch();
|
|
18999
|
+
CapabilitySchema = z23.object({
|
|
19000
|
+
key: z23.enum([
|
|
19001
|
+
"interactive_session",
|
|
19002
|
+
"supervisor_eval",
|
|
19003
|
+
"idle_detection",
|
|
19004
|
+
"context_attach",
|
|
19005
|
+
"review"
|
|
19006
|
+
]),
|
|
19007
|
+
supported: z23.boolean(),
|
|
19008
|
+
label: z23.string().min(1)
|
|
19009
|
+
});
|
|
19010
|
+
BaseCustomProviderInputSchema = z23.object({
|
|
19011
|
+
id: z23.string().trim().min(1).regex(/^[a-z0-9][a-z0-9-_]*$/),
|
|
19012
|
+
displayName: z23.string().trim().min(1),
|
|
19013
|
+
command: z23.string().trim().min(1),
|
|
19014
|
+
args: z23.array(z23.string()),
|
|
19015
|
+
env: z23.record(z23.string(), z23.string()),
|
|
19016
|
+
cwdMode: z23.literal("workspace_root"),
|
|
19017
|
+
sessionMode: z23.literal("interactive"),
|
|
19018
|
+
startupPrompt: z23.string().optional(),
|
|
19019
|
+
capabilities: z23.array(CapabilitySchema).min(1)
|
|
19020
|
+
});
|
|
19021
|
+
registerCommand("customProvider.list", z23.object({}), async (_args, ctx) => {
|
|
19022
|
+
requireCustomProviderSupport(ctx);
|
|
19023
|
+
return ctx.customProviderRepo.list().map((config) => toProviderListItem(buildCustomProviderDefinition(config)));
|
|
19024
|
+
});
|
|
19025
|
+
registerCommand("customProvider.create", BaseCustomProviderInputSchema, async (args, ctx) => {
|
|
19026
|
+
requireCustomProviderSupport(ctx);
|
|
19027
|
+
if (ctx.providerRegistry.some((provider) => provider.id === args.id)) {
|
|
19028
|
+
throw {
|
|
19029
|
+
code: "custom_provider_exists",
|
|
19030
|
+
message: `Provider already exists: ${args.id}`
|
|
19031
|
+
};
|
|
19032
|
+
}
|
|
19033
|
+
const config = materializeConfig(args);
|
|
19034
|
+
const saved = ctx.customProviderRepo.set(config);
|
|
19035
|
+
const definition = buildCustomProviderDefinition(saved);
|
|
19036
|
+
ctx.setProviderRegistry(upsertProviderDefinition(ctx.providerRegistry, definition));
|
|
19037
|
+
return toProviderListItem(definition);
|
|
19038
|
+
});
|
|
19039
|
+
registerCommand("customProvider.update", BaseCustomProviderInputSchema, async (args, ctx) => {
|
|
19040
|
+
requireCustomProviderSupport(ctx);
|
|
19041
|
+
const existing = ctx.customProviderRepo.get(args.id);
|
|
19042
|
+
if (!existing) {
|
|
19043
|
+
throw {
|
|
19044
|
+
code: "custom_provider_not_found",
|
|
19045
|
+
message: `Custom provider not found: ${args.id}`
|
|
19046
|
+
};
|
|
19047
|
+
}
|
|
19048
|
+
const saved = ctx.customProviderRepo.set(materializeConfig(args, existing));
|
|
19049
|
+
const definition = buildCustomProviderDefinition(saved);
|
|
19050
|
+
ctx.setProviderRegistry(upsertProviderDefinition(ctx.providerRegistry, definition));
|
|
19051
|
+
return toProviderListItem(definition);
|
|
19052
|
+
});
|
|
19053
|
+
registerCommand(
|
|
19054
|
+
"customProvider.delete",
|
|
19055
|
+
z23.object({
|
|
19056
|
+
id: z23.string().trim().min(1)
|
|
19057
|
+
}),
|
|
19058
|
+
async (args, ctx) => {
|
|
19059
|
+
requireCustomProviderSupport(ctx);
|
|
19060
|
+
const existing = ctx.customProviderRepo.get(args.id);
|
|
19061
|
+
if (!existing) {
|
|
19062
|
+
throw {
|
|
19063
|
+
code: "custom_provider_not_found",
|
|
19064
|
+
message: `Custom provider not found: ${args.id}`
|
|
19065
|
+
};
|
|
19066
|
+
}
|
|
19067
|
+
ctx.customProviderRepo.delete(args.id);
|
|
19068
|
+
ctx.setProviderRegistry(removeProviderDefinition(ctx.providerRegistry, args.id));
|
|
19069
|
+
return { deleted: true, id: args.id };
|
|
19070
|
+
}
|
|
19071
|
+
);
|
|
19072
|
+
}
|
|
19073
|
+
});
|
|
19074
|
+
|
|
17336
19075
|
// packages/server/src/commands/supervisor.ts
|
|
17337
|
-
import { z as
|
|
19076
|
+
import { z as z24 } from "zod";
|
|
17338
19077
|
var supervisorObjectiveSchema, createSupervisorSchema, updateSupervisorSchema, sessionIdSchema, workspaceIdSchema, supervisorIdSchema, restoreSupervisorSchema;
|
|
17339
19078
|
var init_supervisor2 = __esm({
|
|
17340
19079
|
"packages/server/src/commands/supervisor.ts"() {
|
|
17341
19080
|
"use strict";
|
|
17342
19081
|
init_dispatch();
|
|
17343
|
-
supervisorObjectiveSchema =
|
|
17344
|
-
createSupervisorSchema =
|
|
17345
|
-
sessionId:
|
|
17346
|
-
workspaceId:
|
|
19082
|
+
supervisorObjectiveSchema = z24.string().trim().min(1).max(4e3);
|
|
19083
|
+
createSupervisorSchema = z24.object({
|
|
19084
|
+
sessionId: z24.string(),
|
|
19085
|
+
workspaceId: z24.string(),
|
|
17347
19086
|
objective: supervisorObjectiveSchema,
|
|
17348
|
-
evaluatorProviderId:
|
|
17349
|
-
evaluatorModel:
|
|
17350
|
-
maxSupervisionCount:
|
|
17351
|
-
scheduledAt:
|
|
19087
|
+
evaluatorProviderId: z24.string(),
|
|
19088
|
+
evaluatorModel: z24.string().trim().min(1).max(200).optional(),
|
|
19089
|
+
maxSupervisionCount: z24.number().int().min(0).max(Number.MAX_SAFE_INTEGER).optional(),
|
|
19090
|
+
scheduledAt: z24.number().int().min(0).max(Number.MAX_SAFE_INTEGER).optional()
|
|
17352
19091
|
}).strict();
|
|
17353
|
-
updateSupervisorSchema =
|
|
17354
|
-
id:
|
|
19092
|
+
updateSupervisorSchema = z24.object({
|
|
19093
|
+
id: z24.string(),
|
|
17355
19094
|
objective: supervisorObjectiveSchema.optional(),
|
|
17356
|
-
evaluatorProviderId:
|
|
17357
|
-
evaluatorModel:
|
|
17358
|
-
maxSupervisionCount:
|
|
17359
|
-
scheduledAt:
|
|
19095
|
+
evaluatorProviderId: z24.string().optional(),
|
|
19096
|
+
evaluatorModel: z24.string().trim().min(1).max(200).nullable().optional(),
|
|
19097
|
+
maxSupervisionCount: z24.number().int().min(0).max(Number.MAX_SAFE_INTEGER).optional(),
|
|
19098
|
+
scheduledAt: z24.number().int().min(0).max(Number.MAX_SAFE_INTEGER).nullable().optional()
|
|
17360
19099
|
}).strict().refine(
|
|
17361
19100
|
(input) => input.objective !== void 0 || input.evaluatorProviderId !== void 0 || input.evaluatorModel !== void 0 || input.maxSupervisionCount !== void 0 || input.scheduledAt !== void 0,
|
|
17362
19101
|
"at least one supervisor field is required"
|
|
17363
19102
|
);
|
|
17364
|
-
sessionIdSchema =
|
|
17365
|
-
workspaceIdSchema =
|
|
17366
|
-
supervisorIdSchema =
|
|
17367
|
-
restoreSupervisorSchema =
|
|
17368
|
-
sessionId:
|
|
17369
|
-
workspaceId:
|
|
17370
|
-
sourceTargetId:
|
|
17371
|
-
evaluatorProviderId:
|
|
17372
|
-
evaluatorModel:
|
|
17373
|
-
maxSupervisionCount:
|
|
17374
|
-
scheduledAt:
|
|
19103
|
+
sessionIdSchema = z24.object({ sessionId: z24.string() });
|
|
19104
|
+
workspaceIdSchema = z24.object({ workspaceId: z24.string() });
|
|
19105
|
+
supervisorIdSchema = z24.object({ id: z24.string() });
|
|
19106
|
+
restoreSupervisorSchema = z24.object({
|
|
19107
|
+
sessionId: z24.string(),
|
|
19108
|
+
workspaceId: z24.string(),
|
|
19109
|
+
sourceTargetId: z24.string(),
|
|
19110
|
+
evaluatorProviderId: z24.string(),
|
|
19111
|
+
evaluatorModel: z24.string().trim().min(1).max(200).optional(),
|
|
19112
|
+
maxSupervisionCount: z24.number().int().min(0).max(Number.MAX_SAFE_INTEGER).optional(),
|
|
19113
|
+
scheduledAt: z24.number().int().min(0).max(Number.MAX_SAFE_INTEGER).optional()
|
|
17375
19114
|
}).strict();
|
|
17376
19115
|
registerCommand("supervisor.create", createSupervisorSchema, async (args, ctx) => {
|
|
17377
19116
|
return {
|
|
@@ -17573,7 +19312,7 @@ var init_worktree = __esm({
|
|
|
17573
19312
|
|
|
17574
19313
|
// packages/server/src/commands/worktree.ts
|
|
17575
19314
|
import path13 from "node:path";
|
|
17576
|
-
import { z as
|
|
19315
|
+
import { z as z25 } from "zod";
|
|
17577
19316
|
async function findRelatedWorkspaceIds(ctx, workspacePath) {
|
|
17578
19317
|
const targetCommonDir = await getGitCommonDirPath(workspacePath);
|
|
17579
19318
|
const relatedWorkspaceIds = await Promise.all(
|
|
@@ -17606,7 +19345,7 @@ var init_worktree2 = __esm({
|
|
|
17606
19345
|
init_worktree();
|
|
17607
19346
|
init_dispatch();
|
|
17608
19347
|
init_git_events();
|
|
17609
|
-
registerCommand("worktree.list",
|
|
19348
|
+
registerCommand("worktree.list", z25.object({ workspaceId: z25.string() }), async (args, ctx) => {
|
|
17610
19349
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
17611
19350
|
if (!workspace) {
|
|
17612
19351
|
throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
|
|
@@ -17615,7 +19354,7 @@ var init_worktree2 = __esm({
|
|
|
17615
19354
|
});
|
|
17616
19355
|
registerCommand(
|
|
17617
19356
|
"worktree.status",
|
|
17618
|
-
|
|
19357
|
+
z25.object({ workspaceId: z25.string(), worktreePath: z25.string() }),
|
|
17619
19358
|
async (args, ctx) => {
|
|
17620
19359
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
17621
19360
|
if (!workspace) {
|
|
@@ -17627,10 +19366,10 @@ var init_worktree2 = __esm({
|
|
|
17627
19366
|
);
|
|
17628
19367
|
registerCommand(
|
|
17629
19368
|
"worktree.diff",
|
|
17630
|
-
|
|
17631
|
-
workspaceId:
|
|
17632
|
-
worktreePath:
|
|
17633
|
-
staged:
|
|
19369
|
+
z25.object({
|
|
19370
|
+
workspaceId: z25.string(),
|
|
19371
|
+
worktreePath: z25.string(),
|
|
19372
|
+
staged: z25.boolean().optional().default(false)
|
|
17634
19373
|
}),
|
|
17635
19374
|
async (args, ctx) => {
|
|
17636
19375
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -17643,7 +19382,7 @@ var init_worktree2 = __esm({
|
|
|
17643
19382
|
);
|
|
17644
19383
|
registerCommand(
|
|
17645
19384
|
"worktree.tree",
|
|
17646
|
-
|
|
19385
|
+
z25.object({ workspaceId: z25.string(), worktreePath: z25.string() }),
|
|
17647
19386
|
async (args, ctx) => {
|
|
17648
19387
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
17649
19388
|
if (!workspace) {
|
|
@@ -17655,10 +19394,10 @@ var init_worktree2 = __esm({
|
|
|
17655
19394
|
);
|
|
17656
19395
|
registerCommand(
|
|
17657
19396
|
"worktree.create",
|
|
17658
|
-
|
|
17659
|
-
workspaceId:
|
|
17660
|
-
branch:
|
|
17661
|
-
path:
|
|
19397
|
+
z25.object({
|
|
19398
|
+
workspaceId: z25.string(),
|
|
19399
|
+
branch: z25.string(),
|
|
19400
|
+
path: z25.string()
|
|
17662
19401
|
}),
|
|
17663
19402
|
async (args, ctx) => {
|
|
17664
19403
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -17673,10 +19412,10 @@ var init_worktree2 = __esm({
|
|
|
17673
19412
|
);
|
|
17674
19413
|
registerCommand(
|
|
17675
19414
|
"worktree.remove",
|
|
17676
|
-
|
|
17677
|
-
workspaceId:
|
|
17678
|
-
worktreePath:
|
|
17679
|
-
force:
|
|
19415
|
+
z25.object({
|
|
19416
|
+
workspaceId: z25.string(),
|
|
19417
|
+
worktreePath: z25.string(),
|
|
19418
|
+
force: z25.boolean().optional().default(false)
|
|
17680
19419
|
}),
|
|
17681
19420
|
async (args, ctx) => {
|
|
17682
19421
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -17700,7 +19439,7 @@ var init_worktree2 = __esm({
|
|
|
17700
19439
|
});
|
|
17701
19440
|
|
|
17702
19441
|
// packages/server/src/commands/fencing.ts
|
|
17703
|
-
import { z as
|
|
19442
|
+
import { z as z26 } from "zod";
|
|
17704
19443
|
function createMockFencingRequest() {
|
|
17705
19444
|
return {
|
|
17706
19445
|
ip: "127.0.0.1",
|
|
@@ -17713,9 +19452,9 @@ var init_fencing2 = __esm({
|
|
|
17713
19452
|
init_dispatch();
|
|
17714
19453
|
registerCommand(
|
|
17715
19454
|
"fencing.request",
|
|
17716
|
-
|
|
17717
|
-
workspaceId:
|
|
17718
|
-
tabId:
|
|
19455
|
+
z26.object({
|
|
19456
|
+
workspaceId: z26.string(),
|
|
19457
|
+
tabId: z26.string()
|
|
17719
19458
|
}),
|
|
17720
19459
|
async (args, ctx, clientId) => {
|
|
17721
19460
|
return ctx.fencingMgr.requestControl(
|
|
@@ -17728,7 +19467,7 @@ var init_fencing2 = __esm({
|
|
|
17728
19467
|
);
|
|
17729
19468
|
registerCommand(
|
|
17730
19469
|
"fencing.heartbeat",
|
|
17731
|
-
|
|
19470
|
+
z26.object({ workspaceId: z26.string() }),
|
|
17732
19471
|
async (args, ctx, clientId) => {
|
|
17733
19472
|
const success = ctx.fencingMgr.heartbeat(args.workspaceId, clientId);
|
|
17734
19473
|
return { success };
|
|
@@ -17736,13 +19475,13 @@ var init_fencing2 = __esm({
|
|
|
17736
19475
|
);
|
|
17737
19476
|
registerCommand(
|
|
17738
19477
|
"fencing.release",
|
|
17739
|
-
|
|
19478
|
+
z26.object({ workspaceId: z26.string() }),
|
|
17740
19479
|
async (args, ctx, clientId) => {
|
|
17741
19480
|
ctx.fencingMgr.release(args.workspaceId, clientId);
|
|
17742
19481
|
return {};
|
|
17743
19482
|
}
|
|
17744
19483
|
);
|
|
17745
|
-
registerCommand("fencing.status",
|
|
19484
|
+
registerCommand("fencing.status", z26.object({ workspaceId: z26.string() }), async (args, ctx) => {
|
|
17746
19485
|
const controller = ctx.fencingMgr.getController(args.workspaceId);
|
|
17747
19486
|
const isUnresponsive = ctx.fencingMgr.isControllerUnresponsive(args.workspaceId);
|
|
17748
19487
|
return {
|
|
@@ -17753,9 +19492,9 @@ var init_fencing2 = __esm({
|
|
|
17753
19492
|
});
|
|
17754
19493
|
registerCommand(
|
|
17755
19494
|
"fencing.takeover",
|
|
17756
|
-
|
|
17757
|
-
workspaceId:
|
|
17758
|
-
tabId:
|
|
19495
|
+
z26.object({
|
|
19496
|
+
workspaceId: z26.string(),
|
|
19497
|
+
tabId: z26.string()
|
|
17759
19498
|
}),
|
|
17760
19499
|
async (args, ctx, clientId) => {
|
|
17761
19500
|
return ctx.fencingMgr.forceTakeover(
|
|
@@ -17793,7 +19532,7 @@ var init_runtime_status2 = __esm({
|
|
|
17793
19532
|
});
|
|
17794
19533
|
|
|
17795
19534
|
// packages/server/src/commands/lsp.ts
|
|
17796
|
-
import { z as
|
|
19535
|
+
import { z as z27 } from "zod";
|
|
17797
19536
|
var init_lsp2 = __esm({
|
|
17798
19537
|
"packages/server/src/commands/lsp.ts"() {
|
|
17799
19538
|
"use strict";
|
|
@@ -17801,16 +19540,16 @@ var init_lsp2 = __esm({
|
|
|
17801
19540
|
init_dispatch();
|
|
17802
19541
|
registerCommand(
|
|
17803
19542
|
"lsp.ensureSession",
|
|
17804
|
-
|
|
17805
|
-
workspaceId:
|
|
17806
|
-
path:
|
|
19543
|
+
z27.object({
|
|
19544
|
+
workspaceId: z27.string(),
|
|
19545
|
+
path: z27.string()
|
|
17807
19546
|
}),
|
|
17808
19547
|
async (args, ctx) => ctx.lspMgr.ensureSession(args)
|
|
17809
19548
|
);
|
|
17810
19549
|
registerCommand(
|
|
17811
19550
|
"lsp.setMode",
|
|
17812
|
-
|
|
17813
|
-
mode:
|
|
19551
|
+
z27.object({
|
|
19552
|
+
mode: z27.enum(["auto", "off"])
|
|
17814
19553
|
}),
|
|
17815
19554
|
async (args, ctx) => {
|
|
17816
19555
|
await ctx.lspMgr.setRuntimeMode(args.mode);
|
|
@@ -17819,8 +19558,8 @@ var init_lsp2 = __esm({
|
|
|
17819
19558
|
);
|
|
17820
19559
|
registerCommand(
|
|
17821
19560
|
"lsp.runtimeStatus",
|
|
17822
|
-
|
|
17823
|
-
workspaceId:
|
|
19561
|
+
z27.object({
|
|
19562
|
+
workspaceId: z27.string()
|
|
17824
19563
|
}),
|
|
17825
19564
|
async (args, ctx) => {
|
|
17826
19565
|
if (!ctx.lspToolMgr) {
|
|
@@ -17844,9 +19583,9 @@ var init_lsp2 = __esm({
|
|
|
17844
19583
|
);
|
|
17845
19584
|
registerCommand(
|
|
17846
19585
|
"lsp.install.start",
|
|
17847
|
-
|
|
17848
|
-
workspaceId:
|
|
17849
|
-
serverKind:
|
|
19586
|
+
z27.object({
|
|
19587
|
+
workspaceId: z27.string(),
|
|
19588
|
+
serverKind: z27.enum(["typescript", "python", "go", "rust"])
|
|
17850
19589
|
}),
|
|
17851
19590
|
async (args, ctx) => {
|
|
17852
19591
|
if (!ctx.lspToolInstallMgr) {
|
|
@@ -17870,8 +19609,8 @@ var init_lsp2 = __esm({
|
|
|
17870
19609
|
);
|
|
17871
19610
|
registerCommand(
|
|
17872
19611
|
"lsp.install.get",
|
|
17873
|
-
|
|
17874
|
-
jobId:
|
|
19612
|
+
z27.object({
|
|
19613
|
+
jobId: z27.string()
|
|
17875
19614
|
}),
|
|
17876
19615
|
async (args, ctx) => {
|
|
17877
19616
|
if (!ctx.lspToolInstallMgr) {
|
|
@@ -17892,86 +19631,86 @@ var init_lsp2 = __esm({
|
|
|
17892
19631
|
);
|
|
17893
19632
|
registerCommand(
|
|
17894
19633
|
"lsp.openDocument",
|
|
17895
|
-
|
|
17896
|
-
workspaceId:
|
|
17897
|
-
path:
|
|
17898
|
-
languageId:
|
|
17899
|
-
text:
|
|
19634
|
+
z27.object({
|
|
19635
|
+
workspaceId: z27.string(),
|
|
19636
|
+
path: z27.string(),
|
|
19637
|
+
languageId: z27.string(),
|
|
19638
|
+
text: z27.string()
|
|
17900
19639
|
}),
|
|
17901
19640
|
async (args, ctx) => ctx.lspMgr.openDocument(args)
|
|
17902
19641
|
);
|
|
17903
19642
|
registerCommand(
|
|
17904
19643
|
"lsp.changeDocument",
|
|
17905
|
-
|
|
17906
|
-
workspaceId:
|
|
17907
|
-
path:
|
|
17908
|
-
text:
|
|
19644
|
+
z27.object({
|
|
19645
|
+
workspaceId: z27.string(),
|
|
19646
|
+
path: z27.string(),
|
|
19647
|
+
text: z27.string()
|
|
17909
19648
|
}),
|
|
17910
19649
|
async (args, ctx) => ctx.lspMgr.changeDocument(args)
|
|
17911
19650
|
);
|
|
17912
19651
|
registerCommand(
|
|
17913
19652
|
"lsp.closeDocument",
|
|
17914
|
-
|
|
17915
|
-
workspaceId:
|
|
17916
|
-
path:
|
|
19653
|
+
z27.object({
|
|
19654
|
+
workspaceId: z27.string(),
|
|
19655
|
+
path: z27.string()
|
|
17917
19656
|
}),
|
|
17918
19657
|
async (args, ctx) => ctx.lspMgr.closeDocument(args)
|
|
17919
19658
|
);
|
|
17920
19659
|
registerCommand(
|
|
17921
19660
|
"lsp.definition",
|
|
17922
|
-
|
|
17923
|
-
workspaceId:
|
|
17924
|
-
path:
|
|
17925
|
-
line:
|
|
17926
|
-
column:
|
|
19661
|
+
z27.object({
|
|
19662
|
+
workspaceId: z27.string(),
|
|
19663
|
+
path: z27.string(),
|
|
19664
|
+
line: z27.number().int().positive(),
|
|
19665
|
+
column: z27.number().int().positive()
|
|
17927
19666
|
}),
|
|
17928
19667
|
async (args, ctx) => ctx.lspMgr.definition(args)
|
|
17929
19668
|
);
|
|
17930
19669
|
registerCommand(
|
|
17931
19670
|
"lsp.declaration",
|
|
17932
|
-
|
|
17933
|
-
workspaceId:
|
|
17934
|
-
path:
|
|
17935
|
-
line:
|
|
17936
|
-
column:
|
|
19671
|
+
z27.object({
|
|
19672
|
+
workspaceId: z27.string(),
|
|
19673
|
+
path: z27.string(),
|
|
19674
|
+
line: z27.number().int().positive(),
|
|
19675
|
+
column: z27.number().int().positive()
|
|
17937
19676
|
}),
|
|
17938
19677
|
async (args, ctx) => ctx.lspMgr.declaration(args)
|
|
17939
19678
|
);
|
|
17940
19679
|
registerCommand(
|
|
17941
19680
|
"lsp.typeDefinition",
|
|
17942
|
-
|
|
17943
|
-
workspaceId:
|
|
17944
|
-
path:
|
|
17945
|
-
line:
|
|
17946
|
-
column:
|
|
19681
|
+
z27.object({
|
|
19682
|
+
workspaceId: z27.string(),
|
|
19683
|
+
path: z27.string(),
|
|
19684
|
+
line: z27.number().int().positive(),
|
|
19685
|
+
column: z27.number().int().positive()
|
|
17947
19686
|
}),
|
|
17948
19687
|
async (args, ctx) => ctx.lspMgr.typeDefinition(args)
|
|
17949
19688
|
);
|
|
17950
19689
|
registerCommand(
|
|
17951
19690
|
"lsp.references",
|
|
17952
|
-
|
|
17953
|
-
workspaceId:
|
|
17954
|
-
path:
|
|
17955
|
-
line:
|
|
17956
|
-
column:
|
|
19691
|
+
z27.object({
|
|
19692
|
+
workspaceId: z27.string(),
|
|
19693
|
+
path: z27.string(),
|
|
19694
|
+
line: z27.number().int().positive(),
|
|
19695
|
+
column: z27.number().int().positive()
|
|
17957
19696
|
}),
|
|
17958
19697
|
async (args, ctx) => ctx.lspMgr.references(args)
|
|
17959
19698
|
);
|
|
17960
19699
|
registerCommand(
|
|
17961
19700
|
"lsp.hover",
|
|
17962
|
-
|
|
17963
|
-
workspaceId:
|
|
17964
|
-
path:
|
|
17965
|
-
line:
|
|
17966
|
-
column:
|
|
19701
|
+
z27.object({
|
|
19702
|
+
workspaceId: z27.string(),
|
|
19703
|
+
path: z27.string(),
|
|
19704
|
+
line: z27.number().int().positive(),
|
|
19705
|
+
column: z27.number().int().positive()
|
|
17967
19706
|
}),
|
|
17968
19707
|
async (args, ctx) => ctx.lspMgr.hover(args)
|
|
17969
19708
|
);
|
|
17970
19709
|
registerCommand(
|
|
17971
19710
|
"lsp.documentSymbols",
|
|
17972
|
-
|
|
17973
|
-
workspaceId:
|
|
17974
|
-
path:
|
|
19711
|
+
z27.object({
|
|
19712
|
+
workspaceId: z27.string(),
|
|
19713
|
+
path: z27.string()
|
|
17975
19714
|
}),
|
|
17976
19715
|
async (args, ctx) => ctx.lspMgr.documentSymbols(args)
|
|
17977
19716
|
);
|
|
@@ -17979,12 +19718,12 @@ var init_lsp2 = __esm({
|
|
|
17979
19718
|
});
|
|
17980
19719
|
|
|
17981
19720
|
// packages/server/src/commands/updates.ts
|
|
17982
|
-
import { z as
|
|
19721
|
+
import { z as z28 } from "zod";
|
|
17983
19722
|
var init_updates = __esm({
|
|
17984
19723
|
"packages/server/src/commands/updates.ts"() {
|
|
17985
19724
|
"use strict";
|
|
17986
19725
|
init_dispatch();
|
|
17987
|
-
registerCommand("updates.getState",
|
|
19726
|
+
registerCommand("updates.getState", z28.object({}).default({}), async (_args, ctx) => {
|
|
17988
19727
|
if (!ctx.updateService) {
|
|
17989
19728
|
throw {
|
|
17990
19729
|
code: "update_unavailable",
|
|
@@ -17993,7 +19732,7 @@ var init_updates = __esm({
|
|
|
17993
19732
|
}
|
|
17994
19733
|
return ctx.updateService.getStateView();
|
|
17995
19734
|
});
|
|
17996
|
-
registerCommand("updates.check",
|
|
19735
|
+
registerCommand("updates.check", z28.object({}).default({}), async (_args, ctx) => {
|
|
17997
19736
|
if (!ctx.updateService) {
|
|
17998
19737
|
throw {
|
|
17999
19738
|
code: "update_unavailable",
|
|
@@ -18002,7 +19741,7 @@ var init_updates = __esm({
|
|
|
18002
19741
|
}
|
|
18003
19742
|
return await ctx.updateService.checkForUpdates({ manual: true });
|
|
18004
19743
|
});
|
|
18005
|
-
registerCommand("updates.prepareInstall",
|
|
19744
|
+
registerCommand("updates.prepareInstall", z28.object({}).default({}), async (_args, ctx) => {
|
|
18006
19745
|
if (!ctx.updateService) {
|
|
18007
19746
|
throw {
|
|
18008
19747
|
code: "update_unavailable",
|
|
@@ -18013,9 +19752,9 @@ var init_updates = __esm({
|
|
|
18013
19752
|
});
|
|
18014
19753
|
registerCommand(
|
|
18015
19754
|
"updates.startInstall",
|
|
18016
|
-
|
|
18017
|
-
targetVersion:
|
|
18018
|
-
force:
|
|
19755
|
+
z28.object({
|
|
19756
|
+
targetVersion: z28.string().optional(),
|
|
19757
|
+
force: z28.boolean().optional()
|
|
18019
19758
|
}),
|
|
18020
19759
|
async (args, ctx) => {
|
|
18021
19760
|
if (!ctx.updateService) {
|
|
@@ -18040,12 +19779,17 @@ var init_commands = __esm({
|
|
|
18040
19779
|
init_connection();
|
|
18041
19780
|
init_recovery();
|
|
18042
19781
|
init_session2();
|
|
19782
|
+
init_session_metadata();
|
|
19783
|
+
init_session_review();
|
|
18043
19784
|
init_terminal();
|
|
18044
19785
|
init_file();
|
|
18045
19786
|
init_git2();
|
|
19787
|
+
init_agent_instructions();
|
|
19788
|
+
init_agent_context();
|
|
18046
19789
|
init_settings2();
|
|
18047
19790
|
init_diagnostics2();
|
|
18048
19791
|
init_provider();
|
|
19792
|
+
init_custom_provider2();
|
|
18049
19793
|
init_supervisor2();
|
|
18050
19794
|
init_worktree2();
|
|
18051
19795
|
init_fencing2();
|
|
@@ -18057,12 +19801,12 @@ var init_commands = __esm({
|
|
|
18057
19801
|
// packages/server/src/server.ts
|
|
18058
19802
|
import { mkdtempSync, rmSync as rmSync2 } from "node:fs";
|
|
18059
19803
|
import { tmpdir } from "node:os";
|
|
18060
|
-
import { join as
|
|
19804
|
+
import { join as join18 } from "node:path";
|
|
18061
19805
|
async function createServer(configOverrides) {
|
|
18062
19806
|
const config = parseServerConfig(configOverrides);
|
|
18063
19807
|
const configuredStateDir = resolveConfiguredStateDir(config);
|
|
18064
19808
|
const shouldCleanupStateRoot = configuredStateDir === IN_MEMORY_STATE_DIR;
|
|
18065
|
-
const stateRoot = shouldCleanupStateRoot ? mkdtempSync(
|
|
19809
|
+
const stateRoot = shouldCleanupStateRoot ? mkdtempSync(join18(tmpdir(), "coder-studio-state-")) : configuredStateDir;
|
|
18066
19810
|
ensureStateDir(config);
|
|
18067
19811
|
const eventBus = new EventBus();
|
|
18068
19812
|
const activationMgr = new ActivationManager();
|
|
@@ -18072,10 +19816,10 @@ async function createServer(configOverrides) {
|
|
|
18072
19816
|
let commandContext;
|
|
18073
19817
|
let lspMgr = null;
|
|
18074
19818
|
const terminalRepo = new TerminalRepo({
|
|
18075
|
-
filePath:
|
|
19819
|
+
filePath: join18(stateRoot, "state", "terminals.json")
|
|
18076
19820
|
});
|
|
18077
19821
|
const sessionRepo = new SessionRepo({
|
|
18078
|
-
filePath:
|
|
19822
|
+
filePath: join18(stateRoot, "state", "sessions.json")
|
|
18079
19823
|
});
|
|
18080
19824
|
const terminalMgr = new TerminalManager({
|
|
18081
19825
|
ptyHost: createPtyHost(),
|
|
@@ -18083,10 +19827,10 @@ async function createServer(configOverrides) {
|
|
|
18083
19827
|
db: terminalRepo
|
|
18084
19828
|
});
|
|
18085
19829
|
const settingsRepo = new SettingsRepo({
|
|
18086
|
-
filePath:
|
|
19830
|
+
filePath: join18(stateRoot, "state", "settings.json")
|
|
18087
19831
|
});
|
|
18088
19832
|
const updateStateRepo = new UpdateStateRepo({
|
|
18089
|
-
filePath:
|
|
19833
|
+
filePath: join18(stateRoot, "state", "update-state.json"),
|
|
18090
19834
|
currentVersion: config.appVersion ?? "0.0.0"
|
|
18091
19835
|
});
|
|
18092
19836
|
const autoFetch = new AutoFetchScheduler({
|
|
@@ -18119,17 +19863,27 @@ async function createServer(configOverrides) {
|
|
|
18119
19863
|
}
|
|
18120
19864
|
});
|
|
18121
19865
|
const providerConfigRepo = new ProviderConfigRepo({
|
|
18122
|
-
filePath:
|
|
19866
|
+
filePath: join18(stateRoot, "state", "provider-configs.json")
|
|
19867
|
+
});
|
|
19868
|
+
const customProviderRepo = new CustomProviderRepo({
|
|
19869
|
+
filePath: join18(stateRoot, "state", "custom-providers.json")
|
|
18123
19870
|
});
|
|
18124
19871
|
const workspaceRepo = new WorkspaceRepo({
|
|
18125
|
-
filePath:
|
|
19872
|
+
filePath: join18(stateRoot, "state", "workspaces.json")
|
|
19873
|
+
});
|
|
19874
|
+
const sessionMetadataRepo = new SessionMetadataRepo({
|
|
19875
|
+
workspaceRepo
|
|
18126
19876
|
});
|
|
19877
|
+
let activeProviderRegistry = [
|
|
19878
|
+
...providerRegistry,
|
|
19879
|
+
...customProviderRepo.list().map((config2) => buildCustomProviderDefinition(config2))
|
|
19880
|
+
];
|
|
18127
19881
|
const sessionMgr = new SessionManager({
|
|
18128
19882
|
terminalMgr,
|
|
18129
19883
|
eventBus,
|
|
18130
19884
|
db: sessionRepo,
|
|
18131
19885
|
broadcaster: wsHub,
|
|
18132
|
-
providerRegistry,
|
|
19886
|
+
providerRegistry: activeProviderRegistry,
|
|
18133
19887
|
providerConfigRepo
|
|
18134
19888
|
});
|
|
18135
19889
|
let supervisorMgr;
|
|
@@ -18140,13 +19894,15 @@ async function createServer(configOverrides) {
|
|
|
18140
19894
|
broadcaster: wsHub,
|
|
18141
19895
|
autoFetch,
|
|
18142
19896
|
teardown: async (workspaceId) => {
|
|
19897
|
+
const persistedSessions = sessionRepo.findByWorkspaceId(workspaceId);
|
|
18143
19898
|
await lspMgr?.disposeWorkspace(workspaceId);
|
|
18144
19899
|
await supervisorMgr?.deleteForWorkspace(workspaceId);
|
|
18145
19900
|
await sessionMgr.stopForWorkspace(workspaceId);
|
|
18146
19901
|
await terminalMgr.closeForWorkspace(workspaceId);
|
|
18147
19902
|
sessionMgr.deleteEndedForWorkspace(workspaceId);
|
|
18148
|
-
for (const session of
|
|
19903
|
+
for (const session of persistedSessions) {
|
|
18149
19904
|
sessionRepo.delete(session.id);
|
|
19905
|
+
sessionMetadataRepo.delete(session.id);
|
|
18150
19906
|
}
|
|
18151
19907
|
for (const terminal of terminalRepo.listByWorkspace(workspaceId)) {
|
|
18152
19908
|
terminalRepo.delete(terminal.id);
|
|
@@ -18157,13 +19913,13 @@ async function createServer(configOverrides) {
|
|
|
18157
19913
|
)
|
|
18158
19914
|
});
|
|
18159
19915
|
const authSessionRepo = new AuthSessionRepo({
|
|
18160
|
-
filePath:
|
|
19916
|
+
filePath: join18(stateRoot, "state", "auth-sessions.json")
|
|
18161
19917
|
});
|
|
18162
19918
|
const authLoginBlockRepo = new AuthLoginBlockRepo({
|
|
18163
|
-
filePath:
|
|
19919
|
+
filePath: join18(stateRoot, "state", "auth-login-blocks.json")
|
|
18164
19920
|
});
|
|
18165
19921
|
const appearanceAssetRepo = new AppearanceAssetRepo({
|
|
18166
|
-
filePath:
|
|
19922
|
+
filePath: join18(stateRoot, "state", "appearance-assets.json")
|
|
18167
19923
|
});
|
|
18168
19924
|
const app = await buildFastifyApp({
|
|
18169
19925
|
wsHub,
|
|
@@ -18214,7 +19970,7 @@ async function createServer(configOverrides) {
|
|
|
18214
19970
|
terminalMgr,
|
|
18215
19971
|
workspaceMgr,
|
|
18216
19972
|
sessionMgr,
|
|
18217
|
-
providerRegistry,
|
|
19973
|
+
providerRegistry: activeProviderRegistry,
|
|
18218
19974
|
providerConfigRepo,
|
|
18219
19975
|
settingsRepo,
|
|
18220
19976
|
supervisorRepo,
|
|
@@ -18227,7 +19983,7 @@ async function createServer(configOverrides) {
|
|
|
18227
19983
|
const providerRuntimeDeps = providerMockOverrides ? {
|
|
18228
19984
|
commandExists: providerMockOverrides.commandExists
|
|
18229
19985
|
} : {};
|
|
18230
|
-
const providerInstallMgr = new ProviderInstallManager(
|
|
19986
|
+
const providerInstallMgr = new ProviderInstallManager(activeProviderRegistry, {
|
|
18231
19987
|
...providerRuntimeDeps,
|
|
18232
19988
|
runCommand: providerMockOverrides?.runCommand ?? runCommandAsString
|
|
18233
19989
|
});
|
|
@@ -18239,7 +19995,7 @@ async function createServer(configOverrides) {
|
|
|
18239
19995
|
...config.update,
|
|
18240
19996
|
currentVersion: config.appVersion ?? "0.0.0"
|
|
18241
19997
|
},
|
|
18242
|
-
updateWorkerLogFilePath:
|
|
19998
|
+
updateWorkerLogFilePath: join18(stateRoot, "logs", "update-worker.log"),
|
|
18243
19999
|
countRunningTerminals: () => terminalMgr.getAll().filter((terminal) => terminal.alive).length,
|
|
18244
20000
|
countRunningSessions: () => sessionMgr.getAll().filter((session) => session.state === "starting" || session.state === "running").length,
|
|
18245
20001
|
countActiveSupervisors: () => supervisorMgr?.countActive() ?? 0
|
|
@@ -18253,7 +20009,7 @@ async function createServer(configOverrides) {
|
|
|
18253
20009
|
broadcaster: wsHub,
|
|
18254
20010
|
settingsRepo,
|
|
18255
20011
|
providerConfigRepo,
|
|
18256
|
-
providerRegistry,
|
|
20012
|
+
providerRegistry: activeProviderRegistry,
|
|
18257
20013
|
fencingMgr,
|
|
18258
20014
|
supervisorMgr,
|
|
18259
20015
|
autoFetch,
|
|
@@ -18264,7 +20020,16 @@ async function createServer(configOverrides) {
|
|
|
18264
20020
|
lspMgr,
|
|
18265
20021
|
lspToolMgr,
|
|
18266
20022
|
lspToolInstallMgr,
|
|
18267
|
-
updateService
|
|
20023
|
+
updateService,
|
|
20024
|
+
customProviderRepo,
|
|
20025
|
+
sessionMetadataRepo,
|
|
20026
|
+
setProviderRegistry: (providers) => {
|
|
20027
|
+
activeProviderRegistry = providers;
|
|
20028
|
+
commandContext.providerRegistry = providers;
|
|
20029
|
+
providerInstallMgr.setProviders(providers);
|
|
20030
|
+
sessionMgr.setProviderRegistry(providers);
|
|
20031
|
+
supervisorMgr?.setProviderRegistry(providers);
|
|
20032
|
+
}
|
|
18268
20033
|
};
|
|
18269
20034
|
wsHub.setCommandContext(commandContext);
|
|
18270
20035
|
await app.listen({
|
|
@@ -18348,13 +20113,16 @@ var init_server = __esm({
|
|
|
18348
20113
|
init_manifest_store();
|
|
18349
20114
|
init_tool_root();
|
|
18350
20115
|
init_command_runner();
|
|
20116
|
+
init_custom_provider();
|
|
18351
20117
|
init_e2e_provider_mock();
|
|
18352
20118
|
init_install_manager2();
|
|
18353
20119
|
init_manager3();
|
|
18354
20120
|
init_appearance_asset_repo();
|
|
18355
20121
|
init_auth_login_block_repo();
|
|
18356
20122
|
init_auth_session_repo();
|
|
20123
|
+
init_custom_provider_repo();
|
|
18357
20124
|
init_provider_config_repo();
|
|
20125
|
+
init_session_metadata_repo();
|
|
18358
20126
|
init_session_repo();
|
|
18359
20127
|
init_settings_repo();
|
|
18360
20128
|
init_supervisor_repo();
|
|
@@ -18397,7 +20165,9 @@ var init_storage = __esm({
|
|
|
18397
20165
|
"use strict";
|
|
18398
20166
|
init_auth_login_block_repo();
|
|
18399
20167
|
init_auth_session_repo();
|
|
20168
|
+
init_custom_provider_repo();
|
|
18400
20169
|
init_provider_config_repo();
|
|
20170
|
+
init_session_metadata_repo();
|
|
18401
20171
|
init_session_repo();
|
|
18402
20172
|
init_settings_repo();
|
|
18403
20173
|
init_supervisor_repo();
|
|
@@ -18425,10 +20195,12 @@ __export(src_exports, {
|
|
|
18425
20195
|
ActiveTerminal: () => ActiveTerminal,
|
|
18426
20196
|
AuthLoginBlockRepo: () => AuthLoginBlockRepo,
|
|
18427
20197
|
AuthSessionRepo: () => AuthSessionRepo,
|
|
20198
|
+
CustomProviderRepo: () => CustomProviderRepo,
|
|
18428
20199
|
EventBus: () => EventBus,
|
|
18429
20200
|
NodePtyHost: () => NodePtyHost,
|
|
18430
20201
|
ProviderConfigRepo: () => ProviderConfigRepo,
|
|
18431
20202
|
RingBuffer: () => RingBuffer,
|
|
20203
|
+
SessionMetadataRepo: () => SessionMetadataRepo,
|
|
18432
20204
|
SessionRepo: () => SessionRepo,
|
|
18433
20205
|
SettingsRepo: () => SettingsRepo,
|
|
18434
20206
|
SupervisorRepo: () => SupervisorRepo,
|
|
@@ -18470,9 +20242,9 @@ import { fileURLToPath as fileURLToPath4 } from "url";
|
|
|
18470
20242
|
init_state_paths();
|
|
18471
20243
|
import { existsSync as existsSync10, mkdirSync as mkdirSync8, readFileSync as readFileSync8, writeFileSync as writeFileSync6 } from "fs";
|
|
18472
20244
|
import { homedir as homedir4 } from "os";
|
|
18473
|
-
import { join as
|
|
20245
|
+
import { join as join19 } from "path";
|
|
18474
20246
|
function getCliConfigPath() {
|
|
18475
|
-
return
|
|
20247
|
+
return join19(homedir4(), ".coder-studio", "config.json");
|
|
18476
20248
|
}
|
|
18477
20249
|
function normalizeLegacyDataDir(input) {
|
|
18478
20250
|
return normalizeLegacyStateDir(input);
|
|
@@ -18500,11 +20272,11 @@ function readCliConfig() {
|
|
|
18500
20272
|
|
|
18501
20273
|
// packages/cli/src/embed.ts
|
|
18502
20274
|
import { existsSync as existsSync11 } from "fs";
|
|
18503
|
-
import { dirname as dirname8, resolve as
|
|
20275
|
+
import { dirname as dirname8, resolve as resolve7 } from "path";
|
|
18504
20276
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
18505
20277
|
var __filename = fileURLToPath2(import.meta.url);
|
|
18506
20278
|
var __dirname = dirname8(__filename);
|
|
18507
|
-
var WEB_ASSETS_DIR =
|
|
20279
|
+
var WEB_ASSETS_DIR = resolve7(__dirname, "../web");
|
|
18508
20280
|
function getStaticAssetsDir() {
|
|
18509
20281
|
return WEB_ASSETS_DIR;
|
|
18510
20282
|
}
|
|
@@ -18568,13 +20340,13 @@ function getCliPackageName(importMetaUrl) {
|
|
|
18568
20340
|
|
|
18569
20341
|
// packages/cli/src/update-runtime.ts
|
|
18570
20342
|
import { existsSync as existsSync13 } from "node:fs";
|
|
18571
|
-
import { dirname as dirname9, join as
|
|
20343
|
+
import { dirname as dirname9, join as join20 } from "node:path";
|
|
18572
20344
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
18573
20345
|
function resolveWorkerEntryPath(importMetaUrl) {
|
|
18574
20346
|
const currentDir = dirname9(fileURLToPath3(importMetaUrl));
|
|
18575
20347
|
const candidates = [
|
|
18576
|
-
|
|
18577
|
-
|
|
20348
|
+
join20(currentDir, "update-worker.mjs"),
|
|
20349
|
+
join20(currentDir, "../src/update-worker.ts")
|
|
18578
20350
|
];
|
|
18579
20351
|
return candidates.find((candidate) => existsSync13(candidate));
|
|
18580
20352
|
}
|