@adhdev/daemon-core 0.6.21 → 0.6.23

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.d.ts CHANGED
@@ -168,6 +168,7 @@ interface ADHDevConfig {
168
168
  recentWorkspaceActivity?: WorkspaceActivityEntry[];
169
169
  machineNickname: string | null;
170
170
  machineId?: string;
171
+ machineSecret?: string | null;
171
172
  cliHistory: CliHistoryEntry[];
172
173
  providerSettings: Record<string, Record<string, any>>;
173
174
  ideSettings: Record<string, {
@@ -175,6 +176,7 @@ interface ADHDevConfig {
175
176
  enabled: boolean;
176
177
  }>;
177
178
  }>;
179
+ disableUpstream?: boolean;
178
180
  }
179
181
  interface CliHistoryEntry {
180
182
  cliType: string;
@@ -957,6 +959,7 @@ declare class ProviderLoader {
957
959
  private builtinDirs;
958
960
  private userDir;
959
961
  private upstreamDir;
962
+ private disableUpstream;
960
963
  private watchers;
961
964
  private logFn;
962
965
  private versionArchive;
@@ -969,6 +972,8 @@ declare class ProviderLoader {
969
972
  builtinDir?: string | string[];
970
973
  userDir?: string;
971
974
  logFn?: (msg: string) => void;
975
+ /** Disable upstream auto-download (for dev/testing/OSS) */
976
+ disableUpstream?: boolean;
972
977
  });
973
978
  private log;
974
979
  /**
@@ -2202,7 +2207,6 @@ interface StatusReporterDeps {
2202
2207
  connectedPeerCount: number;
2203
2208
  screenshotActive: boolean;
2204
2209
  sendStatus(data: any): void;
2205
- sendStatusEvent?(event: Record<string, unknown>): boolean;
2206
2210
  } | null;
2207
2211
  providerLoader: {
2208
2212
  resolve(type: string): any;
@@ -2222,6 +2226,11 @@ interface StatusReporterDeps {
2222
2226
  collectAllStates(): ProviderState[];
2223
2227
  collectStatesByCategory(cat: string): ProviderState[];
2224
2228
  };
2229
+ getScreenshotUsage?: () => {
2230
+ dailyUsedMinutes: number;
2231
+ dailyBudgetMinutes: number;
2232
+ budgetExhausted: boolean;
2233
+ } | null;
2225
2234
  }
2226
2235
  declare class DaemonStatusReporter {
2227
2236
  private deps;
package/dist/index.js CHANGED
@@ -361,9 +361,11 @@ var init_config = __esm({
361
361
  recentWorkspaceActivity: [],
362
362
  machineNickname: null,
363
363
  machineId: void 0,
364
+ machineSecret: null,
364
365
  cliHistory: [],
365
366
  providerSettings: {},
366
- ideSettings: {}
367
+ ideSettings: {},
368
+ disableUpstream: false
367
369
  };
368
370
  }
369
371
  });
@@ -5716,6 +5718,7 @@ var ProviderLoader = class _ProviderLoader {
5716
5718
  builtinDirs;
5717
5719
  userDir;
5718
5720
  upstreamDir;
5721
+ disableUpstream;
5719
5722
  watchers = [];
5720
5723
  logFn;
5721
5724
  versionArchive = null;
@@ -5734,6 +5737,7 @@ var ProviderLoader = class _ProviderLoader {
5734
5737
  }
5735
5738
  this.userDir = options?.userDir || path6.join(os7.homedir(), ".adhdev", "providers");
5736
5739
  this.upstreamDir = path6.join(this.userDir, ".upstream");
5740
+ this.disableUpstream = options?.disableUpstream ?? false;
5737
5741
  this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
5738
5742
  }
5739
5743
  log(msg) {
@@ -5750,11 +5754,13 @@ var ProviderLoader = class _ProviderLoader {
5750
5754
  loadAll() {
5751
5755
  this.providers.clear();
5752
5756
  let upstreamCount = 0;
5753
- if (fs5.existsSync(this.upstreamDir)) {
5757
+ if (!this.disableUpstream && fs5.existsSync(this.upstreamDir)) {
5754
5758
  upstreamCount = this.loadDir(this.upstreamDir);
5755
5759
  if (upstreamCount > 0) {
5756
5760
  this.log(`Loaded ${upstreamCount} upstream providers (auto-updated)`);
5757
5761
  }
5762
+ } else if (this.disableUpstream) {
5763
+ this.log("Upstream loading disabled (disableUpstream=true)");
5758
5764
  }
5759
5765
  if (fs5.existsSync(this.userDir)) {
5760
5766
  const userCount = this.loadDir(this.userDir, [".upstream"]);
@@ -6157,6 +6163,10 @@ var ProviderLoader = class _ProviderLoader {
6157
6163
  * @returns Whether an update occurred
6158
6164
  */
6159
6165
  async fetchLatest() {
6166
+ if (this.disableUpstream) {
6167
+ this.log("Upstream fetch skipped (disableUpstream=true)");
6168
+ return { updated: false };
6169
+ }
6160
6170
  const https = require("https");
6161
6171
  const { execSync: execSync7 } = require("child_process");
6162
6172
  const metaPath = path6.join(this.upstreamDir, _ProviderLoader.META_FILE);
@@ -7458,12 +7468,6 @@ var DaemonStatusReporter = class {
7458
7468
  emitStatusEvent(event) {
7459
7469
  LOG.info("StatusEvent", `${event.event} (${event.providerType || event.ideType || ""})`);
7460
7470
  this.deps.serverConn?.sendMessage("status_event", event);
7461
- if (this.deps.p2p?.isConnected) {
7462
- try {
7463
- this.deps.p2p.sendStatusEvent?.(event);
7464
- } catch {
7465
- }
7466
- }
7467
7471
  }
7468
7472
  removeAgentTracking(_key) {
7469
7473
  }
@@ -7541,6 +7545,7 @@ var DaemonStatusReporter = class {
7541
7545
  peers: p2p?.connectedPeerCount || 0,
7542
7546
  screenshotActive: p2p?.screenshotActive || false
7543
7547
  },
7548
+ screenshotUsage: this.deps.getScreenshotUsage?.() || null,
7544
7549
  connectedExtensions: [],
7545
7550
  detectedIdes: this.deps.detectedIdes || [],
7546
7551
  availableProviders: this.deps.providerLoader.getAll().map((p) => ({
@@ -12525,6 +12530,22 @@ var DevServer = class _DevServer {
12525
12530
  lines.push("| focusEditor | `{ focused: true/false }` |");
12526
12531
  lines.push("| openPanel | `{ opened: true/false }` |");
12527
12532
  lines.push("");
12533
+ lines.push("## \u{1F534} CRITICAL: readChat `status` Lifecycle");
12534
+ lines.push("The `status` field in readChat controls how the dashboard and daemon auto-approve-loop behave.");
12535
+ lines.push("Getting this wrong will break the entire automation pipeline. The status MUST reflect the ACTUAL current state:");
12536
+ lines.push("");
12537
+ lines.push("| Status | When to use | How to detect |");
12538
+ lines.push("|---|---|---|");
12539
+ lines.push("| `idle` | AI is NOT generating, no approval needed | Default state. No stop button, no spinners, no approval pills/buttons |");
12540
+ lines.push("| `generating` | AI is actively streaming/thinking | ANY of: (1) Stop/Cancel button visible, (2) CSS animation (animate-spin/pulse/bounce), (3) floating state text like Thinking/Generating/Sailing, (4) streaming indicator class |");
12541
+ lines.push("| `waiting_approval` | AI stopped and needs user action | Actionable buttons like Run/Skip/Accept/Reject are visible AND clickable |");
12542
+ lines.push("");
12543
+ lines.push("### \u26A0\uFE0F Status Detection Gotchas (MUST READ!)");
12544
+ lines.push('1. **FALSE POSITIVES from old messages**: Chat history may contain text like "Command Awaiting Approval" from PAST turns. If you search the entire chat panel for this text, you will get false matches from parent divs whose innerText includes ALL child text. ONLY match small leaf elements (under 80 chars) or use explicit button/pill selectors.');
12545
+ lines.push('2. **Awaiting Approval pill without actions**: Some IDEs show a floating pill/banner saying "Awaiting Approval" that is just a scroll-to indicator (not an actual approval dialog). If this pill exists but NO actionable buttons (Run/Skip/Accept/Reject) exist anywhere in the panel, the status should be `idle`, NOT `waiting_approval`.');
12546
+ lines.push("3. **generating detection must be multi-signal**: Do NOT rely on just one indicator. Check ALL of: stop buttons, CSS animations, floating state labels, streaming classes. IDEs differ widely.");
12547
+ lines.push("4. **activeModal must include actions**: When `status` is `waiting_approval`, the `activeModal` object MUST include a non-empty `actions` array listing the button labels. If you cannot find any action buttons, the status is NOT `waiting_approval`.");
12548
+ lines.push("");
12528
12549
  lines.push("## Action");
12529
12550
  lines.push("1. Edit the script files to implement working code");
12530
12551
  lines.push("2. After editing, TEST each function using the DevConsole API (see below)");
@@ -12549,7 +12570,7 @@ var DevServer = class _DevServer {
12549
12570
  lines.push("Once you save the file, test it by running:");
12550
12571
  lines.push("```bash");
12551
12572
  lines.push(`curl -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/providers/reload`);
12552
- lines.push(`curl -sS -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/providers/${type}/scripts/run -H "Content-Type: application/json" -d '{"script": "readChat"}'`);
12573
+ 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}"}'`);
12553
12574
  lines.push("```");
12554
12575
  lines.push("");
12555
12576
  lines.push("### Task Workflow");
@@ -12561,12 +12582,44 @@ var DevServer = class _DevServer {
12561
12582
  lines.push("### \u{1F525} Advanced UI Parsing (CRUCIAL for `readChat`)");
12562
12583
  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.");
12563
12584
  lines.push("To achieve this, you MUST generate a live test scenario:");
12564
- lines.push("1. Early in your process, send a rich prompt to the IDE using the API:");
12565
- lines.push(' `curl -sS -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/providers/${type}/scripts/run -H "Content-Type: application/json" -d \'{"script": "sendMessage", "params": {"text": "Write a python script, draw a markdown table, use a tool, and show your reasoning/thought process"}}\'`');
12585
+ lines.push(`1. Early in your process, send a rich prompt to the IDE using the API:`);
12586
+ 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"}}'\``);
12566
12587
  lines.push("2. Wait a few seconds for the IDE AI to generate these elements in the UI.");
12567
12588
  lines.push("3. Use CDP evaluate to deeply inspect the DOM structure of the newly generated tables, code blocks, thought blocks, and tool calls.");
12568
12589
  lines.push("4. Ensure `readChat` extracts `content` with precise markdown formatting (especially for tables/code) and assigns correct `kind` tags (`thought`, `tool`, `terminal`).");
12569
12590
  lines.push("");
12591
+ lines.push("## \u{1F9EA} MANDATORY: Status Integration Test");
12592
+ lines.push("Before finishing, you MUST run this end-to-end test to verify readChat status transitions work:");
12593
+ lines.push("");
12594
+ lines.push("### Step 1: Baseline \u2014 confirm idle");
12595
+ lines.push("```bash");
12596
+ lines.push(`curl -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/providers/reload`);
12597
+ 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}"}')`);
12598
+ 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')"`);
12599
+ lines.push("```");
12600
+ lines.push("");
12601
+ lines.push("### Step 2: Send a message that triggers generation");
12602
+ lines.push("```bash");
12603
+ 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": "Say hello in one word"}}'`);
12604
+ lines.push("sleep 2");
12605
+ lines.push("```");
12606
+ lines.push("");
12607
+ lines.push("### Step 3: Check generating OR completed");
12608
+ lines.push("The AI may still be generating OR may have finished already. Either generating or idle is acceptable:");
12609
+ lines.push("```bash");
12610
+ 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}"}')`);
12611
+ 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}')"`);
12612
+ lines.push("```");
12613
+ lines.push("");
12614
+ lines.push("### Step 4: Wait for completion and verify new message");
12615
+ lines.push("```bash");
12616
+ lines.push("sleep 10");
12617
+ 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}"}')`);
12618
+ 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)}')"`);
12619
+ lines.push("```");
12620
+ lines.push("");
12621
+ lines.push("If ANY step fails, fix your implementation and re-run the test. Do NOT finish until all 4 steps pass.");
12622
+ lines.push("");
12570
12623
  if (userComment) {
12571
12624
  lines.push("## \u26A0\uFE0F User Instructions (HIGH PRIORITY)");
12572
12625
  lines.push("The user has provided the following additional instructions. Follow them strictly:");
@@ -13095,10 +13148,13 @@ init_logger();
13095
13148
  init_config();
13096
13149
  async function initDaemonComponents(config) {
13097
13150
  installGlobalInterceptor();
13151
+ const appConfig = loadConfig();
13152
+ const disableUpstream = appConfig.disableUpstream ?? false;
13098
13153
  const providerLoader = new ProviderLoader({
13099
- logFn: config.providerLogFn
13154
+ logFn: config.providerLogFn,
13155
+ disableUpstream
13100
13156
  });
13101
- if (!providerLoader.hasUpstream()) {
13157
+ if (!disableUpstream && !providerLoader.hasUpstream()) {
13102
13158
  LOG.info("Provider", "No upstream providers found \u2014 downloading from GitHub...");
13103
13159
  try {
13104
13160
  await providerLoader.fetchLatest();