@kaitranntt/ccs 7.45.0-dev.1 → 7.45.0-dev.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/dist/auth/profile-detector.d.ts +4 -1
  2. package/dist/auth/profile-detector.d.ts.map +1 -1
  3. package/dist/auth/profile-detector.js +3 -0
  4. package/dist/auth/profile-detector.js.map +1 -1
  5. package/dist/ccs.js +220 -49
  6. package/dist/ccs.js.map +1 -1
  7. package/dist/cliproxy/session-tracker.d.ts +6 -1
  8. package/dist/cliproxy/session-tracker.d.ts.map +1 -1
  9. package/dist/cliproxy/session-tracker.js +97 -36
  10. package/dist/cliproxy/session-tracker.js.map +1 -1
  11. package/dist/commands/help-command.d.ts.map +1 -1
  12. package/dist/commands/help-command.js +11 -0
  13. package/dist/commands/help-command.js.map +1 -1
  14. package/dist/config/unified-config-types.d.ts +7 -0
  15. package/dist/config/unified-config-types.d.ts.map +1 -1
  16. package/dist/config/unified-config-types.js.map +1 -1
  17. package/dist/targets/claude-adapter.d.ts +29 -0
  18. package/dist/targets/claude-adapter.d.ts.map +1 -0
  19. package/dist/targets/claude-adapter.js +121 -0
  20. package/dist/targets/claude-adapter.js.map +1 -0
  21. package/dist/targets/droid-adapter.d.ts +34 -0
  22. package/dist/targets/droid-adapter.d.ts.map +1 -0
  23. package/dist/targets/droid-adapter.js +164 -0
  24. package/dist/targets/droid-adapter.js.map +1 -0
  25. package/dist/targets/droid-config-manager.d.ts +33 -0
  26. package/dist/targets/droid-config-manager.d.ts.map +1 -0
  27. package/dist/targets/droid-config-manager.js +382 -0
  28. package/dist/targets/droid-config-manager.js.map +1 -0
  29. package/dist/targets/droid-detector.d.ts +25 -0
  30. package/dist/targets/droid-detector.d.ts.map +1 -0
  31. package/dist/targets/droid-detector.js +140 -0
  32. package/dist/targets/droid-detector.js.map +1 -0
  33. package/dist/targets/index.d.ts +14 -0
  34. package/dist/targets/index.d.ts.map +1 -0
  35. package/dist/targets/index.js +31 -0
  36. package/dist/targets/index.js.map +1 -0
  37. package/dist/targets/target-adapter.d.ts +83 -0
  38. package/dist/targets/target-adapter.d.ts.map +1 -0
  39. package/dist/targets/target-adapter.js +9 -0
  40. package/dist/targets/target-adapter.js.map +1 -0
  41. package/dist/targets/target-registry.d.ts +30 -0
  42. package/dist/targets/target-registry.d.ts.map +1 -0
  43. package/dist/targets/target-registry.js +53 -0
  44. package/dist/targets/target-registry.js.map +1 -0
  45. package/dist/targets/target-resolver.d.ts +26 -0
  46. package/dist/targets/target-resolver.d.ts.map +1 -0
  47. package/dist/targets/target-resolver.js +129 -0
  48. package/dist/targets/target-resolver.js.map +1 -0
  49. package/dist/types/index.d.ts +1 -0
  50. package/dist/types/index.d.ts.map +1 -1
  51. package/dist/types/profile.d.ts +5 -0
  52. package/dist/types/profile.d.ts.map +1 -0
  53. package/dist/types/profile.js +3 -0
  54. package/dist/types/profile.js.map +1 -0
  55. package/dist/ui/assets/{accounts-BHMeosy5.js → accounts-CZRsQ7sf.js} +1 -1
  56. package/dist/ui/assets/{alert-dialog-kdzRXnGY.js → alert-dialog-0P-Cx40p.js} +1 -1
  57. package/dist/ui/assets/{api-4enyrd8X.js → api-GdTYk_4c.js} +1 -1
  58. package/dist/ui/assets/{auth-section-w05GvJds.js → auth-section-6n7IpDyK.js} +1 -1
  59. package/dist/ui/assets/{backups-section-C1LXMLNc.js → backups-section-D6iXxy73.js} +1 -1
  60. package/dist/ui/assets/{cliproxy-DAfdY6CN.js → cliproxy-DieJ_NpI.js} +1 -1
  61. package/dist/ui/assets/{cliproxy-control-panel-R13dvwRB.js → cliproxy-control-panel-CmUsqsu4.js} +1 -1
  62. package/dist/ui/assets/{confirm-dialog-CCgn1mEJ.js → confirm-dialog-C-dTFKFS.js} +1 -1
  63. package/dist/ui/assets/{copilot-DIy8RqPs.js → copilot-C3yx1Yh0.js} +1 -1
  64. package/dist/ui/assets/{cursor-DHCd_Oaz.js → cursor-Dga5pVnr.js} +1 -1
  65. package/dist/ui/assets/{globalenv-section-cJrJW6g7.js → globalenv-section-BidNmC8a.js} +1 -1
  66. package/dist/ui/assets/{health-BV7tj4vW.js → health-BcOkZguS.js} +1 -1
  67. package/dist/ui/assets/{index-JybT8b0K.js → index-CKj40Sac.js} +1 -1
  68. package/dist/ui/assets/{index-D5m_H1db.js → index-CwKLhUDL.js} +1 -1
  69. package/dist/ui/assets/{index-DyBUxmQ5.js → index-DvUwAu3g.js} +1 -1
  70. package/dist/ui/assets/{index-T_lRIGPN.css → index-oaoLcjM3.css} +1 -1
  71. package/dist/ui/assets/{index-DuJCqdjs.js → index-pKax8tjI.js} +2 -2
  72. package/dist/ui/assets/{index-DzzXp8Z3.js → index-yd-b32qe.js} +1 -1
  73. package/dist/ui/assets/{proxy-status-widget-BIN7UlKC.js → proxy-status-widget-DTz6nMRE.js} +1 -1
  74. package/dist/ui/assets/{separator-B0ShCVSs.js → separator-sCZEoE44.js} +1 -1
  75. package/dist/ui/assets/{shared-D6GagpY8.js → shared-BPGoB5aD.js} +1 -1
  76. package/dist/ui/assets/{switch-C_3xIueO.js → switch-CUQi21op.js} +1 -1
  77. package/dist/ui/index.html +2 -2
  78. package/dist/utils/shell-executor.d.ts.map +1 -1
  79. package/dist/utils/shell-executor.js +32 -10
  80. package/dist/utils/shell-executor.js.map +1 -1
  81. package/dist/utils/signal-forwarder.d.ts +23 -0
  82. package/dist/utils/signal-forwarder.d.ts.map +1 -0
  83. package/dist/utils/signal-forwarder.js +70 -0
  84. package/dist/utils/signal-forwarder.js.map +1 -0
  85. package/dist/web-server/jsonl-parser.d.ts +1 -0
  86. package/dist/web-server/jsonl-parser.d.ts.map +1 -1
  87. package/dist/web-server/jsonl-parser.js +3 -0
  88. package/dist/web-server/jsonl-parser.js.map +1 -1
  89. package/dist/web-server/usage/data-aggregator.d.ts.map +1 -1
  90. package/dist/web-server/usage/data-aggregator.js +7 -1
  91. package/dist/web-server/usage/data-aggregator.js.map +1 -1
  92. package/dist/web-server/usage/handlers.d.ts.map +1 -1
  93. package/dist/web-server/usage/handlers.js +1 -0
  94. package/dist/web-server/usage/handlers.js.map +1 -1
  95. package/dist/web-server/usage/types.d.ts +2 -0
  96. package/dist/web-server/usage/types.d.ts.map +1 -1
  97. package/package.json +5 -2
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Droid Adapter
3
+ *
4
+ * TargetAdapter implementation for Factory Droid CLI.
5
+ * Writes credentials to ~/.factory/settings.json and spawns `droid -m custom:ccs-<profile>`.
6
+ */
7
+ /// <reference types="node" />
8
+ import { TargetAdapter, TargetBinaryInfo, TargetCredentials, TargetType } from './target-adapter';
9
+ import type { ProfileType } from '../types/profile';
10
+ export declare class DroidAdapter implements TargetAdapter {
11
+ readonly type: TargetType;
12
+ readonly displayName = "Factory Droid";
13
+ private validateCredentials;
14
+ detectBinary(): TargetBinaryInfo | null;
15
+ /**
16
+ * Write CCS credentials to ~/.factory/settings.json as a custom model entry.
17
+ * This is the key difference from Claude — Droid reads config files, not env vars.
18
+ */
19
+ prepareCredentials(creds: TargetCredentials): Promise<void>;
20
+ buildArgs(profile: string, userArgs: string[]): string[];
21
+ /**
22
+ * Droid uses config file for credentials — minimal env needed.
23
+ */
24
+ buildEnv(_creds: TargetCredentials, _profileType: ProfileType): NodeJS.ProcessEnv;
25
+ exec(args: string[], env: NodeJS.ProcessEnv, options?: {
26
+ cwd?: string;
27
+ binaryInfo?: TargetBinaryInfo;
28
+ }): void;
29
+ /**
30
+ * Droid currently supports direct settings-based and default flows only.
31
+ */
32
+ supportsProfileType(profileType: ProfileType): boolean;
33
+ }
34
+ //# sourceMappingURL=droid-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"droid-adapter.d.ts","sourceRoot":"","sources":["../../src/targets/droid-adapter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;;AAIH,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAElG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAKpD,qBAAa,YAAa,YAAW,aAAa;IAChD,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAW;IACpC,QAAQ,CAAC,WAAW,mBAAmB;IAEvC,OAAO,CAAC,mBAAmB;IAS3B,YAAY,IAAI,gBAAgB,GAAG,IAAI;IASvC;;;OAGG;IACG,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAWjE,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE;IAIxD;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,iBAAiB,EAAE,YAAY,EAAE,WAAW,GAAG,MAAM,CAAC,UAAU;IAIjF,IAAI,CACF,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,MAAM,CAAC,UAAU,EACtB,OAAO,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,gBAAgB,CAAA;KAAE,GACxD,IAAI;IA4EP;;OAEG;IACH,mBAAmB,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO;CAGvD"}
@@ -0,0 +1,164 @@
1
+ "use strict";
2
+ /**
3
+ * Droid Adapter
4
+ *
5
+ * TargetAdapter implementation for Factory Droid CLI.
6
+ * Writes credentials to ~/.factory/settings.json and spawns `droid -m custom:ccs-<profile>`.
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
21
+ }) : function(o, v) {
22
+ o["default"] = v;
23
+ });
24
+ var __importStar = (this && this.__importStar) || function (mod) {
25
+ if (mod && mod.__esModule) return mod;
26
+ var result = {};
27
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
28
+ __setModuleDefault(result, mod);
29
+ return result;
30
+ };
31
+ Object.defineProperty(exports, "__esModule", { value: true });
32
+ exports.DroidAdapter = void 0;
33
+ const child_process_1 = require("child_process");
34
+ const fs = __importStar(require("fs"));
35
+ const droid_detector_1 = require("./droid-detector");
36
+ const droid_config_manager_1 = require("./droid-config-manager");
37
+ const shell_executor_1 = require("../utils/shell-executor");
38
+ const signal_forwarder_1 = require("../utils/signal-forwarder");
39
+ class DroidAdapter {
40
+ constructor() {
41
+ this.type = 'droid';
42
+ this.displayName = 'Factory Droid';
43
+ }
44
+ validateCredentials(creds) {
45
+ if (!creds.baseUrl?.trim()) {
46
+ throw new Error('Droid target requires ANTHROPIC_BASE_URL');
47
+ }
48
+ if (!creds.apiKey?.trim()) {
49
+ throw new Error('Droid target requires ANTHROPIC_AUTH_TOKEN');
50
+ }
51
+ }
52
+ detectBinary() {
53
+ const info = (0, droid_detector_1.getDroidBinaryInfo)();
54
+ if (!info)
55
+ return null;
56
+ // Version compatibility check (non-blocking warning)
57
+ (0, droid_detector_1.checkDroidVersion)(info.path);
58
+ return info;
59
+ }
60
+ /**
61
+ * Write CCS credentials to ~/.factory/settings.json as a custom model entry.
62
+ * This is the key difference from Claude — Droid reads config files, not env vars.
63
+ */
64
+ async prepareCredentials(creds) {
65
+ this.validateCredentials(creds);
66
+ await (0, droid_config_manager_1.upsertCcsModel)(creds.profile, {
67
+ model: creds.model || 'claude-opus-4-6',
68
+ displayName: `CCS ${creds.profile}`,
69
+ baseUrl: creds.baseUrl,
70
+ apiKey: creds.apiKey,
71
+ provider: creds.provider || 'anthropic',
72
+ });
73
+ }
74
+ buildArgs(profile, userArgs) {
75
+ return ['-m', `custom:ccs-${profile}`, ...userArgs];
76
+ }
77
+ /**
78
+ * Droid uses config file for credentials — minimal env needed.
79
+ */
80
+ buildEnv(_creds, _profileType) {
81
+ return { ...process.env };
82
+ }
83
+ exec(args, env, options) {
84
+ const droidPath = options?.binaryInfo?.path || (0, droid_detector_1.detectDroidCli)();
85
+ if (!droidPath) {
86
+ console.error('[X] Droid CLI not found. Install: npm i -g @factory/cli');
87
+ process.exit(1);
88
+ return;
89
+ }
90
+ try {
91
+ const stat = fs.statSync(droidPath);
92
+ if (!stat.isFile()) {
93
+ console.error(`[X] Droid CLI path is not a file: ${droidPath}`);
94
+ process.exit(1);
95
+ return;
96
+ }
97
+ }
98
+ catch (err) {
99
+ const error = err;
100
+ console.error(`[X] Droid CLI path is not accessible (${error.code || 'unknown'}): ${droidPath}`);
101
+ process.exit(1);
102
+ return;
103
+ }
104
+ const isWindows = process.platform === 'win32';
105
+ const isPowerShellScript = isWindows && /\.ps1$/i.test(droidPath);
106
+ const needsShell = isWindows && /\.(cmd|bat)$/i.test(droidPath);
107
+ let child;
108
+ if (isPowerShellScript) {
109
+ child = (0, child_process_1.spawn)('powershell.exe', ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', droidPath, ...args], {
110
+ stdio: 'inherit',
111
+ windowsHide: true,
112
+ env,
113
+ });
114
+ }
115
+ else if (needsShell) {
116
+ const cmdString = [droidPath, ...args].map(shell_executor_1.escapeShellArg).join(' ');
117
+ child = (0, child_process_1.spawn)(cmdString, {
118
+ stdio: 'inherit',
119
+ windowsHide: true,
120
+ shell: true,
121
+ env,
122
+ });
123
+ }
124
+ else {
125
+ child = (0, child_process_1.spawn)(droidPath, args, {
126
+ stdio: 'inherit',
127
+ windowsHide: true,
128
+ env,
129
+ });
130
+ }
131
+ (0, signal_forwarder_1.wireChildProcessSignals)(child, (err) => {
132
+ if (err.code === 'EACCES') {
133
+ console.error(`[X] Droid CLI is not executable: ${droidPath}`);
134
+ console.error(' Check file permissions and executable bit.');
135
+ }
136
+ else if (err.code === 'ENOENT') {
137
+ if (isPowerShellScript) {
138
+ console.error('[X] PowerShell executable not found (required for .ps1 wrapper launch).');
139
+ console.error(' Ensure powershell.exe is available in PATH.');
140
+ }
141
+ else if (needsShell) {
142
+ console.error('[X] Windows command shell not found for Droid wrapper launch.');
143
+ console.error(' Ensure cmd.exe is available and accessible.');
144
+ }
145
+ else {
146
+ console.error(`[X] Droid CLI not found: ${droidPath}`);
147
+ console.error(' Install: npm i -g @factory/cli');
148
+ }
149
+ }
150
+ else {
151
+ console.error(`[X] Failed to start Droid CLI (${droidPath}):`, err.message);
152
+ }
153
+ process.exit(1);
154
+ });
155
+ }
156
+ /**
157
+ * Droid currently supports direct settings-based and default flows only.
158
+ */
159
+ supportsProfileType(profileType) {
160
+ return profileType === 'settings' || profileType === 'default';
161
+ }
162
+ }
163
+ exports.DroidAdapter = DroidAdapter;
164
+ //# sourceMappingURL=droid-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"droid-adapter.js","sourceRoot":"","sources":["../../src/targets/droid-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Droid Config Manager
3
+ *
4
+ * Read/write ~/.factory/settings.json safely.
5
+ * Only touches ccs-* prefixed entries in customModels[].
6
+ */
7
+ export interface DroidCustomModel {
8
+ model: string;
9
+ displayName: string;
10
+ baseUrl: string;
11
+ apiKey: string;
12
+ provider: 'anthropic' | 'openai' | 'generic-chat-completion-api';
13
+ maxOutputTokens?: number;
14
+ }
15
+ /**
16
+ * Upsert a CCS-managed custom model entry.
17
+ * Acquires file lock to prevent concurrent write races.
18
+ */
19
+ export declare function upsertCcsModel(profile: string, model: DroidCustomModel): Promise<void>;
20
+ /**
21
+ * Remove a CCS-managed custom model entry.
22
+ */
23
+ export declare function removeCcsModel(profile: string): Promise<void>;
24
+ /**
25
+ * List all CCS-managed custom model entries.
26
+ */
27
+ export declare function listCcsModels(): Promise<Map<string, DroidCustomModel>>;
28
+ /**
29
+ * Prune orphaned CCS entries from settings.json.
30
+ * Removes ccs-* entries whose profile no longer exists in active profiles.
31
+ */
32
+ export declare function pruneOrphanedModels(activeProfiles: string[]): Promise<number>;
33
+ //# sourceMappingURL=droid-config-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"droid-config-manager.d.ts","sourceRoot":"","sources":["../../src/targets/droid-config-manager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA+BH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,WAAW,GAAG,QAAQ,GAAG,6BAA6B,CAAC;IACjE,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAiQD;;;GAGG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+B5F;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBnE;AAED;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAe5E;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,cAAc,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAqCnF"}
@@ -0,0 +1,382 @@
1
+ "use strict";
2
+ /**
3
+ * Droid Config Manager
4
+ *
5
+ * Read/write ~/.factory/settings.json safely.
6
+ * Only touches ccs-* prefixed entries in customModels[].
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
21
+ }) : function(o, v) {
22
+ o["default"] = v;
23
+ });
24
+ var __importStar = (this && this.__importStar) || function (mod) {
25
+ if (mod && mod.__esModule) return mod;
26
+ var result = {};
27
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
28
+ __setModuleDefault(result, mod);
29
+ return result;
30
+ };
31
+ Object.defineProperty(exports, "__esModule", { value: true });
32
+ exports.pruneOrphanedModels = exports.listCcsModels = exports.removeCcsModel = exports.upsertCcsModel = void 0;
33
+ const fs = __importStar(require("fs"));
34
+ const path = __importStar(require("path"));
35
+ const os = __importStar(require("os"));
36
+ const lockfile = __importStar(require("proper-lockfile"));
37
+ const CCS_MODEL_PREFIX = 'ccs-';
38
+ const CCS_DISPLAY_PREFIX = 'CCS ';
39
+ /** Lock configuration for concurrent write safety */
40
+ const LOCK_STALE_MS = 10000;
41
+ const LOCK_RETRY_MIN_MS = 200;
42
+ const LOCK_RETRY_MAX_MS = 1000;
43
+ /**
44
+ * Validate profile name to prevent filesystem/security issues.
45
+ * Only alphanumeric, underscore, hyphen allowed.
46
+ */
47
+ function isValidProfileName(profile) {
48
+ return !!profile && /^[a-zA-Z0-9_-]+$/.test(profile);
49
+ }
50
+ function validateProfileName(profile) {
51
+ if (!isValidProfileName(profile)) {
52
+ throw new Error(`Invalid profile name "${profile}": must contain only alphanumeric characters, underscores, or hyphens`);
53
+ }
54
+ }
55
+ function isSupportedProvider(value) {
56
+ return value === 'anthropic' || value === 'openai' || value === 'generic-chat-completion-api';
57
+ }
58
+ function isDroidCustomModelEntry(value) {
59
+ if (!value || typeof value !== 'object')
60
+ return false;
61
+ const record = value;
62
+ return (typeof record.displayName === 'string' &&
63
+ record.displayName.trim() !== '' &&
64
+ typeof record.model === 'string' &&
65
+ typeof record.baseUrl === 'string' &&
66
+ typeof record.apiKey === 'string' &&
67
+ typeof record.provider === 'string' &&
68
+ record.provider.trim() !== '');
69
+ }
70
+ function isManagedDisplayName(displayName) {
71
+ return displayName.startsWith(CCS_DISPLAY_PREFIX) || displayName.startsWith(CCS_MODEL_PREFIX);
72
+ }
73
+ function parseManagedProfile(displayName) {
74
+ let profile = null;
75
+ if (displayName.startsWith(CCS_DISPLAY_PREFIX)) {
76
+ profile = displayName.slice(CCS_DISPLAY_PREFIX.length).trim();
77
+ }
78
+ else if (displayName.startsWith(CCS_MODEL_PREFIX)) {
79
+ profile = displayName.slice(CCS_MODEL_PREFIX.length).trim();
80
+ }
81
+ if (!profile || !isValidProfileName(profile))
82
+ return null;
83
+ return profile;
84
+ }
85
+ function asModelEntry(value) {
86
+ return isDroidCustomModelEntry(value) ? value : null;
87
+ }
88
+ function normalizeCustomModels(value) {
89
+ if (Array.isArray(value)) {
90
+ return value
91
+ .map((entry) => asModelEntry(entry))
92
+ .filter((entry) => !!entry);
93
+ }
94
+ // Accept legacy object-map shapes and normalize to array.
95
+ if (value && typeof value === 'object') {
96
+ return Object.values(value)
97
+ .map((entry) => asModelEntry(entry))
98
+ .filter((entry) => !!entry);
99
+ }
100
+ return [];
101
+ }
102
+ /**
103
+ * Get path to ~/.factory/settings.json.
104
+ * Respects CCS_HOME for test isolation (uses CCS_HOME/.factory/ in tests).
105
+ */
106
+ function getFactoryDir() {
107
+ const base = process.env.CCS_HOME || os.homedir();
108
+ return path.join(base, '.factory');
109
+ }
110
+ function getSettingsPath() {
111
+ return path.join(getFactoryDir(), 'settings.json');
112
+ }
113
+ /**
114
+ * Ensure ~/.factory/ directory exists.
115
+ */
116
+ function ensureFactoryDir() {
117
+ const dir = getFactoryDir();
118
+ try {
119
+ fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
120
+ }
121
+ catch (err) {
122
+ const error = err;
123
+ if (error.code !== 'EEXIST')
124
+ throw error;
125
+ }
126
+ }
127
+ function getNoFollowFlag() {
128
+ const candidate = fs.constants['O_NOFOLLOW'];
129
+ if (process.platform !== 'win32' && typeof candidate === 'number') {
130
+ return candidate;
131
+ }
132
+ return 0;
133
+ }
134
+ function openFileNoFollow(filePath, flags, mode) {
135
+ const safeFlags = flags | getNoFollowFlag();
136
+ if (mode === undefined) {
137
+ return fs.openSync(filePath, safeFlags);
138
+ }
139
+ return fs.openSync(filePath, safeFlags, mode);
140
+ }
141
+ function readFileUtf8NoFollow(filePath) {
142
+ const fd = openFileNoFollow(filePath, fs.constants.O_RDONLY);
143
+ try {
144
+ const stat = fs.fstatSync(fd);
145
+ if (!stat.isFile()) {
146
+ throw new Error('Refusing to read: settings.json is not a regular file');
147
+ }
148
+ return fs.readFileSync(fd, 'utf8');
149
+ }
150
+ finally {
151
+ fs.closeSync(fd);
152
+ }
153
+ }
154
+ /**
155
+ * Read ~/.factory/settings.json, creating empty structure if missing.
156
+ */
157
+ function readDroidSettings() {
158
+ const settingsPath = getSettingsPath();
159
+ if (!fs.existsSync(settingsPath)) {
160
+ return { customModels: [] };
161
+ }
162
+ const fileStat = fs.lstatSync(settingsPath);
163
+ if (fileStat.isSymbolicLink()) {
164
+ throw new Error('Refusing to read: settings.json is a symlink');
165
+ }
166
+ if (!fileStat.isFile()) {
167
+ throw new Error('Refusing to read: settings.json is not a regular file');
168
+ }
169
+ const raw = readFileUtf8NoFollow(settingsPath);
170
+ try {
171
+ const parsed = JSON.parse(raw);
172
+ return {
173
+ ...parsed,
174
+ customModels: normalizeCustomModels(parsed.customModels),
175
+ };
176
+ }
177
+ catch {
178
+ // Corrupted file — preserve as backup, start fresh
179
+ const backup = settingsPath + '.bak';
180
+ try {
181
+ fs.copyFileSync(settingsPath, backup);
182
+ fs.chmodSync(backup, 0o600); // Secure backup permissions
183
+ console.warn(`[!] Corrupted ${settingsPath}, backed up to ${backup}`);
184
+ }
185
+ catch (error) {
186
+ console.warn(`[!] Corrupted ${settingsPath}; backup failed: ${error.message}`);
187
+ }
188
+ return { customModels: [] };
189
+ }
190
+ }
191
+ async function acquireFactoryLock(retries) {
192
+ ensureFactoryDir();
193
+ const factoryDir = getFactoryDir();
194
+ try {
195
+ return await lockfile.lock(factoryDir, {
196
+ stale: LOCK_STALE_MS,
197
+ retries: { retries, minTimeout: LOCK_RETRY_MIN_MS, maxTimeout: LOCK_RETRY_MAX_MS },
198
+ });
199
+ }
200
+ catch (error) {
201
+ throw new Error(`Failed to lock Droid settings directory (${factoryDir}): ${error.message}`);
202
+ }
203
+ }
204
+ function fsyncDir(dirPath) {
205
+ try {
206
+ const dirFd = fs.openSync(dirPath, fs.constants.O_RDONLY);
207
+ try {
208
+ fs.fsyncSync(dirFd);
209
+ }
210
+ finally {
211
+ fs.closeSync(dirFd);
212
+ }
213
+ }
214
+ catch {
215
+ // Best-effort directory fsync (platform dependent).
216
+ }
217
+ }
218
+ /**
219
+ * Write ~/.factory/settings.json atomically with safe permissions.
220
+ * Uses temp file + rename for atomicity on same filesystem.
221
+ */
222
+ function writeDroidSettings(settings) {
223
+ ensureFactoryDir();
224
+ const settingsPath = getSettingsPath();
225
+ // Refuse to write if target is a symlink (prevents symlink attacks)
226
+ if (fs.existsSync(settingsPath)) {
227
+ const stat = fs.lstatSync(settingsPath);
228
+ if (stat.isSymbolicLink()) {
229
+ throw new Error('Refusing to write: settings.json is a symlink');
230
+ }
231
+ }
232
+ const tmpPath = settingsPath + '.tmp';
233
+ if (fs.existsSync(tmpPath)) {
234
+ const tmpStat = fs.lstatSync(tmpPath);
235
+ if (tmpStat.isSymbolicLink()) {
236
+ throw new Error('Refusing to write: settings.json.tmp is a symlink');
237
+ }
238
+ }
239
+ const payload = JSON.stringify({
240
+ ...settings,
241
+ customModels: normalizeCustomModels(settings.customModels),
242
+ }, null, 2);
243
+ const fd = openFileNoFollow(tmpPath, fs.constants.O_WRONLY | fs.constants.O_CREAT | fs.constants.O_TRUNC, 0o600);
244
+ try {
245
+ const tmpFdStat = fs.fstatSync(fd);
246
+ if (!tmpFdStat.isFile()) {
247
+ throw new Error('Refusing to write: settings.json.tmp is not a regular file');
248
+ }
249
+ fs.writeFileSync(fd, payload + '\n', { encoding: 'utf8' });
250
+ fs.fsyncSync(fd);
251
+ }
252
+ finally {
253
+ fs.closeSync(fd);
254
+ }
255
+ fs.renameSync(tmpPath, settingsPath);
256
+ fsyncDir(path.dirname(settingsPath));
257
+ // Fix permissions on existing file if world-readable
258
+ try {
259
+ const stat = fs.statSync(settingsPath);
260
+ if (stat.mode & 0o077) {
261
+ fs.chmodSync(settingsPath, 0o600);
262
+ console.warn('[!] Fixed permissions on ~/.factory/settings.json (was world-readable)');
263
+ }
264
+ }
265
+ catch {
266
+ // Best-effort permission check
267
+ }
268
+ }
269
+ /**
270
+ * Upsert a CCS-managed custom model entry.
271
+ * Acquires file lock to prevent concurrent write races.
272
+ */
273
+ async function upsertCcsModel(profile, model) {
274
+ validateProfileName(profile);
275
+ ensureFactoryDir();
276
+ let release;
277
+ try {
278
+ release = await acquireFactoryLock(10);
279
+ const settings = readDroidSettings();
280
+ settings.customModels = normalizeCustomModels(settings.customModels);
281
+ const entry = {
282
+ ...model,
283
+ displayName: `CCS ${profile}`,
284
+ };
285
+ // Find existing current or legacy entry for this profile.
286
+ const idx = settings.customModels.findIndex((m) => parseManagedProfile(m.displayName) === profile);
287
+ if (idx >= 0) {
288
+ settings.customModels[idx] = entry;
289
+ }
290
+ else {
291
+ settings.customModels.push(entry);
292
+ }
293
+ writeDroidSettings(settings);
294
+ }
295
+ finally {
296
+ if (release)
297
+ await release();
298
+ }
299
+ }
300
+ exports.upsertCcsModel = upsertCcsModel;
301
+ /**
302
+ * Remove a CCS-managed custom model entry.
303
+ */
304
+ async function removeCcsModel(profile) {
305
+ validateProfileName(profile);
306
+ ensureFactoryDir();
307
+ const settingsPath = getSettingsPath();
308
+ let release;
309
+ try {
310
+ release = await acquireFactoryLock(3);
311
+ if (!fs.existsSync(settingsPath))
312
+ return;
313
+ const settings = readDroidSettings();
314
+ settings.customModels = normalizeCustomModels(settings.customModels);
315
+ settings.customModels = settings.customModels.filter((m) => parseManagedProfile(m.displayName) !== profile);
316
+ writeDroidSettings(settings);
317
+ }
318
+ finally {
319
+ if (release)
320
+ await release();
321
+ }
322
+ }
323
+ exports.removeCcsModel = removeCcsModel;
324
+ /**
325
+ * List all CCS-managed custom model entries.
326
+ */
327
+ async function listCcsModels() {
328
+ const result = new Map();
329
+ const settings = readDroidSettings();
330
+ for (const entry of normalizeCustomModels(settings.customModels)) {
331
+ const profile = parseManagedProfile(entry.displayName);
332
+ if (!profile)
333
+ continue;
334
+ if (!isSupportedProvider(entry.provider))
335
+ continue;
336
+ result.set(profile, {
337
+ ...entry,
338
+ provider: entry.provider,
339
+ });
340
+ }
341
+ return result;
342
+ }
343
+ exports.listCcsModels = listCcsModels;
344
+ /**
345
+ * Prune orphaned CCS entries from settings.json.
346
+ * Removes ccs-* entries whose profile no longer exists in active profiles.
347
+ */
348
+ async function pruneOrphanedModels(activeProfiles) {
349
+ // Validate all profile names before pruning
350
+ activeProfiles.forEach((profile) => validateProfileName(profile));
351
+ ensureFactoryDir();
352
+ const settingsPath = getSettingsPath();
353
+ let release;
354
+ let removed = 0;
355
+ try {
356
+ release = await acquireFactoryLock(3);
357
+ if (!fs.existsSync(settingsPath))
358
+ return 0;
359
+ const settings = readDroidSettings();
360
+ settings.customModels = normalizeCustomModels(settings.customModels);
361
+ const before = settings.customModels.length;
362
+ settings.customModels = settings.customModels.filter((m) => {
363
+ const profile = parseManagedProfile(m.displayName);
364
+ if (profile) {
365
+ return activeProfiles.includes(profile);
366
+ }
367
+ // Drop malformed managed entries; keep user-managed entries.
368
+ return !isManagedDisplayName(m.displayName);
369
+ });
370
+ removed = before - settings.customModels.length;
371
+ if (removed > 0) {
372
+ writeDroidSettings(settings);
373
+ }
374
+ }
375
+ finally {
376
+ if (release)
377
+ await release();
378
+ }
379
+ return removed;
380
+ }
381
+ exports.pruneOrphanedModels = pruneOrphanedModels;
382
+ //# sourceMappingURL=droid-config-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"droid-config-manager.js","sourceRoot":"","sources":["../../src/targets/droid-config-manager.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,uCAAyB;AACzB,2CAA6B;AAC7B,uCAAyB;AACzB,0DAA4C;AAE5C,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAChC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAElC,qDAAqD;AACrD,MAAM,aAAa,GAAG,KAAK,CAAC;AAC5B,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAC9B,MAAM,iBAAiB,GAAG,IAAI,CAAC;AAE/B;;;GAGG;AACH,SAAS,kBAAkB,CAAC,OAAe;IACzC,OAAO,CAAC,CAAC,OAAO,IAAI,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACvD,CAAC;AAED,SAAS,mBAAmB,CAAC,OAAe;IAC1C,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CACb,yBAAyB,OAAO,uEAAuE,CACxG,CAAC;IACJ,CAAC;AACH,CAAC;AA0BD,SAAS,mBAAmB,CAAC,KAAa;IACxC,OAAO,KAAK,KAAK,WAAW,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,6BAA6B,CAAC;AAChG,CAAC;AAED,SAAS,uBAAuB,CAAC,KAAc;IAC7C,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACtD,MAAM,MAAM,GAAG,KAAgC,CAAC;IAChD,OAAO,CACL,OAAO,MAAM,CAAC,WAAW,KAAK,QAAQ;QACtC,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE;QAChC,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ;QAChC,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ;QAClC,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ;QACjC,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ;QACnC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,CAC9B,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAAC,WAAmB;IAC/C,OAAO,WAAW,CAAC,UAAU,CAAC,kBAAkB,CAAC,IAAI,WAAW,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;AAChG,CAAC;AAED,SAAS,mBAAmB,CAAC,WAAmB;IAC9C,IAAI,OAAO,GAAkB,IAAI,CAAC;IAElC,IAAI,WAAW,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC;QAC/C,OAAO,GAAG,WAAW,CAAC,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IAChE,CAAC;SAAM,IAAI,WAAW,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACpD,OAAO,GAAG,WAAW,CAAC,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9D,CAAC;IAED,IAAI,CAAC,OAAO,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1D,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,YAAY,CAAC,KAAc;IAClC,OAAO,uBAAuB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACvD,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAc;IAC3C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK;aACT,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;aACnC,MAAM,CAAC,CAAC,KAAK,EAAkC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAChE,CAAC;IAED,0DAA0D;IAC1D,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;aACxB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;aACnC,MAAM,CAAC,CAAC,KAAK,EAAkC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAChE,CAAC;IAED,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;GAGG;AACH,SAAS,aAAa;IACpB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;IAClD,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,eAAe;IACtB,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,eAAe,CAAC,CAAC;AACrD,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB;IACvB,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;IAC5B,IAAI,CAAC;QACH,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACtD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,KAAK,GAAG,GAA4B,CAAC;QAC3C,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ;YAAE,MAAM,KAAK,CAAC;IAC3C,CAAC;AACH,CAAC;AAED,SAAS,eAAe;IACtB,MAAM,SAAS,GAAI,EAAE,CAAC,SAAoC,CAAC,YAAY,CAAC,CAAC;IACzE,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;QAClE,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,gBAAgB,CAAC,QAAgB,EAAE,KAAa,EAAE,IAAa;IACtE,MAAM,SAAS,GAAG,KAAK,GAAG,eAAe,EAAE,CAAC;IAC5C,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,oBAAoB,CAAC,QAAgB;IAC5C,MAAM,EAAE,GAAG,gBAAgB,CAAC,QAAQ,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC7D,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;QAC3E,CAAC;QACD,OAAO,EAAE,CAAC,YAAY,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IACrC,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB;IACxB,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;IACvC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACjC,OAAO,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC;IAC9B,CAAC;IAED,MAAM,QAAQ,GAAG,EAAE,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IAC5C,IAAI,QAAQ,CAAC,cAAc,EAAE,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAC3E,CAAC;IAED,MAAM,GAAG,GAAG,oBAAoB,CAAC,YAAY,CAAC,CAAC;IAC/C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAkB,CAAC;QAChD,OAAO;YACL,GAAG,MAAM;YACT,YAAY,EAAE,qBAAqB,CAAE,MAAqC,CAAC,YAAY,CAAC;SACzF,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,mDAAmD;QACnD,MAAM,MAAM,GAAG,YAAY,GAAG,MAAM,CAAC;QACrC,IAAI,CAAC;YACH,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;YACtC,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,4BAA4B;YACzD,OAAO,CAAC,IAAI,CAAC,iBAAiB,YAAY,kBAAkB,MAAM,EAAE,CAAC,CAAC;QACxE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,iBAAiB,YAAY,oBAAqB,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5F,CAAC;QACD,OAAO,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC;IAC9B,CAAC;AACH,CAAC;AAED,KAAK,UAAU,kBAAkB,CAAC,OAAe;IAC/C,gBAAgB,EAAE,CAAC;IACnB,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IACnC,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE;YACrC,KAAK,EAAE,aAAa;YACpB,OAAO,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,UAAU,EAAE,iBAAiB,EAAE;SACnF,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,4CAA4C,UAAU,MAAO,KAAe,CAAC,OAAO,EAAE,CACvF,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,OAAe;IAC/B,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC1D,IAAI,CAAC;YACH,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;gBAAS,CAAC;YACT,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,oDAAoD;IACtD,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,kBAAkB,CAAC,QAAuB;IACjD,gBAAgB,EAAE,CAAC;IACnB,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;IAEvC,oEAAoE;IACpE,IAAI,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,EAAE,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACxC,IAAI,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,YAAY,GAAG,MAAM,CAAC;IACtC,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAC5B;QACE,GAAG,QAAQ;QACX,YAAY,EAAE,qBAAqB,CAAE,QAAuC,CAAC,YAAY,CAAC;KAC3F,EACD,IAAI,EACJ,CAAC,CACF,CAAC;IACF,MAAM,EAAE,GAAG,gBAAgB,CACzB,OAAO,EACP,EAAE,CAAC,SAAS,CAAC,QAAQ,GAAG,EAAE,CAAC,SAAS,CAAC,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC,OAAO,EACnE,KAAK,CACN,CAAC;IACF,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QACnC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;QAChF,CAAC;QACD,EAAE,CAAC,aAAa,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;QAC3D,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IACnB,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IACnB,CAAC;IACD,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IACrC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;IAErC,qDAAqD;IACrD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QAEvC,IAAI,IAAI,CAAC,IAAI,GAAG,KAAK,EAAE,CAAC;YACtB,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;YAClC,OAAO,CAAC,IAAI,CAAC,wEAAwE,CAAC,CAAC;QACzF,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,+BAA+B;IACjC,CAAC;AACH,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,cAAc,CAAC,OAAe,EAAE,KAAuB;IAC3E,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC7B,gBAAgB,EAAE,CAAC;IAEnB,IAAI,OAA0C,CAAC;IAC/C,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,kBAAkB,CAAC,EAAE,CAAC,CAAC;QAEvC,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAC;QACrC,QAAQ,CAAC,YAAY,GAAG,qBAAqB,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QAErE,MAAM,KAAK,GAA0B;YACnC,GAAG,KAAK;YACR,WAAW,EAAE,OAAO,OAAO,EAAE;SAC9B,CAAC;QAEF,0DAA0D;QAC1D,MAAM,GAAG,GAAG,QAAQ,CAAC,YAAY,CAAC,SAAS,CACzC,CAAC,CAAC,EAAE,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,OAAO,CACtD,CAAC;QAEF,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;YACb,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACrC,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC;QAED,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;YAAS,CAAC;QACT,IAAI,OAAO;YAAE,MAAM,OAAO,EAAE,CAAC;IAC/B,CAAC;AACH,CAAC;AA/BD,wCA+BC;AAED;;GAEG;AACI,KAAK,UAAU,cAAc,CAAC,OAAe;IAClD,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC7B,gBAAgB,EAAE,CAAC;IACnB,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;IAEvC,IAAI,OAA0C,CAAC;IAC/C,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,kBAAkB,CAAC,CAAC,CAAC,CAAC;QACtC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC;YAAE,OAAO;QAEzC,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAC;QACrC,QAAQ,CAAC,YAAY,GAAG,qBAAqB,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QAErE,QAAQ,CAAC,YAAY,GAAG,QAAQ,CAAC,YAAY,CAAC,MAAM,CAClD,CAAC,CAAC,EAAE,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,OAAO,CACtD,CAAC;QAEF,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;YAAS,CAAC;QACT,IAAI,OAAO;YAAE,MAAM,OAAO,EAAE,CAAC;IAC/B,CAAC;AACH,CAAC;AArBD,wCAqBC;AAED;;GAEG;AACI,KAAK,UAAU,aAAa;IACjC,MAAM,MAAM,GAAG,IAAI,GAAG,EAA4B,CAAC;IACnD,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAC;IACrC,KAAK,MAAM,KAAK,IAAI,qBAAqB,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QACjE,MAAM,OAAO,GAAG,mBAAmB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QACvD,IAAI,CAAC,OAAO;YAAE,SAAS;QACvB,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,QAAQ,CAAC;YAAE,SAAS;QAEnD,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE;YAClB,GAAG,KAAK;YACR,QAAQ,EAAE,KAAK,CAAC,QAAQ;SACzB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAfD,sCAeC;AAED;;;GAGG;AACI,KAAK,UAAU,mBAAmB,CAAC,cAAwB;IAChE,4CAA4C;IAC5C,cAAc,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC;IAElE,gBAAgB,EAAE,CAAC;IACnB,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;IAEvC,IAAI,OAA0C,CAAC;IAC/C,IAAI,OAAO,GAAG,CAAC,CAAC;IAEhB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,kBAAkB,CAAC,CAAC,CAAC,CAAC;QACtC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC;YAAE,OAAO,CAAC,CAAC;QAE3C,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAC;QACrC,QAAQ,CAAC,YAAY,GAAG,qBAAqB,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QAErE,MAAM,MAAM,GAAG,QAAQ,CAAC,YAAY,CAAC,MAAM,CAAC;QAC5C,QAAQ,CAAC,YAAY,GAAG,QAAQ,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;YACzD,MAAM,OAAO,GAAG,mBAAmB,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;YACnD,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC1C,CAAC;YAED,6DAA6D;YAC7D,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;QAEH,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC,YAAY,CAAC,MAAM,CAAC;QAChD,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;YAChB,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;YAAS,CAAC;QACT,IAAI,OAAO;YAAE,MAAM,OAAO,EAAE,CAAC;IAC/B,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AArCD,kDAqCC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Droid CLI Detector
3
+ *
4
+ * Detects Factory Droid CLI binary in PATH.
5
+ * Mirrors claude-detector.ts pattern.
6
+ */
7
+ import { TargetBinaryInfo } from './target-adapter';
8
+ /**
9
+ * Detect Droid CLI executable.
10
+ *
11
+ * Priority:
12
+ * 1. CCS_DROID_PATH env var (user override)
13
+ * 2. PATH lookup via which/where.exe
14
+ */
15
+ export declare function detectDroidCli(): string | null;
16
+ /**
17
+ * Get Droid CLI binary info for target adapter.
18
+ */
19
+ export declare function getDroidBinaryInfo(): TargetBinaryInfo | null;
20
+ /**
21
+ * Check Droid CLI version for compatibility warnings.
22
+ * Non-blocking — logs warning and continues.
23
+ */
24
+ export declare function checkDroidVersion(droidPath: string): void;
25
+ //# sourceMappingURL=droid-detector.d.ts.map