adhdev 0.9.2 → 0.9.5

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
@@ -729,35 +729,6 @@ var init_saved_sessions = __esm({
729
729
  }
730
730
  });
731
731
 
732
- // ../../oss/packages/daemon-core/src/providers/provider-session-id.ts
733
- function normalizeProviderSessionId(providerType, providerSessionId) {
734
- const normalizedProviderType = typeof providerType === "string" ? providerType.trim() : "";
735
- const normalizedId = typeof providerSessionId === "string" ? providerSessionId.trim() : "";
736
- if (!normalizedId) return "";
737
- const lowered = normalizedId.toLowerCase();
738
- if (lowered === "undefined" || lowered === "null") return "";
739
- if (normalizedProviderType === "hermes-cli" && !HERMES_SESSION_ID_RE.test(normalizedId)) {
740
- return "";
741
- }
742
- if (normalizedProviderType === "claude-cli" && !CLAUDE_SESSION_ID_RE.test(normalizedId)) {
743
- return "";
744
- }
745
- return normalizedId;
746
- }
747
- function isLegacyVolatileSessionReadKey(key) {
748
- const normalizedKey = typeof key === "string" ? key.trim() : "";
749
- if (!normalizedKey) return false;
750
- return normalizedKey.startsWith("provider:codex:vscode-webview://");
751
- }
752
- var HERMES_SESSION_ID_RE, CLAUDE_SESSION_ID_RE;
753
- var init_provider_session_id = __esm({
754
- "../../oss/packages/daemon-core/src/providers/provider-session-id.ts"() {
755
- "use strict";
756
- HERMES_SESSION_ID_RE = /^\d{8}_\d{6}_[a-z0-9]+$/i;
757
- CLAUDE_SESSION_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
758
- }
759
- });
760
-
761
732
  // ../../oss/packages/daemon-core/src/config/state-store.ts
