@adhdev/daemon-core 0.9.53 → 0.9.55
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/boot/daemon-lifecycle.d.ts +5 -0
- package/dist/cli-adapters/provider-cli-adapter.d.ts +1 -0
- package/dist/cli-adapters/provider-cli-config.d.ts +1 -0
- package/dist/cli-adapters/provider-cli-shared.d.ts +2 -0
- package/dist/commands/handler.d.ts +7 -0
- package/dist/git/git-commands.d.ts +139 -0
- package/dist/git/git-diff.d.ts +17 -0
- package/dist/git/git-executor.d.ts +34 -0
- package/dist/git/git-monitor.d.ts +57 -0
- package/dist/git/git-snapshot-store.d.ts +50 -0
- package/dist/git/git-status.d.ts +19 -0
- package/dist/git/git-summary.d.ts +10 -0
- package/dist/git/git-types.d.ts +113 -0
- package/dist/git/index.d.ts +16 -0
- package/dist/git/turn-snapshot-tracker.d.ts +16 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1772 -386
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1744 -383
- package/dist/index.mjs.map +1 -1
- package/dist/providers/contracts.d.ts +2 -0
- package/dist/shared-types.d.ts +7 -1
- package/dist/status/builders.d.ts +2 -0
- package/dist/status/snapshot.d.ts +2 -0
- package/node_modules/@adhdev/session-host-core/package.json +1 -1
- package/package.json +1 -1
- package/src/boot/daemon-lifecycle.ts +6 -0
- package/src/cli-adapters/provider-cli-adapter.ts +19 -0
- package/src/cli-adapters/provider-cli-config.d.ts +1 -0
- package/src/cli-adapters/provider-cli-config.ts +2 -0
- package/src/cli-adapters/provider-cli-shared.d.ts +2 -0
- package/src/cli-adapters/provider-cli-shared.ts +2 -0
- package/src/commands/handler.ts +25 -1
- package/src/git/git-commands.ts +582 -0
- package/src/git/git-diff.ts +303 -0
- package/src/git/git-executor.ts +268 -0
- package/src/git/git-monitor.ts +194 -0
- package/src/git/git-snapshot-store.ts +238 -0
- package/src/git/git-status.ts +193 -0
- package/src/git/git-summary.ts +43 -0
- package/src/git/git-types.ts +154 -0
- package/src/git/index.ts +75 -0
- package/src/git/turn-snapshot-tracker.ts +31 -0
- package/src/index.ts +4 -0
- package/src/providers/contracts.d.ts +8 -0
- package/src/providers/contracts.ts +2 -0
- package/src/providers/provider-schema.ts +1 -0
- package/src/shared-types.ts +33 -1
- package/src/status/builders.ts +26 -4
- package/src/status/snapshot.ts +10 -2
|
@@ -358,6 +358,8 @@ export interface ProviderModule {
|
|
|
358
358
|
sendKey?: string;
|
|
359
359
|
/** How the CLI adapter decides when to submit typed input */
|
|
360
360
|
submitStrategy?: 'wait_for_echo' | 'immediate';
|
|
361
|
+
/** If true, typed input must echo on the PTY screen before the adapter sends Enter. */
|
|
362
|
+
requirePromptEchoBeforeSubmit?: boolean;
|
|
361
363
|
/** Keep this provider out of the upstream auto-updated bundle */
|
|
362
364
|
/** @deprecated Machine-level provider source policy now lives in config.providerSourceMode. Local overrides shadow upstream by root precedence and should not rely on provider-level disableUpstream. */
|
|
363
365
|
disableUpstream?: boolean;
|
package/dist/shared-types.d.ts
CHANGED
|
@@ -13,6 +13,8 @@ export type { ProviderErrorReason } from './providers/provider-instance.js';
|
|
|
13
13
|
import type { ActiveChatData as _ActiveChatData, ProviderErrorReason as _ProviderErrorReason } from './providers/provider-instance.js';
|
|
14
14
|
import type { WorkspaceEntry } from './config/workspaces.js';
|
|
15
15
|
import type { ProviderResumeCapability } from './providers/contracts.js';
|
|
16
|
+
import type { GitCompactSummary, GitWorkspaceUpdate, WorkspaceGitSubscriptionParams } from './git/git-types.js';
|
|
17
|
+
export type { GitCommandName, GitCompactSummary, GitDiffSummary, GitFailureReason, GitFileChange, GitFileChangeStatus, GitRepoIdentity, GitRepoStatus, GitSnapshot, GitSnapshotCompareSummary, GitSnapshotReason, GitWorkspaceUpdate, WorkspaceGitSubscriptionParams, } from './git/git-types.js';
|
|
16
18
|
export interface SessionActiveChatData extends Omit<_ActiveChatData, 'messages'> {
|
|
17
19
|
messages?: _ActiveChatData['messages'];
|
|
18
20
|
}
|
|
@@ -132,7 +134,7 @@ export interface SessionHostDiagnosticsSnapshot {
|
|
|
132
134
|
recentRequests: SessionHostRequestTrace[];
|
|
133
135
|
recentTransitions: SessionHostRuntimeTransition[];
|
|
134
136
|
}
|
|
135
|
-
export type TransportTopic = 'session.chat_tail' | 'session.runtime_output' | 'machine.runtime' | 'session_host.diagnostics' | 'session.modal' | 'daemon.metadata';
|
|
137
|
+
export type TransportTopic = 'session.chat_tail' | 'session.runtime_output' | 'machine.runtime' | 'session_host.diagnostics' | 'session.modal' | 'daemon.metadata' | 'workspace.git';
|
|
136
138
|
export interface SessionChatTailSubscriptionParams extends ReadChatCursor {
|
|
137
139
|
targetSessionId: string;
|
|
138
140
|
historySessionId?: string;
|
|
@@ -213,6 +215,7 @@ export interface TopicUpdateEnvelopeMap {
|
|
|
213
215
|
'session_host.diagnostics': SessionHostDiagnosticsUpdate;
|
|
214
216
|
'session.modal': SessionModalUpdate;
|
|
215
217
|
'daemon.metadata': DaemonMetadataUpdate;
|
|
218
|
+
'workspace.git': GitWorkspaceUpdate;
|
|
216
219
|
}
|
|
217
220
|
export type TopicUpdateEnvelope = TopicUpdateEnvelopeMap[TransportTopic];
|
|
218
221
|
export interface SubscribeRequestMap {
|
|
@@ -222,6 +225,7 @@ export interface SubscribeRequestMap {
|
|
|
222
225
|
'session_host.diagnostics': SessionHostDiagnosticsSubscriptionParams;
|
|
223
226
|
'session.modal': SessionModalSubscriptionParams;
|
|
224
227
|
'daemon.metadata': DaemonMetadataSubscriptionParams;
|
|
228
|
+
'workspace.git': WorkspaceGitSubscriptionParams;
|
|
225
229
|
}
|
|
226
230
|
export type SubscribeRequest = {
|
|
227
231
|
[K in TransportTopic]: {
|
|
@@ -255,6 +259,7 @@ export interface SessionEntry {
|
|
|
255
259
|
status: SessionStatus;
|
|
256
260
|
title: string;
|
|
257
261
|
workspace?: string | null;
|
|
262
|
+
git?: GitCompactSummary;
|
|
258
263
|
runtimeKey?: string;
|
|
259
264
|
runtimeDisplayName?: string;
|
|
260
265
|
runtimeWorkspaceLabel?: string;
|
|
@@ -305,6 +310,7 @@ export interface CompactSessionEntry {
|
|
|
305
310
|
status: SessionStatus;
|
|
306
311
|
title: string;
|
|
307
312
|
workspace: string | null;
|
|
313
|
+
git?: GitCompactSummary;
|
|
308
314
|
cdpConnected?: boolean;
|
|
309
315
|
runtimeKey?: string;
|
|
310
316
|
runtimeDisplayName?: string;
|
|
@@ -8,11 +8,13 @@
|
|
|
8
8
|
* Consolidates ProviderState→ManagedEntry mapping logic.
|
|
9
9
|
*/
|
|
10
10
|
import type { DaemonCdpManager } from '../cdp/manager.js';
|
|
11
|
+
import type { GitCompactSummary } from '../git/git-types.js';
|
|
11
12
|
import type { SessionEntry } from '../shared-types.js';
|
|
12
13
|
import type { ProviderState } from '../providers/provider-instance.js';
|
|
13
14
|
export type SessionEntryProfile = 'full' | 'live' | 'metadata';
|
|
14
15
|
export interface SessionEntryBuildOptions {
|
|
15
16
|
profile?: SessionEntryProfile;
|
|
17
|
+
getGitSummaryForWorkspace?: (workspace: string) => GitCompactSummary | null | undefined;
|
|
16
18
|
}
|
|
17
19
|
/**
|
|
18
20
|
* Find a CDP manager by key. Supports single-window (`cursor`) and full multi-window keys (`cursor_<targetId>`).
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* - daemon-standalone HTTP/WS status responses
|
|
7
7
|
*/
|
|
8
8
|
import type { DaemonCdpManager } from '../cdp/manager.js';
|
|
9
|
+
import type { GitCompactSummary } from '../git/git-types.js';
|
|
9
10
|
import { type SessionEntryProfile } from './builders.js';
|
|
10
11
|
import type { ProviderState } from '../providers/provider-instance.js';
|
|
11
12
|
import type { AvailableProviderInfo, MachineInfo, RecentSessionBucket, StatusReportPayload } from '../shared-types.js';
|
|
@@ -45,6 +46,7 @@ export interface StatusSnapshotOptions {
|
|
|
45
46
|
p2p?: StatusReportPayload['p2p'];
|
|
46
47
|
machineNickname?: string | null;
|
|
47
48
|
profile?: SessionEntryProfile;
|
|
49
|
+
getGitSummaryForWorkspace?: (workspace: string) => GitCompactSummary | null | undefined;
|
|
48
50
|
}
|
|
49
51
|
export type StatusSnapshot = StatusReportPayload;
|
|
50
52
|
export interface RecentReadDebugSnapshot {
|
package/package.json
CHANGED
|
@@ -35,6 +35,7 @@ import {
|
|
|
35
35
|
import { loadConfig } from '../config/config.js';
|
|
36
36
|
import type { PtyTransportFactory } from '../cli-adapters/pty-transport.js';
|
|
37
37
|
import type { IdeProviderInstance } from '../providers/ide-provider-instance.js';
|
|
38
|
+
import { createDefaultGitCommandServices } from '../git/git-commands.js';
|
|
38
39
|
|
|
39
40
|
// ─── Init Config ───
|
|
40
41
|
|
|
@@ -78,6 +79,9 @@ export interface DaemonInitConfig {
|
|
|
78
79
|
statusInstanceId?: string;
|
|
79
80
|
statusVersion?: string;
|
|
80
81
|
statusDaemonMode?: boolean;
|
|
82
|
+
|
|
83
|
+
/** Fired before send_chat is dispatched — used for turn snapshot hooks */
|
|
84
|
+
onBeforeSendChat?: (params: { workspace: string; sessionId: string }) => void;
|
|
81
85
|
}
|
|
82
86
|
|
|
83
87
|
// ─── Result ───
|
|
@@ -256,6 +260,7 @@ export async function initDaemonComponents(config: DaemonInitConfig): Promise<Da
|
|
|
256
260
|
providerLoader,
|
|
257
261
|
instanceManager,
|
|
258
262
|
sessionRegistry,
|
|
263
|
+
gitCommandServices: createDefaultGitCommandServices(),
|
|
259
264
|
onProviderSettingChanged: async (providerType) => {
|
|
260
265
|
await refreshProviderAvailability(providerType);
|
|
261
266
|
config.onStatusChange?.();
|
|
@@ -264,6 +269,7 @@ export async function initDaemonComponents(config: DaemonInitConfig): Promise<Da
|
|
|
264
269
|
await refreshProviderAvailability();
|
|
265
270
|
config.onStatusChange?.();
|
|
266
271
|
},
|
|
272
|
+
onBeforeSendChat: config.onBeforeSendChat,
|
|
267
273
|
});
|
|
268
274
|
|
|
269
275
|
// 8. AgentStreamManager
|
|
@@ -598,6 +598,7 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
598
598
|
private readonly sendDelayMs: number;
|
|
599
599
|
private readonly sendKey: string;
|
|
600
600
|
private readonly submitStrategy: 'wait_for_echo' | 'immediate';
|
|
601
|
+
private readonly requirePromptEchoBeforeSubmit: boolean;
|
|
601
602
|
private static readonly SCRIPT_STATUS_DEBOUNCE_MS = 3000;
|
|
602
603
|
|
|
603
604
|
constructor(
|
|
@@ -620,6 +621,7 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
620
621
|
this.sendDelayMs = resolvedConfig.sendDelayMs;
|
|
621
622
|
this.sendKey = resolvedConfig.sendKey;
|
|
622
623
|
this.submitStrategy = resolvedConfig.submitStrategy;
|
|
624
|
+
this.requirePromptEchoBeforeSubmit = resolvedConfig.requirePromptEchoBeforeSubmit;
|
|
623
625
|
this.providerResolutionMeta = resolvedConfig.providerResolutionMeta;
|
|
624
626
|
|
|
625
627
|
// Scripts are required — loaded by ProviderLoader via compatibility array
|
|
@@ -2392,6 +2394,22 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
2392
2394
|
}
|
|
2393
2395
|
|
|
2394
2396
|
if (elapsed >= state.maxEchoWaitMs) {
|
|
2397
|
+
const diagnostic = {
|
|
2398
|
+
elapsed,
|
|
2399
|
+
maxEchoWaitMs: state.maxEchoWaitMs,
|
|
2400
|
+
submitDelayMs: state.submitDelayMs,
|
|
2401
|
+
promptSnippet: state.normalizedPromptSnippet,
|
|
2402
|
+
requirePromptEchoBeforeSubmit: this.requirePromptEchoBeforeSubmit,
|
|
2403
|
+
screenText: summarizeCliTraceText(screenText, 1000),
|
|
2404
|
+
};
|
|
2405
|
+
this.recordTrace('submit_echo_missing', diagnostic);
|
|
2406
|
+
if (this.requirePromptEchoBeforeSubmit) {
|
|
2407
|
+
const message = `${this.cliName} prompt echo was not observed on the PTY screen before submit`;
|
|
2408
|
+
LOG.warn('CLI', `[${this.cliType}] ${message} elapsed=${elapsed}ms maxEchoWaitMs=${state.maxEchoWaitMs} screen=${JSON.stringify(diagnostic.screenText).slice(0, 240)}`);
|
|
2409
|
+
completion.rejectOnce(new Error(message));
|
|
2410
|
+
return;
|
|
2411
|
+
}
|
|
2412
|
+
LOG.warn('CLI', `[${this.cliType}] prompt echo was not observed before submit; sending submit key anyway elapsed=${elapsed}ms maxEchoWaitMs=${state.maxEchoWaitMs}`);
|
|
2395
2413
|
this.submitSendKey(state, completion);
|
|
2396
2414
|
return;
|
|
2397
2415
|
}
|
|
@@ -2880,6 +2898,7 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
2880
2898
|
sendDelayMs: this.sendDelayMs,
|
|
2881
2899
|
sendKey: this.sendKey,
|
|
2882
2900
|
submitStrategy: this.submitStrategy,
|
|
2901
|
+
requirePromptEchoBeforeSubmit: this.requirePromptEchoBeforeSubmit,
|
|
2883
2902
|
submitPendingUntil: this.submitPendingUntil,
|
|
2884
2903
|
responseSettleIgnoreUntil: this.responseSettleIgnoreUntil,
|
|
2885
2904
|
resizeSuppressUntil: this.resizeSuppressUntil,
|
|
@@ -25,6 +25,7 @@ export interface ResolvedCliAdapterConfig {
|
|
|
25
25
|
sendDelayMs: number;
|
|
26
26
|
sendKey: string;
|
|
27
27
|
submitStrategy: 'wait_for_echo' | 'immediate';
|
|
28
|
+
requirePromptEchoBeforeSubmit: boolean;
|
|
28
29
|
providerResolutionMeta: ProviderResolutionMeta;
|
|
29
30
|
}
|
|
30
31
|
export declare function resolveCliAdapterConfig(provider: CliProviderModule): ResolvedCliAdapterConfig;
|
|
@@ -29,6 +29,7 @@ export interface ResolvedCliAdapterConfig {
|
|
|
29
29
|
sendDelayMs: number;
|
|
30
30
|
sendKey: string;
|
|
31
31
|
submitStrategy: 'wait_for_echo' | 'immediate';
|
|
32
|
+
requirePromptEchoBeforeSubmit: boolean;
|
|
32
33
|
providerResolutionMeta: ProviderResolutionMeta;
|
|
33
34
|
}
|
|
34
35
|
|
|
@@ -55,6 +56,7 @@ export function resolveCliAdapterConfig(provider: CliProviderModule): ResolvedCl
|
|
|
55
56
|
? provider.sendKey
|
|
56
57
|
: '\r',
|
|
57
58
|
submitStrategy: provider.submitStrategy === 'immediate' ? 'immediate' : 'wait_for_echo',
|
|
59
|
+
requirePromptEchoBeforeSubmit: provider.requirePromptEchoBeforeSubmit === true,
|
|
58
60
|
providerResolutionMeta: {
|
|
59
61
|
type: provider.type,
|
|
60
62
|
name: provider.name,
|
|
@@ -104,6 +104,8 @@ export interface CliProviderModule {
|
|
|
104
104
|
sendDelayMs?: number;
|
|
105
105
|
sendKey?: string;
|
|
106
106
|
submitStrategy?: 'wait_for_echo' | 'immediate';
|
|
107
|
+
/** Require the typed prompt to be visible on the PTY screen before sending Enter. */
|
|
108
|
+
requirePromptEchoBeforeSubmit?: boolean;
|
|
107
109
|
/** Allow sending another prompt while the CLI is still generating so users can intervene mid-turn. */
|
|
108
110
|
allowInputDuringGeneration?: boolean;
|
|
109
111
|
scripts?: CliScripts;
|
|
@@ -122,6 +122,8 @@ export interface CliProviderModule {
|
|
|
122
122
|
sendDelayMs?: number;
|
|
123
123
|
sendKey?: string;
|
|
124
124
|
submitStrategy?: 'wait_for_echo' | 'immediate';
|
|
125
|
+
/** Require the typed prompt to be visible on the PTY screen before sending Enter. */
|
|
126
|
+
requirePromptEchoBeforeSubmit?: boolean;
|
|
125
127
|
/** Allow sending another prompt while the CLI is still generating so users can intervene mid-turn. */
|
|
126
128
|
allowInputDuringGeneration?: boolean;
|
|
127
129
|
/** When provider-owned, daemon treats provider parser output as canonical transcript authority. */
|
package/src/commands/handler.ts
CHANGED
|
@@ -32,6 +32,7 @@ import * as Cdp from './cdp-commands.js';
|
|
|
32
32
|
import * as Stream from './stream-commands.js';
|
|
33
33
|
import * as WorkspaceCmd from './workspace-commands.js';
|
|
34
34
|
import { getWorkspaceState } from '../config/workspaces.js';
|
|
35
|
+
import { handleGitCommand, isGitCommandName, type GitCommandServices } from '../git/git-commands.js';
|
|
35
36
|
|
|
36
37
|
export interface CommandResult {
|
|
37
38
|
success: boolean;
|
|
@@ -48,6 +49,9 @@ export interface CommandContext {
|
|
|
48
49
|
sessionRegistry?: SessionRegistry;
|
|
49
50
|
onProviderSettingChanged?: (providerType: string, key: string, value: any) => Promise<void> | void;
|
|
50
51
|
onProviderSourceConfigChanged?: () => Promise<void> | void;
|
|
52
|
+
gitCommandServices?: GitCommandServices;
|
|
53
|
+
/** Fired synchronously before send_chat is dispatched; fire-and-forget for callers */
|
|
54
|
+
onBeforeSendChat?: (params: { workspace: string; sessionId: string }) => void;
|
|
51
55
|
}
|
|
52
56
|
|
|
53
57
|
/**
|
|
@@ -377,6 +381,13 @@ export class DaemonCommandHandler implements CommandHelpers {
|
|
|
377
381
|
this._currentRoute = this.resolveRoute(args);
|
|
378
382
|
const startedAt = Date.now();
|
|
379
383
|
this.logCommandStart(cmd, args);
|
|
384
|
+
let result: CommandResult;
|
|
385
|
+
|
|
386
|
+
if (isGitCommandName(cmd)) {
|
|
387
|
+
result = await handleGitCommand(cmd, args, this._ctx.gitCommandServices);
|
|
388
|
+
this.logCommandEnd(cmd, result, startedAt);
|
|
389
|
+
return result;
|
|
390
|
+
}
|
|
380
391
|
|
|
381
392
|
const sessionScopedCommands = new Set([
|
|
382
393
|
'read_chat',
|
|
@@ -406,7 +417,6 @@ export class DaemonCommandHandler implements CommandHelpers {
|
|
|
406
417
|
}
|
|
407
418
|
|
|
408
419
|
// Commands without ideType CDP silently fail (prevent P2P retry spam)
|
|
409
|
-
let result: CommandResult;
|
|
410
420
|
if (!this._currentRoute.session && !this._currentRoute.managerKey && !this._currentRoute.providerType) {
|
|
411
421
|
const cdpCommands = ['send_chat', 'read_chat', 'list_chats', 'new_chat', 'switch_chat', 'set_mode', 'change_model', 'set_thought_level', 'resolve_action'];
|
|
412
422
|
if (cdpCommands.includes(cmd)) {
|
|
@@ -416,6 +426,20 @@ export class DaemonCommandHandler implements CommandHelpers {
|
|
|
416
426
|
}
|
|
417
427
|
}
|
|
418
428
|
|
|
429
|
+
if (cmd === 'send_chat' && this._ctx.onBeforeSendChat) {
|
|
430
|
+
const sessionId = this._currentRoute.session?.sessionId;
|
|
431
|
+
const workspace = sessionId
|
|
432
|
+
? (this._ctx.instanceManager?.getInstance(sessionId) as any)?.getState?.()?.workspace
|
|
433
|
+
: undefined;
|
|
434
|
+
if (workspace && sessionId) {
|
|
435
|
+
try {
|
|
436
|
+
this._ctx.onBeforeSendChat({ workspace, sessionId });
|
|
437
|
+
} catch {
|
|
438
|
+
// hook must not block send_chat
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
419
443
|
try {
|
|
420
444
|
result = await this.dispatch(cmd, args);
|
|
421
445
|
this.logCommandEnd(cmd, result, startedAt);
|