@adhdev/daemon-core 0.6.56 → 0.6.58

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.
Files changed (37) hide show
  1. package/dist/index.d.ts +23 -0
  2. package/dist/index.js +423 -95
  3. package/dist/index.js.map +1 -1
  4. package/package.json +1 -1
  5. package/providers/_builtin/cli/aider-cli/scripts/1.0/parse_output.js +51 -3
  6. package/providers/_builtin/cli/claude-cli/provider.json +18 -6
  7. package/providers/_builtin/cli/claude-cli/scripts/1.0/detect_status.js +68 -16
  8. package/providers/_builtin/cli/claude-cli/scripts/1.0/parse_approval.js +81 -22
  9. package/providers/_builtin/cli/claude-cli/scripts/1.0/parse_output.js +347 -94
  10. package/providers/_builtin/cli/codex-cli/provider.json +2 -0
  11. package/providers/_builtin/cli/codex-cli/scripts/1.0/detect_status.js +44 -10
  12. package/providers/_builtin/cli/codex-cli/scripts/1.0/parse_approval.js +83 -7
  13. package/providers/_builtin/cli/codex-cli/scripts/1.0/parse_output.js +501 -47
  14. package/providers/_builtin/cli/cursor-cli/scripts/1.0/parse_output.js +1 -1
  15. package/providers/_builtin/cli/github-copilot-cli/scripts/1.0/parse_output.js +1 -1
  16. package/providers/_builtin/cli/goose-cli/scripts/1.0/parse_output.js +1 -1
  17. package/providers/_builtin/cli/opencode-cli/scripts/1.0/parse_output.js +1 -1
  18. package/providers/_builtin/ide/vscode/provider.json +5 -1
  19. package/providers/_builtin/ide/vscode/scripts/1.0/focus_editor.js +1 -0
  20. package/providers/_builtin/ide/vscode/scripts/1.0/list_models.js +1 -0
  21. package/providers/_builtin/ide/vscode/scripts/1.0/list_sessions.js +1 -0
  22. package/providers/_builtin/ide/vscode/scripts/1.0/new_session.js +1 -0
  23. package/providers/_builtin/ide/vscode/scripts/1.0/open_panel.js +1 -0
  24. package/providers/_builtin/ide/vscode/scripts/1.0/read_chat.js +1 -0
  25. package/providers/_builtin/ide/vscode/scripts/1.0/resolve_action.js +1 -0
  26. package/providers/_builtin/ide/vscode/scripts/1.0/scripts.js +25 -0
  27. package/providers/_builtin/ide/vscode/scripts/1.0/send_message.js +1 -0
  28. package/providers/_builtin/ide/vscode/scripts/1.0/set_model.js +1 -0
  29. package/providers/_builtin/ide/vscode/scripts/1.0/switch_session.js +1 -0
  30. package/providers/_builtin/registry.json +1 -1
  31. package/src/cli-adapters/provider-cli-adapter.ts +410 -65
  32. package/src/commands/chat-commands.ts +7 -1
  33. package/src/config/chat-history.ts +53 -1
  34. package/src/daemon/dev-server.ts +7 -9
  35. package/src/providers/cli-provider-instance.ts +10 -23
  36. package/src/providers/provider-instance.ts +1 -0
  37. package/src/providers/version-archive.ts +4 -1
@@ -35,7 +35,13 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
35
35
  _log(`${provider.category} adapter: ${(adapter as any).cliType}`);
36
36
  const status = (adapter as any).getStatus?.();
37
37
  if (status) {
38
- return { success: true, messages: status.messages || [], status: status.status, activeModal: status.activeModal };
38
+ return {
39
+ success: true,
40
+ messages: status.messages || [],
41
+ status: status.status,
42
+ activeModal: status.activeModal,
43
+ terminalHistory: status.terminalHistory || '',
44
+ };
39
45
  }
40
46
  }
41
47
  return { success: false, error: `${provider.category} adapter not found` };
