@kafca/agentdock 0.1.23 → 0.1.25
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/README.md +3 -0
- package/dist/renderer/assets/{Badge-C2K5apfV.js → Badge-Bn2h-Qkf.js} +1 -1
- package/dist/renderer/assets/{Chat-DI2YeVKb.js → Chat-Cgo9aneg.js} +1 -1
- package/dist/renderer/assets/{ChatMarkdown-DMAr15Oi.js → ChatMarkdown-CYzHfSiR.js} +1 -1
- package/dist/renderer/assets/{Config-7rP3EuUf.js → Config-DljB2-eP.js} +1 -1
- package/dist/renderer/assets/{CronList-81QslYE8.js → CronList-DeVbiY9a.js} +1 -1
- package/dist/renderer/assets/{Dashboard-Db2T7rSZ.js → Dashboard-fSqx5sm8.js} +2 -2
- package/dist/renderer/assets/{EmptyState-BBJ3cTvB.js → EmptyState-DgqKDwlq.js} +1 -1
- package/dist/renderer/assets/{KnowledgeDetail-Dz_6flG3.js → KnowledgeDetail-u8s2SmPV.js} +1 -1
- package/dist/renderer/assets/{KnowledgeHome-DIh046mN.js → KnowledgeHome-BdQw8nbY.js} +1 -1
- package/dist/renderer/assets/{Logs-BXBtHJLf.js → Logs-DSbndMpy.js} +1 -1
- package/dist/renderer/assets/{Modal-BB2Av_Xs.js → Modal-0d0EmAuK.js} +1 -1
- package/dist/renderer/assets/{Page-DPSdvMgU.js → Page-CVbOH_Kh.js} +1 -1
- package/dist/renderer/assets/{ProjectDetail-C6EWGvGg.js → ProjectDetail-C91tF7uA.js} +1 -1
- package/dist/renderer/assets/{ProjectList-BBo5ygnS.js → ProjectList-D78Pc-BQ.js} +1 -1
- package/dist/renderer/assets/{Select-CNX-Tx_O.js → Select-BbKzAIuO.js} +1 -1
- package/dist/renderer/assets/{SessionChat-BIn46jqZ.js → SessionChat-BERvL5e4.js} +1 -1
- package/dist/renderer/assets/{SessionList-CZt6f1Rd.js → SessionList-Bomz335M.js} +1 -1
- package/dist/renderer/assets/ThreadChat-CLr3amU2.js +23 -0
- package/dist/renderer/assets/{Workspace-C_4tdpjX.js → Workspace-In91z4W2.js} +1 -1
- package/dist/renderer/assets/{arrow-left-cHr5wkpq.js → arrow-left-FBnVKKBl.js} +1 -1
- package/dist/renderer/assets/{book-open-4nx5C8T-.js → book-open-4_CuP6Sa.js} +1 -1
- package/dist/renderer/assets/{check-exTS-R-x.js → check-vsoVjvac.js} +1 -1
- package/dist/renderer/assets/{chevron-down-DSvxXQa0.js → chevron-down-DFpmFTJW.js} +1 -1
- package/dist/renderer/assets/{circle-DyvEovdw.js → circle-vRULegER.js} +1 -1
- package/dist/renderer/assets/desktop-BkMW-h5p.js +4 -0
- package/dist/renderer/assets/{desktop-B-KVT10D.js → desktop-ul0Tpzyc.js} +1 -1
- package/dist/renderer/assets/{funnel-DA9qVdTy.js → funnel-Gu0E_hJ_.js} +1 -1
- package/dist/renderer/assets/{heart-DuEV0ZRJ.js → heart-DsdofOHf.js} +1 -1
- package/dist/renderer/assets/{index-Biz-aexG.js → index-BD3aCyBa.js} +3 -3
- package/dist/renderer/assets/{index-BgflqkCN.js → index-pJUFobU7.js} +1 -1
- package/dist/renderer/assets/{pencil-DBDxeNmO.js → pencil-DbKmV8nD.js} +1 -1
- package/dist/renderer/assets/{play-IzlP83_7.js → play-BDMsRxSm.js} +1 -1
- package/dist/renderer/assets/{plug-CuT-qFnW.js → plug-t2dMl78-.js} +1 -1
- package/dist/renderer/assets/{plus-DEqgkn63.js → plus-BUb6zOAe.js} +1 -1
- package/dist/renderer/assets/projects-4F6D_Q8t.js +1 -0
- package/dist/renderer/assets/{save-D4sRo07y.js → save-C-_5rQdv.js} +1 -1
- package/dist/renderer/assets/{search-DbPZLuV8.js → search-R3ekHFPM.js} +1 -1
- package/dist/renderer/assets/{server-D1jUQmwN.js → server-BTuvHf5n.js} +1 -1
- package/dist/renderer/assets/{session-utils-Aife8ep2.js → session-utils-ClX6VPFG.js} +1 -1
- package/dist/renderer/assets/{sessions-DaH3H7gC.js → sessions-AFKIC-ub.js} +1 -1
- package/dist/renderer/assets/{shield-check-BGwUFWNr.js → shield-check-CqMW8CHe.js} +1 -1
- package/dist/renderer/assets/{trash-2-CIFBioBa.js → trash-2-BNLcHyUw.js} +1 -1
- package/dist/renderer/assets/{user-CnKcvHdo.js → user-BCCN8FYK.js} +1 -1
- package/dist/renderer/assets/{wifi-off-ClO53WGa.js → wifi-off-BsNsx3oX.js} +1 -1
- package/dist/renderer/index.html +1 -1
- package/dist-electron/electron/agent-runtime-detector.test.js +64 -0
- package/dist-electron/electron/architecture-docs.test.js +56 -0
- package/dist-electron/electron/channel-content.test.js +37 -0
- package/dist-electron/electron/lac-cli.test.js +297 -4
- package/dist-electron/electron/local-core-acp-content.test.js +39 -0
- package/dist-electron/electron/local-core-contracts.test.js +67 -0
- package/dist-electron/electron/local-core-refactor.test.js +789 -3
- package/dist-electron/electron/plugin-kernel.test.js +108 -0
- package/dist-electron/electron/renderer-packaging.test.js +77 -0
- package/dist-electron/electron/workspace-task-store.test.js +181 -0
- package/dist-electron/packages/contracts/src/local-core.js +110 -0
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-backend.js +67 -6
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-content.js +25 -4
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-permission-lifecycle.js +76 -0
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-progress.js +201 -0
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-response-processor.js +3 -2
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-session-coordinator.js +29 -0
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-store.js +74 -46
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-turn-coordinator.js +112 -210
- package/dist-electron/services/local-ai-core/src/acp/local-core-slash-commands.js +60 -0
- package/dist-electron/services/local-ai-core/src/acp/workspace-acp-permissions.js +5 -48
- package/dist-electron/services/local-ai-core/src/channel/lark/local-core-lark-gateway.js +83 -28
- package/dist-electron/services/local-ai-core/src/channel/lark/runtime-state.js +11 -0
- package/dist-electron/services/local-ai-core/src/channel/shared/content.js +23 -0
- package/dist-electron/services/local-ai-core/src/channel/shared/file-utils.js +13 -1
- package/dist-electron/services/local-ai-core/src/channel/weixin/local-core-weixin-gateway.js +31 -29
- package/dist-electron/services/local-ai-core/src/cli/lac.js +22 -17
- package/dist-electron/services/local-ai-core/src/kernel/bootstrap.js +1 -0
- package/dist-electron/services/local-ai-core/src/plugins/builtin/agent-localcore-acp-plugin.js +9 -0
- package/dist-electron/services/local-ai-core/src/router/workspace-route-config.js +221 -10
- package/dist-electron/services/local-ai-core/src/runtime/agent-runtime-detector.js +39 -9
- package/dist-electron/services/local-ai-core/src/runtime/local-core-controller.js +1 -0
- package/dist-electron/services/local-ai-core/src/runtime/runtime-detection-service.js +1 -0
- package/dist-electron/services/local-ai-core/src/runtime/server-routes.js +439 -0
- package/dist-electron/services/local-ai-core/src/runtime/server.js +208 -303
- package/dist-electron/services/local-ai-core/src/scheduler/job-id.js +15 -0
- package/dist-electron/services/local-ai-core/src/scheduler/scheduler-service.js +30 -5
- package/dist-electron/shared/desktop.js +34 -8
- package/dist-electron/src/pages/Threads/thread-chat-message-blocks.js +187 -0
- package/dist-electron/src/pages/Threads/thread-chat-model.js +58 -0
- package/dist-electron/src/pages/Threads/thread-chat-page-state.js +96 -0
- package/dist-electron/src/pages/Threads/thread-chat-permission.js +18 -0
- package/dist-electron/src/pages/Threads/thread-chat-permission.test.js +347 -0
- package/package.json +4 -2
- package/dist/renderer/assets/ThreadChat-BotD0gKQ.js +0 -23
- package/dist/renderer/assets/desktop-CVibRyAw.js +0 -4
- package/dist/renderer/assets/projects-DDtDN1rc.js +0 -1
|
@@ -4,6 +4,7 @@ exports.normalizePlatformTypes = normalizePlatformTypes;
|
|
|
4
4
|
exports.isLocalCoreNativeAcpProject = isLocalCoreNativeAcpProject;
|
|
5
5
|
exports.toLocalCoreProjectConfig = toLocalCoreProjectConfig;
|
|
6
6
|
const node_module_1 = require("node:module");
|
|
7
|
+
const node_fs_1 = require("node:fs");
|
|
7
8
|
const node_path_1 = require("node:path");
|
|
8
9
|
const desktop_js_1 = require("../../../../shared/desktop.js");
|
|
9
10
|
function normalizePlatformTypes(project) {
|
|
@@ -17,10 +18,13 @@ function isLocalCoreNativeAcpProject(project) {
|
|
|
17
18
|
|| agentType === 'acp'
|
|
18
19
|
|| agentType === desktop_js_1.LOCALCORE_ACP_AGENT_TYPE;
|
|
19
20
|
}
|
|
20
|
-
function
|
|
21
|
+
function resolveAgentModel(project, providers) {
|
|
21
22
|
const agentType = String(project.agent?.type || '').trim().toLowerCase();
|
|
22
23
|
const rawModel = String(project.agent?.options?.model || '').trim();
|
|
23
24
|
const normalizedModel = (0, desktop_js_1.normalizeDesktopAgentModel)(agentType, rawModel);
|
|
25
|
+
if (agentType === 'pi') {
|
|
26
|
+
return rawModel || getFirstProviderModelId(providers);
|
|
27
|
+
}
|
|
24
28
|
if (agentType !== 'opencode') {
|
|
25
29
|
return normalizedModel;
|
|
26
30
|
}
|
|
@@ -31,6 +35,15 @@ function resolveOpencodeModel(project, providers) {
|
|
|
31
35
|
}
|
|
32
36
|
return normalizedModel;
|
|
33
37
|
}
|
|
38
|
+
function getFirstProviderModelId(providers) {
|
|
39
|
+
for (const provider of providers) {
|
|
40
|
+
const modelId = getProviderDefaultModelId(provider);
|
|
41
|
+
if (modelId) {
|
|
42
|
+
return modelId;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return '';
|
|
46
|
+
}
|
|
34
47
|
function getFirstProviderModelRef(providers) {
|
|
35
48
|
for (const provider of providers) {
|
|
36
49
|
const providerId = normalizeOpencodeProviderId(provider.name);
|
|
@@ -131,6 +144,108 @@ function collectProviderEnv(providers) {
|
|
|
131
144
|
}
|
|
132
145
|
return env;
|
|
133
146
|
}
|
|
147
|
+
function collectPiProviderEnv(providers) {
|
|
148
|
+
const env = {};
|
|
149
|
+
for (const provider of providers) {
|
|
150
|
+
const apiKey = String(provider.api_key || '').trim();
|
|
151
|
+
const envName = piProviderApiKeyEnvName(provider.name);
|
|
152
|
+
if (apiKey && envName) {
|
|
153
|
+
env[envName] = apiKey;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return env;
|
|
157
|
+
}
|
|
158
|
+
function resolvePiProviderModel(providers, model) {
|
|
159
|
+
const [explicitProvider, explicitModel] = splitProviderModelRef(model);
|
|
160
|
+
if (explicitProvider && explicitModel) {
|
|
161
|
+
return {
|
|
162
|
+
providerId: normalizePiProviderId(explicitProvider),
|
|
163
|
+
modelId: explicitModel,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
for (const provider of providers) {
|
|
167
|
+
const providerId = normalizePiProviderId(provider.name);
|
|
168
|
+
const modelId = getProviderDefaultModelId(provider);
|
|
169
|
+
if (providerId && modelId && (!model || model === modelId)) {
|
|
170
|
+
return { providerId, modelId };
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
const fallbackProvider = providers.find((provider) => normalizePiProviderId(provider.name));
|
|
174
|
+
return {
|
|
175
|
+
providerId: normalizePiProviderId(fallbackProvider?.name),
|
|
176
|
+
modelId: model,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
function splitProviderModelRef(value) {
|
|
180
|
+
const trimmed = value.trim();
|
|
181
|
+
const slashIndex = trimmed.indexOf('/');
|
|
182
|
+
if (slashIndex <= 0 || slashIndex >= trimmed.length - 1) {
|
|
183
|
+
return ['', trimmed];
|
|
184
|
+
}
|
|
185
|
+
return [trimmed.slice(0, slashIndex), trimmed.slice(slashIndex + 1)];
|
|
186
|
+
}
|
|
187
|
+
function normalizePiProviderId(providerName) {
|
|
188
|
+
const providerId = normalizeProviderId(providerName);
|
|
189
|
+
const aliases = {
|
|
190
|
+
google: 'google',
|
|
191
|
+
gemini: 'google',
|
|
192
|
+
kimi: 'kimi-coding',
|
|
193
|
+
moonshot: 'moonshotai',
|
|
194
|
+
zhipuai: 'zai',
|
|
195
|
+
};
|
|
196
|
+
return aliases[providerId] || providerId;
|
|
197
|
+
}
|
|
198
|
+
function piProviderAgentDir(configState, projectName) {
|
|
199
|
+
const configDir = (0, node_path_1.dirname)(configState.path);
|
|
200
|
+
const safeProjectName = String(projectName || 'workspace')
|
|
201
|
+
.trim()
|
|
202
|
+
.replace(/[^a-zA-Z0-9._-]+/g, '-')
|
|
203
|
+
.replace(/^-+|-+$/g, '') || 'workspace';
|
|
204
|
+
return (0, node_path_1.resolve)(configDir, '.pi-agent', safeProjectName);
|
|
205
|
+
}
|
|
206
|
+
function writeJsonFile(path, value, mode = 0o600) {
|
|
207
|
+
(0, node_fs_1.writeFileSync)(path, `${JSON.stringify(value, null, 2)}\n`, { encoding: 'utf8', mode });
|
|
208
|
+
(0, node_fs_1.chmodSync)(path, mode);
|
|
209
|
+
}
|
|
210
|
+
function writePiProviderRuntimeConfig(configState, project, providers, model) {
|
|
211
|
+
if (providers.length === 0) {
|
|
212
|
+
return {};
|
|
213
|
+
}
|
|
214
|
+
const { providerId, modelId } = resolvePiProviderModel(providers, model);
|
|
215
|
+
const agentDir = piProviderAgentDir(configState, project.name);
|
|
216
|
+
(0, node_fs_1.mkdirSync)(agentDir, { recursive: true, mode: 0o700 });
|
|
217
|
+
(0, node_fs_1.chmodSync)(agentDir, 0o700);
|
|
218
|
+
const auth = {};
|
|
219
|
+
const modelProviders = {};
|
|
220
|
+
for (const provider of providers) {
|
|
221
|
+
const id = normalizePiProviderId(provider.name);
|
|
222
|
+
if (!id) {
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
const apiKey = String(provider.api_key || '').trim();
|
|
226
|
+
const baseUrl = String(provider.base_url || '').trim();
|
|
227
|
+
if (apiKey) {
|
|
228
|
+
auth[id] = { type: 'api_key', key: apiKey };
|
|
229
|
+
}
|
|
230
|
+
if (baseUrl || apiKey) {
|
|
231
|
+
modelProviders[id] = {
|
|
232
|
+
name: String(provider.name || id).trim() || id,
|
|
233
|
+
...(baseUrl ? { baseUrl } : {}),
|
|
234
|
+
...(apiKey ? { apiKey } : {}),
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
writeJsonFile((0, node_path_1.resolve)(agentDir, 'auth.json'), auth);
|
|
239
|
+
writeJsonFile((0, node_path_1.resolve)(agentDir, 'models.json'), { providers: modelProviders });
|
|
240
|
+
writeJsonFile((0, node_path_1.resolve)(agentDir, 'settings.json'), {
|
|
241
|
+
...(providerId ? { defaultProvider: providerId } : {}),
|
|
242
|
+
...(modelId ? { defaultModel: modelId } : {}),
|
|
243
|
+
quietStartup: true,
|
|
244
|
+
}, 0o644);
|
|
245
|
+
return {
|
|
246
|
+
PI_CODING_AGENT_DIR: agentDir,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
134
249
|
function normalizeOpencodeProviderId(value) {
|
|
135
250
|
return String(value || '')
|
|
136
251
|
.trim()
|
|
@@ -138,6 +253,48 @@ function normalizeOpencodeProviderId(value) {
|
|
|
138
253
|
.replace(/[^a-z0-9._-]+/g, '-')
|
|
139
254
|
.replace(/^-+|-+$/g, '');
|
|
140
255
|
}
|
|
256
|
+
function normalizeProviderId(value) {
|
|
257
|
+
return String(value || '')
|
|
258
|
+
.trim()
|
|
259
|
+
.toLowerCase()
|
|
260
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
261
|
+
.replace(/^-+|-+$/g, '');
|
|
262
|
+
}
|
|
263
|
+
function piProviderApiKeyEnvName(providerName) {
|
|
264
|
+
const providerId = normalizeProviderId(providerName);
|
|
265
|
+
const envNames = {
|
|
266
|
+
anthropic: 'ANTHROPIC_API_KEY',
|
|
267
|
+
'azure-openai': 'AZURE_OPENAI_API_KEY',
|
|
268
|
+
'azure-openai-responses': 'AZURE_OPENAI_API_KEY',
|
|
269
|
+
cerebras: 'CEREBRAS_API_KEY',
|
|
270
|
+
cloudflare: 'CLOUDFLARE_API_KEY',
|
|
271
|
+
'cloudflare-ai-gateway': 'CLOUDFLARE_API_KEY',
|
|
272
|
+
'cloudflare-workers-ai': 'CLOUDFLARE_API_KEY',
|
|
273
|
+
deepseek: 'DEEPSEEK_API_KEY',
|
|
274
|
+
fireworks: 'FIREWORKS_API_KEY',
|
|
275
|
+
gemini: 'GEMINI_API_KEY',
|
|
276
|
+
google: 'GEMINI_API_KEY',
|
|
277
|
+
groq: 'GROQ_API_KEY',
|
|
278
|
+
huggingface: 'HF_TOKEN',
|
|
279
|
+
kimi: 'KIMI_API_KEY',
|
|
280
|
+
'kimi-coding': 'KIMI_API_KEY',
|
|
281
|
+
minimax: 'MINIMAX_API_KEY',
|
|
282
|
+
'minimax-cn': 'MINIMAX_CN_API_KEY',
|
|
283
|
+
mistral: 'MISTRAL_API_KEY',
|
|
284
|
+
moonshot: 'KIMI_API_KEY',
|
|
285
|
+
openai: 'OPENAI_API_KEY',
|
|
286
|
+
opencode: 'OPENCODE_API_KEY',
|
|
287
|
+
'opencode-go': 'OPENCODE_API_KEY',
|
|
288
|
+
openrouter: 'OPENROUTER_API_KEY',
|
|
289
|
+
siliconflow: 'SILICONFLOW_API_KEY',
|
|
290
|
+
vercel: 'AI_GATEWAY_API_KEY',
|
|
291
|
+
'vercel-ai-gateway': 'AI_GATEWAY_API_KEY',
|
|
292
|
+
xai: 'XAI_API_KEY',
|
|
293
|
+
zai: 'ZAI_API_KEY',
|
|
294
|
+
zhipuai: 'ZAI_API_KEY',
|
|
295
|
+
};
|
|
296
|
+
return envNames[providerId] || '';
|
|
297
|
+
}
|
|
141
298
|
function opencodeProviderApiKeyEnvName(providerId) {
|
|
142
299
|
const suffix = providerId.toUpperCase().replace(/[^A-Z0-9]+/g, '_').replace(/^_+|_+$/g, '');
|
|
143
300
|
return `AI_WORKSTATION_OPENCODE_${suffix || 'PROVIDER'}_API_KEY`;
|
|
@@ -152,7 +309,7 @@ function shouldUseOpenAiCompatibleProvider(providerId) {
|
|
|
152
309
|
}
|
|
153
310
|
function resolveBundledAcpCommand(packageName, binName) {
|
|
154
311
|
const require = (0, node_module_1.createRequire)(__filename);
|
|
155
|
-
const packageJsonPath =
|
|
312
|
+
const packageJsonPath = resolveBundledPackageJsonPath(packageName);
|
|
156
313
|
const packageJson = require(packageJsonPath);
|
|
157
314
|
const binField = packageJson.bin;
|
|
158
315
|
const relativeBinPath = typeof binField === 'string'
|
|
@@ -166,12 +323,44 @@ function resolveBundledAcpCommand(packageName, binName) {
|
|
|
166
323
|
args: [(0, node_path_1.resolve)((0, node_path_1.dirname)(packageJsonPath), relativeBinPath)],
|
|
167
324
|
};
|
|
168
325
|
}
|
|
326
|
+
function resolveBundledPackageJsonPath(packageName) {
|
|
327
|
+
const require = (0, node_module_1.createRequire)(__filename);
|
|
328
|
+
try {
|
|
329
|
+
return require.resolve(`${packageName}/package.json`);
|
|
330
|
+
}
|
|
331
|
+
catch (error) {
|
|
332
|
+
if (error?.code !== 'ERR_PACKAGE_PATH_NOT_EXPORTED') {
|
|
333
|
+
throw error;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
for (const basePath of require.resolve.paths(packageName) || []) {
|
|
337
|
+
const packageJsonPath = (0, node_path_1.resolve)(basePath, ...packageName.split('/'), 'package.json');
|
|
338
|
+
if ((0, node_fs_1.existsSync)(packageJsonPath)) {
|
|
339
|
+
return packageJsonPath;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
let current = (0, node_path_1.dirname)(require.resolve(packageName));
|
|
343
|
+
while (current && current !== (0, node_path_1.dirname)(current)) {
|
|
344
|
+
const packageJsonPath = (0, node_path_1.resolve)(current, 'package.json');
|
|
345
|
+
if ((0, node_fs_1.existsSync)(packageJsonPath)) {
|
|
346
|
+
return packageJsonPath;
|
|
347
|
+
}
|
|
348
|
+
current = (0, node_path_1.dirname)(current);
|
|
349
|
+
}
|
|
350
|
+
throw new Error(`Bundled package "${packageName}" package.json could not be resolved.`);
|
|
351
|
+
}
|
|
169
352
|
function resolveBundledCodexCommand() {
|
|
170
353
|
return resolveBundledAcpCommand(desktop_js_1.DESKTOP_CODEX_ACP_PACKAGE, 'codex-acp');
|
|
171
354
|
}
|
|
172
355
|
function resolveBundledClaudeCodeCommand() {
|
|
173
356
|
return resolveBundledAcpCommand(desktop_js_1.DESKTOP_CLAUDECODE_ACP_PACKAGE, 'claude-agent-acp');
|
|
174
357
|
}
|
|
358
|
+
function resolveBundledPiAcpCommand() {
|
|
359
|
+
return resolveBundledAcpCommand(desktop_js_1.DESKTOP_PI_ACP_PACKAGE, 'pi-acp');
|
|
360
|
+
}
|
|
361
|
+
function resolveBundledPiCommand() {
|
|
362
|
+
return resolveBundledAcpCommand(desktop_js_1.DESKTOP_PI_CODING_AGENT_PACKAGE, 'pi').args[0];
|
|
363
|
+
}
|
|
175
364
|
function toLocalCoreProjectConfig(configState, project) {
|
|
176
365
|
const rawWorkDir = String(project.agent?.options?.work_dir || '.').trim() || '.';
|
|
177
366
|
const configDir = (0, node_path_1.dirname)(configState.path);
|
|
@@ -188,8 +377,11 @@ function toLocalCoreProjectConfig(configState, project) {
|
|
|
188
377
|
: {};
|
|
189
378
|
const agentType = String(project.agent?.type || '').trim().toLowerCase();
|
|
190
379
|
const providers = Array.isArray(project.agent?.providers) ? project.agent.providers : [];
|
|
191
|
-
const model =
|
|
380
|
+
const model = resolveAgentModel(project, providers);
|
|
192
381
|
const providerEnv = collectProviderEnv(providers);
|
|
382
|
+
const piProviderEnv = agentType === 'pi'
|
|
383
|
+
? collectPiProviderEnv(providers)
|
|
384
|
+
: {};
|
|
193
385
|
const opencodeInlineConfig = agentType === 'opencode'
|
|
194
386
|
? buildOpencodeInlineConfig(model, providers)
|
|
195
387
|
: null;
|
|
@@ -204,6 +396,22 @@ function toLocalCoreProjectConfig(configState, project) {
|
|
|
204
396
|
ANTHROPIC_MODEL: model,
|
|
205
397
|
}
|
|
206
398
|
: {};
|
|
399
|
+
const bundledPiAcp = agentType === 'pi'
|
|
400
|
+
? resolveBundledPiAcpCommand()
|
|
401
|
+
: null;
|
|
402
|
+
const bundledPiCommand = agentType === 'pi'
|
|
403
|
+
? resolveBundledPiCommand()
|
|
404
|
+
: '';
|
|
405
|
+
const piProviderRuntimeEnv = agentType === 'pi'
|
|
406
|
+
? writePiProviderRuntimeConfig(configState, project, providers, model)
|
|
407
|
+
: {};
|
|
408
|
+
const inferredPiEnv = agentType === 'pi'
|
|
409
|
+
? {
|
|
410
|
+
...piProviderEnv,
|
|
411
|
+
...piProviderRuntimeEnv,
|
|
412
|
+
PI_ACP_PI_COMMAND: bundledPiCommand,
|
|
413
|
+
}
|
|
414
|
+
: {};
|
|
207
415
|
const bundledCodex = agentType === 'codex'
|
|
208
416
|
? resolveBundledCodexCommand()
|
|
209
417
|
: null;
|
|
@@ -212,18 +420,20 @@ function toLocalCoreProjectConfig(configState, project) {
|
|
|
212
420
|
: null;
|
|
213
421
|
const inferredCommand = agentType === 'opencode'
|
|
214
422
|
? 'opencode'
|
|
215
|
-
: bundledCodex?.command || bundledClaudeCode?.command || '';
|
|
423
|
+
: bundledPiAcp?.command || bundledCodex?.command || bundledClaudeCode?.command || '';
|
|
216
424
|
const command = String(project.agent?.options?.command || inferredCommand).trim();
|
|
217
425
|
if (!command) {
|
|
218
426
|
throw new Error(`Workspace "${project.name}" requires [projects.agent.options].command for Local AI Core ACP execution.`);
|
|
219
427
|
}
|
|
220
428
|
const defaultArgs = agentType === 'opencode'
|
|
221
429
|
? ['acp']
|
|
222
|
-
: agentType === '
|
|
223
|
-
? [...(
|
|
224
|
-
: agentType === '
|
|
225
|
-
? [...(
|
|
226
|
-
:
|
|
430
|
+
: agentType === 'pi'
|
|
431
|
+
? [...(bundledPiAcp?.args || [])]
|
|
432
|
+
: agentType === 'codex'
|
|
433
|
+
? [...(bundledCodex?.args || [])]
|
|
434
|
+
: agentType === 'claudecode'
|
|
435
|
+
? [...(bundledClaudeCode?.args || [])]
|
|
436
|
+
: [];
|
|
227
437
|
return {
|
|
228
438
|
workspaceId: project.name,
|
|
229
439
|
agentType,
|
|
@@ -231,9 +441,10 @@ function toLocalCoreProjectConfig(configState, project) {
|
|
|
231
441
|
command,
|
|
232
442
|
args: args.length > 0 ? args : defaultArgs,
|
|
233
443
|
env: {
|
|
234
|
-
...providerEnv,
|
|
235
444
|
...inferredOpencodeEnv,
|
|
236
445
|
...inferredClaudeCodeEnv,
|
|
446
|
+
...inferredPiEnv,
|
|
447
|
+
...providerEnv,
|
|
237
448
|
...env,
|
|
238
449
|
},
|
|
239
450
|
model,
|
|
@@ -7,6 +7,7 @@ const node_module_1 = require("node:module");
|
|
|
7
7
|
const node_child_process_1 = require("node:child_process");
|
|
8
8
|
const desktop_js_1 = require("../../../../shared/desktop.js");
|
|
9
9
|
const DISPLAY_NAMES = {
|
|
10
|
+
pi: 'Pi',
|
|
10
11
|
opencode: 'OpenCode',
|
|
11
12
|
codex: 'Codex',
|
|
12
13
|
claudecode: 'Claude Code',
|
|
@@ -17,6 +18,7 @@ const DISPLAY_NAMES = {
|
|
|
17
18
|
[desktop_js_1.LOCALCORE_ACP_AGENT_TYPE]: 'LocalCore ACP',
|
|
18
19
|
};
|
|
19
20
|
const COMMAND_CANDIDATES = {
|
|
21
|
+
pi: ['pi'],
|
|
20
22
|
opencode: ['opencode'],
|
|
21
23
|
codex: ['codex-acp', 'codex'],
|
|
22
24
|
claudecode: ['claude-agent-acp'],
|
|
@@ -26,6 +28,7 @@ const COMMAND_CANDIDATES = {
|
|
|
26
28
|
iflow: ['iflow'],
|
|
27
29
|
};
|
|
28
30
|
const VERSION_ARGUMENTS = {
|
|
31
|
+
pi: ['--version'],
|
|
29
32
|
opencode: ['--version'],
|
|
30
33
|
codex: ['--version'],
|
|
31
34
|
claudecode: ['--version'],
|
|
@@ -61,14 +64,16 @@ function detectInstalledAgentRuntimes(options = {}) {
|
|
|
61
64
|
? installedRuntime(agentType, resolved, 'config', detectedAt, env, versionTimeoutMs)
|
|
62
65
|
: missingRuntime(agentType, detectedAt, `Configured command not found: ${configured}`);
|
|
63
66
|
}
|
|
64
|
-
if (agentType === 'codex' || agentType === 'claudecode') {
|
|
65
|
-
const bundled = agentType === '
|
|
66
|
-
? resolveBundledAcpPackage(options.requireFrom, desktop_js_1.
|
|
67
|
-
:
|
|
68
|
-
'
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
67
|
+
if (agentType === 'pi' || agentType === 'codex' || agentType === 'claudecode') {
|
|
68
|
+
const bundled = agentType === 'pi'
|
|
69
|
+
? resolveBundledAcpPackage(options.requireFrom, desktop_js_1.DESKTOP_PI_CODING_AGENT_PACKAGE, ['dist/cli.js'])
|
|
70
|
+
: agentType === 'codex'
|
|
71
|
+
? resolveBundledAcpPackage(options.requireFrom, desktop_js_1.DESKTOP_CODEX_ACP_PACKAGE, ['bin/codex-acp.js'])
|
|
72
|
+
: resolveBundledAcpPackage(options.requireFrom, desktop_js_1.DESKTOP_CLAUDECODE_ACP_PACKAGE, [
|
|
73
|
+
'dist/cli.js',
|
|
74
|
+
'bin/claude-agent-acp.js',
|
|
75
|
+
'cli.js',
|
|
76
|
+
]);
|
|
72
77
|
if (bundled) {
|
|
73
78
|
return installedRuntime(agentType, bundled, 'bundled', detectedAt, env, versionTimeoutMs);
|
|
74
79
|
}
|
|
@@ -224,7 +229,7 @@ function parseVersionOutput(output) {
|
|
|
224
229
|
function resolveBundledAcpPackage(requireFrom, packageName, candidates) {
|
|
225
230
|
try {
|
|
226
231
|
const require = (0, node_module_1.createRequire)(requireFrom || (0, node_path_1.join)(process.cwd(), 'package.json'));
|
|
227
|
-
const packageJsonPath = require
|
|
232
|
+
const packageJsonPath = resolveBundledPackageJsonPath(require, packageName);
|
|
228
233
|
const packageDir = (0, node_path_1.dirname)(packageJsonPath);
|
|
229
234
|
const packageJson = require(packageJsonPath);
|
|
230
235
|
const binField = packageJson.bin;
|
|
@@ -246,3 +251,28 @@ function resolveBundledAcpPackage(requireFrom, packageName, candidates) {
|
|
|
246
251
|
return null;
|
|
247
252
|
}
|
|
248
253
|
}
|
|
254
|
+
function resolveBundledPackageJsonPath(require, packageName) {
|
|
255
|
+
try {
|
|
256
|
+
return require.resolve(`${packageName}/package.json`);
|
|
257
|
+
}
|
|
258
|
+
catch (error) {
|
|
259
|
+
if (error?.code !== 'ERR_PACKAGE_PATH_NOT_EXPORTED') {
|
|
260
|
+
throw error;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
for (const basePath of require.resolve.paths(packageName) || []) {
|
|
264
|
+
const packageJsonPath = (0, node_path_1.join)(basePath, ...packageName.split('/'), 'package.json');
|
|
265
|
+
if ((0, node_fs_1.existsSync)(packageJsonPath)) {
|
|
266
|
+
return packageJsonPath;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
let current = (0, node_path_1.dirname)(require.resolve(packageName));
|
|
270
|
+
while (current && current !== (0, node_path_1.dirname)(current)) {
|
|
271
|
+
const packageJsonPath = (0, node_path_1.join)(current, 'package.json');
|
|
272
|
+
if ((0, node_fs_1.existsSync)(packageJsonPath)) {
|
|
273
|
+
return packageJsonPath;
|
|
274
|
+
}
|
|
275
|
+
current = (0, node_path_1.dirname)(current);
|
|
276
|
+
}
|
|
277
|
+
throw new Error(`Bundled package "${packageName}" package.json could not be resolved.`);
|
|
278
|
+
}
|
|
@@ -348,6 +348,7 @@ class LocalCoreController extends node_events_1.EventEmitter {
|
|
|
348
348
|
type: 'file',
|
|
349
349
|
path: input.path,
|
|
350
350
|
fileName: input.fileName,
|
|
351
|
+
metadata: input.workspacePath ? { workspacePath: input.workspacePath } : undefined,
|
|
351
352
|
}],
|
|
352
353
|
});
|
|
353
354
|
const attachment = result.attachments?.[0];
|