@adhdev/daemon-standalone 0.8.37 → 0.8.39

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/index.js CHANGED
@@ -34872,11 +34872,10 @@ ${effect.notification.body || ""}`.trim();
34872
34872
  }
34873
34873
  function findCdpManager(cdpManagers, key) {
34874
34874
  const exact = cdpManagers.get(key);
34875
- if (exact) return exact;
34875
+ if (exact) return exact.isConnected ? exact : null;
34876
34876
  const prefix = key + "_";
34877
- for (const [k, m] of cdpManagers.entries()) {
34878
- if (k.startsWith(prefix) && m.isConnected) return m;
34879
- }
34877
+ const matches = [...cdpManagers.entries()].filter(([k, m]) => m.isConnected && k.startsWith(prefix));
34878
+ if (matches.length === 1) return matches[0][1];
34880
34879
  return null;
34881
34880
  }
34882
34881
  function hasCdpManager(cdpManagers, key) {
@@ -34888,8 +34887,13 @@ ${effect.notification.body || ""}`.trim();
34888
34887
  return false;
34889
34888
  }
34890
34889
  function isCdpConnected(cdpManagers, key) {
34891
- const m = findCdpManager(cdpManagers, key);
34892
- return m?.isConnected ?? false;
34890
+ const exact = cdpManagers.get(key);
34891
+ if (exact?.isConnected) return true;
34892
+ const prefix = key + "_";
34893
+ for (const [k, m] of cdpManagers.entries()) {
34894
+ if (m.isConnected && k.startsWith(prefix)) return true;
34895
+ }
34896
+ return false;
34893
34897
  }
