@adhdev/daemon-core 0.9.28 → 0.9.30
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/config/config.d.ts +16 -0
- package/dist/index.js +374 -67
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +348 -41
- package/dist/index.mjs.map +1 -1
- package/dist/providers/provider-loader.d.ts +39 -8
- package/dist/shared-types.d.ts +35 -0
- package/dist/status/snapshot.d.ts +5 -1
- package/node_modules/@adhdev/session-host-core/package.json +1 -1
- package/package.json +1 -1
- package/src/boot/daemon-lifecycle.ts +4 -3
- package/src/commands/cli-manager.ts +45 -15
- package/src/commands/router.ts +38 -2
- package/src/config/config.ts +46 -0
- package/src/providers/provider-loader.d.ts +23 -0
- package/src/providers/provider-loader.ts +286 -18
- package/src/shared-types.d.ts +4 -0
- package/src/shared-types.ts +36 -0
- package/src/status/snapshot.ts +12 -0
|
@@ -38,6 +38,40 @@ interface ProviderAvailabilityState {
|
|
|
38
38
|
detectedPath: string | null;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
export type ProviderMachineStatus =
|
|
42
|
+
| 'disabled'
|
|
43
|
+
| 'enabled_unchecked'
|
|
44
|
+
| 'not_detected'
|
|
45
|
+
| 'detected';
|
|
46
|
+
|
|
47
|
+
export interface MachineProviderCheckResult {
|
|
48
|
+
ok: boolean;
|
|
49
|
+
stage?: 'detection' | 'runnable' | 'verification';
|
|
50
|
+
checkedAt?: string;
|
|
51
|
+
message?: string;
|
|
52
|
+
command?: string;
|
|
53
|
+
path?: string | null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface MachineProviderConfig {
|
|
57
|
+
enabled?: boolean;
|
|
58
|
+
executable?: string;
|
|
59
|
+
args?: string[];
|
|
60
|
+
lastDetection?: MachineProviderCheckResult;
|
|
61
|
+
lastVerification?: MachineProviderCheckResult;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
type CliDetectionEntry = {
|
|
65
|
+
id: string;
|
|
66
|
+
displayName: string;
|
|
67
|
+
icon: string;
|
|
68
|
+
command: string;
|
|
69
|
+
args?: string[];
|
|
70
|
+
category: string;
|
|
71
|
+
enabled: boolean;
|
|
72
|
+
versionCommand?: string;
|
|
73
|
+
};
|
|
74
|
+
|
|
41
75
|
export class ProviderLoader {
|
|
42
76
|
private providers = new Map<string, ProviderModule>();
|
|
43
77
|
private providerAvailability = new Map<string, ProviderAvailabilityState>();
|
|
@@ -362,18 +396,21 @@ export class ProviderLoader {
|
|
|
362
396
|
* Build CLI/ACP detection list (replaces cli-detector)
|
|
363
397
|
* Dynamically generated from provider.js spawn.command.
|
|
364
398
|
*/
|
|
365
|
-
getCliDetectionList():
|
|
366
|
-
const result:
|
|
399
|
+
getCliDetectionList(): CliDetectionEntry[] {
|
|
400
|
+
const result: CliDetectionEntry[] = [];
|
|
367
401
|
for (const p of this.providers.values()) {
|
|
368
|
-
if ((p.category === 'cli' || p.category === 'acp') && p.spawn?.command) {
|
|
402
|
+
if ((p.category === 'cli' || p.category === 'acp') && p.spawn?.command && this.isMachineProviderEnabled(p.type)) {
|
|
369
403
|
const versionCommand = this.getPlatformVersionCommand(p.versionCommand);
|
|
370
404
|
const command = this.getSpawnCommand(p.type, p.spawn.command);
|
|
405
|
+
const args = this.getSpawnArgs(p.type, p.spawn.args || []);
|
|
371
406
|
result.push({
|
|
372
407
|
id: p.type,
|
|
373
408
|
displayName: p.displayName || p.name,
|
|
374
409
|
icon: p.icon || '🔧',
|
|
375
410
|
command,
|
|
411
|
+
...(args.length > 0 ? { args } : {}),
|
|
376
412
|
category: p.category,
|
|
413
|
+
enabled: true,
|
|
377
414
|
...(typeof versionCommand === 'string' && versionCommand.trim()
|
|
378
415
|
? { versionCommand: versionCommand.trim() }
|
|
379
416
|
: {}),
|
|
@@ -520,9 +557,10 @@ export class ProviderLoader {
|
|
|
520
557
|
}
|
|
521
558
|
|
|
522
559
|
getSpawnCommand(type: string, fallback?: string): string {
|
|
523
|
-
const
|
|
524
|
-
|
|
525
|
-
|
|
560
|
+
const providerType = this.resolveAlias(type);
|
|
561
|
+
const machineConfig = this.getMachineProviderConfig(providerType);
|
|
562
|
+
if (machineConfig.executable) return machineConfig.executable;
|
|
563
|
+
return fallback || this.providers.get(providerType)?.spawn?.command || providerType;
|
|
526
564
|
}
|
|
527
565
|
|
|
528
566
|
getIdeCliCommand(type: string, fallback?: string | null): string | null {
|
|
@@ -539,6 +577,139 @@ export class ProviderLoader {
|
|
|
539
577
|
return Array.isArray(osPaths) ? [...osPaths] : [];
|
|
540
578
|
}
|
|
541
579
|
|
|
580
|
+
isMachineProviderEnabled(type: string): boolean {
|
|
581
|
+
const providerType = this.resolveAlias(type);
|
|
582
|
+
const config = this.readConfig();
|
|
583
|
+
return config?.machineProviders?.[providerType]?.enabled === true;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
getMachineProviderConfig(type: string): MachineProviderConfig {
|
|
587
|
+
const providerType = this.resolveAlias(type);
|
|
588
|
+
const raw = this.readConfig()?.machineProviders?.[providerType];
|
|
589
|
+
if (!raw || typeof raw !== 'object') return {};
|
|
590
|
+
const executable = typeof raw.executable === 'string' && raw.executable.trim() ? raw.executable.trim() : undefined;
|
|
591
|
+
return {
|
|
592
|
+
...(raw.enabled === true ? { enabled: true } : {}),
|
|
593
|
+
...(executable ? { executable } : {}),
|
|
594
|
+
...(Array.isArray(raw.args) ? { args: raw.args.filter((arg: unknown): arg is string => typeof arg === 'string') } : {}),
|
|
595
|
+
...(raw.lastDetection && typeof raw.lastDetection === 'object' ? { lastDetection: raw.lastDetection } : {}),
|
|
596
|
+
...(raw.lastVerification && typeof raw.lastVerification === 'object' ? { lastVerification: raw.lastVerification } : {}),
|
|
597
|
+
};
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
setMachineProviderConfig(type: string, patch: Partial<MachineProviderConfig>): boolean {
|
|
601
|
+
const providerType = this.resolveAlias(type);
|
|
602
|
+
if (!this.providers.has(providerType)) return false;
|
|
603
|
+
const config = this.readConfig();
|
|
604
|
+
if (!config) return false;
|
|
605
|
+
|
|
606
|
+
try {
|
|
607
|
+
if (!config.machineProviders) config.machineProviders = {};
|
|
608
|
+
const current: MachineProviderConfig = config.machineProviders[providerType] || {};
|
|
609
|
+
const next: MachineProviderConfig = { ...current };
|
|
610
|
+
const enabledChanged = 'enabled' in patch && current.enabled !== (patch.enabled === true);
|
|
611
|
+
const executableChanged = 'executable' in patch;
|
|
612
|
+
const argsChanged = 'args' in patch;
|
|
613
|
+
if ('enabled' in patch) next.enabled = patch.enabled === true;
|
|
614
|
+
if ('executable' in patch) {
|
|
615
|
+
const executable = typeof patch.executable === 'string' ? patch.executable.trim() : '';
|
|
616
|
+
if (executable) next.executable = executable;
|
|
617
|
+
else delete next.executable;
|
|
618
|
+
}
|
|
619
|
+
if ('args' in patch) {
|
|
620
|
+
if (Array.isArray(patch.args)) next.args = patch.args.filter((arg): arg is string => typeof arg === 'string');
|
|
621
|
+
else delete next.args;
|
|
622
|
+
}
|
|
623
|
+
if (enabledChanged || executableChanged || argsChanged) {
|
|
624
|
+
delete next.lastDetection;
|
|
625
|
+
delete next.lastVerification;
|
|
626
|
+
}
|
|
627
|
+
if ('lastDetection' in patch) {
|
|
628
|
+
if (patch.lastDetection) next.lastDetection = patch.lastDetection;
|
|
629
|
+
else delete next.lastDetection;
|
|
630
|
+
}
|
|
631
|
+
if ('lastVerification' in patch) {
|
|
632
|
+
if (patch.lastVerification) next.lastVerification = patch.lastVerification;
|
|
633
|
+
else delete next.lastVerification;
|
|
634
|
+
}
|
|
635
|
+
config.machineProviders[providerType] = next;
|
|
636
|
+
if (next.enabled !== true) {
|
|
637
|
+
this.providerAvailability.set(providerType, { installed: false, detectedPath: null });
|
|
638
|
+
}
|
|
639
|
+
this.writeConfig(config);
|
|
640
|
+
this.log(`Machine provider config updated: ${providerType}`);
|
|
641
|
+
return true;
|
|
642
|
+
} catch (e) {
|
|
643
|
+
this.log(`Failed to save machine provider config: ${(e as Error).message}`);
|
|
644
|
+
return false;
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
setMachineProviderEnabled(type: string, enabled: boolean): boolean {
|
|
649
|
+
return this.setMachineProviderConfig(type, { enabled });
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
getMachineProviderStatus(type: string): ProviderMachineStatus {
|
|
653
|
+
const providerType = this.resolveAlias(type);
|
|
654
|
+
if (!this.isMachineProviderEnabled(providerType)) return 'disabled';
|
|
655
|
+
const availability = this.providerAvailability.get(providerType);
|
|
656
|
+
if (!availability) return 'enabled_unchecked';
|
|
657
|
+
return availability.installed ? 'detected' : 'not_detected';
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
getSpawnArgs(type: string, fallback: string[] = []): string[] {
|
|
661
|
+
const machineConfig = this.getMachineProviderConfig(type);
|
|
662
|
+
if (machineConfig.args) return [...machineConfig.args];
|
|
663
|
+
return [...fallback];
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
private parseArgsSetting(value: string): string[] {
|
|
667
|
+
const args: string[] = [];
|
|
668
|
+
let current = '';
|
|
669
|
+
let quote: 'single' | 'double' | null = null;
|
|
670
|
+
let escaping = false;
|
|
671
|
+
for (const ch of value.trim()) {
|
|
672
|
+
if (escaping) {
|
|
673
|
+
current += ch;
|
|
674
|
+
escaping = false;
|
|
675
|
+
continue;
|
|
676
|
+
}
|
|
677
|
+
if (ch === '\\') {
|
|
678
|
+
escaping = true;
|
|
679
|
+
continue;
|
|
680
|
+
}
|
|
681
|
+
if (quote === 'single') {
|
|
682
|
+
if (ch === "'") quote = null;
|
|
683
|
+
else current += ch;
|
|
684
|
+
continue;
|
|
685
|
+
}
|
|
686
|
+
if (quote === 'double') {
|
|
687
|
+
if (ch === '"') quote = null;
|
|
688
|
+
else current += ch;
|
|
689
|
+
continue;
|
|
690
|
+
}
|
|
691
|
+
if (ch === "'") {
|
|
692
|
+
quote = 'single';
|
|
693
|
+
continue;
|
|
694
|
+
}
|
|
695
|
+
if (ch === '"') {
|
|
696
|
+
quote = 'double';
|
|
697
|
+
continue;
|
|
698
|
+
}
|
|
699
|
+
if (/\s/.test(ch)) {
|
|
700
|
+
if (current) {
|
|
701
|
+
args.push(current);
|
|
702
|
+
current = '';
|
|
703
|
+
}
|
|
704
|
+
continue;
|
|
705
|
+
}
|
|
706
|
+
current += ch;
|
|
707
|
+
}
|
|
708
|
+
if (escaping) current += '\\';
|
|
709
|
+
if (current) args.push(current);
|
|
710
|
+
return args;
|
|
711
|
+
}
|
|
712
|
+
|
|
542
713
|
setProviderAvailability(type: string, state: { installed: boolean; detectedPath?: string | null }): void {
|
|
543
714
|
this.providerAvailability.set(type, {
|
|
544
715
|
installed: !!state.installed,
|
|
@@ -547,18 +718,55 @@ export class ProviderLoader {
|
|
|
547
718
|
}
|
|
548
719
|
|
|
549
720
|
setCliDetectionResults(results: Array<{ id: string; installed: boolean; path?: string }>, replace: boolean = true): void {
|
|
721
|
+
const resultByType = new Map<string, { id: string; installed: boolean; path?: string }>();
|
|
722
|
+
for (const result of results) {
|
|
723
|
+
resultByType.set(this.resolveAlias(result.id), result);
|
|
724
|
+
}
|
|
725
|
+
|
|
550
726
|
if (replace) {
|
|
551
727
|
for (const provider of this.providers.values()) {
|
|
552
728
|
if (provider.category === 'cli' || provider.category === 'acp') {
|
|
553
|
-
|
|
729
|
+
const result = resultByType.get(provider.type);
|
|
730
|
+
const installed = !!result?.installed;
|
|
731
|
+
const detectedPath = result?.path || null;
|
|
732
|
+
this.providerAvailability.set(provider.type, { installed, detectedPath });
|
|
733
|
+
if (this.isMachineProviderEnabled(provider.type)) {
|
|
734
|
+
this.setMachineProviderConfig(provider.type, {
|
|
735
|
+
lastDetection: {
|
|
736
|
+
ok: installed,
|
|
737
|
+
stage: 'detection',
|
|
738
|
+
checkedAt: new Date().toISOString(),
|
|
739
|
+
command: this.getSpawnCommand(provider.type, provider.spawn?.command),
|
|
740
|
+
path: detectedPath,
|
|
741
|
+
message: installed ? 'Provider command detected' : 'Provider command was not detected',
|
|
742
|
+
},
|
|
743
|
+
});
|
|
744
|
+
}
|
|
554
745
|
}
|
|
555
746
|
}
|
|
747
|
+
return;
|
|
556
748
|
}
|
|
749
|
+
|
|
557
750
|
for (const result of results) {
|
|
558
|
-
this.
|
|
751
|
+
const providerType = this.resolveAlias(result.id);
|
|
752
|
+
const provider = this.providers.get(providerType);
|
|
753
|
+
const detectedPath = result.path || null;
|
|
754
|
+
this.setProviderAvailability(providerType, {
|
|
559
755
|
installed: !!result.installed,
|
|
560
|
-
detectedPath
|
|
756
|
+
detectedPath,
|
|
561
757
|
});
|
|
758
|
+
if (provider && (provider.category === 'cli' || provider.category === 'acp') && this.isMachineProviderEnabled(providerType)) {
|
|
759
|
+
this.setMachineProviderConfig(providerType, {
|
|
760
|
+
lastDetection: {
|
|
761
|
+
ok: !!result.installed,
|
|
762
|
+
stage: 'detection',
|
|
763
|
+
checkedAt: new Date().toISOString(),
|
|
764
|
+
command: this.getSpawnCommand(providerType, provider.spawn?.command),
|
|
765
|
+
path: detectedPath,
|
|
766
|
+
message: result.installed ? 'Provider command detected' : 'Provider command was not detected',
|
|
767
|
+
},
|
|
768
|
+
});
|
|
769
|
+
}
|
|
562
770
|
}
|
|
563
771
|
}
|
|
564
772
|
|
|
@@ -578,11 +786,17 @@ export class ProviderLoader {
|
|
|
578
786
|
}
|
|
579
787
|
}
|
|
580
788
|
|
|
581
|
-
getAvailableProviderInfos(): Array<ProviderModule & { installed?: boolean; detectedPath?: string | null }> {
|
|
789
|
+
getAvailableProviderInfos(): Array<ProviderModule & { installed?: boolean; detectedPath?: string | null; enabled: boolean; machineStatus: ProviderMachineStatus; lastDetection?: MachineProviderCheckResult; lastVerification?: MachineProviderCheckResult }> {
|
|
582
790
|
return this.getAll().map((provider) => {
|
|
583
791
|
const availability = this.providerAvailability.get(provider.type);
|
|
792
|
+
const enabled = this.isMachineProviderEnabled(provider.type);
|
|
793
|
+
const machineConfig = this.getMachineProviderConfig(provider.type);
|
|
584
794
|
return {
|
|
585
795
|
...provider,
|
|
796
|
+
enabled,
|
|
797
|
+
machineStatus: this.getMachineProviderStatus(provider.type),
|
|
798
|
+
...(machineConfig.lastDetection ? { lastDetection: machineConfig.lastDetection } : {}),
|
|
799
|
+
...(machineConfig.lastVerification ? { lastVerification: machineConfig.lastVerification } : {}),
|
|
586
800
|
...(availability
|
|
587
801
|
? {
|
|
588
802
|
installed: availability.installed,
|
|
@@ -764,6 +978,14 @@ export class ProviderLoader {
|
|
|
764
978
|
}
|
|
765
979
|
}
|
|
766
980
|
|
|
981
|
+
if ((resolved.category === 'cli' || resolved.category === 'acp') && resolved.spawn?.command) {
|
|
982
|
+
resolved.spawn = {
|
|
983
|
+
...resolved.spawn,
|
|
984
|
+
command: this.getSpawnCommand(type, resolved.spawn.command),
|
|
985
|
+
args: this.getSpawnArgs(type, resolved.spawn.args || []),
|
|
986
|
+
};
|
|
987
|
+
}
|
|
988
|
+
|
|
767
989
|
return resolved;
|
|
768
990
|
}
|
|
769
991
|
|
|
@@ -1117,7 +1339,19 @@ export class ProviderLoader {
|
|
|
1117
1339
|
* Resolved setting value for a provider (default + user override)
|
|
1118
1340
|
*/
|
|
1119
1341
|
getSettingValue(type: string, key: string): any {
|
|
1120
|
-
const
|
|
1342
|
+
const providerType = this.resolveAlias(type);
|
|
1343
|
+
const machineConfig = this.getMachineProviderConfig(providerType);
|
|
1344
|
+
if (key === 'enabled') {
|
|
1345
|
+
return machineConfig.enabled === true;
|
|
1346
|
+
}
|
|
1347
|
+
if (key === 'executablePath') {
|
|
1348
|
+
return machineConfig.executable || '';
|
|
1349
|
+
}
|
|
1350
|
+
if (key === 'executableArgs') {
|
|
1351
|
+
const args = machineConfig.args;
|
|
1352
|
+
return args ? args.map((arg) => /\s/.test(arg) ? JSON.stringify(arg) : arg).join(' ') : '';
|
|
1353
|
+
}
|
|
1354
|
+
const schemaDef = this.getSettingsSchema(providerType)[key];
|
|
1121
1355
|
const defaultVal = schemaDef
|
|
1122
1356
|
? (key === 'autoApprove' && schemaDef.type === 'boolean'
|
|
1123
1357
|
? true
|
|
@@ -1125,7 +1359,7 @@ export class ProviderLoader {
|
|
|
1125
1359
|
: undefined;
|
|
1126
1360
|
|
|
1127
1361
|
const config = this.readConfig();
|
|
1128
|
-
const userVal = config?.providerSettings?.[
|
|
1362
|
+
const userVal = config?.providerSettings?.[providerType]?.[key];
|
|
1129
1363
|
return userVal !== undefined ? userVal : defaultVal;
|
|
1130
1364
|
}
|
|
1131
1365
|
|
|
@@ -1133,10 +1367,11 @@ export class ProviderLoader {
|
|
|
1133
1367
|
* All resolved settings for a provider (default + user override)
|
|
1134
1368
|
*/
|
|
1135
1369
|
getSettings(type: string): Record<string, any> {
|
|
1136
|
-
const
|
|
1370
|
+
const providerType = this.resolveAlias(type);
|
|
1371
|
+
const settings = this.getSettingsSchema(providerType);
|
|
1137
1372
|
const result: Record<string, any> = {};
|
|
1138
1373
|
for (const [key] of Object.entries(settings)) {
|
|
1139
|
-
result[key] = this.getSettingValue(
|
|
1374
|
+
result[key] = this.getSettingValue(providerType, key);
|
|
1140
1375
|
}
|
|
1141
1376
|
return result;
|
|
1142
1377
|
}
|
|
@@ -1145,7 +1380,8 @@ export class ProviderLoader {
|
|
|
1145
1380
|
* Save provider setting value (writes to config.json)
|
|
1146
1381
|
*/
|
|
1147
1382
|
setSetting(type: string, key: string, value: any): boolean {
|
|
1148
|
-
const
|
|
1383
|
+
const providerType = this.resolveAlias(type);
|
|
1384
|
+
const schemaDef = this.getSettingsSchema(providerType)[key];
|
|
1149
1385
|
if (!schemaDef) return false;
|
|
1150
1386
|
|
|
1151
1387
|
// Non-public settings cannot be modified externally
|
|
@@ -1161,15 +1397,27 @@ export class ProviderLoader {
|
|
|
1161
1397
|
}
|
|
1162
1398
|
if (schemaDef.type === 'select' && schemaDef.options && !schemaDef.options.includes(value)) return false;
|
|
1163
1399
|
|
|
1400
|
+
if (key === 'enabled') {
|
|
1401
|
+
return this.setMachineProviderEnabled(providerType, value);
|
|
1402
|
+
}
|
|
1403
|
+
if (key === 'executablePath') {
|
|
1404
|
+
return this.setMachineProviderConfig(providerType, { executable: value });
|
|
1405
|
+
}
|
|
1406
|
+
if (key === 'executableArgs') {
|
|
1407
|
+
return this.setMachineProviderConfig(providerType, {
|
|
1408
|
+
args: value.trim() ? this.parseArgsSetting(value) : undefined,
|
|
1409
|
+
});
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1164
1412
|
const config = this.readConfig();
|
|
1165
1413
|
if (!config) return false;
|
|
1166
1414
|
|
|
1167
1415
|
try {
|
|
1168
1416
|
if (!config.providerSettings) config.providerSettings = {};
|
|
1169
|
-
if (!config.providerSettings[
|
|
1170
|
-
config.providerSettings[
|
|
1417
|
+
if (!config.providerSettings[providerType]) config.providerSettings[providerType] = {};
|
|
1418
|
+
config.providerSettings[providerType][key] = value;
|
|
1171
1419
|
this.writeConfig(config);
|
|
1172
|
-
this.log(`Setting updated: ${
|
|
1420
|
+
this.log(`Setting updated: ${providerType}.${key} = ${JSON.stringify(value)}`);
|
|
1173
1421
|
return true;
|
|
1174
1422
|
} catch (e) {
|
|
1175
1423
|
this.log(`Failed to save setting: ${(e as Error).message}`);
|
|
@@ -1237,6 +1485,16 @@ export class ProviderLoader {
|
|
|
1237
1485
|
private getSyntheticSettings(type: string, provider: ProviderModule): Record<string, ProviderSettingDef> {
|
|
1238
1486
|
const result: Record<string, ProviderSettingDef> = {};
|
|
1239
1487
|
|
|
1488
|
+
if (provider.category === 'cli' || provider.category === 'acp') {
|
|
1489
|
+
result.enabled = {
|
|
1490
|
+
type: 'boolean',
|
|
1491
|
+
default: false,
|
|
1492
|
+
public: true,
|
|
1493
|
+
label: 'Enabled on this machine',
|
|
1494
|
+
description: 'Opt in before ADHDev detects, launches, or verifies this provider on this machine.',
|
|
1495
|
+
};
|
|
1496
|
+
}
|
|
1497
|
+
|
|
1240
1498
|
if (!provider.settings?.autoApprove) {
|
|
1241
1499
|
result.autoApprove = {
|
|
1242
1500
|
type: 'boolean',
|
|
@@ -1257,6 +1515,16 @@ export class ProviderLoader {
|
|
|
1257
1515
|
};
|
|
1258
1516
|
}
|
|
1259
1517
|
|
|
1518
|
+
if ((provider.category === 'cli' || provider.category === 'acp') && provider.spawn?.command && !provider.settings?.executableArgs) {
|
|
1519
|
+
result.executableArgs = {
|
|
1520
|
+
type: 'string',
|
|
1521
|
+
default: '',
|
|
1522
|
+
public: true,
|
|
1523
|
+
label: 'Executable arguments',
|
|
1524
|
+
description: 'Optional replacement for provider default command arguments. Leave blank to use the provider default.',
|
|
1525
|
+
};
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1260
1528
|
if (provider.category === 'ide') {
|
|
1261
1529
|
if (provider.cli && !provider.settings?.cliPathOverride) {
|
|
1262
1530
|
result.cliPathOverride = {
|
package/src/shared-types.d.ts
CHANGED
|
@@ -240,6 +240,10 @@ export interface AvailableProviderInfo {
|
|
|
240
240
|
icon: string;
|
|
241
241
|
installed?: boolean;
|
|
242
242
|
detectedPath?: string | null;
|
|
243
|
+
/** Machine-local opt-in activation state. Undefined means older daemon payload. */
|
|
244
|
+
enabled?: boolean;
|
|
245
|
+
/** Machine-local readiness state for opt-in providers. */
|
|
246
|
+
machineStatus?: 'disabled' | 'enabled_unchecked' | 'not_detected' | 'detected';
|
|
243
247
|
}
|
|
244
248
|
/** ACP config option (model/mode/thought_level selection) */
|
|
245
249
|
export interface AcpConfigOption {
|
package/src/shared-types.ts
CHANGED
|
@@ -372,12 +372,31 @@ export interface CompactSessionEntry {
|
|
|
372
372
|
parentId: string | null;
|
|
373
373
|
providerType: string;
|
|
374
374
|
providerName: string;
|
|
375
|
+
providerSessionId?: string;
|
|
375
376
|
kind: SessionKind;
|
|
376
377
|
transport: SessionTransport;
|
|
377
378
|
status: SessionStatus;
|
|
378
379
|
title: string;
|
|
379
380
|
workspace: string | null;
|
|
380
381
|
cdpConnected?: boolean;
|
|
382
|
+
runtimeKey?: string;
|
|
383
|
+
runtimeDisplayName?: string;
|
|
384
|
+
runtimeWorkspaceLabel?: string;
|
|
385
|
+
runtimeWriteOwner?: RuntimeWriteOwner | null;
|
|
386
|
+
runtimeAttachedClients?: RuntimeAttachedClient[];
|
|
387
|
+
lastMessagePreview?: string;
|
|
388
|
+
lastMessageRole?: string;
|
|
389
|
+
lastMessageAt?: number;
|
|
390
|
+
lastMessageHash?: string;
|
|
391
|
+
lastUpdated?: number;
|
|
392
|
+
unread?: boolean;
|
|
393
|
+
lastSeenAt?: number;
|
|
394
|
+
inboxBucket?: RecentSessionBucket;
|
|
395
|
+
completionMarker?: string;
|
|
396
|
+
seenCompletionMarker?: string;
|
|
397
|
+
surfaceHidden?: boolean;
|
|
398
|
+
controlValues?: Record<string, string | number | boolean>;
|
|
399
|
+
providerControls?: ProviderControlSchema[];
|
|
381
400
|
summaryMetadata?: ProviderSummaryMetadata;
|
|
382
401
|
}
|
|
383
402
|
|
|
@@ -396,6 +415,23 @@ export interface AvailableProviderInfo {
|
|
|
396
415
|
icon: string;
|
|
397
416
|
installed?: boolean;
|
|
398
417
|
detectedPath?: string | null;
|
|
418
|
+
/** Machine-local opt-in activation state. Undefined means older daemon payload. */
|
|
419
|
+
enabled?: boolean;
|
|
420
|
+
/** Machine-local readiness state for opt-in providers. */
|
|
421
|
+
machineStatus?: 'disabled' | 'enabled_unchecked' | 'not_detected' | 'detected';
|
|
422
|
+
/** Last machine-local command detection/runnable check result. */
|
|
423
|
+
lastDetection?: MachineProviderCheckResult;
|
|
424
|
+
/** Last end-to-end ADHDev verification result, when available. */
|
|
425
|
+
lastVerification?: MachineProviderCheckResult;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
export interface MachineProviderCheckResult {
|
|
429
|
+
ok: boolean;
|
|
430
|
+
stage?: 'detection' | 'runnable' | 'verification';
|
|
431
|
+
checkedAt?: string;
|
|
432
|
+
message?: string;
|
|
433
|
+
command?: string;
|
|
434
|
+
path?: string | null;
|
|
399
435
|
}
|
|
400
436
|
|
|
401
437
|
/** ACP config option (model/mode/thought_level selection) */
|
package/src/status/snapshot.ts
CHANGED
|
@@ -45,6 +45,10 @@ export interface StatusSnapshotOptions {
|
|
|
45
45
|
category: 'ide' | 'extension' | 'cli' | 'acp';
|
|
46
46
|
installed?: boolean;
|
|
47
47
|
detectedPath?: string | null;
|
|
48
|
+
enabled?: boolean;
|
|
49
|
+
machineStatus?: 'disabled' | 'enabled_unchecked' | 'not_detected' | 'detected';
|
|
50
|
+
lastDetection?: AvailableProviderInfo['lastDetection'];
|
|
51
|
+
lastVerification?: AvailableProviderInfo['lastVerification'];
|
|
48
52
|
}>;
|
|
49
53
|
};
|
|
50
54
|
detectedIdes: Array<{
|
|
@@ -134,6 +138,10 @@ function buildAvailableProviders(
|
|
|
134
138
|
category: 'ide' | 'extension' | 'cli' | 'acp';
|
|
135
139
|
installed?: boolean;
|
|
136
140
|
detectedPath?: string | null;
|
|
141
|
+
enabled?: boolean;
|
|
142
|
+
machineStatus?: 'disabled' | 'enabled_unchecked' | 'not_detected' | 'detected';
|
|
143
|
+
lastDetection?: AvailableProviderInfo['lastDetection'];
|
|
144
|
+
lastVerification?: AvailableProviderInfo['lastVerification'];
|
|
137
145
|
}> = providerLoader.getAvailableProviderInfos?.() || providerLoader.getAll();
|
|
138
146
|
return providers.map((provider) => ({
|
|
139
147
|
type: provider.type,
|
|
@@ -143,6 +151,10 @@ function buildAvailableProviders(
|
|
|
143
151
|
category: provider.category,
|
|
144
152
|
...(provider.installed !== undefined ? { installed: provider.installed } : {}),
|
|
145
153
|
...(provider.detectedPath !== undefined ? { detectedPath: provider.detectedPath } : {}),
|
|
154
|
+
...(provider.enabled !== undefined ? { enabled: provider.enabled } : {}),
|
|
155
|
+
...(provider.machineStatus !== undefined ? { machineStatus: provider.machineStatus } : {}),
|
|
156
|
+
...(provider.lastDetection !== undefined ? { lastDetection: provider.lastDetection } : {}),
|
|
157
|
+
...(provider.lastVerification !== undefined ? { lastVerification: provider.lastVerification } : {}),
|
|
146
158
|
}));
|
|
147
159
|
}
|
|
148
160
|
|