@spencer-kit/coder-studio 0.4.7 → 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 +8 -0
- package/dist/esm/bin.mjs +2604 -895
- package/dist/esm/bin.mjs.map +4 -4
- package/dist/esm/server-runner.mjs +2576 -867
- package/dist/esm/server-runner.mjs.map +4 -4
- package/dist/web/assets/{components-BC_6z_aX.css → components-D5qT9_xF.css} +1 -1
- package/dist/web/assets/{components-ynft7c9H.js → components-DmD8Ga_M.js} +7 -7
- package/dist/web/assets/components-DmD8Ga_M.js.map +1 -0
- package/dist/web/assets/{main-BMKYuTcM.js → main-C9Cqb7HD.js} +2 -2
- package/dist/web/assets/{main-BMKYuTcM.js.map → main-C9Cqb7HD.js.map} +1 -1
- package/dist/web/assets/{ui-preview-BC1JKu3-.js → ui-preview-DOaeyhSh.js} +2 -2
- package/dist/web/assets/{ui-preview-BC1JKu3-.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 +1 -1
- package/dist/web/assets/components-ynft7c9H.js.map +0 -1
package/dist/esm/bin.mjs
CHANGED
|
@@ -647,7 +647,15 @@ var init_definition = __esm({
|
|
|
647
647
|
id: "claude",
|
|
648
648
|
displayName: "Claude Code",
|
|
649
649
|
badge: "Claude",
|
|
650
|
+
kind: "built_in",
|
|
650
651
|
capability: "full",
|
|
652
|
+
capabilities: [
|
|
653
|
+
{ key: "interactive_session", supported: true, label: "Interactive session" },
|
|
654
|
+
{ key: "supervisor_eval", supported: true, label: "Supervisor evaluation" },
|
|
655
|
+
{ key: "idle_detection", supported: true, label: "Idle detection" },
|
|
656
|
+
{ key: "context_attach", supported: false, label: "Context attach" },
|
|
657
|
+
{ key: "review", supported: false, label: "Review" }
|
|
658
|
+
],
|
|
651
659
|
install: claudeInstallMetadata,
|
|
652
660
|
// ===== Command construction =====
|
|
653
661
|
buildCommand(config, ctx) {
|
|
@@ -817,7 +825,15 @@ var init_definition2 = __esm({
|
|
|
817
825
|
id: "codex",
|
|
818
826
|
displayName: "Codex",
|
|
819
827
|
badge: "Codex",
|
|
828
|
+
kind: "built_in",
|
|
820
829
|
capability: "full",
|
|
830
|
+
capabilities: [
|
|
831
|
+
{ key: "interactive_session", supported: true, label: "Interactive session" },
|
|
832
|
+
{ key: "supervisor_eval", supported: true, label: "Supervisor evaluation" },
|
|
833
|
+
{ key: "idle_detection", supported: true, label: "Idle detection" },
|
|
834
|
+
{ key: "context_attach", supported: false, label: "Context attach" },
|
|
835
|
+
{ key: "review", supported: false, label: "Review" }
|
|
836
|
+
],
|
|
821
837
|
install: codexInstallMetadata,
|
|
822
838
|
// ===== Command construction =====
|
|
823
839
|
buildCommand(config, ctx) {
|
|
@@ -850,7 +866,78 @@ var init_definition2 = __esm({
|
|
|
850
866
|
}
|
|
851
867
|
});
|
|
852
868
|
|
|
869
|
+
// packages/providers/src/presets.ts
|
|
870
|
+
function cloneCapabilities(capabilities) {
|
|
871
|
+
return capabilities.map((capability) => ({ ...capability }));
|
|
872
|
+
}
|
|
873
|
+
var defaultCapabilities, providerPresets;
|
|
874
|
+
var init_presets = __esm({
|
|
875
|
+
"packages/providers/src/presets.ts"() {
|
|
876
|
+
"use strict";
|
|
877
|
+
defaultCapabilities = [
|
|
878
|
+
{ key: "interactive_session", supported: true, label: "Interactive session" },
|
|
879
|
+
{ key: "context_attach", supported: true, label: "Context attach" },
|
|
880
|
+
{ key: "review", supported: true, label: "Review" }
|
|
881
|
+
];
|
|
882
|
+
providerPresets = [
|
|
883
|
+
{
|
|
884
|
+
id: "gemini-cli",
|
|
885
|
+
displayName: "Gemini CLI",
|
|
886
|
+
kind: "preset",
|
|
887
|
+
description: "Preset metadata for launching Google's Gemini CLI through the custom provider flow.",
|
|
888
|
+
command: "gemini",
|
|
889
|
+
args: [],
|
|
890
|
+
env: {},
|
|
891
|
+
cwdMode: "workspace_root",
|
|
892
|
+
sessionMode: "interactive",
|
|
893
|
+
startupPrompt: "Follow the workspace instructions and explain important tradeoffs.",
|
|
894
|
+
capabilities: cloneCapabilities(defaultCapabilities),
|
|
895
|
+
requiredCommands: ["gemini"]
|
|
896
|
+
},
|
|
897
|
+
{
|
|
898
|
+
id: "aider",
|
|
899
|
+
displayName: "Aider",
|
|
900
|
+
kind: "preset",
|
|
901
|
+
description: "Preset metadata for launching Aider as a workspace-root interactive coding agent.",
|
|
902
|
+
command: "aider",
|
|
903
|
+
args: [],
|
|
904
|
+
env: {},
|
|
905
|
+
cwdMode: "workspace_root",
|
|
906
|
+
sessionMode: "interactive",
|
|
907
|
+
startupPrompt: "Review the current workspace state before making edits.",
|
|
908
|
+
capabilities: cloneCapabilities(defaultCapabilities),
|
|
909
|
+
requiredCommands: ["aider"]
|
|
910
|
+
},
|
|
911
|
+
{
|
|
912
|
+
id: "opencode",
|
|
913
|
+
displayName: "OpenCode",
|
|
914
|
+
kind: "preset",
|
|
915
|
+
description: "Preset metadata for launching OpenCode from the workspace root.",
|
|
916
|
+
command: "opencode",
|
|
917
|
+
args: [],
|
|
918
|
+
env: {},
|
|
919
|
+
cwdMode: "workspace_root",
|
|
920
|
+
sessionMode: "interactive",
|
|
921
|
+
startupPrompt: "Use the repository instructions and verify changes before finishing.",
|
|
922
|
+
capabilities: cloneCapabilities(defaultCapabilities),
|
|
923
|
+
requiredCommands: ["opencode"]
|
|
924
|
+
}
|
|
925
|
+
];
|
|
926
|
+
}
|
|
927
|
+
});
|
|
928
|
+
|
|
853
929
|
// packages/providers/src/registry.ts
|
|
930
|
+
function toProviderListItem(provider) {
|
|
931
|
+
return {
|
|
932
|
+
id: provider.id,
|
|
933
|
+
displayName: provider.displayName,
|
|
934
|
+
badge: provider.badge,
|
|
935
|
+
kind: provider.kind,
|
|
936
|
+
capability: provider.capability,
|
|
937
|
+
capabilities: provider.capabilities.map((capability) => ({ ...capability })),
|
|
938
|
+
requiredCommands: [...provider.requiredCommands]
|
|
939
|
+
};
|
|
940
|
+
}
|
|
854
941
|
var providerRegistry;
|
|
855
942
|
var init_registry = __esm({
|
|
856
943
|
"packages/providers/src/registry.ts"() {
|
|
@@ -870,6 +957,7 @@ var init_src = __esm({
|
|
|
870
957
|
init_config_schema2();
|
|
871
958
|
init_definition2();
|
|
872
959
|
init_stdout_heuristics();
|
|
960
|
+
init_presets();
|
|
873
961
|
init_registry();
|
|
874
962
|
}
|
|
875
963
|
});
|
|
@@ -1712,7 +1800,7 @@ import { mkdir as mkdir3, mkdtemp, rm as rm3, writeFile as writeFile2 } from "fs
|
|
|
1712
1800
|
import os2 from "os";
|
|
1713
1801
|
import path7 from "path";
|
|
1714
1802
|
async function runGit(cwd, args, options = {}) {
|
|
1715
|
-
return new Promise((
|
|
1803
|
+
return new Promise((resolve8, reject) => {
|
|
1716
1804
|
const gitArgs = [
|
|
1717
1805
|
...options.config?.flatMap(([key, value]) => ["-c", `${key}=${value}`]) ?? [],
|
|
1718
1806
|
...args
|
|
@@ -1739,7 +1827,7 @@ async function runGit(cwd, args, options = {}) {
|
|
|
1739
1827
|
if (err) {
|
|
1740
1828
|
reject(new GitError(err.message, stderr));
|
|
1741
1829
|
} else {
|
|
1742
|
-
|
|
1830
|
+
resolve8({ stdout, stderr });
|
|
1743
1831
|
}
|
|
1744
1832
|
}
|
|
1745
1833
|
);
|
|
@@ -3620,12 +3708,12 @@ var init_auto_fetch = __esm({
|
|
|
3620
3708
|
}
|
|
3621
3709
|
acquireWorkspaceOperation(workspaceId) {
|
|
3622
3710
|
const state = this.getOrCreateState(workspaceId);
|
|
3623
|
-
return new Promise((
|
|
3711
|
+
return new Promise((resolve8) => {
|
|
3624
3712
|
const grant = () => {
|
|
3625
3713
|
state.inFlight = true;
|
|
3626
3714
|
state.nextFetchAt = void 0;
|
|
3627
3715
|
let released = false;
|
|
3628
|
-
|
|
3716
|
+
resolve8(() => {
|
|
3629
3717
|
if (released) {
|
|
3630
3718
|
return;
|
|
3631
3719
|
}
|
|
@@ -4628,7 +4716,7 @@ var init_manager = __esm({
|
|
|
4628
4716
|
// packages/server/src/provider-runtime/command-runner.ts
|
|
4629
4717
|
import { spawn as spawn2 } from "node:child_process";
|
|
4630
4718
|
async function runCommandAsString(file, args, options) {
|
|
4631
|
-
return new Promise((
|
|
4719
|
+
return new Promise((resolve8, reject) => {
|
|
4632
4720
|
const child = spawn2(file, args, {
|
|
4633
4721
|
cwd: options?.cwd,
|
|
4634
4722
|
env: options?.env,
|
|
@@ -4655,7 +4743,7 @@ async function runCommandAsString(file, args, options) {
|
|
|
4655
4743
|
const stdout = Buffer.concat(stdoutChunks).toString("utf8");
|
|
4656
4744
|
const stderr = Buffer.concat(stderrChunks).toString("utf8");
|
|
4657
4745
|
if (code === 0) {
|
|
4658
|
-
|
|
4746
|
+
resolve8({ stdout, stderr });
|
|
4659
4747
|
return;
|
|
4660
4748
|
}
|
|
4661
4749
|
reject(
|
|
@@ -5455,6 +5543,66 @@ var init_tool_root = __esm({
|
|
|
5455
5543
|
}
|
|
5456
5544
|
});
|
|
5457
5545
|
|
|
5546
|
+
// packages/server/src/provider-runtime/custom-provider.ts
|
|
5547
|
+
import { z as z4 } from "zod";
|
|
5548
|
+
function deriveProviderCapability(capabilities) {
|
|
5549
|
+
const interactive = capabilities.find((capability) => capability.key === "interactive_session");
|
|
5550
|
+
if (!interactive?.supported) {
|
|
5551
|
+
return "unsupported";
|
|
5552
|
+
}
|
|
5553
|
+
const allSupported = capabilities.length > 0 && capabilities.every((capability) => capability.supported);
|
|
5554
|
+
return allSupported ? "full" : "limited";
|
|
5555
|
+
}
|
|
5556
|
+
function buildCustomProviderDefinition(config) {
|
|
5557
|
+
const command = config.command.trim();
|
|
5558
|
+
const requiredCommand = command.split(/\s+/)[0] ?? command;
|
|
5559
|
+
return {
|
|
5560
|
+
id: config.id,
|
|
5561
|
+
displayName: config.displayName,
|
|
5562
|
+
badge: "Custom",
|
|
5563
|
+
kind: "custom",
|
|
5564
|
+
capability: deriveProviderCapability(config.capabilities),
|
|
5565
|
+
capabilities: config.capabilities.map((capability) => ({ ...capability })),
|
|
5566
|
+
install: {
|
|
5567
|
+
prerequisites: [],
|
|
5568
|
+
manualGuideKeys: [],
|
|
5569
|
+
docUrls: {
|
|
5570
|
+
provider: "",
|
|
5571
|
+
prerequisites: {}
|
|
5572
|
+
},
|
|
5573
|
+
strategies: {}
|
|
5574
|
+
},
|
|
5575
|
+
buildCommand(_providerConfig, ctx) {
|
|
5576
|
+
return {
|
|
5577
|
+
argv: [command, ...config.args],
|
|
5578
|
+
env: {
|
|
5579
|
+
...config.env,
|
|
5580
|
+
CODER_STUDIO_SESSION_ID: ctx.sessionId
|
|
5581
|
+
},
|
|
5582
|
+
cwd: ctx.workspacePath
|
|
5583
|
+
};
|
|
5584
|
+
},
|
|
5585
|
+
configSchema: CUSTOM_PROVIDER_CONFIG_SCHEMA,
|
|
5586
|
+
defaultConfig: {},
|
|
5587
|
+
requiredCommands: requiredCommand ? [requiredCommand] : []
|
|
5588
|
+
};
|
|
5589
|
+
}
|
|
5590
|
+
function upsertProviderDefinition(registry, provider) {
|
|
5591
|
+
const next = registry.filter((item) => item.id !== provider.id);
|
|
5592
|
+
next.push(provider);
|
|
5593
|
+
return next;
|
|
5594
|
+
}
|
|
5595
|
+
function removeProviderDefinition(registry, providerId) {
|
|
5596
|
+
return registry.filter((item) => item.id !== providerId);
|
|
5597
|
+
}
|
|
5598
|
+
var CUSTOM_PROVIDER_CONFIG_SCHEMA;
|
|
5599
|
+
var init_custom_provider = __esm({
|
|
5600
|
+
"packages/server/src/provider-runtime/custom-provider.ts"() {
|
|
5601
|
+
"use strict";
|
|
5602
|
+
CUSTOM_PROVIDER_CONFIG_SCHEMA = z4.object({}).passthrough();
|
|
5603
|
+
}
|
|
5604
|
+
});
|
|
5605
|
+
|
|
5458
5606
|
// packages/server/src/provider-runtime/e2e-provider-mock.ts
|
|
5459
5607
|
import { chmodSync, existsSync as existsSync5, mkdirSync as mkdirSync6, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "node:fs";
|
|
5460
5608
|
import { dirname as dirname5, join as join8 } from "node:path";
|
|
@@ -5697,9 +5845,24 @@ var init_install_manager2 = __esm({
|
|
|
5697
5845
|
deps;
|
|
5698
5846
|
constructor(providers, deps = {}) {
|
|
5699
5847
|
this.deps = deps;
|
|
5848
|
+
this.setProviders(providers);
|
|
5849
|
+
}
|
|
5850
|
+
setProviders(providers) {
|
|
5851
|
+
const nextIds = new Set(providers.map((provider) => provider.id));
|
|
5852
|
+
this.providers.clear();
|
|
5700
5853
|
for (const provider of providers) {
|
|
5701
5854
|
this.providers.set(provider.id, provider);
|
|
5702
5855
|
}
|
|
5856
|
+
for (const providerId of this.activeJobIdsByProviderId.keys()) {
|
|
5857
|
+
if (!nextIds.has(providerId)) {
|
|
5858
|
+
this.activeJobIdsByProviderId.delete(providerId);
|
|
5859
|
+
}
|
|
5860
|
+
}
|
|
5861
|
+
for (const providerId of this.inFlightStartsByProviderId.keys()) {
|
|
5862
|
+
if (!nextIds.has(providerId)) {
|
|
5863
|
+
this.inFlightStartsByProviderId.delete(providerId);
|
|
5864
|
+
}
|
|
5865
|
+
}
|
|
5703
5866
|
}
|
|
5704
5867
|
async start(providerId) {
|
|
5705
5868
|
const activeJob = this.getActiveJob(providerId);
|
|
@@ -6169,7 +6332,7 @@ var init_update = __esm({
|
|
|
6169
6332
|
});
|
|
6170
6333
|
|
|
6171
6334
|
// packages/core/src/protocol/messages.ts
|
|
6172
|
-
import { z as
|
|
6335
|
+
import { z as z5 } from "zod";
|
|
6173
6336
|
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;
|
|
6174
6337
|
var init_messages = __esm({
|
|
6175
6338
|
"packages/core/src/protocol/messages.ts"() {
|
|
@@ -6232,49 +6395,49 @@ var init_messages = __esm({
|
|
|
6232
6395
|
frame.set(payload, TERMINAL_BINARY_HEADER_SIZE + topicBytes.length);
|
|
6233
6396
|
return frame;
|
|
6234
6397
|
};
|
|
6235
|
-
CommandMessage =
|
|
6236
|
-
kind:
|
|
6237
|
-
id:
|
|
6238
|
-
op:
|
|
6239
|
-
args:
|
|
6398
|
+
CommandMessage = z5.object({
|
|
6399
|
+
kind: z5.literal("command"),
|
|
6400
|
+
id: z5.string().uuid(),
|
|
6401
|
+
op: z5.string(),
|
|
6402
|
+
args: z5.unknown()
|
|
6240
6403
|
});
|
|
6241
|
-
ResultMessage =
|
|
6242
|
-
kind:
|
|
6243
|
-
id:
|
|
6244
|
-
ok:
|
|
6245
|
-
data:
|
|
6246
|
-
error:
|
|
6247
|
-
code:
|
|
6248
|
-
message:
|
|
6249
|
-
details:
|
|
6404
|
+
ResultMessage = z5.object({
|
|
6405
|
+
kind: z5.literal("result"),
|
|
6406
|
+
id: z5.string().uuid(),
|
|
6407
|
+
ok: z5.boolean(),
|
|
6408
|
+
data: z5.unknown().optional(),
|
|
6409
|
+
error: z5.object({
|
|
6410
|
+
code: z5.string(),
|
|
6411
|
+
message: z5.string(),
|
|
6412
|
+
details: z5.unknown().optional()
|
|
6250
6413
|
}).optional()
|
|
6251
6414
|
});
|
|
6252
|
-
EventMessage =
|
|
6253
|
-
kind:
|
|
6254
|
-
topic:
|
|
6255
|
-
seq:
|
|
6256
|
-
timestamp:
|
|
6257
|
-
data:
|
|
6415
|
+
EventMessage = z5.object({
|
|
6416
|
+
kind: z5.literal("event"),
|
|
6417
|
+
topic: z5.string(),
|
|
6418
|
+
seq: z5.number().int().nonnegative(),
|
|
6419
|
+
timestamp: z5.number().int().positive(),
|
|
6420
|
+
data: z5.unknown()
|
|
6258
6421
|
});
|
|
6259
|
-
SubscribeMessage =
|
|
6260
|
-
kind:
|
|
6261
|
-
topics:
|
|
6422
|
+
SubscribeMessage = z5.object({
|
|
6423
|
+
kind: z5.literal("subscribe"),
|
|
6424
|
+
topics: z5.array(z5.string())
|
|
6262
6425
|
});
|
|
6263
|
-
UnsubscribeMessage =
|
|
6264
|
-
kind:
|
|
6265
|
-
topics:
|
|
6426
|
+
UnsubscribeMessage = z5.object({
|
|
6427
|
+
kind: z5.literal("unsubscribe"),
|
|
6428
|
+
topics: z5.array(z5.string())
|
|
6266
6429
|
});
|
|
6267
|
-
ResyncMessage =
|
|
6268
|
-
kind:
|
|
6269
|
-
lastSeen:
|
|
6430
|
+
ResyncMessage = z5.object({
|
|
6431
|
+
kind: z5.literal("resync"),
|
|
6432
|
+
lastSeen: z5.record(z5.string(), z5.number())
|
|
6270
6433
|
});
|
|
6271
|
-
ClientMessage =
|
|
6434
|
+
ClientMessage = z5.discriminatedUnion("kind", [
|
|
6272
6435
|
CommandMessage,
|
|
6273
6436
|
SubscribeMessage,
|
|
6274
6437
|
UnsubscribeMessage,
|
|
6275
6438
|
ResyncMessage
|
|
6276
6439
|
]);
|
|
6277
|
-
ServerMessage =
|
|
6440
|
+
ServerMessage = z5.discriminatedUnion("kind", [ResultMessage, EventMessage]);
|
|
6278
6441
|
}
|
|
6279
6442
|
});
|
|
6280
6443
|
|
|
@@ -6347,7 +6510,7 @@ var init_src3 = __esm({
|
|
|
6347
6510
|
});
|
|
6348
6511
|
|
|
6349
6512
|
// packages/server/src/provider-config.ts
|
|
6350
|
-
import { z as
|
|
6513
|
+
import { z as z6 } from "zod";
|
|
6351
6514
|
function isSupportedProviderId(providerId) {
|
|
6352
6515
|
return supportedProviderIds.has(providerId);
|
|
6353
6516
|
}
|
|
@@ -6367,17 +6530,17 @@ var init_provider_config = __esm({
|
|
|
6367
6530
|
"use strict";
|
|
6368
6531
|
SUPPORTED_PROVIDER_IDS = ["claude", "codex"];
|
|
6369
6532
|
supportedProviderIds = new Set(SUPPORTED_PROVIDER_IDS);
|
|
6370
|
-
ProviderLaunchConfigInputSchema =
|
|
6371
|
-
additionalArgs:
|
|
6372
|
-
envVars:
|
|
6533
|
+
ProviderLaunchConfigInputSchema = z6.object({
|
|
6534
|
+
additionalArgs: z6.array(z6.string()).optional(),
|
|
6535
|
+
envVars: z6.record(z6.string(), z6.string()).optional()
|
|
6373
6536
|
}).strict();
|
|
6374
|
-
ProviderSettingsSchema =
|
|
6537
|
+
ProviderSettingsSchema = z6.object({
|
|
6375
6538
|
claude: ProviderLaunchConfigInputSchema.optional(),
|
|
6376
6539
|
codex: ProviderLaunchConfigInputSchema.optional()
|
|
6377
6540
|
}).strict();
|
|
6378
|
-
ProviderLaunchConfigSchema =
|
|
6379
|
-
additionalArgs:
|
|
6380
|
-
envVars:
|
|
6541
|
+
ProviderLaunchConfigSchema = z6.object({
|
|
6542
|
+
additionalArgs: z6.array(z6.string()).default([]),
|
|
6543
|
+
envVars: z6.record(z6.string(), z6.string()).optional()
|
|
6381
6544
|
});
|
|
6382
6545
|
}
|
|
6383
6546
|
});
|
|
@@ -6873,6 +7036,9 @@ var init_manager3 = __esm({
|
|
|
6873
7036
|
comparators = /* @__PURE__ */ new Map();
|
|
6874
7037
|
detectorUnsubscribes = /* @__PURE__ */ new Map();
|
|
6875
7038
|
logger;
|
|
7039
|
+
setProviderRegistry(providerRegistry2) {
|
|
7040
|
+
this.deps.providerRegistry = providerRegistry2;
|
|
7041
|
+
}
|
|
6876
7042
|
/**
|
|
6877
7043
|
* Create a new session with provider
|
|
6878
7044
|
*/
|
|
@@ -7837,15 +8003,104 @@ var init_auth_session_repo = __esm({
|
|
|
7837
8003
|
}
|
|
7838
8004
|
});
|
|
7839
8005
|
|
|
7840
|
-
// packages/server/src/storage/repositories/provider-
|
|
8006
|
+
// packages/server/src/storage/repositories/custom-provider-repo.ts
|
|
7841
8007
|
function isRecord5(value) {
|
|
7842
8008
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
7843
8009
|
}
|
|
7844
|
-
function
|
|
8010
|
+
function normalizeConfig(config) {
|
|
8011
|
+
return {
|
|
8012
|
+
...config,
|
|
8013
|
+
args: [...config.args],
|
|
8014
|
+
env: { ...config.env },
|
|
8015
|
+
capabilities: config.capabilities.map((capability) => ({ ...capability }))
|
|
8016
|
+
};
|
|
8017
|
+
}
|
|
8018
|
+
function normalizeFileConfigs(value) {
|
|
7845
8019
|
if (isRecord5(value) && value.version === 1 && isRecord5(value.providers)) {
|
|
7846
|
-
return
|
|
8020
|
+
return Object.fromEntries(
|
|
8021
|
+
Object.entries(value.providers).map(([id, config]) => [
|
|
8022
|
+
id,
|
|
8023
|
+
normalizeConfig(config)
|
|
8024
|
+
])
|
|
8025
|
+
);
|
|
7847
8026
|
}
|
|
7848
8027
|
if (isRecord5(value)) {
|
|
8028
|
+
return Object.fromEntries(
|
|
8029
|
+
Object.entries(value).map(([id, config]) => [
|
|
8030
|
+
id,
|
|
8031
|
+
normalizeConfig(config)
|
|
8032
|
+
])
|
|
8033
|
+
);
|
|
8034
|
+
}
|
|
8035
|
+
return {};
|
|
8036
|
+
}
|
|
8037
|
+
var CustomProviderRepo;
|
|
8038
|
+
var init_custom_provider_repo = __esm({
|
|
8039
|
+
"packages/server/src/storage/repositories/custom-provider-repo.ts"() {
|
|
8040
|
+
"use strict";
|
|
8041
|
+
init_json_file_store();
|
|
8042
|
+
CustomProviderRepo = class {
|
|
8043
|
+
filePath;
|
|
8044
|
+
constructor(input2) {
|
|
8045
|
+
this.filePath = input2.filePath;
|
|
8046
|
+
}
|
|
8047
|
+
list() {
|
|
8048
|
+
return Object.values(this.loadFileConfigs()).sort(
|
|
8049
|
+
(left, right) => right.updatedAt - left.updatedAt || left.id.localeCompare(right.id)
|
|
8050
|
+
);
|
|
8051
|
+
}
|
|
8052
|
+
get(id) {
|
|
8053
|
+
return this.loadFileConfigs()[id];
|
|
8054
|
+
}
|
|
8055
|
+
set(config) {
|
|
8056
|
+
const existing = this.get(config.id);
|
|
8057
|
+
const createdAt = existing?.createdAt ?? config.createdAt;
|
|
8058
|
+
const normalized = normalizeConfig({
|
|
8059
|
+
...config,
|
|
8060
|
+
createdAt
|
|
8061
|
+
});
|
|
8062
|
+
const next = this.loadFileConfigs();
|
|
8063
|
+
next[normalized.id] = normalized;
|
|
8064
|
+
this.saveFileConfigs(next);
|
|
8065
|
+
return next[normalized.id];
|
|
8066
|
+
}
|
|
8067
|
+
delete(id) {
|
|
8068
|
+
const next = this.loadFileConfigs();
|
|
8069
|
+
if (!Object.prototype.hasOwnProperty.call(next, id)) {
|
|
8070
|
+
return;
|
|
8071
|
+
}
|
|
8072
|
+
delete next[id];
|
|
8073
|
+
this.saveFileConfigs(next);
|
|
8074
|
+
}
|
|
8075
|
+
loadFileConfigs() {
|
|
8076
|
+
const parsed = readJsonFile(
|
|
8077
|
+
this.filePath
|
|
8078
|
+
);
|
|
8079
|
+
if (parsed !== void 0) {
|
|
8080
|
+
return normalizeFileConfigs(parsed);
|
|
8081
|
+
}
|
|
8082
|
+
return {};
|
|
8083
|
+
}
|
|
8084
|
+
saveFileConfigs(configs) {
|
|
8085
|
+
const payload = {
|
|
8086
|
+
version: 1,
|
|
8087
|
+
providers: configs
|
|
8088
|
+
};
|
|
8089
|
+
writeJsonFileAtomic(this.filePath, payload);
|
|
8090
|
+
}
|
|
8091
|
+
};
|
|
8092
|
+
}
|
|
8093
|
+
});
|
|
8094
|
+
|
|
8095
|
+
// packages/server/src/storage/repositories/provider-config-repo.ts
|
|
8096
|
+
function isRecord6(value) {
|
|
8097
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
8098
|
+
}
|
|
8099
|
+
function normalizeProviderConfigFile(value) {
|
|
8100
|
+
if (isRecord6(value) && value.version === 1 && isRecord6(value.providers)) {
|
|
8101
|
+
return value.providers;
|
|
8102
|
+
}
|
|
8103
|
+
if (isRecord6(value)) {
|
|
7849
8104
|
return value;
|
|
7850
8105
|
}
|
|
7851
8106
|
return {};
|
|
@@ -7918,15 +8173,159 @@ var init_provider_config_repo = __esm({
|
|
|
7918
8173
|
}
|
|
7919
8174
|
});
|
|
7920
8175
|
|
|
8176
|
+
// packages/server/src/workspace/workspace-state.ts
|
|
8177
|
+
import { join as join9 } from "node:path";
|
|
8178
|
+
function resolveWorkspaceStateFilePath(workspacePath, fileName) {
|
|
8179
|
+
return join9(workspacePath, WORKSPACE_STATE_DIR, fileName);
|
|
8180
|
+
}
|
|
8181
|
+
var WORKSPACE_STATE_DIR, AGENT_INSTRUCTIONS_RELATIVE_PATH, SESSION_METADATA_FILE_NAME, SESSION_METADATA_RELATIVE_PATH;
|
|
8182
|
+
var init_workspace_state = __esm({
|
|
8183
|
+
"packages/server/src/workspace/workspace-state.ts"() {
|
|
8184
|
+
"use strict";
|
|
8185
|
+
WORKSPACE_STATE_DIR = ".coder-studio";
|
|
8186
|
+
AGENT_INSTRUCTIONS_RELATIVE_PATH = `${WORKSPACE_STATE_DIR}/AGENTS.md`;
|
|
8187
|
+
SESSION_METADATA_FILE_NAME = "session-metadata.json";
|
|
8188
|
+
SESSION_METADATA_RELATIVE_PATH = `${WORKSPACE_STATE_DIR}/${SESSION_METADATA_FILE_NAME}`;
|
|
8189
|
+
}
|
|
8190
|
+
});
|
|
8191
|
+
|
|
8192
|
+
// packages/server/src/storage/repositories/session-metadata-repo.ts
|
|
8193
|
+
function isRecord7(value) {
|
|
8194
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
8195
|
+
}
|
|
8196
|
+
function normalizeRun(run) {
|
|
8197
|
+
return {
|
|
8198
|
+
...run
|
|
8199
|
+
};
|
|
8200
|
+
}
|
|
8201
|
+
function normalizeMetadata(metadata) {
|
|
8202
|
+
return {
|
|
8203
|
+
sessionId: metadata.sessionId,
|
|
8204
|
+
workspaceId: metadata.workspaceId,
|
|
8205
|
+
providerId: metadata.providerId,
|
|
8206
|
+
objective: metadata.objective ?? void 0,
|
|
8207
|
+
baselineGitHead: metadata.baselineGitHead ?? void 0,
|
|
8208
|
+
baselineCapturedAt: metadata.baselineCapturedAt ?? void 0,
|
|
8209
|
+
verificationRuns: metadata.verificationRuns.map(normalizeRun)
|
|
8210
|
+
};
|
|
8211
|
+
}
|
|
8212
|
+
function normalizeFileMetadata(value) {
|
|
8213
|
+
if (isRecord7(value) && value.version === 1 && isRecord7(value.metadata)) {
|
|
8214
|
+
return Object.fromEntries(
|
|
8215
|
+
Object.entries(value.metadata).map(([sessionId, metadata]) => [
|
|
8216
|
+
sessionId,
|
|
8217
|
+
normalizeMetadata(metadata)
|
|
8218
|
+
])
|
|
8219
|
+
);
|
|
8220
|
+
}
|
|
8221
|
+
if (isRecord7(value)) {
|
|
8222
|
+
return Object.fromEntries(
|
|
8223
|
+
Object.entries(value).map(([sessionId, metadata]) => [
|
|
8224
|
+
sessionId,
|
|
8225
|
+
normalizeMetadata(metadata)
|
|
8226
|
+
])
|
|
8227
|
+
);
|
|
8228
|
+
}
|
|
8229
|
+
return {};
|
|
8230
|
+
}
|
|
8231
|
+
var SessionMetadataRepo;
|
|
8232
|
+
var init_session_metadata_repo = __esm({
|
|
8233
|
+
"packages/server/src/storage/repositories/session-metadata-repo.ts"() {
|
|
8234
|
+
"use strict";
|
|
8235
|
+
init_workspace_state();
|
|
8236
|
+
init_json_file_store();
|
|
8237
|
+
SessionMetadataRepo = class {
|
|
8238
|
+
workspaceRepo;
|
|
8239
|
+
constructor(input2) {
|
|
8240
|
+
this.workspaceRepo = input2.workspaceRepo;
|
|
8241
|
+
}
|
|
8242
|
+
upsert(metadata) {
|
|
8243
|
+
const normalized = normalizeMetadata(metadata);
|
|
8244
|
+
const workspace = this.workspaceRepo.findById(normalized.workspaceId);
|
|
8245
|
+
if (!workspace) {
|
|
8246
|
+
throw new Error(`Workspace not found for session metadata: ${normalized.workspaceId}`);
|
|
8247
|
+
}
|
|
8248
|
+
const existing = this.findSessionLocation(normalized.sessionId);
|
|
8249
|
+
if (existing && existing.workspace.id !== workspace.id) {
|
|
8250
|
+
delete existing.fileMetadata[normalized.sessionId];
|
|
8251
|
+
this.saveWorkspaceFileMetadata(existing.workspace.path, existing.fileMetadata);
|
|
8252
|
+
}
|
|
8253
|
+
const next = existing && existing.workspace.id === workspace.id ? existing.fileMetadata : this.loadWorkspaceFileMetadata(workspace.path);
|
|
8254
|
+
next[normalized.sessionId] = normalized;
|
|
8255
|
+
this.saveWorkspaceFileMetadata(workspace.path, next);
|
|
8256
|
+
return next[normalized.sessionId];
|
|
8257
|
+
}
|
|
8258
|
+
get(sessionId) {
|
|
8259
|
+
return this.findSessionLocation(sessionId)?.fileMetadata[sessionId];
|
|
8260
|
+
}
|
|
8261
|
+
addVerificationRun(sessionId, run) {
|
|
8262
|
+
const existing = this.findSessionLocation(sessionId);
|
|
8263
|
+
if (!existing) {
|
|
8264
|
+
throw new Error(`Session metadata not found: ${sessionId}`);
|
|
8265
|
+
}
|
|
8266
|
+
existing.fileMetadata[sessionId] = normalizeMetadata({
|
|
8267
|
+
...existing.fileMetadata[sessionId],
|
|
8268
|
+
verificationRuns: [...existing.fileMetadata[sessionId].verificationRuns, normalizeRun(run)]
|
|
8269
|
+
});
|
|
8270
|
+
this.saveWorkspaceFileMetadata(existing.workspace.path, existing.fileMetadata);
|
|
8271
|
+
return existing.fileMetadata[sessionId];
|
|
8272
|
+
}
|
|
8273
|
+
delete(sessionId) {
|
|
8274
|
+
this.deleteFromAnyWorkspace(sessionId);
|
|
8275
|
+
}
|
|
8276
|
+
findSessionLocation(sessionId) {
|
|
8277
|
+
for (const workspace of this.workspaceRepo.list()) {
|
|
8278
|
+
const fileMetadata = this.loadWorkspaceFileMetadata(workspace.path);
|
|
8279
|
+
if (Object.prototype.hasOwnProperty.call(fileMetadata, sessionId)) {
|
|
8280
|
+
return {
|
|
8281
|
+
workspace,
|
|
8282
|
+
fileMetadata
|
|
8283
|
+
};
|
|
8284
|
+
}
|
|
8285
|
+
}
|
|
8286
|
+
return void 0;
|
|
8287
|
+
}
|
|
8288
|
+
deleteFromAnyWorkspace(sessionId) {
|
|
8289
|
+
const existing = this.findSessionLocation(sessionId);
|
|
8290
|
+
if (!existing) {
|
|
8291
|
+
return false;
|
|
8292
|
+
}
|
|
8293
|
+
delete existing.fileMetadata[sessionId];
|
|
8294
|
+
this.saveWorkspaceFileMetadata(existing.workspace.path, existing.fileMetadata);
|
|
8295
|
+
return true;
|
|
8296
|
+
}
|
|
8297
|
+
loadWorkspaceFileMetadata(workspacePath) {
|
|
8298
|
+
const parsed = readJsonFile(
|
|
8299
|
+
resolveWorkspaceStateFilePath(workspacePath, SESSION_METADATA_FILE_NAME)
|
|
8300
|
+
);
|
|
8301
|
+
if (parsed !== void 0) {
|
|
8302
|
+
return normalizeFileMetadata(parsed);
|
|
8303
|
+
}
|
|
8304
|
+
return {};
|
|
8305
|
+
}
|
|
8306
|
+
saveWorkspaceFileMetadata(workspacePath, metadata) {
|
|
8307
|
+
const payload = {
|
|
8308
|
+
version: 1,
|
|
8309
|
+
metadata
|
|
8310
|
+
};
|
|
8311
|
+
writeJsonFileAtomic(
|
|
8312
|
+
resolveWorkspaceStateFilePath(workspacePath, SESSION_METADATA_FILE_NAME),
|
|
8313
|
+
payload
|
|
8314
|
+
);
|
|
8315
|
+
}
|
|
8316
|
+
};
|
|
8317
|
+
}
|
|
8318
|
+
});
|
|
8319
|
+
|
|
7921
8320
|
// packages/server/src/storage/repositories/settings-repo.ts
|
|
7922
|
-
function
|
|
8321
|
+
function isRecord8(value) {
|
|
7923
8322
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
7924
8323
|
}
|
|
7925
8324
|
function normalizeSettingsFile(value) {
|
|
7926
|
-
if (
|
|
8325
|
+
if (isRecord8(value) && value.version === 1 && isRecord8(value.settings)) {
|
|
7927
8326
|
return { ...value.settings };
|
|
7928
8327
|
}
|
|
7929
|
-
if (
|
|
8328
|
+
if (isRecord8(value)) {
|
|
7930
8329
|
return { ...value };
|
|
7931
8330
|
}
|
|
7932
8331
|
return {};
|
|
@@ -8077,11 +8476,11 @@ var init_supervisor_repo = __esm({
|
|
|
8077
8476
|
});
|
|
8078
8477
|
|
|
8079
8478
|
// packages/server/src/storage/repositories/terminal-repo.ts
|
|
8080
|
-
function
|
|
8479
|
+
function isRecord9(value) {
|
|
8081
8480
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
8082
8481
|
}
|
|
8083
8482
|
function isTerminal(value) {
|
|
8084
|
-
if (!
|
|
8483
|
+
if (!isRecord9(value)) {
|
|
8085
8484
|
return false;
|
|
8086
8485
|
}
|
|
8087
8486
|
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";
|
|
@@ -8093,7 +8492,7 @@ function normalizeTerminal(value) {
|
|
|
8093
8492
|
};
|
|
8094
8493
|
}
|
|
8095
8494
|
function normalizeTerminalFile(value) {
|
|
8096
|
-
if (
|
|
8495
|
+
if (isRecord9(value) && value.version === 1 && isRecord9(value.terminals)) {
|
|
8097
8496
|
const normalized = {};
|
|
8098
8497
|
for (const entry of Object.values(value.terminals)) {
|
|
8099
8498
|
if (isTerminal(entry)) {
|
|
@@ -8111,7 +8510,7 @@ function normalizeTerminalFile(value) {
|
|
|
8111
8510
|
}
|
|
8112
8511
|
return normalized;
|
|
8113
8512
|
}
|
|
8114
|
-
if (
|
|
8513
|
+
if (isRecord9(value)) {
|
|
8115
8514
|
const normalized = {};
|
|
8116
8515
|
for (const [terminalId, entry] of Object.entries(value)) {
|
|
8117
8516
|
if (isTerminal(entry)) {
|
|
@@ -8277,12 +8676,12 @@ var init_terminal_repo = __esm({
|
|
|
8277
8676
|
});
|
|
8278
8677
|
|
|
8279
8678
|
// packages/server/src/storage/repositories/update-state-repo.ts
|
|
8280
|
-
function
|
|
8679
|
+
function isRecord10(value) {
|
|
8281
8680
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
8282
8681
|
}
|
|
8283
8682
|
function normalizeUpdateState(value, currentVersion) {
|
|
8284
8683
|
const defaults = createDefaultUpdateState(currentVersion);
|
|
8285
|
-
if (!
|
|
8684
|
+
if (!isRecord10(value)) {
|
|
8286
8685
|
return defaults;
|
|
8287
8686
|
}
|
|
8288
8687
|
return {
|
|
@@ -8345,17 +8744,17 @@ var init_update_state_repo = __esm({
|
|
|
8345
8744
|
});
|
|
8346
8745
|
|
|
8347
8746
|
// packages/server/src/storage/repositories/workspace-repo.ts
|
|
8348
|
-
function
|
|
8747
|
+
function isRecord11(value) {
|
|
8349
8748
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
8350
8749
|
}
|
|
8351
8750
|
function isWorkspace(value) {
|
|
8352
|
-
if (!
|
|
8751
|
+
if (!isRecord11(value)) {
|
|
8353
8752
|
return false;
|
|
8354
8753
|
}
|
|
8355
|
-
return typeof value.id === "string" && typeof value.path === "string" && (value.targetRuntime === "native" || value.targetRuntime === "wsl") && typeof value.openedAt === "number" && typeof value.lastActiveAt === "number" &&
|
|
8754
|
+
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);
|
|
8356
8755
|
}
|
|
8357
8756
|
function normalizeWorkspaceFile(value) {
|
|
8358
|
-
if (
|
|
8757
|
+
if (isRecord11(value) && value.version === 1 && isRecord11(value.workspaces)) {
|
|
8359
8758
|
const normalized = {};
|
|
8360
8759
|
for (const entry of Object.values(value.workspaces)) {
|
|
8361
8760
|
if (isWorkspace(entry)) {
|
|
@@ -8373,7 +8772,7 @@ function normalizeWorkspaceFile(value) {
|
|
|
8373
8772
|
}
|
|
8374
8773
|
return normalized;
|
|
8375
8774
|
}
|
|
8376
|
-
if (
|
|
8775
|
+
if (isRecord11(value)) {
|
|
8377
8776
|
const normalized = {};
|
|
8378
8777
|
for (const [workspaceId, entry] of Object.entries(value)) {
|
|
8379
8778
|
if (isWorkspace(entry)) {
|
|
@@ -8618,13 +9017,13 @@ function ensureNodePtySpawnHelperExecutable(deps = {}) {
|
|
|
8618
9017
|
return;
|
|
8619
9018
|
}
|
|
8620
9019
|
const arch = deps.arch ?? process.arch;
|
|
8621
|
-
const
|
|
9020
|
+
const resolve8 = deps.resolve ?? ((id) => require4.resolve(id));
|
|
8622
9021
|
const fileExists = deps.existsSync ?? existsSync6;
|
|
8623
|
-
const
|
|
9022
|
+
const stat12 = deps.statSync ?? statSync;
|
|
8624
9023
|
const chmod = deps.chmodSync ?? chmodSync2;
|
|
8625
9024
|
let packageJsonPath;
|
|
8626
9025
|
try {
|
|
8627
|
-
packageJsonPath =
|
|
9026
|
+
packageJsonPath = resolve8(NODE_PTY_PKG);
|
|
8628
9027
|
} catch {
|
|
8629
9028
|
return;
|
|
8630
9029
|
}
|
|
@@ -8638,7 +9037,7 @@ function ensureNodePtySpawnHelperExecutable(deps = {}) {
|
|
|
8638
9037
|
if (!fileExists(helperPath)) {
|
|
8639
9038
|
return;
|
|
8640
9039
|
}
|
|
8641
|
-
const currentMode =
|
|
9040
|
+
const currentMode = stat12(helperPath).mode;
|
|
8642
9041
|
const executableMode = currentMode | 73;
|
|
8643
9042
|
if (executableMode === currentMode) {
|
|
8644
9043
|
return;
|
|
@@ -8689,7 +9088,7 @@ async function escalateKillWithPolling(pid, signal, options) {
|
|
|
8689
9088
|
const startTime = Date.now();
|
|
8690
9089
|
const deadline = startTime + timeoutMs;
|
|
8691
9090
|
while (Date.now() < deadline) {
|
|
8692
|
-
await new Promise((
|
|
9091
|
+
await new Promise((resolve8) => setTimeout(resolve8, pollIntervalMs));
|
|
8693
9092
|
if (!isProcessAlive(pid)) {
|
|
8694
9093
|
return true;
|
|
8695
9094
|
}
|
|
@@ -9053,7 +9452,7 @@ async function runCommand(command, timeoutMs, options = {}) {
|
|
|
9053
9452
|
if (options.signal?.aborted) {
|
|
9054
9453
|
throw createSupervisorEvalAbortedError();
|
|
9055
9454
|
}
|
|
9056
|
-
return await new Promise((
|
|
9455
|
+
return await new Promise((resolve8, reject) => {
|
|
9057
9456
|
const child = spawn3(command.argv[0], command.argv.slice(1), {
|
|
9058
9457
|
cwd: command.cwd,
|
|
9059
9458
|
detached: process.platform !== "win32",
|
|
@@ -9083,7 +9482,7 @@ async function runCommand(command, timeoutMs, options = {}) {
|
|
|
9083
9482
|
}
|
|
9084
9483
|
settled = true;
|
|
9085
9484
|
cleanup();
|
|
9086
|
-
|
|
9485
|
+
resolve8(value);
|
|
9087
9486
|
};
|
|
9088
9487
|
const terminate = (error) => {
|
|
9089
9488
|
if (terminationError) {
|
|
@@ -9911,12 +10310,12 @@ var init_scheduler = __esm({
|
|
|
9911
10310
|
|
|
9912
10311
|
// packages/server/src/supervisor/manager.ts
|
|
9913
10312
|
function createDeferredCompletion() {
|
|
9914
|
-
let
|
|
10313
|
+
let resolve8 = () => {
|
|
9915
10314
|
};
|
|
9916
10315
|
const promise = new Promise((innerResolve) => {
|
|
9917
|
-
|
|
10316
|
+
resolve8 = innerResolve;
|
|
9918
10317
|
});
|
|
9919
|
-
return { promise, resolve:
|
|
10318
|
+
return { promise, resolve: resolve8 };
|
|
9920
10319
|
}
|
|
9921
10320
|
function generateSupervisorId() {
|
|
9922
10321
|
return `sup_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
|
|
@@ -10037,6 +10436,9 @@ var init_manager4 = __esm({
|
|
|
10037
10436
|
logger;
|
|
10038
10437
|
config;
|
|
10039
10438
|
lifecycleUnsubscribe = null;
|
|
10439
|
+
setProviderRegistry(providerRegistry2) {
|
|
10440
|
+
this.deps.providerRegistry = providerRegistry2;
|
|
10441
|
+
}
|
|
10040
10442
|
start() {
|
|
10041
10443
|
this.lifecycleUnsubscribe?.();
|
|
10042
10444
|
this.lifecycleUnsubscribe = this.deps.eventBus.on(
|
|
@@ -11271,10 +11673,10 @@ var init_manager4 = __esm({
|
|
|
11271
11673
|
if (signal?.aborted) {
|
|
11272
11674
|
throw { code: "supervisor_eval_aborted", message: "Supervisor evaluator aborted" };
|
|
11273
11675
|
}
|
|
11274
|
-
await new Promise((
|
|
11676
|
+
await new Promise((resolve8, reject) => {
|
|
11275
11677
|
const timer = setTimeout(() => {
|
|
11276
11678
|
signal?.removeEventListener("abort", onAbort);
|
|
11277
|
-
|
|
11679
|
+
resolve8();
|
|
11278
11680
|
}, delayMs);
|
|
11279
11681
|
timer.unref?.();
|
|
11280
11682
|
const onAbort = () => {
|
|
@@ -11306,30 +11708,30 @@ __export(target_store_exports, {
|
|
|
11306
11708
|
saveTargetMeta: () => saveTargetMeta
|
|
11307
11709
|
});
|
|
11308
11710
|
import { mkdir as mkdir4, mkdtemp as mkdtemp2, readdir as readdir2, readFile as readFile3, rename, rm as rm6, writeFile as writeFile4 } from "node:fs/promises";
|
|
11309
|
-
import { dirname as dirname6, join as
|
|
11711
|
+
import { dirname as dirname6, join as join10 } from "node:path";
|
|
11310
11712
|
function targetDir(workspacePath, targetId) {
|
|
11311
|
-
return
|
|
11713
|
+
return join10(workspacePath, ".coder-studio", "supervisor", "targets", targetId);
|
|
11312
11714
|
}
|
|
11313
11715
|
function metaPath(workspacePath, targetId) {
|
|
11314
|
-
return
|
|
11716
|
+
return join10(targetDir(workspacePath, targetId), "meta.json");
|
|
11315
11717
|
}
|
|
11316
11718
|
function memoryPath(workspacePath, targetId) {
|
|
11317
|
-
return
|
|
11719
|
+
return join10(targetDir(workspacePath, targetId), "memory.json");
|
|
11318
11720
|
}
|
|
11319
11721
|
function cyclesPath(workspacePath, targetId) {
|
|
11320
|
-
return
|
|
11722
|
+
return join10(targetDir(workspacePath, targetId), "cycles.jsonl");
|
|
11321
11723
|
}
|
|
11322
11724
|
function targetsRoot(workspacePath) {
|
|
11323
|
-
return
|
|
11725
|
+
return join10(workspacePath, ".coder-studio", "supervisor", "targets");
|
|
11324
11726
|
}
|
|
11325
11727
|
function metaFilePath(dirPath) {
|
|
11326
|
-
return
|
|
11728
|
+
return join10(dirPath, "meta.json");
|
|
11327
11729
|
}
|
|
11328
11730
|
function memoryFilePath(dirPath) {
|
|
11329
|
-
return
|
|
11731
|
+
return join10(dirPath, "memory.json");
|
|
11330
11732
|
}
|
|
11331
11733
|
function cyclesFilePath(dirPath) {
|
|
11332
|
-
return
|
|
11734
|
+
return join10(dirPath, "cycles.jsonl");
|
|
11333
11735
|
}
|
|
11334
11736
|
function hasCode2(error, code) {
|
|
11335
11737
|
return Boolean(
|
|
@@ -11348,7 +11750,7 @@ function errorMessage(error, fallback) {
|
|
|
11348
11750
|
}
|
|
11349
11751
|
return fallback;
|
|
11350
11752
|
}
|
|
11351
|
-
function
|
|
11753
|
+
function isRecord12(value) {
|
|
11352
11754
|
return Boolean(value) && typeof value === "object";
|
|
11353
11755
|
}
|
|
11354
11756
|
function readNonEmptyString(value) {
|
|
@@ -11392,7 +11794,7 @@ function fallbackAcceptanceCriteria(title) {
|
|
|
11392
11794
|
return [`${title} is complete`];
|
|
11393
11795
|
}
|
|
11394
11796
|
function normalizeItem(value, fallbackKind) {
|
|
11395
|
-
if (!
|
|
11797
|
+
if (!isRecord12(value)) {
|
|
11396
11798
|
return null;
|
|
11397
11799
|
}
|
|
11398
11800
|
const id = readNonEmptyString(value.id);
|
|
@@ -11423,7 +11825,7 @@ function normalizeLegacyPlanItems(plan) {
|
|
|
11423
11825
|
}
|
|
11424
11826
|
return plan.flatMap((value) => {
|
|
11425
11827
|
const item = normalizeItem(
|
|
11426
|
-
|
|
11828
|
+
isRecord12(value) ? {
|
|
11427
11829
|
id: value.id,
|
|
11428
11830
|
kind: "stage",
|
|
11429
11831
|
title: value.title,
|
|
@@ -11447,7 +11849,7 @@ function resolveActiveItemId(items, candidate) {
|
|
|
11447
11849
|
return items.find((item) => item.status === "in_progress")?.id ?? items.find((item) => item.status === "pending")?.id ?? items[0]?.id;
|
|
11448
11850
|
}
|
|
11449
11851
|
function normalizeTargetMemory(raw, targetId) {
|
|
11450
|
-
if (!
|
|
11852
|
+
if (!isRecord12(raw)) {
|
|
11451
11853
|
return buildTargetMemory(targetId, 0);
|
|
11452
11854
|
}
|
|
11453
11855
|
const updatedAt = readTimestamp(raw.updatedAt, 0);
|
|
@@ -11474,7 +11876,7 @@ function normalizeTargetMemory(raw, targetId) {
|
|
|
11474
11876
|
};
|
|
11475
11877
|
}
|
|
11476
11878
|
function normalizePersistedSupervisor(raw, fallback) {
|
|
11477
|
-
if (!
|
|
11879
|
+
if (!isRecord12(raw)) {
|
|
11478
11880
|
return void 0;
|
|
11479
11881
|
}
|
|
11480
11882
|
const id = readNonEmptyString(raw.id) ?? fallback.targetId;
|
|
@@ -11510,7 +11912,7 @@ function normalizePersistedSupervisor(raw, fallback) {
|
|
|
11510
11912
|
};
|
|
11511
11913
|
}
|
|
11512
11914
|
function normalizeTargetMeta(raw, fallbackTargetId) {
|
|
11513
|
-
if (!
|
|
11915
|
+
if (!isRecord12(raw)) {
|
|
11514
11916
|
const targetId2 = fallbackTargetId ?? "";
|
|
11515
11917
|
return {
|
|
11516
11918
|
targetId: targetId2,
|
|
@@ -11631,7 +12033,7 @@ async function resetTargetFiles(workspacePath, input2) {
|
|
|
11631
12033
|
const parentDir = dirname6(dir);
|
|
11632
12034
|
const backupDir = `${dir}.backup-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
11633
12035
|
await mkdir4(parentDir, { recursive: true });
|
|
11634
|
-
const stagingDir = await mkdtemp2(
|
|
12036
|
+
const stagingDir = await mkdtemp2(join10(parentDir, `${input2.targetId}.reset-`));
|
|
11635
12037
|
let backupCreated = false;
|
|
11636
12038
|
let promoted = false;
|
|
11637
12039
|
let restored = false;
|
|
@@ -12088,8 +12490,8 @@ var init_terminal_snapshot_buffer = __esm({
|
|
|
12088
12490
|
if (this.pendingWriteCount === 0) {
|
|
12089
12491
|
return Promise.resolve();
|
|
12090
12492
|
}
|
|
12091
|
-
return new Promise((
|
|
12092
|
-
this.drainResolvers.push(
|
|
12493
|
+
return new Promise((resolve8) => {
|
|
12494
|
+
this.drainResolvers.push(resolve8);
|
|
12093
12495
|
});
|
|
12094
12496
|
}
|
|
12095
12497
|
resolveDrainIfIdle() {
|
|
@@ -12098,8 +12500,8 @@ var init_terminal_snapshot_buffer = __esm({
|
|
|
12098
12500
|
}
|
|
12099
12501
|
const resolvers = this.drainResolvers;
|
|
12100
12502
|
this.drainResolvers = [];
|
|
12101
|
-
for (const
|
|
12102
|
-
|
|
12503
|
+
for (const resolve8 of resolvers) {
|
|
12504
|
+
resolve8();
|
|
12103
12505
|
}
|
|
12104
12506
|
}
|
|
12105
12507
|
requireTerminal() {
|
|
@@ -12460,10 +12862,10 @@ var init_manager5 = __esm({
|
|
|
12460
12862
|
}
|
|
12461
12863
|
return existing.promise;
|
|
12462
12864
|
}
|
|
12463
|
-
let
|
|
12865
|
+
let resolve8 = () => {
|
|
12464
12866
|
};
|
|
12465
12867
|
const promise = new Promise((innerResolve) => {
|
|
12466
|
-
|
|
12868
|
+
resolve8 = innerResolve;
|
|
12467
12869
|
});
|
|
12468
12870
|
let markKillCompleted = () => {
|
|
12469
12871
|
};
|
|
@@ -12476,7 +12878,7 @@ var init_manager5 = __esm({
|
|
|
12476
12878
|
markKillCompleted,
|
|
12477
12879
|
finalized: false,
|
|
12478
12880
|
promise,
|
|
12479
|
-
resolve:
|
|
12881
|
+
resolve: resolve8
|
|
12480
12882
|
});
|
|
12481
12883
|
void terminal.pty.kill(signal).finally(() => {
|
|
12482
12884
|
const waiter = this.explicitCloseWaiters.get(terminalId);
|
|
@@ -13046,7 +13448,7 @@ var init_validator = __esm({
|
|
|
13046
13448
|
// packages/server/src/fs/gitignore.ts
|
|
13047
13449
|
import { existsSync as existsSync7, readFileSync as readFileSync6 } from "fs";
|
|
13048
13450
|
import ignore from "ignore";
|
|
13049
|
-
import { join as
|
|
13451
|
+
import { join as join11, relative as relative2 } from "path";
|
|
13050
13452
|
function normalizePath(path14) {
|
|
13051
13453
|
return path14.replace(/\\/g, "/");
|
|
13052
13454
|
}
|
|
@@ -13069,7 +13471,7 @@ function isIgnoredByGitignore(ig, path14) {
|
|
|
13069
13471
|
return ig.ignores(path14) || ig.ignores(`${path14}/`);
|
|
13070
13472
|
}
|
|
13071
13473
|
function createGitignoreFilter(rootPath, dirPath) {
|
|
13072
|
-
const gitignorePath =
|
|
13474
|
+
const gitignorePath = join11(rootPath, ".gitignore");
|
|
13073
13475
|
if (!existsSync7(gitignorePath)) {
|
|
13074
13476
|
return (name) => !isDefaultTreeIgnored(name);
|
|
13075
13477
|
}
|
|
@@ -13079,7 +13481,7 @@ function createGitignoreFilter(rootPath, dirPath) {
|
|
|
13079
13481
|
if (isAlwaysTreeIgnored(name)) {
|
|
13080
13482
|
return false;
|
|
13081
13483
|
}
|
|
13082
|
-
const relativePath = relativeToRoot(rootPath,
|
|
13484
|
+
const relativePath = relativeToRoot(rootPath, join11(dirPath, name));
|
|
13083
13485
|
return !isIgnoredByGitignore(ig, relativePath);
|
|
13084
13486
|
};
|
|
13085
13487
|
}
|
|
@@ -13752,7 +14154,7 @@ var init_fencing = __esm({
|
|
|
13752
14154
|
// packages/server/src/commands/terminal.ts
|
|
13753
14155
|
import { stat as stat8 } from "node:fs/promises";
|
|
13754
14156
|
import { basename, isAbsolute as isAbsolute2 } from "node:path";
|
|
13755
|
-
import { z as
|
|
14157
|
+
import { z as z7 } from "zod";
|
|
13756
14158
|
function decodeTerminalInput(args) {
|
|
13757
14159
|
if ("bytes" in args) {
|
|
13758
14160
|
return Buffer.from(args.bytes, "base64");
|
|
@@ -13824,29 +14226,29 @@ var init_terminal = __esm({
|
|
|
13824
14226
|
init_src3();
|
|
13825
14227
|
init_file_io();
|
|
13826
14228
|
init_dispatch();
|
|
13827
|
-
TerminalInputActivitySchema =
|
|
13828
|
-
TerminalInputSchema =
|
|
13829
|
-
|
|
13830
|
-
terminalId:
|
|
13831
|
-
bytes:
|
|
14229
|
+
TerminalInputActivitySchema = z7.enum(TERMINAL_INPUT_ACTIVITIES).optional();
|
|
14230
|
+
TerminalInputSchema = z7.union([
|
|
14231
|
+
z7.object({
|
|
14232
|
+
terminalId: z7.string(),
|
|
14233
|
+
bytes: z7.string(),
|
|
13832
14234
|
activity: TerminalInputActivitySchema,
|
|
13833
|
-
submittedText:
|
|
14235
|
+
submittedText: z7.string().optional()
|
|
13834
14236
|
}),
|
|
13835
|
-
|
|
13836
|
-
terminalId:
|
|
13837
|
-
transport:
|
|
13838
|
-
streamId:
|
|
13839
|
-
size:
|
|
14237
|
+
z7.object({
|
|
14238
|
+
terminalId: z7.string(),
|
|
14239
|
+
transport: z7.literal("binary"),
|
|
14240
|
+
streamId: z7.number().int().nonnegative(),
|
|
14241
|
+
size: z7.number().int().nonnegative(),
|
|
13840
14242
|
activity: TerminalInputActivitySchema,
|
|
13841
|
-
submittedText:
|
|
14243
|
+
submittedText: z7.string().optional()
|
|
13842
14244
|
})
|
|
13843
14245
|
]);
|
|
13844
14246
|
pendingTerminalInput = /* @__PURE__ */ new Map();
|
|
13845
14247
|
nextOutboundBinaryStreamId = 0;
|
|
13846
14248
|
registerCommand(
|
|
13847
14249
|
"terminal.list",
|
|
13848
|
-
|
|
13849
|
-
workspaceId:
|
|
14250
|
+
z7.object({
|
|
14251
|
+
workspaceId: z7.string()
|
|
13850
14252
|
}),
|
|
13851
14253
|
async (args, ctx) => {
|
|
13852
14254
|
return ctx.terminalMgr.getAll().map((terminal) => terminal.toDTO()).filter((terminal) => terminal.workspaceId === args.workspaceId);
|
|
@@ -13854,12 +14256,12 @@ var init_terminal = __esm({
|
|
|
13854
14256
|
);
|
|
13855
14257
|
registerCommand(
|
|
13856
14258
|
"terminal.create",
|
|
13857
|
-
|
|
13858
|
-
workspaceId:
|
|
13859
|
-
cols:
|
|
13860
|
-
rows:
|
|
13861
|
-
cwdPath:
|
|
13862
|
-
themeBackground:
|
|
14259
|
+
z7.object({
|
|
14260
|
+
workspaceId: z7.string(),
|
|
14261
|
+
cols: z7.number().int().positive().optional(),
|
|
14262
|
+
rows: z7.number().int().positive().optional(),
|
|
14263
|
+
cwdPath: z7.string().optional(),
|
|
14264
|
+
themeBackground: z7.string().regex(/^#[0-9a-fA-F]{3,8}$/).optional()
|
|
13863
14265
|
}),
|
|
13864
14266
|
async (args, ctx) => {
|
|
13865
14267
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -13905,9 +14307,9 @@ var init_terminal = __esm({
|
|
|
13905
14307
|
);
|
|
13906
14308
|
registerCommand(
|
|
13907
14309
|
"terminal.replay",
|
|
13908
|
-
|
|
13909
|
-
terminalId:
|
|
13910
|
-
lastSeq:
|
|
14310
|
+
z7.object({
|
|
14311
|
+
terminalId: z7.string(),
|
|
14312
|
+
lastSeq: z7.number().int().nonnegative().optional()
|
|
13911
14313
|
}),
|
|
13912
14314
|
async (args, ctx, clientId) => {
|
|
13913
14315
|
const replay = ctx.terminalMgr.replay(args.terminalId, args.lastSeq ?? 0);
|
|
@@ -13932,8 +14334,8 @@ var init_terminal = __esm({
|
|
|
13932
14334
|
);
|
|
13933
14335
|
registerCommand(
|
|
13934
14336
|
"terminal.snapshot",
|
|
13935
|
-
|
|
13936
|
-
terminalId:
|
|
14337
|
+
z7.object({
|
|
14338
|
+
terminalId: z7.string()
|
|
13937
14339
|
}),
|
|
13938
14340
|
async (args, ctx, clientId) => {
|
|
13939
14341
|
const snapshot = await ctx.terminalMgr.snapshot(args.terminalId);
|
|
@@ -13961,8 +14363,8 @@ var init_terminal = __esm({
|
|
|
13961
14363
|
);
|
|
13962
14364
|
registerCommand(
|
|
13963
14365
|
"terminal.close",
|
|
13964
|
-
|
|
13965
|
-
terminalId:
|
|
14366
|
+
z7.object({
|
|
14367
|
+
terminalId: z7.string()
|
|
13966
14368
|
}),
|
|
13967
14369
|
async (args, ctx) => {
|
|
13968
14370
|
await ctx.terminalMgr.close(args.terminalId);
|
|
@@ -13984,10 +14386,10 @@ var init_terminal = __esm({
|
|
|
13984
14386
|
});
|
|
13985
14387
|
registerCommand(
|
|
13986
14388
|
"terminal.resize",
|
|
13987
|
-
|
|
13988
|
-
terminalId:
|
|
13989
|
-
cols:
|
|
13990
|
-
rows:
|
|
14389
|
+
z7.object({
|
|
14390
|
+
terminalId: z7.string(),
|
|
14391
|
+
cols: z7.number().int().positive(),
|
|
14392
|
+
rows: z7.number().int().positive()
|
|
13991
14393
|
}),
|
|
13992
14394
|
async (args, ctx) => {
|
|
13993
14395
|
const sessionId = ctx.sessionMgr.findSessionIdByTerminal(args.terminalId);
|
|
@@ -14610,7 +15012,7 @@ var init_hub = __esm({
|
|
|
14610
15012
|
}
|
|
14611
15013
|
}
|
|
14612
15014
|
awaitBinaryPayload(clientId) {
|
|
14613
|
-
return new Promise((
|
|
15015
|
+
return new Promise((resolve8, reject) => {
|
|
14614
15016
|
const timer = setTimeout(() => {
|
|
14615
15017
|
const waiters = this.pendingBinaryWaiters.get(clientId);
|
|
14616
15018
|
if (!waiters) return;
|
|
@@ -14622,7 +15024,7 @@ var init_hub = __esm({
|
|
|
14622
15024
|
}
|
|
14623
15025
|
reject(new Error("Timeout waiting for terminal input binary payload"));
|
|
14624
15026
|
}, BINARY_PAYLOAD_TIMEOUT_MS);
|
|
14625
|
-
const waiter = { resolve:
|
|
15027
|
+
const waiter = { resolve: resolve8, reject, timer };
|
|
14626
15028
|
const queue = this.pendingBinaryWaiters.get(clientId);
|
|
14627
15029
|
if (queue) {
|
|
14628
15030
|
queue.push(waiter);
|
|
@@ -14926,57 +15328,270 @@ var init_hub = __esm({
|
|
|
14926
15328
|
}
|
|
14927
15329
|
});
|
|
14928
15330
|
|
|
14929
|
-
// packages/server/src/
|
|
14930
|
-
import {
|
|
14931
|
-
import {
|
|
14932
|
-
|
|
14933
|
-
|
|
14934
|
-
|
|
14935
|
-
|
|
14936
|
-
|
|
14937
|
-
|
|
15331
|
+
// packages/server/src/workspace/intelligence.ts
|
|
15332
|
+
import { access as access2, lstat as lstat2, readFile as readFile4, stat as stat9 } from "node:fs/promises";
|
|
15333
|
+
import { join as join12, resolve as resolve4 } from "node:path";
|
|
15334
|
+
async function inspectWorkspaceIntelligence(input2) {
|
|
15335
|
+
const [packageManager, manifest, git, docsExistence, agentsExists, frameworks] = await Promise.all([
|
|
15336
|
+
detectPackageManager(input2.rootPath),
|
|
15337
|
+
readPackageJson(input2.rootPath),
|
|
15338
|
+
detectGitState(input2.rootPath),
|
|
15339
|
+
detectDocs(input2.rootPath),
|
|
15340
|
+
pathExists(join12(input2.rootPath, AGENT_INSTRUCTIONS_RELATIVE_PATH)),
|
|
15341
|
+
detectFrameworks(input2.rootPath)
|
|
15342
|
+
]);
|
|
15343
|
+
const scripts = extractScripts(manifest);
|
|
15344
|
+
return {
|
|
15345
|
+
workspaceId: input2.workspaceId,
|
|
15346
|
+
rootPath: input2.rootPath,
|
|
15347
|
+
git,
|
|
15348
|
+
packageManager,
|
|
15349
|
+
frameworks,
|
|
15350
|
+
scripts,
|
|
15351
|
+
recommendedCommands: buildRecommendedCommands(packageManager, scripts),
|
|
15352
|
+
docs: docsExistence,
|
|
15353
|
+
agentInstructions: {
|
|
15354
|
+
exists: agentsExists,
|
|
15355
|
+
path: AGENT_INSTRUCTIONS_RELATIVE_PATH
|
|
15356
|
+
}
|
|
15357
|
+
};
|
|
15358
|
+
}
|
|
15359
|
+
async function detectPackageManager(rootPath) {
|
|
15360
|
+
for (const candidate of packageManagerCandidates) {
|
|
15361
|
+
if (await pathExists(join12(rootPath, candidate.file))) {
|
|
15362
|
+
return candidate.manager;
|
|
15363
|
+
}
|
|
14938
15364
|
}
|
|
14939
|
-
if (
|
|
14940
|
-
return
|
|
15365
|
+
if (await pathExists(join12(rootPath, "package.json"))) {
|
|
15366
|
+
return "npm";
|
|
14941
15367
|
}
|
|
14942
|
-
return
|
|
15368
|
+
return void 0;
|
|
14943
15369
|
}
|
|
14944
|
-
async function
|
|
14945
|
-
const
|
|
14946
|
-
|
|
14947
|
-
|
|
15370
|
+
async function readPackageJson(rootPath) {
|
|
15371
|
+
const packageJsonPath = join12(rootPath, "package.json");
|
|
15372
|
+
if (!await pathExists(packageJsonPath)) {
|
|
15373
|
+
return null;
|
|
15374
|
+
}
|
|
14948
15375
|
try {
|
|
14949
|
-
|
|
15376
|
+
const raw = await readFile4(packageJsonPath, "utf8");
|
|
15377
|
+
const parsed = JSON.parse(raw);
|
|
15378
|
+
return parsed && typeof parsed === "object" ? parsed : null;
|
|
14950
15379
|
} catch {
|
|
15380
|
+
return null;
|
|
14951
15381
|
}
|
|
14952
|
-
|
|
14953
|
-
|
|
14954
|
-
|
|
15382
|
+
}
|
|
15383
|
+
function extractScripts(manifest) {
|
|
15384
|
+
const scripts = manifest?.scripts ?? {};
|
|
15385
|
+
return {
|
|
15386
|
+
dev: normalizeScript(scripts.dev),
|
|
15387
|
+
test: normalizeScript(scripts.test),
|
|
15388
|
+
build: normalizeScript(scripts.build),
|
|
15389
|
+
lint: normalizeScript(scripts.lint)
|
|
15390
|
+
};
|
|
15391
|
+
}
|
|
15392
|
+
function normalizeScript(value) {
|
|
15393
|
+
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
15394
|
+
}
|
|
15395
|
+
function buildRecommendedCommands(packageManager, scripts) {
|
|
15396
|
+
if (!packageManager) {
|
|
15397
|
+
return [];
|
|
14955
15398
|
}
|
|
14956
|
-
return
|
|
15399
|
+
return packageScriptKeys.flatMap((key) => {
|
|
15400
|
+
if (!scripts[key]) {
|
|
15401
|
+
return [];
|
|
15402
|
+
}
|
|
15403
|
+
return [
|
|
15404
|
+
{
|
|
15405
|
+
key,
|
|
15406
|
+
command: buildPackageCommand(packageManager, key),
|
|
15407
|
+
source: "package_json"
|
|
15408
|
+
}
|
|
15409
|
+
];
|
|
15410
|
+
});
|
|
14957
15411
|
}
|
|
14958
|
-
|
|
14959
|
-
|
|
14960
|
-
|
|
14961
|
-
|
|
14962
|
-
|
|
14963
|
-
return
|
|
14964
|
-
|
|
14965
|
-
|
|
14966
|
-
|
|
14967
|
-
|
|
14968
|
-
|
|
14969
|
-
|
|
14970
|
-
|
|
14971
|
-
|
|
14972
|
-
|
|
14973
|
-
|
|
15412
|
+
function buildPackageCommand(packageManager, scriptName) {
|
|
15413
|
+
switch (packageManager) {
|
|
15414
|
+
case "pnpm":
|
|
15415
|
+
return `pnpm ${scriptName}`;
|
|
15416
|
+
case "yarn":
|
|
15417
|
+
return `yarn ${scriptName}`;
|
|
15418
|
+
case "bun":
|
|
15419
|
+
return `bun run ${scriptName}`;
|
|
15420
|
+
case "npm":
|
|
15421
|
+
default:
|
|
15422
|
+
return `npm run ${scriptName}`;
|
|
15423
|
+
}
|
|
15424
|
+
}
|
|
15425
|
+
async function detectFrameworks(rootPath) {
|
|
15426
|
+
const manifest = await readPackageJson(rootPath);
|
|
15427
|
+
const deps = {
|
|
15428
|
+
...manifest?.dependencies ?? {},
|
|
15429
|
+
...manifest?.devDependencies ?? {}
|
|
15430
|
+
};
|
|
15431
|
+
const frameworks = /* @__PURE__ */ new Set();
|
|
15432
|
+
if ("next" in deps) {
|
|
15433
|
+
frameworks.add("Next.js");
|
|
15434
|
+
}
|
|
15435
|
+
if ("react" in deps) {
|
|
15436
|
+
frameworks.add("React");
|
|
15437
|
+
}
|
|
15438
|
+
if ("vite" in deps || await hasAnyPath(rootPath, viteConfigFiles)) {
|
|
15439
|
+
frameworks.add("Vite");
|
|
15440
|
+
}
|
|
15441
|
+
if (manifest) {
|
|
15442
|
+
frameworks.add("Node");
|
|
15443
|
+
}
|
|
15444
|
+
if (await hasAnyPath(rootPath, ["pnpm-workspace.yaml", "turbo.json", "nx.json"])) {
|
|
15445
|
+
frameworks.add("Monorepo");
|
|
15446
|
+
}
|
|
15447
|
+
return frameworkOrder.filter((framework) => frameworks.has(framework));
|
|
15448
|
+
}
|
|
15449
|
+
async function detectGitState(rootPath) {
|
|
15450
|
+
const gitPath = join12(rootPath, ".git");
|
|
15451
|
+
let stats;
|
|
15452
|
+
try {
|
|
15453
|
+
stats = await lstat2(gitPath);
|
|
15454
|
+
} catch {
|
|
15455
|
+
return { isRepo: false };
|
|
15456
|
+
}
|
|
15457
|
+
const gitDir = stats.isDirectory() ? gitPath : stats.isFile() ? await resolveGitDirFromFile(rootPath, gitPath) : null;
|
|
15458
|
+
if (!gitDir) {
|
|
15459
|
+
return { isRepo: false };
|
|
15460
|
+
}
|
|
15461
|
+
const branch = await readGitBranch(gitDir);
|
|
15462
|
+
return branch ? { isRepo: true, branch } : { isRepo: true };
|
|
15463
|
+
}
|
|
15464
|
+
async function resolveGitDirFromFile(rootPath, gitFilePath) {
|
|
15465
|
+
try {
|
|
15466
|
+
const raw = await readFile4(gitFilePath, "utf8");
|
|
15467
|
+
const match = raw.match(/^gitdir:\s*(.+)\s*$/m);
|
|
15468
|
+
if (!match) {
|
|
15469
|
+
return null;
|
|
15470
|
+
}
|
|
15471
|
+
const gitDirPath = match[1];
|
|
15472
|
+
if (!gitDirPath) {
|
|
15473
|
+
return null;
|
|
15474
|
+
}
|
|
15475
|
+
return resolve4(rootPath, gitDirPath);
|
|
15476
|
+
} catch {
|
|
15477
|
+
return null;
|
|
15478
|
+
}
|
|
15479
|
+
}
|
|
15480
|
+
async function readGitBranch(gitDir) {
|
|
15481
|
+
try {
|
|
15482
|
+
const head = await readFile4(join12(gitDir, "HEAD"), "utf8");
|
|
15483
|
+
const refMatch = head.match(/^ref:\s*refs\/heads\/(.+)\s*$/);
|
|
15484
|
+
return refMatch?.[1];
|
|
15485
|
+
} catch {
|
|
15486
|
+
return void 0;
|
|
15487
|
+
}
|
|
15488
|
+
}
|
|
15489
|
+
async function detectDocs(rootPath) {
|
|
15490
|
+
const docs = [];
|
|
15491
|
+
if (await pathExists(join12(rootPath, "README.md"))) {
|
|
15492
|
+
docs.push({ path: "README.md", kind: "readme" });
|
|
15493
|
+
}
|
|
15494
|
+
if (await pathExists(join12(rootPath, "docs"))) {
|
|
15495
|
+
try {
|
|
15496
|
+
const docsStats = await stat9(join12(rootPath, "docs"));
|
|
15497
|
+
if (docsStats.isDirectory()) {
|
|
15498
|
+
docs.push({ path: "docs", kind: "docs" });
|
|
15499
|
+
}
|
|
15500
|
+
} catch {
|
|
15501
|
+
}
|
|
15502
|
+
}
|
|
15503
|
+
return docs;
|
|
15504
|
+
}
|
|
15505
|
+
async function hasAnyPath(rootPath, relativePaths) {
|
|
15506
|
+
for (const relativePath of relativePaths) {
|
|
15507
|
+
if (await pathExists(join12(rootPath, relativePath))) {
|
|
15508
|
+
return true;
|
|
15509
|
+
}
|
|
15510
|
+
}
|
|
15511
|
+
return false;
|
|
15512
|
+
}
|
|
15513
|
+
async function pathExists(path14) {
|
|
15514
|
+
try {
|
|
15515
|
+
await access2(path14);
|
|
15516
|
+
return true;
|
|
15517
|
+
} catch {
|
|
15518
|
+
return false;
|
|
15519
|
+
}
|
|
15520
|
+
}
|
|
15521
|
+
var frameworkOrder, packageManagerCandidates, packageScriptKeys, viteConfigFiles;
|
|
15522
|
+
var init_intelligence = __esm({
|
|
15523
|
+
"packages/server/src/workspace/intelligence.ts"() {
|
|
15524
|
+
"use strict";
|
|
15525
|
+
init_workspace_state();
|
|
15526
|
+
frameworkOrder = ["Next.js", "React", "Vite", "Node", "Monorepo"];
|
|
15527
|
+
packageManagerCandidates = [
|
|
15528
|
+
{ file: "pnpm-lock.yaml", manager: "pnpm" },
|
|
15529
|
+
{ file: "yarn.lock", manager: "yarn" },
|
|
15530
|
+
{ file: "bun.lockb", manager: "bun" },
|
|
15531
|
+
{ file: "package-lock.json", manager: "npm" }
|
|
15532
|
+
];
|
|
15533
|
+
packageScriptKeys = ["dev", "test", "build", "lint"];
|
|
15534
|
+
viteConfigFiles = [
|
|
15535
|
+
"vite.config.ts",
|
|
15536
|
+
"vite.config.js",
|
|
15537
|
+
"vite.config.mjs",
|
|
15538
|
+
"vite.config.cjs"
|
|
15539
|
+
];
|
|
15540
|
+
}
|
|
15541
|
+
});
|
|
15542
|
+
|
|
15543
|
+
// packages/server/src/commands/workspace.ts
|
|
15544
|
+
import { readdir as readdir3, realpath as realpath3 } from "node:fs/promises";
|
|
15545
|
+
import { homedir as homedir2 } from "node:os";
|
|
15546
|
+
import { isAbsolute as isAbsolute3, join as join13, resolve as resolve5 } from "node:path";
|
|
15547
|
+
import { z as z8 } from "zod";
|
|
15548
|
+
function resolveBrowsePath(path14) {
|
|
15549
|
+
const home = homedir2();
|
|
15550
|
+
if (!path14 || path14 === "~") {
|
|
15551
|
+
return home;
|
|
15552
|
+
}
|
|
15553
|
+
if (path14.startsWith("~/")) {
|
|
15554
|
+
return join13(home, path14.slice(2));
|
|
15555
|
+
}
|
|
15556
|
+
return isAbsolute3(path14) ? path14 : resolve5(home, path14);
|
|
15557
|
+
}
|
|
15558
|
+
async function buildRootPaths(currentPath) {
|
|
15559
|
+
const roots = /* @__PURE__ */ new Set(["/"]);
|
|
15560
|
+
const home = homedir2();
|
|
15561
|
+
roots.add(home);
|
|
15562
|
+
try {
|
|
15563
|
+
roots.add(await realpath3(home));
|
|
15564
|
+
} catch {
|
|
15565
|
+
}
|
|
15566
|
+
const currentSegments = currentPath.split("/").filter(Boolean);
|
|
15567
|
+
if (currentSegments.length > 0) {
|
|
15568
|
+
roots.add(`/${currentSegments[0]}`);
|
|
15569
|
+
}
|
|
15570
|
+
return Array.from(roots);
|
|
15571
|
+
}
|
|
15572
|
+
var init_workspace = __esm({
|
|
15573
|
+
"packages/server/src/commands/workspace.ts"() {
|
|
15574
|
+
"use strict";
|
|
15575
|
+
init_intelligence();
|
|
15576
|
+
init_dispatch();
|
|
15577
|
+
registerCommand("workspace.list", z8.object({}), async (_args, ctx) => {
|
|
15578
|
+
return ctx.workspaceMgr.list();
|
|
15579
|
+
});
|
|
15580
|
+
registerCommand(
|
|
15581
|
+
"workspace.browse",
|
|
15582
|
+
z8.object({
|
|
15583
|
+
path: z8.string().optional()
|
|
15584
|
+
}),
|
|
15585
|
+
async (args) => {
|
|
15586
|
+
const basePath = resolveBrowsePath(args.path);
|
|
15587
|
+
const entries = await readdir3(basePath, { withFileTypes: true });
|
|
15588
|
+
const directories = entries.filter((entry) => entry.isDirectory()).map((entry) => ({
|
|
14974
15589
|
name: entry.name,
|
|
14975
|
-
path:
|
|
15590
|
+
path: join13(basePath, entry.name)
|
|
14976
15591
|
})).sort((a, b) => a.name.localeCompare(b.name));
|
|
14977
15592
|
return {
|
|
14978
15593
|
currentPath: basePath,
|
|
14979
|
-
parentPath: basePath !== "/" ?
|
|
15594
|
+
parentPath: basePath !== "/" ? join13(basePath, "..") : null,
|
|
14980
15595
|
directories,
|
|
14981
15596
|
rootPaths: await buildRootPaths(basePath)
|
|
14982
15597
|
};
|
|
@@ -14984,8 +15599,8 @@ var init_workspace = __esm({
|
|
|
14984
15599
|
);
|
|
14985
15600
|
registerCommand(
|
|
14986
15601
|
"workspace.open",
|
|
14987
|
-
|
|
14988
|
-
path:
|
|
15602
|
+
z8.object({
|
|
15603
|
+
path: z8.string()
|
|
14989
15604
|
}),
|
|
14990
15605
|
async (args, ctx) => {
|
|
14991
15606
|
return ctx.workspaceMgr.open({
|
|
@@ -14993,10 +15608,26 @@ var init_workspace = __esm({
|
|
|
14993
15608
|
});
|
|
14994
15609
|
}
|
|
14995
15610
|
);
|
|
15611
|
+
registerCommand(
|
|
15612
|
+
"workspace.intelligence",
|
|
15613
|
+
z8.object({
|
|
15614
|
+
workspaceId: z8.string()
|
|
15615
|
+
}),
|
|
15616
|
+
async (args, ctx) => {
|
|
15617
|
+
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
15618
|
+
if (!workspace) {
|
|
15619
|
+
throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
|
|
15620
|
+
}
|
|
15621
|
+
return inspectWorkspaceIntelligence({
|
|
15622
|
+
workspaceId: workspace.id,
|
|
15623
|
+
rootPath: workspace.path
|
|
15624
|
+
});
|
|
15625
|
+
}
|
|
15626
|
+
);
|
|
14996
15627
|
registerCommand(
|
|
14997
15628
|
"workspace.close",
|
|
14998
|
-
|
|
14999
|
-
id:
|
|
15629
|
+
z8.object({
|
|
15630
|
+
id: z8.string()
|
|
15000
15631
|
}),
|
|
15001
15632
|
async (args, ctx) => {
|
|
15002
15633
|
await ctx.workspaceMgr.close(args.id);
|
|
@@ -15004,27 +15635,27 @@ var init_workspace = __esm({
|
|
|
15004
15635
|
);
|
|
15005
15636
|
registerCommand(
|
|
15006
15637
|
"workspace.uiState.set",
|
|
15007
|
-
|
|
15008
|
-
workspaceId:
|
|
15009
|
-
uiState:
|
|
15010
|
-
leftPanelWidth:
|
|
15011
|
-
bottomPanelHeight:
|
|
15012
|
-
focusMode:
|
|
15013
|
-
activeSessionId:
|
|
15014
|
-
fileTreeExpandedDirs:
|
|
15015
|
-
paneLayout:
|
|
15016
|
-
id:
|
|
15017
|
-
type:
|
|
15018
|
-
sessionId:
|
|
15019
|
-
direction:
|
|
15020
|
-
children:
|
|
15021
|
-
() =>
|
|
15022
|
-
|
|
15023
|
-
id:
|
|
15024
|
-
type:
|
|
15025
|
-
sessionId:
|
|
15026
|
-
direction:
|
|
15027
|
-
children:
|
|
15638
|
+
z8.object({
|
|
15639
|
+
workspaceId: z8.string(),
|
|
15640
|
+
uiState: z8.object({
|
|
15641
|
+
leftPanelWidth: z8.number(),
|
|
15642
|
+
bottomPanelHeight: z8.number(),
|
|
15643
|
+
focusMode: z8.boolean(),
|
|
15644
|
+
activeSessionId: z8.string().optional(),
|
|
15645
|
+
fileTreeExpandedDirs: z8.array(z8.string()).optional(),
|
|
15646
|
+
paneLayout: z8.object({
|
|
15647
|
+
id: z8.string(),
|
|
15648
|
+
type: z8.enum(["leaf", "split"]),
|
|
15649
|
+
sessionId: z8.string().optional(),
|
|
15650
|
+
direction: z8.enum(["horizontal", "vertical"]).optional(),
|
|
15651
|
+
children: z8.lazy(
|
|
15652
|
+
() => z8.array(
|
|
15653
|
+
z8.object({
|
|
15654
|
+
id: z8.string(),
|
|
15655
|
+
type: z8.enum(["leaf", "split"]),
|
|
15656
|
+
sessionId: z8.string().optional(),
|
|
15657
|
+
direction: z8.enum(["horizontal", "vertical"]).optional(),
|
|
15658
|
+
children: z8.any().optional()
|
|
15028
15659
|
})
|
|
15029
15660
|
)
|
|
15030
15661
|
).optional()
|
|
@@ -15044,7 +15675,7 @@ var init_workspace = __esm({
|
|
|
15044
15675
|
});
|
|
15045
15676
|
|
|
15046
15677
|
// packages/server/src/commands/workspace-activity.ts
|
|
15047
|
-
import { z as
|
|
15678
|
+
import { z as z9 } from "zod";
|
|
15048
15679
|
function parseWorkspaceLastViewedTarget(value) {
|
|
15049
15680
|
try {
|
|
15050
15681
|
const parsed = JSON.parse(value);
|
|
@@ -15060,15 +15691,15 @@ var init_workspace_activity = __esm({
|
|
|
15060
15691
|
"use strict";
|
|
15061
15692
|
init_dispatch();
|
|
15062
15693
|
WORKSPACE_LAST_VIEWED_TARGET_KEY = "workspace.lastViewedTarget";
|
|
15063
|
-
workspaceLastViewedTargetSchema =
|
|
15064
|
-
workspaceId:
|
|
15065
|
-
sessionId:
|
|
15066
|
-
updatedAt:
|
|
15694
|
+
workspaceLastViewedTargetSchema = z9.object({
|
|
15695
|
+
workspaceId: z9.string(),
|
|
15696
|
+
sessionId: z9.string().optional(),
|
|
15697
|
+
updatedAt: z9.number()
|
|
15067
15698
|
});
|
|
15068
15699
|
registerCommand(
|
|
15069
15700
|
"workspace.activate",
|
|
15070
|
-
|
|
15071
|
-
workspaceId:
|
|
15701
|
+
z9.object({
|
|
15702
|
+
workspaceId: z9.string()
|
|
15072
15703
|
}),
|
|
15073
15704
|
async (args, ctx, clientId) => {
|
|
15074
15705
|
if (!clientId) {
|
|
@@ -15078,14 +15709,14 @@ var init_workspace_activity = __esm({
|
|
|
15078
15709
|
return {};
|
|
15079
15710
|
}
|
|
15080
15711
|
);
|
|
15081
|
-
registerCommand("workspace.deactivate",
|
|
15712
|
+
registerCommand("workspace.deactivate", z9.object({}), async (_args, ctx, clientId) => {
|
|
15082
15713
|
if (!clientId) {
|
|
15083
15714
|
return {};
|
|
15084
15715
|
}
|
|
15085
15716
|
ctx.autoFetch.unregisterViewer(clientId);
|
|
15086
15717
|
return {};
|
|
15087
15718
|
});
|
|
15088
|
-
registerCommand("workspace.lastViewedTarget.get",
|
|
15719
|
+
registerCommand("workspace.lastViewedTarget.get", z9.object({}), async (_args, ctx) => {
|
|
15089
15720
|
const value = ctx.settingsRepo.get(WORKSPACE_LAST_VIEWED_TARGET_KEY);
|
|
15090
15721
|
if (value === void 0) {
|
|
15091
15722
|
return null;
|
|
@@ -15094,9 +15725,9 @@ var init_workspace_activity = __esm({
|
|
|
15094
15725
|
});
|
|
15095
15726
|
registerCommand(
|
|
15096
15727
|
"workspace.lastViewedTarget.set",
|
|
15097
|
-
|
|
15098
|
-
workspaceId:
|
|
15099
|
-
sessionId:
|
|
15728
|
+
z9.object({
|
|
15729
|
+
workspaceId: z9.string(),
|
|
15730
|
+
sessionId: z9.string().optional()
|
|
15100
15731
|
}),
|
|
15101
15732
|
async (args, ctx) => {
|
|
15102
15733
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -15120,14 +15751,14 @@ var init_workspace_activity = __esm({
|
|
|
15120
15751
|
});
|
|
15121
15752
|
|
|
15122
15753
|
// packages/server/src/commands/activation.ts
|
|
15123
|
-
import { z as
|
|
15754
|
+
import { z as z10 } from "zod";
|
|
15124
15755
|
var init_activation2 = __esm({
|
|
15125
15756
|
"packages/server/src/commands/activation.ts"() {
|
|
15126
15757
|
"use strict";
|
|
15127
15758
|
init_dispatch();
|
|
15128
15759
|
registerCommand(
|
|
15129
15760
|
"activation.claim",
|
|
15130
|
-
|
|
15761
|
+
z10.object({ clientInstanceId: z10.string().min(1) }),
|
|
15131
15762
|
async (args, ctx, clientId) => {
|
|
15132
15763
|
if (!clientId) {
|
|
15133
15764
|
throw {
|
|
@@ -15151,7 +15782,7 @@ var init_activation2 = __esm({
|
|
|
15151
15782
|
);
|
|
15152
15783
|
registerCommand(
|
|
15153
15784
|
"activation.release",
|
|
15154
|
-
|
|
15785
|
+
z10.object({ clientInstanceId: z10.string(), generation: z10.number().int().positive() }),
|
|
15155
15786
|
async (args, ctx, clientId) => {
|
|
15156
15787
|
const lease = ctx.activationMgr.getLease();
|
|
15157
15788
|
if (!clientId || !lease || lease.wsClientId !== clientId) {
|
|
@@ -15165,34 +15796,34 @@ var init_activation2 = __esm({
|
|
|
15165
15796
|
});
|
|
15166
15797
|
|
|
15167
15798
|
// packages/server/src/commands/connection.ts
|
|
15168
|
-
import { z as
|
|
15799
|
+
import { z as z11 } from "zod";
|
|
15169
15800
|
var init_connection = __esm({
|
|
15170
15801
|
"packages/server/src/commands/connection.ts"() {
|
|
15171
15802
|
"use strict";
|
|
15172
15803
|
init_dispatch();
|
|
15173
|
-
registerCommand("connection.probe",
|
|
15804
|
+
registerCommand("connection.probe", z11.object({}).default({}), async () => {
|
|
15174
15805
|
return { ok: true };
|
|
15175
15806
|
});
|
|
15176
15807
|
}
|
|
15177
15808
|
});
|
|
15178
15809
|
|
|
15179
15810
|
// packages/server/src/commands/recovery.ts
|
|
15180
|
-
import { z as
|
|
15811
|
+
import { z as z12 } from "zod";
|
|
15181
15812
|
var RecoveryReasonSchema;
|
|
15182
15813
|
var init_recovery = __esm({
|
|
15183
15814
|
"packages/server/src/commands/recovery.ts"() {
|
|
15184
15815
|
"use strict";
|
|
15185
15816
|
init_src3();
|
|
15186
15817
|
init_dispatch();
|
|
15187
|
-
RecoveryReasonSchema =
|
|
15818
|
+
RecoveryReasonSchema = z12.enum(RECOVERY_REASONS);
|
|
15188
15819
|
registerCommand(
|
|
15189
15820
|
"recovery.reconcile",
|
|
15190
|
-
|
|
15821
|
+
z12.object({
|
|
15191
15822
|
reason: RecoveryReasonSchema,
|
|
15192
|
-
terminals:
|
|
15193
|
-
|
|
15194
|
-
terminalId:
|
|
15195
|
-
renderedSeq:
|
|
15823
|
+
terminals: z12.array(
|
|
15824
|
+
z12.object({
|
|
15825
|
+
terminalId: z12.string(),
|
|
15826
|
+
renderedSeq: z12.number().int().nonnegative()
|
|
15196
15827
|
})
|
|
15197
15828
|
)
|
|
15198
15829
|
}),
|
|
@@ -15438,15 +16069,33 @@ var init_pane_layout = __esm({
|
|
|
15438
16069
|
});
|
|
15439
16070
|
|
|
15440
16071
|
// packages/server/src/commands/session.ts
|
|
15441
|
-
import {
|
|
16072
|
+
import { readFile as readFile5 } from "node:fs/promises";
|
|
16073
|
+
import { join as join14, resolve as resolve6 } from "node:path";
|
|
16074
|
+
import { z as z13 } from "zod";
|
|
15442
16075
|
function delay(ms) {
|
|
15443
|
-
return new Promise((
|
|
15444
|
-
setTimeout(
|
|
16076
|
+
return new Promise((resolve8) => {
|
|
16077
|
+
setTimeout(resolve8, ms);
|
|
15445
16078
|
});
|
|
15446
16079
|
}
|
|
15447
16080
|
function getProviderFromRegistry(providerId, registry) {
|
|
15448
16081
|
return registry.find((provider) => provider.id === providerId);
|
|
15449
16082
|
}
|
|
16083
|
+
async function tryReadGitHead(workspacePath) {
|
|
16084
|
+
try {
|
|
16085
|
+
const gitEntryPath = join14(workspacePath, ".git");
|
|
16086
|
+
const gitEntry = await readFile5(gitEntryPath, "utf8").catch(() => null);
|
|
16087
|
+
let gitDir = gitEntryPath;
|
|
16088
|
+
if (gitEntry && gitEntry.startsWith("gitdir:")) {
|
|
16089
|
+
const relativeGitDir = gitEntry.slice("gitdir:".length).trim();
|
|
16090
|
+
gitDir = resolve6(workspacePath, relativeGitDir);
|
|
16091
|
+
}
|
|
16092
|
+
const head = await readFile5(join14(gitDir, "HEAD"), "utf8");
|
|
16093
|
+
const trimmed = head.trim();
|
|
16094
|
+
return trimmed.length > 0 && !trimmed.startsWith("ref:") ? trimmed : void 0;
|
|
16095
|
+
} catch {
|
|
16096
|
+
return void 0;
|
|
16097
|
+
}
|
|
16098
|
+
}
|
|
15450
16099
|
var SESSION_CLOSE_POLL_INTERVAL_MS, SESSION_CLOSE_TIMEOUT_MS;
|
|
15451
16100
|
var init_session2 = __esm({
|
|
15452
16101
|
"packages/server/src/commands/session.ts"() {
|
|
@@ -15458,8 +16107,8 @@ var init_session2 = __esm({
|
|
|
15458
16107
|
SESSION_CLOSE_TIMEOUT_MS = 5e3;
|
|
15459
16108
|
registerCommand(
|
|
15460
16109
|
"session.list",
|
|
15461
|
-
|
|
15462
|
-
workspaceId:
|
|
16110
|
+
z13.object({
|
|
16111
|
+
workspaceId: z13.string()
|
|
15463
16112
|
}),
|
|
15464
16113
|
async (args, ctx) => {
|
|
15465
16114
|
return ctx.sessionMgr.getForWorkspace(args.workspaceId);
|
|
@@ -15467,11 +16116,11 @@ var init_session2 = __esm({
|
|
|
15467
16116
|
);
|
|
15468
16117
|
registerCommand(
|
|
15469
16118
|
"session.create",
|
|
15470
|
-
|
|
15471
|
-
workspaceId:
|
|
15472
|
-
providerId:
|
|
15473
|
-
draft:
|
|
15474
|
-
themeBackground:
|
|
16119
|
+
z13.object({
|
|
16120
|
+
workspaceId: z13.string(),
|
|
16121
|
+
providerId: z13.string(),
|
|
16122
|
+
draft: z13.string().optional(),
|
|
16123
|
+
themeBackground: z13.string().regex(/^#[0-9a-fA-F]{3,8}$/).optional()
|
|
15475
16124
|
}),
|
|
15476
16125
|
async (args, ctx) => {
|
|
15477
16126
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -15494,7 +16143,7 @@ var init_session2 = __esm({
|
|
|
15494
16143
|
}
|
|
15495
16144
|
};
|
|
15496
16145
|
}
|
|
15497
|
-
|
|
16146
|
+
const session = await ctx.sessionMgr.create({
|
|
15498
16147
|
workspaceId: args.workspaceId,
|
|
15499
16148
|
workspacePath: workspace.path,
|
|
15500
16149
|
providerId: args.providerId,
|
|
@@ -15502,12 +16151,22 @@ var init_session2 = __esm({
|
|
|
15502
16151
|
draft: args.draft,
|
|
15503
16152
|
themeBackground: args.themeBackground
|
|
15504
16153
|
});
|
|
16154
|
+
ctx.sessionMetadataRepo?.upsert({
|
|
16155
|
+
sessionId: session.id,
|
|
16156
|
+
workspaceId: args.workspaceId,
|
|
16157
|
+
providerId: args.providerId,
|
|
16158
|
+
objective: args.draft?.trim() || void 0,
|
|
16159
|
+
baselineGitHead: await tryReadGitHead(workspace.path),
|
|
16160
|
+
baselineCapturedAt: Date.now(),
|
|
16161
|
+
verificationRuns: []
|
|
16162
|
+
});
|
|
16163
|
+
return session;
|
|
15505
16164
|
}
|
|
15506
16165
|
);
|
|
15507
16166
|
registerCommand(
|
|
15508
16167
|
"session.stop",
|
|
15509
|
-
|
|
15510
|
-
sessionId:
|
|
16168
|
+
z13.object({
|
|
16169
|
+
sessionId: z13.string()
|
|
15511
16170
|
}),
|
|
15512
16171
|
async (args, ctx) => {
|
|
15513
16172
|
await ctx.sessionMgr.stop(args.sessionId);
|
|
@@ -15515,8 +16174,8 @@ var init_session2 = __esm({
|
|
|
15515
16174
|
);
|
|
15516
16175
|
registerCommand(
|
|
15517
16176
|
"session.remove",
|
|
15518
|
-
|
|
15519
|
-
sessionId:
|
|
16177
|
+
z13.object({
|
|
16178
|
+
sessionId: z13.string()
|
|
15520
16179
|
}),
|
|
15521
16180
|
async (args, ctx) => {
|
|
15522
16181
|
const session = ctx.sessionMgr.get(args.sessionId);
|
|
@@ -15527,13 +16186,14 @@ var init_session2 = __esm({
|
|
|
15527
16186
|
throw { code: "invalid_state", message: `Cannot remove session in state: ${session.state}` };
|
|
15528
16187
|
}
|
|
15529
16188
|
ctx.sessionMgr.delete(args.sessionId);
|
|
16189
|
+
ctx.sessionMetadataRepo?.delete(args.sessionId);
|
|
15530
16190
|
}
|
|
15531
16191
|
);
|
|
15532
16192
|
registerCommand(
|
|
15533
16193
|
"session.close",
|
|
15534
|
-
|
|
15535
|
-
sessionId:
|
|
15536
|
-
paneDisposition:
|
|
16194
|
+
z13.object({
|
|
16195
|
+
sessionId: z13.string(),
|
|
16196
|
+
paneDisposition: z13.enum(["draft", "remove"]).default("draft")
|
|
15537
16197
|
}),
|
|
15538
16198
|
async (args, ctx) => {
|
|
15539
16199
|
let session = ctx.sessionMgr.get(args.sessionId);
|
|
@@ -15589,112 +16249,553 @@ var init_session2 = __esm({
|
|
|
15589
16249
|
};
|
|
15590
16250
|
ctx.workspaceMgr.updateUiState(session.workspaceId, nextUiState);
|
|
15591
16251
|
ctx.sessionMgr.delete(args.sessionId);
|
|
16252
|
+
ctx.sessionMetadataRepo?.delete(args.sessionId);
|
|
15592
16253
|
}
|
|
15593
16254
|
);
|
|
15594
16255
|
}
|
|
15595
16256
|
});
|
|
15596
16257
|
|
|
15597
|
-
// packages/server/src/
|
|
15598
|
-
import {
|
|
15599
|
-
import {
|
|
15600
|
-
|
|
15601
|
-
|
|
15602
|
-
|
|
15603
|
-
|
|
15604
|
-
|
|
15605
|
-
if (!query) {
|
|
15606
|
-
return {
|
|
15607
|
-
files: [],
|
|
15608
|
-
totalMatchCount: 0,
|
|
15609
|
-
hasMoreFiles: false,
|
|
15610
|
-
truncatedMatchFileCount: 0
|
|
16258
|
+
// packages/server/src/commands/session-metadata.ts
|
|
16259
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
16260
|
+
import { z as z14 } from "zod";
|
|
16261
|
+
function requireSessionMetadataRepo(ctx) {
|
|
16262
|
+
if (!ctx.sessionMetadataRepo) {
|
|
16263
|
+
throw {
|
|
16264
|
+
code: "session_metadata_unavailable",
|
|
16265
|
+
message: "Session metadata repository is not configured"
|
|
15611
16266
|
};
|
|
15612
16267
|
}
|
|
15613
|
-
const result = await searchWithRipgrep(rootPath, query, options.maxFiles).catch(
|
|
15614
|
-
async (error) => {
|
|
15615
|
-
if (error.code === "ENOENT") {
|
|
15616
|
-
return searchWithNode(rootPath, query, options.maxFiles);
|
|
15617
|
-
}
|
|
15618
|
-
throw error;
|
|
15619
|
-
}
|
|
15620
|
-
);
|
|
15621
|
-
return finalizeResults(result, options.maxFiles, options.maxMatchesPerFile);
|
|
15622
16268
|
}
|
|
15623
|
-
|
|
15624
|
-
|
|
15625
|
-
|
|
15626
|
-
|
|
15627
|
-
|
|
15628
|
-
|
|
15629
|
-
|
|
15630
|
-
|
|
15631
|
-
|
|
15632
|
-
|
|
15633
|
-
|
|
15634
|
-
|
|
15635
|
-
|
|
15636
|
-
|
|
15637
|
-
|
|
15638
|
-
|
|
15639
|
-
|
|
15640
|
-
|
|
15641
|
-
|
|
15642
|
-
args.push(query, ".");
|
|
15643
|
-
return new Promise((resolve6, reject) => {
|
|
15644
|
-
const child = spawn5("rg", args, { cwd: rootPath, stdio: ["ignore", "pipe", "pipe"] });
|
|
15645
|
-
const stdout = createInterface({ input: child.stdout });
|
|
15646
|
-
const files = /* @__PURE__ */ new Map();
|
|
15647
|
-
let totalMatchCount = 0;
|
|
15648
|
-
let hasMoreFiles = false;
|
|
15649
|
-
let stderr = "";
|
|
15650
|
-
stdout.on("line", (line) => {
|
|
15651
|
-
if (!line.trim()) {
|
|
15652
|
-
return;
|
|
15653
|
-
}
|
|
15654
|
-
const event = JSON.parse(line);
|
|
15655
|
-
if (event.type !== "match") {
|
|
15656
|
-
return;
|
|
15657
|
-
}
|
|
15658
|
-
const rawPath = event.data?.path?.text;
|
|
15659
|
-
if (!rawPath) {
|
|
15660
|
-
return;
|
|
15661
|
-
}
|
|
15662
|
-
const relativePath = normalizeRelativePath(relative3(rootPath, join12(rootPath, rawPath)));
|
|
15663
|
-
const preview = (event.data?.lines?.text ?? "").replace(/\r?\n$/, "");
|
|
15664
|
-
const lineNumber = event.data?.line_number ?? 1;
|
|
15665
|
-
const submatches = event.data?.submatches ?? [];
|
|
15666
|
-
totalMatchCount += submatches.length;
|
|
15667
|
-
if (!files.has(relativePath) && files.size >= maxFiles) {
|
|
15668
|
-
hasMoreFiles = true;
|
|
15669
|
-
return;
|
|
16269
|
+
var init_session_metadata = __esm({
|
|
16270
|
+
"packages/server/src/commands/session-metadata.ts"() {
|
|
16271
|
+
"use strict";
|
|
16272
|
+
init_dispatch();
|
|
16273
|
+
registerCommand(
|
|
16274
|
+
"session.metadata.get",
|
|
16275
|
+
z14.object({
|
|
16276
|
+
sessionId: z14.string()
|
|
16277
|
+
}),
|
|
16278
|
+
async (args, ctx) => {
|
|
16279
|
+
requireSessionMetadataRepo(ctx);
|
|
16280
|
+
const metadata = ctx.sessionMetadataRepo.get(args.sessionId);
|
|
16281
|
+
if (!metadata) {
|
|
16282
|
+
throw {
|
|
16283
|
+
code: "session_metadata_not_found",
|
|
16284
|
+
message: `Session metadata not found: ${args.sessionId}`
|
|
16285
|
+
};
|
|
16286
|
+
}
|
|
16287
|
+
return metadata;
|
|
15670
16288
|
}
|
|
15671
|
-
|
|
15672
|
-
|
|
15673
|
-
|
|
15674
|
-
|
|
15675
|
-
|
|
15676
|
-
|
|
15677
|
-
|
|
15678
|
-
|
|
16289
|
+
);
|
|
16290
|
+
registerCommand(
|
|
16291
|
+
"session.verification.add",
|
|
16292
|
+
z14.object({
|
|
16293
|
+
sessionId: z14.string(),
|
|
16294
|
+
command: z14.string().trim().min(1),
|
|
16295
|
+
status: z14.enum(["passed", "failed", "unknown"]),
|
|
16296
|
+
exitCode: z14.number().int().optional(),
|
|
16297
|
+
summary: z14.string().optional()
|
|
16298
|
+
}),
|
|
16299
|
+
async (args, ctx) => {
|
|
16300
|
+
requireSessionMetadataRepo(ctx);
|
|
16301
|
+
return ctx.sessionMetadataRepo.addVerificationRun(args.sessionId, {
|
|
16302
|
+
id: randomUUID6(),
|
|
16303
|
+
command: args.command,
|
|
16304
|
+
status: args.status,
|
|
16305
|
+
exitCode: args.exitCode,
|
|
16306
|
+
summary: args.summary?.trim() || void 0,
|
|
16307
|
+
createdAt: Date.now()
|
|
15679
16308
|
});
|
|
15680
16309
|
}
|
|
15681
|
-
|
|
15682
|
-
|
|
15683
|
-
|
|
15684
|
-
|
|
15685
|
-
|
|
15686
|
-
|
|
15687
|
-
|
|
15688
|
-
|
|
15689
|
-
|
|
15690
|
-
|
|
15691
|
-
|
|
15692
|
-
|
|
15693
|
-
|
|
15694
|
-
|
|
15695
|
-
|
|
15696
|
-
|
|
15697
|
-
|
|
16310
|
+
);
|
|
16311
|
+
}
|
|
16312
|
+
});
|
|
16313
|
+
|
|
16314
|
+
// packages/server/src/git/diff.ts
|
|
16315
|
+
import { mkdtemp as mkdtemp3, readFile as readFile6, rm as rm7 } from "fs/promises";
|
|
16316
|
+
import os3 from "os";
|
|
16317
|
+
import path11 from "path";
|
|
16318
|
+
async function isTrackedPath(cwd, filePath) {
|
|
16319
|
+
try {
|
|
16320
|
+
await runGit(cwd, ["ls-files", "--error-unmatch", "--", filePath]);
|
|
16321
|
+
return true;
|
|
16322
|
+
} catch {
|
|
16323
|
+
return false;
|
|
16324
|
+
}
|
|
16325
|
+
}
|
|
16326
|
+
async function getUntrackedFileDiff(cwd, filePath) {
|
|
16327
|
+
const tempDir = await mkdtemp3(path11.join(os3.tmpdir(), "coder-studio-git-diff-"));
|
|
16328
|
+
const tempIndex = path11.join(tempDir, "index");
|
|
16329
|
+
try {
|
|
16330
|
+
try {
|
|
16331
|
+
await runGit(cwd, ["read-tree", "HEAD"], {
|
|
16332
|
+
env: { GIT_INDEX_FILE: tempIndex }
|
|
16333
|
+
});
|
|
16334
|
+
} catch (error) {
|
|
16335
|
+
if (!(error instanceof GitError)) {
|
|
16336
|
+
throw error;
|
|
16337
|
+
}
|
|
16338
|
+
await runGit(cwd, ["read-tree", "--empty"], {
|
|
16339
|
+
env: { GIT_INDEX_FILE: tempIndex }
|
|
16340
|
+
});
|
|
16341
|
+
}
|
|
16342
|
+
await runGit(cwd, ["add", "-N", "--", filePath], {
|
|
16343
|
+
env: { GIT_INDEX_FILE: tempIndex }
|
|
16344
|
+
});
|
|
16345
|
+
const result = await runGit(cwd, ["diff", "--", filePath], {
|
|
16346
|
+
env: { GIT_INDEX_FILE: tempIndex }
|
|
16347
|
+
});
|
|
16348
|
+
return result.stdout;
|
|
16349
|
+
} finally {
|
|
16350
|
+
await rm7(tempDir, { recursive: true, force: true });
|
|
16351
|
+
}
|
|
16352
|
+
}
|
|
16353
|
+
async function pathExists2(cwd, filePath) {
|
|
16354
|
+
try {
|
|
16355
|
+
await readFile6(resolveSafe(cwd, filePath));
|
|
16356
|
+
return true;
|
|
16357
|
+
} catch {
|
|
16358
|
+
return false;
|
|
16359
|
+
}
|
|
16360
|
+
}
|
|
16361
|
+
async function readTextAtRevision(cwd, revision, filePath) {
|
|
16362
|
+
if (revision === "WORKTREE") {
|
|
16363
|
+
return readFile6(resolveSafe(cwd, filePath), "utf-8");
|
|
16364
|
+
}
|
|
16365
|
+
try {
|
|
16366
|
+
const gitSpec = revision === "INDEX" ? `:${filePath}` : `${revision}:${filePath}`;
|
|
16367
|
+
const result = await runGit(cwd, ["show", gitSpec]);
|
|
16368
|
+
return result.stdout;
|
|
16369
|
+
} catch {
|
|
16370
|
+
return "";
|
|
16371
|
+
}
|
|
16372
|
+
}
|
|
16373
|
+
async function deriveFileDiffStatus(cwd, filePath, staged) {
|
|
16374
|
+
const tracked = await isTrackedPath(cwd, filePath);
|
|
16375
|
+
const existsOnDisk = await pathExists2(cwd, filePath);
|
|
16376
|
+
if (!staged && !tracked) {
|
|
16377
|
+
return "added";
|
|
16378
|
+
}
|
|
16379
|
+
if (staged) {
|
|
16380
|
+
try {
|
|
16381
|
+
await runGit(cwd, ["cat-file", "-e", `HEAD:${filePath}`]);
|
|
16382
|
+
return existsOnDisk ? "modified" : "deleted";
|
|
16383
|
+
} catch {
|
|
16384
|
+
return "added";
|
|
16385
|
+
}
|
|
16386
|
+
}
|
|
16387
|
+
return existsOnDisk ? "modified" : "deleted";
|
|
16388
|
+
}
|
|
16389
|
+
async function buildTextDiffResult(cwd, filePath, staged, diff) {
|
|
16390
|
+
const status = await deriveFileDiffStatus(cwd, filePath, staged);
|
|
16391
|
+
if (status === "added") {
|
|
16392
|
+
return {
|
|
16393
|
+
diff,
|
|
16394
|
+
renderAs: "text",
|
|
16395
|
+
status,
|
|
16396
|
+
originalContent: "",
|
|
16397
|
+
modifiedContent: await readTextAtRevision(cwd, staged ? "INDEX" : "WORKTREE", filePath)
|
|
16398
|
+
};
|
|
16399
|
+
}
|
|
16400
|
+
if (status === "deleted") {
|
|
16401
|
+
return {
|
|
16402
|
+
diff,
|
|
16403
|
+
renderAs: "text",
|
|
16404
|
+
status,
|
|
16405
|
+
originalContent: await readTextAtRevision(cwd, staged ? "HEAD" : "INDEX", filePath),
|
|
16406
|
+
modifiedContent: ""
|
|
16407
|
+
};
|
|
16408
|
+
}
|
|
16409
|
+
return {
|
|
16410
|
+
diff,
|
|
16411
|
+
renderAs: "text",
|
|
16412
|
+
status,
|
|
16413
|
+
originalContent: await readTextAtRevision(cwd, staged ? "HEAD" : "INDEX", filePath),
|
|
16414
|
+
modifiedContent: await readTextAtRevision(cwd, staged ? "INDEX" : "WORKTREE", filePath)
|
|
16415
|
+
};
|
|
16416
|
+
}
|
|
16417
|
+
async function getFileDiff(cwd, path14, staged = false) {
|
|
16418
|
+
const imageType = getImageTypeInfo(path14);
|
|
16419
|
+
if (!staged && !await isTrackedPath(cwd, path14)) {
|
|
16420
|
+
const diff = await getUntrackedFileDiff(cwd, path14);
|
|
16421
|
+
if (imageType) {
|
|
16422
|
+
return {
|
|
16423
|
+
diff,
|
|
16424
|
+
renderAs: "image",
|
|
16425
|
+
status: "added",
|
|
16426
|
+
originalRevision: "HEAD",
|
|
16427
|
+
modifiedRevision: "WORKTREE"
|
|
16428
|
+
};
|
|
16429
|
+
}
|
|
16430
|
+
return buildTextDiffResult(cwd, path14, staged, diff);
|
|
16431
|
+
}
|
|
16432
|
+
const args = staged ? ["diff", "--staged", "--", path14] : ["diff", "--", path14];
|
|
16433
|
+
const result = await runGit(cwd, args);
|
|
16434
|
+
if (imageType && /Binary files .* differ/.test(result.stdout)) {
|
|
16435
|
+
return {
|
|
16436
|
+
diff: result.stdout,
|
|
16437
|
+
renderAs: "image",
|
|
16438
|
+
status: await deriveFileDiffStatus(cwd, path14, staged),
|
|
16439
|
+
originalRevision: staged ? "HEAD" : "INDEX",
|
|
16440
|
+
modifiedRevision: staged ? "INDEX" : "WORKTREE"
|
|
16441
|
+
};
|
|
16442
|
+
}
|
|
16443
|
+
return buildTextDiffResult(cwd, path14, staged, result.stdout);
|
|
16444
|
+
}
|
|
16445
|
+
var init_diff = __esm({
|
|
16446
|
+
"packages/server/src/git/diff.ts"() {
|
|
16447
|
+
"use strict";
|
|
16448
|
+
init_file_io();
|
|
16449
|
+
init_image();
|
|
16450
|
+
init_cli();
|
|
16451
|
+
}
|
|
16452
|
+
});
|
|
16453
|
+
|
|
16454
|
+
// packages/server/src/session-review/review.ts
|
|
16455
|
+
function isWorkspaceStatePath(path14) {
|
|
16456
|
+
return path14 === WORKSPACE_STATE_DIR || path14.startsWith(`${WORKSPACE_STATE_DIR}/`);
|
|
16457
|
+
}
|
|
16458
|
+
function requireSessionMetadata(metadataRepo, sessionId) {
|
|
16459
|
+
const metadata = metadataRepo.get(sessionId);
|
|
16460
|
+
if (!metadata) {
|
|
16461
|
+
throw {
|
|
16462
|
+
code: "session_metadata_not_found",
|
|
16463
|
+
message: `Session metadata not found: ${sessionId}`
|
|
16464
|
+
};
|
|
16465
|
+
}
|
|
16466
|
+
return metadata;
|
|
16467
|
+
}
|
|
16468
|
+
async function isGitRepository(workspacePath) {
|
|
16469
|
+
try {
|
|
16470
|
+
await runGit(workspacePath, ["rev-parse", "--git-dir"]);
|
|
16471
|
+
return true;
|
|
16472
|
+
} catch (error) {
|
|
16473
|
+
if (error instanceof GitError) {
|
|
16474
|
+
return false;
|
|
16475
|
+
}
|
|
16476
|
+
throw error;
|
|
16477
|
+
}
|
|
16478
|
+
}
|
|
16479
|
+
function compareGitChanges(a, b) {
|
|
16480
|
+
const pathCompare = a.path.localeCompare(b.path);
|
|
16481
|
+
if (pathCompare !== 0) {
|
|
16482
|
+
return pathCompare;
|
|
16483
|
+
}
|
|
16484
|
+
return (a.oldPath ?? "").localeCompare(b.oldPath ?? "");
|
|
16485
|
+
}
|
|
16486
|
+
function mapGitStatus(code) {
|
|
16487
|
+
switch (code[0]) {
|
|
16488
|
+
case "A":
|
|
16489
|
+
return "added";
|
|
16490
|
+
case "D":
|
|
16491
|
+
return "deleted";
|
|
16492
|
+
case "M":
|
|
16493
|
+
default:
|
|
16494
|
+
return "modified";
|
|
16495
|
+
}
|
|
16496
|
+
}
|
|
16497
|
+
async function listTrackedChangesSinceBaseline(workspacePath, baselineGitHead) {
|
|
16498
|
+
const { stdout } = await runGit(workspacePath, [
|
|
16499
|
+
"diff",
|
|
16500
|
+
"--name-status",
|
|
16501
|
+
"--find-renames",
|
|
16502
|
+
baselineGitHead,
|
|
16503
|
+
"--"
|
|
16504
|
+
]);
|
|
16505
|
+
const changes = stdout.split("\n").map((line) => line.trim()).filter((line) => line.length > 0).map((line) => {
|
|
16506
|
+
const parts = line.split(" ");
|
|
16507
|
+
const statusCode = parts[0] ?? "M";
|
|
16508
|
+
if (statusCode.startsWith("R")) {
|
|
16509
|
+
const oldPath = parts[1];
|
|
16510
|
+
const path15 = parts[2];
|
|
16511
|
+
if (!oldPath || !path15) {
|
|
16512
|
+
return null;
|
|
16513
|
+
}
|
|
16514
|
+
return {
|
|
16515
|
+
oldPath,
|
|
16516
|
+
path: path15,
|
|
16517
|
+
status: "renamed"
|
|
16518
|
+
};
|
|
16519
|
+
}
|
|
16520
|
+
const path14 = parts[1];
|
|
16521
|
+
if (!path14) {
|
|
16522
|
+
return null;
|
|
16523
|
+
}
|
|
16524
|
+
return {
|
|
16525
|
+
path: path14,
|
|
16526
|
+
status: mapGitStatus(statusCode)
|
|
16527
|
+
};
|
|
16528
|
+
});
|
|
16529
|
+
return changes.filter((change) => change !== null).filter((change) => !isWorkspaceStatePath(change.path)).sort(compareGitChanges);
|
|
16530
|
+
}
|
|
16531
|
+
async function listUntrackedChanges(workspacePath) {
|
|
16532
|
+
const { stdout } = await runGit(workspacePath, ["ls-files", "--others", "--exclude-standard"]);
|
|
16533
|
+
return stdout.split("\n").map((line) => line.trim()).filter((line) => line.length > 0).map((path14) => ({
|
|
16534
|
+
path: path14,
|
|
16535
|
+
status: "untracked"
|
|
16536
|
+
})).filter((change) => !isWorkspaceStatePath(change.path)).sort(compareGitChanges);
|
|
16537
|
+
}
|
|
16538
|
+
async function isUntrackedPath(workspacePath, filePath) {
|
|
16539
|
+
const { stdout } = await runGit(workspacePath, [
|
|
16540
|
+
"ls-files",
|
|
16541
|
+
"--others",
|
|
16542
|
+
"--exclude-standard",
|
|
16543
|
+
"--",
|
|
16544
|
+
filePath
|
|
16545
|
+
]);
|
|
16546
|
+
return stdout.trim().length > 0;
|
|
16547
|
+
}
|
|
16548
|
+
async function buildSessionReviewSummary(input2) {
|
|
16549
|
+
const metadata = requireSessionMetadata(input2.metadataRepo, input2.sessionId);
|
|
16550
|
+
if (!metadata.baselineGitHead) {
|
|
16551
|
+
return {
|
|
16552
|
+
sessionId: metadata.sessionId,
|
|
16553
|
+
workspaceId: metadata.workspaceId,
|
|
16554
|
+
baselineGitHead: metadata.baselineGitHead,
|
|
16555
|
+
changedFiles: [],
|
|
16556
|
+
verificationRuns: metadata.verificationRuns,
|
|
16557
|
+
warnings: [MISSING_BASELINE_WARNING]
|
|
16558
|
+
};
|
|
16559
|
+
}
|
|
16560
|
+
if (!await isGitRepository(input2.workspacePath)) {
|
|
16561
|
+
return {
|
|
16562
|
+
sessionId: metadata.sessionId,
|
|
16563
|
+
workspaceId: metadata.workspaceId,
|
|
16564
|
+
baselineGitHead: metadata.baselineGitHead,
|
|
16565
|
+
changedFiles: [],
|
|
16566
|
+
verificationRuns: metadata.verificationRuns,
|
|
16567
|
+
warnings: [NOT_GIT_REPO_WARNING]
|
|
16568
|
+
};
|
|
16569
|
+
}
|
|
16570
|
+
const trackedChanges = await listTrackedChangesSinceBaseline(
|
|
16571
|
+
input2.workspacePath,
|
|
16572
|
+
metadata.baselineGitHead
|
|
16573
|
+
);
|
|
16574
|
+
const trackedPaths = new Set(trackedChanges.map((change) => change.path));
|
|
16575
|
+
const untrackedChanges = (await listUntrackedChanges(input2.workspacePath)).filter(
|
|
16576
|
+
(change) => !trackedPaths.has(change.path)
|
|
16577
|
+
);
|
|
16578
|
+
return {
|
|
16579
|
+
sessionId: metadata.sessionId,
|
|
16580
|
+
workspaceId: metadata.workspaceId,
|
|
16581
|
+
baselineGitHead: metadata.baselineGitHead,
|
|
16582
|
+
changedFiles: [...trackedChanges, ...untrackedChanges],
|
|
16583
|
+
verificationRuns: metadata.verificationRuns,
|
|
16584
|
+
warnings: []
|
|
16585
|
+
};
|
|
16586
|
+
}
|
|
16587
|
+
async function getSessionReviewDiff(input2) {
|
|
16588
|
+
const metadata = requireSessionMetadata(input2.metadataRepo, input2.sessionId);
|
|
16589
|
+
if (!metadata.baselineGitHead) {
|
|
16590
|
+
return "";
|
|
16591
|
+
}
|
|
16592
|
+
if (!await isGitRepository(input2.workspacePath)) {
|
|
16593
|
+
return "";
|
|
16594
|
+
}
|
|
16595
|
+
if (await isUntrackedPath(input2.workspacePath, input2.path)) {
|
|
16596
|
+
return (await getFileDiff(input2.workspacePath, input2.path)).diff;
|
|
16597
|
+
}
|
|
16598
|
+
const { stdout } = await runGit(input2.workspacePath, [
|
|
16599
|
+
"diff",
|
|
16600
|
+
metadata.baselineGitHead,
|
|
16601
|
+
"--",
|
|
16602
|
+
input2.path
|
|
16603
|
+
]);
|
|
16604
|
+
return stdout;
|
|
16605
|
+
}
|
|
16606
|
+
var MISSING_BASELINE_WARNING, NOT_GIT_REPO_WARNING;
|
|
16607
|
+
var init_review = __esm({
|
|
16608
|
+
"packages/server/src/session-review/review.ts"() {
|
|
16609
|
+
"use strict";
|
|
16610
|
+
init_cli();
|
|
16611
|
+
init_diff();
|
|
16612
|
+
init_workspace_state();
|
|
16613
|
+
MISSING_BASELINE_WARNING = {
|
|
16614
|
+
code: "missing_baseline",
|
|
16615
|
+
message: "Session baseline is missing."
|
|
16616
|
+
};
|
|
16617
|
+
NOT_GIT_REPO_WARNING = {
|
|
16618
|
+
code: "not_git_repo",
|
|
16619
|
+
message: "Workspace is not a Git repository."
|
|
16620
|
+
};
|
|
16621
|
+
}
|
|
16622
|
+
});
|
|
16623
|
+
|
|
16624
|
+
// packages/server/src/commands/session-review.ts
|
|
16625
|
+
import { z as z15 } from "zod";
|
|
16626
|
+
function requireSessionMetadataRepo2(ctx) {
|
|
16627
|
+
if (!ctx.sessionMetadataRepo) {
|
|
16628
|
+
throw {
|
|
16629
|
+
code: "session_metadata_unavailable",
|
|
16630
|
+
message: "Session metadata repository is not configured"
|
|
16631
|
+
};
|
|
16632
|
+
}
|
|
16633
|
+
}
|
|
16634
|
+
function requireWorkspace(ctx, workspaceId) {
|
|
16635
|
+
const workspace = ctx.workspaceMgr.get(workspaceId);
|
|
16636
|
+
if (!workspace) {
|
|
16637
|
+
throw { code: "workspace_not_found", message: `Workspace not found: ${workspaceId}` };
|
|
16638
|
+
}
|
|
16639
|
+
return workspace;
|
|
16640
|
+
}
|
|
16641
|
+
var init_session_review = __esm({
|
|
16642
|
+
"packages/server/src/commands/session-review.ts"() {
|
|
16643
|
+
"use strict";
|
|
16644
|
+
init_review();
|
|
16645
|
+
init_dispatch();
|
|
16646
|
+
registerCommand(
|
|
16647
|
+
"sessionReview.summary",
|
|
16648
|
+
z15.object({
|
|
16649
|
+
sessionId: z15.string()
|
|
16650
|
+
}),
|
|
16651
|
+
async (args, ctx) => {
|
|
16652
|
+
requireSessionMetadataRepo2(ctx);
|
|
16653
|
+
const metadata = ctx.sessionMetadataRepo.get(args.sessionId);
|
|
16654
|
+
if (!metadata) {
|
|
16655
|
+
throw {
|
|
16656
|
+
code: "session_metadata_not_found",
|
|
16657
|
+
message: `Session metadata not found: ${args.sessionId}`
|
|
16658
|
+
};
|
|
16659
|
+
}
|
|
16660
|
+
const workspace = requireWorkspace(ctx, metadata.workspaceId);
|
|
16661
|
+
return buildSessionReviewSummary({
|
|
16662
|
+
sessionId: args.sessionId,
|
|
16663
|
+
workspacePath: workspace.path,
|
|
16664
|
+
metadataRepo: ctx.sessionMetadataRepo
|
|
16665
|
+
});
|
|
16666
|
+
}
|
|
16667
|
+
);
|
|
16668
|
+
registerCommand(
|
|
16669
|
+
"sessionReview.diff",
|
|
16670
|
+
z15.object({
|
|
16671
|
+
sessionId: z15.string(),
|
|
16672
|
+
path: z15.string().trim().min(1)
|
|
16673
|
+
}),
|
|
16674
|
+
async (args, ctx) => {
|
|
16675
|
+
requireSessionMetadataRepo2(ctx);
|
|
16676
|
+
const metadata = ctx.sessionMetadataRepo.get(args.sessionId);
|
|
16677
|
+
if (!metadata) {
|
|
16678
|
+
throw {
|
|
16679
|
+
code: "session_metadata_not_found",
|
|
16680
|
+
message: `Session metadata not found: ${args.sessionId}`
|
|
16681
|
+
};
|
|
16682
|
+
}
|
|
16683
|
+
const workspace = requireWorkspace(ctx, metadata.workspaceId);
|
|
16684
|
+
return {
|
|
16685
|
+
path: args.path,
|
|
16686
|
+
diff: await getSessionReviewDiff({
|
|
16687
|
+
sessionId: args.sessionId,
|
|
16688
|
+
workspacePath: workspace.path,
|
|
16689
|
+
metadataRepo: ctx.sessionMetadataRepo,
|
|
16690
|
+
path: args.path
|
|
16691
|
+
})
|
|
16692
|
+
};
|
|
16693
|
+
}
|
|
16694
|
+
);
|
|
16695
|
+
}
|
|
16696
|
+
});
|
|
16697
|
+
|
|
16698
|
+
// packages/server/src/fs/content-search.ts
|
|
16699
|
+
import { spawn as spawn5 } from "child_process";
|
|
16700
|
+
import { existsSync as existsSync8 } from "fs";
|
|
16701
|
+
import { readdir as readdir4, readFile as readFile7, stat as stat10 } from "fs/promises";
|
|
16702
|
+
import { basename as basename2, join as join15, relative as relative3 } from "path";
|
|
16703
|
+
import { createInterface } from "readline";
|
|
16704
|
+
async function searchFileContents(rootPath, options) {
|
|
16705
|
+
const query = options.query.trim();
|
|
16706
|
+
if (!query) {
|
|
16707
|
+
return {
|
|
16708
|
+
files: [],
|
|
16709
|
+
totalMatchCount: 0,
|
|
16710
|
+
hasMoreFiles: false,
|
|
16711
|
+
truncatedMatchFileCount: 0
|
|
16712
|
+
};
|
|
16713
|
+
}
|
|
16714
|
+
const result = await searchWithRipgrep(rootPath, query, options.maxFiles).catch(
|
|
16715
|
+
async (error) => {
|
|
16716
|
+
if (error.code === "ENOENT") {
|
|
16717
|
+
return searchWithNode(rootPath, query, options.maxFiles);
|
|
16718
|
+
}
|
|
16719
|
+
throw error;
|
|
16720
|
+
}
|
|
16721
|
+
);
|
|
16722
|
+
return finalizeResults(result, options.maxFiles, options.maxMatchesPerFile);
|
|
16723
|
+
}
|
|
16724
|
+
async function searchWithRipgrep(rootPath, query, maxFiles) {
|
|
16725
|
+
const hasGitignore = existsSync8(join15(rootPath, ".gitignore"));
|
|
16726
|
+
const args = [
|
|
16727
|
+
"--json",
|
|
16728
|
+
"--line-number",
|
|
16729
|
+
"--column",
|
|
16730
|
+
"--fixed-strings",
|
|
16731
|
+
"--sort",
|
|
16732
|
+
"path",
|
|
16733
|
+
"--with-filename",
|
|
16734
|
+
"--glob",
|
|
16735
|
+
"!**/.git/**",
|
|
16736
|
+
"--glob",
|
|
16737
|
+
"!**/node_modules/**"
|
|
16738
|
+
];
|
|
16739
|
+
if (hasGitignore) {
|
|
16740
|
+
args.push("--hidden");
|
|
16741
|
+
args.push("--no-require-git");
|
|
16742
|
+
}
|
|
16743
|
+
args.push(query, ".");
|
|
16744
|
+
return new Promise((resolve8, reject) => {
|
|
16745
|
+
const child = spawn5("rg", args, { cwd: rootPath, stdio: ["ignore", "pipe", "pipe"] });
|
|
16746
|
+
const stdout = createInterface({ input: child.stdout });
|
|
16747
|
+
const files = /* @__PURE__ */ new Map();
|
|
16748
|
+
let totalMatchCount = 0;
|
|
16749
|
+
let hasMoreFiles = false;
|
|
16750
|
+
let stderr = "";
|
|
16751
|
+
stdout.on("line", (line) => {
|
|
16752
|
+
if (!line.trim()) {
|
|
16753
|
+
return;
|
|
16754
|
+
}
|
|
16755
|
+
const event = JSON.parse(line);
|
|
16756
|
+
if (event.type !== "match") {
|
|
16757
|
+
return;
|
|
16758
|
+
}
|
|
16759
|
+
const rawPath = event.data?.path?.text;
|
|
16760
|
+
if (!rawPath) {
|
|
16761
|
+
return;
|
|
16762
|
+
}
|
|
16763
|
+
const relativePath = normalizeRelativePath(relative3(rootPath, join15(rootPath, rawPath)));
|
|
16764
|
+
const preview = (event.data?.lines?.text ?? "").replace(/\r?\n$/, "");
|
|
16765
|
+
const lineNumber = event.data?.line_number ?? 1;
|
|
16766
|
+
const submatches = event.data?.submatches ?? [];
|
|
16767
|
+
totalMatchCount += submatches.length;
|
|
16768
|
+
if (!files.has(relativePath) && files.size >= maxFiles) {
|
|
16769
|
+
hasMoreFiles = true;
|
|
16770
|
+
return;
|
|
16771
|
+
}
|
|
16772
|
+
for (const submatch of submatches) {
|
|
16773
|
+
pushMatch(files, relativePath, {
|
|
16774
|
+
line: lineNumber,
|
|
16775
|
+
column: byteOffsetToColumn(preview, submatch.start),
|
|
16776
|
+
endColumn: byteOffsetToColumn(preview, submatch.end),
|
|
16777
|
+
preview,
|
|
16778
|
+
previewColumnStart: byteOffsetToColumn(preview, submatch.start),
|
|
16779
|
+
previewColumnEnd: byteOffsetToColumn(preview, submatch.end)
|
|
16780
|
+
});
|
|
16781
|
+
}
|
|
16782
|
+
});
|
|
16783
|
+
child.stderr.on("data", (chunk) => {
|
|
16784
|
+
stderr += chunk.toString();
|
|
16785
|
+
});
|
|
16786
|
+
child.on("error", (error) => {
|
|
16787
|
+
void stdout.close();
|
|
16788
|
+
reject(error);
|
|
16789
|
+
});
|
|
16790
|
+
child.on("close", (code) => {
|
|
16791
|
+
void stdout.close();
|
|
16792
|
+
if (code === 0 || code === 1) {
|
|
16793
|
+
resolve8({
|
|
16794
|
+
files: sortAccumulators(files),
|
|
16795
|
+
totalMatchCount,
|
|
16796
|
+
hasMoreFiles
|
|
16797
|
+
});
|
|
16798
|
+
return;
|
|
15698
16799
|
}
|
|
15699
16800
|
reject(
|
|
15700
16801
|
Object.assign(new Error(stderr || `rg exited with code ${code ?? "unknown"}`), { code })
|
|
@@ -15712,7 +16813,7 @@ async function searchWithNode(rootPath, query, maxFiles) {
|
|
|
15712
16813
|
const filteredEntries = entries.filter((entry) => filter(entry.name));
|
|
15713
16814
|
filteredEntries.sort((a, b) => a.name.localeCompare(b.name));
|
|
15714
16815
|
for (const entry of filteredEntries) {
|
|
15715
|
-
const fullPath =
|
|
16816
|
+
const fullPath = join15(dirPath, entry.name);
|
|
15716
16817
|
if (entry.isDirectory()) {
|
|
15717
16818
|
await walk(fullPath);
|
|
15718
16819
|
continue;
|
|
@@ -15720,11 +16821,11 @@ async function searchWithNode(rootPath, query, maxFiles) {
|
|
|
15720
16821
|
if (!entry.isFile()) {
|
|
15721
16822
|
continue;
|
|
15722
16823
|
}
|
|
15723
|
-
const fileStat = await
|
|
16824
|
+
const fileStat = await stat10(fullPath);
|
|
15724
16825
|
if (fileStat.size > FALLBACK_MAX_FILE_BYTES) {
|
|
15725
16826
|
continue;
|
|
15726
16827
|
}
|
|
15727
|
-
const buffer = await
|
|
16828
|
+
const buffer = await readFile7(fullPath);
|
|
15728
16829
|
if (isBinaryFile(buffer)) {
|
|
15729
16830
|
continue;
|
|
15730
16831
|
}
|
|
@@ -15835,10 +16936,10 @@ var init_content_search = __esm({
|
|
|
15835
16936
|
});
|
|
15836
16937
|
|
|
15837
16938
|
// packages/server/src/fs/tree.ts
|
|
15838
|
-
import { readdir as readdir5, stat as
|
|
15839
|
-
import { join as
|
|
16939
|
+
import { readdir as readdir5, stat as stat11 } from "fs/promises";
|
|
16940
|
+
import { join as join16, relative as relative4 } from "path";
|
|
15840
16941
|
async function readTree(rootPath, subdir) {
|
|
15841
|
-
const targetPath = subdir ?
|
|
16942
|
+
const targetPath = subdir ? join16(rootPath, subdir) : rootPath;
|
|
15842
16943
|
const filter = createTreeVisibilityFilter();
|
|
15843
16944
|
const entries = await readdir5(targetPath, { withFileTypes: true });
|
|
15844
16945
|
const nodes = [];
|
|
@@ -15846,7 +16947,7 @@ async function readTree(rootPath, subdir) {
|
|
|
15846
16947
|
if (!filter(entry.name)) {
|
|
15847
16948
|
continue;
|
|
15848
16949
|
}
|
|
15849
|
-
const fullPath =
|
|
16950
|
+
const fullPath = join16(targetPath, entry.name);
|
|
15850
16951
|
const relPath = relative4(rootPath, fullPath);
|
|
15851
16952
|
if (entry.isDirectory()) {
|
|
15852
16953
|
nodes.push({
|
|
@@ -15857,7 +16958,7 @@ async function readTree(rootPath, subdir) {
|
|
|
15857
16958
|
// Not loaded yet - client will request on expand
|
|
15858
16959
|
});
|
|
15859
16960
|
} else if (entry.isFile()) {
|
|
15860
|
-
const stats = await
|
|
16961
|
+
const stats = await stat11(fullPath);
|
|
15861
16962
|
nodes.push({
|
|
15862
16963
|
name: entry.name,
|
|
15863
16964
|
path: relPath,
|
|
@@ -15890,7 +16991,7 @@ async function searchFiles(rootPath, query, limit = 10) {
|
|
|
15890
16991
|
const filteredEntries = entries.filter((entry) => filter(entry.name));
|
|
15891
16992
|
filteredEntries.sort((a, b) => a.name.localeCompare(b.name));
|
|
15892
16993
|
for (const entry of filteredEntries) {
|
|
15893
|
-
const fullPath =
|
|
16994
|
+
const fullPath = join16(dirPath, entry.name);
|
|
15894
16995
|
const relPath = relative4(rootPath, fullPath);
|
|
15895
16996
|
if (entry.isDirectory()) {
|
|
15896
16997
|
await walk(fullPath);
|
|
@@ -15926,7 +17027,7 @@ async function searchFiles(rootPath, query, limit = 10) {
|
|
|
15926
17027
|
}
|
|
15927
17028
|
return a.path.toLowerCase().localeCompare(b.path.toLowerCase());
|
|
15928
17029
|
}).slice(0, limit)) {
|
|
15929
|
-
const stats = await
|
|
17030
|
+
const stats = await stat11(match.fullPath);
|
|
15930
17031
|
files.push({
|
|
15931
17032
|
name: match.name,
|
|
15932
17033
|
path: match.path,
|
|
@@ -16006,7 +17107,7 @@ var init_tree = __esm({
|
|
|
16006
17107
|
});
|
|
16007
17108
|
|
|
16008
17109
|
// packages/server/src/commands/file.ts
|
|
16009
|
-
import { z as
|
|
17110
|
+
import { z as z16 } from "zod";
|
|
16010
17111
|
var init_file = __esm({
|
|
16011
17112
|
"packages/server/src/commands/file.ts"() {
|
|
16012
17113
|
"use strict";
|
|
@@ -16016,9 +17117,9 @@ var init_file = __esm({
|
|
|
16016
17117
|
init_dispatch();
|
|
16017
17118
|
registerCommand(
|
|
16018
17119
|
"file.readTree",
|
|
16019
|
-
|
|
16020
|
-
workspaceId:
|
|
16021
|
-
subPath:
|
|
17120
|
+
z16.object({
|
|
17121
|
+
workspaceId: z16.string(),
|
|
17122
|
+
subPath: z16.string().optional()
|
|
16022
17123
|
}),
|
|
16023
17124
|
async (args, ctx) => {
|
|
16024
17125
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -16030,10 +17131,10 @@ var init_file = __esm({
|
|
|
16030
17131
|
);
|
|
16031
17132
|
registerCommand(
|
|
16032
17133
|
"file.search",
|
|
16033
|
-
|
|
16034
|
-
workspaceId:
|
|
16035
|
-
query:
|
|
16036
|
-
limit:
|
|
17134
|
+
z16.object({
|
|
17135
|
+
workspaceId: z16.string(),
|
|
17136
|
+
query: z16.string(),
|
|
17137
|
+
limit: z16.number().int().positive().max(50).optional()
|
|
16037
17138
|
}),
|
|
16038
17139
|
async (args, ctx) => {
|
|
16039
17140
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -16045,11 +17146,11 @@ var init_file = __esm({
|
|
|
16045
17146
|
);
|
|
16046
17147
|
registerCommand(
|
|
16047
17148
|
"file.searchContent",
|
|
16048
|
-
|
|
16049
|
-
workspaceId:
|
|
16050
|
-
query:
|
|
16051
|
-
maxFiles:
|
|
16052
|
-
maxMatchesPerFile:
|
|
17149
|
+
z16.object({
|
|
17150
|
+
workspaceId: z16.string(),
|
|
17151
|
+
query: z16.string(),
|
|
17152
|
+
maxFiles: z16.number().int().positive().max(100),
|
|
17153
|
+
maxMatchesPerFile: z16.number().int().positive().max(100)
|
|
16053
17154
|
}),
|
|
16054
17155
|
async (args, ctx) => {
|
|
16055
17156
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -16065,9 +17166,9 @@ var init_file = __esm({
|
|
|
16065
17166
|
);
|
|
16066
17167
|
registerCommand(
|
|
16067
17168
|
"file.read",
|
|
16068
|
-
|
|
16069
|
-
workspaceId:
|
|
16070
|
-
path:
|
|
17169
|
+
z16.object({
|
|
17170
|
+
workspaceId: z16.string(),
|
|
17171
|
+
path: z16.string()
|
|
16071
17172
|
}),
|
|
16072
17173
|
async (args, ctx) => {
|
|
16073
17174
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -16079,9 +17180,9 @@ var init_file = __esm({
|
|
|
16079
17180
|
);
|
|
16080
17181
|
registerCommand(
|
|
16081
17182
|
"file.create",
|
|
16082
|
-
|
|
16083
|
-
workspaceId:
|
|
16084
|
-
path:
|
|
17183
|
+
z16.object({
|
|
17184
|
+
workspaceId: z16.string(),
|
|
17185
|
+
path: z16.string()
|
|
16085
17186
|
}),
|
|
16086
17187
|
async (args, ctx) => {
|
|
16087
17188
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -16099,9 +17200,9 @@ var init_file = __esm({
|
|
|
16099
17200
|
);
|
|
16100
17201
|
registerCommand(
|
|
16101
17202
|
"file.mkdir",
|
|
16102
|
-
|
|
16103
|
-
workspaceId:
|
|
16104
|
-
path:
|
|
17203
|
+
z16.object({
|
|
17204
|
+
workspaceId: z16.string(),
|
|
17205
|
+
path: z16.string()
|
|
16105
17206
|
}),
|
|
16106
17207
|
async (args, ctx) => {
|
|
16107
17208
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -16119,9 +17220,9 @@ var init_file = __esm({
|
|
|
16119
17220
|
);
|
|
16120
17221
|
registerCommand(
|
|
16121
17222
|
"file.delete",
|
|
16122
|
-
|
|
16123
|
-
workspaceId:
|
|
16124
|
-
path:
|
|
17223
|
+
z16.object({
|
|
17224
|
+
workspaceId: z16.string(),
|
|
17225
|
+
path: z16.string()
|
|
16125
17226
|
}),
|
|
16126
17227
|
async (args, ctx) => {
|
|
16127
17228
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -16139,10 +17240,10 @@ var init_file = __esm({
|
|
|
16139
17240
|
);
|
|
16140
17241
|
registerCommand(
|
|
16141
17242
|
"file.rename",
|
|
16142
|
-
|
|
16143
|
-
workspaceId:
|
|
16144
|
-
fromPath:
|
|
16145
|
-
toPath:
|
|
17243
|
+
z16.object({
|
|
17244
|
+
workspaceId: z16.string(),
|
|
17245
|
+
fromPath: z16.string(),
|
|
17246
|
+
toPath: z16.string()
|
|
16146
17247
|
}),
|
|
16147
17248
|
async (args, ctx) => {
|
|
16148
17249
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -16160,167 +17261,27 @@ var init_file = __esm({
|
|
|
16160
17261
|
);
|
|
16161
17262
|
registerCommand(
|
|
16162
17263
|
"file.write",
|
|
16163
|
-
|
|
16164
|
-
workspaceId:
|
|
16165
|
-
path:
|
|
16166
|
-
content:
|
|
16167
|
-
baseHash:
|
|
17264
|
+
z16.object({
|
|
17265
|
+
workspaceId: z16.string(),
|
|
17266
|
+
path: z16.string(),
|
|
17267
|
+
content: z16.string(),
|
|
17268
|
+
baseHash: z16.string().optional()
|
|
16168
17269
|
// For conflict detection
|
|
16169
17270
|
}),
|
|
16170
|
-
async (args, ctx) => {
|
|
16171
|
-
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
16172
|
-
if (!workspace) {
|
|
16173
|
-
throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
|
|
16174
|
-
}
|
|
16175
|
-
const result = await writeFile(workspace.path, args.path, args.content, args.baseHash);
|
|
16176
|
-
ctx.eventBus.emit({
|
|
16177
|
-
type: "fs.dirty",
|
|
16178
|
-
workspaceId: args.workspaceId,
|
|
16179
|
-
reason: "file_content"
|
|
16180
|
-
});
|
|
16181
|
-
return result;
|
|
16182
|
-
}
|
|
16183
|
-
);
|
|
16184
|
-
}
|
|
16185
|
-
});
|
|
16186
|
-
|
|
16187
|
-
// packages/server/src/git/diff.ts
|
|
16188
|
-
import { mkdtemp as mkdtemp3, readFile as readFile5, rm as rm7 } from "fs/promises";
|
|
16189
|
-
import os3 from "os";
|
|
16190
|
-
import path11 from "path";
|
|
16191
|
-
async function isTrackedPath(cwd, filePath) {
|
|
16192
|
-
try {
|
|
16193
|
-
await runGit(cwd, ["ls-files", "--error-unmatch", "--", filePath]);
|
|
16194
|
-
return true;
|
|
16195
|
-
} catch {
|
|
16196
|
-
return false;
|
|
16197
|
-
}
|
|
16198
|
-
}
|
|
16199
|
-
async function getUntrackedFileDiff(cwd, filePath) {
|
|
16200
|
-
const tempDir = await mkdtemp3(path11.join(os3.tmpdir(), "coder-studio-git-diff-"));
|
|
16201
|
-
const tempIndex = path11.join(tempDir, "index");
|
|
16202
|
-
try {
|
|
16203
|
-
try {
|
|
16204
|
-
await runGit(cwd, ["read-tree", "HEAD"], {
|
|
16205
|
-
env: { GIT_INDEX_FILE: tempIndex }
|
|
16206
|
-
});
|
|
16207
|
-
} catch (error) {
|
|
16208
|
-
if (!(error instanceof GitError)) {
|
|
16209
|
-
throw error;
|
|
16210
|
-
}
|
|
16211
|
-
await runGit(cwd, ["read-tree", "--empty"], {
|
|
16212
|
-
env: { GIT_INDEX_FILE: tempIndex }
|
|
16213
|
-
});
|
|
16214
|
-
}
|
|
16215
|
-
await runGit(cwd, ["add", "-N", "--", filePath], {
|
|
16216
|
-
env: { GIT_INDEX_FILE: tempIndex }
|
|
16217
|
-
});
|
|
16218
|
-
const result = await runGit(cwd, ["diff", "--", filePath], {
|
|
16219
|
-
env: { GIT_INDEX_FILE: tempIndex }
|
|
16220
|
-
});
|
|
16221
|
-
return result.stdout;
|
|
16222
|
-
} finally {
|
|
16223
|
-
await rm7(tempDir, { recursive: true, force: true });
|
|
16224
|
-
}
|
|
16225
|
-
}
|
|
16226
|
-
async function pathExists(cwd, filePath) {
|
|
16227
|
-
try {
|
|
16228
|
-
await readFile5(resolveSafe(cwd, filePath));
|
|
16229
|
-
return true;
|
|
16230
|
-
} catch {
|
|
16231
|
-
return false;
|
|
16232
|
-
}
|
|
16233
|
-
}
|
|
16234
|
-
async function readTextAtRevision(cwd, revision, filePath) {
|
|
16235
|
-
if (revision === "WORKTREE") {
|
|
16236
|
-
return readFile5(resolveSafe(cwd, filePath), "utf-8");
|
|
16237
|
-
}
|
|
16238
|
-
try {
|
|
16239
|
-
const gitSpec = revision === "INDEX" ? `:${filePath}` : `${revision}:${filePath}`;
|
|
16240
|
-
const result = await runGit(cwd, ["show", gitSpec]);
|
|
16241
|
-
return result.stdout;
|
|
16242
|
-
} catch {
|
|
16243
|
-
return "";
|
|
16244
|
-
}
|
|
16245
|
-
}
|
|
16246
|
-
async function deriveFileDiffStatus(cwd, filePath, staged) {
|
|
16247
|
-
const tracked = await isTrackedPath(cwd, filePath);
|
|
16248
|
-
const existsOnDisk = await pathExists(cwd, filePath);
|
|
16249
|
-
if (!staged && !tracked) {
|
|
16250
|
-
return "added";
|
|
16251
|
-
}
|
|
16252
|
-
if (staged) {
|
|
16253
|
-
try {
|
|
16254
|
-
await runGit(cwd, ["cat-file", "-e", `HEAD:${filePath}`]);
|
|
16255
|
-
return existsOnDisk ? "modified" : "deleted";
|
|
16256
|
-
} catch {
|
|
16257
|
-
return "added";
|
|
16258
|
-
}
|
|
16259
|
-
}
|
|
16260
|
-
return existsOnDisk ? "modified" : "deleted";
|
|
16261
|
-
}
|
|
16262
|
-
async function buildTextDiffResult(cwd, filePath, staged, diff) {
|
|
16263
|
-
const status = await deriveFileDiffStatus(cwd, filePath, staged);
|
|
16264
|
-
if (status === "added") {
|
|
16265
|
-
return {
|
|
16266
|
-
diff,
|
|
16267
|
-
renderAs: "text",
|
|
16268
|
-
status,
|
|
16269
|
-
originalContent: "",
|
|
16270
|
-
modifiedContent: await readTextAtRevision(cwd, staged ? "INDEX" : "WORKTREE", filePath)
|
|
16271
|
-
};
|
|
16272
|
-
}
|
|
16273
|
-
if (status === "deleted") {
|
|
16274
|
-
return {
|
|
16275
|
-
diff,
|
|
16276
|
-
renderAs: "text",
|
|
16277
|
-
status,
|
|
16278
|
-
originalContent: await readTextAtRevision(cwd, staged ? "HEAD" : "INDEX", filePath),
|
|
16279
|
-
modifiedContent: ""
|
|
16280
|
-
};
|
|
16281
|
-
}
|
|
16282
|
-
return {
|
|
16283
|
-
diff,
|
|
16284
|
-
renderAs: "text",
|
|
16285
|
-
status,
|
|
16286
|
-
originalContent: await readTextAtRevision(cwd, staged ? "HEAD" : "INDEX", filePath),
|
|
16287
|
-
modifiedContent: await readTextAtRevision(cwd, staged ? "INDEX" : "WORKTREE", filePath)
|
|
16288
|
-
};
|
|
16289
|
-
}
|
|
16290
|
-
async function getFileDiff(cwd, path14, staged = false) {
|
|
16291
|
-
const imageType = getImageTypeInfo(path14);
|
|
16292
|
-
if (!staged && !await isTrackedPath(cwd, path14)) {
|
|
16293
|
-
const diff = await getUntrackedFileDiff(cwd, path14);
|
|
16294
|
-
if (imageType) {
|
|
16295
|
-
return {
|
|
16296
|
-
diff,
|
|
16297
|
-
renderAs: "image",
|
|
16298
|
-
status: "added",
|
|
16299
|
-
originalRevision: "HEAD",
|
|
16300
|
-
modifiedRevision: "WORKTREE"
|
|
16301
|
-
};
|
|
16302
|
-
}
|
|
16303
|
-
return buildTextDiffResult(cwd, path14, staged, diff);
|
|
16304
|
-
}
|
|
16305
|
-
const args = staged ? ["diff", "--staged", "--", path14] : ["diff", "--", path14];
|
|
16306
|
-
const result = await runGit(cwd, args);
|
|
16307
|
-
if (imageType && /Binary files .* differ/.test(result.stdout)) {
|
|
16308
|
-
return {
|
|
16309
|
-
diff: result.stdout,
|
|
16310
|
-
renderAs: "image",
|
|
16311
|
-
status: await deriveFileDiffStatus(cwd, path14, staged),
|
|
16312
|
-
originalRevision: staged ? "HEAD" : "INDEX",
|
|
16313
|
-
modifiedRevision: staged ? "INDEX" : "WORKTREE"
|
|
16314
|
-
};
|
|
16315
|
-
}
|
|
16316
|
-
return buildTextDiffResult(cwd, path14, staged, result.stdout);
|
|
16317
|
-
}
|
|
16318
|
-
var init_diff = __esm({
|
|
16319
|
-
"packages/server/src/git/diff.ts"() {
|
|
16320
|
-
"use strict";
|
|
16321
|
-
init_file_io();
|
|
16322
|
-
init_image();
|
|
16323
|
-
init_cli();
|
|
17271
|
+
async (args, ctx) => {
|
|
17272
|
+
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
17273
|
+
if (!workspace) {
|
|
17274
|
+
throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
|
|
17275
|
+
}
|
|
17276
|
+
const result = await writeFile(workspace.path, args.path, args.content, args.baseHash);
|
|
17277
|
+
ctx.eventBus.emit({
|
|
17278
|
+
type: "fs.dirty",
|
|
17279
|
+
workspaceId: args.workspaceId,
|
|
17280
|
+
reason: "file_content"
|
|
17281
|
+
});
|
|
17282
|
+
return result;
|
|
17283
|
+
}
|
|
17284
|
+
);
|
|
16324
17285
|
}
|
|
16325
17286
|
});
|
|
16326
17287
|
|
|
@@ -16341,7 +17302,7 @@ var init_git_events = __esm({
|
|
|
16341
17302
|
});
|
|
16342
17303
|
|
|
16343
17304
|
// packages/server/src/commands/git.ts
|
|
16344
|
-
import { z as
|
|
17305
|
+
import { z as z17 } from "zod";
|
|
16345
17306
|
async function runGitNetworkOperation(ctx, workspaceId, op) {
|
|
16346
17307
|
if (!ctx.autoFetch?.runExclusive) {
|
|
16347
17308
|
return op();
|
|
@@ -16356,16 +17317,16 @@ var init_git2 = __esm({
|
|
|
16356
17317
|
init_diff();
|
|
16357
17318
|
init_dispatch();
|
|
16358
17319
|
init_git_events();
|
|
16359
|
-
gitHttpAuthSchema =
|
|
16360
|
-
username:
|
|
16361
|
-
password:
|
|
17320
|
+
gitHttpAuthSchema = z17.object({
|
|
17321
|
+
username: z17.string(),
|
|
17322
|
+
password: z17.string()
|
|
16362
17323
|
});
|
|
16363
|
-
gitCommitRevisionSchema =
|
|
17324
|
+
gitCommitRevisionSchema = z17.string().regex(/^[0-9a-fA-F]{7,64}$/, "Invalid git commit revision");
|
|
16364
17325
|
GIT_BACKGROUND_FETCH_TIMEOUT_MS = 30 * 1e3;
|
|
16365
17326
|
registerCommand(
|
|
16366
17327
|
"git.status",
|
|
16367
|
-
|
|
16368
|
-
workspaceId:
|
|
17328
|
+
z17.object({
|
|
17329
|
+
workspaceId: z17.string()
|
|
16369
17330
|
}),
|
|
16370
17331
|
async (args, ctx) => {
|
|
16371
17332
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -16377,9 +17338,9 @@ var init_git2 = __esm({
|
|
|
16377
17338
|
);
|
|
16378
17339
|
registerCommand(
|
|
16379
17340
|
"git.stage",
|
|
16380
|
-
|
|
16381
|
-
workspaceId:
|
|
16382
|
-
paths:
|
|
17341
|
+
z17.object({
|
|
17342
|
+
workspaceId: z17.string(),
|
|
17343
|
+
paths: z17.array(z17.string())
|
|
16383
17344
|
}),
|
|
16384
17345
|
async (args, ctx) => {
|
|
16385
17346
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -16393,10 +17354,10 @@ var init_git2 = __esm({
|
|
|
16393
17354
|
);
|
|
16394
17355
|
registerCommand(
|
|
16395
17356
|
"git.diff",
|
|
16396
|
-
|
|
16397
|
-
workspaceId:
|
|
16398
|
-
path:
|
|
16399
|
-
staged:
|
|
17357
|
+
z17.object({
|
|
17358
|
+
workspaceId: z17.string(),
|
|
17359
|
+
path: z17.string(),
|
|
17360
|
+
staged: z17.boolean().optional()
|
|
16400
17361
|
}),
|
|
16401
17362
|
async (args, ctx) => {
|
|
16402
17363
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -16408,9 +17369,9 @@ var init_git2 = __esm({
|
|
|
16408
17369
|
);
|
|
16409
17370
|
registerCommand(
|
|
16410
17371
|
"git.log",
|
|
16411
|
-
|
|
16412
|
-
workspaceId:
|
|
16413
|
-
limit:
|
|
17372
|
+
z17.object({
|
|
17373
|
+
workspaceId: z17.string(),
|
|
17374
|
+
limit: z17.number().int().min(1).max(50).optional()
|
|
16414
17375
|
}),
|
|
16415
17376
|
async (args, ctx) => {
|
|
16416
17377
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -16424,8 +17385,8 @@ var init_git2 = __esm({
|
|
|
16424
17385
|
);
|
|
16425
17386
|
registerCommand(
|
|
16426
17387
|
"git.show",
|
|
16427
|
-
|
|
16428
|
-
workspaceId:
|
|
17388
|
+
z17.object({
|
|
17389
|
+
workspaceId: z17.string(),
|
|
16429
17390
|
sha: gitCommitRevisionSchema
|
|
16430
17391
|
}),
|
|
16431
17392
|
async (args, ctx) => {
|
|
@@ -16440,9 +17401,9 @@ var init_git2 = __esm({
|
|
|
16440
17401
|
);
|
|
16441
17402
|
registerCommand(
|
|
16442
17403
|
"git.unstage",
|
|
16443
|
-
|
|
16444
|
-
workspaceId:
|
|
16445
|
-
paths:
|
|
17404
|
+
z17.object({
|
|
17405
|
+
workspaceId: z17.string(),
|
|
17406
|
+
paths: z17.array(z17.string())
|
|
16446
17407
|
}),
|
|
16447
17408
|
async (args, ctx) => {
|
|
16448
17409
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -16456,9 +17417,9 @@ var init_git2 = __esm({
|
|
|
16456
17417
|
);
|
|
16457
17418
|
registerCommand(
|
|
16458
17419
|
"git.discard",
|
|
16459
|
-
|
|
16460
|
-
workspaceId:
|
|
16461
|
-
paths:
|
|
17420
|
+
z17.object({
|
|
17421
|
+
workspaceId: z17.string(),
|
|
17422
|
+
paths: z17.array(z17.string())
|
|
16462
17423
|
}),
|
|
16463
17424
|
async (args, ctx) => {
|
|
16464
17425
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -16474,9 +17435,9 @@ var init_git2 = __esm({
|
|
|
16474
17435
|
);
|
|
16475
17436
|
registerCommand(
|
|
16476
17437
|
"git.commit",
|
|
16477
|
-
|
|
16478
|
-
workspaceId:
|
|
16479
|
-
message:
|
|
17438
|
+
z17.object({
|
|
17439
|
+
workspaceId: z17.string(),
|
|
17440
|
+
message: z17.string()
|
|
16480
17441
|
}),
|
|
16481
17442
|
async (args, ctx) => {
|
|
16482
17443
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -16493,11 +17454,11 @@ var init_git2 = __esm({
|
|
|
16493
17454
|
);
|
|
16494
17455
|
registerCommand(
|
|
16495
17456
|
"git.push",
|
|
16496
|
-
|
|
16497
|
-
workspaceId:
|
|
16498
|
-
remote:
|
|
16499
|
-
branch:
|
|
16500
|
-
force:
|
|
17457
|
+
z17.object({
|
|
17458
|
+
workspaceId: z17.string(),
|
|
17459
|
+
remote: z17.string().optional(),
|
|
17460
|
+
branch: z17.string().optional(),
|
|
17461
|
+
force: z17.boolean().optional(),
|
|
16501
17462
|
auth: gitHttpAuthSchema.optional()
|
|
16502
17463
|
}),
|
|
16503
17464
|
async (args, ctx) => {
|
|
@@ -16523,128 +17484,737 @@ var init_git2 = __esm({
|
|
|
16523
17484
|
}
|
|
16524
17485
|
);
|
|
16525
17486
|
registerCommand(
|
|
16526
|
-
"git.pull",
|
|
16527
|
-
|
|
16528
|
-
workspaceId:
|
|
16529
|
-
remote:
|
|
16530
|
-
branch:
|
|
16531
|
-
auth: gitHttpAuthSchema.optional()
|
|
17487
|
+
"git.pull",
|
|
17488
|
+
z17.object({
|
|
17489
|
+
workspaceId: z17.string(),
|
|
17490
|
+
remote: z17.string().optional(),
|
|
17491
|
+
branch: z17.string().optional(),
|
|
17492
|
+
auth: gitHttpAuthSchema.optional()
|
|
17493
|
+
}),
|
|
17494
|
+
async (args, ctx) => {
|
|
17495
|
+
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
17496
|
+
if (!workspace) {
|
|
17497
|
+
throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
|
|
17498
|
+
}
|
|
17499
|
+
const result = await runGitNetworkOperation(
|
|
17500
|
+
ctx,
|
|
17501
|
+
args.workspaceId,
|
|
17502
|
+
() => runGitPull(workspace.path, {
|
|
17503
|
+
remote: args.remote,
|
|
17504
|
+
branch: args.branch,
|
|
17505
|
+
auth: args.auth
|
|
17506
|
+
})
|
|
17507
|
+
);
|
|
17508
|
+
ctx.workspaceMgr.recordFetch(args.workspaceId);
|
|
17509
|
+
emitGitStateChanged(ctx, args.workspaceId, {
|
|
17510
|
+
treeChanged: true,
|
|
17511
|
+
branchChanged: true,
|
|
17512
|
+
worktreeChanged: true
|
|
17513
|
+
});
|
|
17514
|
+
return result;
|
|
17515
|
+
}
|
|
17516
|
+
);
|
|
17517
|
+
registerCommand(
|
|
17518
|
+
"git.fetch",
|
|
17519
|
+
z17.object({
|
|
17520
|
+
workspaceId: z17.string(),
|
|
17521
|
+
remote: z17.string().optional(),
|
|
17522
|
+
prune: z17.boolean().optional(),
|
|
17523
|
+
auth: gitHttpAuthSchema.optional(),
|
|
17524
|
+
background: z17.boolean().optional()
|
|
17525
|
+
}),
|
|
17526
|
+
async (args, ctx, clientId) => {
|
|
17527
|
+
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
17528
|
+
if (!workspace) {
|
|
17529
|
+
throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
|
|
17530
|
+
}
|
|
17531
|
+
try {
|
|
17532
|
+
const isInternalBackgroundFetch = args.background === true && !clientId;
|
|
17533
|
+
const runFetch = () => runGitFetch(workspace.path, {
|
|
17534
|
+
remote: args.remote,
|
|
17535
|
+
prune: args.prune,
|
|
17536
|
+
auth: args.auth,
|
|
17537
|
+
timeoutMs: args.background ? GIT_BACKGROUND_FETCH_TIMEOUT_MS : void 0
|
|
17538
|
+
});
|
|
17539
|
+
const result = isInternalBackgroundFetch ? await runFetch() : await runGitNetworkOperation(ctx, args.workspaceId, runFetch);
|
|
17540
|
+
ctx.workspaceMgr.recordFetch(args.workspaceId);
|
|
17541
|
+
emitGitStateChanged(ctx, args.workspaceId, { branchChanged: true });
|
|
17542
|
+
return result;
|
|
17543
|
+
} catch (err) {
|
|
17544
|
+
if (args.background && err instanceof GitAuthError) {
|
|
17545
|
+
return { success: false, message: err.message, updatedRefs: [] };
|
|
17546
|
+
}
|
|
17547
|
+
throw err;
|
|
17548
|
+
}
|
|
17549
|
+
}
|
|
17550
|
+
);
|
|
17551
|
+
registerCommand(
|
|
17552
|
+
"git.checkout",
|
|
17553
|
+
z17.object({
|
|
17554
|
+
workspaceId: z17.string(),
|
|
17555
|
+
ref: z17.string(),
|
|
17556
|
+
createBranch: z17.boolean().optional()
|
|
17557
|
+
}),
|
|
17558
|
+
async (args, ctx) => {
|
|
17559
|
+
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
17560
|
+
if (!workspace) {
|
|
17561
|
+
throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
|
|
17562
|
+
}
|
|
17563
|
+
const result = await runGitCheckout(workspace.path, args.ref, {
|
|
17564
|
+
createBranch: args.createBranch
|
|
17565
|
+
});
|
|
17566
|
+
if (result.success) {
|
|
17567
|
+
emitGitStateChanged(ctx, args.workspaceId, {
|
|
17568
|
+
treeChanged: true,
|
|
17569
|
+
branchChanged: true,
|
|
17570
|
+
worktreeChanged: true
|
|
17571
|
+
});
|
|
17572
|
+
}
|
|
17573
|
+
return result;
|
|
17574
|
+
}
|
|
17575
|
+
);
|
|
17576
|
+
registerCommand(
|
|
17577
|
+
"git.branch",
|
|
17578
|
+
z17.object({
|
|
17579
|
+
workspaceId: z17.string(),
|
|
17580
|
+
name: z17.string(),
|
|
17581
|
+
startPoint: z17.string().optional()
|
|
17582
|
+
}),
|
|
17583
|
+
async (args, ctx) => {
|
|
17584
|
+
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
17585
|
+
if (!workspace) {
|
|
17586
|
+
throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
|
|
17587
|
+
}
|
|
17588
|
+
const result = await runGitCreateBranch(workspace.path, args.name, {
|
|
17589
|
+
startPoint: args.startPoint
|
|
17590
|
+
});
|
|
17591
|
+
emitGitStateChanged(ctx, args.workspaceId, {
|
|
17592
|
+
branchChanged: true,
|
|
17593
|
+
worktreeChanged: true
|
|
17594
|
+
});
|
|
17595
|
+
return result;
|
|
17596
|
+
}
|
|
17597
|
+
);
|
|
17598
|
+
registerCommand(
|
|
17599
|
+
"git.branches",
|
|
17600
|
+
z17.object({
|
|
17601
|
+
workspaceId: z17.string()
|
|
17602
|
+
}),
|
|
17603
|
+
async (args, ctx) => {
|
|
17604
|
+
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
17605
|
+
if (!workspace) {
|
|
17606
|
+
throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
|
|
17607
|
+
}
|
|
17608
|
+
return runGitListBranches(workspace.path);
|
|
17609
|
+
}
|
|
17610
|
+
);
|
|
17611
|
+
}
|
|
17612
|
+
});
|
|
17613
|
+
|
|
17614
|
+
// packages/server/src/agent-instructions/generator.ts
|
|
17615
|
+
function buildAgentInstructionsMarkdown(summary) {
|
|
17616
|
+
const lines = ["# Agent Instructions", ""];
|
|
17617
|
+
pushSection(lines, "Project Overview", buildProjectOverview(summary));
|
|
17618
|
+
pushSection(lines, "Development Commands", buildDevelopmentCommands(summary));
|
|
17619
|
+
pushSection(lines, "Working Rules", [...WORKING_RULES.map((rule) => `- ${rule}`)]);
|
|
17620
|
+
pushSection(
|
|
17621
|
+
lines,
|
|
17622
|
+
"Review Expectations",
|
|
17623
|
+
REVIEW_EXPECTATIONS.map((rule) => `- ${rule}`)
|
|
17624
|
+
);
|
|
17625
|
+
pushSection(
|
|
17626
|
+
lines,
|
|
17627
|
+
"Provider Notes",
|
|
17628
|
+
PROVIDER_NOTES.map((note) => `- ${note}`)
|
|
17629
|
+
);
|
|
17630
|
+
return lines.join("\n");
|
|
17631
|
+
}
|
|
17632
|
+
function buildProjectOverview(summary) {
|
|
17633
|
+
const lines = [];
|
|
17634
|
+
if (summary.git.isRepo) {
|
|
17635
|
+
if (summary.git.branch) {
|
|
17636
|
+
lines.push(`- Git branch: ${summary.git.branch}`);
|
|
17637
|
+
} else {
|
|
17638
|
+
lines.push("- Git repository: yes");
|
|
17639
|
+
}
|
|
17640
|
+
} else {
|
|
17641
|
+
lines.push("- Git repository: no");
|
|
17642
|
+
}
|
|
17643
|
+
if (summary.packageManager) {
|
|
17644
|
+
lines.push(`- Package manager: ${summary.packageManager}`);
|
|
17645
|
+
}
|
|
17646
|
+
if (summary.frameworks.length > 0) {
|
|
17647
|
+
lines.push(`- Frameworks: ${summary.frameworks.join(", ")}`);
|
|
17648
|
+
}
|
|
17649
|
+
if (summary.docs.length > 0) {
|
|
17650
|
+
lines.push(`- Docs: ${summary.docs.map((doc) => doc.path).join(", ")}`);
|
|
17651
|
+
}
|
|
17652
|
+
lines.push(
|
|
17653
|
+
`- ${summary.agentInstructions.path}: ${summary.agentInstructions.exists ? "exists" : "missing"}`
|
|
17654
|
+
);
|
|
17655
|
+
return lines;
|
|
17656
|
+
}
|
|
17657
|
+
function buildDevelopmentCommands(summary) {
|
|
17658
|
+
const lines = [];
|
|
17659
|
+
const commandLabels = {
|
|
17660
|
+
dev: "Dev",
|
|
17661
|
+
test: "Test",
|
|
17662
|
+
build: "Build",
|
|
17663
|
+
lint: "Lint"
|
|
17664
|
+
};
|
|
17665
|
+
for (const key of ["dev", "test", "build", "lint"]) {
|
|
17666
|
+
const command = summary.recommendedCommands.find((item) => item.key === key)?.command;
|
|
17667
|
+
if (!command) {
|
|
17668
|
+
continue;
|
|
17669
|
+
}
|
|
17670
|
+
lines.push(`- ${commandLabels[key]}: \`${command}\``);
|
|
17671
|
+
}
|
|
17672
|
+
return lines;
|
|
17673
|
+
}
|
|
17674
|
+
function pushSection(lines, heading, body) {
|
|
17675
|
+
lines.push(`## ${heading}`, "");
|
|
17676
|
+
lines.push(...body);
|
|
17677
|
+
lines.push("");
|
|
17678
|
+
}
|
|
17679
|
+
var WORKING_RULES, REVIEW_EXPECTATIONS, PROVIDER_NOTES;
|
|
17680
|
+
var init_generator = __esm({
|
|
17681
|
+
"packages/server/src/agent-instructions/generator.ts"() {
|
|
17682
|
+
"use strict";
|
|
17683
|
+
WORKING_RULES = [
|
|
17684
|
+
"Keep changes focused on the requested task.",
|
|
17685
|
+
"Do not revert user changes unless explicitly asked.",
|
|
17686
|
+
"Prefer the project's existing patterns.",
|
|
17687
|
+
"Run the relevant verification command before reporting completion."
|
|
17688
|
+
];
|
|
17689
|
+
REVIEW_EXPECTATIONS = [
|
|
17690
|
+
"Summarize changed files.",
|
|
17691
|
+
"Report verification commands and results.",
|
|
17692
|
+
"Call out risks, skipped tests, and assumptions."
|
|
17693
|
+
];
|
|
17694
|
+
PROVIDER_NOTES = [
|
|
17695
|
+
"Claude Code: use the project rules above.",
|
|
17696
|
+
"Codex: use the project rules above."
|
|
17697
|
+
];
|
|
17698
|
+
}
|
|
17699
|
+
});
|
|
17700
|
+
|
|
17701
|
+
// packages/server/src/agent-instructions/health.ts
|
|
17702
|
+
function evaluateAgentInstructionsMarkdown(content) {
|
|
17703
|
+
if (!content.trim()) {
|
|
17704
|
+
return {
|
|
17705
|
+
path: AGENT_INSTRUCTIONS_RELATIVE_PATH,
|
|
17706
|
+
exists: false,
|
|
17707
|
+
status: "missing",
|
|
17708
|
+
checks: {
|
|
17709
|
+
projectOverview: false,
|
|
17710
|
+
developmentCommands: false,
|
|
17711
|
+
workingRules: false,
|
|
17712
|
+
reviewExpectations: false,
|
|
17713
|
+
safetyRules: false,
|
|
17714
|
+
providerNotes: false
|
|
17715
|
+
},
|
|
17716
|
+
issues: [
|
|
17717
|
+
{
|
|
17718
|
+
code: "missing_document",
|
|
17719
|
+
message: `${AGENT_INSTRUCTIONS_RELATIVE_PATH} is missing`
|
|
17720
|
+
}
|
|
17721
|
+
]
|
|
17722
|
+
};
|
|
17723
|
+
}
|
|
17724
|
+
const sections = indexSections(content);
|
|
17725
|
+
const projectOverview = sections.has("Project Overview");
|
|
17726
|
+
const developmentCommands = hasAnyBullet(sections.get("Development Commands"));
|
|
17727
|
+
const workingRulesSection = sections.get("Working Rules");
|
|
17728
|
+
const reviewExpectationsSection = sections.get("Review Expectations");
|
|
17729
|
+
const providerNotesSection = sections.get("Provider Notes");
|
|
17730
|
+
const workingRules = hasAnyBullet(workingRulesSection);
|
|
17731
|
+
const reviewExpectations = hasAnyBullet(reviewExpectationsSection) && REQUIRED_REVIEW_EXPECTATIONS.every(
|
|
17732
|
+
(rule) => reviewExpectationsSection?.some((line) => line.includes(rule))
|
|
17733
|
+
);
|
|
17734
|
+
const providerNotes = hasAnyBullet(providerNotesSection) && PROVIDER_NOTE_MARKERS.some(
|
|
17735
|
+
(marker) => providerNotesSection?.some((line) => line.includes(marker))
|
|
17736
|
+
);
|
|
17737
|
+
const safetyRules = REQUIRED_WORKING_RULES.every(
|
|
17738
|
+
(rule) => workingRulesSection?.some((line) => line.includes(rule))
|
|
17739
|
+
);
|
|
17740
|
+
const issues = [];
|
|
17741
|
+
if (!projectOverview) {
|
|
17742
|
+
issues.push({
|
|
17743
|
+
code: "missing_project_overview",
|
|
17744
|
+
message: "Project Overview section is missing"
|
|
17745
|
+
});
|
|
17746
|
+
}
|
|
17747
|
+
if (!developmentCommands) {
|
|
17748
|
+
issues.push({
|
|
17749
|
+
code: "missing_development_commands",
|
|
17750
|
+
message: "Development Commands section is missing"
|
|
17751
|
+
});
|
|
17752
|
+
}
|
|
17753
|
+
if (!workingRules) {
|
|
17754
|
+
issues.push({
|
|
17755
|
+
code: "missing_working_rules",
|
|
17756
|
+
message: "Working Rules section is missing"
|
|
17757
|
+
});
|
|
17758
|
+
}
|
|
17759
|
+
if (!reviewExpectations) {
|
|
17760
|
+
issues.push({
|
|
17761
|
+
code: "missing_review_expectations",
|
|
17762
|
+
message: "Review Expectations section is missing"
|
|
17763
|
+
});
|
|
17764
|
+
}
|
|
17765
|
+
if (!safetyRules) {
|
|
17766
|
+
issues.push({
|
|
17767
|
+
code: "missing_safety_rules",
|
|
17768
|
+
message: "Working rules do not include the required safety rules"
|
|
17769
|
+
});
|
|
17770
|
+
}
|
|
17771
|
+
if (!providerNotes) {
|
|
17772
|
+
issues.push({
|
|
17773
|
+
code: "missing_provider_notes",
|
|
17774
|
+
message: "Provider Notes section is missing"
|
|
17775
|
+
});
|
|
17776
|
+
}
|
|
17777
|
+
const status = issues.length === 0 ? "healthy" : "warning";
|
|
17778
|
+
return {
|
|
17779
|
+
path: AGENT_INSTRUCTIONS_RELATIVE_PATH,
|
|
17780
|
+
exists: true,
|
|
17781
|
+
status,
|
|
17782
|
+
checks: {
|
|
17783
|
+
projectOverview,
|
|
17784
|
+
developmentCommands,
|
|
17785
|
+
workingRules,
|
|
17786
|
+
reviewExpectations,
|
|
17787
|
+
safetyRules,
|
|
17788
|
+
providerNotes
|
|
17789
|
+
},
|
|
17790
|
+
issues
|
|
17791
|
+
};
|
|
17792
|
+
}
|
|
17793
|
+
function indexSections(content) {
|
|
17794
|
+
const sections = /* @__PURE__ */ new Map();
|
|
17795
|
+
const lines = content.split(/\r?\n/);
|
|
17796
|
+
let currentHeading = null;
|
|
17797
|
+
for (const line of lines) {
|
|
17798
|
+
const heading = line.match(/^##\s+(.+?)\s*$/)?.[1];
|
|
17799
|
+
if (heading) {
|
|
17800
|
+
currentHeading = heading;
|
|
17801
|
+
if (!sections.has(heading)) {
|
|
17802
|
+
sections.set(heading, []);
|
|
17803
|
+
}
|
|
17804
|
+
continue;
|
|
17805
|
+
}
|
|
17806
|
+
if (currentHeading) {
|
|
17807
|
+
sections.get(currentHeading)?.push(line);
|
|
17808
|
+
}
|
|
17809
|
+
}
|
|
17810
|
+
return sections;
|
|
17811
|
+
}
|
|
17812
|
+
function hasAnyBullet(lines) {
|
|
17813
|
+
return Boolean(lines?.some((line) => line.trimStart().startsWith("- ")));
|
|
17814
|
+
}
|
|
17815
|
+
var REQUIRED_WORKING_RULES, REQUIRED_REVIEW_EXPECTATIONS, PROVIDER_NOTE_MARKERS;
|
|
17816
|
+
var init_health = __esm({
|
|
17817
|
+
"packages/server/src/agent-instructions/health.ts"() {
|
|
17818
|
+
"use strict";
|
|
17819
|
+
init_workspace_state();
|
|
17820
|
+
REQUIRED_WORKING_RULES = [
|
|
17821
|
+
"Keep changes focused on the requested task.",
|
|
17822
|
+
"Do not revert user changes unless explicitly asked.",
|
|
17823
|
+
"Prefer the project's existing patterns.",
|
|
17824
|
+
"Run the relevant verification command before reporting completion."
|
|
17825
|
+
];
|
|
17826
|
+
REQUIRED_REVIEW_EXPECTATIONS = [
|
|
17827
|
+
"Summarize changed files.",
|
|
17828
|
+
"Report verification commands and results.",
|
|
17829
|
+
"Call out risks, skipped tests, and assumptions."
|
|
17830
|
+
];
|
|
17831
|
+
PROVIDER_NOTE_MARKERS = ["Claude Code:", "Codex:"];
|
|
17832
|
+
}
|
|
17833
|
+
});
|
|
17834
|
+
|
|
17835
|
+
// packages/server/src/commands/agent-instructions.ts
|
|
17836
|
+
import { z as z18 } from "zod";
|
|
17837
|
+
async function readAgentInstructionsDocument(workspaceId, rootPath) {
|
|
17838
|
+
const path14 = AGENT_INSTRUCTIONS_RELATIVE_PATH;
|
|
17839
|
+
try {
|
|
17840
|
+
const result = await readFile(workspaceId, rootPath, path14);
|
|
17841
|
+
if (result.kind !== "text") {
|
|
17842
|
+
return {
|
|
17843
|
+
path: path14,
|
|
17844
|
+
exists: true,
|
|
17845
|
+
content: ""
|
|
17846
|
+
};
|
|
17847
|
+
}
|
|
17848
|
+
return {
|
|
17849
|
+
path: path14,
|
|
17850
|
+
exists: true,
|
|
17851
|
+
content: result.content,
|
|
17852
|
+
baseHash: result.baseHash
|
|
17853
|
+
};
|
|
17854
|
+
} catch {
|
|
17855
|
+
return {
|
|
17856
|
+
path: path14,
|
|
17857
|
+
exists: false,
|
|
17858
|
+
content: ""
|
|
17859
|
+
};
|
|
17860
|
+
}
|
|
17861
|
+
}
|
|
17862
|
+
var init_agent_instructions = __esm({
|
|
17863
|
+
"packages/server/src/commands/agent-instructions.ts"() {
|
|
17864
|
+
"use strict";
|
|
17865
|
+
init_generator();
|
|
17866
|
+
init_health();
|
|
17867
|
+
init_file_io();
|
|
17868
|
+
init_intelligence();
|
|
17869
|
+
init_workspace_state();
|
|
17870
|
+
init_dispatch();
|
|
17871
|
+
registerCommand(
|
|
17872
|
+
"agentInstructions.read",
|
|
17873
|
+
z18.object({
|
|
17874
|
+
workspaceId: z18.string()
|
|
17875
|
+
}),
|
|
17876
|
+
async (args, ctx) => {
|
|
17877
|
+
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
17878
|
+
if (!workspace) {
|
|
17879
|
+
throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
|
|
17880
|
+
}
|
|
17881
|
+
return readAgentInstructionsDocument(workspace.id, workspace.path);
|
|
17882
|
+
}
|
|
17883
|
+
);
|
|
17884
|
+
registerCommand(
|
|
17885
|
+
"agentInstructions.generate",
|
|
17886
|
+
z18.object({
|
|
17887
|
+
workspaceId: z18.string()
|
|
17888
|
+
}),
|
|
17889
|
+
async (args, ctx) => {
|
|
17890
|
+
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
17891
|
+
if (!workspace) {
|
|
17892
|
+
throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
|
|
17893
|
+
}
|
|
17894
|
+
const summary = await inspectWorkspaceIntelligence({
|
|
17895
|
+
workspaceId: workspace.id,
|
|
17896
|
+
rootPath: workspace.path
|
|
17897
|
+
});
|
|
17898
|
+
return {
|
|
17899
|
+
path: AGENT_INSTRUCTIONS_RELATIVE_PATH,
|
|
17900
|
+
exists: false,
|
|
17901
|
+
content: buildAgentInstructionsMarkdown(summary)
|
|
17902
|
+
};
|
|
17903
|
+
}
|
|
17904
|
+
);
|
|
17905
|
+
registerCommand(
|
|
17906
|
+
"agentInstructions.write",
|
|
17907
|
+
z18.object({
|
|
17908
|
+
workspaceId: z18.string(),
|
|
17909
|
+
content: z18.string(),
|
|
17910
|
+
overwrite: z18.boolean().optional(),
|
|
17911
|
+
baseHash: z18.string().optional()
|
|
16532
17912
|
}),
|
|
16533
17913
|
async (args, ctx) => {
|
|
16534
17914
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
16535
17915
|
if (!workspace) {
|
|
16536
17916
|
throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
|
|
16537
17917
|
}
|
|
16538
|
-
const
|
|
16539
|
-
|
|
16540
|
-
|
|
16541
|
-
|
|
16542
|
-
|
|
16543
|
-
|
|
16544
|
-
|
|
16545
|
-
|
|
17918
|
+
const existing = await readAgentInstructionsDocument(workspace.id, workspace.path);
|
|
17919
|
+
if (existing.exists && !args.overwrite) {
|
|
17920
|
+
throw {
|
|
17921
|
+
code: "agent_instructions_exists",
|
|
17922
|
+
message: `${AGENT_INSTRUCTIONS_RELATIVE_PATH} already exists`
|
|
17923
|
+
};
|
|
17924
|
+
}
|
|
17925
|
+
const result = await writeFile(
|
|
17926
|
+
workspace.path,
|
|
17927
|
+
AGENT_INSTRUCTIONS_RELATIVE_PATH,
|
|
17928
|
+
args.content,
|
|
17929
|
+
args.baseHash
|
|
16546
17930
|
);
|
|
16547
|
-
ctx.
|
|
16548
|
-
|
|
16549
|
-
|
|
16550
|
-
|
|
16551
|
-
worktreeChanged: true
|
|
17931
|
+
ctx.eventBus.emit({
|
|
17932
|
+
type: "fs.dirty",
|
|
17933
|
+
workspaceId: args.workspaceId,
|
|
17934
|
+
reason: "file_content"
|
|
16552
17935
|
});
|
|
16553
|
-
return
|
|
17936
|
+
return {
|
|
17937
|
+
path: AGENT_INSTRUCTIONS_RELATIVE_PATH,
|
|
17938
|
+
exists: true,
|
|
17939
|
+
content: args.content,
|
|
17940
|
+
baseHash: result.newHash
|
|
17941
|
+
};
|
|
16554
17942
|
}
|
|
16555
17943
|
);
|
|
16556
17944
|
registerCommand(
|
|
16557
|
-
"
|
|
16558
|
-
|
|
16559
|
-
workspaceId:
|
|
16560
|
-
remote: z14.string().optional(),
|
|
16561
|
-
prune: z14.boolean().optional(),
|
|
16562
|
-
auth: gitHttpAuthSchema.optional(),
|
|
16563
|
-
background: z14.boolean().optional()
|
|
17945
|
+
"agentInstructions.health",
|
|
17946
|
+
z18.object({
|
|
17947
|
+
workspaceId: z18.string()
|
|
16564
17948
|
}),
|
|
16565
|
-
async (args, ctx
|
|
17949
|
+
async (args, ctx) => {
|
|
16566
17950
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
16567
17951
|
if (!workspace) {
|
|
16568
17952
|
throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
|
|
16569
17953
|
}
|
|
16570
|
-
|
|
16571
|
-
|
|
16572
|
-
const runFetch = () => runGitFetch(workspace.path, {
|
|
16573
|
-
remote: args.remote,
|
|
16574
|
-
prune: args.prune,
|
|
16575
|
-
auth: args.auth,
|
|
16576
|
-
timeoutMs: args.background ? GIT_BACKGROUND_FETCH_TIMEOUT_MS : void 0
|
|
16577
|
-
});
|
|
16578
|
-
const result = isInternalBackgroundFetch ? await runFetch() : await runGitNetworkOperation(ctx, args.workspaceId, runFetch);
|
|
16579
|
-
ctx.workspaceMgr.recordFetch(args.workspaceId);
|
|
16580
|
-
emitGitStateChanged(ctx, args.workspaceId, { branchChanged: true });
|
|
16581
|
-
return result;
|
|
16582
|
-
} catch (err) {
|
|
16583
|
-
if (args.background && err instanceof GitAuthError) {
|
|
16584
|
-
return { success: false, message: err.message, updatedRefs: [] };
|
|
16585
|
-
}
|
|
16586
|
-
throw err;
|
|
16587
|
-
}
|
|
17954
|
+
const document = await readAgentInstructionsDocument(workspace.id, workspace.path);
|
|
17955
|
+
return evaluateAgentInstructionsMarkdown(document.content);
|
|
16588
17956
|
}
|
|
16589
17957
|
);
|
|
17958
|
+
}
|
|
17959
|
+
});
|
|
17960
|
+
|
|
17961
|
+
// packages/server/src/agent-context/context-package.ts
|
|
17962
|
+
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
17963
|
+
import { readFile as readFile8 } from "node:fs/promises";
|
|
17964
|
+
function resolveOptions(options) {
|
|
17965
|
+
return {
|
|
17966
|
+
createId: options?.createId ?? randomUUID7,
|
|
17967
|
+
now: options?.now ?? Date.now
|
|
17968
|
+
};
|
|
17969
|
+
}
|
|
17970
|
+
function formatSource(source) {
|
|
17971
|
+
const parts = [`workspace=${source.workspaceId}`];
|
|
17972
|
+
if (source.sessionId) {
|
|
17973
|
+
parts.push(`session=${source.sessionId}`);
|
|
17974
|
+
}
|
|
17975
|
+
if (source.path) {
|
|
17976
|
+
parts.push(`path=${source.path}`);
|
|
17977
|
+
}
|
|
17978
|
+
if (source.terminalId) {
|
|
17979
|
+
parts.push(`terminal=${source.terminalId}`);
|
|
17980
|
+
}
|
|
17981
|
+
return parts.join(" ");
|
|
17982
|
+
}
|
|
17983
|
+
function wrapContext(title, source, body) {
|
|
17984
|
+
return `Context: ${title}
|
|
17985
|
+
Source: ${formatSource(source)}
|
|
17986
|
+
|
|
17987
|
+
${body}`;
|
|
17988
|
+
}
|
|
17989
|
+
function createContextPackage(kind, title, source, body, options) {
|
|
17990
|
+
const resolved = resolveOptions(options);
|
|
17991
|
+
return {
|
|
17992
|
+
id: resolved.createId(),
|
|
17993
|
+
kind,
|
|
17994
|
+
title,
|
|
17995
|
+
body: wrapContext(title, source, body),
|
|
17996
|
+
source,
|
|
17997
|
+
createdAt: resolved.now()
|
|
17998
|
+
};
|
|
17999
|
+
}
|
|
18000
|
+
function requireSessionMetadata2(metadataRepo, sessionId) {
|
|
18001
|
+
const metadata = metadataRepo.get(sessionId);
|
|
18002
|
+
if (!metadata) {
|
|
18003
|
+
throw {
|
|
18004
|
+
code: "session_metadata_not_found",
|
|
18005
|
+
message: `Session metadata not found: ${sessionId}`
|
|
18006
|
+
};
|
|
18007
|
+
}
|
|
18008
|
+
return metadata;
|
|
18009
|
+
}
|
|
18010
|
+
function buildProjectSummaryBody(summary) {
|
|
18011
|
+
const lines = [
|
|
18012
|
+
`Git: ${summary.git.isRepo ? "repository detected" : "no repository detected"}`,
|
|
18013
|
+
`Package manager: ${summary.packageManager ?? "unknown"}`,
|
|
18014
|
+
`Frameworks: ${summary.frameworks.length > 0 ? summary.frameworks.join(", ") : "none"}`
|
|
18015
|
+
];
|
|
18016
|
+
if (summary.recommendedCommands.length > 0) {
|
|
18017
|
+
lines.push("Recommended commands:");
|
|
18018
|
+
for (const command of summary.recommendedCommands) {
|
|
18019
|
+
lines.push(`- ${command.key}: ${command.command}`);
|
|
18020
|
+
}
|
|
18021
|
+
} else {
|
|
18022
|
+
lines.push("Recommended commands: none");
|
|
18023
|
+
}
|
|
18024
|
+
if (summary.docs.length > 0) {
|
|
18025
|
+
lines.push("Docs:");
|
|
18026
|
+
for (const doc of summary.docs) {
|
|
18027
|
+
lines.push(`- ${doc.path}`);
|
|
18028
|
+
}
|
|
18029
|
+
} else {
|
|
18030
|
+
lines.push("Docs: none");
|
|
18031
|
+
}
|
|
18032
|
+
lines.push(
|
|
18033
|
+
`Agent instructions: ${summary.agentInstructions.path} ${summary.agentInstructions.exists ? "present" : "missing"}`
|
|
18034
|
+
);
|
|
18035
|
+
return lines.join("\n");
|
|
18036
|
+
}
|
|
18037
|
+
async function buildFileContextPackage(input2, options) {
|
|
18038
|
+
const content = await readFile8(resolveSafe(input2.workspacePath, input2.path), "utf8");
|
|
18039
|
+
return createContextPackage(
|
|
18040
|
+
"file",
|
|
18041
|
+
`File: ${input2.path}`,
|
|
18042
|
+
{
|
|
18043
|
+
workspaceId: input2.workspaceId,
|
|
18044
|
+
path: input2.path
|
|
18045
|
+
},
|
|
18046
|
+
content,
|
|
18047
|
+
options
|
|
18048
|
+
);
|
|
18049
|
+
}
|
|
18050
|
+
async function buildDiffContextPackage(input2, options) {
|
|
18051
|
+
const metadata = requireSessionMetadata2(input2.metadataRepo, input2.sessionId);
|
|
18052
|
+
const diff = await getSessionReviewDiff({
|
|
18053
|
+
sessionId: input2.sessionId,
|
|
18054
|
+
workspacePath: input2.workspacePath,
|
|
18055
|
+
metadataRepo: input2.metadataRepo,
|
|
18056
|
+
path: input2.path
|
|
18057
|
+
});
|
|
18058
|
+
return createContextPackage(
|
|
18059
|
+
"git_diff",
|
|
18060
|
+
`Git Diff: ${input2.path}`,
|
|
18061
|
+
{
|
|
18062
|
+
workspaceId: metadata.workspaceId,
|
|
18063
|
+
sessionId: input2.sessionId,
|
|
18064
|
+
path: input2.path
|
|
18065
|
+
},
|
|
18066
|
+
diff,
|
|
18067
|
+
options
|
|
18068
|
+
);
|
|
18069
|
+
}
|
|
18070
|
+
async function buildProjectSummaryContextPackage(input2, options) {
|
|
18071
|
+
const summary = await inspectWorkspaceIntelligence({
|
|
18072
|
+
workspaceId: input2.workspaceId,
|
|
18073
|
+
rootPath: input2.workspacePath
|
|
18074
|
+
});
|
|
18075
|
+
return createContextPackage(
|
|
18076
|
+
"project_summary",
|
|
18077
|
+
"Project Summary",
|
|
18078
|
+
{
|
|
18079
|
+
workspaceId: input2.workspaceId
|
|
18080
|
+
},
|
|
18081
|
+
buildProjectSummaryBody(summary),
|
|
18082
|
+
options
|
|
18083
|
+
);
|
|
18084
|
+
}
|
|
18085
|
+
async function buildSessionReviewContextPackage(input2, options) {
|
|
18086
|
+
const metadata = requireSessionMetadata2(input2.metadataRepo, input2.sessionId);
|
|
18087
|
+
const summary = await buildSessionReviewSummary({
|
|
18088
|
+
sessionId: input2.sessionId,
|
|
18089
|
+
workspacePath: input2.workspacePath,
|
|
18090
|
+
metadataRepo: input2.metadataRepo
|
|
18091
|
+
});
|
|
18092
|
+
const lines = [
|
|
18093
|
+
`Baseline: ${summary.baselineGitHead ?? "missing"}`,
|
|
18094
|
+
"Changed files:",
|
|
18095
|
+
...summary.changedFiles.length > 0 ? summary.changedFiles.map((change) => `- ${change.status ?? "modified"}: ${change.path}`) : ["- none"],
|
|
18096
|
+
"Verification runs:",
|
|
18097
|
+
...summary.verificationRuns.length > 0 ? summary.verificationRuns.map((run) => `- ${run.status}: ${run.command}`) : ["- none"]
|
|
18098
|
+
];
|
|
18099
|
+
if (summary.warnings.length > 0) {
|
|
18100
|
+
lines.push("Warnings:");
|
|
18101
|
+
for (const warning of summary.warnings) {
|
|
18102
|
+
lines.push(`- ${warning.code}: ${warning.message}`);
|
|
18103
|
+
}
|
|
18104
|
+
}
|
|
18105
|
+
return createContextPackage(
|
|
18106
|
+
"session_review",
|
|
18107
|
+
`Session Review: ${summary.sessionId}`,
|
|
18108
|
+
{
|
|
18109
|
+
workspaceId: metadata.workspaceId,
|
|
18110
|
+
sessionId: input2.sessionId
|
|
18111
|
+
},
|
|
18112
|
+
lines.join("\n"),
|
|
18113
|
+
options
|
|
18114
|
+
);
|
|
18115
|
+
}
|
|
18116
|
+
var init_context_package = __esm({
|
|
18117
|
+
"packages/server/src/agent-context/context-package.ts"() {
|
|
18118
|
+
"use strict";
|
|
18119
|
+
init_file_io();
|
|
18120
|
+
init_review();
|
|
18121
|
+
init_intelligence();
|
|
18122
|
+
}
|
|
18123
|
+
});
|
|
18124
|
+
|
|
18125
|
+
// packages/server/src/commands/agent-context.ts
|
|
18126
|
+
import { z as z19 } from "zod";
|
|
18127
|
+
function requireWorkspace2(ctx, workspaceId) {
|
|
18128
|
+
const workspace = ctx.workspaceMgr.get(workspaceId);
|
|
18129
|
+
if (!workspace) {
|
|
18130
|
+
throw { code: "workspace_not_found", message: `Workspace not found: ${workspaceId}` };
|
|
18131
|
+
}
|
|
18132
|
+
return workspace;
|
|
18133
|
+
}
|
|
18134
|
+
function requireSessionMetadataRepo3(ctx) {
|
|
18135
|
+
if (!ctx.sessionMetadataRepo) {
|
|
18136
|
+
throw {
|
|
18137
|
+
code: "session_metadata_unavailable",
|
|
18138
|
+
message: "Session metadata repository is not configured"
|
|
18139
|
+
};
|
|
18140
|
+
}
|
|
18141
|
+
}
|
|
18142
|
+
function getSessionWorkspace(ctx, sessionId) {
|
|
18143
|
+
const metadata = ctx.sessionMetadataRepo.get(sessionId);
|
|
18144
|
+
if (!metadata) {
|
|
18145
|
+
throw {
|
|
18146
|
+
code: "session_metadata_not_found",
|
|
18147
|
+
message: `Session metadata not found: ${sessionId}`
|
|
18148
|
+
};
|
|
18149
|
+
}
|
|
18150
|
+
return {
|
|
18151
|
+
metadata,
|
|
18152
|
+
workspace: requireWorkspace2(ctx, metadata.workspaceId)
|
|
18153
|
+
};
|
|
18154
|
+
}
|
|
18155
|
+
var init_agent_context = __esm({
|
|
18156
|
+
"packages/server/src/commands/agent-context.ts"() {
|
|
18157
|
+
"use strict";
|
|
18158
|
+
init_context_package();
|
|
18159
|
+
init_dispatch();
|
|
16590
18160
|
registerCommand(
|
|
16591
|
-
"
|
|
16592
|
-
|
|
16593
|
-
workspaceId:
|
|
16594
|
-
|
|
16595
|
-
createBranch: z14.boolean().optional()
|
|
18161
|
+
"agentContext.fromFile",
|
|
18162
|
+
z19.object({
|
|
18163
|
+
workspaceId: z19.string(),
|
|
18164
|
+
path: z19.string().trim().min(1)
|
|
16596
18165
|
}),
|
|
16597
18166
|
async (args, ctx) => {
|
|
16598
|
-
const workspace = ctx
|
|
16599
|
-
|
|
16600
|
-
|
|
16601
|
-
|
|
16602
|
-
|
|
16603
|
-
createBranch: args.createBranch
|
|
18167
|
+
const workspace = requireWorkspace2(ctx, args.workspaceId);
|
|
18168
|
+
return buildFileContextPackage({
|
|
18169
|
+
workspaceId: workspace.id,
|
|
18170
|
+
workspacePath: workspace.path,
|
|
18171
|
+
path: args.path
|
|
16604
18172
|
});
|
|
16605
|
-
if (result.success) {
|
|
16606
|
-
emitGitStateChanged(ctx, args.workspaceId, {
|
|
16607
|
-
treeChanged: true,
|
|
16608
|
-
branchChanged: true,
|
|
16609
|
-
worktreeChanged: true
|
|
16610
|
-
});
|
|
16611
|
-
}
|
|
16612
|
-
return result;
|
|
16613
18173
|
}
|
|
16614
18174
|
);
|
|
16615
18175
|
registerCommand(
|
|
16616
|
-
"
|
|
16617
|
-
|
|
16618
|
-
|
|
16619
|
-
|
|
16620
|
-
startPoint: z14.string().optional()
|
|
18176
|
+
"agentContext.fromDiff",
|
|
18177
|
+
z19.object({
|
|
18178
|
+
sessionId: z19.string(),
|
|
18179
|
+
path: z19.string().trim().min(1)
|
|
16621
18180
|
}),
|
|
16622
18181
|
async (args, ctx) => {
|
|
16623
|
-
|
|
16624
|
-
|
|
16625
|
-
|
|
16626
|
-
|
|
16627
|
-
|
|
16628
|
-
|
|
18182
|
+
requireSessionMetadataRepo3(ctx);
|
|
18183
|
+
const { workspace } = getSessionWorkspace(ctx, args.sessionId);
|
|
18184
|
+
return buildDiffContextPackage({
|
|
18185
|
+
sessionId: args.sessionId,
|
|
18186
|
+
path: args.path,
|
|
18187
|
+
workspacePath: workspace.path,
|
|
18188
|
+
metadataRepo: ctx.sessionMetadataRepo
|
|
16629
18189
|
});
|
|
16630
|
-
|
|
16631
|
-
|
|
16632
|
-
|
|
18190
|
+
}
|
|
18191
|
+
);
|
|
18192
|
+
registerCommand(
|
|
18193
|
+
"agentContext.fromProjectSummary",
|
|
18194
|
+
z19.object({
|
|
18195
|
+
workspaceId: z19.string()
|
|
18196
|
+
}),
|
|
18197
|
+
async (args, ctx) => {
|
|
18198
|
+
const workspace = requireWorkspace2(ctx, args.workspaceId);
|
|
18199
|
+
return buildProjectSummaryContextPackage({
|
|
18200
|
+
workspaceId: workspace.id,
|
|
18201
|
+
workspacePath: workspace.path
|
|
16633
18202
|
});
|
|
16634
|
-
return result;
|
|
16635
18203
|
}
|
|
16636
18204
|
);
|
|
16637
18205
|
registerCommand(
|
|
16638
|
-
"
|
|
16639
|
-
|
|
16640
|
-
|
|
18206
|
+
"agentContext.fromSessionReview",
|
|
18207
|
+
z19.object({
|
|
18208
|
+
sessionId: z19.string()
|
|
16641
18209
|
}),
|
|
16642
18210
|
async (args, ctx) => {
|
|
16643
|
-
|
|
16644
|
-
|
|
16645
|
-
|
|
16646
|
-
|
|
16647
|
-
|
|
18211
|
+
requireSessionMetadataRepo3(ctx);
|
|
18212
|
+
const { workspace } = getSessionWorkspace(ctx, args.sessionId);
|
|
18213
|
+
return buildSessionReviewContextPackage({
|
|
18214
|
+
sessionId: args.sessionId,
|
|
18215
|
+
workspacePath: workspace.path,
|
|
18216
|
+
metadataRepo: ctx.sessionMetadataRepo
|
|
18217
|
+
});
|
|
16648
18218
|
}
|
|
16649
18219
|
);
|
|
16650
18220
|
}
|
|
@@ -16653,25 +18223,25 @@ var init_git2 = __esm({
|
|
|
16653
18223
|
// packages/server/src/config/config-io.ts
|
|
16654
18224
|
import { existsSync as existsSync9, mkdirSync as mkdirSync7, readFileSync as readFileSync7, renameSync as renameSync2, writeFileSync as writeFileSync5 } from "node:fs";
|
|
16655
18225
|
import { homedir as homedir3 } from "node:os";
|
|
16656
|
-
import { basename as basename3, dirname as dirname7, join as
|
|
18226
|
+
import { basename as basename3, dirname as dirname7, join as join17 } from "node:path";
|
|
16657
18227
|
function resolveConfigPath(configType) {
|
|
16658
18228
|
if (configType === "codex") {
|
|
16659
18229
|
const testHome = process.env.CODER_STUDIO_CODEX_HOME;
|
|
16660
18230
|
if (testHome && testHome.trim()) {
|
|
16661
|
-
return
|
|
18231
|
+
return join17(testHome, "config.toml");
|
|
16662
18232
|
}
|
|
16663
18233
|
const codexHome = process.env.CODEX_HOME;
|
|
16664
18234
|
if (codexHome && codexHome.trim()) {
|
|
16665
|
-
return
|
|
18235
|
+
return join17(codexHome, "config.toml");
|
|
16666
18236
|
}
|
|
16667
|
-
return
|
|
18237
|
+
return join17(homedir3(), ".codex", "config.toml");
|
|
16668
18238
|
}
|
|
16669
18239
|
if (configType === "claude") {
|
|
16670
18240
|
const testHome = process.env.CODER_STUDIO_CLAUDE_HOME;
|
|
16671
18241
|
if (testHome && testHome.trim()) {
|
|
16672
|
-
return
|
|
18242
|
+
return join17(testHome, "settings.json");
|
|
16673
18243
|
}
|
|
16674
|
-
return
|
|
18244
|
+
return join17(homedir3(), ".claude", "settings.json");
|
|
16675
18245
|
}
|
|
16676
18246
|
throw new Error(`Unknown config type: ${configType}`);
|
|
16677
18247
|
}
|
|
@@ -16716,7 +18286,7 @@ function createBackup(filePath) {
|
|
|
16716
18286
|
const base = basename3(filePath, `.${ext}`);
|
|
16717
18287
|
const dir = dirname7(filePath);
|
|
16718
18288
|
const ts = formatTimestamp(/* @__PURE__ */ new Date());
|
|
16719
|
-
const backupPath =
|
|
18289
|
+
const backupPath = join17(dir, `${base}.bak.${ts}.${ext}`);
|
|
16720
18290
|
writeFileSync5(backupPath, original, "utf-8");
|
|
16721
18291
|
return backupPath;
|
|
16722
18292
|
}
|
|
@@ -16731,7 +18301,7 @@ var init_config_io = __esm({
|
|
|
16731
18301
|
});
|
|
16732
18302
|
|
|
16733
18303
|
// packages/server/src/commands/settings.ts
|
|
16734
|
-
import { z as
|
|
18304
|
+
import { z as z20 } from "zod";
|
|
16735
18305
|
function flattenSettings(obj, prefix = "") {
|
|
16736
18306
|
const result = {};
|
|
16737
18307
|
for (const [key, value] of Object.entries(obj)) {
|
|
@@ -16782,13 +18352,13 @@ var init_settings2 = __esm({
|
|
|
16782
18352
|
init_provider_config();
|
|
16783
18353
|
init_settings();
|
|
16784
18354
|
init_dispatch();
|
|
16785
|
-
PersonalizationOverridesSchema =
|
|
16786
|
-
backgroundAssetId:
|
|
16787
|
-
backgroundDimness:
|
|
16788
|
-
backgroundBlur:
|
|
16789
|
-
glassEnabled:
|
|
16790
|
-
glassIntensity:
|
|
16791
|
-
surfaceOpacity:
|
|
18355
|
+
PersonalizationOverridesSchema = z20.object({
|
|
18356
|
+
backgroundAssetId: z20.string().min(1).nullable().optional(),
|
|
18357
|
+
backgroundDimness: z20.number().int().min(0).max(100).optional(),
|
|
18358
|
+
backgroundBlur: z20.number().int().min(0).max(40).optional(),
|
|
18359
|
+
glassEnabled: z20.boolean().optional(),
|
|
18360
|
+
glassIntensity: z20.number().int().min(0).max(100).optional(),
|
|
18361
|
+
surfaceOpacity: z20.number().int().min(0).max(100).optional()
|
|
16792
18362
|
});
|
|
16793
18363
|
PERSONALIZATION_OVERRIDE_BRANCHES = ["desktop", "mobile"];
|
|
16794
18364
|
PERSONALIZATION_OVERRIDE_FIELDS = [
|
|
@@ -16799,59 +18369,59 @@ var init_settings2 = __esm({
|
|
|
16799
18369
|
"glassIntensity",
|
|
16800
18370
|
"surfaceOpacity"
|
|
16801
18371
|
];
|
|
16802
|
-
SettingsSchema =
|
|
16803
|
-
defaultProviderId:
|
|
16804
|
-
notifications:
|
|
16805
|
-
enabled:
|
|
16806
|
-
soundEnabled:
|
|
18372
|
+
SettingsSchema = z20.object({
|
|
18373
|
+
defaultProviderId: z20.string().optional(),
|
|
18374
|
+
notifications: z20.object({
|
|
18375
|
+
enabled: z20.boolean().optional(),
|
|
18376
|
+
soundEnabled: z20.boolean().optional(),
|
|
16807
18377
|
// Legacy field — accepted for backward compat with older clients but
|
|
16808
18378
|
// no longer surfaced in the UI. The web client now picks the channel
|
|
16809
18379
|
// automatically based on workspace focus + page visibility.
|
|
16810
|
-
onlyWhenBackgrounded:
|
|
18380
|
+
onlyWhenBackgrounded: z20.boolean().optional()
|
|
16811
18381
|
}).optional(),
|
|
16812
|
-
supervisor:
|
|
16813
|
-
evaluationTimeoutSec:
|
|
16814
|
-
retryEnabled:
|
|
16815
|
-
retryMaxCount:
|
|
16816
|
-
retryDelaySec:
|
|
16817
|
-
retryOnTimeout:
|
|
16818
|
-
retryOnEvaluatorError:
|
|
18382
|
+
supervisor: z20.object({
|
|
18383
|
+
evaluationTimeoutSec: z20.number().int().min(1).max(MAX_SUPERVISOR_EVALUATION_TIMEOUT_SEC).default(DEFAULT_SUPERVISOR_EVALUATION_TIMEOUT_SEC).optional(),
|
|
18384
|
+
retryEnabled: z20.boolean().optional(),
|
|
18385
|
+
retryMaxCount: z20.number().int().min(0).max(MAX_SUPERVISOR_RETRY_MAX_COUNT).optional(),
|
|
18386
|
+
retryDelaySec: z20.number().int().min(1).max(MAX_SUPERVISOR_RETRY_DELAY_SEC).optional(),
|
|
18387
|
+
retryOnTimeout: z20.boolean().optional(),
|
|
18388
|
+
retryOnEvaluatorError: z20.boolean().optional()
|
|
16819
18389
|
}).optional(),
|
|
16820
|
-
appearance:
|
|
16821
|
-
theme:
|
|
16822
|
-
themeId:
|
|
16823
|
-
terminalRenderer:
|
|
16824
|
-
terminalCopyOnSelect:
|
|
16825
|
-
terminalFontSize:
|
|
16826
|
-
desktopTerminalFontSize:
|
|
16827
|
-
mobileTerminalFontSize:
|
|
16828
|
-
locale:
|
|
16829
|
-
personalization:
|
|
16830
|
-
version:
|
|
16831
|
-
common:
|
|
16832
|
-
backgroundMode:
|
|
16833
|
-
backgroundAssetId:
|
|
16834
|
-
backgroundFit:
|
|
16835
|
-
backgroundDimness:
|
|
16836
|
-
backgroundBlur:
|
|
16837
|
-
glassEnabled:
|
|
16838
|
-
glassIntensity:
|
|
16839
|
-
surfaceOpacity:
|
|
18390
|
+
appearance: z20.object({
|
|
18391
|
+
theme: z20.enum(["dark", "light"]).optional(),
|
|
18392
|
+
themeId: z20.string().optional(),
|
|
18393
|
+
terminalRenderer: z20.enum(["standard", "compatibility"]).optional(),
|
|
18394
|
+
terminalCopyOnSelect: z20.boolean().optional(),
|
|
18395
|
+
terminalFontSize: z20.number().int().min(10).max(18).optional(),
|
|
18396
|
+
desktopTerminalFontSize: z20.number().int().min(10).max(18).optional(),
|
|
18397
|
+
mobileTerminalFontSize: z20.number().int().min(10).max(18).optional(),
|
|
18398
|
+
locale: z20.enum(["zh", "en"]).optional(),
|
|
18399
|
+
personalization: z20.object({
|
|
18400
|
+
version: z20.literal(1).optional(),
|
|
18401
|
+
common: z20.object({
|
|
18402
|
+
backgroundMode: z20.enum(["none", "image"]).optional(),
|
|
18403
|
+
backgroundAssetId: z20.string().min(1).nullable().optional(),
|
|
18404
|
+
backgroundFit: z20.enum(["cover", "contain"]).optional(),
|
|
18405
|
+
backgroundDimness: z20.number().int().min(0).max(100).optional(),
|
|
18406
|
+
backgroundBlur: z20.number().int().min(0).max(40).optional(),
|
|
18407
|
+
glassEnabled: z20.boolean().optional(),
|
|
18408
|
+
glassIntensity: z20.number().int().min(0).max(100).optional(),
|
|
18409
|
+
surfaceOpacity: z20.number().int().min(0).max(100).optional()
|
|
16840
18410
|
}).optional(),
|
|
16841
18411
|
desktop: PersonalizationOverridesSchema.optional(),
|
|
16842
18412
|
mobile: PersonalizationOverridesSchema.optional()
|
|
16843
18413
|
}).optional()
|
|
16844
18414
|
}).optional(),
|
|
16845
|
-
lsp:
|
|
16846
|
-
mode:
|
|
18415
|
+
lsp: z20.object({
|
|
18416
|
+
mode: z20.enum(["auto", "off"]).optional()
|
|
16847
18417
|
}).optional(),
|
|
16848
|
-
updates:
|
|
16849
|
-
autoCheckEnabled:
|
|
16850
|
-
checkIntervalSec:
|
|
18418
|
+
updates: z20.object({
|
|
18419
|
+
autoCheckEnabled: z20.boolean().optional(),
|
|
18420
|
+
checkIntervalSec: z20.number().int().refine(isUpdateCheckIntervalSec).optional()
|
|
16851
18421
|
}).optional(),
|
|
16852
18422
|
providers: ProviderSettingsSchema.optional()
|
|
16853
18423
|
});
|
|
16854
|
-
registerCommand("settings.get",
|
|
18424
|
+
registerCommand("settings.get", z20.object({}), async (_args, ctx) => {
|
|
16855
18425
|
const settings = {};
|
|
16856
18426
|
for (const [key, value] of Object.entries(ctx.settingsRepo.getAll())) {
|
|
16857
18427
|
if (key.startsWith("providers.")) {
|
|
@@ -16903,7 +18473,7 @@ var init_settings2 = __esm({
|
|
|
16903
18473
|
});
|
|
16904
18474
|
registerCommand(
|
|
16905
18475
|
"settings.update",
|
|
16906
|
-
|
|
18476
|
+
z20.object({
|
|
16907
18477
|
settings: SettingsSchema
|
|
16908
18478
|
}),
|
|
16909
18479
|
async (args, ctx) => {
|
|
@@ -16936,10 +18506,10 @@ var init_settings2 = __esm({
|
|
|
16936
18506
|
);
|
|
16937
18507
|
registerCommand(
|
|
16938
18508
|
"settings.previewCommand",
|
|
16939
|
-
|
|
16940
|
-
providerId:
|
|
18509
|
+
z20.object({
|
|
18510
|
+
providerId: z20.string(),
|
|
16941
18511
|
config: ProviderLaunchConfigInputSchema,
|
|
16942
|
-
workspacePath:
|
|
18512
|
+
workspacePath: z20.string().optional()
|
|
16943
18513
|
}),
|
|
16944
18514
|
async (args, ctx) => {
|
|
16945
18515
|
const provider = ctx.providerRegistry.find((item) => item.id === args.providerId);
|
|
@@ -16960,8 +18530,8 @@ var init_settings2 = __esm({
|
|
|
16960
18530
|
);
|
|
16961
18531
|
registerCommand(
|
|
16962
18532
|
"settings.readConfigFile",
|
|
16963
|
-
|
|
16964
|
-
configType:
|
|
18533
|
+
z20.object({
|
|
18534
|
+
configType: z20.enum(["codex", "claude"])
|
|
16965
18535
|
}),
|
|
16966
18536
|
async (args) => {
|
|
16967
18537
|
const result = readConfigFile(args.configType);
|
|
@@ -16970,9 +18540,9 @@ var init_settings2 = __esm({
|
|
|
16970
18540
|
);
|
|
16971
18541
|
registerCommand(
|
|
16972
18542
|
"settings.writeConfigFile",
|
|
16973
|
-
|
|
16974
|
-
configType:
|
|
16975
|
-
content:
|
|
18543
|
+
z20.object({
|
|
18544
|
+
configType: z20.enum(["codex", "claude"]),
|
|
18545
|
+
content: z20.string()
|
|
16976
18546
|
}),
|
|
16977
18547
|
async (args) => {
|
|
16978
18548
|
const result = writeConfigFile(args.configType, args.content);
|
|
@@ -16983,7 +18553,7 @@ var init_settings2 = __esm({
|
|
|
16983
18553
|
});
|
|
16984
18554
|
|
|
16985
18555
|
// packages/server/src/commands/diagnostics.ts
|
|
16986
|
-
import { z as
|
|
18556
|
+
import { z as z21 } from "zod";
|
|
16987
18557
|
function isLoopbackHost(host) {
|
|
16988
18558
|
return host === void 0 || host === "localhost" || host === "127.0.0.1" || host === "::1" || host === "0.0.0.0";
|
|
16989
18559
|
}
|
|
@@ -17353,11 +18923,11 @@ var init_diagnostics2 = __esm({
|
|
|
17353
18923
|
init_runtime_status();
|
|
17354
18924
|
init_validator();
|
|
17355
18925
|
init_dispatch();
|
|
17356
|
-
DiagnosticsRequestSchema =
|
|
17357
|
-
context:
|
|
17358
|
-
workspaceId:
|
|
17359
|
-
workspacePath:
|
|
17360
|
-
providerId:
|
|
18926
|
+
DiagnosticsRequestSchema = z21.object({
|
|
18927
|
+
context: z21.enum(["workspace_open", "session_start", "mobile_continue", "manual_check"]),
|
|
18928
|
+
workspaceId: z21.string().optional(),
|
|
18929
|
+
workspacePath: z21.string().optional(),
|
|
18930
|
+
providerId: z21.string().optional()
|
|
17361
18931
|
});
|
|
17362
18932
|
registerCommand("diagnostics.get", DiagnosticsRequestSchema, async (args, ctx) => {
|
|
17363
18933
|
return buildDiagnostics(args, ctx);
|
|
@@ -17369,19 +18939,23 @@ var init_diagnostics2 = __esm({
|
|
|
17369
18939
|
});
|
|
17370
18940
|
|
|
17371
18941
|
// packages/server/src/commands/provider.ts
|
|
17372
|
-
import { z as
|
|
18942
|
+
import { z as z22 } from "zod";
|
|
17373
18943
|
var init_provider = __esm({
|
|
17374
18944
|
"packages/server/src/commands/provider.ts"() {
|
|
17375
18945
|
"use strict";
|
|
18946
|
+
init_src();
|
|
17376
18947
|
init_runtime_status();
|
|
17377
18948
|
init_dispatch();
|
|
17378
|
-
registerCommand("provider.
|
|
18949
|
+
registerCommand("provider.list", z22.object({}), async (_args, ctx) => {
|
|
18950
|
+
return ctx.providerRegistry.map((provider) => toProviderListItem(provider));
|
|
18951
|
+
});
|
|
18952
|
+
registerCommand("provider.runtimeStatus", z22.object({}), async (_args, ctx) => {
|
|
17379
18953
|
return buildProviderRuntimeStatus(ctx.providerRegistry, ctx.providerRuntimeDeps);
|
|
17380
18954
|
});
|
|
17381
18955
|
registerCommand(
|
|
17382
18956
|
"provider.install.start",
|
|
17383
|
-
|
|
17384
|
-
providerId:
|
|
18957
|
+
z22.object({
|
|
18958
|
+
providerId: z22.string()
|
|
17385
18959
|
}),
|
|
17386
18960
|
async (args, ctx) => {
|
|
17387
18961
|
if (!ctx.providerInstallMgr) {
|
|
@@ -17395,8 +18969,8 @@ var init_provider = __esm({
|
|
|
17395
18969
|
);
|
|
17396
18970
|
registerCommand(
|
|
17397
18971
|
"provider.install.get",
|
|
17398
|
-
|
|
17399
|
-
jobId:
|
|
18972
|
+
z22.object({
|
|
18973
|
+
jobId: z22.string()
|
|
17400
18974
|
}),
|
|
17401
18975
|
async (args, ctx) => {
|
|
17402
18976
|
if (!ctx.providerInstallMgr) {
|
|
@@ -17418,45 +18992,147 @@ var init_provider = __esm({
|
|
|
17418
18992
|
}
|
|
17419
18993
|
});
|
|
17420
18994
|
|
|
18995
|
+
// packages/server/src/commands/custom-provider.ts
|
|
18996
|
+
import { z as z23 } from "zod";
|
|
18997
|
+
function requireCustomProviderSupport(ctx) {
|
|
18998
|
+
if (!ctx.customProviderRepo || !ctx.setProviderRegistry) {
|
|
18999
|
+
throw {
|
|
19000
|
+
code: "custom_provider_unavailable",
|
|
19001
|
+
message: "Custom provider runtime is not configured"
|
|
19002
|
+
};
|
|
19003
|
+
}
|
|
19004
|
+
}
|
|
19005
|
+
function materializeConfig(input2, previous) {
|
|
19006
|
+
const now = Date.now();
|
|
19007
|
+
return {
|
|
19008
|
+
...input2,
|
|
19009
|
+
startupPrompt: input2.startupPrompt?.trim() || void 0,
|
|
19010
|
+
createdAt: previous?.createdAt ?? now,
|
|
19011
|
+
updatedAt: now
|
|
19012
|
+
};
|
|
19013
|
+
}
|
|
19014
|
+
var CapabilitySchema, BaseCustomProviderInputSchema;
|
|
19015
|
+
var init_custom_provider2 = __esm({
|
|
19016
|
+
"packages/server/src/commands/custom-provider.ts"() {
|
|
19017
|
+
"use strict";
|
|
19018
|
+
init_src();
|
|
19019
|
+
init_custom_provider();
|
|
19020
|
+
init_dispatch();
|
|
19021
|
+
CapabilitySchema = z23.object({
|
|
19022
|
+
key: z23.enum([
|
|
19023
|
+
"interactive_session",
|
|
19024
|
+
"supervisor_eval",
|
|
19025
|
+
"idle_detection",
|
|
19026
|
+
"context_attach",
|
|
19027
|
+
"review"
|
|
19028
|
+
]),
|
|
19029
|
+
supported: z23.boolean(),
|
|
19030
|
+
label: z23.string().min(1)
|
|
19031
|
+
});
|
|
19032
|
+
BaseCustomProviderInputSchema = z23.object({
|
|
19033
|
+
id: z23.string().trim().min(1).regex(/^[a-z0-9][a-z0-9-_]*$/),
|
|
19034
|
+
displayName: z23.string().trim().min(1),
|
|
19035
|
+
command: z23.string().trim().min(1),
|
|
19036
|
+
args: z23.array(z23.string()),
|
|
19037
|
+
env: z23.record(z23.string(), z23.string()),
|
|
19038
|
+
cwdMode: z23.literal("workspace_root"),
|
|
19039
|
+
sessionMode: z23.literal("interactive"),
|
|
19040
|
+
startupPrompt: z23.string().optional(),
|
|
19041
|
+
capabilities: z23.array(CapabilitySchema).min(1)
|
|
19042
|
+
});
|
|
19043
|
+
registerCommand("customProvider.list", z23.object({}), async (_args, ctx) => {
|
|
19044
|
+
requireCustomProviderSupport(ctx);
|
|
19045
|
+
return ctx.customProviderRepo.list().map((config) => toProviderListItem(buildCustomProviderDefinition(config)));
|
|
19046
|
+
});
|
|
19047
|
+
registerCommand("customProvider.create", BaseCustomProviderInputSchema, async (args, ctx) => {
|
|
19048
|
+
requireCustomProviderSupport(ctx);
|
|
19049
|
+
if (ctx.providerRegistry.some((provider) => provider.id === args.id)) {
|
|
19050
|
+
throw {
|
|
19051
|
+
code: "custom_provider_exists",
|
|
19052
|
+
message: `Provider already exists: ${args.id}`
|
|
19053
|
+
};
|
|
19054
|
+
}
|
|
19055
|
+
const config = materializeConfig(args);
|
|
19056
|
+
const saved = ctx.customProviderRepo.set(config);
|
|
19057
|
+
const definition = buildCustomProviderDefinition(saved);
|
|
19058
|
+
ctx.setProviderRegistry(upsertProviderDefinition(ctx.providerRegistry, definition));
|
|
19059
|
+
return toProviderListItem(definition);
|
|
19060
|
+
});
|
|
19061
|
+
registerCommand("customProvider.update", BaseCustomProviderInputSchema, async (args, ctx) => {
|
|
19062
|
+
requireCustomProviderSupport(ctx);
|
|
19063
|
+
const existing = ctx.customProviderRepo.get(args.id);
|
|
19064
|
+
if (!existing) {
|
|
19065
|
+
throw {
|
|
19066
|
+
code: "custom_provider_not_found",
|
|
19067
|
+
message: `Custom provider not found: ${args.id}`
|
|
19068
|
+
};
|
|
19069
|
+
}
|
|
19070
|
+
const saved = ctx.customProviderRepo.set(materializeConfig(args, existing));
|
|
19071
|
+
const definition = buildCustomProviderDefinition(saved);
|
|
19072
|
+
ctx.setProviderRegistry(upsertProviderDefinition(ctx.providerRegistry, definition));
|
|
19073
|
+
return toProviderListItem(definition);
|
|
19074
|
+
});
|
|
19075
|
+
registerCommand(
|
|
19076
|
+
"customProvider.delete",
|
|
19077
|
+
z23.object({
|
|
19078
|
+
id: z23.string().trim().min(1)
|
|
19079
|
+
}),
|
|
19080
|
+
async (args, ctx) => {
|
|
19081
|
+
requireCustomProviderSupport(ctx);
|
|
19082
|
+
const existing = ctx.customProviderRepo.get(args.id);
|
|
19083
|
+
if (!existing) {
|
|
19084
|
+
throw {
|
|
19085
|
+
code: "custom_provider_not_found",
|
|
19086
|
+
message: `Custom provider not found: ${args.id}`
|
|
19087
|
+
};
|
|
19088
|
+
}
|
|
19089
|
+
ctx.customProviderRepo.delete(args.id);
|
|
19090
|
+
ctx.setProviderRegistry(removeProviderDefinition(ctx.providerRegistry, args.id));
|
|
19091
|
+
return { deleted: true, id: args.id };
|
|
19092
|
+
}
|
|
19093
|
+
);
|
|
19094
|
+
}
|
|
19095
|
+
});
|
|
19096
|
+
|
|
17421
19097
|
// packages/server/src/commands/supervisor.ts
|
|
17422
|
-
import { z as
|
|
19098
|
+
import { z as z24 } from "zod";
|
|
17423
19099
|
var supervisorObjectiveSchema, createSupervisorSchema, updateSupervisorSchema, sessionIdSchema, workspaceIdSchema, supervisorIdSchema, restoreSupervisorSchema;
|
|
17424
19100
|
var init_supervisor2 = __esm({
|
|
17425
19101
|
"packages/server/src/commands/supervisor.ts"() {
|
|
17426
19102
|
"use strict";
|
|
17427
19103
|
init_dispatch();
|
|
17428
|
-
supervisorObjectiveSchema =
|
|
17429
|
-
createSupervisorSchema =
|
|
17430
|
-
sessionId:
|
|
17431
|
-
workspaceId:
|
|
19104
|
+
supervisorObjectiveSchema = z24.string().trim().min(1).max(4e3);
|
|
19105
|
+
createSupervisorSchema = z24.object({
|
|
19106
|
+
sessionId: z24.string(),
|
|
19107
|
+
workspaceId: z24.string(),
|
|
17432
19108
|
objective: supervisorObjectiveSchema,
|
|
17433
|
-
evaluatorProviderId:
|
|
17434
|
-
evaluatorModel:
|
|
17435
|
-
maxSupervisionCount:
|
|
17436
|
-
scheduledAt:
|
|
19109
|
+
evaluatorProviderId: z24.string(),
|
|
19110
|
+
evaluatorModel: z24.string().trim().min(1).max(200).optional(),
|
|
19111
|
+
maxSupervisionCount: z24.number().int().min(0).max(Number.MAX_SAFE_INTEGER).optional(),
|
|
19112
|
+
scheduledAt: z24.number().int().min(0).max(Number.MAX_SAFE_INTEGER).optional()
|
|
17437
19113
|
}).strict();
|
|
17438
|
-
updateSupervisorSchema =
|
|
17439
|
-
id:
|
|
19114
|
+
updateSupervisorSchema = z24.object({
|
|
19115
|
+
id: z24.string(),
|
|
17440
19116
|
objective: supervisorObjectiveSchema.optional(),
|
|
17441
|
-
evaluatorProviderId:
|
|
17442
|
-
evaluatorModel:
|
|
17443
|
-
maxSupervisionCount:
|
|
17444
|
-
scheduledAt:
|
|
19117
|
+
evaluatorProviderId: z24.string().optional(),
|
|
19118
|
+
evaluatorModel: z24.string().trim().min(1).max(200).nullable().optional(),
|
|
19119
|
+
maxSupervisionCount: z24.number().int().min(0).max(Number.MAX_SAFE_INTEGER).optional(),
|
|
19120
|
+
scheduledAt: z24.number().int().min(0).max(Number.MAX_SAFE_INTEGER).nullable().optional()
|
|
17445
19121
|
}).strict().refine(
|
|
17446
19122
|
(input2) => input2.objective !== void 0 || input2.evaluatorProviderId !== void 0 || input2.evaluatorModel !== void 0 || input2.maxSupervisionCount !== void 0 || input2.scheduledAt !== void 0,
|
|
17447
19123
|
"at least one supervisor field is required"
|
|
17448
19124
|
);
|
|
17449
|
-
sessionIdSchema =
|
|
17450
|
-
workspaceIdSchema =
|
|
17451
|
-
supervisorIdSchema =
|
|
17452
|
-
restoreSupervisorSchema =
|
|
17453
|
-
sessionId:
|
|
17454
|
-
workspaceId:
|
|
17455
|
-
sourceTargetId:
|
|
17456
|
-
evaluatorProviderId:
|
|
17457
|
-
evaluatorModel:
|
|
17458
|
-
maxSupervisionCount:
|
|
17459
|
-
scheduledAt:
|
|
19125
|
+
sessionIdSchema = z24.object({ sessionId: z24.string() });
|
|
19126
|
+
workspaceIdSchema = z24.object({ workspaceId: z24.string() });
|
|
19127
|
+
supervisorIdSchema = z24.object({ id: z24.string() });
|
|
19128
|
+
restoreSupervisorSchema = z24.object({
|
|
19129
|
+
sessionId: z24.string(),
|
|
19130
|
+
workspaceId: z24.string(),
|
|
19131
|
+
sourceTargetId: z24.string(),
|
|
19132
|
+
evaluatorProviderId: z24.string(),
|
|
19133
|
+
evaluatorModel: z24.string().trim().min(1).max(200).optional(),
|
|
19134
|
+
maxSupervisionCount: z24.number().int().min(0).max(Number.MAX_SAFE_INTEGER).optional(),
|
|
19135
|
+
scheduledAt: z24.number().int().min(0).max(Number.MAX_SAFE_INTEGER).optional()
|
|
17460
19136
|
}).strict();
|
|
17461
19137
|
registerCommand("supervisor.create", createSupervisorSchema, async (args, ctx) => {
|
|
17462
19138
|
return {
|
|
@@ -17658,7 +19334,7 @@ var init_worktree = __esm({
|
|
|
17658
19334
|
|
|
17659
19335
|
// packages/server/src/commands/worktree.ts
|
|
17660
19336
|
import path13 from "node:path";
|
|
17661
|
-
import { z as
|
|
19337
|
+
import { z as z25 } from "zod";
|
|
17662
19338
|
async function findRelatedWorkspaceIds(ctx, workspacePath) {
|
|
17663
19339
|
const targetCommonDir = await getGitCommonDirPath(workspacePath);
|
|
17664
19340
|
const relatedWorkspaceIds = await Promise.all(
|
|
@@ -17691,7 +19367,7 @@ var init_worktree2 = __esm({
|
|
|
17691
19367
|
init_worktree();
|
|
17692
19368
|
init_dispatch();
|
|
17693
19369
|
init_git_events();
|
|
17694
|
-
registerCommand("worktree.list",
|
|
19370
|
+
registerCommand("worktree.list", z25.object({ workspaceId: z25.string() }), async (args, ctx) => {
|
|
17695
19371
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
17696
19372
|
if (!workspace) {
|
|
17697
19373
|
throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
|
|
@@ -17700,7 +19376,7 @@ var init_worktree2 = __esm({
|
|
|
17700
19376
|
});
|
|
17701
19377
|
registerCommand(
|
|
17702
19378
|
"worktree.status",
|
|
17703
|
-
|
|
19379
|
+
z25.object({ workspaceId: z25.string(), worktreePath: z25.string() }),
|
|
17704
19380
|
async (args, ctx) => {
|
|
17705
19381
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
17706
19382
|
if (!workspace) {
|
|
@@ -17712,10 +19388,10 @@ var init_worktree2 = __esm({
|
|
|
17712
19388
|
);
|
|
17713
19389
|
registerCommand(
|
|
17714
19390
|
"worktree.diff",
|
|
17715
|
-
|
|
17716
|
-
workspaceId:
|
|
17717
|
-
worktreePath:
|
|
17718
|
-
staged:
|
|
19391
|
+
z25.object({
|
|
19392
|
+
workspaceId: z25.string(),
|
|
19393
|
+
worktreePath: z25.string(),
|
|
19394
|
+
staged: z25.boolean().optional().default(false)
|
|
17719
19395
|
}),
|
|
17720
19396
|
async (args, ctx) => {
|
|
17721
19397
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -17728,7 +19404,7 @@ var init_worktree2 = __esm({
|
|
|
17728
19404
|
);
|
|
17729
19405
|
registerCommand(
|
|
17730
19406
|
"worktree.tree",
|
|
17731
|
-
|
|
19407
|
+
z25.object({ workspaceId: z25.string(), worktreePath: z25.string() }),
|
|
17732
19408
|
async (args, ctx) => {
|
|
17733
19409
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
17734
19410
|
if (!workspace) {
|
|
@@ -17740,10 +19416,10 @@ var init_worktree2 = __esm({
|
|
|
17740
19416
|
);
|
|
17741
19417
|
registerCommand(
|
|
17742
19418
|
"worktree.create",
|
|
17743
|
-
|
|
17744
|
-
workspaceId:
|
|
17745
|
-
branch:
|
|
17746
|
-
path:
|
|
19419
|
+
z25.object({
|
|
19420
|
+
workspaceId: z25.string(),
|
|
19421
|
+
branch: z25.string(),
|
|
19422
|
+
path: z25.string()
|
|
17747
19423
|
}),
|
|
17748
19424
|
async (args, ctx) => {
|
|
17749
19425
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -17758,10 +19434,10 @@ var init_worktree2 = __esm({
|
|
|
17758
19434
|
);
|
|
17759
19435
|
registerCommand(
|
|
17760
19436
|
"worktree.remove",
|
|
17761
|
-
|
|
17762
|
-
workspaceId:
|
|
17763
|
-
worktreePath:
|
|
17764
|
-
force:
|
|
19437
|
+
z25.object({
|
|
19438
|
+
workspaceId: z25.string(),
|
|
19439
|
+
worktreePath: z25.string(),
|
|
19440
|
+
force: z25.boolean().optional().default(false)
|
|
17765
19441
|
}),
|
|
17766
19442
|
async (args, ctx) => {
|
|
17767
19443
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -17785,7 +19461,7 @@ var init_worktree2 = __esm({
|
|
|
17785
19461
|
});
|
|
17786
19462
|
|
|
17787
19463
|
// packages/server/src/commands/fencing.ts
|
|
17788
|
-
import { z as
|
|
19464
|
+
import { z as z26 } from "zod";
|
|
17789
19465
|
function createMockFencingRequest() {
|
|
17790
19466
|
return {
|
|
17791
19467
|
ip: "127.0.0.1",
|
|
@@ -17798,9 +19474,9 @@ var init_fencing2 = __esm({
|
|
|
17798
19474
|
init_dispatch();
|
|
17799
19475
|
registerCommand(
|
|
17800
19476
|
"fencing.request",
|
|
17801
|
-
|
|
17802
|
-
workspaceId:
|
|
17803
|
-
tabId:
|
|
19477
|
+
z26.object({
|
|
19478
|
+
workspaceId: z26.string(),
|
|
19479
|
+
tabId: z26.string()
|
|
17804
19480
|
}),
|
|
17805
19481
|
async (args, ctx, clientId) => {
|
|
17806
19482
|
return ctx.fencingMgr.requestControl(
|
|
@@ -17813,7 +19489,7 @@ var init_fencing2 = __esm({
|
|
|
17813
19489
|
);
|
|
17814
19490
|
registerCommand(
|
|
17815
19491
|
"fencing.heartbeat",
|
|
17816
|
-
|
|
19492
|
+
z26.object({ workspaceId: z26.string() }),
|
|
17817
19493
|
async (args, ctx, clientId) => {
|
|
17818
19494
|
const success = ctx.fencingMgr.heartbeat(args.workspaceId, clientId);
|
|
17819
19495
|
return { success };
|
|
@@ -17821,13 +19497,13 @@ var init_fencing2 = __esm({
|
|
|
17821
19497
|
);
|
|
17822
19498
|
registerCommand(
|
|
17823
19499
|
"fencing.release",
|
|
17824
|
-
|
|
19500
|
+
z26.object({ workspaceId: z26.string() }),
|
|
17825
19501
|
async (args, ctx, clientId) => {
|
|
17826
19502
|
ctx.fencingMgr.release(args.workspaceId, clientId);
|
|
17827
19503
|
return {};
|
|
17828
19504
|
}
|
|
17829
19505
|
);
|
|
17830
|
-
registerCommand("fencing.status",
|
|
19506
|
+
registerCommand("fencing.status", z26.object({ workspaceId: z26.string() }), async (args, ctx) => {
|
|
17831
19507
|
const controller = ctx.fencingMgr.getController(args.workspaceId);
|
|
17832
19508
|
const isUnresponsive = ctx.fencingMgr.isControllerUnresponsive(args.workspaceId);
|
|
17833
19509
|
return {
|
|
@@ -17838,9 +19514,9 @@ var init_fencing2 = __esm({
|
|
|
17838
19514
|
});
|
|
17839
19515
|
registerCommand(
|
|
17840
19516
|
"fencing.takeover",
|
|
17841
|
-
|
|
17842
|
-
workspaceId:
|
|
17843
|
-
tabId:
|
|
19517
|
+
z26.object({
|
|
19518
|
+
workspaceId: z26.string(),
|
|
19519
|
+
tabId: z26.string()
|
|
17844
19520
|
}),
|
|
17845
19521
|
async (args, ctx, clientId) => {
|
|
17846
19522
|
return ctx.fencingMgr.forceTakeover(
|
|
@@ -17878,7 +19554,7 @@ var init_runtime_status2 = __esm({
|
|
|
17878
19554
|
});
|
|
17879
19555
|
|
|
17880
19556
|
// packages/server/src/commands/lsp.ts
|
|
17881
|
-
import { z as
|
|
19557
|
+
import { z as z27 } from "zod";
|
|
17882
19558
|
var init_lsp2 = __esm({
|
|
17883
19559
|
"packages/server/src/commands/lsp.ts"() {
|
|
17884
19560
|
"use strict";
|
|
@@ -17886,16 +19562,16 @@ var init_lsp2 = __esm({
|
|
|
17886
19562
|
init_dispatch();
|
|
17887
19563
|
registerCommand(
|
|
17888
19564
|
"lsp.ensureSession",
|
|
17889
|
-
|
|
17890
|
-
workspaceId:
|
|
17891
|
-
path:
|
|
19565
|
+
z27.object({
|
|
19566
|
+
workspaceId: z27.string(),
|
|
19567
|
+
path: z27.string()
|
|
17892
19568
|
}),
|
|
17893
19569
|
async (args, ctx) => ctx.lspMgr.ensureSession(args)
|
|
17894
19570
|
);
|
|
17895
19571
|
registerCommand(
|
|
17896
19572
|
"lsp.setMode",
|
|
17897
|
-
|
|
17898
|
-
mode:
|
|
19573
|
+
z27.object({
|
|
19574
|
+
mode: z27.enum(["auto", "off"])
|
|
17899
19575
|
}),
|
|
17900
19576
|
async (args, ctx) => {
|
|
17901
19577
|
await ctx.lspMgr.setRuntimeMode(args.mode);
|
|
@@ -17904,8 +19580,8 @@ var init_lsp2 = __esm({
|
|
|
17904
19580
|
);
|
|
17905
19581
|
registerCommand(
|
|
17906
19582
|
"lsp.runtimeStatus",
|
|
17907
|
-
|
|
17908
|
-
workspaceId:
|
|
19583
|
+
z27.object({
|
|
19584
|
+
workspaceId: z27.string()
|
|
17909
19585
|
}),
|
|
17910
19586
|
async (args, ctx) => {
|
|
17911
19587
|
if (!ctx.lspToolMgr) {
|
|
@@ -17929,9 +19605,9 @@ var init_lsp2 = __esm({
|
|
|
17929
19605
|
);
|
|
17930
19606
|
registerCommand(
|
|
17931
19607
|
"lsp.install.start",
|
|
17932
|
-
|
|
17933
|
-
workspaceId:
|
|
17934
|
-
serverKind:
|
|
19608
|
+
z27.object({
|
|
19609
|
+
workspaceId: z27.string(),
|
|
19610
|
+
serverKind: z27.enum(["typescript", "python", "go", "rust"])
|
|
17935
19611
|
}),
|
|
17936
19612
|
async (args, ctx) => {
|
|
17937
19613
|
if (!ctx.lspToolInstallMgr) {
|
|
@@ -17955,8 +19631,8 @@ var init_lsp2 = __esm({
|
|
|
17955
19631
|
);
|
|
17956
19632
|
registerCommand(
|
|
17957
19633
|
"lsp.install.get",
|
|
17958
|
-
|
|
17959
|
-
jobId:
|
|
19634
|
+
z27.object({
|
|
19635
|
+
jobId: z27.string()
|
|
17960
19636
|
}),
|
|
17961
19637
|
async (args, ctx) => {
|
|
17962
19638
|
if (!ctx.lspToolInstallMgr) {
|
|
@@ -17977,86 +19653,86 @@ var init_lsp2 = __esm({
|
|
|
17977
19653
|
);
|
|
17978
19654
|
registerCommand(
|
|
17979
19655
|
"lsp.openDocument",
|
|
17980
|
-
|
|
17981
|
-
workspaceId:
|
|
17982
|
-
path:
|
|
17983
|
-
languageId:
|
|
17984
|
-
text:
|
|
19656
|
+
z27.object({
|
|
19657
|
+
workspaceId: z27.string(),
|
|
19658
|
+
path: z27.string(),
|
|
19659
|
+
languageId: z27.string(),
|
|
19660
|
+
text: z27.string()
|
|
17985
19661
|
}),
|
|
17986
19662
|
async (args, ctx) => ctx.lspMgr.openDocument(args)
|
|
17987
19663
|
);
|
|
17988
19664
|
registerCommand(
|
|
17989
19665
|
"lsp.changeDocument",
|
|
17990
|
-
|
|
17991
|
-
workspaceId:
|
|
17992
|
-
path:
|
|
17993
|
-
text:
|
|
19666
|
+
z27.object({
|
|
19667
|
+
workspaceId: z27.string(),
|
|
19668
|
+
path: z27.string(),
|
|
19669
|
+
text: z27.string()
|
|
17994
19670
|
}),
|
|
17995
19671
|
async (args, ctx) => ctx.lspMgr.changeDocument(args)
|
|
17996
19672
|
);
|
|
17997
19673
|
registerCommand(
|
|
17998
19674
|
"lsp.closeDocument",
|
|
17999
|
-
|
|
18000
|
-
workspaceId:
|
|
18001
|
-
path:
|
|
19675
|
+
z27.object({
|
|
19676
|
+
workspaceId: z27.string(),
|
|
19677
|
+
path: z27.string()
|
|
18002
19678
|
}),
|
|
18003
19679
|
async (args, ctx) => ctx.lspMgr.closeDocument(args)
|
|
18004
19680
|
);
|
|
18005
19681
|
registerCommand(
|
|
18006
19682
|
"lsp.definition",
|
|
18007
|
-
|
|
18008
|
-
workspaceId:
|
|
18009
|
-
path:
|
|
18010
|
-
line:
|
|
18011
|
-
column:
|
|
19683
|
+
z27.object({
|
|
19684
|
+
workspaceId: z27.string(),
|
|
19685
|
+
path: z27.string(),
|
|
19686
|
+
line: z27.number().int().positive(),
|
|
19687
|
+
column: z27.number().int().positive()
|
|
18012
19688
|
}),
|
|
18013
19689
|
async (args, ctx) => ctx.lspMgr.definition(args)
|
|
18014
19690
|
);
|
|
18015
19691
|
registerCommand(
|
|
18016
19692
|
"lsp.declaration",
|
|
18017
|
-
|
|
18018
|
-
workspaceId:
|
|
18019
|
-
path:
|
|
18020
|
-
line:
|
|
18021
|
-
column:
|
|
19693
|
+
z27.object({
|
|
19694
|
+
workspaceId: z27.string(),
|
|
19695
|
+
path: z27.string(),
|
|
19696
|
+
line: z27.number().int().positive(),
|
|
19697
|
+
column: z27.number().int().positive()
|
|
18022
19698
|
}),
|
|
18023
19699
|
async (args, ctx) => ctx.lspMgr.declaration(args)
|
|
18024
19700
|
);
|
|
18025
19701
|
registerCommand(
|
|
18026
19702
|
"lsp.typeDefinition",
|
|
18027
|
-
|
|
18028
|
-
workspaceId:
|
|
18029
|
-
path:
|
|
18030
|
-
line:
|
|
18031
|
-
column:
|
|
19703
|
+
z27.object({
|
|
19704
|
+
workspaceId: z27.string(),
|
|
19705
|
+
path: z27.string(),
|
|
19706
|
+
line: z27.number().int().positive(),
|
|
19707
|
+
column: z27.number().int().positive()
|
|
18032
19708
|
}),
|
|
18033
19709
|
async (args, ctx) => ctx.lspMgr.typeDefinition(args)
|
|
18034
19710
|
);
|
|
18035
19711
|
registerCommand(
|
|
18036
19712
|
"lsp.references",
|
|
18037
|
-
|
|
18038
|
-
workspaceId:
|
|
18039
|
-
path:
|
|
18040
|
-
line:
|
|
18041
|
-
column:
|
|
19713
|
+
z27.object({
|
|
19714
|
+
workspaceId: z27.string(),
|
|
19715
|
+
path: z27.string(),
|
|
19716
|
+
line: z27.number().int().positive(),
|
|
19717
|
+
column: z27.number().int().positive()
|
|
18042
19718
|
}),
|
|
18043
19719
|
async (args, ctx) => ctx.lspMgr.references(args)
|
|
18044
19720
|
);
|
|
18045
19721
|
registerCommand(
|
|
18046
19722
|
"lsp.hover",
|
|
18047
|
-
|
|
18048
|
-
workspaceId:
|
|
18049
|
-
path:
|
|
18050
|
-
line:
|
|
18051
|
-
column:
|
|
19723
|
+
z27.object({
|
|
19724
|
+
workspaceId: z27.string(),
|
|
19725
|
+
path: z27.string(),
|
|
19726
|
+
line: z27.number().int().positive(),
|
|
19727
|
+
column: z27.number().int().positive()
|
|
18052
19728
|
}),
|
|
18053
19729
|
async (args, ctx) => ctx.lspMgr.hover(args)
|
|
18054
19730
|
);
|
|
18055
19731
|
registerCommand(
|
|
18056
19732
|
"lsp.documentSymbols",
|
|
18057
|
-
|
|
18058
|
-
workspaceId:
|
|
18059
|
-
path:
|
|
19733
|
+
z27.object({
|
|
19734
|
+
workspaceId: z27.string(),
|
|
19735
|
+
path: z27.string()
|
|
18060
19736
|
}),
|
|
18061
19737
|
async (args, ctx) => ctx.lspMgr.documentSymbols(args)
|
|
18062
19738
|
);
|
|
@@ -18064,12 +19740,12 @@ var init_lsp2 = __esm({
|
|
|
18064
19740
|
});
|
|
18065
19741
|
|
|
18066
19742
|
// packages/server/src/commands/updates.ts
|
|
18067
|
-
import { z as
|
|
19743
|
+
import { z as z28 } from "zod";
|
|
18068
19744
|
var init_updates = __esm({
|
|
18069
19745
|
"packages/server/src/commands/updates.ts"() {
|
|
18070
19746
|
"use strict";
|
|
18071
19747
|
init_dispatch();
|
|
18072
|
-
registerCommand("updates.getState",
|
|
19748
|
+
registerCommand("updates.getState", z28.object({}).default({}), async (_args, ctx) => {
|
|
18073
19749
|
if (!ctx.updateService) {
|
|
18074
19750
|
throw {
|
|
18075
19751
|
code: "update_unavailable",
|
|
@@ -18078,7 +19754,7 @@ var init_updates = __esm({
|
|
|
18078
19754
|
}
|
|
18079
19755
|
return ctx.updateService.getStateView();
|
|
18080
19756
|
});
|
|
18081
|
-
registerCommand("updates.check",
|
|
19757
|
+
registerCommand("updates.check", z28.object({}).default({}), async (_args, ctx) => {
|
|
18082
19758
|
if (!ctx.updateService) {
|
|
18083
19759
|
throw {
|
|
18084
19760
|
code: "update_unavailable",
|
|
@@ -18087,7 +19763,7 @@ var init_updates = __esm({
|
|
|
18087
19763
|
}
|
|
18088
19764
|
return await ctx.updateService.checkForUpdates({ manual: true });
|
|
18089
19765
|
});
|
|
18090
|
-
registerCommand("updates.prepareInstall",
|
|
19766
|
+
registerCommand("updates.prepareInstall", z28.object({}).default({}), async (_args, ctx) => {
|
|
18091
19767
|
if (!ctx.updateService) {
|
|
18092
19768
|
throw {
|
|
18093
19769
|
code: "update_unavailable",
|
|
@@ -18098,9 +19774,9 @@ var init_updates = __esm({
|
|
|
18098
19774
|
});
|
|
18099
19775
|
registerCommand(
|
|
18100
19776
|
"updates.startInstall",
|
|
18101
|
-
|
|
18102
|
-
targetVersion:
|
|
18103
|
-
force:
|
|
19777
|
+
z28.object({
|
|
19778
|
+
targetVersion: z28.string().optional(),
|
|
19779
|
+
force: z28.boolean().optional()
|
|
18104
19780
|
}),
|
|
18105
19781
|
async (args, ctx) => {
|
|
18106
19782
|
if (!ctx.updateService) {
|
|
@@ -18125,12 +19801,17 @@ var init_commands = __esm({
|
|
|
18125
19801
|
init_connection();
|
|
18126
19802
|
init_recovery();
|
|
18127
19803
|
init_session2();
|
|
19804
|
+
init_session_metadata();
|
|
19805
|
+
init_session_review();
|
|
18128
19806
|
init_terminal();
|
|
18129
19807
|
init_file();
|
|
18130
19808
|
init_git2();
|
|
19809
|
+
init_agent_instructions();
|
|
19810
|
+
init_agent_context();
|
|
18131
19811
|
init_settings2();
|
|
18132
19812
|
init_diagnostics2();
|
|
18133
19813
|
init_provider();
|
|
19814
|
+
init_custom_provider2();
|
|
18134
19815
|
init_supervisor2();
|
|
18135
19816
|
init_worktree2();
|
|
18136
19817
|
init_fencing2();
|
|
@@ -18142,12 +19823,12 @@ var init_commands = __esm({
|
|
|
18142
19823
|
// packages/server/src/server.ts
|
|
18143
19824
|
import { mkdtempSync, rmSync as rmSync2 } from "node:fs";
|
|
18144
19825
|
import { tmpdir } from "node:os";
|
|
18145
|
-
import { join as
|
|
19826
|
+
import { join as join18 } from "node:path";
|
|
18146
19827
|
async function createServer(configOverrides) {
|
|
18147
19828
|
const config = parseServerConfig(configOverrides);
|
|
18148
19829
|
const configuredStateDir = resolveConfiguredStateDir(config);
|
|
18149
19830
|
const shouldCleanupStateRoot = configuredStateDir === IN_MEMORY_STATE_DIR;
|
|
18150
|
-
const stateRoot = shouldCleanupStateRoot ? mkdtempSync(
|
|
19831
|
+
const stateRoot = shouldCleanupStateRoot ? mkdtempSync(join18(tmpdir(), "coder-studio-state-")) : configuredStateDir;
|
|
18151
19832
|
ensureStateDir(config);
|
|
18152
19833
|
const eventBus = new EventBus();
|
|
18153
19834
|
const activationMgr = new ActivationManager();
|
|
@@ -18157,10 +19838,10 @@ async function createServer(configOverrides) {
|
|
|
18157
19838
|
let commandContext;
|
|
18158
19839
|
let lspMgr = null;
|
|
18159
19840
|
const terminalRepo = new TerminalRepo({
|
|
18160
|
-
filePath:
|
|
19841
|
+
filePath: join18(stateRoot, "state", "terminals.json")
|
|
18161
19842
|
});
|
|
18162
19843
|
const sessionRepo = new SessionRepo({
|
|
18163
|
-
filePath:
|
|
19844
|
+
filePath: join18(stateRoot, "state", "sessions.json")
|
|
18164
19845
|
});
|
|
18165
19846
|
const terminalMgr = new TerminalManager({
|
|
18166
19847
|
ptyHost: createPtyHost(),
|
|
@@ -18168,10 +19849,10 @@ async function createServer(configOverrides) {
|
|
|
18168
19849
|
db: terminalRepo
|
|
18169
19850
|
});
|
|
18170
19851
|
const settingsRepo = new SettingsRepo({
|
|
18171
|
-
filePath:
|
|
19852
|
+
filePath: join18(stateRoot, "state", "settings.json")
|
|
18172
19853
|
});
|
|
18173
19854
|
const updateStateRepo = new UpdateStateRepo({
|
|
18174
|
-
filePath:
|
|
19855
|
+
filePath: join18(stateRoot, "state", "update-state.json"),
|
|
18175
19856
|
currentVersion: config.appVersion ?? "0.0.0"
|
|
18176
19857
|
});
|
|
18177
19858
|
const autoFetch = new AutoFetchScheduler({
|
|
@@ -18204,17 +19885,27 @@ async function createServer(configOverrides) {
|
|
|
18204
19885
|
}
|
|
18205
19886
|
});
|
|
18206
19887
|
const providerConfigRepo = new ProviderConfigRepo({
|
|
18207
|
-
filePath:
|
|
19888
|
+
filePath: join18(stateRoot, "state", "provider-configs.json")
|
|
19889
|
+
});
|
|
19890
|
+
const customProviderRepo = new CustomProviderRepo({
|
|
19891
|
+
filePath: join18(stateRoot, "state", "custom-providers.json")
|
|
18208
19892
|
});
|
|
18209
19893
|
const workspaceRepo = new WorkspaceRepo({
|
|
18210
|
-
filePath:
|
|
19894
|
+
filePath: join18(stateRoot, "state", "workspaces.json")
|
|
19895
|
+
});
|
|
19896
|
+
const sessionMetadataRepo = new SessionMetadataRepo({
|
|
19897
|
+
workspaceRepo
|
|
18211
19898
|
});
|
|
19899
|
+
let activeProviderRegistry = [
|
|
19900
|
+
...providerRegistry,
|
|
19901
|
+
...customProviderRepo.list().map((config2) => buildCustomProviderDefinition(config2))
|
|
19902
|
+
];
|
|
18212
19903
|
const sessionMgr = new SessionManager({
|
|
18213
19904
|
terminalMgr,
|
|
18214
19905
|
eventBus,
|
|
18215
19906
|
db: sessionRepo,
|
|
18216
19907
|
broadcaster: wsHub,
|
|
18217
|
-
providerRegistry,
|
|
19908
|
+
providerRegistry: activeProviderRegistry,
|
|
18218
19909
|
providerConfigRepo
|
|
18219
19910
|
});
|
|
18220
19911
|
let supervisorMgr;
|
|
@@ -18225,13 +19916,15 @@ async function createServer(configOverrides) {
|
|
|
18225
19916
|
broadcaster: wsHub,
|
|
18226
19917
|
autoFetch,
|
|
18227
19918
|
teardown: async (workspaceId) => {
|
|
19919
|
+
const persistedSessions = sessionRepo.findByWorkspaceId(workspaceId);
|
|
18228
19920
|
await lspMgr?.disposeWorkspace(workspaceId);
|
|
18229
19921
|
await supervisorMgr?.deleteForWorkspace(workspaceId);
|
|
18230
19922
|
await sessionMgr.stopForWorkspace(workspaceId);
|
|
18231
19923
|
await terminalMgr.closeForWorkspace(workspaceId);
|
|
18232
19924
|
sessionMgr.deleteEndedForWorkspace(workspaceId);
|
|
18233
|
-
for (const session of
|
|
19925
|
+
for (const session of persistedSessions) {
|
|
18234
19926
|
sessionRepo.delete(session.id);
|
|
19927
|
+
sessionMetadataRepo.delete(session.id);
|
|
18235
19928
|
}
|
|
18236
19929
|
for (const terminal of terminalRepo.listByWorkspace(workspaceId)) {
|
|
18237
19930
|
terminalRepo.delete(terminal.id);
|
|
@@ -18242,13 +19935,13 @@ async function createServer(configOverrides) {
|
|
|
18242
19935
|
)
|
|
18243
19936
|
});
|
|
18244
19937
|
const authSessionRepo = new AuthSessionRepo({
|
|
18245
|
-
filePath:
|
|
19938
|
+
filePath: join18(stateRoot, "state", "auth-sessions.json")
|
|
18246
19939
|
});
|
|
18247
19940
|
const authLoginBlockRepo = new AuthLoginBlockRepo({
|
|
18248
|
-
filePath:
|
|
19941
|
+
filePath: join18(stateRoot, "state", "auth-login-blocks.json")
|
|
18249
19942
|
});
|
|
18250
19943
|
const appearanceAssetRepo = new AppearanceAssetRepo({
|
|
18251
|
-
filePath:
|
|
19944
|
+
filePath: join18(stateRoot, "state", "appearance-assets.json")
|
|
18252
19945
|
});
|
|
18253
19946
|
const app = await buildFastifyApp({
|
|
18254
19947
|
wsHub,
|
|
@@ -18299,7 +19992,7 @@ async function createServer(configOverrides) {
|
|
|
18299
19992
|
terminalMgr,
|
|
18300
19993
|
workspaceMgr,
|
|
18301
19994
|
sessionMgr,
|
|
18302
|
-
providerRegistry,
|
|
19995
|
+
providerRegistry: activeProviderRegistry,
|
|
18303
19996
|
providerConfigRepo,
|
|
18304
19997
|
settingsRepo,
|
|
18305
19998
|
supervisorRepo,
|
|
@@ -18312,7 +20005,7 @@ async function createServer(configOverrides) {
|
|
|
18312
20005
|
const providerRuntimeDeps = providerMockOverrides ? {
|
|
18313
20006
|
commandExists: providerMockOverrides.commandExists
|
|
18314
20007
|
} : {};
|
|
18315
|
-
const providerInstallMgr = new ProviderInstallManager(
|
|
20008
|
+
const providerInstallMgr = new ProviderInstallManager(activeProviderRegistry, {
|
|
18316
20009
|
...providerRuntimeDeps,
|
|
18317
20010
|
runCommand: providerMockOverrides?.runCommand ?? runCommandAsString
|
|
18318
20011
|
});
|
|
@@ -18324,7 +20017,7 @@ async function createServer(configOverrides) {
|
|
|
18324
20017
|
...config.update,
|
|
18325
20018
|
currentVersion: config.appVersion ?? "0.0.0"
|
|
18326
20019
|
},
|
|
18327
|
-
updateWorkerLogFilePath:
|
|
20020
|
+
updateWorkerLogFilePath: join18(stateRoot, "logs", "update-worker.log"),
|
|
18328
20021
|
countRunningTerminals: () => terminalMgr.getAll().filter((terminal) => terminal.alive).length,
|
|
18329
20022
|
countRunningSessions: () => sessionMgr.getAll().filter((session) => session.state === "starting" || session.state === "running").length,
|
|
18330
20023
|
countActiveSupervisors: () => supervisorMgr?.countActive() ?? 0
|
|
@@ -18338,7 +20031,7 @@ async function createServer(configOverrides) {
|
|
|
18338
20031
|
broadcaster: wsHub,
|
|
18339
20032
|
settingsRepo,
|
|
18340
20033
|
providerConfigRepo,
|
|
18341
|
-
providerRegistry,
|
|
20034
|
+
providerRegistry: activeProviderRegistry,
|
|
18342
20035
|
fencingMgr,
|
|
18343
20036
|
supervisorMgr,
|
|
18344
20037
|
autoFetch,
|
|
@@ -18349,7 +20042,16 @@ async function createServer(configOverrides) {
|
|
|
18349
20042
|
lspMgr,
|
|
18350
20043
|
lspToolMgr,
|
|
18351
20044
|
lspToolInstallMgr,
|
|
18352
|
-
updateService
|
|
20045
|
+
updateService,
|
|
20046
|
+
customProviderRepo,
|
|
20047
|
+
sessionMetadataRepo,
|
|
20048
|
+
setProviderRegistry: (providers) => {
|
|
20049
|
+
activeProviderRegistry = providers;
|
|
20050
|
+
commandContext.providerRegistry = providers;
|
|
20051
|
+
providerInstallMgr.setProviders(providers);
|
|
20052
|
+
sessionMgr.setProviderRegistry(providers);
|
|
20053
|
+
supervisorMgr?.setProviderRegistry(providers);
|
|
20054
|
+
}
|
|
18353
20055
|
};
|
|
18354
20056
|
wsHub.setCommandContext(commandContext);
|
|
18355
20057
|
await app.listen({
|
|
@@ -18433,13 +20135,16 @@ var init_server = __esm({
|
|
|
18433
20135
|
init_manifest_store();
|
|
18434
20136
|
init_tool_root();
|
|
18435
20137
|
init_command_runner();
|
|
20138
|
+
init_custom_provider();
|
|
18436
20139
|
init_e2e_provider_mock();
|
|
18437
20140
|
init_install_manager2();
|
|
18438
20141
|
init_manager3();
|
|
18439
20142
|
init_appearance_asset_repo();
|
|
18440
20143
|
init_auth_login_block_repo();
|
|
18441
20144
|
init_auth_session_repo();
|
|
20145
|
+
init_custom_provider_repo();
|
|
18442
20146
|
init_provider_config_repo();
|
|
20147
|
+
init_session_metadata_repo();
|
|
18443
20148
|
init_session_repo();
|
|
18444
20149
|
init_settings_repo();
|
|
18445
20150
|
init_supervisor_repo();
|
|
@@ -18482,7 +20187,9 @@ var init_storage = __esm({
|
|
|
18482
20187
|
"use strict";
|
|
18483
20188
|
init_auth_login_block_repo();
|
|
18484
20189
|
init_auth_session_repo();
|
|
20190
|
+
init_custom_provider_repo();
|
|
18485
20191
|
init_provider_config_repo();
|
|
20192
|
+
init_session_metadata_repo();
|
|
18486
20193
|
init_session_repo();
|
|
18487
20194
|
init_settings_repo();
|
|
18488
20195
|
init_supervisor_repo();
|
|
@@ -18510,10 +20217,12 @@ __export(src_exports, {
|
|
|
18510
20217
|
ActiveTerminal: () => ActiveTerminal,
|
|
18511
20218
|
AuthLoginBlockRepo: () => AuthLoginBlockRepo,
|
|
18512
20219
|
AuthSessionRepo: () => AuthSessionRepo,
|
|
20220
|
+
CustomProviderRepo: () => CustomProviderRepo,
|
|
18513
20221
|
EventBus: () => EventBus,
|
|
18514
20222
|
NodePtyHost: () => NodePtyHost,
|
|
18515
20223
|
ProviderConfigRepo: () => ProviderConfigRepo,
|
|
18516
20224
|
RingBuffer: () => RingBuffer,
|
|
20225
|
+
SessionMetadataRepo: () => SessionMetadataRepo,
|
|
18517
20226
|
SessionRepo: () => SessionRepo,
|
|
18518
20227
|
SettingsRepo: () => SettingsRepo,
|
|
18519
20228
|
SupervisorRepo: () => SupervisorRepo,
|
|
@@ -18548,20 +20257,20 @@ var init_src4 = __esm({
|
|
|
18548
20257
|
|
|
18549
20258
|
// packages/cli/src/cli.ts
|
|
18550
20259
|
import { existsSync as existsSync15 } from "fs";
|
|
18551
|
-
import { dirname as dirname10, join as
|
|
20260
|
+
import { dirname as dirname10, join as join23 } from "path";
|
|
18552
20261
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
18553
20262
|
|
|
18554
20263
|
// packages/cli/src/auth-control.ts
|
|
18555
20264
|
await init_src4();
|
|
18556
|
-
import { join as
|
|
20265
|
+
import { join as join20 } from "node:path";
|
|
18557
20266
|
|
|
18558
20267
|
// packages/cli/src/config-store.ts
|
|
18559
20268
|
init_state_paths();
|
|
18560
20269
|
import { existsSync as existsSync10, mkdirSync as mkdirSync8, readFileSync as readFileSync8, writeFileSync as writeFileSync6 } from "fs";
|
|
18561
20270
|
import { homedir as homedir4 } from "os";
|
|
18562
|
-
import { join as
|
|
20271
|
+
import { join as join19 } from "path";
|
|
18563
20272
|
function getCliConfigPath() {
|
|
18564
|
-
return
|
|
20273
|
+
return join19(homedir4(), ".coder-studio", "config.json");
|
|
18565
20274
|
}
|
|
18566
20275
|
function normalizeLegacyDataDir(input2) {
|
|
18567
20276
|
return normalizeLegacyStateDir(input2);
|
|
@@ -18588,7 +20297,7 @@ function readCliConfig() {
|
|
|
18588
20297
|
}
|
|
18589
20298
|
function writeCliConfig(config) {
|
|
18590
20299
|
const path14 = getCliConfigPath();
|
|
18591
|
-
const dir =
|
|
20300
|
+
const dir = join19(homedir4(), ".coder-studio");
|
|
18592
20301
|
const normalizedConfig = {
|
|
18593
20302
|
...config.host !== void 0 ? { host: config.host } : {},
|
|
18594
20303
|
...config.port !== void 0 && config.port > 0 ? { port: config.port } : {},
|
|
@@ -18610,7 +20319,7 @@ function resolveStateDir() {
|
|
|
18610
20319
|
}
|
|
18611
20320
|
async function listAuthBlocks(now = Date.now()) {
|
|
18612
20321
|
const repo = new AuthLoginBlockRepo({
|
|
18613
|
-
filePath:
|
|
20322
|
+
filePath: join20(resolveStateDir(), "state", "auth-login-blocks.json")
|
|
18614
20323
|
});
|
|
18615
20324
|
return repo.listActiveBlocks(now).map((record) => ({
|
|
18616
20325
|
ip: record.ip,
|
|
@@ -18622,7 +20331,7 @@ async function listAuthBlocks(now = Date.now()) {
|
|
|
18622
20331
|
}
|
|
18623
20332
|
async function clearAuthBlockByIp(ip) {
|
|
18624
20333
|
const repo = new AuthLoginBlockRepo({
|
|
18625
|
-
filePath:
|
|
20334
|
+
filePath: join20(resolveStateDir(), "state", "auth-login-blocks.json")
|
|
18626
20335
|
});
|
|
18627
20336
|
return repo.delete(ip);
|
|
18628
20337
|
}
|
|
@@ -18641,7 +20350,7 @@ function getOpenCommand(url) {
|
|
|
18641
20350
|
}
|
|
18642
20351
|
async function openBrowser(url) {
|
|
18643
20352
|
const { command, args } = getOpenCommand(url);
|
|
18644
|
-
await new Promise((
|
|
20353
|
+
await new Promise((resolve8, reject) => {
|
|
18645
20354
|
const child = spawn6(command, args, {
|
|
18646
20355
|
detached: true,
|
|
18647
20356
|
stdio: "ignore",
|
|
@@ -18650,7 +20359,7 @@ async function openBrowser(url) {
|
|
|
18650
20359
|
child.once("error", reject);
|
|
18651
20360
|
child.once("spawn", () => {
|
|
18652
20361
|
child.unref();
|
|
18653
|
-
|
|
20362
|
+
resolve8();
|
|
18654
20363
|
});
|
|
18655
20364
|
});
|
|
18656
20365
|
}
|
|
@@ -18983,7 +20692,7 @@ function parseArgs(argv) {
|
|
|
18983
20692
|
init_runtime();
|
|
18984
20693
|
import { mkdirSync as mkdirSync9 } from "fs";
|
|
18985
20694
|
import { homedir as homedir5 } from "os";
|
|
18986
|
-
import { join as
|
|
20695
|
+
import { join as join21 } from "path";
|
|
18987
20696
|
var MANAGED_SERVER_NAME = "coder-studio-server";
|
|
18988
20697
|
var PM2_RESTART_DELAY_MS = 2e3;
|
|
18989
20698
|
var PM2_MIN_UPTIME = "5s";
|
|
@@ -19023,29 +20732,29 @@ async function loadPm2() {
|
|
|
19023
20732
|
}
|
|
19024
20733
|
var connectPm2 = async () => {
|
|
19025
20734
|
const pm2 = await loadPm2();
|
|
19026
|
-
return new Promise((
|
|
20735
|
+
return new Promise((resolve8, reject) => {
|
|
19027
20736
|
pm2.connect((error) => {
|
|
19028
20737
|
if (error) {
|
|
19029
20738
|
reject(error);
|
|
19030
20739
|
return;
|
|
19031
20740
|
}
|
|
19032
|
-
|
|
20741
|
+
resolve8();
|
|
19033
20742
|
});
|
|
19034
20743
|
});
|
|
19035
20744
|
};
|
|
19036
|
-
var sleep = async (ms) => new Promise((
|
|
19037
|
-
setTimeout(
|
|
20745
|
+
var sleep = async (ms) => new Promise((resolve8) => {
|
|
20746
|
+
setTimeout(resolve8, ms);
|
|
19038
20747
|
});
|
|
19039
20748
|
var disconnectPm2 = async () => {
|
|
19040
20749
|
const pm2 = await loadPm2();
|
|
19041
|
-
await new Promise((
|
|
20750
|
+
await new Promise((resolve8) => {
|
|
19042
20751
|
let settled = false;
|
|
19043
20752
|
const finish = () => {
|
|
19044
20753
|
if (settled) {
|
|
19045
20754
|
return;
|
|
19046
20755
|
}
|
|
19047
20756
|
settled = true;
|
|
19048
|
-
|
|
20757
|
+
resolve8();
|
|
19049
20758
|
};
|
|
19050
20759
|
const timer = setTimeout(finish, PM2_DISCONNECT_WAIT_MS);
|
|
19051
20760
|
try {
|
|
@@ -19059,29 +20768,29 @@ var disconnectPm2 = async () => {
|
|
|
19059
20768
|
}
|
|
19060
20769
|
});
|
|
19061
20770
|
};
|
|
19062
|
-
var describeManagedServer = async (pm2) => new Promise((
|
|
20771
|
+
var describeManagedServer = async (pm2) => new Promise((resolve8, reject) => {
|
|
19063
20772
|
pm2.describe(MANAGED_SERVER_NAME, (error, result) => {
|
|
19064
20773
|
if (error) {
|
|
19065
20774
|
reject(error);
|
|
19066
20775
|
return;
|
|
19067
20776
|
}
|
|
19068
|
-
|
|
20777
|
+
resolve8(result ?? []);
|
|
19069
20778
|
});
|
|
19070
20779
|
});
|
|
19071
|
-
var removeManagedServer = async (pm2) => new Promise((
|
|
20780
|
+
var removeManagedServer = async (pm2) => new Promise((resolve8, reject) => {
|
|
19072
20781
|
pm2.delete(MANAGED_SERVER_NAME, (error) => {
|
|
19073
20782
|
if (error) {
|
|
19074
20783
|
reject(error);
|
|
19075
20784
|
return;
|
|
19076
20785
|
}
|
|
19077
|
-
|
|
20786
|
+
resolve8();
|
|
19078
20787
|
});
|
|
19079
20788
|
});
|
|
19080
20789
|
var killPm2Daemon = async () => {
|
|
19081
20790
|
const pm2 = await loadPm2();
|
|
19082
|
-
return new Promise((
|
|
20791
|
+
return new Promise((resolve8) => {
|
|
19083
20792
|
pm2.kill(() => {
|
|
19084
|
-
|
|
20793
|
+
resolve8();
|
|
19085
20794
|
});
|
|
19086
20795
|
});
|
|
19087
20796
|
};
|
|
@@ -19204,11 +20913,11 @@ var deleteManagedServerInSession = async (pm2, {
|
|
|
19204
20913
|
return true;
|
|
19205
20914
|
};
|
|
19206
20915
|
var ensureLogDirectory = () => {
|
|
19207
|
-
mkdirSync9(
|
|
20916
|
+
mkdirSync9(join21(homedir5(), ".coder-studio", "logs"), { recursive: true });
|
|
19208
20917
|
};
|
|
19209
20918
|
var getLogPaths = () => ({
|
|
19210
|
-
outFile:
|
|
19211
|
-
errFile:
|
|
20919
|
+
outFile: join21(homedir5(), ".coder-studio", "logs", "server.out.log"),
|
|
20920
|
+
errFile: join21(homedir5(), ".coder-studio", "logs", "server.err.log")
|
|
19212
20921
|
});
|
|
19213
20922
|
var captureStartupLogOffsets = () => {
|
|
19214
20923
|
const { outFile, errFile } = getLogPaths();
|
|
@@ -19257,7 +20966,7 @@ var startManagedServer = async ({
|
|
|
19257
20966
|
ensureLogDirectory();
|
|
19258
20967
|
const { outFile, errFile } = getLogPaths();
|
|
19259
20968
|
const logOffsets = captureStartupLogOffsets();
|
|
19260
|
-
await new Promise((
|
|
20969
|
+
await new Promise((resolve8, reject) => {
|
|
19261
20970
|
pm2.start(
|
|
19262
20971
|
{
|
|
19263
20972
|
name: MANAGED_SERVER_NAME,
|
|
@@ -19280,7 +20989,7 @@ var startManagedServer = async ({
|
|
|
19280
20989
|
reject(error);
|
|
19281
20990
|
return;
|
|
19282
20991
|
}
|
|
19283
|
-
|
|
20992
|
+
resolve8();
|
|
19284
20993
|
}
|
|
19285
20994
|
);
|
|
19286
20995
|
});
|
|
@@ -19397,11 +21106,11 @@ import { fileURLToPath as fileURLToPath4 } from "url";
|
|
|
19397
21106
|
|
|
19398
21107
|
// packages/cli/src/embed.ts
|
|
19399
21108
|
import { existsSync as existsSync13 } from "fs";
|
|
19400
|
-
import { dirname as dirname8, resolve as
|
|
21109
|
+
import { dirname as dirname8, resolve as resolve7 } from "path";
|
|
19401
21110
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
19402
21111
|
var __filename = fileURLToPath2(import.meta.url);
|
|
19403
21112
|
var __dirname = dirname8(__filename);
|
|
19404
|
-
var WEB_ASSETS_DIR =
|
|
21113
|
+
var WEB_ASSETS_DIR = resolve7(__dirname, "../web");
|
|
19405
21114
|
function getStaticAssetsDir() {
|
|
19406
21115
|
return WEB_ASSETS_DIR;
|
|
19407
21116
|
}
|
|
@@ -19411,13 +21120,13 @@ function hasWebAssets() {
|
|
|
19411
21120
|
|
|
19412
21121
|
// packages/cli/src/update-runtime.ts
|
|
19413
21122
|
import { existsSync as existsSync14 } from "node:fs";
|
|
19414
|
-
import { dirname as dirname9, join as
|
|
21123
|
+
import { dirname as dirname9, join as join22 } from "node:path";
|
|
19415
21124
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
19416
21125
|
function resolveWorkerEntryPath(importMetaUrl) {
|
|
19417
21126
|
const currentDir = dirname9(fileURLToPath3(importMetaUrl));
|
|
19418
21127
|
const candidates = [
|
|
19419
|
-
|
|
19420
|
-
|
|
21128
|
+
join22(currentDir, "update-worker.mjs"),
|
|
21129
|
+
join22(currentDir, "../src/update-worker.ts")
|
|
19421
21130
|
];
|
|
19422
21131
|
return candidates.find((candidate) => existsSync14(candidate));
|
|
19423
21132
|
}
|
|
@@ -19646,9 +21355,9 @@ function resolveManagedScriptPath() {
|
|
|
19646
21355
|
const currentFile = fileURLToPath5(import.meta.url);
|
|
19647
21356
|
const currentDir = dirname10(currentFile);
|
|
19648
21357
|
const candidates = [
|
|
19649
|
-
|
|
19650
|
-
|
|
19651
|
-
|
|
21358
|
+
join23(currentDir, "server-runner.js"),
|
|
21359
|
+
join23(currentDir, "server-runner.mjs"),
|
|
21360
|
+
join23(currentDir, "../src/server-runner.ts")
|
|
19652
21361
|
];
|
|
19653
21362
|
const scriptPath = candidates.find((candidate) => existsSync15(candidate));
|
|
19654
21363
|
if (!scriptPath) {
|