34894
34898
  function buildFallbackControls(providerControls, serverModel, serverMode, acpConfigOptions, acpModes) {
34895
34899
  if (providerControls && providerControls.length > 0) return providerControls;
@@ -41568,6 +41572,56 @@ Run 'adhdev doctor' for detailed diagnostics.`
41568
41572
  }
41569
41573
  return 0;
41570
41574
  }
41575
+ function stringifyPreviewContent(content) {
41576
+ if (typeof content === "string") return content;
41577
+ if (Array.isArray(content)) {
41578
+ return content.map((block) => {
41579
+ if (typeof block === "string") return block;
41580
+ if (block && typeof block === "object" && "text" in block) {
41581
+ return String(block.text || "");
41582
+ }
41583
+ return "";
41584
+ }).join(" ");
41585
+ }
41586
+ if (content && typeof content === "object" && "text" in content) {
41587
+ return String(content.text || "");
41588
+ }
41589
+ return String(content || "");
41590
+ }
41591
+ function normalizePreviewText(content) {
41592
+ return stringifyPreviewContent(content).replace(/\s+/g, " ").trim();
41593
+ }
41594
+ function clampPreviewText(value, maxChars = 120) {
41595
+ if (value.length <= maxChars) return value;
41596
+ if (maxChars <= 1) return value.slice(0, maxChars);
41597
+ return `${value.slice(0, maxChars - 1)}\u2026`;
41598
+ }
41599
+ function simplePreviewHash(value) {
41600
+ let h = 2166136261;
41601
+ for (let i = 0; i < value.length; i += 1) {
41602
+ h ^= value.charCodeAt(i);
41603
+ h = h * 16777619 >>> 0;
41604
+ }
41605
+ return h.toString(16);
41606
+ }
41607
+ function getLastDisplayMessage(session) {
41608
+ const messages = session.activeChat?.messages;
41609
+ if (!Array.isArray(messages) || messages.length === 0) return null;
41610
+ for (let i = messages.length - 1; i >= 0; i -= 1) {
41611
+ const candidate = messages[i];
41612
+ const role = typeof candidate?.role === "string" ? candidate.role : "";
41613
+ if (role === "system") continue;
41614
+ const preview = clampPreviewText(normalizePreviewText(candidate?.content));
41615
+ if (!preview) continue;
41616
+ return {
41617
+ role,
41618
+ preview,
41619
+ receivedAt: parseMessageTime(candidate?.receivedAt),
41620
+ hash: simplePreviewHash(`${role}:${preview}`)
41621
+ };
41622
+ }
41623
+ return null;
41624
+ }
41571
41625
  function getSessionMessageUpdatedAt(session) {
41572
41626
  const lastMessage = session.activeChat?.messages?.at?.(-1);
41573
41627
  if (!lastMessage) return 0;
@@ -41588,8 +41642,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
41588
41642
  return getSessionMessageUpdatedAt(session) || session.lastUpdated || Date.now();
41589
41643
  }
41590
41644
  function getLastMessageRole(session) {
41591
- const role = session.activeChat?.messages?.at?.(-1)?.role;
41592
- return typeof role === "string" ? role : "";
41645
+ return getLastDisplayMessage(session)?.role || "";
41593
41646
  }
41594
41647
  function getUnreadState(hasContentChange, status, lastUsedAt, lastSeenAt, lastRole, completionMarker, seenCompletionMarker) {
41595
41648
  if (status === "waiting_approval") {
@@ -41656,6 +41709,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
41656
41709
  `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)}`
41657
41710
  );
41658
41711
  }
41712
+ const lastDisplayMessage = getLastDisplayMessage(sourceSession);
41713
+ if (lastDisplayMessage) {
41714
+ session.lastMessagePreview = lastDisplayMessage.preview;
41715
+ session.lastMessageRole = lastDisplayMessage.role;
41716
+ if (lastDisplayMessage.receivedAt > 0) session.lastMessageAt = lastDisplayMessage.receivedAt;
41717
+ session.lastMessageHash = lastDisplayMessage.hash;
41718
+ }
41659
41719
  }
41660
41720
  const includeMachineMetadata = profile !== "live";
41661
41721
  const terminalBackend = includeMachineMetadata ? getTerminalBackendRuntimeStatus() : void 0;
@@ -44384,8 +44444,18 @@ async (params) => {
44384
44444
  }
44385
44445
  async function handleCdpTargets(ctx, _req, res) {
44386
44446
  const targets = [];
44387
- for (const [ide, cdp] of ctx.cdpManagers.entries()) {
44388
- targets.push({ ide, connected: cdp.isConnected, port: cdp.getPort() });
44447
+ for (const [managerKey, cdp] of ctx.cdpManagers.entries()) {
44448
+ const underscore = managerKey.indexOf("_");
44449
+ const ideBase = underscore === -1 ? managerKey : managerKey.slice(0, underscore);
44450
+ targets.push({
44451
+ managerKey,
44452
+ ide: managerKey,
44453
+ ideBase,
44454
+ pageTitle: cdp.pageTitle,
44455
+ targetId: cdp.targetId,
44456
+ connected: cdp.isConnected,
44457
+ port: cdp.getPort()
44458
+ });
44389
44459
  }
44390
44460
  ctx.json(res, 200, { targets });
44391
44461
  }
@@ -46100,6 +46170,16 @@ async (params) => {
46100
46170
  if (category === "cli") {
46101
46171
  return type === "codex-cli" ? "claude-cli" : "codex-cli";
46102
46172
  }
46173
+ if (category === "extension") {
46174
+ const preferred = ["claude-code-vscode", "codex", "cline", "roo-code"];
46175
+ for (const ref of preferred) {
46176
+ if (ref === type) continue;
46177
+ if (ctx.providerLoader.resolve(ref) || ctx.providerLoader.getMeta(ref)) return ref;
46178
+ }
46179
+ const all = ctx.providerLoader.getAll();
46180
+ const fb = all.find((p) => p.category === "extension" && p.type !== type);
46181
+ if (fb?.type) return fb.type;
46182
+ }
46103
46183
  return "antigravity";
46104
46184
  }
46105
46185
  function resolveAutoImplReference(ctx, category, requestedReference, targetType) {
@@ -46681,12 +46761,26 @@ async (params) => {
46681
46761
  return buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, referenceScripts, userComment, referenceType, verification);
46682
46762
  }
46683
46763
  const lines = [];
46764
+ const cdpIdeType = provider.category === "extension" ? "cursor" : type;
46684
46765
  lines.push("You are implementing browser automation scripts for an IDE provider.");
46685
46766
  lines.push("Be concise. Do NOT explain your reasoning. Just edit files directly.");
46686
46767
  lines.push("");
46687
46768
  lines.push(`# Target: ${provider.name || type} (${type})`);
