@adhdev/daemon-core 0.9.76-rc.9 → 0.9.76
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/cli-adapters/provider-cli-adapter.d.ts +5 -2
- package/dist/cli-adapters/provider-cli-runtime.d.ts +1 -0
- package/dist/cli-adapters/provider-cli-shared.d.ts +24 -0
- package/dist/commands/chat-commands.d.ts +2 -0
- package/dist/commands/cli-manager.d.ts +17 -4
- package/dist/commands/mesh-coordinator.d.ts +2 -0
- package/dist/commands/router.d.ts +11 -0
- package/dist/config/mesh-config.d.ts +3 -0
- package/dist/git/git-types.d.ts +1 -1
- package/dist/git/git-worktree.d.ts +64 -0
- package/dist/git/index.d.ts +2 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2427 -561
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2432 -584
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/coordinator-prompt.d.ts +1 -0
- package/dist/mesh/mesh-events.d.ts +18 -0
- package/dist/providers/chat-message-normalization.d.ts +40 -0
- package/dist/providers/cli-provider-instance.d.ts +7 -1
- package/dist/providers/contracts.d.ts +20 -1
- package/dist/providers/io-contracts.d.ts +17 -1
- package/dist/providers/provider-input-support.d.ts +18 -2
- package/dist/providers/provider-instance-manager.d.ts +1 -0
- package/dist/providers/provider-instance.d.ts +4 -0
- package/dist/repo-mesh-types.d.ts +34 -0
- package/dist/session-host/runtime-support.d.ts +2 -1
- package/dist/shared-types.d.ts +8 -0
- package/dist/types.d.ts +9 -0
- package/package.json +4 -5
- package/src/chat/subscription-updates.ts +3 -1
- package/src/cli-adapters/provider-cli-adapter.ts +44 -11
- package/src/cli-adapters/provider-cli-runtime.ts +3 -2
- package/src/cli-adapters/provider-cli-shared.ts +201 -15
- package/src/commands/chat-commands.ts +166 -16
- package/src/commands/cli-manager.ts +78 -5
- package/src/commands/handler.ts +13 -4
- package/src/commands/mesh-coordinator.ts +155 -5
- package/src/commands/router.d.ts +1 -0
- package/src/commands/router.ts +606 -32
- package/src/config/mesh-config.ts +27 -2
- package/src/git/git-commands.ts +5 -1
- package/src/git/git-types.ts +1 -0
- package/src/git/git-worktree.ts +214 -0
- package/src/git/index.ts +14 -0
- package/src/index.ts +20 -1
- package/src/mesh/coordinator-prompt.ts +36 -14
- package/src/mesh/mesh-events.ts +173 -42
- package/src/providers/acp-provider-instance.ts +118 -30
- package/src/providers/chat-message-normalization.ts +241 -0
- package/src/providers/cli-provider-instance.d.ts +2 -0
- package/src/providers/cli-provider-instance.ts +219 -13
- package/src/providers/contracts.ts +25 -1
- package/src/providers/io-contracts.ts +63 -5
- package/src/providers/provider-input-support.ts +125 -1
- package/src/providers/provider-instance-manager.ts +20 -1
- package/src/providers/provider-instance.ts +4 -0
- package/src/providers/provider-schema.ts +38 -8
- package/src/providers/read-chat-contract.ts +8 -0
- package/src/repo-mesh-types.ts +38 -0
- package/src/session-host/runtime-support.ts +55 -7
- package/src/shared-types.ts +8 -0
- package/src/status/builders.ts +5 -3
- package/src/status/reporter.ts +6 -0
- package/src/types.ts +9 -0
|
@@ -1,2 +1,20 @@
|
|
|
1
1
|
import type { DaemonComponents } from '../boot/daemon-lifecycle.js';
|
|
2
|
+
export interface PendingMeshCoordinatorEvent {
|
|
3
|
+
event: string;
|
|
4
|
+
meshId: string;
|
|
5
|
+
nodeLabel: string;
|
|
6
|
+
metadataEvent: Record<string, unknown>;
|
|
7
|
+
queuedAt: number;
|
|
8
|
+
}
|
|
9
|
+
/** Drain and return all pending coordinator events, clearing the queue. */
|
|
10
|
+
export declare function drainPendingMeshCoordinatorEvents(): PendingMeshCoordinatorEvent[];
|
|
11
|
+
export declare function handleMeshForwardEvent(components: DaemonComponents, payload: Record<string, unknown>): {
|
|
12
|
+
success: boolean;
|
|
13
|
+
forwarded: number;
|
|
14
|
+
error?: undefined;
|
|
15
|
+
} | {
|
|
16
|
+
success: boolean;
|
|
17
|
+
error: string;
|
|
18
|
+
forwarded?: undefined;
|
|
19
|
+
};
|
|
2
20
|
export declare function setupMeshEventForwarding(components: DaemonComponents): void;
|
|
@@ -2,6 +2,31 @@ import type { ChatMessage } from '../types.js';
|
|
|
2
2
|
export declare const BUILTIN_CHAT_MESSAGE_KINDS: readonly ["standard", "thought", "tool", "terminal", "system"];
|
|
3
3
|
export type BuiltinChatMessageKind = typeof BUILTIN_CHAT_MESSAGE_KINDS[number];
|
|
4
4
|
export type ChatMessageKind = BuiltinChatMessageKind | (string & {});
|
|
5
|
+
export declare const CHAT_MESSAGE_VISIBILITIES: readonly ["user", "debug", "internal", "hidden"];
|
|
6
|
+
export declare const CHAT_MESSAGE_TRANSCRIPT_VISIBILITIES: readonly ["visible", "chat", "user", "debug", "internal", "hidden"];
|
|
7
|
+
export declare const CHAT_MESSAGE_AUDIENCES: readonly ["chat", "debug", "trace", "internal"];
|
|
8
|
+
export declare const CHAT_MESSAGE_SOURCES: readonly ["assistant_text", "tool_call", "terminal_command", "runtime_activity", "runtime_status", "provider_chrome", "control"];
|
|
9
|
+
export declare const CHAT_MESSAGE_ACTIVITY_SOURCES: readonly ["tool_call", "terminal_command", "runtime_activity"];
|
|
10
|
+
export declare const CHAT_MESSAGE_INTERNAL_SOURCES: readonly ["runtime_status", "provider_chrome", "control"];
|
|
11
|
+
export type ChatMessageVisibility = typeof CHAT_MESSAGE_VISIBILITIES[number] | (string & {});
|
|
12
|
+
export type ChatMessageTranscriptVisibility = typeof CHAT_MESSAGE_TRANSCRIPT_VISIBILITIES[number] | (string & {});
|
|
13
|
+
export type ChatMessageAudience = typeof CHAT_MESSAGE_AUDIENCES[number] | (string & {});
|
|
14
|
+
export type ChatMessageSource = typeof CHAT_MESSAGE_SOURCES[number] | (string & {});
|
|
15
|
+
export type ChatMessageTranscriptSurface = 'chat' | 'activity' | 'internal';
|
|
16
|
+
export interface ChatMessageVisibilityClassification {
|
|
17
|
+
surface: ChatMessageTranscriptSurface;
|
|
18
|
+
isUserFacing: boolean;
|
|
19
|
+
isActivityFacing: boolean;
|
|
20
|
+
isInternal: boolean;
|
|
21
|
+
explicitUserFacing: boolean;
|
|
22
|
+
explicitHidden: boolean;
|
|
23
|
+
role: string;
|
|
24
|
+
kind: ChatMessageKind;
|
|
25
|
+
visibility: string;
|
|
26
|
+
transcriptVisibility: string;
|
|
27
|
+
audience: string;
|
|
28
|
+
source: string;
|
|
29
|
+
}
|
|
5
30
|
export declare function isBuiltinChatMessageKind(kind: unknown): kind is BuiltinChatMessageKind;
|
|
6
31
|
export declare function normalizeChatMessageKind(kind: unknown, role: unknown): ChatMessageKind;
|
|
7
32
|
export declare function resolveChatMessageKind<T extends ChatMessage>(message: T): ChatMessageKind;
|
|
@@ -63,3 +88,18 @@ export declare function buildUserChatMessage<T extends Omit<ChatMessage, 'role'
|
|
|
63
88
|
});
|
|
64
89
|
export declare function normalizeChatMessage<T extends ChatMessage>(message: T): T;
|
|
65
90
|
export declare function normalizeChatMessages<T extends ChatMessage>(messages: T[] | null | undefined): T[];
|
|
91
|
+
/**
|
|
92
|
+
* Shared transcript visibility protocol for all ADHDev provider chat messages.
|
|
93
|
+
*
|
|
94
|
+
* Producers can stamp visibility/audience/source/userFacing/internal/debug either
|
|
95
|
+
* at the top level or under `meta`. Consumers should use this classifier instead
|
|
96
|
+
* of matching command text, icons, provider names, or terminal UI fragments.
|
|
97
|
+
*/
|
|
98
|
+
export declare function classifyChatMessageVisibility(message: ChatMessage | null | undefined): ChatMessageVisibilityClassification;
|
|
99
|
+
export declare function isUserFacingChatMessage(message: ChatMessage | null | undefined): boolean;
|
|
100
|
+
export declare function isActivityChatMessage(message: ChatMessage | null | undefined): boolean;
|
|
101
|
+
export declare function isInternalChatMessage(message: ChatMessage | null | undefined): boolean;
|
|
102
|
+
export declare function filterUserFacingChatMessages<T extends ChatMessage>(messages: T[] | null | undefined): T[];
|
|
103
|
+
export declare function filterActivityChatMessages<T extends ChatMessage>(messages: T[] | null | undefined): T[];
|
|
104
|
+
export declare function filterInternalChatMessages<T extends ChatMessage>(messages: T[] | null | undefined): T[];
|
|
105
|
+
export declare function filterChatMessagesByVisibility<T extends ChatMessage>(messages: T[] | null | undefined, surface: ChatMessageTranscriptSurface): T[];
|
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
* Lifecycle layer on top of ProviderCliAdapter.
|
|
5
5
|
* collectCliData() + status transition logic from daemon-status.ts moved here.
|
|
6
6
|
*/
|
|
7
|
-
import { type ProviderModule } from './contracts.js';
|
|
7
|
+
import { type ProviderModule, type InputEnvelope } from './contracts.js';
|
|
8
8
|
import type { ProviderInstance, ProviderState, InstanceContext, HotChatSessionState, SessionModalState } from './provider-instance.js';
|
|
9
9
|
import { ProviderCliAdapter } from '../cli-adapters/provider-cli-adapter.js';
|
|
10
10
|
import type { PtyTransportFactory } from '../cli-adapters/pty-transport.js';
|
|
11
|
+
import type { ChatMessage } from '../types.js';
|
|
11
12
|
type PersistableCliHistoryMessage = {
|
|
12
13
|
role: string;
|
|
13
14
|
content: string;
|
|
@@ -15,6 +16,9 @@ type PersistableCliHistoryMessage = {
|
|
|
15
16
|
senderName?: string;
|
|
16
17
|
receivedAt?: number;
|
|
17
18
|
};
|
|
19
|
+
export declare function buildCliStructuredInputPrompt(input: InputEnvelope, options?: {
|
|
20
|
+
materializeDir?: string;
|
|
21
|
+
}): string;
|
|
18
22
|
export declare function buildIncrementalHistoryAppendMessages(previousMessages: PersistableCliHistoryMessage[], currentMessages: PersistableCliHistoryMessage[]): PersistableCliHistoryMessage[];
|
|
19
23
|
export declare function getForcedNewSessionScriptName(provider: ProviderModule | undefined, launchMode: 'new' | 'resume' | 'manual'): string | null;
|
|
20
24
|
export declare function waitForCliAdapterReady(adapter: {
|
|
@@ -67,6 +71,7 @@ export declare class CliProviderInstance implements ProviderInstance {
|
|
|
67
71
|
constructor(provider: ProviderModule, workingDir: string, cliArgs?: string[], instanceId?: string, transportFactory?: PtyTransportFactory, options?: {
|
|
68
72
|
providerSessionId?: string;
|
|
69
73
|
launchMode?: 'new' | 'resume' | 'manual';
|
|
74
|
+
extraEnv?: Record<string, string>;
|
|
70
75
|
onProviderSessionResolved?: (info: {
|
|
71
76
|
instanceId: string;
|
|
72
77
|
providerType: string;
|
|
@@ -112,6 +117,7 @@ export declare class CliProviderInstance implements ProviderInstance {
|
|
|
112
117
|
private maybeAppendRuntimeRecoveryMessage;
|
|
113
118
|
private appendRuntimeSystemMessage;
|
|
114
119
|
private appendRuntimeMessage;
|
|
120
|
+
mergeRuntimeChatMessages(parsedMessages: ChatMessage[]): ChatMessage[];
|
|
115
121
|
private mergeConversationMessages;
|
|
116
122
|
private formatApprovalRequestMessage;
|
|
117
123
|
private promoteProviderSessionId;
|
|
@@ -87,7 +87,7 @@ export interface ProviderEffect {
|
|
|
87
87
|
* ContentBlock — ACP ContentBlock union type
|
|
88
88
|
* Represents displayable content in messages, tool call results, etc.
|
|
89
89
|
*/
|
|
90
|
-
export type ContentBlock = TextBlock | ImageBlock | AudioBlock | ResourceLinkBlock | ResourceBlock;
|
|
90
|
+
export type ContentBlock = TextBlock | ImageBlock | AudioBlock | VideoBlock | ResourceLinkBlock | ResourceBlock;
|
|
91
91
|
/** Text content — ACP TextContent */
|
|
92
92
|
export interface TextBlock {
|
|
93
93
|
type: 'text';
|
|
@@ -100,6 +100,7 @@ export interface ImageBlock {
|
|
|
100
100
|
data: string;
|
|
101
101
|
mimeType: string;
|
|
102
102
|
uri?: string;
|
|
103
|
+
alt?: string;
|
|
103
104
|
annotations?: ContentAnnotations;
|
|
104
105
|
}
|
|
105
106
|
/** Audio content — ACP AudioContent */
|
|
@@ -107,6 +108,18 @@ export interface AudioBlock {
|
|
|
107
108
|
type: 'audio';
|
|
108
109
|
data: string;
|
|
109
110
|
mimeType: string;
|
|
111
|
+
uri?: string;
|
|
112
|
+
transcript?: string;
|
|
113
|
+
annotations?: ContentAnnotations;
|
|
114
|
+
}
|
|
115
|
+
/** Video content — ADHDev canonical display block. ACP prompt input degrades video to resource_link/text. */
|
|
116
|
+
export interface VideoBlock {
|
|
117
|
+
type: 'video';
|
|
118
|
+
data?: string;
|
|
119
|
+
mimeType: string;
|
|
120
|
+
uri?: string;
|
|
121
|
+
transcript?: string;
|
|
122
|
+
posterUri?: string;
|
|
110
123
|
annotations?: ContentAnnotations;
|
|
111
124
|
}
|
|
112
125
|
/** Resource link (file reference) — ACP ResourceLink */
|
|
@@ -487,6 +500,12 @@ export interface ProviderModule {
|
|
|
487
500
|
input?: {
|
|
488
501
|
multipart?: boolean;
|
|
489
502
|
mediaTypes?: Array<'text' | 'image' | 'audio' | 'video' | 'resource'>;
|
|
503
|
+
strategies?: Array<{
|
|
504
|
+
mediaType: 'text' | 'image' | 'audio' | 'video' | 'resource';
|
|
505
|
+
strategies?: Array<'native' | 'native_acp' | 'resource_link' | 'text_fallback' | 'paste' | 'upload'>;
|
|
506
|
+
native?: boolean;
|
|
507
|
+
degradation?: Array<'native' | 'native_acp' | 'resource_link' | 'text_fallback' | 'paste' | 'upload'>;
|
|
508
|
+
}>;
|
|
490
509
|
};
|
|
491
510
|
output?: {
|
|
492
511
|
richContent?: boolean;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ContentAnnotations } from './contracts.js';
|
|
2
|
-
export type InputPart = TextInputPart | ImageInputPart | AudioInputPart | VideoInputPart | ResourceInputPart;
|
|
2
|
+
export type InputPart = TextInputPart | ImageInputPart | AudioInputPart | VideoInputPart | ResourceLinkInputPart | ResourceInputPart;
|
|
3
3
|
export interface TextInputPart {
|
|
4
4
|
type: 'text';
|
|
5
5
|
text: string;
|
|
@@ -23,6 +23,7 @@ export interface VideoInputPart {
|
|
|
23
23
|
mimeType: string;
|
|
24
24
|
uri?: string;
|
|
25
25
|
data?: string;
|
|
26
|
+
transcript?: string;
|
|
26
27
|
posterUri?: string;
|
|
27
28
|
}
|
|
28
29
|
export interface ResourceInputPart {
|
|
@@ -33,6 +34,16 @@ export interface ResourceInputPart {
|
|
|
33
34
|
text?: string;
|
|
34
35
|
data?: string;
|
|
35
36
|
}
|
|
37
|
+
export interface ResourceLinkInputPart {
|
|
38
|
+
type: 'resource_link';
|
|
39
|
+
uri: string;
|
|
40
|
+
name: string;
|
|
41
|
+
title?: string;
|
|
42
|
+
description?: string;
|
|
43
|
+
mimeType?: string;
|
|
44
|
+
size?: number;
|
|
45
|
+
annotations?: ContentAnnotations;
|
|
46
|
+
}
|
|
36
47
|
export interface InputEnvelope {
|
|
37
48
|
parts: InputPart[];
|
|
38
49
|
textFallback: string;
|
|
@@ -52,6 +63,7 @@ export interface ImageMessagePart {
|
|
|
52
63
|
mimeType: string;
|
|
53
64
|
uri?: string;
|
|
54
65
|
data?: string;
|
|
66
|
+
alt?: string;
|
|
55
67
|
annotations?: ContentAnnotations;
|
|
56
68
|
}
|
|
57
69
|
export interface AudioMessagePart {
|
|
@@ -67,6 +79,7 @@ export interface VideoMessagePart {
|
|
|
67
79
|
mimeType: string;
|
|
68
80
|
uri?: string;
|
|
69
81
|
data?: string;
|
|
82
|
+
transcript?: string;
|
|
70
83
|
posterUri?: string;
|
|
71
84
|
annotations?: ContentAnnotations;
|
|
72
85
|
}
|
|
@@ -74,8 +87,11 @@ export interface ResourceLinkMessagePart {
|
|
|
74
87
|
type: 'resource_link';
|
|
75
88
|
uri: string;
|
|
76
89
|
name: string;
|
|
90
|
+
title?: string;
|
|
91
|
+
description?: string;
|
|
77
92
|
mimeType?: string;
|
|
78
93
|
size?: number;
|
|
94
|
+
annotations?: ContentAnnotations;
|
|
79
95
|
}
|
|
80
96
|
export interface ResourceMessagePart {
|
|
81
97
|
type: 'resource';
|
|
@@ -1,9 +1,25 @@
|
|
|
1
1
|
import type { InputEnvelope, ProviderModule } from './contracts.js';
|
|
2
|
-
type InputMediaType = 'text' | 'image' | 'audio' | 'video' | 'resource';
|
|
2
|
+
export type InputMediaType = 'text' | 'image' | 'audio' | 'video' | 'resource';
|
|
3
|
+
export type InputAttachmentStrategy = 'native' | 'native_acp' | 'resource_link' | 'text_fallback' | 'paste' | 'upload';
|
|
4
|
+
export interface InputMediaStrategyDescriptor {
|
|
5
|
+
mediaType: InputMediaType;
|
|
6
|
+
strategies: InputAttachmentStrategy[];
|
|
7
|
+
native?: boolean;
|
|
8
|
+
degradation?: InputAttachmentStrategy[];
|
|
9
|
+
}
|
|
10
|
+
export interface MessageInputSupport {
|
|
11
|
+
text: boolean;
|
|
12
|
+
multipart: boolean;
|
|
13
|
+
mediaTypes: InputMediaType[];
|
|
14
|
+
strategies: InputMediaStrategyDescriptor[];
|
|
15
|
+
}
|
|
16
|
+
export declare const TEXT_ONLY_MESSAGE_INPUT_SUPPORT: MessageInputSupport;
|
|
3
17
|
export declare function assertTextOnlyInput(provider: Pick<ProviderModule, 'name' | 'type'> | null | undefined, input: InputEnvelope): void;
|
|
4
18
|
export declare function getDeclaredProviderInputSupport(provider?: Pick<ProviderModule, 'capabilities'> | null): {
|
|
5
19
|
multipart: boolean;
|
|
6
20
|
mediaTypes: Set<InputMediaType>;
|
|
21
|
+
strategies: InputMediaStrategyDescriptor[];
|
|
7
22
|
};
|
|
23
|
+
export declare function normalizeInputStrategyDescriptors(raw: unknown): InputMediaStrategyDescriptor[];
|
|
24
|
+
export declare function getEffectiveMessageInputSupport(provider?: Pick<ProviderModule, 'category' | 'capabilities'> | null, runtimeCapabilities?: Record<string, any> | null): MessageInputSupport;
|
|
8
25
|
export declare function assertProviderSupportsDeclaredInput(provider: Pick<ProviderModule, 'name' | 'type' | 'capabilities'> | null | undefined, input: InputEnvelope): void;
|
|
9
|
-
export {};
|
|
@@ -67,6 +67,7 @@ export declare class ProviderInstanceManager {
|
|
|
67
67
|
onEvent(listener: (event: ProviderEvent & {
|
|
68
68
|
providerType: string;
|
|
69
69
|
}) => void): void;
|
|
70
|
+
emitProviderEvent(providerType: string, instanceId: string, event: ProviderEvent): void;
|
|
70
71
|
private emitPendingEvents;
|
|
71
72
|
/**
|
|
72
73
|
* Forward event to specific Instance
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import type { ProviderModule, ProviderResumeCapability } from './contracts.js';
|
|
11
11
|
import type { AcpConfigOption, AcpMode, ProviderControlSchema, ProviderSummaryMetadata, SessionCapability } from '../shared-types.js';
|
|
12
|
+
import type { MessageInputSupport } from './provider-input-support.js';
|
|
12
13
|
import type { ChatMessage } from '../types.js';
|
|
13
14
|
export type ProviderStatus = 'idle' | 'generating' | 'waiting_approval' | 'error' | 'stopped' | 'starting';
|
|
14
15
|
export interface ProviderRuntimeWriteOwner {
|
|
@@ -71,6 +72,7 @@ interface ProviderStateBase {
|
|
|
71
72
|
runtime?: ProviderRuntimeInfo;
|
|
72
73
|
resume?: ProviderResumeCapability;
|
|
73
74
|
sessionCapabilities?: SessionCapability[];
|
|
75
|
+
messageInput?: MessageInputSupport;
|
|
74
76
|
/** Dynamic control current values */
|
|
75
77
|
controlValues?: Record<string, string | number | boolean>;
|
|
76
78
|
/** Provider-declared controls schema (from provider.controls) */
|
|
@@ -147,6 +149,8 @@ export interface InstanceContext {
|
|
|
147
149
|
onPtyData?: (data: string) => void;
|
|
148
150
|
/** Provider configvalue (resolved) */
|
|
149
151
|
settings: Record<string, any>;
|
|
152
|
+
/** Immediate provider-originated status/event emission. Used to avoid waiting for status polling. */
|
|
153
|
+
emitProviderEvent?: (event: ProviderEvent) => void;
|
|
150
154
|
}
|
|
151
155
|
export interface ProviderInstance {
|
|
152
156
|
/** Provider type */
|
|
@@ -40,6 +40,8 @@ export interface RepoMeshNode {
|
|
|
40
40
|
status: 'enabled' | 'disabled' | 'removed';
|
|
41
41
|
}
|
|
42
42
|
export type RepoMeshNodeHealth = 'online' | 'offline' | 'degraded' | 'dirty' | 'wrong_branch' | 'unknown';
|
|
43
|
+
export type RepoMeshSessionCleanupMode = 'preserve' | 'stop' | 'delete_stopped' | 'stop_and_delete';
|
|
44
|
+
export type RepoMeshSpawnedSessionVisibility = 'visible' | 'hidden';
|
|
43
45
|
export interface RepoMeshPolicy {
|
|
44
46
|
requirePreTaskCheckpoint: boolean;
|
|
45
47
|
requirePostTaskCheckpoint: boolean;
|
|
@@ -48,11 +50,37 @@ export interface RepoMeshPolicy {
|
|
|
48
50
|
dirtyWorkspaceBehavior: 'block' | 'warn' | 'checkpoint_then_continue';
|
|
49
51
|
maxParallelTasks: number;
|
|
50
52
|
allowedProviders?: string[];
|
|
53
|
+
/**
|
|
54
|
+
* Whether sessions spawned by mesh/coordinator policy should auto-open as visible
|
|
55
|
+
* dashboard tabs or start hidden. Defaults to 'visible' to preserve existing
|
|
56
|
+
* watch-the-agents behavior; hidden sessions remain discoverable and manually openable.
|
|
57
|
+
*/
|
|
58
|
+
spawnedSessionVisibility?: RepoMeshSpawnedSessionVisibility;
|
|
59
|
+
/**
|
|
60
|
+
* What to do with delegated session-host records for a node when it is removed.
|
|
61
|
+
* Defaults to 'preserve' so completed work can be reviewed later and live
|
|
62
|
+
* runtimes are never stopped/deleted unless the mesh owner opts in.
|
|
63
|
+
*/
|
|
64
|
+
sessionCleanupOnNodeRemove?: RepoMeshSessionCleanupMode;
|
|
65
|
+
}
|
|
66
|
+
export interface RepoMeshRelatedRepo {
|
|
67
|
+
/** Stable display label for an explicitly configured associated checkout. */
|
|
68
|
+
label: string;
|
|
69
|
+
/** Absolute checkout/workspace path for git freshness probes. */
|
|
70
|
+
workspace: string;
|
|
51
71
|
}
|
|
52
72
|
export interface RepoMeshNodePolicy {
|
|
53
73
|
readOnly?: boolean;
|
|
54
74
|
canPush?: boolean;
|
|
55
75
|
maxConcurrentSessions?: number;
|
|
76
|
+
/** Ordered provider preference used when mesh_launch_session omits an explicit type. */
|
|
77
|
+
providerPriority?: string[];
|
|
78
|
+
/**
|
|
79
|
+
* Optional associated/external repos that must be checked alongside this node.
|
|
80
|
+
* These are explicit policy/config entries only; Repo Mesh does not auto-discover
|
|
81
|
+
* sibling paths so freshness checks stay fail-closed and non-surprising.
|
|
82
|
+
*/
|
|
83
|
+
relatedRepos?: RepoMeshRelatedRepo[];
|
|
56
84
|
}
|
|
57
85
|
export declare const DEFAULT_MESH_POLICY: RepoMeshPolicy;
|
|
58
86
|
export interface RepoMeshNodeCapabilities {
|
|
@@ -149,6 +177,12 @@ export interface LocalMeshNodeEntry {
|
|
|
149
177
|
policy: RepoMeshNodePolicy;
|
|
150
178
|
/** For single-machine mesh: same daemon, different worktree */
|
|
151
179
|
isLocalWorktree?: boolean;
|
|
180
|
+
/** Branch this worktree tracks (set when created via clone_mesh_node) */
|
|
181
|
+
worktreeBranch?: string;
|
|
182
|
+
/** Node ID this worktree was cloned from */
|
|
183
|
+
clonedFromNodeId?: string;
|
|
184
|
+
/** Optional associated/external repos configured as node metadata. */
|
|
185
|
+
relatedRepos?: RepoMeshRelatedRepo[];
|
|
152
186
|
}
|
|
153
187
|
export interface RepoMeshStatus {
|
|
154
188
|
meshId: string;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { type SessionHostEndpoint } from '@adhdev/session-host-core';
|
|
1
|
+
import { type SessionHostEndpoint, type SessionHostRequestType } from '@adhdev/session-host-core';
|
|
2
2
|
import type { HostedCliRuntimeDescriptor } from '../commands/cli-manager.js';
|
|
3
3
|
export declare function ensureSessionHostReady(options: {
|
|
4
4
|
appName?: string;
|
|
5
5
|
spawnHost: () => void;
|
|
6
6
|
timeoutMs?: number;
|
|
7
|
+
requiredRequestTypes?: readonly SessionHostRequestType[];
|
|
7
8
|
}): Promise<SessionHostEndpoint>;
|
|
8
9
|
export declare function listHostedCliRuntimes(endpoint: SessionHostEndpoint): Promise<HostedCliRuntimeDescriptor[]>;
|
package/dist/shared-types.d.ts
CHANGED
|
@@ -240,7 +240,9 @@ export type SessionTransport = 'cdp-page' | 'cdp-webview' | 'pty' | 'acp';
|
|
|
240
240
|
export type SessionKind = 'workspace' | 'agent';
|
|
241
241
|
export type SessionCapability = 'read_chat' | 'send_message' | 'new_session' | 'list_sessions' | 'switch_session' | 'resolve_action' | 'open_panel' | 'terminal_io' | 'resize_terminal' | 'change_model' | 'set_mode' | 'set_thought_level' | 'delete_notification' | 'mark_notification_unread';
|
|
242
242
|
import type { RuntimeWriteOwner, RuntimeAttachedClient, SessionStatus } from './shared-types-extra.js';
|
|
243
|
+
import type { MessageInputSupport } from './providers/provider-input-support.js';
|
|
243
244
|
export type { RuntimeWriteOwner, RuntimeAttachedClient, SessionStatus } from './shared-types-extra.js';
|
|
245
|
+
export type { MessageInputSupport, InputMediaStrategyDescriptor, InputAttachmentStrategy, InputMediaType } from './providers/provider-input-support.js';
|
|
244
246
|
export interface SessionEntry {
|
|
245
247
|
id: string;
|
|
246
248
|
parentId: string | null;
|
|
@@ -267,6 +269,8 @@ export interface SessionEntry {
|
|
|
267
269
|
resume?: ProviderResumeCapability;
|
|
268
270
|
activeChat: SessionActiveChatData | null;
|
|
269
271
|
capabilities?: SessionCapability[];
|
|
272
|
+
/** Effective message input/media support for this session. Defaults fail-closed to text-only. */
|
|
273
|
+
messageInput?: MessageInputSupport;
|
|
270
274
|
cdpConnected?: boolean;
|
|
271
275
|
/** Dynamic control current values (generic key-value) */
|
|
272
276
|
controlValues?: Record<string, string | number | boolean>;
|
|
@@ -522,6 +526,8 @@ export interface DaemonStatusEventPayload {
|
|
|
522
526
|
timestamp: number;
|
|
523
527
|
targetSessionId?: string;
|
|
524
528
|
providerType?: string;
|
|
529
|
+
providerSessionId?: string;
|
|
530
|
+
workspaceName?: string;
|
|
525
531
|
duration?: number;
|
|
526
532
|
elapsedSec?: number;
|
|
527
533
|
modalMessage?: string;
|
|
@@ -535,6 +541,8 @@ export interface DashboardStatusEventPayload {
|
|
|
535
541
|
daemonId?: string;
|
|
536
542
|
providerType?: string;
|
|
537
543
|
targetSessionId?: string;
|
|
544
|
+
providerSessionId?: string;
|
|
545
|
+
workspaceName?: string;
|
|
538
546
|
duration?: number;
|
|
539
547
|
elapsedSec?: number;
|
|
540
548
|
modalMessage?: string;
|
package/dist/types.d.ts
CHANGED
|
@@ -42,6 +42,15 @@ export interface ChatMessage {
|
|
|
42
42
|
/** Optional: fiber metadata */
|
|
43
43
|
_type?: string;
|
|
44
44
|
_sub?: string;
|
|
45
|
+
/** Transcript visibility/audience contract for separating chat-visible content from internal/debug runtime rows. */
|
|
46
|
+
visibility?: 'visible' | 'user' | 'chat' | 'hidden' | 'debug' | 'internal' | (string & {});
|
|
47
|
+
transcriptVisibility?: 'visible' | 'user' | 'chat' | 'hidden' | 'debug' | 'internal' | (string & {});
|
|
48
|
+
audience?: 'chat' | 'debug' | 'trace' | 'internal' | (string & {});
|
|
49
|
+
source?: 'assistant_text' | 'tool_call' | 'terminal_command' | 'runtime_activity' | 'runtime_status' | 'provider_chrome' | 'control' | (string & {});
|
|
50
|
+
userFacing?: boolean;
|
|
51
|
+
internal?: boolean;
|
|
52
|
+
isInternal?: boolean;
|
|
53
|
+
debug?: boolean;
|
|
45
54
|
/** Meta information for thought/terminal logs etc */
|
|
46
55
|
meta?: {
|
|
47
56
|
label?: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adhdev/daemon-core",
|
|
3
|
-
"version": "0.9.76
|
|
3
|
+
"version": "0.9.76",
|
|
4
4
|
"description": "ADHDev daemon core — CDP, IDE detection, providers, command execution",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -50,18 +50,17 @@
|
|
|
50
50
|
"@agentclientprotocol/sdk": "^0.16.1",
|
|
51
51
|
"@xterm/xterm": "^6.0.0",
|
|
52
52
|
"chalk": "^5.3.0",
|
|
53
|
-
"chokidar": "^
|
|
53
|
+
"chokidar": "^4.0.3",
|
|
54
54
|
"conf": "^13.0.0",
|
|
55
|
+
"js-yaml": "^4.1.1",
|
|
55
56
|
"node-pty": "^1.2.0-beta.12",
|
|
56
57
|
"ws": "^8.19.0"
|
|
57
58
|
},
|
|
58
|
-
"bundleDependencies": [
|
|
59
|
-
"@adhdev/session-host-core"
|
|
60
|
-
],
|
|
61
59
|
"optionalDependencies": {
|
|
62
60
|
"@adhdev/ghostty-vt-node": "*"
|
|
63
61
|
},
|
|
64
62
|
"devDependencies": {
|
|
63
|
+
"@types/js-yaml": "^4.0.9",
|
|
65
64
|
"@types/node": "^22.0.0",
|
|
66
65
|
"@types/ws": "^8.18.1",
|
|
67
66
|
"tsup": "^8.2.0",
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
buildSessionModalDeliverySignature,
|
|
9
9
|
} from './chat-signatures.js'
|
|
10
10
|
import { normalizeManagedStatus } from '../status/normalize.js'
|
|
11
|
+
import { normalizeChatMessages } from '../providers/chat-message-normalization.js'
|
|
11
12
|
|
|
12
13
|
export interface ChatTailSubscriptionCursor {
|
|
13
14
|
tailLimit: number
|
|
@@ -101,7 +102,8 @@ export function prepareSessionChatTailUpdate(
|
|
|
101
102
|
}
|
|
102
103
|
}
|
|
103
104
|
|
|
104
|
-
const
|
|
105
|
+
const fullMessages = normalizeChatMessages(Array.isArray(result.messages) ? result.messages as any[] : [])
|
|
106
|
+
const messages = fullMessages
|
|
105
107
|
const title = typeof result.title === 'string' ? result.title : undefined
|
|
106
108
|
const activeModal = normalizeChatTailActiveModal(result.activeModal)
|
|
107
109
|
const status = typeof result.status === 'string' ? result.status : 'idle'
|
|
@@ -35,6 +35,7 @@ import {
|
|
|
35
35
|
normalizeScreenSnapshot,
|
|
36
36
|
promptLikelyVisible,
|
|
37
37
|
sanitizeTerminalText,
|
|
38
|
+
TerminalTranscriptAccumulator,
|
|
38
39
|
type CliChatMessage,
|
|
39
40
|
type CliProviderModule,
|
|
40
41
|
type CliScriptInput,
|
|
@@ -195,8 +196,10 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
195
196
|
// ─── CLI Scripts (script-based parsing) ───
|
|
196
197
|
private cliScripts: CliScripts;
|
|
197
198
|
private runtimeSettings: Record<string, any> = {};
|
|
198
|
-
/** Full accumulated
|
|
199
|
+
/** Full accumulated rendered PTY transcript for parser/readback use */
|
|
199
200
|
private accumulatedBuffer: string = '';
|
|
201
|
+
/** Stateful rendered transcript accumulator; raw debug remains in accumulatedRawBuffer. */
|
|
202
|
+
private transcriptAccumulator = new TerminalTranscriptAccumulator();
|
|
200
203
|
/** Full accumulated raw PTY output (with ANSI) */
|
|
201
204
|
private accumulatedRawBuffer: string = '';
|
|
202
205
|
/** Current visible terminal screen snapshot */
|
|
@@ -287,6 +290,7 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
287
290
|
|
|
288
291
|
private resetTerminalScreen(rows?: number, cols?: number): void {
|
|
289
292
|
this.terminalScreen.reset(rows, cols);
|
|
293
|
+
this.transcriptAccumulator.reset();
|
|
290
294
|
this.lastScreenText = '';
|
|
291
295
|
this.lastScreenSnapshot = '';
|
|
292
296
|
this.lastScreenChangeAt = 0;
|
|
@@ -422,6 +426,7 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
422
426
|
provider: CliProviderModule,
|
|
423
427
|
workingDir: string,
|
|
424
428
|
private extraArgs: string[] = [],
|
|
429
|
+
private extraEnv: Record<string, string> = {},
|
|
425
430
|
transportFactory: PtyTransportFactory = new NodePtyTransportFactory(),
|
|
426
431
|
) {
|
|
427
432
|
this.provider = provider;
|
|
@@ -523,6 +528,7 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
523
528
|
runtimeSettings: this.runtimeSettings,
|
|
524
529
|
workingDir: this.workingDir,
|
|
525
530
|
extraArgs: this.extraArgs,
|
|
531
|
+
extraEnv: this.extraEnv,
|
|
526
532
|
});
|
|
527
533
|
|
|
528
534
|
LOG.info('CLI', `[${this.cliType}] Spawning in ${this.workingDir}`);
|
|
@@ -632,6 +638,7 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
632
638
|
private handleOutput(rawData: string): void {
|
|
633
639
|
this.terminalScreen.write(rawData);
|
|
634
640
|
const cleanData = sanitizeTerminalText(rawData);
|
|
641
|
+
const renderedTranscript = this.transcriptAccumulator.append(rawData);
|
|
635
642
|
const now = Date.now();
|
|
636
643
|
const shouldReadScreen = this.shouldReadTerminalScreenSnapshot(now);
|
|
637
644
|
const screenText = shouldReadScreen ? this.readTerminalScreenText(now) : this.lastScreenText;
|
|
@@ -678,15 +685,23 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
678
685
|
}
|
|
679
686
|
}
|
|
680
687
|
|
|
681
|
-
// Rolling buffers
|
|
688
|
+
// Rolling parser/readback buffers. `accumulatedBuffer` and
|
|
689
|
+
// `recentOutputBuffer` intentionally use the rendered transcript state,
|
|
690
|
+
// not raw PTY append text, so overwritten CLI status/tool lines do not
|
|
691
|
+
// leak stale cells into read_chat / mesh_read_chat compact summaries.
|
|
682
692
|
const prevRecentLen = this.recentOutputBuffer.length;
|
|
683
|
-
const prevAccumulatedLen = this.accumulatedBuffer.length;
|
|
684
693
|
const prevAccumulatedRawLen = this.accumulatedRawBuffer.length;
|
|
685
|
-
|
|
686
|
-
|
|
694
|
+
const nextAccumulatedBuffer = renderedTranscript.length <= ProviderCliAdapter.MAX_ACCUMULATED_BUFFER
|
|
695
|
+
? renderedTranscript
|
|
696
|
+
: renderedTranscript.slice(-ProviderCliAdapter.MAX_ACCUMULATED_BUFFER);
|
|
697
|
+
const nextRecentOutputBuffer = nextAccumulatedBuffer.slice(-ProviderCliAdapter.MAX_RECENT_OUTPUT_BUFFER);
|
|
698
|
+
this.recentOutputBuffer = nextRecentOutputBuffer;
|
|
699
|
+
this.accumulatedBuffer = nextAccumulatedBuffer;
|
|
687
700
|
this.accumulatedRawBuffer = appendBoundedText(this.accumulatedRawBuffer, rawData, ProviderCliAdapter.MAX_ACCUMULATED_BUFFER);
|
|
688
|
-
|
|
689
|
-
|
|
701
|
+
// recentOutputBuffer is a 1000-char sliding window over accumulatedBuffer.
|
|
702
|
+
// Anything that doesn't fit in the window is considered dropped.
|
|
703
|
+
const droppedRecent = Math.max(0, renderedTranscript.length - ProviderCliAdapter.MAX_RECENT_OUTPUT_BUFFER);
|
|
704
|
+
const droppedClean = Math.max(0, renderedTranscript.length - this.accumulatedBuffer.length);
|
|
690
705
|
const droppedRaw = this.recordBoundedAppendDrop(prevAccumulatedRawLen, rawData.length, this.accumulatedRawBuffer.length);
|
|
691
706
|
this.recentOutputDroppedChars += droppedRecent;
|
|
692
707
|
this.accumulatedBufferDroppedChars += droppedClean;
|
|
@@ -1855,9 +1870,13 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1855
1870
|
};
|
|
1856
1871
|
this.recordTrace('submit_echo_missing', diagnostic);
|
|
1857
1872
|
if (this.requirePromptEchoBeforeSubmit) {
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1873
|
+
// At this point the prompt text write already completed. Rejecting without
|
|
1874
|
+
// a submit key can leave the delegated CLI with an unsent prompt sitting at
|
|
1875
|
+
// the input line, which makes later coordinator sends appear stuck. Prefer a
|
|
1876
|
+
// guarded submit after the full echo wait; the existing stuck-submit retry
|
|
1877
|
+
// will send a delayed follow-up Enter if the prompt remains visible.
|
|
1878
|
+
LOG.warn('CLI', `[${this.cliType}] prompt echo was not observed before submit; sending guarded submit key anyway elapsed=${elapsed}ms maxEchoWaitMs=${state.maxEchoWaitMs} screen=${JSON.stringify(diagnostic.screenText).slice(0, 240)}`);
|
|
1879
|
+
this.submitSendKey(state, completion);
|
|
1861
1880
|
return;
|
|
1862
1881
|
}
|
|
1863
1882
|
LOG.warn('CLI', `[${this.cliType}] prompt echo was not observed before submit; sending submit key anyway elapsed=${elapsed}ms maxEchoWaitMs=${state.maxEchoWaitMs}`);
|
|
@@ -1912,7 +1931,21 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1912
1931
|
? String(parsedStatusBeforeSend.status)
|
|
1913
1932
|
: '';
|
|
1914
1933
|
if (!allowInputDuringGeneration && (parsedSessionStatus === 'generating' || parsedSessionStatus === 'long_generating')) {
|
|
1915
|
-
|
|
1934
|
+
const parsedModal = parsedStatusBeforeSend?.activeModal ?? parsedStatusBeforeSend?.modal ?? null;
|
|
1935
|
+
const parsedHasActionableModal = Boolean(
|
|
1936
|
+
parsedModal
|
|
1937
|
+
&& Array.isArray(parsedModal.buttons)
|
|
1938
|
+
&& parsedModal.buttons.some((candidate: unknown) => typeof candidate === 'string' && candidate.trim()),
|
|
1939
|
+
);
|
|
1940
|
+
const terminalLooksIdle = this.currentStatus === 'idle'
|
|
1941
|
+
&& this.runDetectStatus(this.recentOutputBuffer) === 'idle'
|
|
1942
|
+
&& !this.isWaitingForResponse
|
|
1943
|
+
&& !this.currentTurnScope
|
|
1944
|
+
&& !this.hasActionableApproval()
|
|
1945
|
+
&& !parsedHasActionableModal;
|
|
1946
|
+
if (!terminalLooksIdle) {
|
|
1947
|
+
throw new Error(`${this.cliName} is still processing the previous prompt`);
|
|
1948
|
+
}
|
|
1916
1949
|
}
|
|
1917
1950
|
if (this.isWaitingForResponse && !allowInputDuringGeneration) {
|
|
1918
1951
|
if (!this.clearStaleIdleResponseGuard('send_message_guard')) {
|
|
@@ -27,8 +27,9 @@ export function resolveCliSpawnPlan(options: {
|
|
|
27
27
|
runtimeSettings: Record<string, any>;
|
|
28
28
|
workingDir: string;
|
|
29
29
|
extraArgs: string[];
|
|
30
|
+
extraEnv?: Record<string, string>;
|
|
30
31
|
}): CliSpawnPlan {
|
|
31
|
-
const { provider, runtimeSettings, workingDir, extraArgs } = options;
|
|
32
|
+
const { provider, runtimeSettings, workingDir, extraArgs, extraEnv } = options;
|
|
32
33
|
const { spawn: spawnConfig } = provider;
|
|
33
34
|
const configuredCommand = typeof runtimeSettings.executablePath === 'string' && runtimeSettings.executablePath.trim()
|
|
34
35
|
? runtimeSettings.executablePath.trim()
|
|
@@ -65,7 +66,7 @@ export function resolveCliSpawnPlan(options: {
|
|
|
65
66
|
shellArgs = allArgs;
|
|
66
67
|
}
|
|
67
68
|
|
|
68
|
-
const env = buildCliSpawnEnv(process.env, spawnConfig.env);
|
|
69
|
+
const env = buildCliSpawnEnv(process.env, { ...(spawnConfig.env || {}), ...(extraEnv || {}) });
|
|
69
70
|
// Some CLI agents, notably Hermes, route their tools through TERMINAL_CWD
|
|
70
71
|
// rather than process.cwd(). Keep the generic ADHDev launch workspace as
|
|
71
72
|
// the single source of truth so PTY cwd and tool cwd cannot diverge.
|