@adhdev/daemon-core 0.8.36 → 0.8.38
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/daemon/dev-server.d.ts +6 -3
- package/dist/index.js +146 -30
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +146 -30
- package/dist/index.mjs.map +1 -1
- package/dist/shared-types.d.ts +4 -0
- package/dist/status/builders.d.ts +4 -7
- package/node_modules/@adhdev/session-host-core/package.json +1 -1
- package/package.json +1 -1
- package/src/daemon/dev-auto-implement.ts +36 -8
- package/src/daemon/dev-cdp-handlers.ts +22 -3
- package/src/daemon/dev-server.ts +20 -14
- package/src/installer.ts +13 -0
- package/src/shared-types.ts +4 -0
- package/src/status/builders.ts +17 -16
- package/src/status/snapshot.ts +73 -2
package/dist/index.mjs
CHANGED
|
@@ -7035,11 +7035,10 @@ function shouldIncludeRuntimeMetadata(profile) {
|
|
|
7035
7035
|
}
|
|
7036
7036
|
function findCdpManager(cdpManagers, key) {
|
|
7037
7037
|
const exact = cdpManagers.get(key);
|
|
7038
|
-
if (exact) return exact;
|
|
7038
|
+
if (exact) return exact.isConnected ? exact : null;
|
|
7039
7039
|
const prefix = key + "_";
|
|
7040
|
-
|
|
7041
|
-
|
|
7042
|
-
}
|
|
7040
|
+
const matches = [...cdpManagers.entries()].filter(([k, m]) => m.isConnected && k.startsWith(prefix));
|
|
7041
|
+
if (matches.length === 1) return matches[0][1];
|
|
7043
7042
|
return null;
|
|
7044
7043
|
}
|
|
7045
7044
|
function hasCdpManager(cdpManagers, key) {
|
|
@@ -7051,8 +7050,13 @@ function hasCdpManager(cdpManagers, key) {
|
|
|
7051
7050
|
return false;
|
|
7052
7051
|
}
|
|
7053
7052
|
function isCdpConnected(cdpManagers, key) {
|
|
7054
|
-
const
|
|
7055
|
-
|
|
7053
|
+
const exact = cdpManagers.get(key);
|
|
7054
|
+
if (exact?.isConnected) return true;
|
|
7055
|
+
const prefix = key + "_";
|
|
7056
|
+
for (const [k, m] of cdpManagers.entries()) {
|
|
7057
|
+
if (m.isConnected && k.startsWith(prefix)) return true;
|
|
7058
|
+
}
|
|
7059
|
+
return false;
|
|
7056
7060
|
}
|
|
7057
7061
|
function buildFallbackControls(providerControls, serverModel, serverMode, acpConfigOptions, acpModes) {
|
|
7058
7062
|
if (providerControls && providerControls.length > 0) return providerControls;
|
|
@@ -13774,6 +13778,56 @@ function parseMessageTime(value) {
|
|
|
13774
13778
|
}
|
|
13775
13779
|
return 0;
|
|
13776
13780
|
}
|
|
13781
|
+
function stringifyPreviewContent(content) {
|
|
13782
|
+
if (typeof content === "string") return content;
|
|
13783
|
+
if (Array.isArray(content)) {
|
|
13784
|
+
return content.map((block) => {
|
|
13785
|
+
if (typeof block === "string") return block;
|
|
13786
|
+
if (block && typeof block === "object" && "text" in block) {
|
|
13787
|
+
return String(block.text || "");
|
|
13788
|
+
}
|
|
13789
|
+
return "";
|
|
13790
|
+
}).join(" ");
|
|
13791
|
+
}
|
|
13792
|
+
if (content && typeof content === "object" && "text" in content) {
|
|
13793
|
+
return String(content.text || "");
|
|
13794
|
+
}
|
|
13795
|
+
return String(content || "");
|
|
13796
|
+
}
|
|
13797
|
+
function normalizePreviewText(content) {
|
|
13798
|
+
return stringifyPreviewContent(content).replace(/\s+/g, " ").trim();
|
|
13799
|
+
}
|
|
13800
|
+
function clampPreviewText(value, maxChars = 120) {
|
|
13801
|
+
if (value.length <= maxChars) return value;
|
|
13802
|
+
if (maxChars <= 1) return value.slice(0, maxChars);
|
|
13803
|
+
return `${value.slice(0, maxChars - 1)}\u2026`;
|
|
13804
|
+
}
|
|
13805
|
+
function simplePreviewHash(value) {
|
|
13806
|
+
let h = 2166136261;
|
|
13807
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
13808
|
+
h ^= value.charCodeAt(i);
|
|
13809
|
+
h = h * 16777619 >>> 0;
|
|
13810
|
+
}
|
|
13811
|
+
return h.toString(16);
|
|
13812
|
+
}
|
|
13813
|
+
function getLastDisplayMessage(session) {
|
|
13814
|
+
const messages = session.activeChat?.messages;
|
|
13815
|
+
if (!Array.isArray(messages) || messages.length === 0) return null;
|
|
13816
|
+
for (let i = messages.length - 1; i >= 0; i -= 1) {
|
|
13817
|
+
const candidate = messages[i];
|
|
13818
|
+
const role = typeof candidate?.role === "string" ? candidate.role : "";
|
|
13819
|
+
if (role === "system") continue;
|
|
13820
|
+
const preview = clampPreviewText(normalizePreviewText(candidate?.content));
|
|
13821
|
+
if (!preview) continue;
|
|
13822
|
+
return {
|
|
13823
|
+
role,
|
|
13824
|
+
preview,
|
|
13825
|
+
receivedAt: parseMessageTime(candidate?.receivedAt),
|
|
13826
|
+
hash: simplePreviewHash(`${role}:${preview}`)
|
|
13827
|
+
};
|
|
13828
|
+
}
|
|
13829
|
+
return null;
|
|
13830
|
+
}
|
|
13777
13831
|
function getSessionMessageUpdatedAt(session) {
|
|
13778
13832
|
const lastMessage = session.activeChat?.messages?.at?.(-1);
|
|
13779
13833
|
if (!lastMessage) return 0;
|
|
@@ -13794,8 +13848,7 @@ function getSessionLastUsedAt(session) {
|
|
|
13794
13848
|
return getSessionMessageUpdatedAt(session) || session.lastUpdated || Date.now();
|
|
13795
13849
|
}
|
|
13796
13850
|
function getLastMessageRole(session) {
|
|
13797
|
-
|
|
13798
|
-
return typeof role === "string" ? role : "";
|
|
13851
|
+
return getLastDisplayMessage(session)?.role || "";
|
|
13799
13852
|
}
|
|
13800
13853
|
function getUnreadState(hasContentChange, status, lastUsedAt, lastSeenAt, lastRole, completionMarker, seenCompletionMarker) {
|
|
13801
13854
|
if (status === "waiting_approval") {
|
|
@@ -13862,6 +13915,13 @@ function buildStatusSnapshot(options) {
|
|
|
13862
13915
|
`snapshot session id=${session.id} provider=${session.providerType} status=${String(session.status || "")} bucket=${inboxBucket} unread=${String(unread)} lastSeenAt=${lastSeenAt} completionMarker=${completionMarker || "-"} seenMarker=${seenCompletionMarker || "-"} lastUpdated=${String(session.lastUpdated || 0)} lastUsedAt=${lastUsedAt} lastRole=${getLastMessageRole(sourceSession)} msgUpdatedAt=${getSessionMessageUpdatedAt(sourceSession)}`
|
|
13863
13916
|
);
|
|
13864
13917
|
}
|
|
13918
|
+
const lastDisplayMessage = getLastDisplayMessage(sourceSession);
|
|
13919
|
+
if (lastDisplayMessage) {
|
|
13920
|
+
session.lastMessagePreview = lastDisplayMessage.preview;
|
|
13921
|
+
session.lastMessageRole = lastDisplayMessage.role;
|
|
13922
|
+
if (lastDisplayMessage.receivedAt > 0) session.lastMessageAt = lastDisplayMessage.receivedAt;
|
|
13923
|
+
session.lastMessageHash = lastDisplayMessage.hash;
|
|
13924
|
+
}
|
|
13865
13925
|
}
|
|
13866
13926
|
const includeMachineMetadata = profile !== "live";
|
|
13867
13927
|
const terminalBackend = includeMachineMetadata ? getTerminalBackendRuntimeStatus() : void 0;
|
|
@@ -16620,8 +16680,18 @@ async function handleScriptHints(ctx, type, _req, res) {
|
|
|
16620
16680
|
}
|
|
16621
16681
|
async function handleCdpTargets(ctx, _req, res) {
|
|
16622
16682
|
const targets = [];
|
|
16623
|
-
for (const [
|
|
16624
|
-
|
|
16683
|
+
for (const [managerKey, cdp] of ctx.cdpManagers.entries()) {
|
|
16684
|
+
const underscore = managerKey.indexOf("_");
|
|
16685
|
+
const ideBase = underscore === -1 ? managerKey : managerKey.slice(0, underscore);
|
|
16686
|
+
targets.push({
|
|
16687
|
+
managerKey,
|
|
16688
|
+
ide: managerKey,
|
|
16689
|
+
ideBase,
|
|
16690
|
+
pageTitle: cdp.pageTitle,
|
|
16691
|
+
targetId: cdp.targetId,
|
|
16692
|
+
connected: cdp.isConnected,
|
|
16693
|
+
port: cdp.getPort()
|
|
16694
|
+
});
|
|
16625
16695
|
}
|
|
16626
16696
|
ctx.json(res, 200, { targets });
|
|
16627
16697
|
}
|
|
@@ -18340,6 +18410,16 @@ function getDefaultAutoImplReference(ctx, category, type) {
|
|
|
18340
18410
|
if (category === "cli") {
|
|
18341
18411
|
return type === "codex-cli" ? "claude-cli" : "codex-cli";
|
|
18342
18412
|
}
|
|
18413
|
+
if (category === "extension") {
|
|
18414
|
+
const preferred = ["claude-code-vscode", "codex", "cline", "roo-code"];
|
|
18415
|
+
for (const ref of preferred) {
|
|
18416
|
+
if (ref === type) continue;
|
|
18417
|
+
if (ctx.providerLoader.resolve(ref) || ctx.providerLoader.getMeta(ref)) return ref;
|
|
18418
|
+
}
|
|
18419
|
+
const all = ctx.providerLoader.getAll();
|
|
18420
|
+
const fb = all.find((p) => p.category === "extension" && p.type !== type);
|
|
18421
|
+
if (fb?.type) return fb.type;
|
|
18422
|
+
}
|
|
18343
18423
|
return "antigravity";
|
|
18344
18424
|
}
|
|
18345
18425
|
function resolveAutoImplReference(ctx, category, requestedReference, targetType) {
|
|
@@ -18921,12 +19001,26 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
18921
19001
|
return buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, referenceScripts, userComment, referenceType, verification);
|
|
18922
19002
|
}
|
|
18923
19003
|
const lines = [];
|
|
19004
|
+
const cdpIdeType = provider.category === "extension" ? "cursor" : type;
|
|
18924
19005
|
lines.push("You are implementing browser automation scripts for an IDE provider.");
|
|
18925
19006
|
lines.push("Be concise. Do NOT explain your reasoning. Just edit files directly.");
|
|
18926
19007
|
lines.push("");
|
|
18927
19008
|
lines.push(`# Target: ${provider.name || type} (${type})`);
|
|
18928
19009
|
lines.push(`Provider directory: \`${providerDir}\``);
|
|
18929
19010
|
lines.push("");
|
|
19011
|
+
if (provider.category === "extension") {
|
|
19012
|
+
lines.push("## CDP host (extension providers)");
|
|
19013
|
+
lines.push(
|
|
19014
|
+
`Extension **${type}** runs inside a host IDE. For \`/api/scripts/run\` and \`/api/cdp/evaluate\`, keep \`"type": "${type}"\` (which provider scripts run) but set \`"ideType"\` to the DevServer CDP **managerKey** for that window.`
|
|
19015
|
+
);
|
|
19016
|
+
lines.push(
|
|
19017
|
+
`Examples use \`"ideType": "${cdpIdeType}"\` (Cursor). If **multiple** IDE windows are connected, run \`GET /api/cdp/targets\` and use the correct \`managerKey\` / \`pageTitle\` \u2014 short \`cursor\` or \`vscode\` only works when it uniquely identifies one window.`
|
|
19018
|
+
);
|
|
19019
|
+
lines.push(
|
|
19020
|
+
"For VS Code hosts, use `vscode` or full `vscode_<targetId>` managerKey in every curl below."
|
|
19021
|
+
);
|
|
19022
|
+
lines.push("");
|
|
19023
|
+
}
|
|
18930
19024
|
const funcToFile = {
|
|
18931
19025
|
readChat: "read_chat.js",
|
|
18932
19026
|
sendMessage: "send_message.js",
|
|
@@ -19107,14 +19201,14 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
19107
19201
|
lines.push("```bash");
|
|
19108
19202
|
lines.push(`curl -sS -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/cdp/evaluate \\`);
|
|
19109
19203
|
lines.push(` -H "Content-Type: application/json" \\`);
|
|
19110
|
-
lines.push(` -d '{"expression": "document.body.innerHTML.substring(0, 1000)", "ideType": "${
|
|
19204
|
+
lines.push(` -d '{"expression": "document.body.innerHTML.substring(0, 1000)", "ideType": "${cdpIdeType}"}'`);
|
|
19111
19205
|
lines.push("```");
|
|
19112
19206
|
lines.push("");
|
|
19113
19207
|
lines.push("### 2. Test your generated function");
|
|
19114
19208
|
lines.push("Once you save the file, test it by running:");
|
|
19115
19209
|
lines.push("```bash");
|
|
19116
19210
|
lines.push(`curl -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/providers/reload`);
|
|
19117
|
-
lines.push(`curl -sS -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/scripts/run -H "Content-Type: application/json" -d '{"script": "readChat", "type": "${type}", "ideType": "${
|
|
19211
|
+
lines.push(`curl -sS -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/scripts/run -H "Content-Type: application/json" -d '{"script": "readChat", "type": "${type}", "ideType": "${cdpIdeType}"}'`);
|
|
19118
19212
|
lines.push("```");
|
|
19119
19213
|
lines.push("");
|
|
19120
19214
|
lines.push("### Task Workflow");
|
|
@@ -19124,10 +19218,12 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
19124
19218
|
lines.push("4. Reload providers and TEST your script via the API.");
|
|
19125
19219
|
lines.push("");
|
|
19126
19220
|
lines.push("### \u{1F525} Advanced UI Parsing (CRUCIAL for `readChat`)");
|
|
19127
|
-
lines.push(
|
|
19221
|
+
lines.push(
|
|
19222
|
+
`Your \`readChat\` must flawlessly parse complex UI elements (tables, code blocks, tool calls, and AI thoughts). Match the depth of the **${referenceType || "reference"}** scripts above (patterns and structure, not necessarily the same DOM).`
|
|
19223
|
+
);
|
|
19128
19224
|
lines.push("To achieve this, you MUST generate a live test scenario:");
|
|
19129
19225
|
lines.push(`1. Early in your process, send a rich prompt to the IDE using the API:`);
|
|
19130
|
-
lines.push(` \`curl -sS -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/scripts/run -H "Content-Type: application/json" -d '{"script": "sendMessage", "type": "${type}", "ideType": "${
|
|
19226
|
+
lines.push(` \`curl -sS -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/scripts/run -H "Content-Type: application/json" -d '{"script": "sendMessage", "type": "${type}", "ideType": "${cdpIdeType}", "args": {"message": "Write a python script, draw a markdown table, use a tool, and show your reasoning/thought process"}}'\``);
|
|
19131
19227
|
lines.push("2. Wait a few seconds for the IDE AI to generate these elements in the UI.");
|
|
19132
19228
|
lines.push("3. Use CDP evaluate to deeply inspect the DOM structure of the newly generated tables, code blocks, thought blocks, and tool calls.");
|
|
19133
19229
|
lines.push("4. Ensure `readChat` extracts `content` with precise markdown formatting (especially for tables/code) and assigns correct `kind` tags (`thought`, `tool`, `terminal`).");
|
|
@@ -19138,27 +19234,27 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
19138
19234
|
lines.push("### Step 1: Baseline \u2014 confirm idle");
|
|
19139
19235
|
lines.push("```bash");
|
|
19140
19236
|
lines.push(`curl -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/providers/reload`);
|
|
19141
|
-
lines.push(`RESULT=$(curl -sS -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/scripts/run -H "Content-Type: application/json" -d '{"script": "readChat", "type": "${type}", "ideType": "${
|
|
19237
|
+
lines.push(`RESULT=$(curl -sS -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/scripts/run -H "Content-Type: application/json" -d '{"script": "readChat", "type": "${type}", "ideType": "${cdpIdeType}"}')`);
|
|
19142
19238
|
lines.push(`echo "$RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); r=d.get('result',d); r=json.loads(r) if isinstance(r,str) else r; assert r.get('status')=='idle', f'Expected idle, got {r.get(chr(34)+chr(115)+chr(116)+chr(97)+chr(116)+chr(117)+chr(115)+chr(34))}'; print('Step 1 PASS: status=idle')"`);
|
|
19143
19239
|
lines.push("```");
|
|
19144
19240
|
lines.push("");
|
|
19145
19241
|
lines.push("### Step 2: Send a LONG message that triggers extended generation (10+ seconds)");
|
|
19146
19242
|
lines.push("```bash");
|
|
19147
|
-
lines.push(`curl -sS -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/scripts/run -H "Content-Type: application/json" -d '{"script": "sendMessage", "type": "${type}", "ideType": "${
|
|
19243
|
+
lines.push(`curl -sS -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/scripts/run -H "Content-Type: application/json" -d '{"script": "sendMessage", "type": "${type}", "ideType": "${cdpIdeType}", "args": {"message": "Write an extremely detailed 5000-word essay about the history of artificial intelligence from Alan Turing to 2025. Be very thorough and verbose."}}'`);
|
|
19148
19244
|
lines.push("sleep 3");
|
|
19149
19245
|
lines.push("```");
|
|
19150
19246
|
lines.push("");
|
|
19151
19247
|
lines.push("### Step 3: Check generating OR completed");
|
|
19152
19248
|
lines.push("The AI may still be generating OR may have finished already. Either generating or idle is acceptable:");
|
|
19153
19249
|
lines.push("```bash");
|
|
19154
|
-
lines.push(`RESULT=$(curl -sS -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/scripts/run -H "Content-Type: application/json" -d '{"script": "readChat", "type": "${type}", "ideType": "${
|
|
19250
|
+
lines.push(`RESULT=$(curl -sS -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/scripts/run -H "Content-Type: application/json" -d '{"script": "readChat", "type": "${type}", "ideType": "${cdpIdeType}"}')`);
|
|
19155
19251
|
lines.push(`echo "$RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); r=d.get('result',d); r=json.loads(r) if isinstance(r,str) else r; s=r.get('status'); assert s in ('generating','idle','waiting_approval'), f'Unexpected: {s}'; print(f'Step 3 PASS: status={s}')"`);
|
|
19156
19252
|
lines.push("```");
|
|
19157
19253
|
lines.push("");
|
|
19158
19254
|
lines.push("### Step 4: Wait for completion and verify new message");
|
|
19159
19255
|
lines.push("```bash");
|
|
19160
19256
|
lines.push("sleep 10");
|
|
19161
|
-
lines.push(`RESULT=$(curl -sS -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/scripts/run -H "Content-Type: application/json" -d '{"script": "readChat", "type": "${type}", "ideType": "${
|
|
19257
|
+
lines.push(`RESULT=$(curl -sS -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/scripts/run -H "Content-Type: application/json" -d '{"script": "readChat", "type": "${type}", "ideType": "${cdpIdeType}"}')`);
|
|
19162
19258
|
lines.push(`echo "$RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); r=d.get('result',d); r=json.loads(r) if isinstance(r,str) else r; s=r.get('status'); msgs=r.get('messages',[]); assert s=='idle', f'Expected idle, got {s}'; assert len(msgs)>0, 'No messages'; print(f'Step 4 PASS: status={s}, messages={len(msgs)}')"`);
|
|
19163
19259
|
lines.push("```");
|
|
19164
19260
|
lines.push("");
|
|
@@ -21034,22 +21130,29 @@ data: ${JSON.stringify(msg.data)}
|
|
|
21034
21130
|
}
|
|
21035
21131
|
}
|
|
21036
21132
|
}
|
|
21037
|
-
/**
|
|
21038
|
-
*
|
|
21039
|
-
*
|
|
21133
|
+
/**
|
|
21134
|
+
* Resolve a CDP manager for DevServer APIs.
|
|
21135
|
+
* - Pass full **managerKey** from `GET /api/cdp/targets` when multiple Cursor/VS Code windows are open
|
|
21136
|
+
* (e.g. `cursor_0006DE34…`); short `cursor` only works when it maps to exactly one connected manager.
|
|
21137
|
+
* - With `ideType` omitted: only succeeds when exactly one connected manager exists.
|
|
21138
|
+
*/
|
|
21040
21139
|
getCdp(ideType) {
|
|
21041
21140
|
if (ideType) {
|
|
21042
|
-
const cdp = this.cdpManagers
|
|
21043
|
-
if (cdp
|
|
21044
|
-
|
|
21045
|
-
|
|
21046
|
-
|
|
21047
|
-
|
|
21141
|
+
const cdp = findCdpManager(this.cdpManagers, ideType);
|
|
21142
|
+
if (cdp) return cdp;
|
|
21143
|
+
LOG.warn(
|
|
21144
|
+
"DevServer",
|
|
21145
|
+
`getCdp: no unique match for '${ideType}', available: [${[...this.cdpManagers.keys()].join(", ")}] \u2014 use managerKey from GET /api/cdp/targets`
|
|
21146
|
+
);
|
|
21048
21147
|
return null;
|
|
21049
21148
|
}
|
|
21050
|
-
|
|
21051
|
-
|
|
21052
|
-
|
|
21149
|
+
const connected = [...this.cdpManagers.entries()].filter(([, m]) => m.isConnected);
|
|
21150
|
+
if (connected.length === 1) return connected[0][1];
|
|
21151
|
+
if (connected.length === 0) return null;
|
|
21152
|
+
LOG.warn(
|
|
21153
|
+
"DevServer",
|
|
21154
|
+
`getCdp: ideType omitted but ${connected.length} CDP windows \u2014 pass managerKey from GET /api/cdp/targets`
|
|
21155
|
+
);
|
|
21053
21156
|
return null;
|
|
21054
21157
|
}
|
|
21055
21158
|
json(res, status, data) {
|
|
@@ -21628,6 +21731,19 @@ var EXTENSION_CATALOG = [
|
|
|
21628
21731
|
requiresApiKey: true,
|
|
21629
21732
|
apiKeyName: "Anthropic/OpenAI API key"
|
|
21630
21733
|
},
|
|
21734
|
+
{
|
|
21735
|
+
id: "claude-code-vscode",
|
|
21736
|
+
name: "Claude Code",
|
|
21737
|
+
displayName: "Claude Code (Anthropic)",
|
|
21738
|
+
marketplaceId: "anthropic.claude-code",
|
|
21739
|
+
description: "Anthropic Claude Code agent in VS Code\u2013compatible editors",
|
|
21740
|
+
category: "ai-agent",
|
|
21741
|
+
icon: "\u{1F7E0}",
|
|
21742
|
+
recommended: true,
|
|
21743
|
+
requiresApiKey: true,
|
|
21744
|
+
apiKeyName: "Anthropic account",
|
|
21745
|
+
website: "https://www.anthropic.com/claude-code"
|
|
21746
|
+
},
|
|
21631
21747
|
{
|
|
21632
21748
|
id: "continue",
|
|
21633
21749
|
name: "Continue",
|