46688
46769
  lines.push(`Provider directory: \`${providerDir}\``);
46689
46770
  lines.push("");
46771
+ if (provider.category === "extension") {
46772
+ lines.push("## CDP host (extension providers)");
46773
+ lines.push(
46774
+ `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.`
46775
+ );
46776
+ lines.push(
46777
+ `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.`
46778
+ );
46779
+ lines.push(
46780
+ "For VS Code hosts, use `vscode` or full `vscode_<targetId>` managerKey in every curl below."
46781
+ );
46782
+ lines.push("");
46783
+ }
46690
46784
  const funcToFile = {
46691
46785
  readChat: "read_chat.js",
46692
46786
  sendMessage: "send_message.js",
@@ -46867,14 +46961,14 @@ async (params) => {
46867
46961
  lines.push("```bash");
46868
46962
  lines.push(`curl -sS -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/cdp/evaluate \\`);
46869
46963
  lines.push(` -H "Content-Type: application/json" \\`);
46870
- lines.push(` -d '{"expression": "document.body.innerHTML.substring(0, 1000)", "ideType": "${type}"}'`);
46964
+ lines.push(` -d '{"expression": "document.body.innerHTML.substring(0, 1000)", "ideType": "${cdpIdeType}"}'`);
46871
46965
  lines.push("```");
46872
46966
  lines.push("");
46873
46967
  lines.push("### 2. Test your generated function");
46874
46968
  lines.push("Once you save the file, test it by running:");
46875
46969
  lines.push("```bash");
46876
46970
  lines.push(`curl -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/providers/reload`);
46877
- 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": "${type}"}'`);
46971
+ 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}"}'`);
46878
46972
  lines.push("```");
46879
46973
  lines.push("");
46880
46974
  lines.push("### Task Workflow");
@@ -46884,10 +46978,12 @@ async (params) => {
46884
46978
  lines.push("4. Reload providers and TEST your script via the API.");
46885
46979
  lines.push("");
46886
46980
  lines.push("### \u{1F525} Advanced UI Parsing (CRUCIAL for `readChat`)");
46887
- lines.push("Your `readChat` must flawlessly parse complex UI elements (tables, code blocks, tool calls, and AI thoughts). The quality must match the `antigravity` reference.");
46981
+ lines.push(
46982
+ `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).`
46983
+ );
46888
46984
  lines.push("To achieve this, you MUST generate a live test scenario:");
46889
46985
  lines.push(`1. Early in your process, send a rich prompt to the IDE using the API:`);
46890
- 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": "${type}", "args": {"message": "Write a python script, draw a markdown table, use a tool, and show your reasoning/thought process"}}'\``);
46986
+ 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"}}'\``);
46891
46987
  lines.push("2. Wait a few seconds for the IDE AI to generate these elements in the UI.");
46892
46988
  lines.push("3. Use CDP evaluate to deeply inspect the DOM structure of the newly generated tables, code blocks, thought blocks, and tool calls.");
46893
46989
  lines.push("4. Ensure `readChat` extracts `content` with precise markdown formatting (especially for tables/code) and assigns correct `kind` tags (`thought`, `tool`, `terminal`).");
@@ -46898,27 +46994,27 @@ async (params) => {
46898
46994
  lines.push("### Step 1: Baseline \u2014 confirm idle");
46899
46995
  lines.push("```bash");
46900
46996
  lines.push(`curl -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/providers/reload`);
46901
- 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": "${type}"}')`);
46997
+ 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}"}')`);
46902
46998
  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')"`);
46903
46999
  lines.push("```");
46904
47000
  lines.push("");
46905
47001
  lines.push("### Step 2: Send a LONG message that triggers extended generation (10+ seconds)");
46906
47002
  lines.push("```bash");
46907
- 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": "${type}", "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."}}'`);
47003
+ 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."}}'`);
46908
47004
  lines.push("sleep 3");
46909
47005
  lines.push("```");
46910
47006
  lines.push("");
46911
47007
  lines.push("### Step 3: Check generating OR completed");
46912
47008
  lines.push("The AI may still be generating OR may have finished already. Either generating or idle is acceptable:");
46913
47009
  lines.push("```bash");
46914
- 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": "${type}"}')`);
47010
+ 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}"}')`);
46915
47011
  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}')"`);