@@ -31,6 +31,8 @@ export class ChatHistoryWriter {
31
31
  private lastSeenCounts = new Map<string, number>();
32
32
  /** Last seen message hash per agent (deduplication) */
33
33
  private lastSeenHashes = new Map<string, Set<string>>();
34
+ /** Last seen append-only terminal transcript per agent */
35
+ private lastSeenTerminal = new Map<string, string>();
34
36
  private rotated = false;
35
37
 
36
38
  /**
@@ -107,10 +109,60 @@ export class ChatHistoryWriter {
107
109
  }
108
110
  }
109
111
 
112
+ appendTerminalHistory(
113
+ agentType: string,
114
+ terminalHistory: string,
115
+ sessionTitle?: string,
116
+ instanceId?: string,
117
+ ): void {
118
+ const next = String(terminalHistory || '');
119
+ if (!next.trim()) return;
120
+
121
+ try {
122
+ const dedupKey = instanceId ? `${agentType}:${instanceId}:terminal` : `${agentType}:terminal`;
123
+ const prev = this.lastSeenTerminal.get(dedupKey) || '';
124
+ if (prev === next) return;
125
+
126
+ let delta = '';
127
+ if (!prev) {
128
+ delta = next;
129
+ } else if (next.startsWith(prev)) {
130
+ delta = next.slice(prev.length);
131
+ } else if (prev.includes(next)) {
132
+ this.lastSeenTerminal.set(dedupKey, next);
133
+ return;
134
+ } else {
135
+ delta = `\n\n[terminal snapshot reset ${new Date().toISOString()} | ${sessionTitle || agentType}]\n${next}`;
136
+ }
137
+
138
+ if (!delta) {
139
+ this.lastSeenTerminal.set(dedupKey, next);
140
+ return;
141
+ }
142
+
143
+ const dir = path.join(HISTORY_DIR, this.sanitize(agentType));
144
+ fs.mkdirSync(dir, { recursive: true });
145
+
146
+ const date = new Date().toISOString().slice(0, 10);
147
+ const filePrefix = instanceId ? `${this.sanitize(instanceId)}_` : '';
148
+ const filePath = path.join(dir, `${filePrefix}${date}.terminal.log`);
149
+ fs.appendFileSync(filePath, delta, 'utf-8');
150
+ this.lastSeenTerminal.set(dedupKey, next);
151
+
152
+ if (!this.rotated) {
153
+ this.rotated = true;
154
+ this.rotateOldFiles().catch(() => {});
155
+ }
156
+ } catch {
157
+ // Ignore terminal history save failures
158
+ }
159
+ }
160
+
110
161
  /** Called when agent session is explicitly changed */
111
162
  onSessionChange(agentType: string): void {
112
163
  this.lastSeenHashes.delete(agentType);
113
164
  this.lastSeenCounts.delete(agentType);
165
+ this.lastSeenTerminal.delete(`${agentType}:terminal`);
114
166
  }
115
167
 
116
168
  /** Delete history files older than 30 days */
@@ -125,7 +177,7 @@ export class ChatHistoryWriter {
125
177
  for (const dir of agentDirs) {
126
178
  const dirPath = path.join(HISTORY_DIR, dir.name);
127
179
  const files = fs.readdirSync(dirPath)
128
- .filter(f => f.endsWith('.jsonl'));
180
+ .filter(f => f.endsWith('.jsonl') || f.endsWith('.terminal.log'));
129
181
 
130
182
  for (const file of files) {
131
183
  const filePath = path.join(dirPath, file);
@@ -19,6 +19,7 @@ import * as fs from 'fs';
19
19
  import * as path from 'path';
20
20
  import * as os from 'os';
21
21
  import type { ProviderLoader } from '../providers/provider-loader.js';
22
+ import type { ProviderCategory } from '../providers/contracts.js';
22
23
  import type { ChildProcess } from 'child_process';
23
24
  import type { DaemonCdpManager } from '../cdp/manager.js';
24
25
  import type { ProviderInstanceManager } from '../providers/provider-instance-manager.js';
@@ -1107,11 +1108,7 @@ export class DevServer {
1107
1108
  }
1108
1109
 
1109
1110
  let targetDir: string;
1110
- if (location === 'user') {
1111
- targetDir = this.providerLoader.getUserProviderDir(category, type);
1112
- } else {
1113
- targetDir = this.providerLoader.getBuiltinProviderDir(category, type);
1114
- }
1111
+ targetDir = this.providerLoader.getUserProviderDir(category, type);
1115
1112
 
1116
1113
  const jsonPath = path.join(targetDir, 'provider.json');
1117
1114
  if (fs.existsSync(jsonPath)) {
@@ -1883,11 +1880,10 @@ export class DevServer {
1883
1880
  return fallback?.type || null;
1884
1881
  }
1885
1882
 
1886
- private loadAutoImplReferenceScripts(category: string, referenceType: string | null): Record<string, string> {
1883
+ private loadAutoImplReferenceScripts(category: ProviderCategory, referenceType: string | null): Record<string, string> {
1887
1884
  if (!referenceType) return {};
1888
1885
 
1889
- const builtinDir = this.providerLoader.getPrimaryBuiltinDir();
1890
- const refDir = path.join(builtinDir, category, referenceType);
1886
+ const refDir = this.providerLoader.getUpstreamProviderDir(category, referenceType);
1891
1887
  if (!fs.existsSync(refDir)) return {};
1892
1888
 
1893
1889
  const referenceScripts: Record<string, string> = {};
@@ -2138,7 +2134,7 @@ export class DevServer {
2138
2134
  }
2139
2135
  if (model) args.push('--model', model);
2140
2136
  const escapedArgs = args.map(a => `'${a.replace(/'/g, "'\\''")}'`).join(' ');
2141
- const metaPrompt = `Read the file at ${promptFile} and follow ALL instructions recursively. You have full authority to implement ALL required script files, update provider.json configurations based on the reference patterns, 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.`;
2137
+ 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.`;
2142
2138
  shellCmd = `${command} ${escapedArgs} "${metaPrompt}"`;
2143
2139
  } else {
2144
2140
  // Generic fallback: pipe prompt via stdin
@@ -2423,6 +2419,8 @@ export class DevServer {
2423
2419
  lines.push('5. Do NOT modify `scripts.js` router — only edit individual `*.js` files');
2424
2420
  lines.push('6. All scripts run in the browser (CDP evaluate) — use DOM APIs only');
2425
2421
  lines.push('7. **Cross-Platform Compatibility**: If you use ARIA labels that contain keyboard shortcuts (e.g., `Cascade (⌘L)`), you MUST use substring matches (`aria-label*="Cascade"`) or handle both macOS (`⌘`, `Cmd`) and Windows (`Ctrl`) so the script does not break on other operating systems.');
2422
+ lines.push('8. **CRITICAL: DO NOT explore the filesystem or read other providers.** The reference implementation pattern is already provided below. Do not run `find`, `rg`, or `cat` on upstream providers. Doing so wastes context tokens and will crash the agent session. Focus entirely on modifying the target files.');
2423
+ lines.push('9. Do NOT delete any files. Implement the logic by replacing the empty stubs.');
2426
2424
  lines.push('');
2427
2425
 
2428
2426
  // ── Output contracts ──
@@ -81,15 +81,7 @@ export class CliProviderInstance implements ProviderInstance {
81
81
  }
82
82
 
83
83
  getState(): ProviderState {
84
- const rawStatus = this.adapter.getStatus();
85
- const parsedStatus = this.adapter.getScriptParsedStatus();
86
-
87
- // Prefer rich script parsed status if available
88
- const adapterStatus = parsedStatus ? {
89
- ...rawStatus,
90
- messages: parsedStatus.messages || rawStatus.messages,
91
- activeModal: parsedStatus.activeModal || rawStatus.activeModal,
92
- } : rawStatus;
84
+ const adapterStatus = this.adapter.getStatus();
93
85
 
94
86
  const dirName = this.workingDir.split('/').filter(Boolean).pop() || 'session';
95
87
 
@@ -102,20 +94,6 @@ export class CliProviderInstance implements ProviderInstance {
102
94
  });
103
95
 
104
96
  // generating during partial response add
105
- const partial = this.adapter.getPartialResponse();
106
- const shouldAppendRawPartial = !parsedStatus;
107
- if (shouldAppendRawPartial && adapterStatus.status === 'generating' && partial) {
108
- const cleaned = partial.trim();
109
- if (cleaned && cleaned !== '(generating...)') {
110
- recentMessages.push({
111
- role: 'assistant',
112
- content: (cleaned.length > 8000 ? cleaned.slice(0, 8000) + '...' : cleaned) + '...',
113
- timestamp: Date.now(),
114
- meta: { streaming: true },
115
- });
116
- }
117
- }
118
-
119
97
  // Save history
120
98
  if (recentMessages.length > 0) {
121
99
  const dirName = this.workingDir.split('/').filter(Boolean).pop() || 'session';
@@ -126,6 +104,14 @@ export class CliProviderInstance implements ProviderInstance {
126
104
  this.instanceId,
127
105
  );
128
106
  }
107
+ if (adapterStatus.terminalHistory?.trim()) {
108
+ this.historyWriter.appendTerminalHistory(
109
+ this.type,
110
+ adapterStatus.terminalHistory,
111
+ `${this.provider.name} · ${dirName}`,
112
+ this.instanceId,
113
+ );
114
+ }
129
115
 
130
116
  return {
131
117
  type: this.type,
@@ -139,6 +125,7 @@ export class CliProviderInstance implements ProviderInstance {
139
125
  status: adapterStatus.status,
140
126
  messages: recentMessages,
141
127
  activeModal: adapterStatus.activeModal,
128
+ terminalHistory: adapterStatus.terminalHistory,
142
129
  inputContent: '',
143
130
  },
144
131
  workspace: this.workingDir,
@@ -22,6 +22,7 @@ export interface ActiveChatData {
22
22
  status: string;
23
23
  messages: ChatMessage[];
24
24
  activeModal: { message: string; buttons: string[] } | null;
25
+ terminalHistory?: string;
25
26
  inputContent?: string;
26
27
  }
27
28
 
@@ -200,7 +200,10 @@ export async function detectAllVersions(
200
200
  detectedAt: new Date().toISOString(),
201
201
  };
202
202
 
203
- const versionCommand = (provider as any).versionCommand;
203
+ const verCmdConfig = (provider as any).versionCommand;
204
+ const versionCommand = typeof verCmdConfig === 'object' && verCmdConfig !== null
205
+ ? verCmdConfig[currentOs]
206
+ : verCmdConfig;
204
207
 
205
208
  if (provider.category === 'ide') {
206
209
  // IDE: check app path + CLI