replicas-engine 0.1.408 → 0.1.410
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/index.js +309 -85
- package/package.json +1 -1
package/dist/src/index.js
CHANGED
|
@@ -479,7 +479,7 @@ var WORKSPACE_SIZES = ["small", "large"];
|
|
|
479
479
|
var INVALID_WORKSPACE_SIZE_ERROR = `Invalid size: must be one of ${WORKSPACE_SIZES.join(", ")}`;
|
|
480
480
|
|
|
481
481
|
// ../shared/src/e2b.ts
|
|
482
|
-
var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-07-08-
|
|
482
|
+
var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-07-08-v5";
|
|
483
483
|
|
|
484
484
|
// ../shared/src/runtime-env.ts
|
|
485
485
|
function parsePosixEnvFile(content) {
|
|
@@ -5533,27 +5533,81 @@ function linearThoughtToResponse(thought) {
|
|
|
5533
5533
|
function summarizeInput(input) {
|
|
5534
5534
|
if (!input) return "";
|
|
5535
5535
|
if (typeof input === "string") return input;
|
|
5536
|
-
if (
|
|
5537
|
-
|
|
5538
|
-
if (
|
|
5539
|
-
if (
|
|
5540
|
-
if (
|
|
5541
|
-
if (
|
|
5542
|
-
if (
|
|
5543
|
-
if (typeof
|
|
5544
|
-
|
|
5545
|
-
|
|
5546
|
-
if (keys.length > 0) {
|
|
5547
|
-
const firstKey = keys[0];
|
|
5548
|
-
return `${firstKey}: ${String(obj[firstKey])}`;
|
|
5536
|
+
if (isRecord(input)) {
|
|
5537
|
+
if (input.file_path) return String(input.file_path);
|
|
5538
|
+
if (input.command) return String(input.command);
|
|
5539
|
+
if (input.pattern) return `pattern: ${String(input.pattern)}`;
|
|
5540
|
+
if (input.query) return String(input.query);
|
|
5541
|
+
if (input.url) return String(input.url);
|
|
5542
|
+
if (typeof input.activeForm === "string" && input.activeForm) return String(input.activeForm);
|
|
5543
|
+
if (typeof input.subject === "string" && input.subject) return String(input.subject);
|
|
5544
|
+
for (const [key, value] of Object.entries(input)) {
|
|
5545
|
+
return `${key}: ${String(value)}`;
|
|
5549
5546
|
}
|
|
5550
5547
|
}
|
|
5551
5548
|
return "";
|
|
5552
5549
|
}
|
|
5550
|
+
function summarizeResult(result) {
|
|
5551
|
+
if (!result) return "";
|
|
5552
|
+
if (typeof result === "string") return result;
|
|
5553
|
+
if (isRecord(result)) {
|
|
5554
|
+
if (typeof result.message === "string") return result.message;
|
|
5555
|
+
if (typeof result.error === "string") return result.error;
|
|
5556
|
+
if (typeof result.stdout === "string") return result.stdout;
|
|
5557
|
+
if (typeof result.stderr === "string") return result.stderr;
|
|
5558
|
+
if (typeof result.path === "string") return result.path;
|
|
5559
|
+
}
|
|
5560
|
+
try {
|
|
5561
|
+
return JSON.stringify(result);
|
|
5562
|
+
} catch {
|
|
5563
|
+
return String(result);
|
|
5564
|
+
}
|
|
5565
|
+
}
|
|
5566
|
+
function toolAction(toolName) {
|
|
5567
|
+
switch (toolName) {
|
|
5568
|
+
case "Bash":
|
|
5569
|
+
case "bash":
|
|
5570
|
+
case "shell":
|
|
5571
|
+
return "Running command";
|
|
5572
|
+
case "Edit":
|
|
5573
|
+
case "edit":
|
|
5574
|
+
return "Editing file";
|
|
5575
|
+
case "Write":
|
|
5576
|
+
case "write":
|
|
5577
|
+
return "Writing file";
|
|
5578
|
+
case "Read":
|
|
5579
|
+
case "read":
|
|
5580
|
+
return "Reading file";
|
|
5581
|
+
case "Glob":
|
|
5582
|
+
case "glob":
|
|
5583
|
+
return "Searching files";
|
|
5584
|
+
case "Grep":
|
|
5585
|
+
case "grep":
|
|
5586
|
+
case "semsearch":
|
|
5587
|
+
return "Searching code";
|
|
5588
|
+
case "WebSearch":
|
|
5589
|
+
return "Web search";
|
|
5590
|
+
case "WebFetch":
|
|
5591
|
+
return "Fetching URL";
|
|
5592
|
+
case "delete":
|
|
5593
|
+
return "Deleting file";
|
|
5594
|
+
case "Task":
|
|
5595
|
+
case "task":
|
|
5596
|
+
return "Spawning subagent";
|
|
5597
|
+
case "TaskCreate":
|
|
5598
|
+
case "TaskUpdate":
|
|
5599
|
+
case "TaskList":
|
|
5600
|
+
case "TaskGet":
|
|
5601
|
+
case "update_todos":
|
|
5602
|
+
case "create_plan":
|
|
5603
|
+
return "Updating plan";
|
|
5604
|
+
default:
|
|
5605
|
+
return toolName;
|
|
5606
|
+
}
|
|
5607
|
+
}
|
|
5553
5608
|
function convertClaudeEvent(event, linearSessionId) {
|
|
5554
5609
|
if (event.type === "assistant") {
|
|
5555
|
-
const
|
|
5556
|
-
const contentBlocks = normalizeContentBlocks(message.message?.content);
|
|
5610
|
+
const contentBlocks = normalizeContentBlocks(event.message.content);
|
|
5557
5611
|
for (const block of contentBlocks) {
|
|
5558
5612
|
if (block.type === "text" && block.text) {
|
|
5559
5613
|
return {
|
|
@@ -5576,47 +5630,11 @@ function convertClaudeEvent(event, linearSessionId) {
|
|
|
5576
5630
|
if (block.type === "tool_use" && block.name) {
|
|
5577
5631
|
const toolName = block.name;
|
|
5578
5632
|
const parameter = summarizeInput(block.input);
|
|
5579
|
-
let action = toolName;
|
|
5580
|
-
switch (toolName) {
|
|
5581
|
-
case "Bash":
|
|
5582
|
-
action = "Running command";
|
|
5583
|
-
break;
|
|
5584
|
-
case "Edit":
|
|
5585
|
-
action = "Editing file";
|
|
5586
|
-
break;
|
|
5587
|
-
case "Write":
|
|
5588
|
-
action = "Writing file";
|
|
5589
|
-
break;
|
|
5590
|
-
case "Read":
|
|
5591
|
-
action = "Reading file";
|
|
5592
|
-
break;
|
|
5593
|
-
case "Glob":
|
|
5594
|
-
action = "Searching files";
|
|
5595
|
-
break;
|
|
5596
|
-
case "Grep":
|
|
5597
|
-
action = "Searching code";
|
|
5598
|
-
break;
|
|
5599
|
-
case "WebSearch":
|
|
5600
|
-
action = "Web search";
|
|
5601
|
-
break;
|
|
5602
|
-
case "WebFetch":
|
|
5603
|
-
action = "Fetching URL";
|
|
5604
|
-
break;
|
|
5605
|
-
case "Task":
|
|
5606
|
-
action = "Spawning subagent";
|
|
5607
|
-
break;
|
|
5608
|
-
case "TaskCreate":
|
|
5609
|
-
case "TaskUpdate":
|
|
5610
|
-
case "TaskList":
|
|
5611
|
-
case "TaskGet":
|
|
5612
|
-
action = "Updating plan";
|
|
5613
|
-
break;
|
|
5614
|
-
}
|
|
5615
5633
|
return {
|
|
5616
5634
|
linearSessionId,
|
|
5617
5635
|
content: {
|
|
5618
5636
|
type: "action",
|
|
5619
|
-
action,
|
|
5637
|
+
action: toolAction(toolName),
|
|
5620
5638
|
parameter
|
|
5621
5639
|
}
|
|
5622
5640
|
};
|
|
@@ -5624,8 +5642,7 @@ function convertClaudeEvent(event, linearSessionId) {
|
|
|
5624
5642
|
}
|
|
5625
5643
|
}
|
|
5626
5644
|
if (event.type === "user") {
|
|
5627
|
-
const
|
|
5628
|
-
const contentBlocks = normalizeContentBlocks(message.message?.content);
|
|
5645
|
+
const contentBlocks = normalizeContentBlocks(event.message.content);
|
|
5629
5646
|
for (const block of contentBlocks) {
|
|
5630
5647
|
if (block.type === "tool_result") {
|
|
5631
5648
|
const resultText = extractToolResultText(block.content);
|
|
@@ -5645,6 +5662,106 @@ function convertClaudeEvent(event, linearSessionId) {
|
|
|
5645
5662
|
}
|
|
5646
5663
|
return null;
|
|
5647
5664
|
}
|
|
5665
|
+
function convertCursorEvent(event, linearSessionId) {
|
|
5666
|
+
if (event.type === "assistant") {
|
|
5667
|
+
for (const block of event.message.content) {
|
|
5668
|
+
if (block.type === "text" && block.text) {
|
|
5669
|
+
return {
|
|
5670
|
+
linearSessionId,
|
|
5671
|
+
content: {
|
|
5672
|
+
type: "thought",
|
|
5673
|
+
body: block.text
|
|
5674
|
+
}
|
|
5675
|
+
};
|
|
5676
|
+
}
|
|
5677
|
+
if (block.type === "tool_use" && block.name) {
|
|
5678
|
+
return {
|
|
5679
|
+
linearSessionId,
|
|
5680
|
+
content: {
|
|
5681
|
+
type: "action",
|
|
5682
|
+
action: toolAction(block.name),
|
|
5683
|
+
parameter: summarizeInput(block.input)
|
|
5684
|
+
}
|
|
5685
|
+
};
|
|
5686
|
+
}
|
|
5687
|
+
}
|
|
5688
|
+
}
|
|
5689
|
+
if (event.type === "thinking" && event.text) {
|
|
5690
|
+
return {
|
|
5691
|
+
linearSessionId,
|
|
5692
|
+
content: {
|
|
5693
|
+
type: "thought",
|
|
5694
|
+
body: event.text
|
|
5695
|
+
}
|
|
5696
|
+
};
|
|
5697
|
+
}
|
|
5698
|
+
if (event.type === "tool_call") {
|
|
5699
|
+
const result = event.status === "running" ? void 0 : event.status === "error" ? `Error: ${summarizeResult(event.result) || "Tool failed"}` : summarizeResult(event.result) || "Done";
|
|
5700
|
+
return {
|
|
5701
|
+
linearSessionId,
|
|
5702
|
+
content: {
|
|
5703
|
+
type: "action",
|
|
5704
|
+
action: toolAction(event.name),
|
|
5705
|
+
parameter: summarizeInput(event.args),
|
|
5706
|
+
...result ? { result } : {}
|
|
5707
|
+
}
|
|
5708
|
+
};
|
|
5709
|
+
}
|
|
5710
|
+
if (event.type === "task" && event.text) {
|
|
5711
|
+
return {
|
|
5712
|
+
linearSessionId,
|
|
5713
|
+
content: {
|
|
5714
|
+
type: "thought",
|
|
5715
|
+
body: event.text
|
|
5716
|
+
}
|
|
5717
|
+
};
|
|
5718
|
+
}
|
|
5719
|
+
return null;
|
|
5720
|
+
}
|
|
5721
|
+
function isOpencodePartEnded(part) {
|
|
5722
|
+
return "time" in part && isRecord(part.time) && part.time.end !== void 0;
|
|
5723
|
+
}
|
|
5724
|
+
function convertOpencodePart(part, linearSessionId) {
|
|
5725
|
+
if ((part.type === "text" || part.type === "reasoning") && isOpencodePartEnded(part)) {
|
|
5726
|
+
const body = typeof part.text === "string" ? part.text.trim() : "";
|
|
5727
|
+
if (!body) return null;
|
|
5728
|
+
return {
|
|
5729
|
+
linearSessionId,
|
|
5730
|
+
content: {
|
|
5731
|
+
type: "thought",
|
|
5732
|
+
body
|
|
5733
|
+
}
|
|
5734
|
+
};
|
|
5735
|
+
}
|
|
5736
|
+
if (part.type === "tool" && isRecord(part.state)) {
|
|
5737
|
+
const state = part.state;
|
|
5738
|
+
const status = typeof state.status === "string" ? state.status : void 0;
|
|
5739
|
+
const result = status === "completed" ? summarizeResult(state.output) || "Done" : status === "error" ? `Error: ${summarizeResult(state.error) || "Tool failed"}` : void 0;
|
|
5740
|
+
return {
|
|
5741
|
+
linearSessionId,
|
|
5742
|
+
content: {
|
|
5743
|
+
type: "action",
|
|
5744
|
+
action: toolAction(typeof part.tool === "string" ? part.tool : "Tool"),
|
|
5745
|
+
parameter: summarizeInput(state.input),
|
|
5746
|
+
...result ? { result } : {}
|
|
5747
|
+
}
|
|
5748
|
+
};
|
|
5749
|
+
}
|
|
5750
|
+
if (part.type === "patch") {
|
|
5751
|
+
const files = "files" in part && Array.isArray(part.files) ? part.files.filter((file) => typeof file === "string") : [];
|
|
5752
|
+
if (files.length === 0) return null;
|
|
5753
|
+
return {
|
|
5754
|
+
linearSessionId,
|
|
5755
|
+
content: {
|
|
5756
|
+
type: "action",
|
|
5757
|
+
action: "File change",
|
|
5758
|
+
parameter: files.join(", "),
|
|
5759
|
+
result: "Done"
|
|
5760
|
+
}
|
|
5761
|
+
};
|
|
5762
|
+
}
|
|
5763
|
+
return null;
|
|
5764
|
+
}
|
|
5648
5765
|
function mapTodoStatus(status) {
|
|
5649
5766
|
if (status === "in_progress") {
|
|
5650
5767
|
return "inProgress";
|
|
@@ -6802,6 +6919,8 @@ var COMMAND_PROTECTION_SAFE_TOOLS = /* @__PURE__ */ new Set([
|
|
|
6802
6919
|
"LS"
|
|
6803
6920
|
]);
|
|
6804
6921
|
var CLAUDE_PARTIAL_MESSAGE_FLUSH_MS = 80;
|
|
6922
|
+
var CLAUDE_SLASH_COMMANDS_CACHE_MS = 6e4;
|
|
6923
|
+
var CLAUDE_SLASH_COMMANDS_DISCOVERY_TIMEOUT_MS = 3e4;
|
|
6805
6924
|
function supportsClaudeThinkingDisplay(model) {
|
|
6806
6925
|
const normalized = (normalizeClaudeModel(model) ?? model).toLowerCase();
|
|
6807
6926
|
return AGENT_MODELS.claude.includes(normalized) || /^claude-(?:opus|sonnet|haiku)-[4-9]/.test(normalized);
|
|
@@ -6952,6 +7071,8 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
6952
7071
|
/** Active tool-input requests keyed by requestId; resolved when the user selects an option. */
|
|
6953
7072
|
pendingToolInputs = /* @__PURE__ */ new Map();
|
|
6954
7073
|
supportedSlashCommands = [];
|
|
7074
|
+
slashCommandsDiscoveredAt = 0;
|
|
7075
|
+
slashCommandsDiscovery = null;
|
|
6955
7076
|
authRetrying = false;
|
|
6956
7077
|
constructor(options) {
|
|
6957
7078
|
super(options);
|
|
@@ -6995,16 +7116,70 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
6995
7116
|
}
|
|
6996
7117
|
async listSlashCommands() {
|
|
6997
7118
|
await this.initialized;
|
|
6998
|
-
if (
|
|
7119
|
+
if (this.activeQuery) {
|
|
7120
|
+
if (this.isProcessing()) {
|
|
7121
|
+
return this.supportedSlashCommands;
|
|
7122
|
+
}
|
|
7123
|
+
try {
|
|
7124
|
+
const commands = await this.activeQuery.supportedCommands();
|
|
7125
|
+
if (commands) {
|
|
7126
|
+
this.supportedSlashCommands = normalizeClaudeSlashCommands(commands);
|
|
7127
|
+
this.slashCommandsDiscoveredAt = Date.now();
|
|
7128
|
+
}
|
|
7129
|
+
} catch (error) {
|
|
7130
|
+
console.warn("[ClaudeManager] Failed to load slash commands:", error);
|
|
7131
|
+
}
|
|
7132
|
+
return this.supportedSlashCommands;
|
|
7133
|
+
}
|
|
7134
|
+
if (this.slashCommandsDiscoveredAt > 0 && Date.now() - this.slashCommandsDiscoveredAt < CLAUDE_SLASH_COMMANDS_CACHE_MS) {
|
|
6999
7135
|
return this.supportedSlashCommands;
|
|
7000
7136
|
}
|
|
7137
|
+
this.slashCommandsDiscovery ??= this.discoverSlashCommands().finally(() => {
|
|
7138
|
+
this.slashCommandsDiscovery = null;
|
|
7139
|
+
});
|
|
7140
|
+
return this.slashCommandsDiscovery;
|
|
7141
|
+
}
|
|
7142
|
+
/**
|
|
7143
|
+
* Sessions are created lazily on the first message, but the dashboard needs
|
|
7144
|
+
* the command list as soon as a chat opens — so with no session alive we
|
|
7145
|
+
* spawn a throwaway query (no prompt is ever pushed, so no model call is
|
|
7146
|
+
* made), read supportedCommands(), and terminate it.
|
|
7147
|
+
*/
|
|
7148
|
+
async discoverSlashCommands() {
|
|
7149
|
+
const promptStream = new PromptStream();
|
|
7150
|
+
let discovery = null;
|
|
7151
|
+
let timeoutHandle;
|
|
7001
7152
|
try {
|
|
7002
|
-
const
|
|
7153
|
+
const shared = await this.buildSharedQueryOptions();
|
|
7154
|
+
discovery = query({
|
|
7155
|
+
prompt: promptStream,
|
|
7156
|
+
options: {
|
|
7157
|
+
cwd: this.workingDirectory,
|
|
7158
|
+
additionalDirectories: shared.additionalDirectories,
|
|
7159
|
+
settingSources: ["user", "project", "local"],
|
|
7160
|
+
...this.mcpServersConfig ? { mcpServers: this.mcpServersConfig } : {},
|
|
7161
|
+
...shared.plugins.length > 0 ? { plugins: shared.plugins } : {},
|
|
7162
|
+
...shared.enableAllSkills ? { skills: "all" } : {},
|
|
7163
|
+
env: shared.env
|
|
7164
|
+
}
|
|
7165
|
+
});
|
|
7166
|
+
const timeout = new Promise((_, reject) => {
|
|
7167
|
+
timeoutHandle = setTimeout(
|
|
7168
|
+
() => reject(new Error("Slash command discovery timed out")),
|
|
7169
|
+
CLAUDE_SLASH_COMMANDS_DISCOVERY_TIMEOUT_MS
|
|
7170
|
+
);
|
|
7171
|
+
});
|
|
7172
|
+
const commands = await Promise.race([discovery.supportedCommands(), timeout]);
|
|
7003
7173
|
if (commands) {
|
|
7004
7174
|
this.supportedSlashCommands = normalizeClaudeSlashCommands(commands);
|
|
7005
7175
|
}
|
|
7006
7176
|
} catch (error) {
|
|
7007
|
-
console.warn("[ClaudeManager] Failed to
|
|
7177
|
+
console.warn("[ClaudeManager] Failed to discover slash commands:", error);
|
|
7178
|
+
} finally {
|
|
7179
|
+
this.slashCommandsDiscoveredAt = Date.now();
|
|
7180
|
+
clearTimeout(timeoutHandle);
|
|
7181
|
+
promptStream.close();
|
|
7182
|
+
discovery?.close();
|
|
7008
7183
|
}
|
|
7009
7184
|
return this.supportedSlashCommands;
|
|
7010
7185
|
}
|
|
@@ -7376,6 +7551,21 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
7376
7551
|
sessionSignaturesMatch(a, b) {
|
|
7377
7552
|
return a.combinedInstructions === b.combinedInstructions && a.thinkingLevel === b.thinkingLevel && a.enableInteractiveTools === b.enableInteractiveTools && a.fastMode === b.fastMode;
|
|
7378
7553
|
}
|
|
7554
|
+
/** Query inputs shared by real sessions and slash-command discovery. */
|
|
7555
|
+
async buildSharedQueryOptions() {
|
|
7556
|
+
const env = buildClaudeAgentEnv(this.envOverrides);
|
|
7557
|
+
const additionalDirectories = await getAgentAdditionalDirectories();
|
|
7558
|
+
let plugins = [];
|
|
7559
|
+
let enableAllSkills = false;
|
|
7560
|
+
try {
|
|
7561
|
+
const registryConfig = await buildClaudeRegistryConfig(ENGINE_ENV.HOME_DIR);
|
|
7562
|
+
plugins = registryConfig.plugins;
|
|
7563
|
+
enableAllSkills = registryConfig.enableAllSkills;
|
|
7564
|
+
} catch (error) {
|
|
7565
|
+
console.warn("[ClaudeManager] Failed to load skill registry config:", error);
|
|
7566
|
+
}
|
|
7567
|
+
return { env, additionalDirectories, plugins, enableAllSkills };
|
|
7568
|
+
}
|
|
7379
7569
|
async startSession(args) {
|
|
7380
7570
|
const {
|
|
7381
7571
|
combinedInstructions,
|
|
@@ -7391,8 +7581,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
7391
7581
|
preset: "claude_code",
|
|
7392
7582
|
append: combinedInstructions
|
|
7393
7583
|
};
|
|
7394
|
-
const
|
|
7395
|
-
const additionalDirectories = await getAgentAdditionalDirectories();
|
|
7584
|
+
const shared = await this.buildSharedQueryOptions();
|
|
7396
7585
|
const interactiveAllowed = enableInteractiveTools && resolvedPermissionMode === "plan";
|
|
7397
7586
|
const useDefaultToolPolicy = !this.toolsOverride;
|
|
7398
7587
|
const allowedTools = useDefaultToolPolicy ? [
|
|
@@ -7404,22 +7593,13 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
7404
7593
|
...useDefaultToolPolicy ? ALWAYS_DISALLOWED_TOOLS : [],
|
|
7405
7594
|
...interactiveAllowed ? [] : INTERACTIVE_TOOL_NAMES
|
|
7406
7595
|
];
|
|
7407
|
-
let registryPlugins = [];
|
|
7408
|
-
let enableRegistrySkills = false;
|
|
7409
|
-
try {
|
|
7410
|
-
const registryConfig = await buildClaudeRegistryConfig(ENGINE_ENV.HOME_DIR);
|
|
7411
|
-
registryPlugins = registryConfig.plugins;
|
|
7412
|
-
enableRegistrySkills = registryConfig.enableAllSkills;
|
|
7413
|
-
} catch (error) {
|
|
7414
|
-
console.warn("[ClaudeManager] Failed to load skill registry config:", error);
|
|
7415
|
-
}
|
|
7416
7596
|
const promptStream = new PromptStream();
|
|
7417
7597
|
const response = query({
|
|
7418
7598
|
prompt: promptStream,
|
|
7419
7599
|
options: {
|
|
7420
7600
|
resume: this.sessionId || void 0,
|
|
7421
7601
|
cwd: this.workingDirectory,
|
|
7422
|
-
additionalDirectories,
|
|
7602
|
+
additionalDirectories: shared.additionalDirectories,
|
|
7423
7603
|
permissionMode: resolvedPermissionMode,
|
|
7424
7604
|
allowDangerouslySkipPermissions: resolvedPermissionMode === "bypassPermissions",
|
|
7425
7605
|
...this.toolsOverride ? { tools: this.toolsOverride } : {},
|
|
@@ -7428,9 +7608,9 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
7428
7608
|
settingSources: ["user", "project", "local"],
|
|
7429
7609
|
systemPrompt,
|
|
7430
7610
|
...this.mcpServersConfig ? { mcpServers: this.mcpServersConfig } : {},
|
|
7431
|
-
...
|
|
7432
|
-
...
|
|
7433
|
-
env:
|
|
7611
|
+
...shared.plugins.length > 0 ? { plugins: shared.plugins } : {},
|
|
7612
|
+
...shared.enableAllSkills ? { skills: "all" } : {},
|
|
7613
|
+
env: shared.env,
|
|
7434
7614
|
model: claudeCodeModel,
|
|
7435
7615
|
settings: { fastMode: signature.fastMode },
|
|
7436
7616
|
includePartialMessages: true,
|
|
@@ -7458,6 +7638,11 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
7458
7638
|
this.sessionLoop = this.runSessionLoop(response).catch((err) => {
|
|
7459
7639
|
console.error("[ClaudeManager] Session loop crashed:", err);
|
|
7460
7640
|
});
|
|
7641
|
+
void response.supportedCommands().then((commands) => {
|
|
7642
|
+
this.supportedSlashCommands = normalizeClaudeSlashCommands(commands);
|
|
7643
|
+
this.slashCommandsDiscoveredAt = Date.now();
|
|
7644
|
+
}).catch(() => {
|
|
7645
|
+
});
|
|
7461
7646
|
}
|
|
7462
7647
|
async runSessionLoop(response) {
|
|
7463
7648
|
const linearSessionId = ENGINE_ENV.LINEAR_SESSION_ID;
|
|
@@ -7791,6 +7976,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
7791
7976
|
}
|
|
7792
7977
|
if (message.type === "system" && message.subtype === "commands_changed") {
|
|
7793
7978
|
this.supportedSlashCommands = normalizeClaudeSlashCommands(message.commands);
|
|
7979
|
+
this.slashCommandsDiscoveredAt = Date.now();
|
|
7794
7980
|
}
|
|
7795
7981
|
this.trackNativeCompaction(message);
|
|
7796
7982
|
await this.recordEvent(message);
|
|
@@ -8018,7 +8204,7 @@ var AspClient = class {
|
|
|
8018
8204
|
// src/managers/codex-asp/app-server-process.ts
|
|
8019
8205
|
var DEFAULT_CODEX_BINARY = "codex";
|
|
8020
8206
|
var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
|
|
8021
|
-
var ENGINE_PACKAGE_VERSION = "0.1.
|
|
8207
|
+
var ENGINE_PACKAGE_VERSION = "0.1.410";
|
|
8022
8208
|
var INITIALIZE_METHOD = "initialize";
|
|
8023
8209
|
var INITIALIZED_NOTIFICATION = "initialized";
|
|
8024
8210
|
var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
|
|
@@ -10192,9 +10378,10 @@ var CursorManager = class extends CodingAgentManager {
|
|
|
10192
10378
|
}
|
|
10193
10379
|
this.slashCommandsRequest ??= (async () => {
|
|
10194
10380
|
try {
|
|
10381
|
+
const repoDirectories = await getAgentAdditionalDirectories();
|
|
10382
|
+
const commandDirectories = [this.workingDirectory, ...repoDirectories, ENGINE_ENV.HOME_DIR].map((directory) => join17(directory, ".cursor", "commands"));
|
|
10195
10383
|
const commands = mergeSlashCommands(
|
|
10196
|
-
await
|
|
10197
|
-
await listCursorCommandsInDirectory(join17(ENGINE_ENV.HOME_DIR, ".cursor", "commands"))
|
|
10384
|
+
...await Promise.all(commandDirectories.map(listCursorCommandsInDirectory))
|
|
10198
10385
|
);
|
|
10199
10386
|
this.slashCommandsCache = { commands, expiresAt: Date.now() + CURSOR_SLASH_COMMANDS_CACHE_MS };
|
|
10200
10387
|
return commands;
|
|
@@ -10224,6 +10411,8 @@ var CursorManager = class extends CodingAgentManager {
|
|
|
10224
10411
|
return this.agent;
|
|
10225
10412
|
}
|
|
10226
10413
|
async processMessageInternal(request) {
|
|
10414
|
+
const linearSessionId = ENGINE_ENV.LINEAR_SESSION_ID;
|
|
10415
|
+
const linearForwarder = new LinearEventForwarder(linearSessionId);
|
|
10227
10416
|
try {
|
|
10228
10417
|
const agent = await this.ensureAgent(request);
|
|
10229
10418
|
const message = await this.toCursorMessage(request);
|
|
@@ -10240,6 +10429,9 @@ var CursorManager = class extends CodingAgentManager {
|
|
|
10240
10429
|
this.activeModel = model;
|
|
10241
10430
|
for await (const event of run.stream()) {
|
|
10242
10431
|
this.recordCursorEvent(event);
|
|
10432
|
+
if (linearSessionId) {
|
|
10433
|
+
linearForwarder.sendEvent(convertCursorEvent(event, linearSessionId));
|
|
10434
|
+
}
|
|
10243
10435
|
}
|
|
10244
10436
|
const result = await run.wait();
|
|
10245
10437
|
if (result.status === "error") {
|
|
@@ -10248,6 +10440,8 @@ var CursorManager = class extends CodingAgentManager {
|
|
|
10248
10440
|
message: result.result || "Cursor run failed",
|
|
10249
10441
|
runId: result.id
|
|
10250
10442
|
}, this.historyFile);
|
|
10443
|
+
} else {
|
|
10444
|
+
linearForwarder.flushThoughtAsResponse();
|
|
10251
10445
|
}
|
|
10252
10446
|
} catch (error) {
|
|
10253
10447
|
this.recordHistoryEvent("cursor-error", {
|
|
@@ -10502,6 +10696,8 @@ var OpencodeManager = class extends CodingAgentManager {
|
|
|
10502
10696
|
textParts = /* @__PURE__ */ new Map();
|
|
10503
10697
|
reasoningParts = /* @__PURE__ */ new Map();
|
|
10504
10698
|
nonAssistantMessageIds = /* @__PURE__ */ new Set();
|
|
10699
|
+
activeLinearForwarder = null;
|
|
10700
|
+
forwardedLinearPartKeys = /* @__PURE__ */ new Set();
|
|
10505
10701
|
modelVariants = /* @__PURE__ */ new Map();
|
|
10506
10702
|
slashCommandsCache = null;
|
|
10507
10703
|
slashCommandsRequest = null;
|
|
@@ -10546,15 +10742,24 @@ var OpencodeManager = class extends CodingAgentManager {
|
|
|
10546
10742
|
this.slashCommandsRequest ??= (async () => {
|
|
10547
10743
|
try {
|
|
10548
10744
|
const client = await this.ensureClient(DEFAULT_OPENCODE_MODEL);
|
|
10549
|
-
const
|
|
10550
|
-
const
|
|
10551
|
-
|
|
10552
|
-
|
|
10553
|
-
|
|
10554
|
-
|
|
10555
|
-
|
|
10556
|
-
|
|
10557
|
-
|
|
10745
|
+
const directories = [this.workingDirectory, ...await getAgentAdditionalDirectories()];
|
|
10746
|
+
const perDirectory = await Promise.all(directories.map(async (directory) => {
|
|
10747
|
+
try {
|
|
10748
|
+
const location = { directory };
|
|
10749
|
+
const [commandResponse, skillResponse] = await Promise.all([
|
|
10750
|
+
client.v2.command.list({ location }, { throwOnError: true }),
|
|
10751
|
+
client.v2.skill.list({ location }, { throwOnError: true })
|
|
10752
|
+
]);
|
|
10753
|
+
return mergeSlashCommands(
|
|
10754
|
+
opencodeCommandListToSlashCommands(commandResponse.data),
|
|
10755
|
+
opencodeSkillListToSlashCommands(skillResponse.data)
|
|
10756
|
+
);
|
|
10757
|
+
} catch (error) {
|
|
10758
|
+
console.warn("[OpencodeManager] Failed to load slash commands for directory:", directory, error);
|
|
10759
|
+
return [];
|
|
10760
|
+
}
|
|
10761
|
+
}));
|
|
10762
|
+
const commands = mergeSlashCommands(...perDirectory);
|
|
10558
10763
|
this.slashCommandsCache = { commands, expiresAt: Date.now() + OPENCODE_SLASH_COMMANDS_CACHE_MS };
|
|
10559
10764
|
return commands;
|
|
10560
10765
|
} catch (error) {
|
|
@@ -10659,7 +10864,11 @@ var OpencodeManager = class extends CodingAgentManager {
|
|
|
10659
10864
|
async processMessageInternal(request) {
|
|
10660
10865
|
const model = request.model ?? DEFAULT_OPENCODE_MODEL;
|
|
10661
10866
|
const controller = new AbortController();
|
|
10867
|
+
const linearSessionId = ENGINE_ENV.LINEAR_SESSION_ID;
|
|
10868
|
+
const linearForwarder = new LinearEventForwarder(linearSessionId);
|
|
10662
10869
|
this.activeAbortController = controller;
|
|
10870
|
+
this.activeLinearForwarder = linearForwarder;
|
|
10871
|
+
this.forwardedLinearPartKeys.clear();
|
|
10663
10872
|
try {
|
|
10664
10873
|
const client = await this.ensureClient(model);
|
|
10665
10874
|
const agent = request.planMode ? "plan" : "build";
|
|
@@ -10681,6 +10890,7 @@ var OpencodeManager = class extends CodingAgentManager {
|
|
|
10681
10890
|
}, { signal: controller.signal, throwOnError: true });
|
|
10682
10891
|
this.recordHistoryEvent("opencode-message.updated", { info: result.data.info }, this.historyFile);
|
|
10683
10892
|
for (const part of result.data.parts) this.recordOpencodePart(part);
|
|
10893
|
+
linearForwarder.flushThoughtAsResponse();
|
|
10684
10894
|
this.recordHistoryEvent("opencode-session.idle", { sessionID: sessionId }, this.historyFile);
|
|
10685
10895
|
} catch (error) {
|
|
10686
10896
|
if (controller.signal.aborted) {
|
|
@@ -10691,6 +10901,8 @@ var OpencodeManager = class extends CodingAgentManager {
|
|
|
10691
10901
|
}
|
|
10692
10902
|
} finally {
|
|
10693
10903
|
this.activeAbortController = null;
|
|
10904
|
+
this.activeLinearForwarder = null;
|
|
10905
|
+
this.forwardedLinearPartKeys.clear();
|
|
10694
10906
|
await this.historyFile.flush();
|
|
10695
10907
|
await this.onTurnComplete();
|
|
10696
10908
|
}
|
|
@@ -10814,8 +11026,20 @@ var OpencodeManager = class extends CodingAgentManager {
|
|
|
10814
11026
|
}
|
|
10815
11027
|
return false;
|
|
10816
11028
|
}
|
|
11029
|
+
forwardOpencodePartToLinear(part) {
|
|
11030
|
+
const linearSessionId = ENGINE_ENV.LINEAR_SESSION_ID;
|
|
11031
|
+
if (!linearSessionId || !this.activeLinearForwarder) return;
|
|
11032
|
+
const event = convertOpencodePart(part, linearSessionId);
|
|
11033
|
+
if (!event) return;
|
|
11034
|
+
if (typeof part.id !== "string") return;
|
|
11035
|
+
const key = `${part.type}:${part.id}:${JSON.stringify(event.content)}`;
|
|
11036
|
+
if (this.forwardedLinearPartKeys.has(key)) return;
|
|
11037
|
+
this.forwardedLinearPartKeys.add(key);
|
|
11038
|
+
this.activeLinearForwarder.sendEvent(event);
|
|
11039
|
+
}
|
|
10817
11040
|
recordOpencodePart(part) {
|
|
10818
11041
|
this.recordHistoryEvent(`opencode-part-${part.type}`, { part }, this.historyFile);
|
|
11042
|
+
this.forwardOpencodePartToLinear(part);
|
|
10819
11043
|
}
|
|
10820
11044
|
};
|
|
10821
11045
|
|