762
733
  function isPlainObject2(value) {
763
734
  return !!value && typeof value === "object" && !Array.isArray(value);
@@ -769,31 +740,24 @@ function normalizeState(raw) {
769
740
  const parsed = isPlainObject2(raw) ? raw : {};
770
741
  const recentActivity = (Array.isArray(parsed.recentActivity) ? parsed.recentActivity : []).filter((entry) => {
771
742
  if (!isPlainObject2(entry)) return false;
772
- const normalizedId = normalizeProviderSessionId(
773
- typeof entry.providerType === "string" ? entry.providerType : "",
774
- typeof entry.providerSessionId === "string" ? entry.providerSessionId : ""
775
- );
776
- if (typeof entry.providerSessionId === "string" && !normalizedId) return false;
743
+ if (typeof entry.providerSessionId === "string" && !entry.providerSessionId.trim()) return false;
777
744
  return true;
778
745
  });
779
746
  const savedProviderSessions = (Array.isArray(parsed.savedProviderSessions) ? parsed.savedProviderSessions : []).filter((entry) => {
780
747
  if (!isPlainObject2(entry)) return false;
781
- return !!normalizeProviderSessionId(
782
- typeof entry.providerType === "string" ? entry.providerType : "",
783
- typeof entry.providerSessionId === "string" ? entry.providerSessionId : ""
784
- );
748
+ return typeof entry.providerSessionId === "string" && !!entry.providerSessionId.trim();
785
749
  });
786
750
  const sessionReads = Object.fromEntries(
787
- Object.entries(isPlainObject2(parsed.sessionReads) ? parsed.sessionReads : {}).filter(([key, value]) => !isLegacyVolatileSessionReadKey(key) && typeof value === "number" && Number.isFinite(value))
751
+ Object.entries(isPlainObject2(parsed.sessionReads) ? parsed.sessionReads : {}).filter(([, value]) => typeof value === "number" && Number.isFinite(value))
788
752
  );
789
753
  const sessionReadMarkers = Object.fromEntries(
790
- Object.entries(isPlainObject2(parsed.sessionReadMarkers) ? parsed.sessionReadMarkers : {}).filter(([key, value]) => !isLegacyVolatileSessionReadKey(key) && typeof value === "string")
754
+ Object.entries(isPlainObject2(parsed.sessionReadMarkers) ? parsed.sessionReadMarkers : {}).filter(([, value]) => typeof value === "string")
791
755
  );
792
756
  const sessionNotificationDismissals = Object.fromEntries(
793
- Object.entries(isPlainObject2(parsed.sessionNotificationDismissals) ? parsed.sessionNotificationDismissals : {}).filter(([key, value]) => !isLegacyVolatileSessionReadKey(key) && typeof value === "string" && value.length > 0)
757
+ Object.entries(isPlainObject2(parsed.sessionNotificationDismissals) ? parsed.sessionNotificationDismissals : {}).filter(([, value]) => typeof value === "string" && value.length > 0)
794
758
  );
795
759
  const sessionNotificationUnreadOverrides = Object.fromEntries(
796
- Object.entries(isPlainObject2(parsed.sessionNotificationUnreadOverrides) ? parsed.sessionNotificationUnreadOverrides : {}).filter(([key, value]) => !isLegacyVolatileSessionReadKey(key) && typeof value === "string" && value.length > 0)
760
+ Object.entries(isPlainObject2(parsed.sessionNotificationUnreadOverrides) ? parsed.sessionNotificationUnreadOverrides : {}).filter(([, value]) => typeof value === "string" && value.length > 0)
797
761
  );
798
762
  return {
799
763
  recentActivity,
@@ -831,7 +795,6 @@ var init_state_store = __esm({
831
795
  import_fs2 = require("fs");
832
796
  import_path2 = require("path");
833
797
  init_config();
834
- init_provider_session_id();
835
798
  DEFAULT_STATE = {
836
799
  recentActivity: [],
837
800
  savedProviderSessions: [],
@@ -913,8 +876,8 @@ async function detectIDEs(providerLoader) {
913
876
  if ((0, import_fs3.existsSync)(bundledCli)) resolvedCli = bundledCli;
914
877
  }
915
878
  if (!resolvedCli && appPath && os29 === "win32") {
916
- const { dirname: dirname9 } = await import("path");
917
- const appDir = dirname9(appPath);
879
+ const { dirname: dirname10 } = await import("path");
880
+ const appDir = dirname10(appPath);
918
881
  const candidates = [
919
882
  `${appDir}\\\\bin\\\\${def.cli}.cmd`,
920
883
  `${appDir}\\\\bin\\\\${def.cli}`,
@@ -3526,12 +3489,21 @@ var init_control_effects = __esm({
3526
3489
  function normalizeHistoryComparable(text) {
3527
3490
  return String(text || "").replace(/\s+/g, " ").trim();
3528
3491
  }
3529
- function cleanupHistoryContent(agentType, role, content) {
3492
+ function cleanupHistoryContent(agentType, role, content, historyBehavior) {
3530
3493
  let value = String(content || "").replace(/\r\n/g, "\n").trim();
3531
3494
  if (!value) return "";
3532
- if (agentType === "codex-cli" && role === "assistant") {
3533
- const filtered = value.split("\n").filter((line) => !CODEX_STARTER_PROMPT_RE.test(line.trim())).join("\n").replace(/\n{3,}/g, "\n\n").trim();
3534
- value = filtered;
3495
+ if (role === "assistant" && historyBehavior?.filterAssistantPatterns?.length) {
3496
+ const filters = historyBehavior.filterAssistantPatterns.map((p) => {
3497
+ try {
3498
+ return new RegExp(p, "i");
3499
+ } catch {
3500
+ return null;
3501
+ }
3502
+ }).filter(Boolean);
3503
+ if (filters.length > 0) {
3504
+ const filtered = value.split("\n").filter((line) => !filters.some((re) => re.test(line.trim()))).join("\n").replace(/\n{3,}/g, "\n\n").trim();
3505
+ value = filtered;
3506
+ }
3535
3507
  }
3536
3508
  return value;
3537
3509
  }
@@ -3548,8 +3520,8 @@ function isAdjacentHistoryDuplicate(agentType, previous, next) {
3548
3520
  if (!previous || !next) return false;
3549
3521
  return buildHistoryMessageSignature(agentType, previous) === buildHistoryMessageSignature(agentType, next);
3550
3522
  }
3551
- function collapseReplayAssistantTurns(agentType, messages) {
3552
- if (agentType !== "codex-cli") return messages;
3523
+ function collapseReplayAssistantTurns(messages, historyBehavior) {
3524
+ if (!historyBehavior?.collapseConsecutiveAssistantTurns) return messages;
3553
3525
  const collapsed = [];
3554
3526
  let sawAssistantSinceLastUser = false;
3555
3527
  for (const message of messages) {
@@ -3654,16 +3626,12 @@ function listHistoryFiles(dir, historySessionId) {
3654
3626
  return true;
3655
3627
  }).sort().reverse();
3656
3628
  }
3657
- function normalizeSavedHistorySessionId(agentType, historySessionId) {
3658
- const normalizedId = String(historySessionId || "").trim();
3659
- if (!normalizedId) return "";
3660
- const strictProviderId = normalizeProviderSessionId(agentType, normalizedId);
3661
- if (strictProviderId) return strictProviderId;
3662
- return agentType === "hermes-cli" ? "" : normalizedId;
3629
+ function normalizeSavedHistorySessionId(historySessionId) {
3630
+ return String(historySessionId || "").trim();
3663
3631
  }
3664
- function extractSavedHistorySessionIdFromFile(agentType, file2) {
3632
+ function extractSavedHistorySessionIdFromFile(file2) {
3665
3633
  const match = file2.match(/^([A-Za-z0-9_-]+)_\d{4}-\d{2}-\d{2}\.jsonl$/);
3666
- return normalizeSavedHistorySessionId(agentType, match?.[1] || "");
3634
+ return normalizeSavedHistorySessionId(match?.[1] || "");
3667
3635
  }
3668
3636
  function buildSavedHistoryFileSignatureMap(dir, files) {
3669
3637
  return new Map(files.map((file2) => {
@@ -3842,7 +3810,7 @@ function persistSavedHistoryFileSummaryEntry(agentType, dir, file2, updater) {
3842
3810
  }
3843
3811
  }
3844
3812
  function updateSavedHistoryIndexForSessionStart(agentType, dir, file2, historySessionId, workspace) {
3845
- const normalizedSessionId = normalizeSavedHistorySessionId(agentType, historySessionId);
3813
+ const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
3846
3814
  const normalizedWorkspace = String(workspace || "").trim();
3847
3815
  if (!normalizedSessionId || !normalizedWorkspace) return;
3848
3816
  persistSavedHistoryFileSummaryEntry(agentType, dir, file2, (currentSummary) => ({
@@ -3857,7 +3825,7 @@ function updateSavedHistoryIndexForSessionStart(agentType, dir, file2, historySe
3857
3825
  }));
3858
3826
  }
3859
3827
  function updateSavedHistoryIndexForAppendedMessages(agentType, dir, file2, historySessionId, messages) {
3860
- const normalizedSessionId = normalizeSavedHistorySessionId(agentType, historySessionId || "");
3828
+ const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId || "");
3861
3829
  if (!normalizedSessionId || messages.length === 0) return;
3862
3830
  persistSavedHistoryFileSummaryEntry(agentType, dir, file2, (currentSummary) => {
3863
3831
  const nextSummary = {
@@ -3894,8 +3862,8 @@ function updateSavedHistoryIndexForAppendedMessages(agentType, dir, file2, histo
3894
3862
  return nextSummary;
3895
3863
  });
3896
3864
  }
3897
- function computeSavedHistoryFileSummary(agentType, dir, file2) {
3898
- const historySessionId = extractSavedHistorySessionIdFromFile(agentType, file2);
3865
+ function computeSavedHistoryFileSummary(dir, file2) {
3866
+ const historySessionId = extractSavedHistorySessionIdFromFile(file2);
3899
3867
  if (!historySessionId) return null;
3900
3868
  const filePath = path7.join(dir, file2);
3901
3869
  const content = fs3.readFileSync(filePath, "utf-8");
@@ -3989,7 +3957,7 @@ function computeSavedHistorySessionSummaries(agentType, dir, files, fileSignatur
3989
3957
  const cached2 = savedHistoryFileSummaryCache.get(filePath);
3990
3958
  const persisted = persistedEntries.get(file2);
3991
3959
  const reusableEntry = cached2?.signature === signature ? cached2 : persisted?.signature === signature ? persisted : null;
3992
- const fileSummary = reusableEntry?.summary || computeSavedHistoryFileSummary(agentType, dir, file2);
3960
+ const fileSummary = reusableEntry?.summary || computeSavedHistoryFileSummary(dir, file2);
3993
3961
  const nextEntry = reusableEntry || {
3994
3962
  signature,
3995
3963
  summary: fileSummary
@@ -4035,7 +4003,7 @@ function computeSavedHistorySessionSummaries(agentType, dir, files, fileSignatur
4035
4003
  persistedEntries: nextPersistedEntries
4036
4004
  };
4037
4005
  }
4038
- function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, excludeRecentCount = 0) {
4006
+ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, excludeRecentCount = 0, historyBehavior) {
4039
4007
  try {
4040
4008
  const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
4041
4009
  const dir = path7.join(HISTORY_DIR, sanitized);
@@ -4070,7 +4038,7 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, ex
4070
4038
  chronological.push(message);
4071
4039
  if (message.role !== "system") lastTurn = message;
4072
4040
  }
4073
- const collapsed = collapseReplayAssistantTurns(agentType, chronological);
4041
+ const collapsed = collapseReplayAssistantTurns(chronological, historyBehavior);
4074
4042
  const boundedLimit = Math.max(1, limit);
4075
4043
  const boundedOffset = Math.max(0, offset);
4076
4044
  const boundedExclude = Math.max(0, Math.min(excludeRecentCount, collapsed.length));
@@ -4083,7 +4051,7 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, ex
4083
4051
  return { messages: [], hasMore: false };
4084
4052
  }
4085
4053
  }
4086
- function listSavedHistorySessions(agentType, options = {}) {
4054
+ function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
4087
4055
  try {
4088
4056
  const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
4089
4057
  const dir = path7.join(HISTORY_DIR, sanitized);
@@ -4214,7 +4182,7 @@ function rewriteCanonicalSavedHistory(agentType, historySessionId, records) {
4214
4182
  }
4215
4183
  }
4216
4184
  function rebuildHermesSavedHistoryFromCanonicalSession(historySessionId) {
4217
- const normalizedSessionId = normalizeSavedHistorySessionId("hermes-cli", historySessionId);
4185
+ const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
4218
4186
  if (!normalizedSessionId) return false;
4219
4187
  try {
4220
4188
  const sessionFilePath = path7.join(os5.homedir(), ".hermes", "sessions", `session_${normalizedSessionId}.json`);
@@ -4363,7 +4331,7 @@ function extractClaudeUserContentParts(content) {
4363
4331
  return parts;
4364
4332
  }
4365
4333
  function rebuildClaudeSavedHistoryFromNativeProject(historySessionId, workspace) {
4366
- const normalizedSessionId = normalizeSavedHistorySessionId("claude-cli", historySessionId);
4334
+ const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
4367
4335
  if (!normalizedSessionId) return false;
4368
4336
  try {
4369
4337
  const transcriptPath = resolveClaudeProjectTranscriptPath(normalizedSessionId, workspace);
@@ -4440,7 +4408,7 @@ function rebuildClaudeSavedHistoryFromNativeProject(historySessionId, workspace)
4440
4408
  return false;
4441
4409
  }
4442
4410
  }
4443
- var fs3, path7, os5, HISTORY_DIR, RETAIN_DAYS, SAVED_HISTORY_INDEX_VERSION, SAVED_HISTORY_INDEX_FILE, SAVED_HISTORY_INDEX_LOCK_SUFFIX, SAVED_HISTORY_INDEX_LOCK_WAIT_MS, SAVED_HISTORY_INDEX_LOCK_STALE_MS, SAVED_HISTORY_INDEX_LOCK_POLL_MS, SAVED_HISTORY_ROLLUP_THRESHOLD_BYTES, savedHistorySessionCache, savedHistoryFileSummaryCache, savedHistoryBackgroundRefresh, savedHistoryRollupInFlight, CODEX_STARTER_PROMPT_RE, ChatHistoryWriter;
4411
+ var fs3, path7, os5, HISTORY_DIR, RETAIN_DAYS, SAVED_HISTORY_INDEX_VERSION, SAVED_HISTORY_INDEX_FILE, SAVED_HISTORY_INDEX_LOCK_SUFFIX, SAVED_HISTORY_INDEX_LOCK_WAIT_MS, SAVED_HISTORY_INDEX_LOCK_STALE_MS, SAVED_HISTORY_INDEX_LOCK_POLL_MS, SAVED_HISTORY_ROLLUP_THRESHOLD_BYTES, savedHistorySessionCache, savedHistoryFileSummaryCache, savedHistoryBackgroundRefresh, savedHistoryRollupInFlight, ChatHistoryWriter;
4444
4412
  var init_chat_history = __esm({
4445
4413
  "../../oss/packages/daemon-core/src/config/chat-history.ts"() {
4446
4414
  "use strict";
@@ -4448,7 +4416,6 @@ var init_chat_history = __esm({
4448
4416
  path7 = __toESM(require("path"));
4449
4417
  os5 = __toESM(require("os"));
4450
4418
  init_chat_message_normalization();
4451
- init_provider_session_id();
4452
4419
  HISTORY_DIR = path7.join(os5.homedir(), ".adhdev", "history");
4453
4420
  RETAIN_DAYS = 30;
4454
4421
  SAVED_HISTORY_INDEX_VERSION = 1;
@@ -4462,7 +4429,6 @@ var init_chat_history = __esm({
4462
4429
  savedHistoryFileSummaryCache = /* @__PURE__ */ new Map();
4463
4430
  savedHistoryBackgroundRefresh = /* @__PURE__ */ new Set();
4464
4431
  savedHistoryRollupInFlight = /* @__PURE__ */ new Set();
4465
- CODEX_STARTER_PROMPT_RE = /^(?:[›❯]\s*)?(?:Find and fix a bug in @filename|Improve documentation in @filename|Write tests for @filename|Explain this codebase|Summarize recent commits|Implement \{feature\}|Use \/skills(?: to list available skills)?|Run \/review on my current changes)$/i;
4466
4432
  ChatHistoryWriter = class {
4467
4433
  /** Last seen message count per agent (deduplication) */
4468
4434
  lastSeenCounts = /* @__PURE__ */ new Map();
@@ -4715,7 +4681,7 @@ var init_chat_history = __esm({
4715
4681
  } catch {
4716
4682
  }
4717
4683
  }
4718
- compactHistorySession(agentType, historySessionId) {
4684
+ compactHistorySession(agentType, historySessionId, historyBehavior) {
4719
4685
  const sessionId = String(historySessionId || "").trim();
4720
4686
  if (!sessionId) return;
4721
4687
  try {
@@ -4753,7 +4719,7 @@ var init_chat_history = __esm({
4753
4719
  dedupedAdjacent.push(entry);
4754
4720
  if (entry.role !== "system") lastTurn = entry;
4755
4721
  }
4756
- const collapsed = collapseReplayAssistantTurns(agentType, dedupedAdjacent);
4722
+ const collapsed = collapseReplayAssistantTurns(dedupedAdjacent, historyBehavior);
4757
4723
  if (collapsed.length === 0) {
4758
4724
  fs3.unlinkSync(filePath);
4759
4725
  continue;
@@ -9198,7 +9164,8 @@ async function executeProviderScript(h, args, scriptName) {
9198
9164
  }
9199
9165
  const managed = runtimeSessionId ? h.agentStream?.getManagedSession(runtimeSessionId) : null;
9200
9166
  const targetSessionId = managed?.cdpSessionId || null;
9201
- const IDE_LEVEL_SCRIPTS = provider.type === "claude-code-vscode" ? ["listModes", "setMode", "listModels", "setModel", "setModelGui"] : ["listModes", "setMode", "listModels", "setModel"];
9167
+ const DEFAULT_IDE_LEVEL_SCRIPTS = ["listModes", "setMode", "listModels", "setModel"];
9168
+ const IDE_LEVEL_SCRIPTS = provider.ideLevelScripts ?? DEFAULT_IDE_LEVEL_SCRIPTS;
9202
9169
  if (IDE_LEVEL_SCRIPTS.includes(scriptName)) {
9203
9170
  if (targetSessionId) {
9204
9171
  try {
@@ -13110,10 +13077,6 @@ ${data.message || ""}`.trim();
13110
13077
  throw new Error(`${this.cliName} is still processing the previous prompt`);
13111
13078
  }
13112
13079
  }
13113
- const blockingModal = this.activeModal || this.getStartupConfirmationModal(this.terminalScreen.getText() || "");
13114
- if (blockingModal || this.currentStatus === "waiting_approval") {
13115
- throw new Error(`${this.cliName} is awaiting confirmation before it can accept a prompt`);
13116
- }
13117
13080
  this.isWaitingForResponse = true;
13118
13081
  this.responseBuffer = "";
13119
13082
  this.finishRetryCount = 0;
@@ -13647,6 +13610,28 @@ ${data.message || ""}`.trim();
13647
13610
  }
13648
13611
  });
13649
13612
 
13613
+ // ../../oss/packages/daemon-core/src/providers/provider-session-id.ts
13614
+ function normalizeProviderSessionId(provider, providerSessionId) {
13615
+ const normalizedId = typeof providerSessionId === "string" ? providerSessionId.trim() : "";
13616
+ if (!normalizedId) return "";
13617
+ const lowered = normalizedId.toLowerCase();
13618
+ if (lowered === "undefined" || lowered === "null") return "";
13619
+ const sessionIdPattern = provider?.sessionIdPattern;
13620
+ if (sessionIdPattern) {
13621
+ try {
13622
+ const re = new RegExp(sessionIdPattern, "i");
13623
+ if (!re.test(normalizedId)) return "";
13624
+ } catch {
13625
+ }
13626
+ }
13627
+ return normalizedId;
13628
+ }
13629
+ var init_provider_session_id = __esm({
13630
+ "../../oss/packages/daemon-core/src/providers/provider-session-id.ts"() {
13631
+ "use strict";
13632
+ }
13633
+ });
13634
+
13650
13635
  // ../../oss/packages/daemon-core/src/providers/cli-provider-instance.ts
13651
13636
  function normalizePersistableCliHistoryContent(content) {
13652
13637
  return flattenContent(content).replace(/\s+/g, " ").trim();
@@ -13824,32 +13809,10 @@ var init_cli_provider_instance = __esm({
13824
13809
  }
13825
13810
  async onTick() {
13826
13811
  if (this.providerSessionId) return;
13827
- if (this.type === "hermes-cli" && this.launchMode === "new") return;
13828
- let probedSessionId = null;
13812
+ if (this.provider.resume?.skipProbeOnNewSession && this.launchMode === "new") return;
13829
13813
  const probeConfig = this.provider.sessionProbe;
13830
- if (probeConfig) {
13831
- probedSessionId = this.probeSessionIdFromConfig(probeConfig);
13832
- } else {
13833
- if (this.type === "opencode-cli") {
13834
- probedSessionId = this.probeSessionIdFromConfig({
13835
- dbPath: "~/.local/share/opencode/opencode.db",
13836
- query: "select id from session where directory in ({dirs}) and time_created >= ? and time_archived is null order by time_updated desc limit 1",
13837
- timestampFormat: "unix_ms"
13838
- });
13839
- } else if (this.type === "codex-cli") {
13840
- probedSessionId = this.probeSessionIdFromConfig({
13841
- dbPath: "~/.codex/state_5.sqlite",
13842
- query: "select id from threads where cwd in ({dirs}) and updated_at >= ? and archived = 0 order by updated_at desc limit 1",
13843
- timestampFormat: "unix_s"
13844
- });
13845
- } else if (this.type === "goose-cli") {
13846
- probedSessionId = this.probeSessionIdFromConfig({
13847
- dbPath: "~/.local/share/goose/sessions/sessions.db",
13848
- query: "select id from sessions where working_dir in ({dirs}) and created_at >= ? order by updated_at desc limit 1",
13849
- timestampFormat: "iso"
13850
- });
13851
- }
13852
- }
13814
+ if (!probeConfig) return;
13815
+ const probedSessionId = this.probeSessionIdFromConfig(probeConfig);
13853
13816
  if (probedSessionId) {
13854
13817
  this.promoteProviderSessionId(probedSessionId);
13855
13818
  }
@@ -13901,7 +13864,7 @@ var init_cli_provider_instance = __esm({
13901
13864
  const autoApproveActive = adapterStatus.status === "waiting_approval" && this.shouldAutoApprove();
13902
13865
  const visibleStatus = parseErrorMessage ? "error" : autoApproveActive ? "generating" : adapterStatus.status;
13903
13866
  const parsedProviderSessionId = normalizeProviderSessionId(
13904
- this.type,
13867
+ this.provider,
13905
13868
  typeof parsedStatus?.providerSessionId === "string" ? parsedStatus.providerSessionId : ""
13906
13869
  );
13907
13870
  if (parsedProviderSessionId) {
@@ -14191,7 +14154,7 @@ var init_cli_provider_instance = __esm({
14191
14154
  applyProviderResponse(data, options) {
14192
14155
  if (!data || typeof data !== "object") return;
14193
14156
  const patchedProviderSessionId = normalizeProviderSessionId(
14194
- this.type,
14157
+ this.provider,
14195
14158
  typeof data.providerSessionId === "string" ? data.providerSessionId : ""
14196
14159
  );
14197
14160
  if (patchedProviderSessionId) {
@@ -14429,52 +14392,39 @@ ${effect.notification.body || ""}`.trim();
14429
14392
  }
14430
14393
  syncCanonicalSavedHistoryIfNeeded() {
14431
14394
  if (!this.providerSessionId) return false;
14432
- if (this.type === "hermes-cli") {
14433
- try {
14434
- const canonicalPath = path11.join(os13.homedir(), ".hermes", "sessions", `session_${this.providerSessionId}.json`);
14435
- if (!fs5.existsSync(canonicalPath)) return false;
14436
- const stat4 = fs5.statSync(canonicalPath);
14395
+ const canonicalHistory = this.provider.canonicalHistory;
14396
+ if (!canonicalHistory) return false;
14397
+ try {
14398
+ let rebuilt = false;
14399
+ if (canonicalHistory.format === "hermes-json") {
14400
+ const watchPath = canonicalHistory.watchPath.replace(/^~/, os13.homedir()).replace("{{sessionId}}", this.providerSessionId);
14401
+ if (!fs5.existsSync(watchPath)) return false;
14402
+ const stat4 = fs5.statSync(watchPath);
14437
14403
  if (stat4.mtimeMs <= this.lastCanonicalHermesSyncMtimeMs) return true;
14438
- const rebuilt = rebuildHermesSavedHistoryFromCanonicalSession(this.providerSessionId);
14439
- if (!rebuilt) return false;
14440
- this.lastCanonicalHermesSyncMtimeMs = stat4.mtimeMs;
14441
- const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId);
14442
- this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
14443
- role: message.role,
14444
- content: message.content,
14445
- kind: message.kind,
14446
- senderName: message.senderName,
14447
- receivedAt: message.receivedAt
14448
- }));
14449
- return true;
14450
- } catch {
14451
- return false;
14452
- }
14453
- }
14454
- if (this.type === "claude-cli") {
14455
- try {
14456
- const rebuilt = rebuildClaudeSavedHistoryFromNativeProject(this.providerSessionId, this.workingDir);
14457
- if (!rebuilt) return false;
14458
- const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId);
14459
- this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
14460
- role: message.role,
14461
- content: message.content,
14462
- kind: message.kind,
14463
- senderName: message.senderName,
14464
- receivedAt: message.receivedAt
14465
- }));
14466
- return true;
14467
- } catch {
14468
- return false;
14469
- }
14404
+ rebuilt = rebuildHermesSavedHistoryFromCanonicalSession(this.providerSessionId);
14405
+ if (rebuilt) this.lastCanonicalHermesSyncMtimeMs = stat4.mtimeMs;
14406
+ } else if (canonicalHistory.format === "claude-jsonl") {
14407
+ rebuilt = rebuildClaudeSavedHistoryFromNativeProject(this.providerSessionId, this.workingDir);
14408
+ }
14409
+ if (!rebuilt) return false;
14410
+ const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId, 0, this.provider.historyBehavior);
14411
+ this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
14412
+ role: message.role,
14413
+ content: message.content,
14414
+ kind: message.kind,
14415
+ senderName: message.senderName,
14416
+ receivedAt: message.receivedAt
14417
+ }));
14418
+ return true;
14419
+ } catch {
14420
+ return false;
14470
14421
  }
14471
- return false;
14472
14422
  }
14473
14423
  restorePersistedHistoryFromCurrentSession() {
14474
14424
  if (!this.providerSessionId) return;
14475
14425
  this.syncCanonicalSavedHistoryIfNeeded();
14476
- this.historyWriter.compactHistorySession(this.type, this.providerSessionId);
14477
- const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId);
14426
+ this.historyWriter.compactHistorySession(this.type, this.providerSessionId, this.provider.historyBehavior);
14427
+ const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId, 0, this.provider.historyBehavior);
14478
14428
  this.historyWriter.seedSessionHistory(
14479
14429
  this.type,
14480
14430
  restoredHistory.messages,
@@ -32026,14 +31976,15 @@ function expandResumeArgs(template, sessionId) {
32026
31976
  if (!Array.isArray(template) || template.length === 0) return void 0;
32027
31977
  return template.map((part) => part === "{{id}}" ? sessionId : part);
32028
31978
  }
32029
- function readCodexResumeSessionId(args) {
32030
- const resumeIndex = args.findIndex((arg) => arg === "resume" || arg === "fork");
31979
+ function readSubcommandSessionId(args, subcommands) {
31980
+ const resumeIndex = args.findIndex((arg) => subcommands.includes(arg));
32031
31981
  if (resumeIndex < 0) return void 0;
32032
31982
  const candidate = args[resumeIndex + 1];
32033
31983
  if (!candidate || candidate.startsWith("-")) return void 0;
32034
31984
  return candidate;
32035
31985
  }
32036
- function detectExplicitProviderSessionId(normalizedType, args) {
31986
+ function detectExplicitProviderSessionId(provider, args) {
31987
+ const resume = provider?.resume;
32037
31988
  const explicitResumeId = readArgValue(args, ["--resume", "-r"]);
32038
31989
  if (explicitResumeId) {
32039
31990
  return { providerSessionId: explicitResumeId, launchMode: "resume" };
@@ -32047,19 +31998,20 @@ function detectExplicitProviderSessionId(normalizedType, args) {
32047
31998
  }
32048
31999
  const explicitSessionId = readArgValue(args, ["--session-id"]);
32049
32000
  if (explicitSessionId) {
32050
- if (normalizedType === "goose-cli" && !hasArg(args, ["--resume", "-r"])) {
32001
+ if (resume?.sessionIdIsNewByDefault && !hasArg(args, ["--resume", "-r"])) {
32051
32002
  return { launchMode: "manual" };
32052
32003
  }
32053
- const isResume = normalizedType === "goose-cli" ? hasArg(args, ["--resume", "-r"]) : hasArg(args, ["--continue"]) || hasArg(args, ["--resume", "-r"]);
32004
+ const isResume = resume?.sessionIdIsNewByDefault ? hasArg(args, ["--resume", "-r"]) : hasArg(args, ["--continue"]) || hasArg(args, ["--resume", "-r"]);
32054
32005
  return {
32055
32006
  providerSessionId: explicitSessionId,
32056
32007
  launchMode: isResume ? "resume" : "new"
32057
32008
  };
32058
32009
  }
32059
- if (normalizedType === "codex-cli") {
32060
- const codexSessionId = readCodexResumeSessionId(args);
32061
- if (codexSessionId) {
32062
- return { providerSessionId: codexSessionId, launchMode: "resume" };
32010
+ const subcommands = resume?.sessionIdFromSubcommand;
32011
+ if (Array.isArray(subcommands) && subcommands.length > 0) {
32012
+ const subcommandSessionId = readSubcommandSessionId(args, subcommands);
32013
+ if (subcommandSessionId) {
32014
+ return { providerSessionId: subcommandSessionId, launchMode: "resume" };
32063
32015
  }
32064
32016
  }
32065
32017
  return { launchMode: "manual" };
@@ -32076,7 +32028,7 @@ function resolveCliSessionBinding(provider, normalizedType, cliArgs, requestedRe
32076
32028
  if (!resume?.supported) {
32077
32029
  return { cliArgs: baseArgs, launchMode: "manual" };
32078
32030
  }
32079
- const explicit = detectExplicitProviderSessionId(normalizedType, baseArgs || []);
32031
+ const explicit = detectExplicitProviderSessionId(provider, baseArgs || []);
32080
32032
  if (explicit.providerSessionId) {
32081
32033
  return {
32082
32034
  cliArgs: baseArgs,
@@ -32084,6 +32036,12 @@ function resolveCliSessionBinding(provider, normalizedType, cliArgs, requestedRe
32084
32036
  launchMode: explicit.launchMode
32085
32037
  };
32086
32038
  }
32039
+ if (explicit.launchMode === "manual" && hasArg(baseArgs || [], ["--session-id"])) {
32040
+ return {
32041
+ cliArgs: baseArgs,
32042
+ launchMode: "manual"
32043
+ };
32044
+ }
32087
32045
  if (requestedResumeSessionId) {
32088
32046
  if (resume.sessionIdFormat === "uuid" && !isUuid(requestedResumeSessionId)) {
32089
32047
  throw new Error(`Invalid ${provider?.displayName || provider?.name || normalizedType} session ID: ${requestedResumeSessionId}`);
@@ -32951,10 +32909,10 @@ var init_readdirp = __esm({
32951
32909
  }
32952
32910
  async _formatEntry(dirent, path29) {
32953
32911
  let entry;
32954
- const basename8 = this._isDirent ? dirent.name : dirent;
32912
+ const basename9 = this._isDirent ? dirent.name : dirent;
32955
32913
  try {
32956
- const fullPath = (0, import_node_path.resolve)((0, import_node_path.join)(path29, basename8));
32957
- entry = { path: (0, import_node_path.relative)(this._root, fullPath), fullPath, basename: basename8 };
32914
+ const fullPath = (0, import_node_path.resolve)((0, import_node_path.join)(path29, basename9));
32915
+ entry = { path: (0, import_node_path.relative)(this._root, fullPath), fullPath, basename: basename9 };
32958
32916
  entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
32959
32917
  } catch (err) {
32960
32918
  this._onError(err);
@@ -33485,9 +33443,9 @@ var init_handler2 = __esm({
33485
33443
  _watchWithNodeFs(path29, listener) {
33486
33444
  const opts = this.fsw.options;
33487
33445
  const directory = sp.dirname(path29);
33488
- const basename8 = sp.basename(path29);
33446
+ const basename9 = sp.basename(path29);
33489
33447
  const parent = this.fsw._getWatchedDir(directory);
33490
- parent.add(basename8);
33448
+ parent.add(basename9);
33491
33449
  const absolutePath = sp.resolve(path29);
33492
33450
  const options = {
33493
33451
  persistent: opts.persistent
@@ -33497,7 +33455,7 @@ var init_handler2 = __esm({
33497
33455
  let closer;
33498
33456
  if (opts.usePolling) {
33499
33457
  const enableBin = opts.interval !== opts.binaryInterval;
33500
- options.interval = enableBin && isBinaryPath(basename8) ? opts.binaryInterval : opts.interval;
33458
+ options.interval = enableBin && isBinaryPath(basename9) ? opts.binaryInterval : opts.interval;
33501
33459
  closer = setFsWatchFileListener(path29, absolutePath, options, {
33502
33460
  listener,
33503
33461
  rawEmitter: this.fsw._emitRaw
@@ -33519,11 +33477,11 @@ var init_handler2 = __esm({
33519
33477
  if (this.fsw.closed) {
33520
33478
  return;
33521
33479
  }
33522
- const dirname9 = sp.dirname(file2);
33523
- const basename8 = sp.basename(file2);
33524
- const parent = this.fsw._getWatchedDir(dirname9);
33480
+ const dirname10 = sp.dirname(file2);
33481
+ const basename9 = sp.basename(file2);
33482
+ const parent = this.fsw._getWatchedDir(dirname10);
33525
33483
  let prevStats = stats;
33526
- if (parent.has(basename8))
33484
+ if (parent.has(basename9))
33527
33485
  return;
33528
33486
  const listener = async (path29, newStats) => {
33529
33487
  if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file2, 5))
@@ -33548,9 +33506,9 @@ var init_handler2 = __esm({
33548
33506
  prevStats = newStats2;
33549
33507
  }
33550
33508
  } catch (error48) {
33551
- this.fsw._remove(dirname9, basename8);
33509
+ this.fsw._remove(dirname10, basename9);
33552
33510
  }
33553
- } else if (parent.has(basename8)) {
33511
+ } else if (parent.has(basename9)) {
33554
33512
  const at = newStats.atimeMs;
33555
33513
  const mt = newStats.mtimeMs;
33556
33514
  if (!at || at <= mt || mt !== prevStats.mtimeMs) {
@@ -34686,6 +34644,11 @@ var init_provider_schema = __esm({
34686
34644
  "resume",
34687
34645
  "sessionProbe",
34688
34646
  "approvalPositiveHints",
34647
+ "sessionIdPattern",
34648
+ "historyBehavior",
34649
+ "canonicalHistory",
34650
+ "autoFixProfile",
34651
+ "ideLevelScripts",
34689
34652
  "scripts",
34690
34653
  "vscodeCommands",
34691
34654
  "inputMethod",
@@ -36865,9 +36828,82 @@ function appendUpgradeLog(message) {
36865
36828
  } catch {
36866
36829
  }
36867
36830
  }
36868
- function getNpmExecutable() {
36831
+ function resolveSiblingNpmExecutable(nodeExecutable) {
36832
+ const binDir = path16.dirname(nodeExecutable);
36833
+ const candidates = process.platform === "win32" ? ["npm.cmd", "npm.exe", "npm"] : ["npm"];
36834
+ for (const candidate of candidates) {
36835
+ const candidatePath = path16.join(binDir, candidate);
36836
+ if (fs8.existsSync(candidatePath)) {
36837
+ return candidatePath;
36838
+ }
36839
+ }
36869
36840
  return "npm";
36870
36841
  }
36842
+ function findCurrentPackageRoot(currentCliPath, packageName) {
36843
+ if (!currentCliPath) return null;
36844
+ let resolvedPath = currentCliPath;
36845
+ try {
36846
+ resolvedPath = fs8.realpathSync.native(currentCliPath);
36847
+ } catch {
36848
+ }
36849
+ let currentDir = resolvedPath;
36850
+ try {
36851
+ if (fs8.statSync(resolvedPath).isFile()) {
36852
+ currentDir = path16.dirname(resolvedPath);
36853
+ }
36854
+ } catch {
36855
+ currentDir = path16.dirname(resolvedPath);
36856
+ }
36857
+ while (true) {
36858
+ const packageJsonPath = path16.join(currentDir, "package.json");
36859
+ try {
36860
+ if (fs8.existsSync(packageJsonPath)) {
36861
+ const parsed = JSON.parse(fs8.readFileSync(packageJsonPath, "utf8"));
36862
+ if (parsed?.name === packageName) {
36863
+ const normalized = currentDir.replace(/\\/g, "/");
36864
+ return normalized.includes("/node_modules/") ? currentDir : null;
36865
+ }
36866
+ }
36867
+ } catch {
36868
+ }
36869
+ const parentDir = path16.dirname(currentDir);
36870
+ if (parentDir === currentDir) {
36871
+ return null;
36872
+ }
36873
+ currentDir = parentDir;
36874
+ }
36875
+ }
36876
+ function resolveInstallPrefixFromPackageRoot(packageRoot, packageName) {
36877
+ const nodeModulesDir = packageName.startsWith("@") ? path16.dirname(path16.dirname(packageRoot)) : path16.dirname(packageRoot);
36878
+ if (path16.basename(nodeModulesDir) !== "node_modules") {
36879
+ return null;
36880
+ }
36881
+ const maybeLibDir = path16.dirname(nodeModulesDir);
36882
+ if (path16.basename(maybeLibDir) === "lib") {
36883
+ return path16.dirname(maybeLibDir);
36884
+ }
36885
+ return maybeLibDir;
36886
+ }
36887
+ function resolveCurrentGlobalInstallSurface(options) {
36888
+ const packageRoot = findCurrentPackageRoot(options.currentCliPath || process.argv[1], options.packageName);
36889
+ return {
36890
+ npmExecutable: resolveSiblingNpmExecutable(options.nodeExecutable || process.execPath),
36891
+ packageRoot,
36892
+ installPrefix: packageRoot ? resolveInstallPrefixFromPackageRoot(packageRoot, options.packageName) : null
36893
+ };
36894
+ }
36895
+ function buildPinnedGlobalInstallCommand(options) {
36896
+ const surface = resolveCurrentGlobalInstallSurface(options);
36897
+ const args = ["install", "-g", `${options.packageName}@${options.targetVersion || "latest"}`, "--force"];
36898
+ if (surface.installPrefix) {
36899
+ args.push("--prefix", surface.installPrefix);
36900
+ }
36901
+ return {
36902
+ command: surface.npmExecutable,
36903
+ args,
36904
+ surface
36905
+ };
36906
+ }
36871
36907
  function getNpmExecOptions() {
36872
36908
  return { shell: process.platform === "win32" };
36873
36909
  }
@@ -36930,11 +36966,12 @@ function removeDaemonPidFile() {
36930
36966
  } catch {
36931
36967
  }
36932
36968
  }
36933
- function cleanupStaleGlobalInstallDirs(pkgName) {
36969
+ function cleanupStaleGlobalInstallDirs(pkgName, surface) {
36934
36970
  const npmExecOpts = getNpmExecOptions();
36935
- const npmRoot = (0, import_child_process7.execFileSync)(getNpmExecutable(), ["root", "-g"], { encoding: "utf8", ...npmExecOpts }).trim();
36971
+ const prefixArgs = surface.installPrefix ? ["--prefix", surface.installPrefix] : [];
36972
+ const npmRoot = (0, import_child_process7.execFileSync)(surface.npmExecutable, ["root", "-g", ...prefixArgs], { encoding: "utf8", ...npmExecOpts }).trim();
36936
36973
  if (!npmRoot) return;
36937
- const npmPrefix = (0, import_child_process7.execFileSync)(getNpmExecutable(), ["prefix", "-g"], { encoding: "utf8", ...npmExecOpts }).trim();
36974
+ const npmPrefix = surface.installPrefix || (0, import_child_process7.execFileSync)(surface.npmExecutable, ["prefix", "-g", ...prefixArgs], { encoding: "utf8", ...npmExecOpts }).trim();
36938
36975
  const binDir = process.platform === "win32" ? npmPrefix : path16.join(npmPrefix, "bin");
36939
36976
  const packageBaseName = pkgName.startsWith("@") ? pkgName.split("/")[1] : pkgName;
36940
36977
  const binNames = /* @__PURE__ */ new Set([packageBaseName]);
@@ -36959,7 +36996,7 @@ function cleanupStaleGlobalInstallDirs(pkgName) {
36959
36996
  }
36960
36997
  if (fs8.existsSync(binDir)) {
36961
36998
  for (const entry of fs8.readdirSync(binDir)) {
36962
- if (![...binNames].some((name) => entry.startsWith(`.${name}-`))) continue;
36999
+ if (!Array.from(binNames).some((name) => entry.startsWith(`.${name}-`))) continue;
36963
37000
  fs8.rmSync(path16.join(binDir, entry), { recursive: true, force: true });
36964
37001
  appendUpgradeLog(`Removed stale bin staging entry: ${path16.join(binDir, entry)}`);
36965
37002
  }
@@ -36979,19 +37016,27 @@ function spawnDetachedDaemonUpgradeHelper(payload) {
36979
37016
  async function runDaemonUpgradeHelper(payload) {
36980
37017
  const restartArgv = Array.isArray(payload.restartArgv) ? payload.restartArgv : [];
36981
37018
  const sessionHostAppName = payload.sessionHostAppName || process.env.ADHDEV_SESSION_HOST_NAME || "adhdev";
37019
+ const installCommand = buildPinnedGlobalInstallCommand({
37020
+ packageName: payload.packageName,
37021
+ targetVersion: payload.targetVersion
37022
+ });
36982
37023
  appendUpgradeLog(`Upgrade helper started for ${payload.packageName}@${payload.targetVersion}`);
37024
+ appendUpgradeLog(`Using npm executable: ${installCommand.command}`);
37025
+ if (installCommand.surface.installPrefix) {
37026
+ appendUpgradeLog(`Pinned install prefix: ${installCommand.surface.installPrefix}`);
37027
+ }
36983
37028
  if (Number.isFinite(payload.parentPid) && payload.parentPid > 0) {
36984
37029
  appendUpgradeLog(`Waiting for parent pid ${payload.parentPid} to exit`);
36985
37030
  await waitForPidExit(payload.parentPid, 15e3);
36986
37031
  }
36987
37032
  stopSessionHostProcesses(sessionHostAppName);
36988
37033
  removeDaemonPidFile();
36989
- cleanupStaleGlobalInstallDirs(payload.packageName);
37034
+ cleanupStaleGlobalInstallDirs(payload.packageName, installCommand.surface);
36990
37035
  const spec = `${payload.packageName}@${payload.targetVersion || "latest"}`;
36991
37036
  appendUpgradeLog(`Installing ${spec}`);
36992
37037
  const installOutput = (0, import_child_process7.execFileSync)(
36993
- getNpmExecutable(),
36994
- ["install", "-g", spec, "--force"],
37038
+ installCommand.command,
37039
+ installCommand.args,
36995
37040
  {
36996
37041
  encoding: "utf8",
36997
37042
  stdio: "pipe",
@@ -37004,7 +37049,7 @@ async function runDaemonUpgradeHelper(payload) {
37004
37049
  }
37005
37050
  if (process.platform === "win32") {
37006
37051
  await new Promise((resolve16) => setTimeout(resolve16, 500));
37007
- cleanupStaleGlobalInstallDirs(payload.packageName);
37052
+ cleanupStaleGlobalInstallDirs(payload.packageName, installCommand.surface);
37008
37053
  appendUpgradeLog("Post-install staging cleanup complete");
37009
37054
  }
37010
37055
  if (restartArgv.length > 0) {
@@ -41955,20 +42000,13 @@ function tryKillAutoImplProcess(processRef, signal) {
41955
42000
  } catch {
41956
42001
  }
41957
42002
  }
42003
+ function shouldScheduleAutoStopOnQuiet(options) {
42004
+ return !!options.verification && options.autoImpl?.autoStopOnQuiet === true;
42005
+ }
41958
42006
  function getDefaultAutoImplReference(ctx, category, type) {
41959
- if (category === "cli") {
41960
- return type === "codex-cli" ? "claude-cli" : "codex-cli";
41961
- }
41962
- if (category === "extension") {
41963
- const preferred = ["claude-code-vscode", "codex", "cline", "roo-code"];
41964
- for (const ref of preferred) {
41965
- if (ref === type) continue;
41966
- if (ctx.providerLoader.resolve(ref) || ctx.providerLoader.getMeta(ref)) return ref;
41967
- }
41968
- const all = ctx.providerLoader.getAll();
41969
- const fb = all.find((p) => p.category === "extension" && p.type !== type);
41970
- if (fb?.type) return fb.type;
41971
- }
42007
+ const all = ctx.providerLoader.getAll();
42008
+ const sameCategoryOther = all.find((p) => p.category === category && p.type !== type);
42009
+ if (sameCategoryOther?.type) return sameCategoryOther.type;
41972
42010
  return "antigravity";
41973
42011
  }
41974
42012
  function resolveAutoImplReference(ctx, category, requestedReference, targetType) {
@@ -42286,37 +42324,33 @@ async function handleAutoImplement(ctx, type, req, res) {
42286
42324
  return;
42287
42325
  }
42288
42326
  const command = spawn6.command;
42327
+ const autoImpl = spawn6.autoImpl;
42289
42328
  const interactiveFlags = ["--yolo", "--interactive", "-i"];
42290
42329
  const baseArgs = [...spawn6.args || []].filter((a) => !interactiveFlags.includes(a));
42291
42330
  let shellCmd;
42292
42331
  const isWin = os21.platform() === "win32";
42293
42332
  const escapeArg = (a) => isWin ? `"${a.replace(/"/g, '""')}"` : `'${a.replace(/'/g, "'\\''")}'`;
42294
- if (command === "claude") {
42295
- const args = [...baseArgs, "--dangerously-skip-permissions"];
42333
+ const promptMode = autoImpl?.promptMode ?? "stdin";
42334
+ const extraArgs = autoImpl?.extraArgs ?? [];
42335
+ const rawMetaPrompt = autoImpl?.metaPrompt ? autoImpl.metaPrompt.replace("{{promptFile}}", promptFile) : `Read the file at ${promptFile} and follow ALL the instructions in it exactly. Do not ask questions, just execute.`;
42336
+ if (promptMode === "flag") {
42337
+ const flag = autoImpl?.promptFlag ?? "-p";
42338
+ const args = [...baseArgs, ...extraArgs];
42296
42339
  if (model) args.push("--model", model);
42297
42340
  const escapedArgs = args.map(escapeArg).join(" ");
42298
- const metaPrompt = `Read the file at ${promptFile} and follow ALL the instructions. Implement the specific function requested, then test it via CDP curl targeting 127.0.0.1:19280, wait for confirmation of success, and then close. DO NOT start working on other features not listed in the prompt constraint.`;
42299
- shellCmd = `${command} ${escapedArgs} -p ${escapeArg(metaPrompt)}`;
42300
- } else if (command === "gemini") {
42301
- const args = [...baseArgs, "-y", "-s", "false"];
42302
- if (model) args.push("-m", model);
42303
- const escapedArgs = args.map(escapeArg).join(" ");
42304
- const metaPrompt = `Read the file at ${promptFile} and follow ALL the instructions in it exactly. Do not ask questions, just execute.`;
42305
- shellCmd = `${command} ${escapedArgs} -p ${escapeArg(metaPrompt)}`;
42306
- } else if (command === "codex") {
42307
- const args = ["exec", ...baseArgs];
42308
- if (!args.includes("--dangerously-bypass-approvals-and-sandbox")) {
42309
- args.push("--dangerously-bypass-approvals-and-sandbox");
42310
- }
42311
- if (!args.includes("--skip-git-repo-check")) {
42312
- args.push("--skip-git-repo-check");
42341
+ shellCmd = `${command} ${escapedArgs} ${flag} ${escapeArg(rawMetaPrompt)}`;
42342
+ } else if (promptMode === "subcommand") {
42343
+ const subcommand = autoImpl?.subcommand ?? "";
42344
+ const args = subcommand ? [subcommand, ...baseArgs] : [...baseArgs];
42345
+ for (const extra of extraArgs) {
42346
+ if (!args.includes(extra)) args.push(extra);
42313
42347
  }
42314
42348
  if (model) args.push("--model", model);
42315
42349
  const escapedArgs = args.map(escapeArg).join(" ");
42316
- const metaPrompt = `Read the file at ${promptFile} and follow ALL instructions strictly. DO NOT spend time exploring the filesystem or other providers. You have full authority to implement ALL required script files and independently test them against 127.0.0.1:19280 via CDP CURL. Upon complete validation of ALL assigned files, print exactly "_PIPELINE_COMPLETE_SIGNAL_" to gracefully close the pipeline. DO NOT WAIT FOR APPROVAL, execute completely autonomously.`;
42317
- shellCmd = `${command} ${escapedArgs} ${escapeArg(metaPrompt)}`;
42350
+ shellCmd = `${command} ${escapedArgs} ${escapeArg(rawMetaPrompt)}`;
42318
42351
  } else {
42319
- const escapedArgs = baseArgs.map(escapeArg).join(" ");
42352
+ const args = [...baseArgs, ...extraArgs];
42353
+ const escapedArgs = args.map(escapeArg).join(" ");
42320
42354
  if (isWin) {
42321
42355
  shellCmd = `type "${promptFile}" | ${command} ${escapedArgs}`;
42322
42356
  } else {
@@ -42351,8 +42385,7 @@ async function handleAutoImplement(ctx, type, req, res) {
42351
42385
  stdio: ["pipe", "pipe", "pipe"],
42352
42386
  env: {
42353
42387
  ...process.env,
42354
- ...spawn6.env || {},
42355
- ...command === "gemini" ? { SANDBOX: "1", GEMINI_CLI_NO_RELAUNCH: "1" } : {}
42388
+ ...spawn6.env || {}
42356
42389
  }
42357
42390
  });
42358
42391
  child.on("error", (err2) => {
@@ -42414,7 +42447,7 @@ async function handleAutoImplement(ctx, type, req, res) {
42414
42447
  }
42415
42448
  };
42416
42449
  const scheduleAutoStopForVerification = () => {
42417
- if (!verification || command !== "codex" || completionSignalSeen || autoStopIssued) return;
42450
+ if (!shouldScheduleAutoStopOnQuiet({ verification, autoImpl }) || completionSignalSeen || autoStopIssued) return;
42418
42451
  const elapsed = Date.now() - spawnedAt;
42419
42452
  if (elapsed < 3e4) return;
42420
42453
  clearAutoStopTimer();
@@ -45892,6 +45925,7 @@ __export(src_exports, {
45892
45925
  buildChatMessageSignature: () => buildChatMessageSignature,
45893
45926
  buildChatTailDeliverySignature: () => buildChatTailDeliverySignature,
45894
45927
  buildMachineInfo: () => buildMachineInfo,
45928
+ buildPinnedGlobalInstallCommand: () => buildPinnedGlobalInstallCommand,
45895
45929
  buildRuntimeSystemChatMessage: () => buildRuntimeSystemChatMessage,
45896
45930
  buildSessionEntries: () => buildSessionEntries,
45897
45931
  buildSessionModalDeliverySignature: () => buildSessionModalDeliverySignature,
@@ -45974,6 +46008,7 @@ __export(src_exports, {
45974
46008
  resetDebugRuntimeConfig: () => resetDebugRuntimeConfig,
45975
46009
  resetState: () => resetState,
45976
46010
  resolveChatMessageKind: () => resolveChatMessageKind,
46011
+ resolveCurrentGlobalInstallSurface: () => resolveCurrentGlobalInstallSurface,
45977
46012
  resolveDebugRuntimeConfig: () => resolveDebugRuntimeConfig,
45978
46013
  resolveSessionHostAppName: () => resolveSessionHostAppName,
45979
46014
  resolveSessionHostAppNameResolution: () => resolveSessionHostAppNameResolution,
@@ -55375,7 +55410,7 @@ var init_adhdev_daemon = __esm({
55375
55410
  init_version();
55376
55411
  init_src();
55377
55412
  init_runtime_defaults();
55378
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.2" });
55413
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.5" });
55379
55414
  AdhdevDaemon = class _AdhdevDaemon {
55380
55415
  localHttpServer = null;
55381
55416
  localWss = null;
@@ -87473,6 +87508,7 @@ var open_default = open2;
87473
87508
 
87474
87509
  // src/wizard.ts
87475
87510
  init_src();
87511
+ init_version();
87476
87512
  var SERVER_URL = process.env.ADHDEV_SERVER_URL || "https://api.adhf.dev";
87477
87513
  var LOGO = `
87478
87514
  ${source_default2.cyan("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557")}
@@ -87485,6 +87521,36 @@ function hasCloudMachineAuth() {
87485
87521
  const config2 = loadConfig();
87486
87522
  return Boolean(config2.machineSecret && config2.machineSecret.trim());
87487
87523
  }
87524
+ function readLatestPublishedCliVersion(execFileSyncLocal) {
87525
+ const surface = resolveCurrentGlobalInstallSurface({ packageName: "adhdev" });
87526
+ try {
87527
+ return execFileSyncLocal(surface.npmExecutable, ["view", "adhdev", "version"], {
87528
+ encoding: "utf-8",
87529
+ timeout: 5e3,
87530
+ stdio: ["pipe", "pipe", "pipe"]
87531
+ }).trim();
87532
+ } catch {
87533
+ return null;
87534
+ }
87535
+ }
87536
+ function readInstalledGlobalCliVersion(execFileSyncLocal) {
87537
+ const surface = resolveCurrentGlobalInstallSurface({ packageName: "adhdev" });
87538
+ const args = ["list", "-g", "adhdev", "--json"];
87539
+ if (surface.installPrefix) {
87540
+ args.push("--prefix", surface.installPrefix);
87541
+ }
87542
+ try {
87543
+ const result = execFileSyncLocal(surface.npmExecutable, args, {
87544
+ encoding: "utf-8",
87545
+ timeout: 5e3,
87546
+ stdio: ["pipe", "pipe", "pipe"]
87547
+ });
87548
+ const parsed = JSON.parse(result);
87549
+ return parsed.dependencies?.adhdev?.version || null;
87550
+ } catch {
87551
+ return null;
87552
+ }
87553
+ }
87488
87554
  async function runWizard(options = {}) {
87489
87555
  console.log(LOGO);
87490
87556
  if (isSetupComplete() && hasCloudMachineAuth() && !options.force) {
@@ -87500,27 +87566,10 @@ async function runWizard(options = {}) {
87500
87566
  }
87501
87567
  async function checkForUpdate() {
87502
87568
  try {
87503
- const { execSync: execSync7 } = await import("child_process");
87504
- let currentVersion = null;
87505
- try {
87506
- currentVersion = execSync7("adhdev --version", {
87507
- encoding: "utf-8",
87508
- timeout: 3e3,
87509
- stdio: ["pipe", "pipe", "pipe"]
87510
- }).trim();
87511
- } catch {
87512
- return;
87513
- }
87514
- let latestVersion = null;
87515
- try {
87516
- latestVersion = execSync7("npm show adhdev version", {
87517
- encoding: "utf-8",
87518
- timeout: 5e3,
87519
- stdio: ["pipe", "pipe", "pipe"]
87520
- }).trim();
87521
- } catch {
87522
- return;
87523
- }
87569
+ const { execFileSync: execFileSync4 } = await import("child_process");
87570
+ const currentVersion = resolvePackageVersion();
87571
+ const latestVersion = readLatestPublishedCliVersion(execFileSync4);
87572
+ if (!latestVersion) return;
87524
87573
  if (!currentVersion || !latestVersion || currentVersion === latestVersion) return;
87525
87574
  console.log(source_default2.yellow(` Update available: ${currentVersion} \u2192 ${latestVersion}`));
87526
87575
  const { doUpdate } = await (await Promise.resolve().then(() => (init_lib(), lib_exports))).default.prompt([{
@@ -87535,7 +87584,8 @@ async function checkForUpdate() {
87535
87584
  }
87536
87585
  const spinner = (await Promise.resolve().then(() => (init_ora(), ora_exports))).default("Updating adhdev CLI...").start();
87537
87586
  try {
87538
- execSync7("npm install -g adhdev@latest", {
87587
+ const installCommand = buildPinnedGlobalInstallCommand({ packageName: "adhdev", targetVersion: "latest" });
87588
+ execFileSync4(installCommand.command, installCommand.args, {
87539
87589
  encoding: "utf-8",
87540
87590
  timeout: 6e4,
87541
87591
  stdio: ["pipe", "pipe", "pipe"]
@@ -87773,18 +87823,8 @@ async function startDaemonFlow() {
87773
87823
  }
87774
87824
  }
87775
87825
  async function installCliOnly() {
87776
- const { execSync: execSyncLocal } = await import("child_process");
87777
- let currentVersion = null;
87778
- try {
87779
- const result = execSyncLocal("npm list -g adhdev --json 2>/dev/null || npm list -g adhdev --json 2>nul", {
87780
- encoding: "utf-8",
87781
- timeout: 5e3,
87782
- stdio: ["pipe", "pipe", "pipe"]
87783
- });
87784
- const parsed = JSON.parse(result);
87785
- currentVersion = parsed.dependencies?.adhdev?.version || null;
87786
- } catch {
87787
- }
87826
+ const { execFileSync: execFileSyncLocal } = await import("child_process");
87827
+ const currentVersion = readInstalledGlobalCliVersion(execFileSyncLocal);
87788
87828
  const isNpx = process.env.npm_execpath?.includes("npx") || process.argv[1]?.includes("npx") || process.argv[1]?.includes("_npx");
87789
87829
  console.log(source_default2.bold("\n\u{1F527} ADHDev CLI\n"));
87790
87830
  console.log(source_default2.gray(" The `adhdev` command lets you:"));
@@ -87795,15 +87835,7 @@ async function installCliOnly() {
87795
87835
  console.log();
87796
87836
  if (currentVersion) {
87797
87837
  console.log(source_default2.green(` \u2713 Currently installed: v${currentVersion}`));
87798
- let latestVersion = null;
87799
- try {
87800
- latestVersion = execSyncLocal("npm show adhdev version", {
87801
- encoding: "utf-8",
87802
- timeout: 5e3,
87803
- stdio: ["pipe", "pipe", "pipe"]
87804
- }).trim();
87805
- } catch {
87806
- }
87838
+ const latestVersion = readLatestPublishedCliVersion(execFileSyncLocal);
87807
87839
  if (latestVersion && currentVersion === latestVersion) {
87808
87840
  console.log(source_default2.gray(" (Already up to date)"));
87809
87841
  return;
@@ -87838,20 +87870,13 @@ async function installCliOnly() {
87838
87870
  }
87839
87871
  const installSpinner = ora2("Installing adhdev CLI...").start();
87840
87872
  try {
87841
- execSyncLocal("npm install -g adhdev@latest", {
87873
+ const installCommand = buildPinnedGlobalInstallCommand({ packageName: "adhdev", targetVersion: "latest" });
87874
+ execFileSyncLocal(installCommand.command, installCommand.args, {
87842
87875
  encoding: "utf-8",
87843
87876
  timeout: 6e4,
87844
87877
  stdio: ["pipe", "pipe", "pipe"]
87845
87878
  });
87846
- let newVersion = "latest";
87847
- try {
87848
- newVersion = execSyncLocal("adhdev --version 2>/dev/null || adhdev --version 2>nul", {
87849
- encoding: "utf-8",
87850
- timeout: 5e3,
87851
- stdio: ["pipe", "pipe", "pipe"]
87852
- }).trim();
87853
- } catch {
87854
- }
87879
+ const newVersion = readInstalledGlobalCliVersion(execFileSyncLocal) || "latest";
87855
87880
  installSpinner.succeed(`adhdev CLI ${currentVersion ? "updated" : "installed"} \u2713 (v${newVersion})`);
87856
87881
  console.log(source_default2.gray(" Try: adhdev daemon"));
87857
87882
  console.log();