tarsk 0.4.27 → 0.4.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +438 -148
- package/dist/public/assets/account-view-DcpSNB3N.js +1 -0
- package/dist/public/assets/alert-dialog-CQRWdGnn.js +1 -0
- package/dist/public/assets/api-CH5gAPs5.js +1 -0
- package/dist/public/assets/{browser-tab-DlzO5cMP.js → browser-tab-CiAz6nc1.js} +1 -1
- package/dist/public/assets/chat-input-container-C6U_WFFu.js +21 -0
- package/dist/public/assets/context-menu-A9p22S7d.js +1 -0
- package/dist/public/assets/conversation-history-view-CD_uVRNY.js +1 -0
- package/dist/public/assets/{dialogs-config-DZFG2IQM.js → dialogs-config-vkfELnGl.js} +3 -3
- package/dist/public/assets/diff-view-CjbcDB6m.js +3 -0
- package/dist/public/assets/explorer-tab-view-BfycKUUW.js +2 -0
- package/dist/public/assets/explorer-tree-DTFYhczJ.js +1 -0
- package/dist/public/assets/explorer-view-C0KcZ8NQ.js +1 -0
- package/dist/public/assets/history-view-Dn0hQIKU.js +1 -0
- package/dist/public/assets/index-Bdde81Uo.css +1 -0
- package/dist/public/assets/index-DKQVo4Vz.js +29 -0
- package/dist/public/assets/markdown-renderer-CNuyXHcy.js +10 -0
- package/dist/public/assets/mcp-server-card-DBEBe3Qh.js +1 -0
- package/dist/public/assets/onboarding-DslO5AS6.js +1 -0
- package/dist/public/assets/onboarding-dialog-CE-GhoDt.js +1 -0
- package/dist/public/assets/{page-toolbar-TvYsDwUY.js → page-toolbar-CloU_Kvo.js} +1 -1
- package/dist/public/assets/{project-settings-view-C7GW_R0m.js → project-settings-view-CxD9JZoB.js} +1 -1
- package/dist/public/assets/providers-list-view-CNxVBJlM.js +1 -0
- package/dist/public/assets/radio-group-Co0Lg6se.js +1 -0
- package/dist/public/assets/react-vendor-DyE9sO8V.js +22 -0
- package/dist/public/assets/{resizable-DzrIos_Y.js → resizable-dToeUeVD.js} +1 -1
- package/dist/public/assets/{run-stop-button-k1LeM0M-.js → run-stop-button-DZ4JFwdL.js} +2 -2
- package/dist/public/assets/settings-instructions-view-DWzAH2yN.js +1 -0
- package/dist/public/assets/{settings-mcp-servers-view-Becs_RxN.js → settings-mcp-servers-view-q6gGMMVX.js} +4 -4
- package/dist/public/assets/settings-models-view-BDDFQWWC.js +1 -0
- package/dist/public/assets/settings-rules-view-DsEwgDFr.js +8 -0
- package/dist/public/assets/{settings-skills-view-aPv03-bO.js → settings-skills-view-DV40_L1o.js} +2 -2
- package/dist/public/assets/{settings-slash-commands-view-DLMWXQXA.js → settings-slash-commands-view-BEk3BgOY.js} +1 -1
- package/dist/public/assets/settings-subagents-view-d3P4ylDX.js +2 -0
- package/dist/public/assets/settings-view-ClTMPafQ.js +2 -0
- package/dist/public/assets/{side-panel-container-oMcXib2A.js → side-panel-container-BAYoMt7B.js} +2 -2
- package/dist/public/assets/{skeleton-Bc0U0oGc.js → skeleton-DveUQR4w.js} +1 -1
- package/dist/public/assets/standard-list-item-BLlgm1qW.js +1 -0
- package/dist/public/assets/store-BcwWHqYr.js +4 -0
- package/dist/public/assets/{tab-context-CCvlrC0o.js → tab-context-DWD20a4z.js} +1 -1
- package/dist/public/assets/tabs-CgvpwOBj.js +1 -0
- package/dist/public/assets/{terminal-panel-GuO2XygM.js → terminal-panel-CkIe2d2K.js} +2 -2
- package/dist/public/assets/textarea-C2UIAa7y.js +1 -0
- package/dist/public/assets/todos-view-C-awG1dZ.js +1 -0
- package/dist/public/assets/{use-toast-DqmC-mB5.js → use-toast-yY7qQuQP.js} +1 -1
- package/dist/public/assets/{utils-Cy2s2TEb.js → utils-BKss67Vg.js} +1 -1
- package/dist/public/assets/{whisper-wasm-Clnf-l-9.js → whisper-wasm-B7iuRPFr.js} +1 -1
- package/dist/public/ide/antigravity.svg +1 -0
- package/dist/public/ide/devin.svg +1 -0
- package/dist/public/index.html +22 -21
- package/package.json +1 -1
- package/dist/public/assets/account-view-BFhjAYmz.js +0 -1
- package/dist/public/assets/alert-dialog--tUzAWFm.js +0 -1
- package/dist/public/assets/api-BBbysRIh.js +0 -1
- package/dist/public/assets/chat-input-container-B_qVOGzW.js +0 -21
- package/dist/public/assets/context-menu-D5slxFcc.js +0 -1
- package/dist/public/assets/conversation-history-view-B4zHwyrw.js +0 -1
- package/dist/public/assets/diff-view-fOVqrHQW.js +0 -3
- package/dist/public/assets/explorer-tab-view-MLrWJ1Y0.js +0 -2
- package/dist/public/assets/explorer-tree-8TyBYuC7.js +0 -1
- package/dist/public/assets/explorer-view-5U70mfAJ.js +0 -1
- package/dist/public/assets/history-view-BR8scGnM.js +0 -1
- package/dist/public/assets/index-0BuHfewk.css +0 -1
- package/dist/public/assets/index-BTbiyooe.js +0 -37
- package/dist/public/assets/mcp-server-card-DupwHcKT.js +0 -1
- package/dist/public/assets/onboarding-Cn5RqOCa.js +0 -1
- package/dist/public/assets/onboarding-dialog-BXsvjU1t.js +0 -1
- package/dist/public/assets/providers-list-view-AVt5I1WB.js +0 -1
- package/dist/public/assets/radio-group-Mifbn8sU.js +0 -1
- package/dist/public/assets/react-vendor-Bao-KYKs.js +0 -22
- package/dist/public/assets/settings-instructions-view-CgfWSPmK.js +0 -1
- package/dist/public/assets/settings-models-view-BqdD_7GR.js +0 -1
- package/dist/public/assets/settings-rules-view-D7j5OHUi.js +0 -8
- package/dist/public/assets/settings-subagents-view-DBYzNE4W.js +0 -2
- package/dist/public/assets/settings-view-CccwUKkf.js +0 -2
- package/dist/public/assets/standard-list-item-D2lbPXa1.js +0 -1
- package/dist/public/assets/store-CwvBC-YP.js +0 -2
- package/dist/public/assets/tabs-Mb_cjIfE.js +0 -1
- package/dist/public/assets/textarea-DpXOZLt8.js +0 -1
- package/dist/public/assets/todos-view-C4GMi1Np.js +0 -1
- /package/dist/public/assets/{dist-BI23Ei33.js → dist-Bjt_i1zi.js} +0 -0
- /package/dist/public/assets/{monaco-DDfTQM3i.js → monaco-SWcefg0q.js} +0 -0
package/dist/index.js
CHANGED
|
@@ -769,6 +769,14 @@ var PROGRAMS_CONFIG = {
|
|
|
769
769
|
Terminal: {
|
|
770
770
|
name: "Terminal",
|
|
771
771
|
appName: "Terminal"
|
|
772
|
+
},
|
|
773
|
+
"Devin Desktop": {
|
|
774
|
+
name: "Devin Desktop",
|
|
775
|
+
appName: ["Devin", "Devin Desktop"]
|
|
776
|
+
},
|
|
777
|
+
Antigravity: {
|
|
778
|
+
name: "Antigravity",
|
|
779
|
+
appName: ["com.google.antigravity-ide", "Antigravity IDE"]
|
|
772
780
|
}
|
|
773
781
|
};
|
|
774
782
|
var AVAILABLE_PROGRAMS = Object.keys(PROGRAMS_CONFIG);
|
|
@@ -1820,9 +1828,9 @@ function createGrepTool(cwd, options) {
|
|
|
1820
1828
|
const effectiveLimit = Math.max(1, limit ?? DEFAULT_LIMIT2);
|
|
1821
1829
|
const formatPath = (filePath) => {
|
|
1822
1830
|
if (isDirectory) {
|
|
1823
|
-
const
|
|
1824
|
-
if (
|
|
1825
|
-
return
|
|
1831
|
+
const relative8 = path2.relative(searchPath, filePath);
|
|
1832
|
+
if (relative8 && !relative8.startsWith("..")) {
|
|
1833
|
+
return relative8.replace(/\\/g, "/");
|
|
1826
1834
|
}
|
|
1827
1835
|
}
|
|
1828
1836
|
return path2.basename(filePath);
|
|
@@ -4140,16 +4148,56 @@ var ModelManager = class {
|
|
|
4140
4148
|
};
|
|
4141
4149
|
|
|
4142
4150
|
// src/features/providers/provider-resolver.ts
|
|
4151
|
+
function getProviderApiKeyEnvName(providerEnv) {
|
|
4152
|
+
if (providerEnv.length === 0) {
|
|
4153
|
+
return "";
|
|
4154
|
+
}
|
|
4155
|
+
const explicitApiKeyEnv = providerEnv.find((envName) => /api_key$/i.test(envName));
|
|
4156
|
+
return explicitApiKeyEnv ?? providerEnv[providerEnv.length - 1];
|
|
4157
|
+
}
|
|
4158
|
+
function getProviderApiUrlEnvName(providerName) {
|
|
4159
|
+
return `${providerName.toUpperCase().replace(/-/g, "_")}_API_URL`;
|
|
4160
|
+
}
|
|
4161
|
+
function getProviderResourceName(providerEnv) {
|
|
4162
|
+
const explicitResourceEnv = providerEnv.find((envName) => /resource_name$/i.test(envName));
|
|
4163
|
+
return explicitResourceEnv ?? providerEnv[0] ?? "";
|
|
4164
|
+
}
|
|
4165
|
+
function resolveAzureApiUrl(providerEnv) {
|
|
4166
|
+
const resourceEnvName = getProviderResourceName(providerEnv);
|
|
4167
|
+
const resourceName = process.env[resourceEnvName];
|
|
4168
|
+
if (!resourceName) {
|
|
4169
|
+
return "";
|
|
4170
|
+
}
|
|
4171
|
+
return `https://${resourceName}.openai.azure.com/openai/v1`;
|
|
4172
|
+
}
|
|
4173
|
+
function resolveTemplate(template, envValues) {
|
|
4174
|
+
let hasMissingValue = false;
|
|
4175
|
+
const resolved = template.replace(/\$\{([A-Z0-9_]+)\}/gi, (_match, envName) => {
|
|
4176
|
+
const value = envValues[envName] ?? process.env[envName] ?? "";
|
|
4177
|
+
if (!value) {
|
|
4178
|
+
hasMissingValue = true;
|
|
4179
|
+
}
|
|
4180
|
+
return value;
|
|
4181
|
+
});
|
|
4182
|
+
return hasMissingValue ? "" : resolved;
|
|
4183
|
+
}
|
|
4143
4184
|
async function resolveProviderConfig(providerName) {
|
|
4144
4185
|
const slug = providerName.toLowerCase();
|
|
4145
4186
|
const catalogProvider = await getCatalogProvider(slug);
|
|
4146
4187
|
if (!catalogProvider) return null;
|
|
4147
|
-
|
|
4188
|
+
const apiKeyEnv = getProviderApiKeyEnvName(catalogProvider.env ?? []);
|
|
4189
|
+
const apiUrlEnvName = getProviderApiUrlEnvName(slug);
|
|
4190
|
+
const api = slug === "azure" ? resolveAzureApiUrl(catalogProvider.env ?? []) : process.env[apiUrlEnvName] || (catalogProvider.api ? resolveTemplate(catalogProvider.api, process.env) : "");
|
|
4191
|
+
return {
|
|
4192
|
+
...catalogProvider,
|
|
4193
|
+
api,
|
|
4194
|
+
apiKeyEnv
|
|
4195
|
+
};
|
|
4148
4196
|
}
|
|
4149
4197
|
async function resolveProviderKeyName(providerName) {
|
|
4150
4198
|
const slug = providerName.toLowerCase();
|
|
4151
4199
|
const catalogProvider = await getCatalogProvider(slug);
|
|
4152
|
-
if (catalogProvider?.env?.
|
|
4200
|
+
if (catalogProvider?.env?.length) return getProviderApiKeyEnvName(catalogProvider.env);
|
|
4153
4201
|
return "";
|
|
4154
4202
|
}
|
|
4155
4203
|
|
|
@@ -4346,7 +4394,7 @@ function createGenerateImageTool(options) {
|
|
|
4346
4394
|
details: void 0
|
|
4347
4395
|
};
|
|
4348
4396
|
}
|
|
4349
|
-
let apiKey = providerConfig.
|
|
4397
|
+
let apiKey = providerConfig.apiKeyEnv ? process.env[providerConfig.apiKeyEnv] : void 0;
|
|
4350
4398
|
if (!apiKey) {
|
|
4351
4399
|
const providerKeys = await metadataManager.getProviderKeys();
|
|
4352
4400
|
apiKey = providerKeys[providerConfig.id];
|
|
@@ -4784,8 +4832,12 @@ function createToolSearchTool(options) {
|
|
|
4784
4832
|
let matched = [];
|
|
4785
4833
|
if (parsed.mode === "select") {
|
|
4786
4834
|
for (const name of parsed.names) {
|
|
4787
|
-
const tool
|
|
4788
|
-
|
|
4835
|
+
for (const [toolName, tool] of deferredTools.entries()) {
|
|
4836
|
+
if (toolName.toLowerCase() === name) {
|
|
4837
|
+
matched.push(tool);
|
|
4838
|
+
break;
|
|
4839
|
+
}
|
|
4840
|
+
}
|
|
4789
4841
|
}
|
|
4790
4842
|
} else {
|
|
4791
4843
|
const candidates = [];
|
|
@@ -5039,6 +5091,7 @@ var EventQueue = class {
|
|
|
5039
5091
|
finalContent = "";
|
|
5040
5092
|
errorOccurred = false;
|
|
5041
5093
|
toolCallCount = 0;
|
|
5094
|
+
lastErrorMessage;
|
|
5042
5095
|
/**
|
|
5043
5096
|
* Processes Pi Agent events and transforms them into AgentEvent format
|
|
5044
5097
|
*/
|
|
@@ -5107,6 +5160,9 @@ var EventQueue = class {
|
|
|
5107
5160
|
} else if (event.type === "agent_end") {
|
|
5108
5161
|
const messages = event.messages;
|
|
5109
5162
|
const lastAssistant = [...messages].reverse().find((m) => "role" in m && m.role === "assistant");
|
|
5163
|
+
if (lastAssistant && "errorMessage" in lastAssistant && typeof lastAssistant.errorMessage === "string") {
|
|
5164
|
+
this.lastErrorMessage = lastAssistant.errorMessage;
|
|
5165
|
+
}
|
|
5110
5166
|
if (lastAssistant) {
|
|
5111
5167
|
const extracted = extractTextFromAssistantMessage(lastAssistant);
|
|
5112
5168
|
if (extracted && extracted !== this.finalContent) {
|
|
@@ -5220,14 +5276,14 @@ async function executeSubagent(options) {
|
|
|
5220
5276
|
if (!providerConfig) {
|
|
5221
5277
|
throw new Error(`Unknown provider for subagent: ${providerName}`);
|
|
5222
5278
|
}
|
|
5223
|
-
let apiKey = providerConfig.
|
|
5279
|
+
let apiKey = providerConfig.apiKeyEnv ? process.env[providerConfig.apiKeyEnv] : void 0;
|
|
5224
5280
|
if (!apiKey) {
|
|
5225
5281
|
const providerKeys = await metadataManager.getProviderKeys();
|
|
5226
5282
|
apiKey = providerKeys[providerConfig.id];
|
|
5227
5283
|
}
|
|
5228
5284
|
if (!apiKey) {
|
|
5229
5285
|
throw new Error(
|
|
5230
|
-
`No API key found for subagent provider: ${providerName}. Set ${providerConfig.
|
|
5286
|
+
`No API key found for subagent provider: ${providerName}. Set ${providerConfig.apiKeyEnv ?? "an API key"} in environment variables or configuration.`
|
|
5231
5287
|
);
|
|
5232
5288
|
}
|
|
5233
5289
|
const resolvedModel = resolveModel(providerName, model, providerConfig);
|
|
@@ -6115,10 +6171,94 @@ async function loadAgentSystemPrompt(threadPath, tools, skills, planMode, agents
|
|
|
6115
6171
|
var cachedStreamFn = (model, context, options) => {
|
|
6116
6172
|
return streamSimple(model, context, { ...options, cacheRetention: "long" });
|
|
6117
6173
|
};
|
|
6174
|
+
function summarizeAssistantResponse(response) {
|
|
6175
|
+
const lines = response.split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
|
|
6176
|
+
const salient = lines.filter(
|
|
6177
|
+
(line) => /^(#+\s|[-*]\s|\d+\.\s|```|changed|created|updated|deleted|fixed|implemented|added|removed|renamed|moved|tested|next|summary|result)/i.test(
|
|
6178
|
+
line
|
|
6179
|
+
) || line.length <= 180
|
|
6180
|
+
);
|
|
6181
|
+
const summary = (salient.length > 0 ? salient : lines).slice(0, 12).join("\n");
|
|
6182
|
+
return summary.length > 3e3 ? `${summary.slice(0, 3e3)}\u2026` : summary;
|
|
6183
|
+
}
|
|
6184
|
+
function getAssistantHistoryContent(exchange, isMostRecent) {
|
|
6185
|
+
if (isMostRecent) {
|
|
6186
|
+
return exchange.assistantResponse;
|
|
6187
|
+
}
|
|
6188
|
+
return exchange.assistantSummary ?? summarizeAssistantResponse(exchange.assistantResponse);
|
|
6189
|
+
}
|
|
6190
|
+
function buildAssistantHistoryText(content, isMostRecent) {
|
|
6191
|
+
if (isMostRecent) {
|
|
6192
|
+
return content;
|
|
6193
|
+
}
|
|
6194
|
+
return `[Earlier assistant response summarized to reduce context tokens]
|
|
6195
|
+
${content}`;
|
|
6196
|
+
}
|
|
6197
|
+
function serializeLogValue(value, depth = 0, seen = /* @__PURE__ */ new WeakSet()) {
|
|
6198
|
+
if (value === null || value === void 0) {
|
|
6199
|
+
return value;
|
|
6200
|
+
}
|
|
6201
|
+
const valueType = typeof value;
|
|
6202
|
+
if (valueType === "string" || valueType === "number" || valueType === "boolean") {
|
|
6203
|
+
return value;
|
|
6204
|
+
}
|
|
6205
|
+
if (valueType === "bigint" || valueType === "symbol") {
|
|
6206
|
+
return "[Primitive]";
|
|
6207
|
+
}
|
|
6208
|
+
if (valueType === "function") {
|
|
6209
|
+
return "[Function]";
|
|
6210
|
+
}
|
|
6211
|
+
if (value instanceof Error) {
|
|
6212
|
+
const serializedError = {
|
|
6213
|
+
name: value.name,
|
|
6214
|
+
message: value.message
|
|
6215
|
+
};
|
|
6216
|
+
if (value.stack) {
|
|
6217
|
+
serializedError.stack = value.stack;
|
|
6218
|
+
}
|
|
6219
|
+
if ("cause" in value) {
|
|
6220
|
+
serializedError.cause = serializeLogValue(
|
|
6221
|
+
value.cause,
|
|
6222
|
+
depth + 1,
|
|
6223
|
+
seen
|
|
6224
|
+
);
|
|
6225
|
+
}
|
|
6226
|
+
const errorObject = value;
|
|
6227
|
+
for (const [key, nestedValue] of Object.entries(errorObject)) {
|
|
6228
|
+
if (key in serializedError) continue;
|
|
6229
|
+
serializedError[key] = serializeLogValue(nestedValue, depth + 1, seen);
|
|
6230
|
+
}
|
|
6231
|
+
return serializedError;
|
|
6232
|
+
}
|
|
6233
|
+
if (Array.isArray(value)) {
|
|
6234
|
+
if (depth >= 4) {
|
|
6235
|
+
return "[Truncated]";
|
|
6236
|
+
}
|
|
6237
|
+
return value.slice(0, 50).map((item) => serializeLogValue(item, depth + 1, seen));
|
|
6238
|
+
}
|
|
6239
|
+
if (valueType === "object") {
|
|
6240
|
+
if (seen.has(value)) {
|
|
6241
|
+
return "[Circular]";
|
|
6242
|
+
}
|
|
6243
|
+
if (depth >= 4) {
|
|
6244
|
+
return "[Truncated]";
|
|
6245
|
+
}
|
|
6246
|
+
seen.add(value);
|
|
6247
|
+
const serializedObject = {};
|
|
6248
|
+
const plainObject = value;
|
|
6249
|
+
for (const [key, nestedValue] of Object.entries(plainObject).slice(0, 50)) {
|
|
6250
|
+
serializedObject[key] = serializeLogValue(nestedValue, depth + 1, seen);
|
|
6251
|
+
}
|
|
6252
|
+
return serializedObject;
|
|
6253
|
+
}
|
|
6254
|
+
return "[Unsupported value]";
|
|
6255
|
+
}
|
|
6118
6256
|
function buildHistoryMessages(history) {
|
|
6119
6257
|
const messages = [];
|
|
6120
6258
|
const now = Date.now();
|
|
6121
|
-
|
|
6259
|
+
history.forEach((exchange, index) => {
|
|
6260
|
+
const isMostRecent = index === history.length - 1;
|
|
6261
|
+
const assistantContent = getAssistantHistoryContent(exchange, isMostRecent);
|
|
6122
6262
|
messages.push({
|
|
6123
6263
|
role: "user",
|
|
6124
6264
|
content: exchange.userMessage,
|
|
@@ -6126,7 +6266,9 @@ function buildHistoryMessages(history) {
|
|
|
6126
6266
|
});
|
|
6127
6267
|
messages.push({
|
|
6128
6268
|
role: "assistant",
|
|
6129
|
-
content: [
|
|
6269
|
+
content: [
|
|
6270
|
+
{ type: "text", text: buildAssistantHistoryText(assistantContent, isMostRecent) }
|
|
6271
|
+
],
|
|
6130
6272
|
api: "",
|
|
6131
6273
|
provider: "",
|
|
6132
6274
|
model: "",
|
|
@@ -6141,7 +6283,7 @@ function buildHistoryMessages(history) {
|
|
|
6141
6283
|
stopReason: "stop",
|
|
6142
6284
|
timestamp: now
|
|
6143
6285
|
});
|
|
6144
|
-
}
|
|
6286
|
+
});
|
|
6145
6287
|
return messages;
|
|
6146
6288
|
}
|
|
6147
6289
|
var PiExecutorImpl = class {
|
|
@@ -6171,7 +6313,7 @@ var PiExecutorImpl = class {
|
|
|
6171
6313
|
if (!providerConfig) {
|
|
6172
6314
|
throw new Error(`Unknown provider: ${providerName}`);
|
|
6173
6315
|
}
|
|
6174
|
-
let apiKey = providerConfig.
|
|
6316
|
+
let apiKey = providerConfig.apiKeyEnv ? process.env[providerConfig.apiKeyEnv] : void 0;
|
|
6175
6317
|
let apiKeySource = "environment";
|
|
6176
6318
|
if (!apiKey) {
|
|
6177
6319
|
try {
|
|
@@ -6187,7 +6329,7 @@ var PiExecutorImpl = class {
|
|
|
6187
6329
|
}
|
|
6188
6330
|
if (!apiKey) {
|
|
6189
6331
|
throw new Error(
|
|
6190
|
-
`No API key found for provider: ${providerName}. Set ${providerConfig.
|
|
6332
|
+
`No API key found for provider: ${providerName}. Set ${providerConfig.apiKeyEnv ?? "an API key"} in environment variables or configuration.`
|
|
6191
6333
|
);
|
|
6192
6334
|
}
|
|
6193
6335
|
if (apiKey.includes(":") && apiKey.length > 100) {
|
|
@@ -6302,15 +6444,27 @@ ${decoded}
|
|
|
6302
6444
|
|
|
6303
6445
|
${userPrompt}`;
|
|
6304
6446
|
}
|
|
6305
|
-
|
|
6306
|
-
|
|
6307
|
-
|
|
6447
|
+
const promptRequest = {
|
|
6448
|
+
provider: providerName,
|
|
6449
|
+
model,
|
|
6450
|
+
cwd,
|
|
6451
|
+
prompt: finalPrompt,
|
|
6452
|
+
promptLength: finalPrompt.length,
|
|
6453
|
+
promptPreview: finalPrompt.substring(0, 200) + (finalPrompt.length > 200 ? "..." : ""),
|
|
6454
|
+
imageCount: images.length,
|
|
6455
|
+
images: images.map((img) => ({
|
|
6456
|
+
mimeType: img.mimeType,
|
|
6457
|
+
dataLength: img.data?.length ?? 0
|
|
6458
|
+
})),
|
|
6459
|
+
attachments: (context.attachments ?? []).map((a) => ({
|
|
6308
6460
|
name: a.name,
|
|
6309
6461
|
mimeType: a.mimeType,
|
|
6310
6462
|
contentLength: a.content?.length ?? 0
|
|
6311
|
-
}))
|
|
6312
|
-
|
|
6313
|
-
|
|
6463
|
+
}))
|
|
6464
|
+
};
|
|
6465
|
+
console.log(
|
|
6466
|
+
`[ai] Attachments: ${context.attachments?.length ?? 0} total, ${images.length} image(s), ${textAttachments.length} text file(s)`,
|
|
6467
|
+
promptRequest
|
|
6314
6468
|
);
|
|
6315
6469
|
const promptDone = agent.prompt(finalPrompt, images.length > 0 ? images : void 0).then(() => {
|
|
6316
6470
|
console.log(`[ai] Agent prompt completed successfully`);
|
|
@@ -6319,7 +6473,8 @@ ${userPrompt}`;
|
|
|
6319
6473
|
}).catch((err) => {
|
|
6320
6474
|
const errMessage = err instanceof Error ? err.message : String(err);
|
|
6321
6475
|
console.error(`[ai] Agent prompt failed:`, {
|
|
6322
|
-
|
|
6476
|
+
request: promptRequest,
|
|
6477
|
+
error: serializeLogValue(err),
|
|
6323
6478
|
errorType: err instanceof Error ? err.constructor.name : typeof err
|
|
6324
6479
|
});
|
|
6325
6480
|
if (!eventQueue.errorOccurred) {
|
|
@@ -6373,12 +6528,20 @@ ${userPrompt}`;
|
|
|
6373
6528
|
};
|
|
6374
6529
|
} else {
|
|
6375
6530
|
console.log("[ai] \u26A0\uFE0F Agent ended with no text content and no tool calls.");
|
|
6531
|
+
const upstreamError = eventQueue.lastErrorMessage ? { message: eventQueue.lastErrorMessage } : void 0;
|
|
6532
|
+
console.error("[ai] Agent ended without text content:", {
|
|
6533
|
+
request: promptRequest,
|
|
6534
|
+
upstreamError,
|
|
6535
|
+
finalContentLength: eventQueue.finalContent.length,
|
|
6536
|
+
toolCallCount: eventQueue.toolCallCount
|
|
6537
|
+
});
|
|
6376
6538
|
yield {
|
|
6377
6539
|
type: "error",
|
|
6378
6540
|
content: `The model ${model} from ${providerName} did not provide a response to your prompt. Check your API key and balance and try again.`,
|
|
6379
6541
|
error: {
|
|
6380
6542
|
code: "NO_CONTENT_NO_TOOLS",
|
|
6381
|
-
message: `The model ${model} from ${providerName} did not provide a response to your prompt
|
|
6543
|
+
message: `The model ${model} from ${providerName} did not provide a response to your prompt.`,
|
|
6544
|
+
details: upstreamError
|
|
6382
6545
|
}
|
|
6383
6546
|
};
|
|
6384
6547
|
}
|
|
@@ -6485,6 +6648,63 @@ var ProcessingStateManagerImpl = class {
|
|
|
6485
6648
|
}
|
|
6486
6649
|
};
|
|
6487
6650
|
|
|
6651
|
+
// src/core/env-manager.ts
|
|
6652
|
+
import { promises as fs } from "fs";
|
|
6653
|
+
import { join as join11 } from "path";
|
|
6654
|
+
function updateRuntimeEnv(values) {
|
|
6655
|
+
for (const [key, value] of Object.entries(values)) {
|
|
6656
|
+
process.env[key] = value;
|
|
6657
|
+
}
|
|
6658
|
+
}
|
|
6659
|
+
async function updateEnvFile(keyNames) {
|
|
6660
|
+
const envPath = join11(process.cwd(), ".env");
|
|
6661
|
+
let content = "";
|
|
6662
|
+
try {
|
|
6663
|
+
content = await fs.readFile(envPath, "utf-8");
|
|
6664
|
+
} catch {
|
|
6665
|
+
}
|
|
6666
|
+
const lines = content.split("\n");
|
|
6667
|
+
const envMap = {};
|
|
6668
|
+
for (const line of lines) {
|
|
6669
|
+
const trimmed = line.trim();
|
|
6670
|
+
if (trimmed && !trimmed.startsWith("#") && trimmed.includes("=")) {
|
|
6671
|
+
const index = trimmed.indexOf("=");
|
|
6672
|
+
const key = trimmed.substring(0, index).trim();
|
|
6673
|
+
const value = trimmed.substring(index + 1).trim();
|
|
6674
|
+
envMap[key] = value;
|
|
6675
|
+
}
|
|
6676
|
+
}
|
|
6677
|
+
for (const [key, value] of Object.entries(keyNames)) {
|
|
6678
|
+
if (key) {
|
|
6679
|
+
envMap[key] = value;
|
|
6680
|
+
}
|
|
6681
|
+
}
|
|
6682
|
+
const newLines = [];
|
|
6683
|
+
for (const [key, value] of Object.entries(envMap)) {
|
|
6684
|
+
newLines.push(`${key}=${value}`);
|
|
6685
|
+
}
|
|
6686
|
+
await fs.writeFile(envPath, newLines.join("\n") + "\n", "utf-8");
|
|
6687
|
+
}
|
|
6688
|
+
async function readEnvFile() {
|
|
6689
|
+
const envPath = join11(process.cwd(), ".env");
|
|
6690
|
+
const envMap = {};
|
|
6691
|
+
try {
|
|
6692
|
+
const content = await fs.readFile(envPath, "utf-8");
|
|
6693
|
+
const lines = content.split("\n");
|
|
6694
|
+
for (const line of lines) {
|
|
6695
|
+
const trimmed = line.trim();
|
|
6696
|
+
if (trimmed && !trimmed.startsWith("#") && trimmed.includes("=")) {
|
|
6697
|
+
const index = trimmed.indexOf("=");
|
|
6698
|
+
const key = trimmed.substring(0, index).trim();
|
|
6699
|
+
const value = trimmed.substring(index + 1).trim();
|
|
6700
|
+
envMap[key] = value;
|
|
6701
|
+
}
|
|
6702
|
+
}
|
|
6703
|
+
} catch {
|
|
6704
|
+
}
|
|
6705
|
+
return envMap;
|
|
6706
|
+
}
|
|
6707
|
+
|
|
6488
6708
|
// src/features/ask-user/ask-user.routes.ts
|
|
6489
6709
|
import { Hono } from "hono";
|
|
6490
6710
|
|
|
@@ -6659,7 +6879,7 @@ import { randomUUID as randomUUID4 } from "crypto";
|
|
|
6659
6879
|
|
|
6660
6880
|
// src/features/skills/skills.manager.ts
|
|
6661
6881
|
import { readdir as readdir4, readFile as readFile6 } from "fs/promises";
|
|
6662
|
-
import { join as
|
|
6882
|
+
import { join as join12 } from "path";
|
|
6663
6883
|
import { existsSync as existsSync9 } from "fs";
|
|
6664
6884
|
import { homedir as homedir5 } from "os";
|
|
6665
6885
|
function parseFrontmatter(markdown) {
|
|
@@ -6707,10 +6927,10 @@ function parseFrontmatter(markdown) {
|
|
|
6707
6927
|
return { metadata, content };
|
|
6708
6928
|
}
|
|
6709
6929
|
function getGlobalSkillsDir() {
|
|
6710
|
-
return
|
|
6930
|
+
return join12(homedir5(), ".agents", "skills");
|
|
6711
6931
|
}
|
|
6712
6932
|
function getProjectSkillsDir(threadPath) {
|
|
6713
|
-
return
|
|
6933
|
+
return join12(threadPath, ".agents", "skills");
|
|
6714
6934
|
}
|
|
6715
6935
|
function validateSkillName(name) {
|
|
6716
6936
|
if (!name || name.length === 0 || name.length > 64) {
|
|
@@ -6763,8 +6983,8 @@ var SkillManager = class {
|
|
|
6763
6983
|
for (const entry of entries) {
|
|
6764
6984
|
if (!entry.isDirectory()) continue;
|
|
6765
6985
|
const skillDirName = entry.name;
|
|
6766
|
-
const skillPath =
|
|
6767
|
-
const skillFilePath =
|
|
6986
|
+
const skillPath = join12(dir, skillDirName);
|
|
6987
|
+
const skillFilePath = join12(skillPath, "SKILL.md");
|
|
6768
6988
|
if (!existsSync9(skillFilePath)) {
|
|
6769
6989
|
console.warn(`Skipping skill directory ${skillDirName}: SKILL.md not found`);
|
|
6770
6990
|
continue;
|
|
@@ -6944,7 +7164,7 @@ async function activateSkills(allSkills, taskDescription, thread, options) {
|
|
|
6944
7164
|
|
|
6945
7165
|
// src/features/agents/agents.manager.ts
|
|
6946
7166
|
import { readdir as readdir5, readFile as readFile7 } from "fs/promises";
|
|
6947
|
-
import { join as
|
|
7167
|
+
import { join as join13 } from "path";
|
|
6948
7168
|
import { existsSync as existsSync10 } from "fs";
|
|
6949
7169
|
import { homedir as homedir6 } from "os";
|
|
6950
7170
|
function parseFrontmatter2(markdown) {
|
|
@@ -7002,10 +7222,10 @@ function validateDescription2(description) {
|
|
|
7002
7222
|
return !!description && description.length > 0 && description.length <= 1024;
|
|
7003
7223
|
}
|
|
7004
7224
|
function getGlobalAgentsDir() {
|
|
7005
|
-
return
|
|
7225
|
+
return join13(homedir6(), ".agents", "agents");
|
|
7006
7226
|
}
|
|
7007
7227
|
function getProjectAgentsDir(threadPath) {
|
|
7008
|
-
return
|
|
7228
|
+
return join13(threadPath, ".agents", "agents");
|
|
7009
7229
|
}
|
|
7010
7230
|
var AgentsManager = class {
|
|
7011
7231
|
/**
|
|
@@ -7037,8 +7257,8 @@ var AgentsManager = class {
|
|
|
7037
7257
|
for (const entry of entries) {
|
|
7038
7258
|
if (!entry.isDirectory()) continue;
|
|
7039
7259
|
const agentDirName = entry.name;
|
|
7040
|
-
const agentPath =
|
|
7041
|
-
const agentFilePath =
|
|
7260
|
+
const agentPath = join13(dir, agentDirName);
|
|
7261
|
+
const agentFilePath = join13(agentPath, "AGENT.md");
|
|
7042
7262
|
if (!existsSync10(agentFilePath)) {
|
|
7043
7263
|
console.warn(`[agents] Skipping agent directory ${agentDirName}: AGENT.md not found`);
|
|
7044
7264
|
continue;
|
|
@@ -7225,7 +7445,7 @@ function extractAssistantContent(events, fallback) {
|
|
|
7225
7445
|
// src/features/chat/chat-post.route.ts
|
|
7226
7446
|
init_database();
|
|
7227
7447
|
import { readFile as readFile8, unlink } from "fs/promises";
|
|
7228
|
-
import { join as
|
|
7448
|
+
import { join as join14 } from "path";
|
|
7229
7449
|
|
|
7230
7450
|
// src/features/project-todos/project-todos.database.ts
|
|
7231
7451
|
init_database();
|
|
@@ -8218,7 +8438,7 @@ ${result.output}`;
|
|
|
8218
8438
|
try {
|
|
8219
8439
|
const todo = await getTodoByThreadId(db, threadId);
|
|
8220
8440
|
if (todo && todo.status === "Plan") {
|
|
8221
|
-
const planFilePath =
|
|
8441
|
+
const planFilePath = join14(threadPath, `${todo.id}-plan.md`);
|
|
8222
8442
|
try {
|
|
8223
8443
|
const planContent = await readFile8(planFilePath, "utf-8");
|
|
8224
8444
|
await updateTodo(db, todo.id, { description: planContent.trim() });
|
|
@@ -8430,13 +8650,15 @@ async function updateMessage(db, messageId, content, events, imageUrl) {
|
|
|
8430
8650
|
if (hasMessageUsage) {
|
|
8431
8651
|
if (event.type === "message" && event.message?.usage) {
|
|
8432
8652
|
const usage = event.message.usage;
|
|
8433
|
-
|
|
8434
|
-
|
|
8653
|
+
const tokens = calculateCostEquivalentTokens(usage);
|
|
8654
|
+
inputTokens += tokens.inputTokens;
|
|
8655
|
+
outputTokens += tokens.outputTokens;
|
|
8435
8656
|
}
|
|
8436
8657
|
} else {
|
|
8437
8658
|
if (event.type === "toolcall_delta" && event.partial?.usage) {
|
|
8438
|
-
|
|
8439
|
-
|
|
8659
|
+
const tokens = calculateCostEquivalentTokens(event.partial.usage);
|
|
8660
|
+
inputTokens += tokens.inputTokens;
|
|
8661
|
+
outputTokens += tokens.outputTokens;
|
|
8440
8662
|
}
|
|
8441
8663
|
}
|
|
8442
8664
|
}
|
|
@@ -8467,6 +8689,34 @@ async function updateMessage(db, messageId, content, events, imageUrl) {
|
|
|
8467
8689
|
throw error;
|
|
8468
8690
|
}
|
|
8469
8691
|
}
|
|
8692
|
+
function calculateCostEquivalentTokens(usage) {
|
|
8693
|
+
const input = usage.input ?? 0;
|
|
8694
|
+
const output = usage.output ?? 0;
|
|
8695
|
+
const cacheRead = usage.cacheRead ?? 0;
|
|
8696
|
+
const cacheWrite = usage.cacheWrite ?? 0;
|
|
8697
|
+
const cachedInput = cacheRead + cacheWrite;
|
|
8698
|
+
const uncachedInput = input >= cachedInput ? input - cachedInput : input;
|
|
8699
|
+
const inputCost = usage.cost?.input ?? 0;
|
|
8700
|
+
const cacheCost = (usage.cost?.cacheRead ?? 0) + (usage.cost?.cacheWrite ?? 0);
|
|
8701
|
+
if (uncachedInput > 0 && inputCost > 0 && cacheCost > 0) {
|
|
8702
|
+
const inputCostPerToken = inputCost / uncachedInput;
|
|
8703
|
+
const costEquivalentCachedInput = cacheCost / inputCostPerToken;
|
|
8704
|
+
return {
|
|
8705
|
+
inputTokens: Math.round(uncachedInput + costEquivalentCachedInput),
|
|
8706
|
+
outputTokens: output
|
|
8707
|
+
};
|
|
8708
|
+
}
|
|
8709
|
+
if (input >= cachedInput) {
|
|
8710
|
+
return {
|
|
8711
|
+
inputTokens: uncachedInput + cachedInput,
|
|
8712
|
+
outputTokens: output
|
|
8713
|
+
};
|
|
8714
|
+
}
|
|
8715
|
+
return {
|
|
8716
|
+
inputTokens: input,
|
|
8717
|
+
outputTokens: output
|
|
8718
|
+
};
|
|
8719
|
+
}
|
|
8470
8720
|
async function getConversationHistory(db, threadId) {
|
|
8471
8721
|
try {
|
|
8472
8722
|
const result = await db.execute(
|
|
@@ -9760,6 +10010,7 @@ var MetadataManager = class {
|
|
|
9760
10010
|
await setState(this.db, "selectedThreadId", state.selectedThreadId);
|
|
9761
10011
|
await setState(this.db, "enabledModels", state.enabledModels);
|
|
9762
10012
|
await setState(this.db, "enabledImageModels", state.enabledImageModels);
|
|
10013
|
+
await setState(this.db, "providerEnvValues", state.providerEnvValues);
|
|
9763
10014
|
await setState(this.db, "onboardingCompleted", state.onboardingCompleted);
|
|
9764
10015
|
const encryptedKeys = {};
|
|
9765
10016
|
for (const [provider, key] of Object.entries(state.providerKeys)) {
|
|
@@ -9792,6 +10043,7 @@ var MetadataManager = class {
|
|
|
9792
10043
|
const onboardingCompleted = allState.onboardingCompleted || false;
|
|
9793
10044
|
const enabledModels = allState.enabledModels || {};
|
|
9794
10045
|
const enabledImageModels = allState.enabledImageModels || {};
|
|
10046
|
+
const providerEnvValues = allState.providerEnvValues || {};
|
|
9795
10047
|
const encryptedKeys = allState.providerKeys || {};
|
|
9796
10048
|
const providerKeys = {};
|
|
9797
10049
|
let needsMigration = false;
|
|
@@ -9824,6 +10076,7 @@ var MetadataManager = class {
|
|
|
9824
10076
|
selectedThreadId,
|
|
9825
10077
|
onboardingCompleted,
|
|
9826
10078
|
providerKeys,
|
|
10079
|
+
providerEnvValues,
|
|
9827
10080
|
enabledModels,
|
|
9828
10081
|
enabledImageModels
|
|
9829
10082
|
};
|
|
@@ -9902,6 +10155,36 @@ var MetadataManager = class {
|
|
|
9902
10155
|
throw new Error(`Failed to get provider keys: ${errorMessage}`);
|
|
9903
10156
|
}
|
|
9904
10157
|
}
|
|
10158
|
+
/**
|
|
10159
|
+
* Save provider environment values (non-secret values such as Azure resource name)
|
|
10160
|
+
* @param values - Environment values to merge into metadata state
|
|
10161
|
+
*/
|
|
10162
|
+
async saveProviderEnvValues(values) {
|
|
10163
|
+
try {
|
|
10164
|
+
const state = await this.loadState();
|
|
10165
|
+
state.providerEnvValues = {
|
|
10166
|
+
...state.providerEnvValues,
|
|
10167
|
+
...values
|
|
10168
|
+
};
|
|
10169
|
+
await this.saveState(state);
|
|
10170
|
+
} catch (error) {
|
|
10171
|
+
throw new Error(`Failed to save provider environment values: ${String(error)}`);
|
|
10172
|
+
}
|
|
10173
|
+
}
|
|
10174
|
+
/**
|
|
10175
|
+
* Get provider environment values stored in metadata state
|
|
10176
|
+
* @returns Record of environment variable names to values
|
|
10177
|
+
*/
|
|
10178
|
+
async getProviderEnvValues() {
|
|
10179
|
+
try {
|
|
10180
|
+
const state = await this.loadState();
|
|
10181
|
+
return state.providerEnvValues;
|
|
10182
|
+
} catch (error) {
|
|
10183
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
10184
|
+
console.error("[MetadataManager] Failed to get provider environment values:", errorMessage);
|
|
10185
|
+
throw new Error(`Failed to get provider environment values: ${errorMessage}`);
|
|
10186
|
+
}
|
|
10187
|
+
}
|
|
9905
10188
|
/**
|
|
9906
10189
|
* Set the selected thread ID
|
|
9907
10190
|
* @param threadId - Thread ID to select (or null to deselect)
|
|
@@ -10086,7 +10369,7 @@ async function handleGetAvailableModels(c, modelManager) {
|
|
|
10086
10369
|
const bEnabled = enabledModelIds.has(b.id) ? 0 : 1;
|
|
10087
10370
|
return aEnabled - bEnabled;
|
|
10088
10371
|
});
|
|
10089
|
-
return c.json({ provider, models });
|
|
10372
|
+
return c.json({ provider, models, enabledModelIds: [...enabledModelIds] });
|
|
10090
10373
|
} catch (error) {
|
|
10091
10374
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
10092
10375
|
return c.json({ error: message }, 500);
|
|
@@ -10958,10 +11241,10 @@ async function handleCheckRunning(c, projectManager) {
|
|
|
10958
11241
|
|
|
10959
11242
|
// src/core/run-command-detector.ts
|
|
10960
11243
|
import { readFile as readFile9 } from "fs/promises";
|
|
10961
|
-
import { join as
|
|
11244
|
+
import { join as join15 } from "path";
|
|
10962
11245
|
async function detectPackageManager(projectPath) {
|
|
10963
11246
|
try {
|
|
10964
|
-
const packageJsonPath =
|
|
11247
|
+
const packageJsonPath = join15(projectPath, "package.json");
|
|
10965
11248
|
const content = await readFile9(packageJsonPath, "utf-8");
|
|
10966
11249
|
const packageJson = JSON.parse(content);
|
|
10967
11250
|
if (packageJson.packageManager) {
|
|
@@ -10977,7 +11260,7 @@ async function detectPackageManager(projectPath) {
|
|
|
10977
11260
|
}
|
|
10978
11261
|
async function detectRunScripts(projectPath) {
|
|
10979
11262
|
try {
|
|
10980
|
-
const packageJsonPath =
|
|
11263
|
+
const packageJsonPath = join15(projectPath, "package.json");
|
|
10981
11264
|
const content = await readFile9(packageJsonPath, "utf-8");
|
|
10982
11265
|
const packageJson = JSON.parse(content);
|
|
10983
11266
|
const scripts = packageJson.scripts ?? {};
|
|
@@ -11024,7 +11307,7 @@ async function suggestRunCommand(projectPath) {
|
|
|
11024
11307
|
|
|
11025
11308
|
// src/features/projects/projects-package-scripts.route.ts
|
|
11026
11309
|
import { readFile as readFile10 } from "fs/promises";
|
|
11027
|
-
import { join as
|
|
11310
|
+
import { join as join16 } from "path";
|
|
11028
11311
|
import { glob } from "glob";
|
|
11029
11312
|
function formatScriptName(scriptName) {
|
|
11030
11313
|
return scriptName.replace(/[-:_]/g, " ").replace(/\b\w/g, (l) => l.toUpperCase());
|
|
@@ -11052,7 +11335,7 @@ async function findPackageScripts(projectPath) {
|
|
|
11052
11335
|
const packageManager = await detectPackageManager(projectPath);
|
|
11053
11336
|
for (const filePath of packageJsonFiles) {
|
|
11054
11337
|
try {
|
|
11055
|
-
const fullPath =
|
|
11338
|
+
const fullPath = join16(projectPath, filePath);
|
|
11056
11339
|
const content = await readFile10(fullPath, "utf-8");
|
|
11057
11340
|
const packageJson = JSON.parse(content);
|
|
11058
11341
|
if (packageJson.scripts) {
|
|
@@ -11101,7 +11384,7 @@ async function handleGetPackageScripts(c, projectManager) {
|
|
|
11101
11384
|
|
|
11102
11385
|
// src/features/projects/projects-ai-files.route.ts
|
|
11103
11386
|
import { readdir as readdir6, readFile as readFile11, writeFile as writeFile2, mkdir, access as access2, rm } from "fs/promises";
|
|
11104
|
-
import { join as
|
|
11387
|
+
import { join as join17, extname as extname3, basename } from "path";
|
|
11105
11388
|
import { existsSync as existsSync11 } from "fs";
|
|
11106
11389
|
var IGNORED_DIRS = /* @__PURE__ */ new Set([
|
|
11107
11390
|
".git",
|
|
@@ -11120,8 +11403,8 @@ async function buildFullTree(dirPath, relativeDirPath) {
|
|
|
11120
11403
|
try {
|
|
11121
11404
|
const entries = await readdir6(dirPath, { withFileTypes: true });
|
|
11122
11405
|
for (const entry of entries) {
|
|
11123
|
-
const entryRelPath =
|
|
11124
|
-
const entryAbsPath =
|
|
11406
|
+
const entryRelPath = join17(relativeDirPath, entry.name);
|
|
11407
|
+
const entryAbsPath = join17(dirPath, entry.name);
|
|
11125
11408
|
if (entry.isDirectory()) {
|
|
11126
11409
|
const children = await buildFullTree(entryAbsPath, entryRelPath);
|
|
11127
11410
|
nodes.push({
|
|
@@ -11149,8 +11432,8 @@ async function buildMarkdownFilteredTree(dirPath, relativeDirPath) {
|
|
|
11149
11432
|
try {
|
|
11150
11433
|
const entries = await readdir6(dirPath, { withFileTypes: true });
|
|
11151
11434
|
for (const entry of entries) {
|
|
11152
|
-
const entryRelPath =
|
|
11153
|
-
const entryAbsPath =
|
|
11435
|
+
const entryRelPath = join17(relativeDirPath, entry.name);
|
|
11436
|
+
const entryAbsPath = join17(dirPath, entry.name);
|
|
11154
11437
|
if (entry.isDirectory()) {
|
|
11155
11438
|
if (IGNORED_DIRS.has(entry.name)) continue;
|
|
11156
11439
|
const children = await buildMarkdownFilteredTree(entryAbsPath, entryRelPath);
|
|
@@ -11185,8 +11468,8 @@ async function buildAIFileTree(projectPath) {
|
|
|
11185
11468
|
{ key: "agents", label: "Agents" }
|
|
11186
11469
|
];
|
|
11187
11470
|
for (const { key, label } of agentsFolders) {
|
|
11188
|
-
const relPath =
|
|
11189
|
-
const absPath =
|
|
11471
|
+
const relPath = join17(".agents", key);
|
|
11472
|
+
const absPath = join17(projectPath, relPath);
|
|
11190
11473
|
const exists = existsSync11(absPath);
|
|
11191
11474
|
if (exists) {
|
|
11192
11475
|
const children = await buildFullTree(absPath, relPath);
|
|
@@ -11221,7 +11504,7 @@ async function buildAIFileTree(projectPath) {
|
|
|
11221
11504
|
if (entry.name === ".agents" || entry.name === "AGENTS.md" || IGNORED_DIRS.has(entry.name))
|
|
11222
11505
|
continue;
|
|
11223
11506
|
const entryRelPath = entry.name;
|
|
11224
|
-
const entryAbsPath =
|
|
11507
|
+
const entryAbsPath = join17(projectPath, entry.name);
|
|
11225
11508
|
if (entry.isFile() && MARKDOWN_EXTS.has(extname3(entry.name))) {
|
|
11226
11509
|
nodes.push({
|
|
11227
11510
|
id: entryRelPath,
|
|
@@ -11248,7 +11531,7 @@ async function buildAIFileTree(projectPath) {
|
|
|
11248
11531
|
}
|
|
11249
11532
|
function validateFilePath(projectPath, filePath) {
|
|
11250
11533
|
if (!filePath) return null;
|
|
11251
|
-
const abs =
|
|
11534
|
+
const abs = join17(projectPath, filePath);
|
|
11252
11535
|
if (!abs.startsWith(projectPath + "/") && abs !== projectPath) return null;
|
|
11253
11536
|
return abs;
|
|
11254
11537
|
}
|
|
@@ -11374,7 +11657,7 @@ async function handleSaveAIFile(c, projectManager) {
|
|
|
11374
11657
|
if (!absPath) {
|
|
11375
11658
|
return c.json({ error: { code: "BAD_REQUEST", message: "Invalid file path" } }, 400);
|
|
11376
11659
|
}
|
|
11377
|
-
const parentDir =
|
|
11660
|
+
const parentDir = join17(absPath, "..");
|
|
11378
11661
|
await mkdir(parentDir, { recursive: true });
|
|
11379
11662
|
await writeFile2(absPath, content, "utf-8");
|
|
11380
11663
|
return c.json({ success: true, path: filePath });
|
|
@@ -11474,10 +11757,10 @@ async function handleCreateSkill(c, projectManager) {
|
|
|
11474
11757
|
if (!project) {
|
|
11475
11758
|
return errorResponse(c, ErrorCodes.PROJECT_NOT_FOUND, `Project not found: ${projectId}`, 404);
|
|
11476
11759
|
}
|
|
11477
|
-
const skillRelPath =
|
|
11478
|
-
const skillAbsPath =
|
|
11479
|
-
const skillFileRelPath =
|
|
11480
|
-
const skillFileAbsPath =
|
|
11760
|
+
const skillRelPath = join17(".agents", "skills", name);
|
|
11761
|
+
const skillAbsPath = join17(project.path, skillRelPath);
|
|
11762
|
+
const skillFileRelPath = join17(skillRelPath, "SKILL.md");
|
|
11763
|
+
const skillFileAbsPath = join17(skillAbsPath, "SKILL.md");
|
|
11481
11764
|
if (existsSync11(skillAbsPath)) {
|
|
11482
11765
|
return c.json(
|
|
11483
11766
|
{ error: { code: "CONFLICT", message: `Skill '${name}' already exists` } },
|
|
@@ -11579,7 +11862,7 @@ function createProjectRoutes(projectManager, threadManager) {
|
|
|
11579
11862
|
|
|
11580
11863
|
// src/features/projects/projects.manager.ts
|
|
11581
11864
|
init_utils();
|
|
11582
|
-
import { join as
|
|
11865
|
+
import { join as join20 } from "path";
|
|
11583
11866
|
import { realpathSync as realpathSync2 } from "fs";
|
|
11584
11867
|
import { rm as rm3 } from "fs/promises";
|
|
11585
11868
|
|
|
@@ -11800,13 +12083,13 @@ var ProcessManager = class extends EventEmitter {
|
|
|
11800
12083
|
// src/features/projects/projects.creator.ts
|
|
11801
12084
|
init_utils();
|
|
11802
12085
|
import { randomUUID as randomUUID7 } from "crypto";
|
|
11803
|
-
import { basename as basename2, join as
|
|
12086
|
+
import { basename as basename2, join as join19, relative as relative5 } from "path";
|
|
11804
12087
|
import { access as access3, stat as stat3, readdir as readdir8 } from "fs/promises";
|
|
11805
12088
|
|
|
11806
12089
|
// src/features/scaffold/scaffold.runner.ts
|
|
11807
12090
|
init_utils();
|
|
11808
12091
|
import { existsSync as existsSync12 } from "fs";
|
|
11809
|
-
import { join as
|
|
12092
|
+
import { join as join18 } from "path";
|
|
11810
12093
|
import { mkdir as mkdir2, readdir as readdir7, stat as stat2, rename, rm as rm2, writeFile as writeFile3 } from "fs/promises";
|
|
11811
12094
|
import { createInterface as createInterface2 } from "readline";
|
|
11812
12095
|
|
|
@@ -12528,7 +12811,7 @@ function loadCatalog() {
|
|
|
12528
12811
|
}
|
|
12529
12812
|
async function writeAgentsMd(projectPath, agentsMd) {
|
|
12530
12813
|
if (!agentsMd) return;
|
|
12531
|
-
const agentsPath =
|
|
12814
|
+
const agentsPath = join18(projectPath, "AGENTS.md");
|
|
12532
12815
|
if (existsSync12(agentsPath)) return;
|
|
12533
12816
|
await writeFile3(agentsPath, agentsMd, "utf-8");
|
|
12534
12817
|
}
|
|
@@ -12686,7 +12969,7 @@ async function* runCommandStreaming(cwd, command) {
|
|
|
12686
12969
|
}
|
|
12687
12970
|
}
|
|
12688
12971
|
async function* createScaffoldedProjectStreaming(options) {
|
|
12689
|
-
const projectPath =
|
|
12972
|
+
const projectPath = join18(options.parentDir, options.threadId);
|
|
12690
12973
|
if (!existsSync12(options.parentDir)) {
|
|
12691
12974
|
yield {
|
|
12692
12975
|
type: "result",
|
|
@@ -12776,7 +13059,7 @@ async function* createScaffoldedProjectStreaming(options) {
|
|
|
12776
13059
|
}
|
|
12777
13060
|
try {
|
|
12778
13061
|
const projectName2 = getProjectName(options.projectName);
|
|
12779
|
-
const projectSubDir =
|
|
13062
|
+
const projectSubDir = join18(projectPath, projectName2);
|
|
12780
13063
|
try {
|
|
12781
13064
|
const subDirStat = await stat2(projectSubDir);
|
|
12782
13065
|
if (subDirStat.isDirectory()) {
|
|
@@ -12786,8 +13069,8 @@ async function* createScaffoldedProjectStreaming(options) {
|
|
|
12786
13069
|
};
|
|
12787
13070
|
const items = await readdir7(projectSubDir);
|
|
12788
13071
|
for (const item of items) {
|
|
12789
|
-
const oldPath =
|
|
12790
|
-
const newPath =
|
|
13072
|
+
const oldPath = join18(projectSubDir, item);
|
|
13073
|
+
const newPath = join18(projectPath, item);
|
|
12791
13074
|
await rename(oldPath, newPath);
|
|
12792
13075
|
}
|
|
12793
13076
|
await rm2(projectSubDir, { recursive: true, force: true });
|
|
@@ -13255,7 +13538,7 @@ var ProjectCreator = class {
|
|
|
13255
13538
|
return name;
|
|
13256
13539
|
}
|
|
13257
13540
|
generateThreadPath(_projectId, threadId) {
|
|
13258
|
-
return
|
|
13541
|
+
return join19(this.rootFolder, threadId);
|
|
13259
13542
|
}
|
|
13260
13543
|
async *createProjectFromFolder() {
|
|
13261
13544
|
await loadUtils();
|
|
@@ -13405,19 +13688,19 @@ var ProjectCreator = class {
|
|
|
13405
13688
|
}
|
|
13406
13689
|
async findAllPackageJsonFiles(rootPath, currentPath, setupScripts) {
|
|
13407
13690
|
try {
|
|
13408
|
-
await access3(
|
|
13691
|
+
await access3(join19(currentPath, "package.json"));
|
|
13409
13692
|
const relativePath = relative5(rootPath, currentPath);
|
|
13410
13693
|
let installCommand = "";
|
|
13411
13694
|
try {
|
|
13412
|
-
await access3(
|
|
13695
|
+
await access3(join19(currentPath, "yarn.lock"));
|
|
13413
13696
|
installCommand = "yarn install";
|
|
13414
13697
|
} catch {
|
|
13415
13698
|
try {
|
|
13416
|
-
await access3(
|
|
13699
|
+
await access3(join19(currentPath, "bun.lock"));
|
|
13417
13700
|
installCommand = "bun install";
|
|
13418
13701
|
} catch {
|
|
13419
13702
|
try {
|
|
13420
|
-
await access3(
|
|
13703
|
+
await access3(join19(currentPath, "pnpm-lock.yaml"));
|
|
13421
13704
|
installCommand = "pnpm install";
|
|
13422
13705
|
} catch {
|
|
13423
13706
|
installCommand = "npm install";
|
|
@@ -13434,7 +13717,7 @@ var ProjectCreator = class {
|
|
|
13434
13717
|
try {
|
|
13435
13718
|
const entries = await readdir8(currentPath);
|
|
13436
13719
|
for (const entry of entries) {
|
|
13437
|
-
const entryPath =
|
|
13720
|
+
const entryPath = join19(currentPath, entry);
|
|
13438
13721
|
try {
|
|
13439
13722
|
const stats = await stat3(entryPath);
|
|
13440
13723
|
if (stats.isDirectory() && !entry.startsWith(".") && entry !== "node_modules") {
|
|
@@ -13774,7 +14057,7 @@ var ProjectManagerImpl = class {
|
|
|
13774
14057
|
const session = this.terminalSessionManager.getOrCreateSession(threadId, thread.path);
|
|
13775
14058
|
let workingDir;
|
|
13776
14059
|
if (cwd) {
|
|
13777
|
-
workingDir = cwd.startsWith("/") ? cwd :
|
|
14060
|
+
workingDir = cwd.startsWith("/") ? cwd : join20(thread.path, cwd);
|
|
13778
14061
|
this.terminalSessionManager.updateWorkingDirectory(threadId, workingDir);
|
|
13779
14062
|
} else {
|
|
13780
14063
|
workingDir = session.currentWorkingDirectory;
|
|
@@ -13977,80 +14260,59 @@ ___CWD___%s
|
|
|
13977
14260
|
// src/features/providers/providers.routes.ts
|
|
13978
14261
|
import { Hono as Hono7 } from "hono";
|
|
13979
14262
|
|
|
13980
|
-
// src/
|
|
13981
|
-
|
|
13982
|
-
|
|
13983
|
-
|
|
13984
|
-
const envPath = join20(process.cwd(), ".env");
|
|
13985
|
-
let content = "";
|
|
13986
|
-
try {
|
|
13987
|
-
content = await fs.readFile(envPath, "utf-8");
|
|
13988
|
-
} catch {
|
|
13989
|
-
}
|
|
13990
|
-
const lines = content.split("\n");
|
|
13991
|
-
const envMap = {};
|
|
13992
|
-
for (const line of lines) {
|
|
13993
|
-
const trimmed = line.trim();
|
|
13994
|
-
if (trimmed && !trimmed.startsWith("#") && trimmed.includes("=")) {
|
|
13995
|
-
const index = trimmed.indexOf("=");
|
|
13996
|
-
const key = trimmed.substring(0, index).trim();
|
|
13997
|
-
const value = trimmed.substring(index + 1).trim();
|
|
13998
|
-
envMap[key] = value;
|
|
13999
|
-
}
|
|
14000
|
-
}
|
|
14001
|
-
for (const [key, value] of Object.entries(keyNames)) {
|
|
14002
|
-
if (key) {
|
|
14003
|
-
envMap[key] = value;
|
|
14004
|
-
}
|
|
14005
|
-
}
|
|
14006
|
-
const newLines = [];
|
|
14007
|
-
for (const [key, value] of Object.entries(envMap)) {
|
|
14008
|
-
newLines.push(`${key}=${value}`);
|
|
14263
|
+
// src/features/providers/providers-get.route.ts
|
|
14264
|
+
function getProviderApiKeyEnvName2(providerEnv) {
|
|
14265
|
+
if (providerEnv.length === 0) {
|
|
14266
|
+
return "";
|
|
14009
14267
|
}
|
|
14010
|
-
|
|
14268
|
+
const explicitApiKeyEnv = providerEnv.find((envName) => /api_key$/i.test(envName));
|
|
14269
|
+
return explicitApiKeyEnv ?? providerEnv[providerEnv.length - 1];
|
|
14011
14270
|
}
|
|
14012
|
-
|
|
14013
|
-
const
|
|
14014
|
-
|
|
14015
|
-
|
|
14016
|
-
|
|
14017
|
-
|
|
14018
|
-
|
|
14019
|
-
|
|
14020
|
-
|
|
14021
|
-
const index = trimmed.indexOf("=");
|
|
14022
|
-
const key = trimmed.substring(0, index).trim();
|
|
14023
|
-
const value = trimmed.substring(index + 1).trim();
|
|
14024
|
-
envMap[key] = value;
|
|
14025
|
-
}
|
|
14026
|
-
}
|
|
14027
|
-
} catch {
|
|
14271
|
+
function getProviderResourceName2(providerEnv) {
|
|
14272
|
+
const explicitResourceEnv = providerEnv.find((envName) => /resource_name$/i.test(envName));
|
|
14273
|
+
return explicitResourceEnv ?? providerEnv[0] ?? "";
|
|
14274
|
+
}
|
|
14275
|
+
function resolveAzureApiUrl2(providerEnv, envValues) {
|
|
14276
|
+
const resourceEnvName = getProviderResourceName2(providerEnv);
|
|
14277
|
+
const resourceName = envValues[resourceEnvName] ?? "";
|
|
14278
|
+
if (!resourceName) {
|
|
14279
|
+
return "";
|
|
14028
14280
|
}
|
|
14029
|
-
return
|
|
14281
|
+
return `https://${resourceName}.openai.azure.com/openai/v1`;
|
|
14030
14282
|
}
|
|
14031
|
-
|
|
14032
|
-
// src/features/providers/providers-get.route.ts
|
|
14033
14283
|
async function getProviders(c, metadataManager) {
|
|
14034
14284
|
const keys = await metadataManager.getProviderKeys();
|
|
14285
|
+
const persistedEnvValues = await metadataManager.getProviderEnvValues();
|
|
14035
14286
|
const envFileKeys = await readEnvFile();
|
|
14036
14287
|
const catalog = await getModelsCatalog();
|
|
14037
14288
|
const providersWithKeys = [];
|
|
14038
14289
|
if (catalog) {
|
|
14039
14290
|
for (const [catalogId, catalogProvider] of Object.entries(catalog)) {
|
|
14040
|
-
const
|
|
14291
|
+
const envNames = catalogProvider.env ?? [];
|
|
14292
|
+
const keyName = getProviderApiKeyEnvName2(envNames);
|
|
14293
|
+
const envValues = {};
|
|
14294
|
+
for (const envName of envNames) {
|
|
14295
|
+
envValues[envName] = envFileKeys[envName] ?? process.env[envName] ?? persistedEnvValues[envName] ?? "";
|
|
14296
|
+
}
|
|
14041
14297
|
const envFileKey = keyName ? envFileKeys[keyName] : "";
|
|
14042
14298
|
const processEnvKey = keyName ? process.env[keyName] : "";
|
|
14043
14299
|
const storedKey = keys[catalogProvider.name] || keys[catalogId];
|
|
14044
14300
|
const hasEnvKey = Boolean(envFileKey || processEnvKey);
|
|
14045
14301
|
const resolvedKey = storedKey ?? envFileKey ?? processEnvKey ?? "";
|
|
14046
14302
|
const isEnv = !storedKey && hasEnvKey && resolvedKey !== "";
|
|
14303
|
+
const api = catalogId === "azure" ? resolveAzureApiUrl2(envNames, envValues) : catalogProvider.api ?? "";
|
|
14304
|
+
if (keyName && !envValues[keyName]) {
|
|
14305
|
+
envValues[keyName] = resolvedKey;
|
|
14306
|
+
}
|
|
14047
14307
|
providersWithKeys.push({
|
|
14048
14308
|
name: catalogProvider.name ?? catalogId,
|
|
14049
14309
|
slug: catalogId,
|
|
14050
14310
|
url: catalogProvider.doc ?? "",
|
|
14051
14311
|
keyName,
|
|
14052
14312
|
authType: "APIKey",
|
|
14053
|
-
api
|
|
14313
|
+
api,
|
|
14314
|
+
env: envNames,
|
|
14315
|
+
envValues,
|
|
14054
14316
|
apiKey: resolvedKey,
|
|
14055
14317
|
isEnv
|
|
14056
14318
|
});
|
|
@@ -14069,6 +14331,7 @@ async function postProviderKeys(c, metadataManager) {
|
|
|
14069
14331
|
await metadataManager.saveProviderKey(providerName, apiKey);
|
|
14070
14332
|
const keyName = await resolveProviderKeyName(providerName);
|
|
14071
14333
|
if (keyName) {
|
|
14334
|
+
updateRuntimeEnv({ [keyName]: apiKey });
|
|
14072
14335
|
await updateEnvFile({ [keyName]: apiKey });
|
|
14073
14336
|
}
|
|
14074
14337
|
return c.json({ success: true });
|
|
@@ -14093,6 +14356,7 @@ async function postProviderBulkKeys(c, metadataManager) {
|
|
|
14093
14356
|
}
|
|
14094
14357
|
}
|
|
14095
14358
|
if (Object.keys(envUpdates).length > 0) {
|
|
14359
|
+
updateRuntimeEnv(envUpdates);
|
|
14096
14360
|
await updateEnvFile(envUpdates);
|
|
14097
14361
|
}
|
|
14098
14362
|
return c.json({ success: true });
|
|
@@ -14101,6 +14365,28 @@ async function postProviderBulkKeys(c, metadataManager) {
|
|
|
14101
14365
|
}
|
|
14102
14366
|
}
|
|
14103
14367
|
|
|
14368
|
+
// src/features/providers/providers-post-env.route.ts
|
|
14369
|
+
async function postProviderEnv(c, metadataManager) {
|
|
14370
|
+
try {
|
|
14371
|
+
const { values } = await c.req.json();
|
|
14372
|
+
if (!values || typeof values !== "object") {
|
|
14373
|
+
return c.json({ error: "values object is required" }, 400);
|
|
14374
|
+
}
|
|
14375
|
+
const envValues = {};
|
|
14376
|
+
for (const [key, value] of Object.entries(values)) {
|
|
14377
|
+
if (typeof value === "string") {
|
|
14378
|
+
envValues[key] = value;
|
|
14379
|
+
}
|
|
14380
|
+
}
|
|
14381
|
+
await metadataManager.saveProviderEnvValues(envValues);
|
|
14382
|
+
updateRuntimeEnv(envValues);
|
|
14383
|
+
await updateEnvFile(envValues);
|
|
14384
|
+
return c.json({ success: true });
|
|
14385
|
+
} catch (error) {
|
|
14386
|
+
return c.json({ error: `Failed to save provider environment: ${String(error)}` }, 500);
|
|
14387
|
+
}
|
|
14388
|
+
}
|
|
14389
|
+
|
|
14104
14390
|
// src/features/models/model-info-openrouter.ts
|
|
14105
14391
|
async function getOpenRouterCredits(apiKey) {
|
|
14106
14392
|
try {
|
|
@@ -14196,13 +14482,24 @@ async function getProviderCredits(c, metadataManager) {
|
|
|
14196
14482
|
// src/features/providers/providers-get-logo.route.ts
|
|
14197
14483
|
var LOGO_BASE_URL = "https://models.tarsk.io/svg";
|
|
14198
14484
|
var SLUG_PATTERN = /^[a-z0-9._-]+$/i;
|
|
14485
|
+
var logoCache = /* @__PURE__ */ new Map();
|
|
14486
|
+
var LOGO_CACHE_TTL_MS = 15 * 60 * 1e3;
|
|
14199
14487
|
async function getProviderLogo(c) {
|
|
14200
14488
|
const slug = c.req.param("slug");
|
|
14201
14489
|
if (!slug || !SLUG_PATTERN.test(slug)) {
|
|
14202
14490
|
return c.body(null, 404);
|
|
14203
14491
|
}
|
|
14492
|
+
const cached = logoCache.get(slug);
|
|
14493
|
+
if (cached && Date.now() < cached.expires) {
|
|
14494
|
+
return c.body(cached.svg, 200, {
|
|
14495
|
+
"Content-Type": "image/svg+xml",
|
|
14496
|
+
"Cache-Control": "public, max-age=86400"
|
|
14497
|
+
});
|
|
14498
|
+
}
|
|
14204
14499
|
try {
|
|
14205
|
-
const response = await fetch(`${LOGO_BASE_URL}/${slug}.svg`, {
|
|
14500
|
+
const response = await fetch(`${LOGO_BASE_URL}/${slug}.svg`, {
|
|
14501
|
+
signal: AbortSignal.timeout(5e3)
|
|
14502
|
+
});
|
|
14206
14503
|
if (!response.ok) {
|
|
14207
14504
|
return c.body(null, 404);
|
|
14208
14505
|
}
|
|
@@ -14210,6 +14507,7 @@ async function getProviderLogo(c) {
|
|
|
14210
14507
|
if (!svg.includes("<svg")) {
|
|
14211
14508
|
return c.body(null, 404);
|
|
14212
14509
|
}
|
|
14510
|
+
logoCache.set(slug, { svg, expires: Date.now() + LOGO_CACHE_TTL_MS });
|
|
14213
14511
|
return c.body(svg, 200, {
|
|
14214
14512
|
"Content-Type": "image/svg+xml",
|
|
14215
14513
|
"Cache-Control": "public, max-age=86400"
|
|
@@ -14262,6 +14560,7 @@ function createProviderRoutes(metadataManager) {
|
|
|
14262
14560
|
router.get("/", (c) => getProviders(c, metadataManager));
|
|
14263
14561
|
router.post("/keys", (c) => postProviderKeys(c, metadataManager));
|
|
14264
14562
|
router.post("/bulk-keys", (c) => postProviderBulkKeys(c, metadataManager));
|
|
14563
|
+
router.post("/env", (c) => postProviderEnv(c, metadataManager));
|
|
14265
14564
|
router.get("/:name/credits", (c) => getProviderCredits(c, metadataManager));
|
|
14266
14565
|
router.get("/:slug/logo", (c) => getProviderLogo(c));
|
|
14267
14566
|
router.post("/open-external", (c) => openExternalUrl(c));
|
|
@@ -14512,7 +14811,7 @@ function createScaffoldRoutes(projectManager) {
|
|
|
14512
14811
|
|
|
14513
14812
|
// src/features/slash-commands/slash-commands.manager.ts
|
|
14514
14813
|
import { readdir as readdir9, readFile as readFile12, mkdir as mkdir3, writeFile as writeFile4, unlink as unlink2 } from "fs/promises";
|
|
14515
|
-
import { join as join21, basename as basename3, extname as extname4 } from "path";
|
|
14814
|
+
import { join as join21, basename as basename3, extname as extname4, relative as relative6 } from "path";
|
|
14516
14815
|
import { existsSync as existsSync13 } from "fs";
|
|
14517
14816
|
import { homedir as homedir7 } from "os";
|
|
14518
14817
|
function slugify(filename) {
|
|
@@ -14593,14 +14892,14 @@ var SlashCommandManager = class _SlashCommandManager {
|
|
|
14593
14892
|
const commands = /* @__PURE__ */ new Map();
|
|
14594
14893
|
const globalDir = getGlobalCommandsDir();
|
|
14595
14894
|
if (existsSync13(globalDir)) {
|
|
14596
|
-
const globalCommands = await this.loadCommandsFromDir(globalDir, "global");
|
|
14895
|
+
const globalCommands = await this.loadCommandsFromDir(globalDir, threadPath, "global");
|
|
14597
14896
|
for (const cmd of globalCommands) {
|
|
14598
14897
|
commands.set(cmd.name, cmd);
|
|
14599
14898
|
}
|
|
14600
14899
|
}
|
|
14601
14900
|
const projectDir = getProjectCommandsDir(threadPath);
|
|
14602
14901
|
if (existsSync13(projectDir)) {
|
|
14603
|
-
const projectCommands = await this.loadCommandsFromDir(projectDir, "project");
|
|
14902
|
+
const projectCommands = await this.loadCommandsFromDir(projectDir, threadPath, "project");
|
|
14604
14903
|
for (const cmd of projectCommands) {
|
|
14605
14904
|
if (!_SlashCommandManager.BUILT_IN_COMMANDS.has(cmd.name)) {
|
|
14606
14905
|
commands.set(cmd.name, cmd);
|
|
@@ -14617,7 +14916,7 @@ var SlashCommandManager = class _SlashCommandManager {
|
|
|
14617
14916
|
/**
|
|
14618
14917
|
* Load commands from a specific directory
|
|
14619
14918
|
*/
|
|
14620
|
-
async loadCommandsFromDir(dir, scope) {
|
|
14919
|
+
async loadCommandsFromDir(dir, threadPath, scope) {
|
|
14621
14920
|
const commands = [];
|
|
14622
14921
|
try {
|
|
14623
14922
|
const files = await readdir9(dir);
|
|
@@ -14634,7 +14933,7 @@ var SlashCommandManager = class _SlashCommandManager {
|
|
|
14634
14933
|
content,
|
|
14635
14934
|
metadata,
|
|
14636
14935
|
scope,
|
|
14637
|
-
filePath
|
|
14936
|
+
filePath: scope === "project" ? relative6(threadPath, filePath) : filePath
|
|
14638
14937
|
});
|
|
14639
14938
|
}
|
|
14640
14939
|
} catch (error) {
|
|
@@ -15855,7 +16154,7 @@ async function handleDeleteThread(c, threadManager) {
|
|
|
15855
16154
|
// src/core/project-inspector.ts
|
|
15856
16155
|
import { readFile as readFile13, readdir as readdir10 } from "fs/promises";
|
|
15857
16156
|
import { existsSync as existsSync14 } from "fs";
|
|
15858
|
-
import { join as join23, basename as basename4, relative as
|
|
16157
|
+
import { join as join23, basename as basename4, relative as relative7 } from "path";
|
|
15859
16158
|
import { glob as glob2 } from "glob";
|
|
15860
16159
|
|
|
15861
16160
|
// src/features/project-scripts/project-scripts.database.ts
|
|
@@ -16205,7 +16504,7 @@ function buildRunCommand(scriptName, workspace, packageManager, repoType, projec
|
|
|
16205
16504
|
return `npm run ${scriptName} --workspace=${workspace.relativePath}`;
|
|
16206
16505
|
}
|
|
16207
16506
|
if (!isRoot) {
|
|
16208
|
-
const relPath =
|
|
16507
|
+
const relPath = relative7(projectPath, workspace.folder);
|
|
16209
16508
|
return `cd ${relPath} && ${runCmd}`;
|
|
16210
16509
|
}
|
|
16211
16510
|
return runCmd;
|
|
@@ -17964,7 +18263,7 @@ import { completeSimple } from "@mariozechner/pi-ai";
|
|
|
17964
18263
|
async function resolveModelAndKey(provider, modelId, metadataManager) {
|
|
17965
18264
|
const providerConfig = await resolveProviderConfig(provider);
|
|
17966
18265
|
if (!providerConfig) return null;
|
|
17967
|
-
let apiKey = providerConfig.
|
|
18266
|
+
let apiKey = providerConfig.apiKeyEnv ? process.env[providerConfig.apiKeyEnv] : void 0;
|
|
17968
18267
|
if (!apiKey) {
|
|
17969
18268
|
const providerKeys = await metadataManager.getProviderKeys();
|
|
17970
18269
|
apiKey = providerKeys[providerConfig.id];
|
|
@@ -19894,15 +20193,6 @@ async function gitSyncBranchHandler(c, metadataManager) {
|
|
|
19894
20193
|
400
|
|
19895
20194
|
);
|
|
19896
20195
|
}
|
|
19897
|
-
if (currentBranch === defaultBranch) {
|
|
19898
|
-
console.log(`[sync-branch] Already on default branch: ${defaultBranch}`);
|
|
19899
|
-
return c.json(
|
|
19900
|
-
{
|
|
19901
|
-
error: `Already on default branch (${defaultBranch})`
|
|
19902
|
-
},
|
|
19903
|
-
400
|
|
19904
|
-
);
|
|
19905
|
-
}
|
|
19906
20196
|
const { spawnProcess: spawnProcess2 } = await Promise.resolve().then(() => (init_utils(), utils_exports));
|
|
19907
20197
|
return new Promise((resolve6) => {
|
|
19908
20198
|
console.log(`[sync-branch] Checking branch status...`);
|
|
@@ -20038,13 +20328,12 @@ async function gitSyncBranchHandler(c, metadataManager) {
|
|
|
20038
20328
|
}
|
|
20039
20329
|
pullProc.on("close", (code) => {
|
|
20040
20330
|
if (code === 0) {
|
|
20041
|
-
|
|
20042
|
-
|
|
20043
|
-
);
|
|
20331
|
+
const message = currentBranch === defaultBranch ? `Successfully pulled latest changes from origin/${defaultBranch}` : `Successfully synced ${currentBranch} with ${defaultBranch}`;
|
|
20332
|
+
console.log(`[sync-branch] \u2713 ${message}`);
|
|
20044
20333
|
resolve6(
|
|
20045
20334
|
c.json({
|
|
20046
20335
|
success: true,
|
|
20047
|
-
message
|
|
20336
|
+
message,
|
|
20048
20337
|
branch: currentBranch,
|
|
20049
20338
|
defaultBranch
|
|
20050
20339
|
})
|
|
@@ -21204,7 +21493,7 @@ async function generateImage(c, metadataManager, conversationManager, threadMana
|
|
|
21204
21493
|
if (!providerConfig) {
|
|
21205
21494
|
return c.json({ error: `Unknown provider: ${provider}` }, 400);
|
|
21206
21495
|
}
|
|
21207
|
-
let apiKey = providerConfig.
|
|
21496
|
+
let apiKey = providerConfig.apiKeyEnv ? process.env[providerConfig.apiKeyEnv] : void 0;
|
|
21208
21497
|
if (!apiKey) {
|
|
21209
21498
|
const providerKeys = await metadataManager.getProviderKeys();
|
|
21210
21499
|
apiKey = providerKeys[providerConfig.id];
|
|
@@ -21631,6 +21920,7 @@ async function startTarskServer(options) {
|
|
|
21631
21920
|
const conversationManager = new ConversationManagerImpl(dataDir);
|
|
21632
21921
|
const agentExecutor = new PiExecutorImpl(metadataManager);
|
|
21633
21922
|
await metadataManager.initialize();
|
|
21923
|
+
updateRuntimeEnv(await metadataManager.getProviderEnvValues());
|
|
21634
21924
|
await conversationManager.initialize();
|
|
21635
21925
|
app.get("/health", (c) => {
|
|
21636
21926
|
return c.json({
|