adhdev 0.6.50 → 0.6.52

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
@@ -5074,6 +5074,76 @@ var init_provider_loader = __esm({
5074
5074
  }
5075
5075
  // ─── Public API ────────────────────────────────
5076
5076
  /**
5077
+ * Ordered builtin roots used for local fallback/reference data.
5078
+ */
5079
+ getBuiltinDirs() {
5080
+ return [...this.builtinDirs];
5081
+ }
5082
+ /**
5083
+ * Primary builtin root used for local scaffolding/reference flows.
5084
+ */
5085
+ getPrimaryBuiltinDir() {
5086
+ return this.builtinDirs[0];
5087
+ }
5088
+ /**
5089
+ * User override root (~/.adhdev/providers by default).
5090
+ */
5091
+ getUserDir() {
5092
+ return this.userDir;
5093
+ }
5094
+ /**
5095
+ * Auto-updated upstream root (~/.adhdev/providers/.upstream by default).
5096
+ */
5097
+ getUpstreamDir() {
5098
+ return this.upstreamDir;
5099
+ }
5100
+ /**
5101
+ * Provider search order for on-disk lookups.
5102
+ * Highest-priority editable overrides come first.
5103
+ */
5104
+ getProviderRoots() {
5105
+ return [this.userDir, this.upstreamDir, ...this.builtinDirs];
5106
+ }
5107
+ /**
5108
+ * Canonical provider directory shape for a given root.
5109
+ */
5110
+ getProviderDir(root, category, type) {
5111
+ return path6.join(root, category, type);
5112
+ }
5113
+ /**
5114
+ * Canonical user override directory for a provider.
5115
+ */
5116
+ getUserProviderDir(category, type) {
5117
+ return this.getProviderDir(this.userDir, category, type);
5118
+ }
5119
+ /**
5120
+ * Canonical upstream directory for a provider.
5121
+ */
5122
+ getUpstreamProviderDir(category, type) {
5123
+ return this.getProviderDir(this.upstreamDir, category, type);
5124
+ }
5125
+ /**
5126
+ * Canonical builtin directory for a provider.
5127
+ */
5128
+ getBuiltinProviderDir(category, type) {
5129
+ return this.getProviderDir(this.getPrimaryBuiltinDir(), category, type);
5130
+ }
5131
+ /**
5132
+ * Find the on-disk directory for a provider by type.
5133
+ * Search order: user override → upstream → builtin fallback.
5134
+ */
5135
+ findProviderDir(type) {
5136
+ return this.findProviderDirInternal(type);
5137
+ }
5138
+ /**
5139
+ * Resolve a file within a provider directory.
5140
+ */
5141
+ resolveProviderFile(type, ...segments) {
5142
+ const dir = this.findProviderDirInternal(type);
5143
+ if (!dir) return null;
5144
+ return path6.join(dir, ...segments);
5145
+ }
5146
+ /**
5077
5147
  * Load all providers (3-tier priority)
5078
5148
  * 1. .upstream/ (GitHub auto-download — primary source)
5079
5149
  * 2. User custom (~/.adhdev/providers/ excluding .upstream)
@@ -5399,7 +5469,7 @@ var init_provider_loader = __esm({
5399
5469
  * Tries scripts.js first, then individual .js files.
5400
5470
  */
5401
5471
  loadScriptsFromDir(type, scriptDir) {
5402
- const providerDir = this.findProviderDir(type);
5472
+ const providerDir = this.findProviderDirInternal(type);
5403
5473
  if (!providerDir) {
5404
5474
  this.log(` [loadScriptsFromDir] ${type}: providerDir not found`);
5405
5475
  return null;
@@ -5760,16 +5830,16 @@ var init_provider_loader = __esm({
5760
5830
  // ─── Private ───────────────────────────────────
5761
5831
  /**
5762
5832
  * Find the on-disk directory for a provider by type.
5763
- * Checks builtinDir, upstreamDir, userDir in order.
5833
+ * Preferred shape: root/category/type. Legacy flat root/type is kept temporarily for compatibility.
5764
5834
  */
5765
- findProviderDir(type) {
5835
+ findProviderDirInternal(type) {
5766
5836
  const provider = this.providers.get(type);
5767
5837
  if (!provider) return null;
5768
5838
  const cat = provider.category;
5769
- const searchRoots = [this.userDir, this.upstreamDir, ...this.builtinDirs];
5839
+ const searchRoots = this.getProviderRoots();
5770
5840
  for (const root of searchRoots) {
5771
5841
  if (!fs5.existsSync(root)) continue;
5772
- for (const candidate of [path6.join(root, type), path6.join(root, cat, type)]) {
5842
+ for (const candidate of [this.getProviderDir(root, cat, type), path6.join(root, type)]) {
5773
5843
  if (fs5.existsSync(path6.join(candidate, "provider.json"))) return candidate;
5774
5844
  }
5775
5845
  const catDir = path6.join(root, cat);
@@ -7160,6 +7230,9 @@ var init_provider_cli_adapter = __esm({
7160
7230
  idleTimeout = null;
7161
7231
  ready = false;
7162
7232
  startupBuffer = "";
7233
+ /** After spawn: briefly skip generating/settle so splash/redraw does not flip status; not used to gate sendMessage */
7234
+ startupParseGate = false;
7235
+ spawnAt = 0;
7163
7236
  // PTY I/O
7164
7237
  onPtyDataCallback = null;
7165
7238
  ptyOutputBuffer = "";
@@ -7273,9 +7346,15 @@ var init_provider_cli_adapter = __esm({
7273
7346
  this.ptyProcess = null;
7274
7347
  this.setStatus("stopped", "pty_exit");
7275
7348
  this.ready = false;
7349
+ this.startupParseGate = false;
7350
+ this.spawnAt = 0;
7276
7351
  this.onStatusChange?.();
7277
7352
  });
7278
- this.setStatus("starting", "spawn");
7353
+ this.spawnAt = Date.now();
7354
+ this.startupParseGate = true;
7355
+ this.startupBuffer = "";
7356
+ this.ready = true;
7357
+ this.setStatus("idle", "pty_ready");
7279
7358
  this.onStatusChange?.();
7280
7359
  }
7281
7360
  // ─── Output state machine ────────────────────────────
@@ -7291,7 +7370,7 @@ var init_provider_cli_adapter = __esm({
7291
7370
  }
7292
7371
  }
7293
7372
  this.recentOutputBuffer = (this.recentOutputBuffer + cleanData).slice(-1e3);
7294
- if (!this.ready) {
7373
+ if (this.startupParseGate) {
7295
7374
  this.startupBuffer += cleanData;
7296
7375
  LOG.info("CLI", `[${this.cliType}] startup chunk (${cleanData.length} chars): ${cleanData.slice(0, 200).replace(/\n/g, "\\n")}`);
7297
7376
  const dialogPatterns = [
@@ -7306,13 +7385,19 @@ var init_provider_cli_adapter = __esm({
7306
7385
  this.startupBuffer = "";
7307
7386
  return;
7308
7387
  }
7309
- if (patterns.prompt.some((p) => p.test(this.startupBuffer))) {
7310
- this.ready = true;
7311
- this.setStatus("idle", "prompt_matched");
7312
- LOG.info("CLI", `[${this.cliType}] \u2713 Ready`);
7313
- this.onStatusChange?.();
7388
+ const elapsed = Date.now() - this.spawnAt;
7389
+ const bufCap = this.startupBuffer.length > 12e3;
7390
+ const promptMatched = patterns.prompt.some((p) => p.test(this.startupBuffer));
7391
+ if (promptMatched || elapsed > 8e3 || bufCap) {
7392
+ this.startupParseGate = false;
7393
+ if (promptMatched) {
7394
+ LOG.info("CLI", `[${this.cliType}] \u2713 Startup gate end (prompt matched)`);
7395
+ } else {
7396
+ LOG.info("CLI", `[${this.cliType}] startup gate end (${elapsed}ms, cap=${bufCap}, prompt=${promptMatched})`);
7397
+ }
7398
+ } else {
7399
+ return;
7314
7400
  }
7315
- return;
7316
7401
  }
7317
7402
  if (cleanData.trim().length > 5) {
7318
7403
  LOG.debug("CLI", `[${this.cliType}] output chunk (${cleanData.length}): ${cleanData.slice(0, 300).replace(/\n/g, "\\n")}`);
@@ -7520,6 +7605,8 @@ var init_provider_cli_adapter = __esm({
7520
7605
  this.ptyProcess = null;
7521
7606
  this.setStatus("stopped", "stop_cmd");
7522
7607
  this.ready = false;
7608
+ this.startupParseGate = false;
7609
+ this.spawnAt = 0;
7523
7610
  this.onStatusChange?.();
7524
7611
  }, this.timeouts.shutdownGrace);
7525
7612
  }
@@ -7566,16 +7653,29 @@ var init_provider_cli_adapter = __esm({
7566
7653
  * Used by DevServer /api/cli/debug endpoint.
7567
7654
  */
7568
7655
  getDebugState() {
7656
+ const sb = this.startupBuffer;
7657
+ const testOnStartup = (p) => {
7658
+ const flags = p.flags.includes("g") ? p.flags.replace(/g/g, "") : p.flags;
7659
+ return new RegExp(p.source, flags).test(sb);
7660
+ };
7661
+ const promptDiagnostics = this.provider.patterns.prompt.map((p) => ({
7662
+ pattern: p.toString(),
7663
+ matchedAgainstStartupBuffer: testOnStartup(p)
7664
+ }));
7569
7665
  return {
7570
7666
  type: this.cliType,
7571
7667
  name: this.cliName,
7572
7668
  status: this.currentStatus,
7573
7669
  ready: this.ready,
7670
+ startupParseGate: this.startupParseGate,
7671
+ spawnAt: this.spawnAt,
7574
7672
  workingDir: this.workingDir,
7575
7673
  messages: this.messages.slice(-20),
7576
7674
  messageCount: this.messages.length,
7577
- // Buffers
7578
- startupBuffer: this.startupBuffer.slice(-500),
7675
+ // Buffers (longer tails here than in periodic logs — for matching provider.json patterns)
7676
+ startupBuffer: sb.slice(-4e3),
7677
+ startupBufferLength: sb.length,
7678
+ promptDiagnostics,
7579
7679
  recentOutputBuffer: this.recentOutputBuffer.slice(-500),
7580
7680
  settledBuffer: this.settledBuffer.slice(-500),
7581
7681
  responseBuffer: this.responseBuffer.slice(-500),
@@ -27270,37 +27370,7 @@ var init_dev_server = __esm({
27270
27370
  // ─── Provider File Explorer ───
27271
27371
  /** Find the provider directory on disk */
27272
27372
  findProviderDir(type) {
27273
- const provider = this.providerLoader.getMeta(type);
27274
- if (!provider) return null;
27275
- const cat = provider.category;
27276
- const builtinDir = this.providerLoader.builtinDirs?.[0] || path12.resolve(__dirname, "../providers/_builtin");
27277
- const userDir = path12.join(os14.homedir(), ".adhdev", "providers");
27278
- const directCandidates = [
27279
- path12.join(userDir, type),
27280
- path12.join(builtinDir, cat, type),
27281
- path12.join(builtinDir, type)
27282
- ];
27283
- for (const d of directCandidates) {
27284
- if (fs9.existsSync(path12.join(d, "provider.json"))) return d;
27285
- }
27286
- const catDir = path12.join(builtinDir, cat);
27287
- if (fs9.existsSync(catDir)) {
27288
- try {
27289
- for (const entry of fs9.readdirSync(catDir, { withFileTypes: true })) {
27290
- if (!entry.isDirectory()) continue;
27291
- const jsonPath = path12.join(catDir, entry.name, "provider.json");
27292
- if (fs9.existsSync(jsonPath)) {
27293
- try {
27294
- const data = JSON.parse(fs9.readFileSync(jsonPath, "utf-8"));
27295
- if (data.type === type) return path12.join(catDir, entry.name);
27296
- } catch {
27297
- }
27298
- }
27299
- }
27300
- } catch {
27301
- }
27302
- }
27303
- return null;
27373
+ return this.providerLoader.findProviderDir(type);
27304
27374
  }
27305
27375
  /** GET /api/providers/:type/files — list all files in provider directory */
27306
27376
  async handleListFiles(type, _req, res) {
@@ -27695,10 +27765,9 @@ var init_dev_server = __esm({
27695
27765
  }
27696
27766
  let targetDir;
27697
27767
  if (location === "user") {
27698
- targetDir = path12.join(os14.homedir(), ".adhdev", "providers", type);
27768
+ targetDir = this.providerLoader.getUserProviderDir(category, type);
27699
27769
  } else {
27700
- const builtinDir = this.providerLoader.builtinDirs?.[0] || path12.resolve(__dirname, "../providers/_builtin");
27701
- targetDir = path12.join(builtinDir, category, type);
27770
+ targetDir = this.providerLoader.getBuiltinProviderDir(category, type);
27702
27771
  }
27703
27772
  const jsonPath = path12.join(targetDir, "provider.json");
27704
27773
  if (fs9.existsSync(jsonPath)) {
@@ -28507,7 +28576,7 @@ var init_dev_server = __esm({
28507
28576
  const domContext = null;
28508
28577
  this.sendAutoImplSSE({ event: "progress", data: { function: "_init", status: "loading_reference", message: `\uB808\uD37C\uB7F0\uC2A4 \uC2A4\uD06C\uB9BD\uD2B8 \uB85C\uB4DC \uC911 (${reference})...` } });
28509
28578
  let referenceScripts = {};
28510
- const builtinDir = this.providerLoader.builtinDirs?.[0] || path12.resolve(__dirname, "../providers/_builtin");
28579
+ const builtinDir = this.providerLoader.getPrimaryBuiltinDir();
28511
28580
  const refDir = path12.join(builtinDir, "ide", reference);
28512
28581
  if (fs9.existsSync(refDir)) {
28513
28582
  const scriptsDir = path12.join(refDir, "scripts");
@@ -30914,7 +30983,7 @@ var init_adhdev_daemon = __esm({
30914
30983
  fs11 = __toESM(require("fs"));
30915
30984
  path14 = __toESM(require("path"));
30916
30985
  import_chalk2 = __toESM(require("chalk"));
30917
- pkgVersion = "0.6.50";
30986
+ pkgVersion = "0.6.52";
30918
30987
  if (pkgVersion === "unknown") {
30919
30988
  try {
30920
30989
  const possiblePaths = [