46916
47012
  lines.push("```");
46917
47013
  lines.push("");
46918
47014
  lines.push("### Step 4: Wait for completion and verify new message");
46919
47015
  lines.push("```bash");
46920
47016
  lines.push("sleep 10");
46921
- 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": "${type}"}')`);
47017
+ 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}"}')`);
46922
47018
  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)}')"`);
46923
47019
  lines.push("```");
46924
47020
  lines.push("");
@@ -48792,22 +48888,29 @@ data: ${JSON.stringify(msg.data)}
48792
48888
  }
48793
48889
  }
48794
48890
  }
48795
- /** Get CDP manager — matching IDE when ideType specified, first connected one otherwise.
48796
- * DevServer is a debugging tool so first-connected fallback is acceptable,
48797
- * but callers should pass ideType when possible. */
48891
+ /**
48892
+ * Resolve a CDP manager for DevServer APIs.
48893
+ * - Pass full **managerKey** from `GET /api/cdp/targets` when multiple Cursor/VS Code windows are open
48894
+ * (e.g. `cursor_0006DE34…`); short `cursor` only works when it maps to exactly one connected manager.
48895
+ * - With `ideType` omitted: only succeeds when exactly one connected manager exists.
48896
+ */
48798
48897
  getCdp(ideType) {
48799
48898
  if (ideType) {
48800
- const cdp = this.cdpManagers.get(ideType);
48801
- if (cdp?.isConnected) return cdp;
48802
- for (const [k, m] of this.cdpManagers.entries()) {
48803
- if (k.startsWith(ideType + "_") && m.isConnected) return m;
48804
- }
48805
- LOG2.warn("DevServer", `getCdp: no manager found for ideType '${ideType}', available: [${[...this.cdpManagers.keys()].join(", ")}]`);
48899
+ const cdp = findCdpManager(this.cdpManagers, ideType);
48900
+ if (cdp) return cdp;
48901
+ LOG2.warn(
48902
+ "DevServer",
48903
+ `getCdp: no unique match for '${ideType}', available: [${[...this.cdpManagers.keys()].join(", ")}] \u2014 use managerKey from GET /api/cdp/targets`
48904
+ );
48806
48905
  return null;
48807
48906
  }
48808
- for (const cdp of this.cdpManagers.values()) {
48809
- if (cdp.isConnected) return cdp;
48810
- }
48907
+ const connected = [...this.cdpManagers.entries()].filter(([, m]) => m.isConnected);
48908
+ if (connected.length === 1) return connected[0][1];
48909
+ if (connected.length === 0) return null;
48910
+ LOG2.warn(
48911
+ "DevServer",
48912
+ `getCdp: ideType omitted but ${connected.length} CDP windows \u2014 pass managerKey from GET /api/cdp/targets`
48913
+ );
48811
48914
  return null;
48812
48915
  }
48813
48916
  json(res, status, data) {
@@ -49373,6 +49476,19 @@ data: ${JSON.stringify(msg.data)}
49373
49476
  requiresApiKey: true,
49374
49477
  apiKeyName: "Anthropic/OpenAI API key"
49375
49478
  },
49479
+ {
49480
+ id: "claude-code-vscode",
49481
+ name: "Claude Code",
49482
+ displayName: "Claude Code (Anthropic)",
49483
+ marketplaceId: "anthropic.claude-code",
49484
+ description: "Anthropic Claude Code agent in VS Code\u2013compatible editors",
49485
+ category: "ai-agent",
49486
+ icon: "\u{1F7E0}",
49487
+ recommended: true,
49488
+ requiresApiKey: true,
49489
+ apiKeyName: "Anthropic account",
49490
+ website: "https://www.anthropic.com/claude-code"
49491
+ },
49376
49492
  {
49377
49493
  id: "continue",
49378
49494
  name: "Continue",