@docyrus/docyrus 0.0.30 → 0.0.32
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/agent-loader.js +36 -25
- package/agent-loader.js.map +4 -4
- package/main.js +4 -4
- package/main.js.map +1 -1
- package/package.json +3 -3
- package/resources/pi-agent/extensions/docyrus-web-browser.ts +31 -0
- package/resources/pi-agent/shared/docyrusWebBrowserProtocol.ts +169 -0
- package/resources/pi-agent/skills/diffity-diff/SKILL.md +1 -1
- package/resources/pi-agent/skills/diffity-resolve/SKILL.md +4 -4
- package/resources/pi-agent/skills/diffity-review/SKILL.md +5 -4
- package/resources/pi-agent/skills/docyrus-api-dev/SKILL.md +197 -0
- package/resources/pi-agent/skills/docyrus-api-dev/references/acl-endpoints-frontend.md +295 -0
- package/resources/pi-agent/skills/docyrus-api-dev/references/api-client.md +349 -0
- package/resources/pi-agent/skills/docyrus-api-dev/references/authentication.md +298 -0
- package/resources/pi-agent/skills/docyrus-api-dev/references/data-source-query-guide.md +2063 -0
- package/resources/pi-agent/skills/docyrus-api-dev/references/formula-design-guide-llm.md +312 -0
- package/resources/pi-agent/skills/docyrus-api-dev/references/query-and-formulas.md +592 -0
- package/resources/pi-agent/skills/docyrus-app-dev-react/SKILL.md +361 -0
- package/resources/pi-agent/skills/docyrus-app-dev-react/references/README.md +29 -0
- package/resources/pi-agent/skills/docyrus-app-dev-react/references/api-client-and-auth.md +326 -0
- package/resources/pi-agent/skills/docyrus-app-dev-react/references/collections-and-patterns.md +353 -0
- package/resources/pi-agent/skills/docyrus-app-dev-react/references/component-selection-guide.md +619 -0
- package/resources/pi-agent/skills/docyrus-app-dev-react/references/icon-usage-guide.md +463 -0
- package/resources/pi-agent/skills/docyrus-app-dev-react/references/preferred-components-catalog.md +242 -0
- package/resources/pi-agent/skills/docyrus-platform/SKILL.md +2 -2
- package/resources/pi-agent/skills/docyrus-platform/references/auth-and-multi-tenancy.md +9 -1
- package/resources/pi-agent/skills/docyrus-platform/references/developer-tools.md +3 -2
- package/server-loader.js +328 -87
- package/server-loader.js.map +4 -4
- package/resources/pi-agent/extensions/multi-edit.ts +0 -835
package/server-loader.js
CHANGED
|
@@ -690,9 +690,9 @@ var init_dist = __esm({
|
|
|
690
690
|
});
|
|
691
691
|
|
|
692
692
|
// src/server/server-loader.ts
|
|
693
|
-
var
|
|
693
|
+
var import_node_fs2 = require("node:fs");
|
|
694
694
|
var import_node_url = require("node:url");
|
|
695
|
-
var
|
|
695
|
+
var import_node_path7 = require("node:path");
|
|
696
696
|
var import_picocolors2 = __toESM(require_picocolors());
|
|
697
697
|
|
|
698
698
|
// src/agent/envStore.ts
|
|
@@ -793,11 +793,31 @@ var AgentEnvStore = class {
|
|
|
793
793
|
}
|
|
794
794
|
};
|
|
795
795
|
|
|
796
|
+
// src/agent/packagedExtensions.ts
|
|
797
|
+
var import_node_fs = require("node:fs");
|
|
798
|
+
var import_node_path2 = require("node:path");
|
|
799
|
+
var SERVER_ONLY_PACKAGED_EXTENSION_NAMES = /* @__PURE__ */ new Set(["docyrus-web-browser"]);
|
|
800
|
+
function isPackagedExtensionEntry(entryName, isDirectory) {
|
|
801
|
+
return isDirectory || entryName.endsWith(".ts") || entryName.endsWith(".js");
|
|
802
|
+
}
|
|
803
|
+
function getPackagedExtensionName(entryName) {
|
|
804
|
+
return entryName.replace(/\.(ts|js)$/u, "");
|
|
805
|
+
}
|
|
806
|
+
function resolvePackagedExtensionPaths(resourceRoot, runtime = "terminal") {
|
|
807
|
+
const extensionsRoot = (0, import_node_path2.join)(resourceRoot, "extensions");
|
|
808
|
+
if (!(0, import_node_fs.existsSync)(extensionsRoot)) {
|
|
809
|
+
return [];
|
|
810
|
+
}
|
|
811
|
+
return (0, import_node_fs.readdirSync)(extensionsRoot, {
|
|
812
|
+
withFileTypes: true
|
|
813
|
+
}).filter((entry) => isPackagedExtensionEntry(entry.name, entry.isDirectory())).filter((entry) => runtime === "server" || !SERVER_ONLY_PACKAGED_EXTENSION_NAMES.has(getPackagedExtensionName(entry.name))).map((entry) => (0, import_node_path2.join)(extensionsRoot, entry.name)).sort((left, right) => left.localeCompare(right));
|
|
814
|
+
}
|
|
815
|
+
|
|
796
816
|
// src/server/agentServer.ts
|
|
797
817
|
var import_node_child_process = require("node:child_process");
|
|
798
818
|
var import_node_crypto3 = require("node:crypto");
|
|
799
819
|
var import_promises5 = require("node:fs/promises");
|
|
800
|
-
var
|
|
820
|
+
var import_node_path6 = require("node:path");
|
|
801
821
|
|
|
802
822
|
// ../../node_modules/.pnpm/hono@4.12.8/node_modules/hono/dist/compose.js
|
|
803
823
|
var compose = (middleware, onError, onNotFound) => {
|
|
@@ -3105,9 +3125,122 @@ function parseAskUserResponseFromToolOutput(output) {
|
|
|
3105
3125
|
return normalizeAskUserResponse(output);
|
|
3106
3126
|
}
|
|
3107
3127
|
|
|
3128
|
+
// resources/pi-agent/shared/docyrusWebBrowserProtocol.ts
|
|
3129
|
+
var DOCYRUS_WEB_BROWSER_TAG = "docyrus_web_browser";
|
|
3130
|
+
var DOCYRUS_WEB_BROWSER_OPEN = `<${DOCYRUS_WEB_BROWSER_TAG}>`;
|
|
3131
|
+
var DOCYRUS_WEB_BROWSER_CLOSE = `</${DOCYRUS_WEB_BROWSER_TAG}>`;
|
|
3132
|
+
var DOCYRUS_WEB_BROWSER_RESULT_TAG = "docyrus_web_browser_result";
|
|
3133
|
+
var DOCYRUS_WEB_BROWSER_RESULT_OPEN = `<${DOCYRUS_WEB_BROWSER_RESULT_TAG}>`;
|
|
3134
|
+
var DOCYRUS_WEB_BROWSER_RESULT_CLOSE = `</${DOCYRUS_WEB_BROWSER_RESULT_TAG}>`;
|
|
3135
|
+
var WEB_PREVIEW_CONTEXT_TOOL = "web_preview_context";
|
|
3136
|
+
var WEB_PREVIEW_PLAYWRIGHT_TOOL = "web_preview_playwright";
|
|
3137
|
+
var DOCYRUS_WEB_BROWSER_TOOL_NAMES = [
|
|
3138
|
+
WEB_PREVIEW_CONTEXT_TOOL,
|
|
3139
|
+
WEB_PREVIEW_PLAYWRIGHT_TOOL
|
|
3140
|
+
];
|
|
3141
|
+
var DOCYRUS_WEB_BROWSER_CLIENT_TOOLS = [
|
|
3142
|
+
{
|
|
3143
|
+
name: WEB_PREVIEW_CONTEXT_TOOL,
|
|
3144
|
+
description: "Inspect the current Docyrus web preview state before automation. Prefer this first when preview availability or bridge state is unknown.",
|
|
3145
|
+
inputSchema: {
|
|
3146
|
+
type: "object",
|
|
3147
|
+
properties: {
|
|
3148
|
+
includeSnapshot: { type: "boolean" }
|
|
3149
|
+
},
|
|
3150
|
+
additionalProperties: false
|
|
3151
|
+
}
|
|
3152
|
+
},
|
|
3153
|
+
{
|
|
3154
|
+
name: WEB_PREVIEW_PLAYWRIGHT_TOOL,
|
|
3155
|
+
description: "Run Playwright-style actions against the Docyrus web preview. Prefer structured steps over raw scripts.",
|
|
3156
|
+
inputSchema: {
|
|
3157
|
+
type: "object",
|
|
3158
|
+
properties: {
|
|
3159
|
+
script: { type: "string" },
|
|
3160
|
+
steps: {
|
|
3161
|
+
type: "array",
|
|
3162
|
+
items: {
|
|
3163
|
+
type: "object",
|
|
3164
|
+
properties: {
|
|
3165
|
+
action: { type: "string" },
|
|
3166
|
+
selector: { type: "string" },
|
|
3167
|
+
url: { type: "string" },
|
|
3168
|
+
value: { type: "string" },
|
|
3169
|
+
values: {
|
|
3170
|
+
type: "array",
|
|
3171
|
+
items: { type: "string" }
|
|
3172
|
+
},
|
|
3173
|
+
key: { type: "string" },
|
|
3174
|
+
attribute: { type: "string" },
|
|
3175
|
+
timeoutMs: { type: "number" },
|
|
3176
|
+
state: { type: "string" }
|
|
3177
|
+
},
|
|
3178
|
+
additionalProperties: true
|
|
3179
|
+
}
|
|
3180
|
+
},
|
|
3181
|
+
timeoutMs: { type: "number" },
|
|
3182
|
+
stopOnError: { type: "boolean" }
|
|
3183
|
+
},
|
|
3184
|
+
additionalProperties: true
|
|
3185
|
+
}
|
|
3186
|
+
}
|
|
3187
|
+
];
|
|
3188
|
+
function hashString2(value) {
|
|
3189
|
+
let hash = 0;
|
|
3190
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
3191
|
+
hash = (hash << 5) - hash + value.charCodeAt(index);
|
|
3192
|
+
hash |= 0;
|
|
3193
|
+
}
|
|
3194
|
+
return Math.abs(hash).toString(36);
|
|
3195
|
+
}
|
|
3196
|
+
function isRecord2(value) {
|
|
3197
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3198
|
+
}
|
|
3199
|
+
function isDocyrusWebBrowserToolName(value) {
|
|
3200
|
+
return DOCYRUS_WEB_BROWSER_TOOL_NAMES.some((toolName) => toolName === value);
|
|
3201
|
+
}
|
|
3202
|
+
function normalizeDocyrusWebBrowserToolRequest(value) {
|
|
3203
|
+
if (!isRecord2(value) || !isDocyrusWebBrowserToolName(value.tool)) {
|
|
3204
|
+
return void 0;
|
|
3205
|
+
}
|
|
3206
|
+
return {
|
|
3207
|
+
tool: value.tool,
|
|
3208
|
+
input: isRecord2(value.input) ? value.input : void 0
|
|
3209
|
+
};
|
|
3210
|
+
}
|
|
3211
|
+
function createDocyrusWebBrowserToolCallId(request) {
|
|
3212
|
+
return `docyrus_web_browser_${hashString2(JSON.stringify(request))}`;
|
|
3213
|
+
}
|
|
3214
|
+
function parseDocyrusWebBrowserRequestFromText(text) {
|
|
3215
|
+
const trimmed = text.trim();
|
|
3216
|
+
if (!trimmed.startsWith(DOCYRUS_WEB_BROWSER_OPEN) || !trimmed.endsWith(DOCYRUS_WEB_BROWSER_CLOSE)) {
|
|
3217
|
+
return void 0;
|
|
3218
|
+
}
|
|
3219
|
+
const body = trimmed.slice(DOCYRUS_WEB_BROWSER_OPEN.length, trimmed.length - DOCYRUS_WEB_BROWSER_CLOSE.length).trim();
|
|
3220
|
+
if (!body) {
|
|
3221
|
+
return void 0;
|
|
3222
|
+
}
|
|
3223
|
+
try {
|
|
3224
|
+
return normalizeDocyrusWebBrowserToolRequest(JSON.parse(body));
|
|
3225
|
+
} catch {
|
|
3226
|
+
return void 0;
|
|
3227
|
+
}
|
|
3228
|
+
}
|
|
3229
|
+
function formatDocyrusWebBrowserToolResponsePrompt(response) {
|
|
3230
|
+
return [
|
|
3231
|
+
"The docyrus-web-browser client tool returned a result.",
|
|
3232
|
+
"",
|
|
3233
|
+
`${DOCYRUS_WEB_BROWSER_RESULT_OPEN}`,
|
|
3234
|
+
JSON.stringify(response, null, 2),
|
|
3235
|
+
`${DOCYRUS_WEB_BROWSER_RESULT_CLOSE}`,
|
|
3236
|
+
"",
|
|
3237
|
+
"Continue the task using this result. If the tool reported an availability or bridge blocker, explain that blocker exactly and do not claim success."
|
|
3238
|
+
].join("\n");
|
|
3239
|
+
}
|
|
3240
|
+
|
|
3108
3241
|
// src/server/eventBridge.ts
|
|
3109
3242
|
function createEventBridge(params) {
|
|
3110
|
-
const { messageId, onChunk, onDone, onError, onAskUser } = params;
|
|
3243
|
+
const { messageId, onChunk, onDone, onError, onAskUser, onDocyrusWebBrowserTool } = params;
|
|
3111
3244
|
const activeToolCalls = /* @__PURE__ */ new Map();
|
|
3112
3245
|
let activeTextBuffer = null;
|
|
3113
3246
|
function flushBufferedTextToStream(close) {
|
|
@@ -3143,6 +3276,27 @@ function createEventBridge(params) {
|
|
|
3143
3276
|
});
|
|
3144
3277
|
return true;
|
|
3145
3278
|
}
|
|
3279
|
+
function maybeEmitDocyrusWebBrowserTool(text) {
|
|
3280
|
+
const request = parseDocyrusWebBrowserRequestFromText(text);
|
|
3281
|
+
if (!request) {
|
|
3282
|
+
return false;
|
|
3283
|
+
}
|
|
3284
|
+
const toolCallId = createDocyrusWebBrowserToolCallId(request);
|
|
3285
|
+
onDocyrusWebBrowserTool?.({ toolCallId, request });
|
|
3286
|
+
onChunk({ type: "tool-input-start", toolCallId, toolName: request.tool, dynamic: true });
|
|
3287
|
+
onChunk({
|
|
3288
|
+
type: "tool-input-available",
|
|
3289
|
+
toolCallId,
|
|
3290
|
+
toolName: request.tool,
|
|
3291
|
+
input: request.input ?? {},
|
|
3292
|
+
dynamic: true
|
|
3293
|
+
});
|
|
3294
|
+
return true;
|
|
3295
|
+
}
|
|
3296
|
+
function shouldKeepBufferingDynamicToolText(text) {
|
|
3297
|
+
const dynamicToolTags = ["<ask_user>", "<docyrus_web_browser>"];
|
|
3298
|
+
return dynamicToolTags.some((tag) => tag.startsWith(text) || text.startsWith(tag));
|
|
3299
|
+
}
|
|
3146
3300
|
function handleEvent(event) {
|
|
3147
3301
|
switch (event.type) {
|
|
3148
3302
|
case "message_update": {
|
|
@@ -3181,7 +3335,7 @@ function createEventBridge(params) {
|
|
|
3181
3335
|
break;
|
|
3182
3336
|
}
|
|
3183
3337
|
activeTextBuffer.text += assistantEvent.delta ?? "";
|
|
3184
|
-
if (
|
|
3338
|
+
if (shouldKeepBufferingDynamicToolText(activeTextBuffer.text)) {
|
|
3185
3339
|
break;
|
|
3186
3340
|
}
|
|
3187
3341
|
flushBufferedTextToStream(false);
|
|
@@ -3197,7 +3351,7 @@ function createEventBridge(params) {
|
|
|
3197
3351
|
activeTextBuffer = null;
|
|
3198
3352
|
break;
|
|
3199
3353
|
}
|
|
3200
|
-
if (!maybeEmitAskUser(activeTextBuffer.text)) {
|
|
3354
|
+
if (!maybeEmitAskUser(activeTextBuffer.text) && !maybeEmitDocyrusWebBrowserTool(activeTextBuffer.text)) {
|
|
3201
3355
|
flushBufferedTextToStream(true);
|
|
3202
3356
|
} else {
|
|
3203
3357
|
activeTextBuffer = null;
|
|
@@ -3282,7 +3436,7 @@ function createEventBridge(params) {
|
|
|
3282
3436
|
|
|
3283
3437
|
// src/agent/modelsConfig.ts
|
|
3284
3438
|
var import_promises2 = require("node:fs/promises");
|
|
3285
|
-
var
|
|
3439
|
+
var import_node_path3 = require("node:path");
|
|
3286
3440
|
function createDefaultState2() {
|
|
3287
3441
|
return {
|
|
3288
3442
|
providers: {}
|
|
@@ -3306,7 +3460,7 @@ async function readModelsConfig(filePath) {
|
|
|
3306
3460
|
}
|
|
3307
3461
|
}
|
|
3308
3462
|
async function writeModelsConfig(filePath, state) {
|
|
3309
|
-
const directory = (0,
|
|
3463
|
+
const directory = (0, import_node_path3.dirname)(filePath);
|
|
3310
3464
|
await (0, import_promises2.mkdir)(directory, {
|
|
3311
3465
|
recursive: true,
|
|
3312
3466
|
mode: 448
|
|
@@ -4132,21 +4286,21 @@ var OAuthFlowManager = class {
|
|
|
4132
4286
|
var import_node_crypto2 = require("node:crypto");
|
|
4133
4287
|
var import_promises3 = require("node:fs/promises");
|
|
4134
4288
|
var import_node_os = require("node:os");
|
|
4135
|
-
var
|
|
4289
|
+
var import_node_path4 = require("node:path");
|
|
4136
4290
|
var PROJECT_CONFIG_NAME = ".pi/mcp.json";
|
|
4137
4291
|
var IMPORT_PATHS = {
|
|
4138
|
-
"cursor": (0,
|
|
4139
|
-
"claude-code": (0,
|
|
4140
|
-
"claude-desktop": (0,
|
|
4141
|
-
"codex": (0,
|
|
4142
|
-
"windsurf": (0,
|
|
4292
|
+
"cursor": (0, import_node_path4.join)((0, import_node_os.homedir)(), ".cursor", "mcp.json"),
|
|
4293
|
+
"claude-code": (0, import_node_path4.join)((0, import_node_os.homedir)(), ".claude", "claude_desktop_config.json"),
|
|
4294
|
+
"claude-desktop": (0, import_node_path4.join)((0, import_node_os.homedir)(), "Library", "Application Support", "Claude", "claude_desktop_config.json"),
|
|
4295
|
+
"codex": (0, import_node_path4.join)((0, import_node_os.homedir)(), ".codex", "config.json"),
|
|
4296
|
+
"windsurf": (0, import_node_path4.join)((0, import_node_os.homedir)(), ".windsurf", "mcp.json"),
|
|
4143
4297
|
"vscode": ".vscode/mcp.json"
|
|
4144
4298
|
};
|
|
4145
4299
|
function getMcpConfigPath(agentDir) {
|
|
4146
|
-
return (0,
|
|
4300
|
+
return (0, import_node_path4.join)(agentDir, "mcp.json");
|
|
4147
4301
|
}
|
|
4148
4302
|
function getMcpCachePath(agentDir) {
|
|
4149
|
-
return (0,
|
|
4303
|
+
return (0, import_node_path4.join)(agentDir, "mcp-cache.json");
|
|
4150
4304
|
}
|
|
4151
4305
|
var SERVER_NAME_REGEX = /^[a-zA-Z0-9][a-zA-Z0-9_-]*$/;
|
|
4152
4306
|
function validateServerName(name) {
|
|
@@ -4283,7 +4437,7 @@ async function loadMcpServerConfig(agentDir, cwd) {
|
|
|
4283
4437
|
if (!importPath) {
|
|
4284
4438
|
continue;
|
|
4285
4439
|
}
|
|
4286
|
-
const fullPath = importPath.startsWith(".") ? (0,
|
|
4440
|
+
const fullPath = importPath.startsWith(".") ? (0, import_node_path4.resolve)(cwd, importPath) : importPath;
|
|
4287
4441
|
const imported = await readJsonFile(fullPath);
|
|
4288
4442
|
if (!imported) {
|
|
4289
4443
|
continue;
|
|
@@ -4296,7 +4450,7 @@ async function loadMcpServerConfig(agentDir, cwd) {
|
|
|
4296
4450
|
}
|
|
4297
4451
|
}
|
|
4298
4452
|
}
|
|
4299
|
-
const projectPath = (0,
|
|
4453
|
+
const projectPath = (0, import_node_path4.resolve)(cwd, PROJECT_CONFIG_NAME);
|
|
4300
4454
|
if (projectPath !== configPath) {
|
|
4301
4455
|
const projectRaw = await readJsonFile(projectPath);
|
|
4302
4456
|
if (projectRaw) {
|
|
@@ -4380,7 +4534,7 @@ async function getServerProvenance(agentDir, cwd) {
|
|
|
4380
4534
|
if (!importPath) {
|
|
4381
4535
|
continue;
|
|
4382
4536
|
}
|
|
4383
|
-
const fullPath = importPath.startsWith(".") ? (0,
|
|
4537
|
+
const fullPath = importPath.startsWith(".") ? (0, import_node_path4.resolve)(cwd, importPath) : importPath;
|
|
4384
4538
|
const imported = await readJsonFile(fullPath);
|
|
4385
4539
|
if (!imported) {
|
|
4386
4540
|
continue;
|
|
@@ -4393,7 +4547,7 @@ async function getServerProvenance(agentDir, cwd) {
|
|
|
4393
4547
|
}
|
|
4394
4548
|
}
|
|
4395
4549
|
}
|
|
4396
|
-
const projectPath = (0,
|
|
4550
|
+
const projectPath = (0, import_node_path4.resolve)(cwd, PROJECT_CONFIG_NAME);
|
|
4397
4551
|
if (projectPath !== userPath) {
|
|
4398
4552
|
const projectRaw = await readJsonFile(projectPath);
|
|
4399
4553
|
if (projectRaw) {
|
|
@@ -4417,7 +4571,7 @@ async function readUserConfig(agentDir) {
|
|
|
4417
4571
|
}
|
|
4418
4572
|
async function writeUserConfig(agentDir, raw2) {
|
|
4419
4573
|
const configPath = getMcpConfigPath(agentDir);
|
|
4420
|
-
await (0, import_promises3.mkdir)((0,
|
|
4574
|
+
await (0, import_promises3.mkdir)((0, import_node_path4.dirname)(configPath), { recursive: true });
|
|
4421
4575
|
const tmpPath = `${configPath}.${process.pid}.tmp`;
|
|
4422
4576
|
await (0, import_promises3.writeFile)(tmpPath, JSON.stringify(raw2, null, 2) + "\n", "utf-8");
|
|
4423
4577
|
await (0, import_promises3.rename)(tmpPath, configPath);
|
|
@@ -4475,7 +4629,7 @@ function formatToolName(toolName, serverName, prefix) {
|
|
|
4475
4629
|
|
|
4476
4630
|
// src/server/skillsService.ts
|
|
4477
4631
|
var import_promises4 = require("node:fs/promises");
|
|
4478
|
-
var
|
|
4632
|
+
var import_node_path5 = require("node:path");
|
|
4479
4633
|
function parseFrontmatter(content) {
|
|
4480
4634
|
const frontmatter = {};
|
|
4481
4635
|
if (!content.startsWith("---")) {
|
|
@@ -4509,7 +4663,7 @@ async function dirExists(path) {
|
|
|
4509
4663
|
}
|
|
4510
4664
|
}
|
|
4511
4665
|
async function listSkills(agentDir) {
|
|
4512
|
-
const skillsDir = (0,
|
|
4666
|
+
const skillsDir = (0, import_node_path5.join)(agentDir, "skills");
|
|
4513
4667
|
let entries;
|
|
4514
4668
|
try {
|
|
4515
4669
|
entries = await (0, import_promises4.readdir)(skillsDir, { withFileTypes: true });
|
|
@@ -4521,8 +4675,8 @@ async function listSkills(agentDir) {
|
|
|
4521
4675
|
if (!entry.isDirectory()) {
|
|
4522
4676
|
continue;
|
|
4523
4677
|
}
|
|
4524
|
-
const skillDir = (0,
|
|
4525
|
-
const skillMdPath = (0,
|
|
4678
|
+
const skillDir = (0, import_node_path5.join)(skillsDir, entry.name);
|
|
4679
|
+
const skillMdPath = (0, import_node_path5.join)(skillDir, "SKILL.md");
|
|
4526
4680
|
let content;
|
|
4527
4681
|
try {
|
|
4528
4682
|
content = await (0, import_promises4.readFile)(skillMdPath, "utf-8");
|
|
@@ -4530,7 +4684,7 @@ async function listSkills(agentDir) {
|
|
|
4530
4684
|
continue;
|
|
4531
4685
|
}
|
|
4532
4686
|
const parsed = parseFrontmatter(content);
|
|
4533
|
-
const hasReferences = await dirExists((0,
|
|
4687
|
+
const hasReferences = await dirExists((0, import_node_path5.join)(skillDir, "references"));
|
|
4534
4688
|
skills.push({
|
|
4535
4689
|
name: parsed.frontmatter.name || entry.name,
|
|
4536
4690
|
description: parsed.frontmatter.description || null,
|
|
@@ -4543,7 +4697,7 @@ async function listSkills(agentDir) {
|
|
|
4543
4697
|
return skills.sort((a, b) => a.name.localeCompare(b.name));
|
|
4544
4698
|
}
|
|
4545
4699
|
async function getSkillDetail(agentDir, skillName) {
|
|
4546
|
-
const skillsDir = (0,
|
|
4700
|
+
const skillsDir = (0, import_node_path5.join)(agentDir, "skills");
|
|
4547
4701
|
let entries;
|
|
4548
4702
|
try {
|
|
4549
4703
|
entries = await (0, import_promises4.readdir)(skillsDir, { withFileTypes: true });
|
|
@@ -4554,8 +4708,8 @@ async function getSkillDetail(agentDir, skillName) {
|
|
|
4554
4708
|
if (!entry.isDirectory()) {
|
|
4555
4709
|
continue;
|
|
4556
4710
|
}
|
|
4557
|
-
const skillDir = (0,
|
|
4558
|
-
const skillMdPath = (0,
|
|
4711
|
+
const skillDir = (0, import_node_path5.join)(skillsDir, entry.name);
|
|
4712
|
+
const skillMdPath = (0, import_node_path5.join)(skillDir, "SKILL.md");
|
|
4559
4713
|
let content;
|
|
4560
4714
|
try {
|
|
4561
4715
|
content = await (0, import_promises4.readFile)(skillMdPath, "utf-8");
|
|
@@ -4565,7 +4719,7 @@ async function getSkillDetail(agentDir, skillName) {
|
|
|
4565
4719
|
const parsed = parseFrontmatter(content);
|
|
4566
4720
|
const fmName = parsed.frontmatter.name || entry.name;
|
|
4567
4721
|
if (entry.name === skillName || fmName === skillName) {
|
|
4568
|
-
const hasReferences = await dirExists((0,
|
|
4722
|
+
const hasReferences = await dirExists((0, import_node_path5.join)(skillDir, "references"));
|
|
4569
4723
|
return {
|
|
4570
4724
|
skill: {
|
|
4571
4725
|
name: fmName,
|
|
@@ -4602,7 +4756,7 @@ var BUILT_IN_TOOLS = {
|
|
|
4602
4756
|
]
|
|
4603
4757
|
};
|
|
4604
4758
|
async function listAllTools(params) {
|
|
4605
|
-
const { profile, agentDir, cwd } = params;
|
|
4759
|
+
const { profile, agentDir, cwd, includeDocyrusWebBrowser } = params;
|
|
4606
4760
|
const tools = [];
|
|
4607
4761
|
const builtIn = BUILT_IN_TOOLS[profile] ?? BUILT_IN_TOOLS.coder;
|
|
4608
4762
|
for (const tool of builtIn) {
|
|
@@ -4612,6 +4766,16 @@ async function listAllTools(params) {
|
|
|
4612
4766
|
source: "built-in"
|
|
4613
4767
|
});
|
|
4614
4768
|
}
|
|
4769
|
+
if (includeDocyrusWebBrowser) {
|
|
4770
|
+
for (const tool of DOCYRUS_WEB_BROWSER_CLIENT_TOOLS) {
|
|
4771
|
+
tools.push({
|
|
4772
|
+
name: tool.name,
|
|
4773
|
+
description: tool.description,
|
|
4774
|
+
source: "built-in",
|
|
4775
|
+
inputSchema: tool.inputSchema
|
|
4776
|
+
});
|
|
4777
|
+
}
|
|
4778
|
+
}
|
|
4615
4779
|
let config;
|
|
4616
4780
|
let cache;
|
|
4617
4781
|
try {
|
|
@@ -4661,6 +4825,13 @@ async function listAllTools(params) {
|
|
|
4661
4825
|
function generateMessageId() {
|
|
4662
4826
|
return `msg_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
|
|
4663
4827
|
}
|
|
4828
|
+
function getLastAssistantMessage(messages) {
|
|
4829
|
+
if (messages.length === 0) {
|
|
4830
|
+
return void 0;
|
|
4831
|
+
}
|
|
4832
|
+
const lastMessage = messages[messages.length - 1];
|
|
4833
|
+
return lastMessage.role === "assistant" ? lastMessage : void 0;
|
|
4834
|
+
}
|
|
4664
4835
|
function extractLastUserText(messages) {
|
|
4665
4836
|
if (messages.length === 0) {
|
|
4666
4837
|
return void 0;
|
|
@@ -4677,21 +4848,58 @@ function extractLastUserText(messages) {
|
|
|
4677
4848
|
return void 0;
|
|
4678
4849
|
}
|
|
4679
4850
|
function extractAskUserToolResponse(messages) {
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
|
|
4851
|
+
const message = getLastAssistantMessage(messages);
|
|
4852
|
+
if (!message) {
|
|
4853
|
+
return void 0;
|
|
4854
|
+
}
|
|
4855
|
+
for (let partIndex = message.parts.length - 1; partIndex >= 0; partIndex -= 1) {
|
|
4856
|
+
const part = message.parts[partIndex];
|
|
4857
|
+
if (part.type === "dynamic-tool" && part.toolName === "ask_user" && part.state === "output-available" && typeof part.toolCallId === "string") {
|
|
4858
|
+
const response = parseAskUserResponseFromToolOutput(part.output);
|
|
4859
|
+
if (response) {
|
|
4860
|
+
return {
|
|
4861
|
+
toolCallId: part.toolCallId,
|
|
4862
|
+
response
|
|
4863
|
+
};
|
|
4864
|
+
}
|
|
4684
4865
|
}
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
|
|
4691
|
-
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
|
|
4866
|
+
}
|
|
4867
|
+
return void 0;
|
|
4868
|
+
}
|
|
4869
|
+
function extractDocyrusWebBrowserToolResponse(messages) {
|
|
4870
|
+
const message = getLastAssistantMessage(messages);
|
|
4871
|
+
if (!message) {
|
|
4872
|
+
return void 0;
|
|
4873
|
+
}
|
|
4874
|
+
for (let partIndex = message.parts.length - 1; partIndex >= 0; partIndex -= 1) {
|
|
4875
|
+
const part = message.parts[partIndex];
|
|
4876
|
+
if (part.type === "dynamic-tool" && isDocyrusWebBrowserToolName(part.toolName) && typeof part.toolCallId === "string" && (part.state === "output-available" || part.state === "output-error")) {
|
|
4877
|
+
const errorText = typeof part.errorText === "string" ? part.errorText : typeof part.output === "string" && part.state === "output-error" ? part.output : void 0;
|
|
4878
|
+
return {
|
|
4879
|
+
toolCallId: part.toolCallId,
|
|
4880
|
+
toolName: part.toolName,
|
|
4881
|
+
output: part.state === "output-available" ? part.output : void 0,
|
|
4882
|
+
errorText,
|
|
4883
|
+
isError: part.state === "output-error"
|
|
4884
|
+
};
|
|
4885
|
+
}
|
|
4886
|
+
}
|
|
4887
|
+
return void 0;
|
|
4888
|
+
}
|
|
4889
|
+
function extractDocyrusWebBrowserToolRequest(messages, toolCallId) {
|
|
4890
|
+
const message = getLastAssistantMessage(messages);
|
|
4891
|
+
if (!message) {
|
|
4892
|
+
return void 0;
|
|
4893
|
+
}
|
|
4894
|
+
for (let partIndex = message.parts.length - 1; partIndex >= 0; partIndex -= 1) {
|
|
4895
|
+
const part = message.parts[partIndex];
|
|
4896
|
+
if (part.type === "dynamic-tool" && isDocyrusWebBrowserToolName(part.toolName) && part.toolCallId === toolCallId) {
|
|
4897
|
+
const request = normalizeDocyrusWebBrowserToolRequest({
|
|
4898
|
+
tool: part.toolName,
|
|
4899
|
+
input: part.input
|
|
4900
|
+
});
|
|
4901
|
+
if (request) {
|
|
4902
|
+
return request;
|
|
4695
4903
|
}
|
|
4696
4904
|
}
|
|
4697
4905
|
}
|
|
@@ -4797,6 +5005,17 @@ function convertSessionEntriesToUIMessages(entries) {
|
|
|
4797
5005
|
});
|
|
4798
5006
|
continue;
|
|
4799
5007
|
}
|
|
5008
|
+
const docyrusWebBrowserRequest = parseDocyrusWebBrowserRequestFromText(block.text);
|
|
5009
|
+
if (docyrusWebBrowserRequest) {
|
|
5010
|
+
parts.push({
|
|
5011
|
+
type: "dynamic-tool",
|
|
5012
|
+
toolCallId: createDocyrusWebBrowserToolCallId(docyrusWebBrowserRequest),
|
|
5013
|
+
toolName: docyrusWebBrowserRequest.tool,
|
|
5014
|
+
state: "input-available",
|
|
5015
|
+
input: docyrusWebBrowserRequest.input ?? {}
|
|
5016
|
+
});
|
|
5017
|
+
continue;
|
|
5018
|
+
}
|
|
4800
5019
|
parts.push({ type: "text", text: block.text });
|
|
4801
5020
|
} else if (block.type === "thinking" && typeof block.thinking === "string") {
|
|
4802
5021
|
parts.push({ type: "reasoning", text: block.thinking, state: "complete" });
|
|
@@ -4841,8 +5060,8 @@ var FS_IGNORE = /* @__PURE__ */ new Set([
|
|
|
4841
5060
|
".svelte-kit"
|
|
4842
5061
|
]);
|
|
4843
5062
|
function resolveSafePath(cwd, requestPath) {
|
|
4844
|
-
const resolved = (0,
|
|
4845
|
-
const normalizedCwd = cwd.endsWith(
|
|
5063
|
+
const resolved = (0, import_node_path6.resolve)(cwd, requestPath);
|
|
5064
|
+
const normalizedCwd = cwd.endsWith(import_node_path6.sep) ? cwd : cwd + import_node_path6.sep;
|
|
4846
5065
|
if (resolved !== cwd && !resolved.startsWith(normalizedCwd)) {
|
|
4847
5066
|
throw new Error("Path escapes working directory");
|
|
4848
5067
|
}
|
|
@@ -4879,8 +5098,8 @@ async function buildTree(params) {
|
|
|
4879
5098
|
if (ignore.has(entry.name)) {
|
|
4880
5099
|
continue;
|
|
4881
5100
|
}
|
|
4882
|
-
const fullPath = (0,
|
|
4883
|
-
const relativePath = (0,
|
|
5101
|
+
const fullPath = (0, import_node_path6.join)(dir, entry.name);
|
|
5102
|
+
const relativePath = (0, import_node_path6.relative)(cwd, fullPath);
|
|
4884
5103
|
if (entry.isDirectory()) {
|
|
4885
5104
|
const children = await buildTree({
|
|
4886
5105
|
dir: fullPath,
|
|
@@ -4917,8 +5136,8 @@ async function walkFiles(params) {
|
|
|
4917
5136
|
if (ignore.has(entry.name)) {
|
|
4918
5137
|
continue;
|
|
4919
5138
|
}
|
|
4920
|
-
const fullPath = (0,
|
|
4921
|
-
const relativePath = (0,
|
|
5139
|
+
const fullPath = (0, import_node_path6.join)(dir, entry.name);
|
|
5140
|
+
const relativePath = (0, import_node_path6.relative)(cwd, fullPath);
|
|
4922
5141
|
if (entry.isDirectory()) {
|
|
4923
5142
|
await walkFiles({ dir: fullPath, cwd, pattern, ignore, maxResults, results });
|
|
4924
5143
|
} else if (entry.isFile() && pattern.test(relativePath)) {
|
|
@@ -4930,6 +5149,7 @@ async function createAgentServer(params) {
|
|
|
4930
5149
|
const { port, sessionManager, modelRegistry, authRuntime, context, onCreateSession, onResumeSession, authToken } = params;
|
|
4931
5150
|
let activeSession = params.session;
|
|
4932
5151
|
const pendingAskUserRequests = /* @__PURE__ */ new Map();
|
|
5152
|
+
const pendingDocyrusWebBrowserRequests = /* @__PURE__ */ new Map();
|
|
4933
5153
|
const oauthFlowManager = new OAuthFlowManager();
|
|
4934
5154
|
const app = new Hono2();
|
|
4935
5155
|
function getModelIdsByProvider() {
|
|
@@ -4983,14 +5203,31 @@ async function createAgentServer(params) {
|
|
|
4983
5203
|
}
|
|
4984
5204
|
const sessionId = body.sessionId?.trim() || activeSession.id?.trim() || "active";
|
|
4985
5205
|
const askUserResponse = extractAskUserToolResponse(messages);
|
|
5206
|
+
const docyrusWebBrowserResponse = extractDocyrusWebBrowserToolResponse(messages);
|
|
4986
5207
|
const pendingAskUser = pendingAskUserRequests.get(sessionId);
|
|
4987
|
-
const
|
|
5208
|
+
const pendingDocyrusWebBrowser = pendingDocyrusWebBrowserRequests.get(sessionId);
|
|
5209
|
+
const pendingDocyrusWebBrowserRequest = docyrusWebBrowserResponse ? pendingDocyrusWebBrowser?.get(docyrusWebBrowserResponse.toolCallId) ?? extractDocyrusWebBrowserToolRequest(messages, docyrusWebBrowserResponse.toolCallId) : void 0;
|
|
5210
|
+
const userMessage = askUserResponse ? pendingAskUser && pendingAskUser.toolCallId === askUserResponse.toolCallId ? formatAskUserResponsePrompt(askUserResponse.response) : void 0 : docyrusWebBrowserResponse ? pendingDocyrusWebBrowserRequest ? formatDocyrusWebBrowserToolResponsePrompt({
|
|
5211
|
+
tool: docyrusWebBrowserResponse.toolName,
|
|
5212
|
+
request: pendingDocyrusWebBrowserRequest.input,
|
|
5213
|
+
status: docyrusWebBrowserResponse.isError ? "error" : "success",
|
|
5214
|
+
output: docyrusWebBrowserResponse.output,
|
|
5215
|
+
errorText: docyrusWebBrowserResponse.errorText
|
|
5216
|
+
}) : void 0 : extractLastUserText(messages);
|
|
4988
5217
|
if (!userMessage) {
|
|
4989
|
-
return c.json({
|
|
5218
|
+
return c.json({
|
|
5219
|
+
error: askUserResponse ? "No matching pending ask_user request found" : docyrusWebBrowserResponse ? "No matching pending docyrus-web-browser request found" : "No user message found"
|
|
5220
|
+
}, 400);
|
|
4990
5221
|
}
|
|
4991
5222
|
if (askUserResponse) {
|
|
4992
5223
|
pendingAskUserRequests.delete(sessionId);
|
|
4993
5224
|
}
|
|
5225
|
+
if (docyrusWebBrowserResponse && pendingDocyrusWebBrowser) {
|
|
5226
|
+
pendingDocyrusWebBrowser.delete(docyrusWebBrowserResponse.toolCallId);
|
|
5227
|
+
if (pendingDocyrusWebBrowser.size === 0) {
|
|
5228
|
+
pendingDocyrusWebBrowserRequests.delete(sessionId);
|
|
5229
|
+
}
|
|
5230
|
+
}
|
|
4994
5231
|
if (activeSession.isStreaming) {
|
|
4995
5232
|
await activeSession.abort();
|
|
4996
5233
|
await waitForIdle(activeSession);
|
|
@@ -5012,6 +5249,11 @@ async function createAgentServer(params) {
|
|
|
5012
5249
|
onAskUser: ({ toolCallId, request }) => {
|
|
5013
5250
|
pendingAskUserRequests.set(sessionId, { toolCallId, request });
|
|
5014
5251
|
},
|
|
5252
|
+
onDocyrusWebBrowserTool: ({ toolCallId, request }) => {
|
|
5253
|
+
const pendingForSession = pendingDocyrusWebBrowserRequests.get(sessionId) ?? /* @__PURE__ */ new Map();
|
|
5254
|
+
pendingForSession.set(toolCallId, request);
|
|
5255
|
+
pendingDocyrusWebBrowserRequests.set(sessionId, pendingForSession);
|
|
5256
|
+
},
|
|
5015
5257
|
onDone: () => {
|
|
5016
5258
|
writeChunk({ type: "finish-step" });
|
|
5017
5259
|
writeChunk({ type: "finish" });
|
|
@@ -5383,7 +5625,7 @@ async function createAgentServer(params) {
|
|
|
5383
5625
|
}
|
|
5384
5626
|
try {
|
|
5385
5627
|
const resolved = resolveSafePath(context.cwd, body.path);
|
|
5386
|
-
await (0, import_promises5.mkdir)((0,
|
|
5628
|
+
await (0, import_promises5.mkdir)((0, import_node_path6.join)(resolved, ".."), { recursive: true });
|
|
5387
5629
|
await (0, import_promises5.writeFile)(resolved, body.content, "utf-8");
|
|
5388
5630
|
const fileStat = await (0, import_promises5.stat)(resolved);
|
|
5389
5631
|
return c.json({ ok: true, path: body.path, size: fileStat.size });
|
|
@@ -5414,7 +5656,7 @@ async function createAgentServer(params) {
|
|
|
5414
5656
|
try {
|
|
5415
5657
|
const resolvedFrom = resolveSafePath(context.cwd, body.from);
|
|
5416
5658
|
const resolvedTo = resolveSafePath(context.cwd, body.to);
|
|
5417
|
-
await (0, import_promises5.mkdir)((0,
|
|
5659
|
+
await (0, import_promises5.mkdir)((0, import_node_path6.join)(resolvedTo, ".."), { recursive: true });
|
|
5418
5660
|
await (0, import_promises5.rename)(resolvedFrom, resolvedTo);
|
|
5419
5661
|
return c.json({ ok: true, from: body.from, to: body.to });
|
|
5420
5662
|
} catch (error) {
|
|
@@ -5443,7 +5685,7 @@ async function createAgentServer(params) {
|
|
|
5443
5685
|
}
|
|
5444
5686
|
});
|
|
5445
5687
|
const CLI_EXEC = process.env.DOCYRUS_CLI_EXECUTABLE || process.execPath;
|
|
5446
|
-
const CLI_ENTRY = process.env.DOCYRUS_CLI_ENTRY || (0,
|
|
5688
|
+
const CLI_ENTRY = process.env.DOCYRUS_CLI_ENTRY || (0, import_node_path6.resolve)(process.argv[1] ? (0, import_node_path6.join)(process.argv[1], "..") : __dirname, "main.js");
|
|
5447
5689
|
const CLI_SCOPE = process.env.DOCYRUS_CLI_SCOPE;
|
|
5448
5690
|
const CLI_TIMEOUT_MS = 3e4;
|
|
5449
5691
|
function runCliCommand(args) {
|
|
@@ -5493,7 +5735,7 @@ async function createAgentServer(params) {
|
|
|
5493
5735
|
}
|
|
5494
5736
|
async function detectDevPort(cwd) {
|
|
5495
5737
|
try {
|
|
5496
|
-
const pkg = JSON.parse(await (0, import_promises5.readFile)((0,
|
|
5738
|
+
const pkg = JSON.parse(await (0, import_promises5.readFile)((0, import_node_path6.join)(cwd, "package.json"), "utf-8"));
|
|
5497
5739
|
const devScript = pkg.scripts?.dev;
|
|
5498
5740
|
if (devScript) {
|
|
5499
5741
|
const portFlag = devScript.match(/--port\s+(\d+)/);
|
|
@@ -5509,7 +5751,7 @@ async function createAgentServer(params) {
|
|
|
5509
5751
|
}
|
|
5510
5752
|
for (const name of ["vite.config.ts", "vite.config.mts", "vite.config.js"]) {
|
|
5511
5753
|
try {
|
|
5512
|
-
const content = await (0, import_promises5.readFile)((0,
|
|
5754
|
+
const content = await (0, import_promises5.readFile)((0, import_node_path6.join)(cwd, name), "utf-8");
|
|
5513
5755
|
const portMatch = content.match(/port\s*:\s*(\d+)/);
|
|
5514
5756
|
if (portMatch) {
|
|
5515
5757
|
return Number(portMatch[1]);
|
|
@@ -5519,19 +5761,19 @@ async function createAgentServer(params) {
|
|
|
5519
5761
|
}
|
|
5520
5762
|
for (const name of ["next.config.ts", "next.config.mts", "next.config.js", "next.config.mjs"]) {
|
|
5521
5763
|
try {
|
|
5522
|
-
await (0, import_promises5.stat)((0,
|
|
5764
|
+
await (0, import_promises5.stat)((0, import_node_path6.join)(cwd, name));
|
|
5523
5765
|
return 3e3;
|
|
5524
5766
|
} catch {
|
|
5525
5767
|
}
|
|
5526
5768
|
}
|
|
5527
5769
|
try {
|
|
5528
|
-
await (0, import_promises5.stat)((0,
|
|
5770
|
+
await (0, import_promises5.stat)((0, import_node_path6.join)(cwd, "angular.json"));
|
|
5529
5771
|
return 4200;
|
|
5530
5772
|
} catch {
|
|
5531
5773
|
}
|
|
5532
5774
|
for (const name of ["nuxt.config.ts", "nuxt.config.js"]) {
|
|
5533
5775
|
try {
|
|
5534
|
-
await (0, import_promises5.stat)((0,
|
|
5776
|
+
await (0, import_promises5.stat)((0, import_node_path6.join)(cwd, name));
|
|
5535
5777
|
return 3e3;
|
|
5536
5778
|
} catch {
|
|
5537
5779
|
}
|
|
@@ -5561,14 +5803,14 @@ async function createAgentServer(params) {
|
|
|
5561
5803
|
} catch {
|
|
5562
5804
|
}
|
|
5563
5805
|
try {
|
|
5564
|
-
const pkg = JSON.parse(await (0, import_promises5.readFile)((0,
|
|
5806
|
+
const pkg = JSON.parse(await (0, import_promises5.readFile)((0, import_node_path6.join)(cwd, "package.json"), "utf-8"));
|
|
5565
5807
|
packageName = pkg.name ?? null;
|
|
5566
5808
|
packageVersion = pkg.version ?? null;
|
|
5567
5809
|
} catch {
|
|
5568
5810
|
}
|
|
5569
5811
|
cachedProjectInfo = {
|
|
5570
5812
|
path: cwd,
|
|
5571
|
-
folder: (0,
|
|
5813
|
+
folder: (0, import_node_path6.basename)(cwd),
|
|
5572
5814
|
repo,
|
|
5573
5815
|
packageName,
|
|
5574
5816
|
packageVersion
|
|
@@ -5779,7 +6021,7 @@ async function createAgentServer(params) {
|
|
|
5779
6021
|
}
|
|
5780
6022
|
if (entry.status !== "deleted") {
|
|
5781
6023
|
try {
|
|
5782
|
-
const resolved = (0,
|
|
6024
|
+
const resolved = (0, import_node_path6.resolve)(cwd, entry.path);
|
|
5783
6025
|
const buf = await (0, import_promises5.readFile)(resolved);
|
|
5784
6026
|
if (buf.subarray(0, 8192).includes(0)) {
|
|
5785
6027
|
return null;
|
|
@@ -5958,7 +6200,7 @@ async function createAgentServer(params) {
|
|
|
5958
6200
|
});
|
|
5959
6201
|
app.get("/api/skills", async (c) => {
|
|
5960
6202
|
try {
|
|
5961
|
-
const skills = await listSkills(context.agentDir);
|
|
6203
|
+
const skills = (await listSkills(context.agentDir)).filter((skill) => skill.name !== "docyrus-chrome-devtools-cli");
|
|
5962
6204
|
return c.json({ skills });
|
|
5963
6205
|
} catch (error) {
|
|
5964
6206
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -5968,6 +6210,9 @@ async function createAgentServer(params) {
|
|
|
5968
6210
|
app.get("/api/skills/:skillName", async (c) => {
|
|
5969
6211
|
const skillName = c.req.param("skillName");
|
|
5970
6212
|
try {
|
|
6213
|
+
if (skillName === "docyrus-chrome-devtools-cli") {
|
|
6214
|
+
return c.json({ error: `Skill "${skillName}" not found` }, 404);
|
|
6215
|
+
}
|
|
5971
6216
|
const result = await getSkillDetail(context.agentDir, skillName);
|
|
5972
6217
|
if (!result) {
|
|
5973
6218
|
return c.json({ error: `Skill "${skillName}" not found` }, 404);
|
|
@@ -5983,7 +6228,8 @@ async function createAgentServer(params) {
|
|
|
5983
6228
|
const tools = await listAllTools({
|
|
5984
6229
|
profile: context.profile,
|
|
5985
6230
|
agentDir: context.agentDir,
|
|
5986
|
-
cwd: context.cwd
|
|
6231
|
+
cwd: context.cwd,
|
|
6232
|
+
includeDocyrusWebBrowser: true
|
|
5987
6233
|
});
|
|
5988
6234
|
const builtInCount = tools.filter((t) => t.source === "built-in").length;
|
|
5989
6235
|
const mcpCount = tools.filter((t) => t.source !== "built-in").length;
|
|
@@ -6288,31 +6534,22 @@ function readLoaderRequest() {
|
|
|
6288
6534
|
}
|
|
6289
6535
|
async function loadPiExports() {
|
|
6290
6536
|
const piPackageDir = readRequiredEnv("PI_PACKAGE_DIR");
|
|
6291
|
-
const moduleUrl = (0, import_node_url.pathToFileURL)((0,
|
|
6537
|
+
const moduleUrl = (0, import_node_url.pathToFileURL)((0, import_node_path7.join)(piPackageDir, "dist", "index.js")).href;
|
|
6292
6538
|
return await import(moduleUrl);
|
|
6293
6539
|
}
|
|
6294
6540
|
function resolvePackagedPiResourceRoot() {
|
|
6295
6541
|
const candidates = [
|
|
6296
|
-
(0,
|
|
6297
|
-
(0,
|
|
6298
|
-
(0,
|
|
6299
|
-
(0,
|
|
6542
|
+
(0, import_node_path7.resolve)(process.cwd(), "apps/api-cli/resources/pi-agent"),
|
|
6543
|
+
(0, import_node_path7.resolve)(__dirname, "../resources/pi-agent"),
|
|
6544
|
+
(0, import_node_path7.resolve)(__dirname, "resources/pi-agent"),
|
|
6545
|
+
(0, import_node_path7.resolve)(process.cwd(), "dist/apps/api-cli/resources/pi-agent")
|
|
6300
6546
|
];
|
|
6301
|
-
const resolved = candidates.find((candidate) => (0,
|
|
6547
|
+
const resolved = candidates.find((candidate) => (0, import_node_fs2.existsSync)(candidate));
|
|
6302
6548
|
if (!resolved) {
|
|
6303
6549
|
throw new Error(`Unable to locate pi agent resources. Checked: ${candidates.join(", ")}`);
|
|
6304
6550
|
}
|
|
6305
6551
|
return resolved;
|
|
6306
6552
|
}
|
|
6307
|
-
function resolvePackagedExtensionPaths(resourceRoot) {
|
|
6308
|
-
const extensionsRoot = (0, import_node_path6.join)(resourceRoot, "extensions");
|
|
6309
|
-
if (!(0, import_node_fs.existsSync)(extensionsRoot)) {
|
|
6310
|
-
return [];
|
|
6311
|
-
}
|
|
6312
|
-
return (0, import_node_fs.readdirSync)(extensionsRoot, {
|
|
6313
|
-
withFileTypes: true
|
|
6314
|
-
}).filter((entry) => entry.isDirectory() || entry.isFile() && (entry.name.endsWith(".ts") || entry.name.endsWith(".js"))).map((entry) => (0, import_node_path6.join)(extensionsRoot, entry.name)).sort((left, right) => left.localeCompare(right));
|
|
6315
|
-
}
|
|
6316
6553
|
function setProcessArgValue(flag, value) {
|
|
6317
6554
|
const existingIndex = process.argv.indexOf(flag);
|
|
6318
6555
|
if (existingIndex >= 0) {
|
|
@@ -6424,17 +6661,17 @@ async function main() {
|
|
|
6424
6661
|
const agentDir = readRequiredEnv("PI_CODING_AGENT_DIR");
|
|
6425
6662
|
const version = process.env.DOCYRUS_PI_VERSION || "dev";
|
|
6426
6663
|
const resourceRoot = resolvePackagedPiResourceRoot();
|
|
6427
|
-
const packagedExtensionPaths = resolvePackagedExtensionPaths(resourceRoot);
|
|
6428
|
-
const mcpConfigPath = (0,
|
|
6664
|
+
const packagedExtensionPaths = resolvePackagedExtensionPaths(resourceRoot, "server");
|
|
6665
|
+
const mcpConfigPath = (0, import_node_path7.join)(agentDir, "mcp.json");
|
|
6429
6666
|
const hasPackagedMcpAdapter = packagedExtensionPaths.some((extensionPath) => extensionPath.includes("pi-mcp-adapter"));
|
|
6430
|
-
const envStore = new AgentEnvStore((0,
|
|
6667
|
+
const envStore = new AgentEnvStore((0, import_node_path7.join)(agentDir, "env.json"));
|
|
6431
6668
|
await envStore.hydrateProcessEnv(process.env);
|
|
6432
6669
|
if (hasPackagedMcpAdapter) {
|
|
6433
6670
|
setProcessArgValue("--mcp-config", mcpConfigPath);
|
|
6434
6671
|
}
|
|
6435
|
-
const authStorage = pi.AuthStorage.create((0,
|
|
6672
|
+
const authStorage = pi.AuthStorage.create((0, import_node_path7.join)(agentDir, "auth.json"));
|
|
6436
6673
|
const settingsManager = pi.SettingsManager.create(cwd, agentDir);
|
|
6437
|
-
const modelsJsonPath = (0,
|
|
6674
|
+
const modelsJsonPath = (0, import_node_path7.join)(agentDir, "models.json");
|
|
6438
6675
|
const modelRegistry = new pi.ModelRegistry(authStorage, modelsJsonPath);
|
|
6439
6676
|
const quietStartup = !request.verbose;
|
|
6440
6677
|
if (quietStartup) {
|
|
@@ -6463,7 +6700,11 @@ async function main() {
|
|
|
6463
6700
|
agentDir,
|
|
6464
6701
|
settingsManager,
|
|
6465
6702
|
additionalExtensionPaths: packagedExtensionPaths,
|
|
6466
|
-
|
|
6703
|
+
skillsOverride: ({ skills, diagnostics }) => ({
|
|
6704
|
+
skills: skills.filter((skill) => skill.name !== "docyrus-chrome-devtools-cli"),
|
|
6705
|
+
diagnostics
|
|
6706
|
+
}),
|
|
6707
|
+
systemPrompt: (0, import_node_path7.join)(
|
|
6467
6708
|
resourceRoot,
|
|
6468
6709
|
"prompts",
|
|
6469
6710
|
request.profile === "agent" ? "agent-system.md" : "coder-system.md"
|