@adhdev/daemon-core 0.9.76-rc.25 → 0.9.76-rc.26
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 +88 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +88 -3
- package/dist/index.mjs.map +1 -1
- package/dist/providers/provider-instance-manager.d.ts +1 -0
- package/dist/providers/provider-instance.d.ts +2 -0
- package/dist/shared-types.d.ts +4 -0
- package/package.json +1 -1
- package/src/commands/router.ts +68 -1
- package/src/providers/cli-provider-instance.ts +23 -1
- package/src/providers/provider-instance-manager.ts +20 -1
- package/src/providers/provider-instance.ts +2 -0
- package/src/shared-types.ts +4 -0
- package/src/status/reporter.ts +6 -0
|
@@ -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
|
|
@@ -147,6 +147,8 @@ export interface InstanceContext {
|
|
|
147
147
|
onPtyData?: (data: string) => void;
|
|
148
148
|
/** Provider configvalue (resolved) */
|
|
149
149
|
settings: Record<string, any>;
|
|
150
|
+
/** Immediate provider-originated status/event emission. Used to avoid waiting for status polling. */
|
|
151
|
+
emitProviderEvent?: (event: ProviderEvent) => void;
|
|
150
152
|
}
|
|
151
153
|
export interface ProviderInstance {
|
|
152
154
|
/** Provider type */
|
package/dist/shared-types.d.ts
CHANGED
|
@@ -522,6 +522,8 @@ export interface DaemonStatusEventPayload {
|
|
|
522
522
|
timestamp: number;
|
|
523
523
|
targetSessionId?: string;
|
|
524
524
|
providerType?: string;
|
|
525
|
+
providerSessionId?: string;
|
|
526
|
+
workspaceName?: string;
|
|
525
527
|
duration?: number;
|
|
526
528
|
elapsedSec?: number;
|
|
527
529
|
modalMessage?: string;
|
|
@@ -535,6 +537,8 @@ export interface DashboardStatusEventPayload {
|
|
|
535
537
|
daemonId?: string;
|
|
536
538
|
providerType?: string;
|
|
537
539
|
targetSessionId?: string;
|
|
540
|
+
providerSessionId?: string;
|
|
541
|
+
workspaceName?: string;
|
|
538
542
|
duration?: number;
|
|
539
543
|
elapsedSec?: number;
|
|
540
544
|
modalMessage?: string;
|
package/package.json
CHANGED
package/src/commands/router.ts
CHANGED
|
@@ -62,6 +62,54 @@ function resolveUpgradeChannel(args: any): ReleaseChannel {
|
|
|
62
62
|
|| normalizeReleaseChannel(loadConfig().updateChannel)
|
|
63
63
|
|| 'stable';
|
|
64
64
|
}
|
|
65
|
+
|
|
66
|
+
function readProviderPriorityFromPolicy(policy: unknown): string[] {
|
|
67
|
+
const record = policy && typeof policy === 'object' && !Array.isArray(policy)
|
|
68
|
+
? policy as Record<string, unknown>
|
|
69
|
+
: {};
|
|
70
|
+
const raw = record.providerPriority;
|
|
71
|
+
if (!Array.isArray(raw)) return [];
|
|
72
|
+
const seen = new Set<string>();
|
|
73
|
+
return raw
|
|
74
|
+
.map(type => typeof type === 'string' ? type.trim() : '')
|
|
75
|
+
.filter(Boolean)
|
|
76
|
+
.filter(type => {
|
|
77
|
+
if (seen.has(type)) return false;
|
|
78
|
+
seen.add(type);
|
|
79
|
+
return true;
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async function resolveProviderTypeFromPriority(args: {
|
|
84
|
+
nodeId: string;
|
|
85
|
+
providerPriority: string[];
|
|
86
|
+
providerLoader: ProviderLoader;
|
|
87
|
+
onStatusChange?: () => void;
|
|
88
|
+
}): Promise<{ providerType?: string; error?: string }> {
|
|
89
|
+
if (!args.providerPriority.length) {
|
|
90
|
+
return { error: `Node '${args.nodeId}' has no providerPriority policy; pass cliType explicitly or configure node.policy.providerPriority` };
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const failed: string[] = [];
|
|
94
|
+
for (const requestedType of args.providerPriority) {
|
|
95
|
+
const normalizedType = args.providerLoader.resolveAlias(requestedType);
|
|
96
|
+
if (!args.providerLoader.isMachineProviderEnabled(normalizedType)) {
|
|
97
|
+
failed.push(`${requestedType}: disabled`);
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
const detected = await detectCLI(normalizedType, args.providerLoader, { includeVersion: false });
|
|
101
|
+
args.providerLoader.setCliDetectionResults([{
|
|
102
|
+
id: normalizedType,
|
|
103
|
+
installed: !!detected,
|
|
104
|
+
path: detected?.path,
|
|
105
|
+
}], false);
|
|
106
|
+
args.onStatusChange?.();
|
|
107
|
+
if (detected) return { providerType: normalizedType };
|
|
108
|
+
failed.push(`${requestedType}: not detected`);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return { error: `No usable provider detected for node '${args.nodeId}' from providerPriority: ${failed.join('; ')}` };
|
|
112
|
+
}
|
|
65
113
|
import * as fs from 'fs';
|
|
66
114
|
|
|
67
115
|
type MeshCoordinatorConfigFormat = 'claude_mcp_json' | 'hermes_config_yaml';
|
|
@@ -1194,7 +1242,7 @@ export class DaemonCommandRouter {
|
|
|
1194
1242
|
// ─── Mesh Coordinator Launch ───
|
|
1195
1243
|
case 'launch_mesh_coordinator': {
|
|
1196
1244
|
const meshId = typeof args?.meshId === 'string' ? args.meshId.trim() : '';
|
|
1197
|
-
|
|
1245
|
+
let cliType = typeof args?.cliType === 'string' ? args.cliType.trim() : '';
|
|
1198
1246
|
if (!meshId) return { success: false, error: 'meshId required' };
|
|
1199
1247
|
|
|
1200
1248
|
try {
|
|
@@ -1232,6 +1280,25 @@ export class DaemonCommandRouter {
|
|
|
1232
1280
|
}
|
|
1233
1281
|
const workspace = typeof coordinatorNode.workspace === 'string' ? coordinatorNode.workspace.trim() : '';
|
|
1234
1282
|
if (!workspace) return { success: false, error: 'Coordinator node workspace required', meshId, cliType };
|
|
1283
|
+
if (!cliType) {
|
|
1284
|
+
const resolved = await resolveProviderTypeFromPriority({
|
|
1285
|
+
nodeId: String(coordinatorNode.id || coordinatorNode.nodeId || preferredCoordinatorNodeId || 'coordinator'),
|
|
1286
|
+
providerPriority: readProviderPriorityFromPolicy(coordinatorNode.policy),
|
|
1287
|
+
providerLoader: this.deps.providerLoader,
|
|
1288
|
+
onStatusChange: this.deps.onStatusChange,
|
|
1289
|
+
});
|
|
1290
|
+
if (!resolved.providerType) {
|
|
1291
|
+
return {
|
|
1292
|
+
success: false,
|
|
1293
|
+
code: 'mesh_coordinator_provider_priority_unusable',
|
|
1294
|
+
error: resolved.error || 'No usable provider found from node providerPriority',
|
|
1295
|
+
meshId,
|
|
1296
|
+
cliType,
|
|
1297
|
+
workspace,
|
|
1298
|
+
};
|
|
1299
|
+
}
|
|
1300
|
+
cliType = resolved.providerType;
|
|
1301
|
+
}
|
|
1235
1302
|
const providerMeta = this.deps.providerLoader.resolve?.(cliType) || this.deps.providerLoader.getMeta(cliType);
|
|
1236
1303
|
const coordinatorSetup = resolveMeshCoordinatorSetup({
|
|
1237
1304
|
provider: providerMeta,
|
|
@@ -738,7 +738,29 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
738
738
|
}
|
|
739
739
|
|
|
740
740
|
private pushEvent(event: ProviderEvent): void {
|
|
741
|
-
|
|
741
|
+
const enrichedEvent: ProviderEvent = {
|
|
742
|
+
...event,
|
|
743
|
+
instanceId: typeof event.instanceId === 'string' && event.instanceId.trim()
|
|
744
|
+
? event.instanceId
|
|
745
|
+
: this.instanceId,
|
|
746
|
+
targetSessionId: typeof event.targetSessionId === 'string' && event.targetSessionId.trim()
|
|
747
|
+
? event.targetSessionId
|
|
748
|
+
: this.instanceId,
|
|
749
|
+
providerType: typeof event.providerType === 'string' && event.providerType.trim()
|
|
750
|
+
? event.providerType
|
|
751
|
+
: this.type,
|
|
752
|
+
workspaceName: typeof event.workspaceName === 'string' && event.workspaceName.trim()
|
|
753
|
+
? event.workspaceName
|
|
754
|
+
: this.workingDir,
|
|
755
|
+
providerSessionId: typeof event.providerSessionId === 'string' && event.providerSessionId.trim()
|
|
756
|
+
? event.providerSessionId
|
|
757
|
+
: this.providerSessionId,
|
|
758
|
+
};
|
|
759
|
+
if (this.context?.emitProviderEvent) {
|
|
760
|
+
this.context.emitProviderEvent(enrichedEvent);
|
|
761
|
+
return;
|
|
762
|
+
}
|
|
763
|
+
this.events.push(enrichedEvent);
|
|
742
764
|
}
|
|
743
765
|
|
|
744
766
|
private flushEvents(): ProviderEvent[] {
|
|
@@ -47,7 +47,10 @@ export class ProviderInstanceManager {
|
|
|
47
47
|
this.instances.get(id)!.dispose();
|
|
48
48
|
}
|
|
49
49
|
this.instances.set(id, instance);
|
|
50
|
-
await instance.init(
|
|
50
|
+
await instance.init({
|
|
51
|
+
...context,
|
|
52
|
+
emitProviderEvent: (event) => this.emitProviderEvent(instance.type, id, event),
|
|
53
|
+
});
|
|
51
54
|
}
|
|
52
55
|
|
|
53
56
|
/**
|
|
@@ -237,6 +240,22 @@ export class ProviderInstanceManager {
|
|
|
237
240
|
this.eventListeners.push(listener);
|
|
238
241
|
}
|
|
239
242
|
|
|
243
|
+
emitProviderEvent(providerType: string, instanceId: string, event: ProviderEvent): void {
|
|
244
|
+
const payload = {
|
|
245
|
+
...event,
|
|
246
|
+
providerType,
|
|
247
|
+
instanceId: typeof event.instanceId === 'string' && event.instanceId.trim()
|
|
248
|
+
? event.instanceId
|
|
249
|
+
: instanceId,
|
|
250
|
+
targetSessionId: typeof event.targetSessionId === 'string' && event.targetSessionId.trim()
|
|
251
|
+
? event.targetSessionId
|
|
252
|
+
: instanceId,
|
|
253
|
+
} as ProviderEvent & { providerType: string };
|
|
254
|
+
for (const listener of this.eventListeners) {
|
|
255
|
+
listener(payload);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
240
259
|
private emitPendingEvents(
|
|
241
260
|
providerType: string,
|
|
242
261
|
state: ProviderState,
|
|
@@ -174,6 +174,8 @@ export interface InstanceContext {
|
|
|
174
174
|
onPtyData?: (data: string) => void;
|
|
175
175
|
/** Provider configvalue (resolved) */
|
|
176
176
|
settings: Record<string, any>;
|
|
177
|
+
/** Immediate provider-originated status/event emission. Used to avoid waiting for status polling. */
|
|
178
|
+
emitProviderEvent?: (event: ProviderEvent) => void;
|
|
177
179
|
}
|
|
178
180
|
|
|
179
181
|
export interface ProviderInstance {
|
package/src/shared-types.ts
CHANGED
|
@@ -641,6 +641,8 @@ export interface DaemonStatusEventPayload {
|
|
|
641
641
|
timestamp: number;
|
|
642
642
|
targetSessionId?: string;
|
|
643
643
|
providerType?: string;
|
|
644
|
+
providerSessionId?: string;
|
|
645
|
+
workspaceName?: string;
|
|
644
646
|
duration?: number;
|
|
645
647
|
elapsedSec?: number;
|
|
646
648
|
modalMessage?: string;
|
|
@@ -662,6 +664,8 @@ export interface DashboardStatusEventPayload {
|
|
|
662
664
|
daemonId?: string;
|
|
663
665
|
providerType?: string;
|
|
664
666
|
targetSessionId?: string;
|
|
667
|
+
providerSessionId?: string;
|
|
668
|
+
workspaceName?: string;
|
|
665
669
|
duration?: number;
|
|
666
670
|
elapsedSec?: number;
|
|
667
671
|
modalMessage?: string;
|
package/src/status/reporter.ts
CHANGED
|
@@ -151,6 +151,12 @@ export class DaemonStatusReporter {
|
|
|
151
151
|
if (providerType) {
|
|
152
152
|
payload.providerType = providerType;
|
|
153
153
|
}
|
|
154
|
+
if (typeof event.providerSessionId === 'string' && event.providerSessionId.trim()) {
|
|
155
|
+
payload.providerSessionId = event.providerSessionId.trim();
|
|
156
|
+
}
|
|
157
|
+
if (typeof event.workspaceName === 'string' && event.workspaceName.trim()) {
|
|
158
|
+
payload.workspaceName = event.workspaceName.trim();
|
|
159
|
+
}
|
|
154
160
|
if (typeof event.duration === 'number' && Number.isFinite(event.duration)) {
|
|
155
161
|
payload.duration = event.duration;
|
|
156
162
|
}
|