@standardagents/builder 0.37.0 → 0.37.1
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/built-in-routes.js +1167 -904
- package/dist/built-in-routes.js.map +1 -1
- package/dist/client/{ApiKeysView-CTfDKe47.js → ApiKeysView-BhuT3pIF.js} +1 -1
- package/dist/client/{CenteredContentView-BrVntknT.js → CenteredContentView-CfgX3Ao3.js} +1 -1
- package/dist/client/{CompositionView-BT-1sFij.js → CompositionView-B9FfWMHd.js} +1 -1
- package/dist/client/{ConfirmDialog.vue_vue_type_script_setup_true_lang-yyjbXnqu.js → ConfirmDialog.vue_vue_type_script_setup_true_lang-BqwwsXWJ.js} +1 -1
- package/dist/client/{CopyButton.vue_vue_type_script_setup_true_lang-BWgZbcol.js → CopyButton.vue_vue_type_script_setup_true_lang-Cqm3Vt3E.js} +1 -1
- package/dist/client/{DataTable.vue_vue_type_script_setup_true_lang-DP_WTiEu.js → DataTable.vue_vue_type_script_setup_true_lang-CA5qgsty.js} +1 -1
- package/dist/client/{JsonViewer-DY4s92Td.js → JsonViewer-ByQKCShF.js} +1 -1
- package/dist/client/{LoginView-DHYLpkb0.js → LoginView-J4qtHbQK.js} +1 -1
- package/dist/client/{MarketplaceView-Bcil0ES3.js → MarketplaceView-CshdWDqp.js} +1 -1
- package/dist/client/{Modal.vue_vue_type_script_setup_true_lang-BJgJZ56X.js → Modal.vue_vue_type_script_setup_true_lang-DKdB9A8Z.js} +1 -1
- package/dist/client/{ModelModal.vue_vue_type_script_setup_true_lang-BXTP0K4Z.js → ModelModal.vue_vue_type_script_setup_true_lang-BAxaBZsx.js} +1 -1
- package/dist/client/{ModelsView-_RY4gQ79.js → ModelsView-B_n306yk.js} +1 -1
- package/dist/client/{PromptEditView-D8kyGi30.js → PromptEditView-C85qRgsE.js} +1 -1
- package/dist/client/{PromptModal-DSPIuleV.js → PromptModal-PNpoJfqD.js} +1 -1
- package/dist/client/{PromptsView-DPvBDPJf.js → PromptsView-BKnfThIF.js} +1 -1
- package/dist/client/{ProvidersView-PaPnME7I.js → ProvidersView-Df41VhHD.js} +1 -1
- package/dist/client/ThreadInspectorPane.vue_vue_type_script_setup_true_lang-CtIBWHUR.js +22 -0
- package/dist/client/{ThreadsView-BW4SYvFN.js → ThreadsView-sjo5Rrcm.js} +1 -1
- package/dist/client/{ToolsView-xsIVTHh0.js → ToolsView-C0MH9x3N.js} +1 -1
- package/dist/client/{UsersView-CSXdBGA-.js → UsersView--TQiJYP7.js} +1 -1
- package/dist/client/{VariablesView-Bl5S2ZDn.js → VariablesView-BO3UljZu.js} +1 -1
- package/dist/client/assets/{ThreadInspectorPane-CnbmdCdH.css → ThreadInspectorPane-D9ZMzSTn.css} +1 -1
- package/dist/client/{index-Df4DTwgs.js → index-BgZnQr8X.js} +2 -2
- package/dist/client/index.html +1 -1
- package/dist/{index-yV9JL4r3.d.ts → index-DceFbLG9.d.ts} +45 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +957 -814
- package/dist/index.js.map +1 -1
- package/dist/packing.js +213 -161
- package/dist/packing.js.map +1 -1
- package/dist/plugin.js +535 -505
- package/dist/plugin.js.map +1 -1
- package/dist/runtime.d.ts +110 -38
- package/dist/runtime.js +173 -20
- package/dist/runtime.js.map +1 -1
- package/dist/test.d.ts +1 -1
- package/package.json +5 -5
- package/dist/client/ThreadInspectorPane.vue_vue_type_script_setup_true_lang-BAUlrnb6.js +0 -23
package/dist/plugin.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import
|
|
3
|
-
import * as
|
|
4
|
-
import
|
|
1
|
+
import * as fs9 from 'fs';
|
|
2
|
+
import fs9__default from 'fs';
|
|
3
|
+
import * as path9 from 'path';
|
|
4
|
+
import path9__default from 'path';
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
6
|
import MagicString from 'magic-string';
|
|
7
7
|
import { exec } from 'child_process';
|
|
@@ -41,15 +41,15 @@ function extractSchemaFields(content) {
|
|
|
41
41
|
}
|
|
42
42
|
function scanPromptsWithSchemas(dir) {
|
|
43
43
|
const results = [];
|
|
44
|
-
if (!
|
|
44
|
+
if (!fs9__default.existsSync(dir)) {
|
|
45
45
|
return results;
|
|
46
46
|
}
|
|
47
47
|
try {
|
|
48
|
-
const entries =
|
|
48
|
+
const entries = fs9__default.readdirSync(dir, { withFileTypes: true });
|
|
49
49
|
for (const entry of entries) {
|
|
50
50
|
if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
51
|
-
const filePath =
|
|
52
|
-
const content =
|
|
51
|
+
const filePath = path9__default.join(dir, entry.name);
|
|
52
|
+
const content = fs9__default.readFileSync(filePath, "utf-8");
|
|
53
53
|
const nameMatch = content.match(/name:\s*['"]([^'"]+)['"]/);
|
|
54
54
|
if (nameMatch) {
|
|
55
55
|
const name = nameMatch[1];
|
|
@@ -65,15 +65,15 @@ function scanPromptsWithSchemas(dir) {
|
|
|
65
65
|
}
|
|
66
66
|
function scanAgentsWithSideA(dir) {
|
|
67
67
|
const results = [];
|
|
68
|
-
if (!
|
|
68
|
+
if (!fs9__default.existsSync(dir)) {
|
|
69
69
|
return results;
|
|
70
70
|
}
|
|
71
71
|
try {
|
|
72
|
-
const entries =
|
|
72
|
+
const entries = fs9__default.readdirSync(dir, { withFileTypes: true });
|
|
73
73
|
for (const entry of entries) {
|
|
74
74
|
if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
75
|
-
const filePath =
|
|
76
|
-
const content =
|
|
75
|
+
const filePath = path9__default.join(dir, entry.name);
|
|
76
|
+
const content = fs9__default.readFileSync(filePath, "utf-8");
|
|
77
77
|
const nameMatch = content.match(/name:\s*['"]([^'"]+)['"]/);
|
|
78
78
|
if (nameMatch) {
|
|
79
79
|
const name = nameMatch[1];
|
|
@@ -93,15 +93,15 @@ function scanAgentsWithSideA(dir) {
|
|
|
93
93
|
}
|
|
94
94
|
function scanForNames(dir, useFilename = false) {
|
|
95
95
|
const names = [];
|
|
96
|
-
if (!
|
|
96
|
+
if (!fs9__default.existsSync(dir)) {
|
|
97
97
|
return names;
|
|
98
98
|
}
|
|
99
99
|
try {
|
|
100
|
-
const entries =
|
|
100
|
+
const entries = fs9__default.readdirSync(dir, { withFileTypes: true });
|
|
101
101
|
for (const entry of entries) {
|
|
102
102
|
if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
103
|
-
const filePath =
|
|
104
|
-
const content =
|
|
103
|
+
const filePath = path9__default.join(dir, entry.name);
|
|
104
|
+
const content = fs9__default.readFileSync(filePath, "utf-8");
|
|
105
105
|
if (useFilename) {
|
|
106
106
|
const toolName = entry.name.replace(/\.ts$/, "");
|
|
107
107
|
if (content.includes("defineTool")) {
|
|
@@ -122,18 +122,18 @@ function scanForNames(dir, useFilename = false) {
|
|
|
122
122
|
}
|
|
123
123
|
function scanHooksForIds(dir) {
|
|
124
124
|
const hookIds = [];
|
|
125
|
-
if (!
|
|
125
|
+
if (!fs9__default.existsSync(dir)) {
|
|
126
126
|
return hookIds;
|
|
127
127
|
}
|
|
128
128
|
try {
|
|
129
|
-
const entries =
|
|
129
|
+
const entries = fs9__default.readdirSync(dir, { withFileTypes: true });
|
|
130
130
|
for (const entry of entries) {
|
|
131
131
|
if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
132
132
|
if (entry.name === "index.ts") {
|
|
133
133
|
continue;
|
|
134
134
|
}
|
|
135
|
-
const filePath =
|
|
136
|
-
const content =
|
|
135
|
+
const filePath = path9__default.join(dir, entry.name);
|
|
136
|
+
const content = fs9__default.readFileSync(filePath, "utf-8");
|
|
137
137
|
const idMatch = content.match(/defineHook\s*\(\s*\{[^}]*id:\s*['"]([^'"]+)['"]/s);
|
|
138
138
|
if (idMatch) {
|
|
139
139
|
hookIds.push(idMatch[1]);
|
|
@@ -801,44 +801,44 @@ declare module 'virtual:@standardagents/router' {
|
|
|
801
801
|
`;
|
|
802
802
|
}
|
|
803
803
|
function ensureDir(dir) {
|
|
804
|
-
if (!
|
|
805
|
-
|
|
804
|
+
if (!fs9__default.existsSync(dir)) {
|
|
805
|
+
fs9__default.mkdirSync(dir, { recursive: true });
|
|
806
806
|
}
|
|
807
807
|
}
|
|
808
808
|
function writeFileIfChanged(filePath, content) {
|
|
809
|
-
if (
|
|
810
|
-
const existing =
|
|
809
|
+
if (fs9__default.existsSync(filePath)) {
|
|
810
|
+
const existing = fs9__default.readFileSync(filePath, "utf-8");
|
|
811
811
|
if (existing === content) {
|
|
812
812
|
return;
|
|
813
813
|
}
|
|
814
814
|
}
|
|
815
|
-
|
|
815
|
+
fs9__default.writeFileSync(filePath, content);
|
|
816
816
|
}
|
|
817
817
|
function generateTypes(config) {
|
|
818
818
|
ensureDir(config.outputDir);
|
|
819
819
|
const typesContent = generateTypesContent(config);
|
|
820
|
-
writeFileIfChanged(
|
|
820
|
+
writeFileIfChanged(path9__default.join(config.outputDir, "types.d.ts"), typesContent);
|
|
821
821
|
const virtualModuleContent = generateVirtualModuleContent();
|
|
822
|
-
writeFileIfChanged(
|
|
823
|
-
writeFileIfChanged(
|
|
824
|
-
writeFileIfChanged(
|
|
822
|
+
writeFileIfChanged(path9__default.join(config.outputDir, "virtual-module.d.ts"), virtualModuleContent);
|
|
823
|
+
writeFileIfChanged(path9__default.join(config.outputDir, "tsconfig.json"), TSCONFIG_CONTENT);
|
|
824
|
+
writeFileIfChanged(path9__default.join(config.outputDir, ".gitignore"), "*\n");
|
|
825
825
|
}
|
|
826
826
|
function needsRegeneration(config) {
|
|
827
|
-
const typesPath =
|
|
828
|
-
if (!
|
|
827
|
+
const typesPath = path9__default.join(config.outputDir, "types.d.ts");
|
|
828
|
+
if (!fs9__default.existsSync(typesPath)) {
|
|
829
829
|
return true;
|
|
830
830
|
}
|
|
831
|
-
const typesMtime =
|
|
831
|
+
const typesMtime = fs9__default.statSync(typesPath).mtime;
|
|
832
832
|
const dirs = [config.modelsDir, config.promptsDir, config.agentsDir, config.toolsDir, config.hooksDir];
|
|
833
833
|
for (const dir of dirs) {
|
|
834
|
-
if (!
|
|
834
|
+
if (!fs9__default.existsSync(dir)) {
|
|
835
835
|
continue;
|
|
836
836
|
}
|
|
837
|
-
const entries =
|
|
837
|
+
const entries = fs9__default.readdirSync(dir, { withFileTypes: true });
|
|
838
838
|
for (const entry of entries) {
|
|
839
839
|
if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
840
|
-
const filePath =
|
|
841
|
-
const fileMtime =
|
|
840
|
+
const filePath = path9__default.join(dir, entry.name);
|
|
841
|
+
const fileMtime = fs9__default.statSync(filePath).mtime;
|
|
842
842
|
if (fileMtime > typesMtime) {
|
|
843
843
|
return true;
|
|
844
844
|
}
|
|
@@ -1044,7 +1044,7 @@ function createHmrReloader() {
|
|
|
1044
1044
|
versions,
|
|
1045
1045
|
invalidateSourceFileModule(server, filePath) {
|
|
1046
1046
|
if (!filePath) return;
|
|
1047
|
-
const absolutePath =
|
|
1047
|
+
const absolutePath = path9__default.resolve(filePath);
|
|
1048
1048
|
for (const [envName, env] of Object.entries(server.environments)) {
|
|
1049
1049
|
const modules = env.moduleGraph.getModulesByFile(absolutePath);
|
|
1050
1050
|
if (!modules) continue;
|
|
@@ -1055,10 +1055,10 @@ function createHmrReloader() {
|
|
|
1055
1055
|
}
|
|
1056
1056
|
},
|
|
1057
1057
|
invalidateSourceDirectoryModules(server, dirPath) {
|
|
1058
|
-
if (!
|
|
1058
|
+
if (!fs9__default.existsSync(dirPath)) return;
|
|
1059
1059
|
const scan = (currentDir) => {
|
|
1060
|
-
for (const entry of
|
|
1061
|
-
const nextPath =
|
|
1060
|
+
for (const entry of fs9__default.readdirSync(currentDir, { withFileTypes: true })) {
|
|
1061
|
+
const nextPath = path9__default.join(currentDir, entry.name);
|
|
1062
1062
|
if (entry.isDirectory()) {
|
|
1063
1063
|
scan(nextPath);
|
|
1064
1064
|
} else if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
@@ -1222,12 +1222,12 @@ function createHmrReloader() {
|
|
|
1222
1222
|
};
|
|
1223
1223
|
return reloader;
|
|
1224
1224
|
}
|
|
1225
|
-
var STATE_RELATIVE_PATH =
|
|
1225
|
+
var STATE_RELATIVE_PATH = path9__default.join(".agents", "bootstrap-session.json");
|
|
1226
1226
|
var PROJECT_ROOT_ENV_KEYS = ["INIT_CWD", "PWD", "npm_config_local_prefix"];
|
|
1227
1227
|
function uniquePaths(paths) {
|
|
1228
1228
|
return Array.from(
|
|
1229
1229
|
new Set(
|
|
1230
|
-
paths.filter((value) => !!value?.trim()).map((value) =>
|
|
1230
|
+
paths.filter((value) => !!value?.trim()).map((value) => path9__default.resolve(value))
|
|
1231
1231
|
)
|
|
1232
1232
|
);
|
|
1233
1233
|
}
|
|
@@ -1243,11 +1243,11 @@ function mergeCookieHeader(cookieHeader, injectedCookie) {
|
|
|
1243
1243
|
return raw ? `${raw}; ${injectedCookie}` : injectedCookie;
|
|
1244
1244
|
}
|
|
1245
1245
|
function loadLocalBootstrapSession(projectRoot) {
|
|
1246
|
-
const statePath =
|
|
1247
|
-
if (!
|
|
1246
|
+
const statePath = path9__default.join(projectRoot, STATE_RELATIVE_PATH);
|
|
1247
|
+
if (!fs9__default.existsSync(statePath)) return null;
|
|
1248
1248
|
try {
|
|
1249
1249
|
const parsed = JSON.parse(
|
|
1250
|
-
|
|
1250
|
+
fs9__default.readFileSync(statePath, "utf-8")
|
|
1251
1251
|
);
|
|
1252
1252
|
if (parsed.version !== 1) return null;
|
|
1253
1253
|
if (!parsed.endpoint || !parsed.user?.id || !parsed.account?.id) return null;
|
|
@@ -1264,7 +1264,7 @@ function findLocalBootstrapSession(projectRoot, env) {
|
|
|
1264
1264
|
const envSession = loadLocalBootstrapSessionFromEnv();
|
|
1265
1265
|
if (envSession) {
|
|
1266
1266
|
return {
|
|
1267
|
-
projectRoot: projectRoot ?
|
|
1267
|
+
projectRoot: projectRoot ? path9__default.resolve(projectRoot) : process.cwd(),
|
|
1268
1268
|
session: envSession
|
|
1269
1269
|
};
|
|
1270
1270
|
}
|
|
@@ -1909,23 +1909,23 @@ function nameToFilename(name) {
|
|
|
1909
1909
|
}
|
|
1910
1910
|
function getModelFilePath(modelsDir, name) {
|
|
1911
1911
|
const filename = nameToFilename(name);
|
|
1912
|
-
return
|
|
1912
|
+
return path9__default.join(modelsDir, `${filename}.ts`);
|
|
1913
1913
|
}
|
|
1914
1914
|
function getProviderFilePath(providersDir, name) {
|
|
1915
1915
|
const filename = nameToFilename(name);
|
|
1916
|
-
return
|
|
1916
|
+
return path9__default.join(providersDir, `${filename}.ts`);
|
|
1917
1917
|
}
|
|
1918
1918
|
function extensionlessImportPath(fromDir, toFile) {
|
|
1919
|
-
let
|
|
1920
|
-
if (!
|
|
1921
|
-
|
|
1919
|
+
let relative4 = path9__default.relative(fromDir, toFile).replace(/\\/g, "/").replace(/\.ts$/, "");
|
|
1920
|
+
if (!relative4.startsWith(".")) {
|
|
1921
|
+
relative4 = `./${relative4}`;
|
|
1922
1922
|
}
|
|
1923
|
-
return
|
|
1923
|
+
return relative4;
|
|
1924
1924
|
}
|
|
1925
1925
|
function getLocalProviderInfo(modelsDir, providersDir, providerName) {
|
|
1926
1926
|
if (!providersDir) return null;
|
|
1927
1927
|
const providerPath = getProviderFilePath(providersDir, providerName);
|
|
1928
|
-
if (!
|
|
1928
|
+
if (!fs9__default.existsSync(providerPath)) return null;
|
|
1929
1929
|
return {
|
|
1930
1930
|
name: nameToFilename(providerName),
|
|
1931
1931
|
package: extensionlessImportPath(modelsDir, providerPath),
|
|
@@ -1934,15 +1934,15 @@ function getLocalProviderInfo(modelsDir, providersDir, providerName) {
|
|
|
1934
1934
|
}
|
|
1935
1935
|
function modelExists(modelsDir, name) {
|
|
1936
1936
|
const filePath = getModelFilePath(modelsDir, name);
|
|
1937
|
-
return
|
|
1937
|
+
return fs9__default.existsSync(filePath);
|
|
1938
1938
|
}
|
|
1939
1939
|
async function saveModel(modelsDir, data, overwrite = false, providerPackageMap = defaultProviderPackageMap, providersDir) {
|
|
1940
1940
|
try {
|
|
1941
|
-
if (!
|
|
1942
|
-
|
|
1941
|
+
if (!fs9__default.existsSync(modelsDir)) {
|
|
1942
|
+
fs9__default.mkdirSync(modelsDir, { recursive: true });
|
|
1943
1943
|
}
|
|
1944
1944
|
const filePath = getModelFilePath(modelsDir, data.name);
|
|
1945
|
-
if (!overwrite &&
|
|
1945
|
+
if (!overwrite && fs9__default.existsSync(filePath)) {
|
|
1946
1946
|
return {
|
|
1947
1947
|
success: false,
|
|
1948
1948
|
error: `Model file already exists: ${filePath}. Use update to modify existing models.`
|
|
@@ -1950,7 +1950,7 @@ async function saveModel(modelsDir, data, overwrite = false, providerPackageMap
|
|
|
1950
1950
|
}
|
|
1951
1951
|
const providerInfo = providerPackageMap[data.provider] ?? getLocalProviderInfo(modelsDir, providersDir, data.provider);
|
|
1952
1952
|
if (!providerInfo) {
|
|
1953
|
-
const localProviderNames = providersDir &&
|
|
1953
|
+
const localProviderNames = providersDir && fs9__default.existsSync(providersDir) ? fs9__default.readdirSync(providersDir).filter((fileName) => fileName.endsWith(".ts")).map((fileName) => fileName.replace(/\.ts$/, "")) : [];
|
|
1954
1954
|
const validProviders = [...Object.keys(providerPackageMap), ...localProviderNames];
|
|
1955
1955
|
return {
|
|
1956
1956
|
success: false,
|
|
@@ -1962,7 +1962,7 @@ async function saveModel(modelsDir, data, overwrite = false, providerPackageMap
|
|
|
1962
1962
|
providerPackage: providerInfo.package,
|
|
1963
1963
|
defaultImport: providerInfo.defaultImport
|
|
1964
1964
|
});
|
|
1965
|
-
await
|
|
1965
|
+
await fs9__default.promises.writeFile(filePath, content, "utf-8");
|
|
1966
1966
|
return {
|
|
1967
1967
|
success: true,
|
|
1968
1968
|
filePath
|
|
@@ -1977,13 +1977,13 @@ async function saveModel(modelsDir, data, overwrite = false, providerPackageMap
|
|
|
1977
1977
|
async function deleteModel(modelsDir, name) {
|
|
1978
1978
|
try {
|
|
1979
1979
|
const filePath = getModelFilePath(modelsDir, name);
|
|
1980
|
-
if (!
|
|
1980
|
+
if (!fs9__default.existsSync(filePath)) {
|
|
1981
1981
|
return {
|
|
1982
1982
|
success: false,
|
|
1983
1983
|
error: `Model file not found: ${filePath}`
|
|
1984
1984
|
};
|
|
1985
1985
|
}
|
|
1986
|
-
await
|
|
1986
|
+
await fs9__default.promises.unlink(filePath);
|
|
1987
1987
|
return {
|
|
1988
1988
|
success: true,
|
|
1989
1989
|
filePath
|
|
@@ -2029,7 +2029,7 @@ function validateModelDataWithProviders(data, providerPackageMap, providersDir)
|
|
|
2029
2029
|
const validProviders = Object.keys(providerPackageMap);
|
|
2030
2030
|
const hasLocalProvider = Boolean(getLocalProviderInfo(process.cwd(), providersDir, data.provider));
|
|
2031
2031
|
if (!validProviders.includes(data.provider) && !hasLocalProvider) {
|
|
2032
|
-
const localProviderNames = providersDir &&
|
|
2032
|
+
const localProviderNames = providersDir && fs9__default.existsSync(providersDir) ? fs9__default.readdirSync(providersDir).filter((fileName) => fileName.endsWith(".ts")).map((fileName) => fileName.replace(/\.ts$/, "")) : [];
|
|
2033
2033
|
errors["provider"] = `Invalid provider '${data.provider}'. Must be one of: ${[...validProviders, ...localProviderNames].join(", ")}`;
|
|
2034
2034
|
}
|
|
2035
2035
|
}
|
|
@@ -2246,26 +2246,26 @@ function transformPromptData(data) {
|
|
|
2246
2246
|
}
|
|
2247
2247
|
function getPromptFilePath(promptsDir, name) {
|
|
2248
2248
|
const filename = nameToFilename(name);
|
|
2249
|
-
return
|
|
2249
|
+
return path9__default.join(promptsDir, `${filename}.ts`);
|
|
2250
2250
|
}
|
|
2251
2251
|
function promptExists(promptsDir, name) {
|
|
2252
2252
|
const filePath = getPromptFilePath(promptsDir, name);
|
|
2253
|
-
return
|
|
2253
|
+
return fs9__default.existsSync(filePath);
|
|
2254
2254
|
}
|
|
2255
2255
|
async function savePrompt(promptsDir, data, overwrite = false) {
|
|
2256
2256
|
try {
|
|
2257
|
-
if (!
|
|
2258
|
-
|
|
2257
|
+
if (!fs9__default.existsSync(promptsDir)) {
|
|
2258
|
+
fs9__default.mkdirSync(promptsDir, { recursive: true });
|
|
2259
2259
|
}
|
|
2260
2260
|
const filePath = getPromptFilePath(promptsDir, data.name);
|
|
2261
|
-
if (!overwrite &&
|
|
2261
|
+
if (!overwrite && fs9__default.existsSync(filePath)) {
|
|
2262
2262
|
return {
|
|
2263
2263
|
success: false,
|
|
2264
2264
|
error: `Prompt file already exists: ${filePath}. Use update to modify existing prompts.`
|
|
2265
2265
|
};
|
|
2266
2266
|
}
|
|
2267
2267
|
const content = generatePromptFile(data);
|
|
2268
|
-
await
|
|
2268
|
+
await fs9__default.promises.writeFile(filePath, content, "utf-8");
|
|
2269
2269
|
return {
|
|
2270
2270
|
success: true,
|
|
2271
2271
|
filePath
|
|
@@ -2280,13 +2280,13 @@ async function savePrompt(promptsDir, data, overwrite = false) {
|
|
|
2280
2280
|
async function deletePrompt(promptsDir, name) {
|
|
2281
2281
|
try {
|
|
2282
2282
|
const filePath = getPromptFilePath(promptsDir, name);
|
|
2283
|
-
if (!
|
|
2283
|
+
if (!fs9__default.existsSync(filePath)) {
|
|
2284
2284
|
return {
|
|
2285
2285
|
success: false,
|
|
2286
2286
|
error: `Prompt file not found: ${filePath}`
|
|
2287
2287
|
};
|
|
2288
2288
|
}
|
|
2289
|
-
await
|
|
2289
|
+
await fs9__default.promises.unlink(filePath);
|
|
2290
2290
|
return {
|
|
2291
2291
|
success: true,
|
|
2292
2292
|
filePath
|
|
@@ -2302,25 +2302,25 @@ async function renamePrompt(promptsDir, oldName, newName) {
|
|
|
2302
2302
|
try {
|
|
2303
2303
|
const oldFilePath = getPromptFilePath(promptsDir, oldName);
|
|
2304
2304
|
const newFilePath = getPromptFilePath(promptsDir, newName);
|
|
2305
|
-
if (!
|
|
2305
|
+
if (!fs9__default.existsSync(oldFilePath)) {
|
|
2306
2306
|
return {
|
|
2307
2307
|
success: false,
|
|
2308
2308
|
error: `Prompt file not found: ${oldFilePath}`
|
|
2309
2309
|
};
|
|
2310
2310
|
}
|
|
2311
|
-
if (
|
|
2311
|
+
if (fs9__default.existsSync(newFilePath)) {
|
|
2312
2312
|
return {
|
|
2313
2313
|
success: false,
|
|
2314
2314
|
error: `Prompt file already exists: ${newFilePath}`
|
|
2315
2315
|
};
|
|
2316
2316
|
}
|
|
2317
|
-
const content = await
|
|
2317
|
+
const content = await fs9__default.promises.readFile(oldFilePath, "utf-8");
|
|
2318
2318
|
const updatedContent = content.replace(
|
|
2319
2319
|
/name:\s*['"]([^'"]+)['"]/,
|
|
2320
2320
|
`name: '${newName}'`
|
|
2321
2321
|
);
|
|
2322
|
-
await
|
|
2323
|
-
await
|
|
2322
|
+
await fs9__default.promises.writeFile(newFilePath, updatedContent, "utf-8");
|
|
2323
|
+
await fs9__default.promises.unlink(oldFilePath);
|
|
2324
2324
|
return {
|
|
2325
2325
|
success: true,
|
|
2326
2326
|
filePath: newFilePath
|
|
@@ -2620,15 +2620,15 @@ function transformAgentData(data) {
|
|
|
2620
2620
|
}
|
|
2621
2621
|
function getAgentFilePath(agentsDir, name) {
|
|
2622
2622
|
const filename = nameToFilename(name);
|
|
2623
|
-
return
|
|
2623
|
+
return path9__default.join(agentsDir, `${filename}.ts`);
|
|
2624
2624
|
}
|
|
2625
2625
|
function agentExists(agentsDir, name) {
|
|
2626
2626
|
const filePath = getAgentFilePath(agentsDir, name);
|
|
2627
|
-
return
|
|
2627
|
+
return fs9__default.existsSync(filePath);
|
|
2628
2628
|
}
|
|
2629
2629
|
function extractAgentMetadata(filePath) {
|
|
2630
2630
|
try {
|
|
2631
|
-
const content =
|
|
2631
|
+
const content = fs9__default.readFileSync(filePath, "utf-8");
|
|
2632
2632
|
const metadata = {};
|
|
2633
2633
|
const packageNameMatch = content.match(/packageName:\s*['"]([^'"]+)['"]/);
|
|
2634
2634
|
if (packageNameMatch) metadata.packageName = packageNameMatch[1];
|
|
@@ -2645,17 +2645,17 @@ function extractAgentMetadata(filePath) {
|
|
|
2645
2645
|
}
|
|
2646
2646
|
async function saveAgent(agentsDir, data, overwrite = false) {
|
|
2647
2647
|
try {
|
|
2648
|
-
if (!
|
|
2649
|
-
|
|
2648
|
+
if (!fs9__default.existsSync(agentsDir)) {
|
|
2649
|
+
fs9__default.mkdirSync(agentsDir, { recursive: true });
|
|
2650
2650
|
}
|
|
2651
2651
|
const filePath = getAgentFilePath(agentsDir, data.name);
|
|
2652
|
-
if (!overwrite &&
|
|
2652
|
+
if (!overwrite && fs9__default.existsSync(filePath)) {
|
|
2653
2653
|
return {
|
|
2654
2654
|
success: false,
|
|
2655
2655
|
error: `Agent file already exists: ${filePath}. Use update to modify existing agents.`
|
|
2656
2656
|
};
|
|
2657
2657
|
}
|
|
2658
|
-
if (overwrite &&
|
|
2658
|
+
if (overwrite && fs9__default.existsSync(filePath)) {
|
|
2659
2659
|
const existingMetadata = extractAgentMetadata(filePath);
|
|
2660
2660
|
if (existingMetadata.packageName && !data.packageName) {
|
|
2661
2661
|
data.packageName = existingMetadata.packageName;
|
|
@@ -2671,7 +2671,7 @@ async function saveAgent(agentsDir, data, overwrite = false) {
|
|
|
2671
2671
|
}
|
|
2672
2672
|
}
|
|
2673
2673
|
const content = generateAgentFile(data);
|
|
2674
|
-
await
|
|
2674
|
+
await fs9__default.promises.writeFile(filePath, content, "utf-8");
|
|
2675
2675
|
return {
|
|
2676
2676
|
success: true,
|
|
2677
2677
|
filePath
|
|
@@ -2686,13 +2686,13 @@ async function saveAgent(agentsDir, data, overwrite = false) {
|
|
|
2686
2686
|
async function deleteAgent(agentsDir, name) {
|
|
2687
2687
|
try {
|
|
2688
2688
|
const filePath = getAgentFilePath(agentsDir, name);
|
|
2689
|
-
if (!
|
|
2689
|
+
if (!fs9__default.existsSync(filePath)) {
|
|
2690
2690
|
return {
|
|
2691
2691
|
success: false,
|
|
2692
2692
|
error: `Agent file not found: ${filePath}`
|
|
2693
2693
|
};
|
|
2694
2694
|
}
|
|
2695
|
-
await
|
|
2695
|
+
await fs9__default.promises.unlink(filePath);
|
|
2696
2696
|
return {
|
|
2697
2697
|
success: true,
|
|
2698
2698
|
filePath
|
|
@@ -2708,25 +2708,25 @@ async function renameModel(modelsDir, oldName, newName) {
|
|
|
2708
2708
|
try {
|
|
2709
2709
|
const oldFilePath = getModelFilePath(modelsDir, oldName);
|
|
2710
2710
|
const newFilePath = getModelFilePath(modelsDir, newName);
|
|
2711
|
-
if (!
|
|
2711
|
+
if (!fs9__default.existsSync(oldFilePath)) {
|
|
2712
2712
|
return {
|
|
2713
2713
|
success: false,
|
|
2714
2714
|
error: `Model file not found: ${oldFilePath}`
|
|
2715
2715
|
};
|
|
2716
2716
|
}
|
|
2717
|
-
if (
|
|
2717
|
+
if (fs9__default.existsSync(newFilePath)) {
|
|
2718
2718
|
return {
|
|
2719
2719
|
success: false,
|
|
2720
2720
|
error: `Model file already exists: ${newFilePath}`
|
|
2721
2721
|
};
|
|
2722
2722
|
}
|
|
2723
|
-
const content = await
|
|
2723
|
+
const content = await fs9__default.promises.readFile(oldFilePath, "utf-8");
|
|
2724
2724
|
const updatedContent = content.replace(
|
|
2725
2725
|
/name:\s*['"]([^'"]+)['"]/,
|
|
2726
2726
|
`name: '${newName}'`
|
|
2727
2727
|
);
|
|
2728
|
-
await
|
|
2729
|
-
await
|
|
2728
|
+
await fs9__default.promises.writeFile(newFilePath, updatedContent, "utf-8");
|
|
2729
|
+
await fs9__default.promises.unlink(oldFilePath);
|
|
2730
2730
|
return {
|
|
2731
2731
|
success: true,
|
|
2732
2732
|
filePath: newFilePath
|
|
@@ -2740,17 +2740,17 @@ async function renameModel(modelsDir, oldName, newName) {
|
|
|
2740
2740
|
}
|
|
2741
2741
|
async function updateModelReferencesInPrompts(promptsDir, oldModelName, newModelName) {
|
|
2742
2742
|
const updatedFiles = [];
|
|
2743
|
-
if (!
|
|
2743
|
+
if (!fs9__default.existsSync(promptsDir)) {
|
|
2744
2744
|
return updatedFiles;
|
|
2745
2745
|
}
|
|
2746
|
-
const files =
|
|
2746
|
+
const files = fs9__default.readdirSync(promptsDir).filter((f) => f.endsWith(".ts"));
|
|
2747
2747
|
for (const file of files) {
|
|
2748
|
-
const filePath =
|
|
2749
|
-
let content = await
|
|
2748
|
+
const filePath = path9__default.join(promptsDir, file);
|
|
2749
|
+
let content = await fs9__default.promises.readFile(filePath, "utf-8");
|
|
2750
2750
|
const modelRegex = new RegExp(`model:\\s*['"]${escapeRegExp(oldModelName)}['"]`, "g");
|
|
2751
2751
|
if (modelRegex.test(content)) {
|
|
2752
2752
|
content = content.replace(modelRegex, `model: '${newModelName}'`);
|
|
2753
|
-
await
|
|
2753
|
+
await fs9__default.promises.writeFile(filePath, content, "utf-8");
|
|
2754
2754
|
updatedFiles.push(filePath);
|
|
2755
2755
|
}
|
|
2756
2756
|
}
|
|
@@ -2758,13 +2758,13 @@ async function updateModelReferencesInPrompts(promptsDir, oldModelName, newModel
|
|
|
2758
2758
|
}
|
|
2759
2759
|
async function updatePromptReferencesInPrompts(promptsDir, oldPromptName, newPromptName) {
|
|
2760
2760
|
const updatedFiles = [];
|
|
2761
|
-
if (!
|
|
2761
|
+
if (!fs9__default.existsSync(promptsDir)) {
|
|
2762
2762
|
return updatedFiles;
|
|
2763
2763
|
}
|
|
2764
|
-
const files =
|
|
2764
|
+
const files = fs9__default.readdirSync(promptsDir).filter((f) => f.endsWith(".ts"));
|
|
2765
2765
|
for (const file of files) {
|
|
2766
|
-
const filePath =
|
|
2767
|
-
let content = await
|
|
2766
|
+
const filePath = path9__default.join(promptsDir, file);
|
|
2767
|
+
let content = await fs9__default.promises.readFile(filePath, "utf-8");
|
|
2768
2768
|
let modified = false;
|
|
2769
2769
|
const toolsArrayRegex = /tools:\s*\[([^\]]*)\]/gs;
|
|
2770
2770
|
const newContent = content.replace(toolsArrayRegex, (match) => {
|
|
@@ -2777,7 +2777,7 @@ async function updatePromptReferencesInPrompts(promptsDir, oldPromptName, newPro
|
|
|
2777
2777
|
return replaced;
|
|
2778
2778
|
});
|
|
2779
2779
|
if (modified) {
|
|
2780
|
-
await
|
|
2780
|
+
await fs9__default.promises.writeFile(filePath, newContent, "utf-8");
|
|
2781
2781
|
updatedFiles.push(filePath);
|
|
2782
2782
|
}
|
|
2783
2783
|
}
|
|
@@ -2785,17 +2785,17 @@ async function updatePromptReferencesInPrompts(promptsDir, oldPromptName, newPro
|
|
|
2785
2785
|
}
|
|
2786
2786
|
async function updatePromptReferencesInAgents(agentsDir, oldPromptName, newPromptName) {
|
|
2787
2787
|
const updatedFiles = [];
|
|
2788
|
-
if (!
|
|
2788
|
+
if (!fs9__default.existsSync(agentsDir)) {
|
|
2789
2789
|
return updatedFiles;
|
|
2790
2790
|
}
|
|
2791
|
-
const files =
|
|
2791
|
+
const files = fs9__default.readdirSync(agentsDir).filter((f) => f.endsWith(".ts"));
|
|
2792
2792
|
for (const file of files) {
|
|
2793
|
-
const filePath =
|
|
2794
|
-
let content = await
|
|
2793
|
+
const filePath = path9__default.join(agentsDir, file);
|
|
2794
|
+
let content = await fs9__default.promises.readFile(filePath, "utf-8");
|
|
2795
2795
|
const promptRegex = new RegExp(`prompt:\\s*['"]${escapeRegExp(oldPromptName)}['"]`, "g");
|
|
2796
2796
|
if (promptRegex.test(content)) {
|
|
2797
2797
|
content = content.replace(promptRegex, `prompt: '${newPromptName}'`);
|
|
2798
|
-
await
|
|
2798
|
+
await fs9__default.promises.writeFile(filePath, content, "utf-8");
|
|
2799
2799
|
updatedFiles.push(filePath);
|
|
2800
2800
|
}
|
|
2801
2801
|
}
|
|
@@ -2922,16 +2922,16 @@ function parseThreadEndpointRouteKey(input) {
|
|
|
2922
2922
|
};
|
|
2923
2923
|
}
|
|
2924
2924
|
function scanThreadEndpointFiles(dir, options = {}) {
|
|
2925
|
-
if (!
|
|
2925
|
+
if (!fs9__default.existsSync(dir)) {
|
|
2926
2926
|
return [];
|
|
2927
2927
|
}
|
|
2928
2928
|
const extensions = options.extensions ?? [".ts"];
|
|
2929
2929
|
const routes = [];
|
|
2930
2930
|
const scan = (currentDir, relativeDir = "") => {
|
|
2931
|
-
const entries =
|
|
2931
|
+
const entries = fs9__default.readdirSync(currentDir, { withFileTypes: true });
|
|
2932
2932
|
for (const entry of entries) {
|
|
2933
|
-
const filePath =
|
|
2934
|
-
const relativePath = relativeDir ?
|
|
2933
|
+
const filePath = path9__default.join(currentDir, entry.name);
|
|
2934
|
+
const relativePath = relativeDir ? path9__default.posix.join(relativeDir, entry.name) : entry.name;
|
|
2935
2935
|
if (entry.isDirectory()) {
|
|
2936
2936
|
scan(filePath, relativePath);
|
|
2937
2937
|
continue;
|
|
@@ -2965,7 +2965,7 @@ function scanApiDirectory(dir) {
|
|
|
2965
2965
|
try {
|
|
2966
2966
|
return scanThreadEndpointFiles(dir, {
|
|
2967
2967
|
extensions: [".ts"],
|
|
2968
|
-
importPathForFile: (filePath) => "./" +
|
|
2968
|
+
importPathForFile: (filePath) => "./" + path9__default.relative(process.cwd(), filePath).replace(/\\/g, "/")
|
|
2969
2969
|
}).map(({ method, route, importPath }) => ({
|
|
2970
2970
|
method,
|
|
2971
2971
|
route,
|
|
@@ -2977,26 +2977,26 @@ function scanApiDirectory(dir) {
|
|
|
2977
2977
|
}
|
|
2978
2978
|
}
|
|
2979
2979
|
function discoverPackedPackageDirectories(packedDir) {
|
|
2980
|
-
if (!
|
|
2980
|
+
if (!fs9__default.existsSync(packedDir)) {
|
|
2981
2981
|
return [];
|
|
2982
2982
|
}
|
|
2983
2983
|
const packageDirs = [];
|
|
2984
|
-
const entries =
|
|
2984
|
+
const entries = fs9__default.readdirSync(packedDir, { withFileTypes: true }).filter((entry) => entry.isDirectory());
|
|
2985
2985
|
for (const entry of entries) {
|
|
2986
|
-
const fullPath =
|
|
2987
|
-
const packageJsonPath =
|
|
2988
|
-
if (
|
|
2986
|
+
const fullPath = path9__default.join(packedDir, entry.name);
|
|
2987
|
+
const packageJsonPath = path9__default.join(fullPath, "package.json");
|
|
2988
|
+
if (fs9__default.existsSync(packageJsonPath)) {
|
|
2989
2989
|
packageDirs.push(fullPath);
|
|
2990
2990
|
continue;
|
|
2991
2991
|
}
|
|
2992
2992
|
if (!entry.name.startsWith("@")) {
|
|
2993
2993
|
continue;
|
|
2994
2994
|
}
|
|
2995
|
-
const scopedEntries =
|
|
2995
|
+
const scopedEntries = fs9__default.readdirSync(fullPath, { withFileTypes: true }).filter((scopedEntry) => scopedEntry.isDirectory());
|
|
2996
2996
|
for (const scopedEntry of scopedEntries) {
|
|
2997
|
-
const scopedPackagePath =
|
|
2998
|
-
const scopedPackageJson =
|
|
2999
|
-
if (
|
|
2997
|
+
const scopedPackagePath = path9__default.join(fullPath, scopedEntry.name);
|
|
2998
|
+
const scopedPackageJson = path9__default.join(scopedPackagePath, "package.json");
|
|
2999
|
+
if (fs9__default.existsSync(scopedPackageJson)) {
|
|
3000
3000
|
packageDirs.push(scopedPackagePath);
|
|
3001
3001
|
}
|
|
3002
3002
|
}
|
|
@@ -3004,26 +3004,26 @@ function discoverPackedPackageDirectories(packedDir) {
|
|
|
3004
3004
|
return packageDirs;
|
|
3005
3005
|
}
|
|
3006
3006
|
function scanPackedDistDirectory(packagePath, outputDir, subDir) {
|
|
3007
|
-
const fullPath =
|
|
3008
|
-
if (!
|
|
3007
|
+
const fullPath = path9__default.join(packagePath, outputDir, subDir);
|
|
3008
|
+
if (!fs9__default.existsSync(fullPath)) {
|
|
3009
3009
|
return [];
|
|
3010
3010
|
}
|
|
3011
|
-
return
|
|
3011
|
+
return fs9__default.readdirSync(fullPath).filter((fileName) => fileName.endsWith(".js") || fileName.endsWith(".ts")).map((fileName) => ({
|
|
3012
3012
|
name: fileName.replace(/\.(js|ts)$/, ""),
|
|
3013
|
-
path:
|
|
3013
|
+
path: path9__default.join(fullPath, fileName).replace(/\\/g, "/")
|
|
3014
3014
|
}));
|
|
3015
3015
|
}
|
|
3016
3016
|
function scanPackedThreadEndpoints(packagePath, outputDir) {
|
|
3017
|
-
const rootDir =
|
|
3018
|
-
if (!
|
|
3017
|
+
const rootDir = path9__default.join(packagePath, outputDir, "thread-endpoints");
|
|
3018
|
+
if (!fs9__default.existsSync(rootDir)) {
|
|
3019
3019
|
return [];
|
|
3020
3020
|
}
|
|
3021
3021
|
const endpoints = [];
|
|
3022
3022
|
const scan = (dir, relativeDir = "") => {
|
|
3023
|
-
const entries =
|
|
3023
|
+
const entries = fs9__default.readdirSync(dir, { withFileTypes: true });
|
|
3024
3024
|
for (const entry of entries) {
|
|
3025
|
-
const nextRelative = relativeDir ?
|
|
3026
|
-
const absolutePath =
|
|
3025
|
+
const nextRelative = relativeDir ? path9__default.posix.join(relativeDir, entry.name) : entry.name;
|
|
3026
|
+
const absolutePath = path9__default.join(dir, entry.name);
|
|
3027
3027
|
if (entry.isDirectory()) {
|
|
3028
3028
|
scan(absolutePath, nextRelative);
|
|
3029
3029
|
continue;
|
|
@@ -3053,7 +3053,7 @@ function isSnakeCase(str) {
|
|
|
3053
3053
|
}
|
|
3054
3054
|
function validateToolFile(filePath, fileName) {
|
|
3055
3055
|
try {
|
|
3056
|
-
const content =
|
|
3056
|
+
const content = fs9__default.readFileSync(filePath, "utf-8");
|
|
3057
3057
|
const hasDefaultExport = /export\s+default\s+defineTool/.test(content);
|
|
3058
3058
|
if (!hasDefaultExport) {
|
|
3059
3059
|
return `Tool file '${fileName}.ts' must have a default export using defineTool()`;
|
|
@@ -3065,15 +3065,15 @@ function validateToolFile(filePath, fileName) {
|
|
|
3065
3065
|
}
|
|
3066
3066
|
async function scanToolsDirectory(dir) {
|
|
3067
3067
|
const tools = [];
|
|
3068
|
-
if (!
|
|
3068
|
+
if (!fs9__default.existsSync(dir)) {
|
|
3069
3069
|
return tools;
|
|
3070
3070
|
}
|
|
3071
|
-
const entries = await
|
|
3071
|
+
const entries = await fs9__default.promises.readdir(dir, { withFileTypes: true });
|
|
3072
3072
|
for (const entry of entries) {
|
|
3073
3073
|
if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
3074
3074
|
const fileName = entry.name.replace(".ts", "");
|
|
3075
|
-
const filePath =
|
|
3076
|
-
const importPath = "./" +
|
|
3075
|
+
const filePath = path9__default.join(dir, entry.name);
|
|
3076
|
+
const importPath = "./" + path9__default.relative(process.cwd(), filePath).replace(/\\/g, "/");
|
|
3077
3077
|
let toolError;
|
|
3078
3078
|
const validationError = validateToolFile(filePath, fileName);
|
|
3079
3079
|
if (validationError) {
|
|
@@ -3100,18 +3100,18 @@ async function scanToolsDirectory(dir) {
|
|
|
3100
3100
|
}
|
|
3101
3101
|
async function scanHooksDirectory(dir) {
|
|
3102
3102
|
const hooks = [];
|
|
3103
|
-
if (!
|
|
3103
|
+
if (!fs9__default.existsSync(dir)) {
|
|
3104
3104
|
return hooks;
|
|
3105
3105
|
}
|
|
3106
|
-
const entries = await
|
|
3106
|
+
const entries = await fs9__default.promises.readdir(dir, { withFileTypes: true });
|
|
3107
3107
|
for (const entry of entries) {
|
|
3108
3108
|
if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
3109
3109
|
const fileName = entry.name.replace(".ts", "");
|
|
3110
3110
|
if (fileName === "index") continue;
|
|
3111
|
-
const filePath =
|
|
3112
|
-
const importPath = "./" +
|
|
3111
|
+
const filePath = path9__default.join(dir, entry.name);
|
|
3112
|
+
const importPath = "./" + path9__default.relative(process.cwd(), filePath).replace(/\\/g, "/");
|
|
3113
3113
|
try {
|
|
3114
|
-
const content =
|
|
3114
|
+
const content = fs9__default.readFileSync(filePath, "utf-8");
|
|
3115
3115
|
const idMatch = content.match(/id:\s*['"]([^'"]+)['"]/);
|
|
3116
3116
|
const hookMatch = content.match(/hook:\s*['"]([^'"]+)['"]/);
|
|
3117
3117
|
if (idMatch && hookMatch) {
|
|
@@ -3134,16 +3134,16 @@ async function scanHooksDirectory(dir) {
|
|
|
3134
3134
|
}
|
|
3135
3135
|
async function scanConfigDirectory(dir, definePattern) {
|
|
3136
3136
|
const items = [];
|
|
3137
|
-
if (!
|
|
3137
|
+
if (!fs9__default.existsSync(dir)) {
|
|
3138
3138
|
return items;
|
|
3139
3139
|
}
|
|
3140
|
-
const entries = await
|
|
3140
|
+
const entries = await fs9__default.promises.readdir(dir, { withFileTypes: true });
|
|
3141
3141
|
for (const entry of entries) {
|
|
3142
3142
|
if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
3143
|
-
const filePath =
|
|
3144
|
-
const importPath = "./" +
|
|
3143
|
+
const filePath = path9__default.join(dir, entry.name);
|
|
3144
|
+
const importPath = "./" + path9__default.relative(process.cwd(), filePath).replace(/\\/g, "/");
|
|
3145
3145
|
try {
|
|
3146
|
-
const content =
|
|
3146
|
+
const content = fs9__default.readFileSync(filePath, "utf-8");
|
|
3147
3147
|
const hasDefaultExport = definePattern.test(content);
|
|
3148
3148
|
if (!hasDefaultExport) {
|
|
3149
3149
|
items.push({
|
|
@@ -3188,20 +3188,20 @@ async function scanAgentsDirectory(dir) {
|
|
|
3188
3188
|
}
|
|
3189
3189
|
async function scanEffectsDirectory(dir) {
|
|
3190
3190
|
const effects = [];
|
|
3191
|
-
if (!
|
|
3191
|
+
if (!fs9__default.existsSync(dir)) {
|
|
3192
3192
|
return effects;
|
|
3193
3193
|
}
|
|
3194
|
-
const entries = await
|
|
3194
|
+
const entries = await fs9__default.promises.readdir(dir, { withFileTypes: true });
|
|
3195
3195
|
for (const entry of entries) {
|
|
3196
3196
|
if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
3197
3197
|
const fileName = entry.name.replace(".ts", "");
|
|
3198
|
-
const filePath =
|
|
3199
|
-
const importPath = "./" +
|
|
3198
|
+
const filePath = path9__default.join(dir, entry.name);
|
|
3199
|
+
const importPath = "./" + path9__default.relative(process.cwd(), filePath).replace(/\\/g, "/");
|
|
3200
3200
|
if (fileName === "CLAUDE" || fileName.startsWith("_")) {
|
|
3201
3201
|
continue;
|
|
3202
3202
|
}
|
|
3203
3203
|
try {
|
|
3204
|
-
const content =
|
|
3204
|
+
const content = fs9__default.readFileSync(filePath, "utf-8");
|
|
3205
3205
|
if (!content.includes("defineEffect")) {
|
|
3206
3206
|
continue;
|
|
3207
3207
|
}
|
|
@@ -3214,14 +3214,14 @@ async function scanEffectsDirectory(dir) {
|
|
|
3214
3214
|
return effects;
|
|
3215
3215
|
}
|
|
3216
3216
|
function parseRequestBody(req) {
|
|
3217
|
-
return new Promise((
|
|
3217
|
+
return new Promise((resolve3, reject) => {
|
|
3218
3218
|
let body = "";
|
|
3219
3219
|
req.on("data", (chunk) => {
|
|
3220
3220
|
body += chunk.toString();
|
|
3221
3221
|
});
|
|
3222
3222
|
req.on("end", () => {
|
|
3223
3223
|
try {
|
|
3224
|
-
|
|
3224
|
+
resolve3(body ? JSON.parse(body) : {});
|
|
3225
3225
|
} catch {
|
|
3226
3226
|
reject(new Error("Invalid JSON body"));
|
|
3227
3227
|
}
|
|
@@ -3231,17 +3231,17 @@ function parseRequestBody(req) {
|
|
|
3231
3231
|
}
|
|
3232
3232
|
function scanUsersDirectory(dir) {
|
|
3233
3233
|
const results = [];
|
|
3234
|
-
if (!
|
|
3234
|
+
if (!fs9__default.existsSync(dir)) return results;
|
|
3235
3235
|
const walk = (current, prefix) => {
|
|
3236
3236
|
let entries;
|
|
3237
3237
|
try {
|
|
3238
|
-
entries =
|
|
3238
|
+
entries = fs9__default.readdirSync(current, { withFileTypes: true });
|
|
3239
3239
|
} catch (error) {
|
|
3240
3240
|
console.error(`Error scanning users directory ${current}:`, error);
|
|
3241
3241
|
return;
|
|
3242
3242
|
}
|
|
3243
3243
|
for (const entry of entries) {
|
|
3244
|
-
const fullPath =
|
|
3244
|
+
const fullPath = path9__default.join(current, entry.name);
|
|
3245
3245
|
if (entry.isDirectory()) {
|
|
3246
3246
|
walk(fullPath, prefix ? `${prefix}/${entry.name}` : entry.name);
|
|
3247
3247
|
continue;
|
|
@@ -3251,7 +3251,7 @@ function scanUsersDirectory(dir) {
|
|
|
3251
3251
|
const key = prefix ? `${prefix}/${base}` : base;
|
|
3252
3252
|
results.push({
|
|
3253
3253
|
key,
|
|
3254
|
-
importPath: "./" +
|
|
3254
|
+
importPath: "./" + path9__default.relative(process.cwd(), fullPath).replace(/\\/g, "/")
|
|
3255
3255
|
});
|
|
3256
3256
|
}
|
|
3257
3257
|
};
|
|
@@ -3484,7 +3484,7 @@ async function handleModelApiRequest(context) {
|
|
|
3484
3484
|
}
|
|
3485
3485
|
await hmr.reloadRouterModule(server);
|
|
3486
3486
|
await hmr.reloadBuilderModule(server);
|
|
3487
|
-
await new Promise((
|
|
3487
|
+
await new Promise((resolve3) => setTimeout(resolve3, 100));
|
|
3488
3488
|
res.statusCode = 200;
|
|
3489
3489
|
res.setHeader("Content-Type", "application/json");
|
|
3490
3490
|
res.end(JSON.stringify({
|
|
@@ -3711,6 +3711,49 @@ async function handleConfigApiRequest(context) {
|
|
|
3711
3711
|
if (await handleAgentApiRequest(context)) return true;
|
|
3712
3712
|
return false;
|
|
3713
3713
|
}
|
|
3714
|
+
|
|
3715
|
+
// src/packing/package-identifier.ts
|
|
3716
|
+
function assertSafePackageIdentifier(identifier) {
|
|
3717
|
+
const value = identifier.trim();
|
|
3718
|
+
if (!value || value.includes("\\") || value.includes("\0") || value.startsWith("/")) {
|
|
3719
|
+
throw new Error("Invalid package identifier");
|
|
3720
|
+
}
|
|
3721
|
+
const parts = value.split("/");
|
|
3722
|
+
const scoped = parts.length === 2 && parts[0].startsWith("@");
|
|
3723
|
+
if (parts.length > 1 && !scoped) throw new Error("Invalid package identifier");
|
|
3724
|
+
if (parts.some((part) => !part || part === "." || part === ".." || !/^@?[a-zA-Z0-9._-]+$/.test(part))) {
|
|
3725
|
+
throw new Error("Invalid package identifier");
|
|
3726
|
+
}
|
|
3727
|
+
return value;
|
|
3728
|
+
}
|
|
3729
|
+
|
|
3730
|
+
// src/packing/path-safety.ts
|
|
3731
|
+
function isWithin(base, candidate) {
|
|
3732
|
+
const relative4 = path9.relative(base, candidate);
|
|
3733
|
+
return relative4 === "" || !relative4.startsWith(`..${path9.sep}`) && relative4 !== ".." && !path9.isAbsolute(relative4);
|
|
3734
|
+
}
|
|
3735
|
+
function resolvePathWithin(base, ...segments) {
|
|
3736
|
+
const resolvedBase = path9.resolve(base);
|
|
3737
|
+
const candidate = path9.resolve(resolvedBase, ...segments);
|
|
3738
|
+
if (!isWithin(resolvedBase, candidate)) {
|
|
3739
|
+
throw new Error("Path must remain inside the configured AgentBuilder directory");
|
|
3740
|
+
}
|
|
3741
|
+
if (fs9.existsSync(resolvedBase)) {
|
|
3742
|
+
const realBase = fs9.realpathSync(resolvedBase);
|
|
3743
|
+
if (typeof realBase !== "string") return candidate;
|
|
3744
|
+
let existing = candidate;
|
|
3745
|
+
while (!fs9.existsSync(existing) && existing !== resolvedBase) {
|
|
3746
|
+
existing = path9.dirname(existing);
|
|
3747
|
+
}
|
|
3748
|
+
if (fs9.existsSync(existing)) {
|
|
3749
|
+
const realExisting = fs9.realpathSync(existing);
|
|
3750
|
+
if (typeof realExisting === "string" && !isWithin(realBase, realExisting)) {
|
|
3751
|
+
throw new Error("Path traverses a symlink outside the configured AgentBuilder directory");
|
|
3752
|
+
}
|
|
3753
|
+
}
|
|
3754
|
+
}
|
|
3755
|
+
return candidate;
|
|
3756
|
+
}
|
|
3714
3757
|
var MetadataService = class {
|
|
3715
3758
|
metadataDir;
|
|
3716
3759
|
/**
|
|
@@ -3719,7 +3762,7 @@ var MetadataService = class {
|
|
|
3719
3762
|
* @param agentsDir - Path to the agents/ directory
|
|
3720
3763
|
*/
|
|
3721
3764
|
constructor(agentsDir) {
|
|
3722
|
-
this.metadataDir =
|
|
3765
|
+
this.metadataDir = path9.join(agentsDir, ".standardagent");
|
|
3723
3766
|
}
|
|
3724
3767
|
/**
|
|
3725
3768
|
* Read metadata for an agent.
|
|
@@ -3729,11 +3772,11 @@ var MetadataService = class {
|
|
|
3729
3772
|
*/
|
|
3730
3773
|
async read(agentName) {
|
|
3731
3774
|
const filePath = this.getMetadataPath(agentName);
|
|
3732
|
-
if (!
|
|
3775
|
+
if (!fs9.existsSync(filePath)) {
|
|
3733
3776
|
return null;
|
|
3734
3777
|
}
|
|
3735
3778
|
try {
|
|
3736
|
-
const content =
|
|
3779
|
+
const content = fs9.readFileSync(filePath, "utf-8");
|
|
3737
3780
|
return JSON.parse(content);
|
|
3738
3781
|
} catch {
|
|
3739
3782
|
return null;
|
|
@@ -3746,11 +3789,11 @@ var MetadataService = class {
|
|
|
3746
3789
|
* @param metadata - Metadata to write
|
|
3747
3790
|
*/
|
|
3748
3791
|
async write(agentName, metadata) {
|
|
3749
|
-
if (!
|
|
3750
|
-
|
|
3792
|
+
if (!fs9.existsSync(this.metadataDir)) {
|
|
3793
|
+
fs9.mkdirSync(this.metadataDir, { recursive: true });
|
|
3751
3794
|
}
|
|
3752
3795
|
const filePath = this.getMetadataPath(agentName);
|
|
3753
|
-
|
|
3796
|
+
fs9.writeFileSync(filePath, JSON.stringify(metadata, null, 2));
|
|
3754
3797
|
}
|
|
3755
3798
|
/**
|
|
3756
3799
|
* Delete metadata for an agent.
|
|
@@ -3759,8 +3802,8 @@ var MetadataService = class {
|
|
|
3759
3802
|
*/
|
|
3760
3803
|
async delete(agentName) {
|
|
3761
3804
|
const filePath = this.getMetadataPath(agentName);
|
|
3762
|
-
if (
|
|
3763
|
-
|
|
3805
|
+
if (fs9.existsSync(filePath)) {
|
|
3806
|
+
fs9.unlinkSync(filePath);
|
|
3764
3807
|
}
|
|
3765
3808
|
}
|
|
3766
3809
|
/**
|
|
@@ -3841,7 +3884,7 @@ var MetadataService = class {
|
|
|
3841
3884
|
* Get the file path for an agent's metadata.
|
|
3842
3885
|
*/
|
|
3843
3886
|
getMetadataPath(agentName) {
|
|
3844
|
-
return
|
|
3887
|
+
return path9.join(this.metadataDir, `${agentName}.json`);
|
|
3845
3888
|
}
|
|
3846
3889
|
};
|
|
3847
3890
|
var _ts;
|
|
@@ -4213,9 +4256,9 @@ var PackingService = class {
|
|
|
4213
4256
|
* @returns Version specifier (e.g., '^1.2.3') or '*' if not found
|
|
4214
4257
|
*/
|
|
4215
4258
|
resolvePackageVersion(pkgName, rootDir) {
|
|
4216
|
-
const pkgJsonPath =
|
|
4259
|
+
const pkgJsonPath = path9.join(rootDir, "node_modules", pkgName, "package.json");
|
|
4217
4260
|
try {
|
|
4218
|
-
const pkgJson = JSON.parse(
|
|
4261
|
+
const pkgJson = JSON.parse(fs9.readFileSync(pkgJsonPath, "utf-8"));
|
|
4219
4262
|
return `^${pkgJson.version}`;
|
|
4220
4263
|
} catch {
|
|
4221
4264
|
return "*";
|
|
@@ -4232,7 +4275,7 @@ var PackingService = class {
|
|
|
4232
4275
|
* @returns Analysis result with all discovered constituents
|
|
4233
4276
|
*/
|
|
4234
4277
|
async analyzeAgent(agentName, rootDir) {
|
|
4235
|
-
const agentsDir =
|
|
4278
|
+
const agentsDir = path9.join(rootDir, "agents");
|
|
4236
4279
|
const analysis = {
|
|
4237
4280
|
agent: agentName,
|
|
4238
4281
|
primaryPrompt: "",
|
|
@@ -4256,7 +4299,7 @@ var PackingService = class {
|
|
|
4256
4299
|
warnings: [],
|
|
4257
4300
|
errors: []
|
|
4258
4301
|
};
|
|
4259
|
-
const agentFilePath = await this.findFile(
|
|
4302
|
+
const agentFilePath = await this.findFile(path9.join(agentsDir, "agents"), agentName);
|
|
4260
4303
|
if (!agentFilePath) {
|
|
4261
4304
|
analysis.errors.push(`Agent file not found: ${agentName}`);
|
|
4262
4305
|
return analysis;
|
|
@@ -4267,7 +4310,7 @@ var PackingService = class {
|
|
|
4267
4310
|
discoveredVia: "static",
|
|
4268
4311
|
sharedWith: []
|
|
4269
4312
|
});
|
|
4270
|
-
const agentSource =
|
|
4313
|
+
const agentSource = fs9.readFileSync(agentFilePath, "utf-8");
|
|
4271
4314
|
const agentPrompts = await extractAgentPrompts(agentSource);
|
|
4272
4315
|
if (agentPrompts.sideA) {
|
|
4273
4316
|
analysis.primaryPrompt = agentPrompts.sideA;
|
|
@@ -4292,13 +4335,13 @@ var PackingService = class {
|
|
|
4292
4335
|
* @returns Object with generatedReadme and agentDescription
|
|
4293
4336
|
*/
|
|
4294
4337
|
async generateReadmeForAnalysis(analysis, rootDir) {
|
|
4295
|
-
const agentsDir =
|
|
4338
|
+
const agentsDir = path9.join(rootDir, "agents");
|
|
4296
4339
|
const metadataService = new MetadataService(agentsDir);
|
|
4297
4340
|
let agentDescription;
|
|
4298
4341
|
const agentItem = analysis.constituents.agents.find((a) => a.name === analysis.agent);
|
|
4299
4342
|
if (agentItem?.filePath) {
|
|
4300
4343
|
try {
|
|
4301
|
-
const agentSource =
|
|
4344
|
+
const agentSource = fs9.readFileSync(agentItem.filePath, "utf-8");
|
|
4302
4345
|
agentDescription = await extractAgentDescription(agentSource) || void 0;
|
|
4303
4346
|
} catch {
|
|
4304
4347
|
}
|
|
@@ -4322,7 +4365,7 @@ var PackingService = class {
|
|
|
4322
4365
|
* include all endpoint modules discovered under agents/api.
|
|
4323
4366
|
*/
|
|
4324
4367
|
async analyzeThreadEndpoints(agentsDir, analysis) {
|
|
4325
|
-
const apiDir =
|
|
4368
|
+
const apiDir = path9.join(agentsDir, "api");
|
|
4326
4369
|
const endpoints = this.scanThreadEndpointFiles(apiDir);
|
|
4327
4370
|
for (const endpoint of endpoints) {
|
|
4328
4371
|
if (analysis.constituents.threadEndpoints.some((item) => item.name === endpoint.name)) {
|
|
@@ -4344,15 +4387,15 @@ var PackingService = class {
|
|
|
4344
4387
|
* - `admin/users/[userId]/sync.post`
|
|
4345
4388
|
*/
|
|
4346
4389
|
scanThreadEndpointFiles(apiDir, relativeDir = "") {
|
|
4347
|
-
if (!
|
|
4390
|
+
if (!fs9.existsSync(apiDir)) {
|
|
4348
4391
|
return [];
|
|
4349
4392
|
}
|
|
4350
4393
|
const endpoints = [];
|
|
4351
|
-
const currentDir = relativeDir ?
|
|
4352
|
-
if (!
|
|
4394
|
+
const currentDir = relativeDir ? path9.join(apiDir, relativeDir) : apiDir;
|
|
4395
|
+
if (!fs9.existsSync(currentDir)) {
|
|
4353
4396
|
return endpoints;
|
|
4354
4397
|
}
|
|
4355
|
-
const entries =
|
|
4398
|
+
const entries = fs9.readdirSync(currentDir, { withFileTypes: true });
|
|
4356
4399
|
if (entries.length > 0 && typeof entries[0] === "string") {
|
|
4357
4400
|
return endpoints;
|
|
4358
4401
|
}
|
|
@@ -4360,8 +4403,8 @@ var PackingService = class {
|
|
|
4360
4403
|
const entryName = typeof entry === "string" ? entry : entry.name;
|
|
4361
4404
|
const isDirectory = typeof entry === "string" ? false : entry.isDirectory();
|
|
4362
4405
|
const isFile = typeof entry === "string" ? true : entry.isFile();
|
|
4363
|
-
const entryRelative = relativeDir ?
|
|
4364
|
-
const absolutePath =
|
|
4406
|
+
const entryRelative = relativeDir ? path9.posix.join(relativeDir.replace(/\\/g, "/"), entryName) : entryName;
|
|
4407
|
+
const absolutePath = path9.join(apiDir, entryRelative);
|
|
4365
4408
|
if (isDirectory) {
|
|
4366
4409
|
endpoints.push(...this.scanThreadEndpointFiles(apiDir, entryRelative));
|
|
4367
4410
|
continue;
|
|
@@ -4388,7 +4431,7 @@ var PackingService = class {
|
|
|
4388
4431
|
* include all effect modules discovered under agents/effects.
|
|
4389
4432
|
*/
|
|
4390
4433
|
async analyzeEffects(agentsDir, analysis) {
|
|
4391
|
-
const effectsDir =
|
|
4434
|
+
const effectsDir = path9.join(agentsDir, "effects");
|
|
4392
4435
|
const effects = this.scanEffectFiles(effectsDir);
|
|
4393
4436
|
for (const effect of effects) {
|
|
4394
4437
|
if (analysis.constituents.effects.some((item) => item.name === effect.name)) {
|
|
@@ -4410,15 +4453,15 @@ var PackingService = class {
|
|
|
4410
4453
|
* - `notifications/digest`
|
|
4411
4454
|
*/
|
|
4412
4455
|
scanEffectFiles(effectsDir, relativeDir = "") {
|
|
4413
|
-
if (!
|
|
4456
|
+
if (!fs9.existsSync(effectsDir)) {
|
|
4414
4457
|
return [];
|
|
4415
4458
|
}
|
|
4416
4459
|
const effects = [];
|
|
4417
|
-
const currentDir = relativeDir ?
|
|
4418
|
-
if (!
|
|
4460
|
+
const currentDir = relativeDir ? path9.join(effectsDir, relativeDir) : effectsDir;
|
|
4461
|
+
if (!fs9.existsSync(currentDir)) {
|
|
4419
4462
|
return effects;
|
|
4420
4463
|
}
|
|
4421
|
-
const entries =
|
|
4464
|
+
const entries = fs9.readdirSync(currentDir, { withFileTypes: true });
|
|
4422
4465
|
if (entries.length > 0 && typeof entries[0] === "string") {
|
|
4423
4466
|
return effects;
|
|
4424
4467
|
}
|
|
@@ -4426,8 +4469,8 @@ var PackingService = class {
|
|
|
4426
4469
|
const entryName = typeof entry === "string" ? entry : entry.name;
|
|
4427
4470
|
const isDirectory = typeof entry === "string" ? false : entry.isDirectory();
|
|
4428
4471
|
const isFile = typeof entry === "string" ? true : entry.isFile();
|
|
4429
|
-
const entryRelative = relativeDir ?
|
|
4430
|
-
const absolutePath =
|
|
4472
|
+
const entryRelative = relativeDir ? path9.posix.join(relativeDir.replace(/\\/g, "/"), entryName) : entryName;
|
|
4473
|
+
const absolutePath = path9.join(effectsDir, entryRelative);
|
|
4431
4474
|
if (isDirectory) {
|
|
4432
4475
|
effects.push(...this.scanEffectFiles(effectsDir, entryRelative));
|
|
4433
4476
|
continue;
|
|
@@ -4451,7 +4494,7 @@ var PackingService = class {
|
|
|
4451
4494
|
* Recursively analyze a prompt and its dependencies.
|
|
4452
4495
|
*/
|
|
4453
4496
|
async analyzePrompt(promptName, agentsDir, analysis, visited, parentKey) {
|
|
4454
|
-
const promptFilePath = await this.findFile(
|
|
4497
|
+
const promptFilePath = await this.findFile(path9.join(agentsDir, "prompts"), promptName);
|
|
4455
4498
|
if (!promptFilePath) {
|
|
4456
4499
|
analysis.warnings.push(`Prompt file not found: ${promptName}`);
|
|
4457
4500
|
return;
|
|
@@ -4470,7 +4513,7 @@ var PackingService = class {
|
|
|
4470
4513
|
return;
|
|
4471
4514
|
}
|
|
4472
4515
|
visited.add(`prompt:${promptName}`);
|
|
4473
|
-
const promptSource =
|
|
4516
|
+
const promptSource = fs9.readFileSync(promptFilePath, "utf-8");
|
|
4474
4517
|
const modelName = await extractPromptModel(promptSource);
|
|
4475
4518
|
if (modelName) {
|
|
4476
4519
|
await this.analyzeModel(modelName, agentsDir, analysis, visited, thisKey);
|
|
@@ -4496,17 +4539,17 @@ var PackingService = class {
|
|
|
4496
4539
|
*/
|
|
4497
4540
|
async analyzeTool(toolName, agentsDir, analysis, visited, discoveredVia, parentKey) {
|
|
4498
4541
|
const thisKey = `tool:${toolName}`;
|
|
4499
|
-
const promptFilePath = await this.findFile(
|
|
4542
|
+
const promptFilePath = await this.findFile(path9.join(agentsDir, "prompts"), toolName);
|
|
4500
4543
|
if (promptFilePath) {
|
|
4501
4544
|
await this.analyzePrompt(toolName, agentsDir, analysis, visited, parentKey);
|
|
4502
4545
|
return;
|
|
4503
4546
|
}
|
|
4504
|
-
const agentFilePath = await this.findFile(
|
|
4547
|
+
const agentFilePath = await this.findFile(path9.join(agentsDir, "agents"), toolName);
|
|
4505
4548
|
if (agentFilePath) {
|
|
4506
4549
|
await this.analyzeNestedAgent(toolName, agentsDir, analysis, visited, parentKey);
|
|
4507
4550
|
return;
|
|
4508
4551
|
}
|
|
4509
|
-
const toolFilePath = await this.findFile(
|
|
4552
|
+
const toolFilePath = await this.findFile(path9.join(agentsDir, "tools"), toolName);
|
|
4510
4553
|
if (!toolFilePath) {
|
|
4511
4554
|
analysis.warnings.push(`Tool file not found: ${toolName}`);
|
|
4512
4555
|
return;
|
|
@@ -4524,7 +4567,7 @@ var PackingService = class {
|
|
|
4524
4567
|
return;
|
|
4525
4568
|
}
|
|
4526
4569
|
visited.add(`tool:${toolName}`);
|
|
4527
|
-
const toolSource =
|
|
4570
|
+
const toolSource = fs9.readFileSync(toolFilePath, "utf-8");
|
|
4528
4571
|
const { uses } = await extractToolUses(toolSource);
|
|
4529
4572
|
for (const usedItem of uses) {
|
|
4530
4573
|
await this.analyzeTool(usedItem, agentsDir, analysis, visited, "uses", thisKey);
|
|
@@ -4534,7 +4577,7 @@ var PackingService = class {
|
|
|
4534
4577
|
* Analyze a nested agent (used as a handoff target).
|
|
4535
4578
|
*/
|
|
4536
4579
|
async analyzeNestedAgent(agentName, agentsDir, analysis, visited, parentKey) {
|
|
4537
|
-
const agentFilePath = await this.findFile(
|
|
4580
|
+
const agentFilePath = await this.findFile(path9.join(agentsDir, "agents"), agentName);
|
|
4538
4581
|
if (!agentFilePath) {
|
|
4539
4582
|
analysis.warnings.push(`Agent file not found: ${agentName}`);
|
|
4540
4583
|
return;
|
|
@@ -4553,7 +4596,7 @@ var PackingService = class {
|
|
|
4553
4596
|
return;
|
|
4554
4597
|
}
|
|
4555
4598
|
visited.add(`agent:${agentName}`);
|
|
4556
|
-
const agentSource =
|
|
4599
|
+
const agentSource = fs9.readFileSync(agentFilePath, "utf-8");
|
|
4557
4600
|
const agentPrompts = await extractAgentPrompts(agentSource);
|
|
4558
4601
|
if (agentPrompts.sideA) {
|
|
4559
4602
|
await this.analyzePrompt(agentPrompts.sideA, agentsDir, analysis, visited, thisKey);
|
|
@@ -4566,7 +4609,7 @@ var PackingService = class {
|
|
|
4566
4609
|
* Analyze a model and its fallbacks.
|
|
4567
4610
|
*/
|
|
4568
4611
|
async analyzeModel(modelName, agentsDir, analysis, visited, parentKey) {
|
|
4569
|
-
const modelFilePath = await this.findFile(
|
|
4612
|
+
const modelFilePath = await this.findFile(path9.join(agentsDir, "models"), modelName);
|
|
4570
4613
|
if (!modelFilePath) {
|
|
4571
4614
|
analysis.warnings.push(`Model file not found: ${modelName}`);
|
|
4572
4615
|
return;
|
|
@@ -4585,7 +4628,7 @@ var PackingService = class {
|
|
|
4585
4628
|
return;
|
|
4586
4629
|
}
|
|
4587
4630
|
visited.add(`model:${modelName}`);
|
|
4588
|
-
const modelSource =
|
|
4631
|
+
const modelSource = fs9.readFileSync(modelFilePath, "utf-8");
|
|
4589
4632
|
const fallbacks = await extractModelFallbacks(modelSource);
|
|
4590
4633
|
for (const fallbackName of fallbacks) {
|
|
4591
4634
|
await this.analyzeModel(fallbackName, agentsDir, analysis, visited, thisKey);
|
|
@@ -4595,13 +4638,13 @@ var PackingService = class {
|
|
|
4595
4638
|
* Check which items are shared with other agents.
|
|
4596
4639
|
*/
|
|
4597
4640
|
async checkSharedItems(agentsDir, analysis) {
|
|
4598
|
-
const agentsPath =
|
|
4599
|
-
if (!
|
|
4600
|
-
const agentFiles =
|
|
4641
|
+
const agentsPath = path9.join(agentsDir, "agents");
|
|
4642
|
+
if (!fs9.existsSync(agentsPath)) return;
|
|
4643
|
+
const agentFiles = fs9.readdirSync(agentsPath).filter((f) => f.endsWith(".ts"));
|
|
4601
4644
|
for (const agentFile of agentFiles) {
|
|
4602
4645
|
const otherAgentName = agentFile.replace(".ts", "");
|
|
4603
4646
|
if (otherAgentName === analysis.agent) continue;
|
|
4604
|
-
const otherAnalysis = await this.analyzeAgentLight(otherAgentName,
|
|
4647
|
+
const otherAnalysis = await this.analyzeAgentLight(otherAgentName, path9.dirname(agentsDir));
|
|
4605
4648
|
for (const prompt of analysis.constituents.prompts) {
|
|
4606
4649
|
if (otherAnalysis.prompts.includes(prompt.name)) {
|
|
4607
4650
|
prompt.sharedWith.push(otherAgentName);
|
|
@@ -4633,19 +4676,19 @@ var PackingService = class {
|
|
|
4633
4676
|
*/
|
|
4634
4677
|
async analyzeAgentLight(agentName, rootDir) {
|
|
4635
4678
|
const result = { prompts: [], tools: [], models: [] };
|
|
4636
|
-
const agentsDir =
|
|
4679
|
+
const agentsDir = path9.join(rootDir, "agents");
|
|
4637
4680
|
const visited = /* @__PURE__ */ new Set();
|
|
4638
|
-
const agentFilePath = await this.findFile(
|
|
4681
|
+
const agentFilePath = await this.findFile(path9.join(agentsDir, "agents"), agentName);
|
|
4639
4682
|
if (!agentFilePath) return result;
|
|
4640
|
-
const agentSource =
|
|
4683
|
+
const agentSource = fs9.readFileSync(agentFilePath, "utf-8");
|
|
4641
4684
|
const agentPrompts = await extractAgentPrompts(agentSource);
|
|
4642
4685
|
const analyzePromptLight = async (promptName) => {
|
|
4643
4686
|
if (visited.has(promptName)) return;
|
|
4644
4687
|
visited.add(promptName);
|
|
4645
4688
|
result.prompts.push(promptName);
|
|
4646
|
-
const promptFilePath = await this.findFile(
|
|
4689
|
+
const promptFilePath = await this.findFile(path9.join(agentsDir, "prompts"), promptName);
|
|
4647
4690
|
if (!promptFilePath) return;
|
|
4648
|
-
const promptSource =
|
|
4691
|
+
const promptSource = fs9.readFileSync(promptFilePath, "utf-8");
|
|
4649
4692
|
const modelName = await extractPromptModel(promptSource);
|
|
4650
4693
|
if (modelName && !result.models.includes(modelName)) {
|
|
4651
4694
|
result.models.push(modelName);
|
|
@@ -4718,14 +4761,15 @@ var PackingService = class {
|
|
|
4718
4761
|
return result;
|
|
4719
4762
|
}
|
|
4720
4763
|
result.warnings = analysis.warnings;
|
|
4721
|
-
const
|
|
4722
|
-
|
|
4723
|
-
|
|
4724
|
-
|
|
4725
|
-
|
|
4726
|
-
|
|
4727
|
-
|
|
4728
|
-
|
|
4764
|
+
const safePackageId = assertSafePackageIdentifier(packageId);
|
|
4765
|
+
const pkgOutputDir = resolvePathWithin(outputDir, safePackageId);
|
|
4766
|
+
fs9.mkdirSync(path9.join(pkgOutputDir, "dist", "agents"), { recursive: true });
|
|
4767
|
+
fs9.mkdirSync(path9.join(pkgOutputDir, "dist", "prompts"), { recursive: true });
|
|
4768
|
+
fs9.mkdirSync(path9.join(pkgOutputDir, "dist", "tools"), { recursive: true });
|
|
4769
|
+
fs9.mkdirSync(path9.join(pkgOutputDir, "dist", "models"), { recursive: true });
|
|
4770
|
+
fs9.mkdirSync(path9.join(pkgOutputDir, "dist", "hooks"), { recursive: true });
|
|
4771
|
+
fs9.mkdirSync(path9.join(pkgOutputDir, "dist", "effects"), { recursive: true });
|
|
4772
|
+
fs9.mkdirSync(path9.join(pkgOutputDir, "dist", "thread-endpoints"), { recursive: true });
|
|
4729
4773
|
const seenItems = /* @__PURE__ */ new Set();
|
|
4730
4774
|
const allItems = [];
|
|
4731
4775
|
for (const a of analysis.constituents.agents) {
|
|
@@ -4779,13 +4823,13 @@ var PackingService = class {
|
|
|
4779
4823
|
}
|
|
4780
4824
|
const externalDeps = /* @__PURE__ */ new Map();
|
|
4781
4825
|
for (const item of allItems) {
|
|
4782
|
-
const outputPath =
|
|
4826
|
+
const outputPath = resolvePathWithin(
|
|
4783
4827
|
pkgOutputDir,
|
|
4784
4828
|
"dist",
|
|
4785
4829
|
this.getTypeDir(item.type),
|
|
4786
4830
|
`${item.name}.js`
|
|
4787
4831
|
);
|
|
4788
|
-
|
|
4832
|
+
fs9.mkdirSync(path9.dirname(outputPath), { recursive: true });
|
|
4789
4833
|
const deps = await this.bundleFile(item.filePath, outputPath, rootDir);
|
|
4790
4834
|
for (const [depName, depVersion] of deps) {
|
|
4791
4835
|
if (!externalDeps.has(depName)) {
|
|
@@ -4795,12 +4839,12 @@ var PackingService = class {
|
|
|
4795
4839
|
result.filesCreated.push(outputPath);
|
|
4796
4840
|
}
|
|
4797
4841
|
const indexJs = this.generateReExportIndex(analysis, meta);
|
|
4798
|
-
const indexJsPath =
|
|
4799
|
-
|
|
4842
|
+
const indexJsPath = resolvePathWithin(pkgOutputDir, "dist", "index.js");
|
|
4843
|
+
fs9.writeFileSync(indexJsPath, indexJs);
|
|
4800
4844
|
result.filesCreated.push(indexJsPath);
|
|
4801
4845
|
const indexDts = this.generateIndexDts(analysis);
|
|
4802
|
-
const indexDtsPath =
|
|
4803
|
-
|
|
4846
|
+
const indexDtsPath = resolvePathWithin(pkgOutputDir, "dist", "index.d.ts");
|
|
4847
|
+
fs9.writeFileSync(indexDtsPath, indexDts);
|
|
4804
4848
|
result.filesCreated.push(indexDtsPath);
|
|
4805
4849
|
const pkgJson = this.generatePackageJson(
|
|
4806
4850
|
finalPackageName,
|
|
@@ -4813,13 +4857,13 @@ var PackingService = class {
|
|
|
4813
4857
|
license,
|
|
4814
4858
|
licenseOwner
|
|
4815
4859
|
);
|
|
4816
|
-
const pkgJsonPath =
|
|
4817
|
-
|
|
4860
|
+
const pkgJsonPath = path9.join(pkgOutputDir, "package.json");
|
|
4861
|
+
fs9.writeFileSync(pkgJsonPath, JSON.stringify(pkgJson, null, 2));
|
|
4818
4862
|
result.filesCreated.push(pkgJsonPath);
|
|
4819
4863
|
if (license) {
|
|
4820
4864
|
const licenseContent = this.generateLicenseFile(license, licenseOwner);
|
|
4821
|
-
const licensePath =
|
|
4822
|
-
|
|
4865
|
+
const licensePath = path9.join(pkgOutputDir, "LICENSE");
|
|
4866
|
+
fs9.writeFileSync(licensePath, licenseContent);
|
|
4823
4867
|
result.filesCreated.push(licensePath);
|
|
4824
4868
|
}
|
|
4825
4869
|
let readmeContent = readme;
|
|
@@ -4827,7 +4871,7 @@ var PackingService = class {
|
|
|
4827
4871
|
const agentItem = analysis.constituents.agents.find((a) => a.name === agentName);
|
|
4828
4872
|
let agentDescription;
|
|
4829
4873
|
if (agentItem?.filePath) {
|
|
4830
|
-
const agentSource =
|
|
4874
|
+
const agentSource = fs9.readFileSync(agentItem.filePath, "utf-8");
|
|
4831
4875
|
agentDescription = await extractAgentDescription(agentSource) || void 0;
|
|
4832
4876
|
}
|
|
4833
4877
|
readmeContent = this.generateReadme(
|
|
@@ -4838,21 +4882,21 @@ var PackingService = class {
|
|
|
4838
4882
|
agentDescription
|
|
4839
4883
|
);
|
|
4840
4884
|
}
|
|
4841
|
-
const readmePath =
|
|
4842
|
-
|
|
4885
|
+
const readmePath = path9.join(pkgOutputDir, "README.md");
|
|
4886
|
+
fs9.writeFileSync(readmePath, readmeContent);
|
|
4843
4887
|
result.filesCreated.push(readmePath);
|
|
4844
4888
|
if (removeOriginals || itemSelections) {
|
|
4845
4889
|
result.filesRemoved = [];
|
|
4846
4890
|
for (const item of allItems) {
|
|
4847
4891
|
const selection = itemSelections?.find((s) => s.name === item.name && s.type === item.type);
|
|
4848
4892
|
const shouldRemove = selection ? selection.mode === "extract" : removeOriginals && item.sharedWith.length === 0 && item.type !== "thread-endpoint" && item.type !== "effect";
|
|
4849
|
-
if (shouldRemove &&
|
|
4850
|
-
|
|
4893
|
+
if (shouldRemove && fs9.existsSync(item.filePath)) {
|
|
4894
|
+
fs9.unlinkSync(item.filePath);
|
|
4851
4895
|
result.filesRemoved.push(item.filePath);
|
|
4852
4896
|
}
|
|
4853
4897
|
}
|
|
4854
4898
|
}
|
|
4855
|
-
const agentsDir =
|
|
4899
|
+
const agentsDir = path9.join(rootDir, "agents");
|
|
4856
4900
|
const metadataService = new MetadataService(agentsDir);
|
|
4857
4901
|
const metadata = {
|
|
4858
4902
|
packageName: finalPackageName,
|
|
@@ -4886,7 +4930,7 @@ var PackingService = class {
|
|
|
4886
4930
|
const commonjs = (await import('@rollup/plugin-commonjs')).default;
|
|
4887
4931
|
const esbuild = (await import('rollup-plugin-esbuild')).default;
|
|
4888
4932
|
const externalDeps = /* @__PURE__ */ new Map();
|
|
4889
|
-
const agentsDir =
|
|
4933
|
+
const agentsDir = path9.join(rootDir, "agents");
|
|
4890
4934
|
const resolveVersion = this.resolvePackageVersion.bind(this);
|
|
4891
4935
|
const trackExternalsPlugin = {
|
|
4892
4936
|
name: "track-externals",
|
|
@@ -4895,14 +4939,14 @@ var PackingService = class {
|
|
|
4895
4939
|
return null;
|
|
4896
4940
|
}
|
|
4897
4941
|
if (source.startsWith("./") || source.startsWith("../")) {
|
|
4898
|
-
const resolved =
|
|
4942
|
+
const resolved = path9.resolve(path9.dirname(importer), source);
|
|
4899
4943
|
let tsResolved = resolved;
|
|
4900
4944
|
if (!resolved.endsWith(".ts") && !resolved.endsWith(".js")) {
|
|
4901
|
-
if (
|
|
4945
|
+
if (fs9.existsSync(`${resolved}.ts`)) {
|
|
4902
4946
|
tsResolved = `${resolved}.ts`;
|
|
4903
|
-
} else if (
|
|
4947
|
+
} else if (fs9.existsSync(`${resolved}.js`)) {
|
|
4904
4948
|
tsResolved = `${resolved}.js`;
|
|
4905
|
-
} else if (
|
|
4949
|
+
} else if (fs9.existsSync(`${resolved}/index.ts`)) {
|
|
4906
4950
|
tsResolved = `${resolved}/index.ts`;
|
|
4907
4951
|
}
|
|
4908
4952
|
}
|
|
@@ -4951,11 +4995,11 @@ var PackingService = class {
|
|
|
4951
4995
|
exports: "named"
|
|
4952
4996
|
});
|
|
4953
4997
|
const bundledCode = output[0].code;
|
|
4954
|
-
const header = `// Bundled from: ${
|
|
4998
|
+
const header = `// Bundled from: ${path9.relative(rootDir, inputPath)}
|
|
4955
4999
|
// Local dependencies have been inlined
|
|
4956
5000
|
|
|
4957
5001
|
`;
|
|
4958
|
-
|
|
5002
|
+
fs9.writeFileSync(outputPath, header + bundledCode);
|
|
4959
5003
|
await bundle.close();
|
|
4960
5004
|
} catch (error) {
|
|
4961
5005
|
await bundle.close();
|
|
@@ -5380,30 +5424,31 @@ Copyright (c) ${year} ${copyrightHolder}
|
|
|
5380
5424
|
* @returns Package info or null if not found
|
|
5381
5425
|
*/
|
|
5382
5426
|
getPackedInfo(packageId, rootDir) {
|
|
5383
|
-
const packedDir =
|
|
5384
|
-
|
|
5385
|
-
|
|
5386
|
-
|
|
5427
|
+
const packedDir = path9.join(rootDir, "agents", "packed");
|
|
5428
|
+
const safePackageId = assertSafePackageIdentifier(packageId);
|
|
5429
|
+
let packageDir = resolvePathWithin(packedDir, safePackageId);
|
|
5430
|
+
if (!fs9.existsSync(packageDir)) {
|
|
5431
|
+
if (!fs9.existsSync(packedDir)) {
|
|
5387
5432
|
return null;
|
|
5388
5433
|
}
|
|
5389
|
-
const dirs =
|
|
5434
|
+
const dirs = fs9.readdirSync(packedDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
|
|
5390
5435
|
const matchingDir = dirs.find(
|
|
5391
5436
|
(d) => d === packageId || d === `standardagent-${packageId}` || d === `standardagent-${packageId.replace(/_/g, "-")}`
|
|
5392
5437
|
);
|
|
5393
5438
|
if (!matchingDir) {
|
|
5394
5439
|
return null;
|
|
5395
5440
|
}
|
|
5396
|
-
packageDir =
|
|
5441
|
+
packageDir = path9.join(packedDir, matchingDir);
|
|
5397
5442
|
}
|
|
5398
|
-
const pkgJsonPath =
|
|
5399
|
-
if (!
|
|
5443
|
+
const pkgJsonPath = path9.join(packageDir, "package.json");
|
|
5444
|
+
if (!fs9.existsSync(pkgJsonPath)) {
|
|
5400
5445
|
return null;
|
|
5401
5446
|
}
|
|
5402
|
-
const pkgJson = JSON.parse(
|
|
5447
|
+
const pkgJson = JSON.parse(fs9.readFileSync(pkgJsonPath, "utf-8"));
|
|
5403
5448
|
let readme;
|
|
5404
|
-
const readmePath =
|
|
5405
|
-
if (
|
|
5406
|
-
readme =
|
|
5449
|
+
const readmePath = path9.join(packageDir, "README.md");
|
|
5450
|
+
if (fs9.existsSync(readmePath)) {
|
|
5451
|
+
readme = fs9.readFileSync(readmePath, "utf-8");
|
|
5407
5452
|
}
|
|
5408
5453
|
return {
|
|
5409
5454
|
packageName: pkgJson.name,
|
|
@@ -5421,11 +5466,11 @@ Copyright (c) ${year} ${copyrightHolder}
|
|
|
5421
5466
|
* @returns Array of package directory names
|
|
5422
5467
|
*/
|
|
5423
5468
|
listPackedPackages(rootDir) {
|
|
5424
|
-
const packedDir =
|
|
5425
|
-
if (!
|
|
5469
|
+
const packedDir = path9.join(rootDir, "agents", "packed");
|
|
5470
|
+
if (!fs9.existsSync(packedDir)) {
|
|
5426
5471
|
return [];
|
|
5427
5472
|
}
|
|
5428
|
-
return
|
|
5473
|
+
return fs9.readdirSync(packedDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
|
|
5429
5474
|
}
|
|
5430
5475
|
/**
|
|
5431
5476
|
* Generate README.md content for a packed agent.
|
|
@@ -5472,17 +5517,17 @@ ${license || "See LICENSE file"}
|
|
|
5472
5517
|
* Find a file by name in a directory.
|
|
5473
5518
|
*/
|
|
5474
5519
|
async findFile(dir, name) {
|
|
5475
|
-
if (!
|
|
5520
|
+
if (!fs9.existsSync(dir)) {
|
|
5476
5521
|
return null;
|
|
5477
5522
|
}
|
|
5478
|
-
const exactPath =
|
|
5479
|
-
if (
|
|
5523
|
+
const exactPath = resolvePathWithin(dir, `${name}.ts`);
|
|
5524
|
+
if (fs9.existsSync(exactPath)) {
|
|
5480
5525
|
return exactPath;
|
|
5481
5526
|
}
|
|
5482
|
-
const files =
|
|
5527
|
+
const files = fs9.readdirSync(dir).filter((f) => f.endsWith(".ts"));
|
|
5483
5528
|
for (const file of files) {
|
|
5484
|
-
const filePath =
|
|
5485
|
-
const source =
|
|
5529
|
+
const filePath = path9.join(dir, file);
|
|
5530
|
+
const source = fs9.readFileSync(filePath, "utf-8");
|
|
5486
5531
|
const extractedName = await extractDefinitionName(source);
|
|
5487
5532
|
if (extractedName === name) {
|
|
5488
5533
|
return filePath;
|
|
@@ -5494,15 +5539,15 @@ ${license || "See LICENSE file"}
|
|
|
5494
5539
|
* List all agents in the workspace.
|
|
5495
5540
|
*/
|
|
5496
5541
|
async listAgents(rootDir) {
|
|
5497
|
-
const agentsDir =
|
|
5498
|
-
if (!
|
|
5542
|
+
const agentsDir = path9.join(rootDir, "agents", "agents");
|
|
5543
|
+
if (!fs9.existsSync(agentsDir)) {
|
|
5499
5544
|
return [];
|
|
5500
5545
|
}
|
|
5501
|
-
const files =
|
|
5546
|
+
const files = fs9.readdirSync(agentsDir).filter((f) => f.endsWith(".ts"));
|
|
5502
5547
|
const agents = [];
|
|
5503
5548
|
for (const file of files) {
|
|
5504
|
-
const filePath =
|
|
5505
|
-
const source =
|
|
5549
|
+
const filePath = path9.join(agentsDir, file);
|
|
5550
|
+
const source = fs9.readFileSync(filePath, "utf-8");
|
|
5506
5551
|
const name = await extractDefinitionName(source);
|
|
5507
5552
|
if (name) {
|
|
5508
5553
|
agents.push(name);
|
|
@@ -5518,7 +5563,7 @@ var PackageDiscoveryService = class {
|
|
|
5518
5563
|
constructor(config) {
|
|
5519
5564
|
this.config = {
|
|
5520
5565
|
rootDir: config.rootDir,
|
|
5521
|
-
packedDir: config.packedDir ??
|
|
5566
|
+
packedDir: config.packedDir ?? path9.join(config.rootDir, "agents", "packed"),
|
|
5522
5567
|
scanNpm: config.scanNpm ?? true,
|
|
5523
5568
|
scanLocal: config.scanLocal ?? true
|
|
5524
5569
|
};
|
|
@@ -5551,19 +5596,19 @@ var PackageDiscoveryService = class {
|
|
|
5551
5596
|
*/
|
|
5552
5597
|
async discoverNpmPackages() {
|
|
5553
5598
|
const packages = [];
|
|
5554
|
-
const nodeModulesDir =
|
|
5555
|
-
if (!
|
|
5599
|
+
const nodeModulesDir = path9.join(this.config.rootDir, "node_modules");
|
|
5600
|
+
if (!fs9.existsSync(nodeModulesDir)) {
|
|
5556
5601
|
return packages;
|
|
5557
5602
|
}
|
|
5558
5603
|
const rootEntries = await this.scanDirectory(nodeModulesDir);
|
|
5559
5604
|
for (const entry of rootEntries) {
|
|
5560
5605
|
if (entry.startsWith(".")) continue;
|
|
5561
5606
|
if (entry.startsWith("@")) {
|
|
5562
|
-
const scopeDir =
|
|
5607
|
+
const scopeDir = path9.join(nodeModulesDir, entry);
|
|
5563
5608
|
const scopeEntries = await this.scanDirectory(scopeDir);
|
|
5564
5609
|
for (const scopedPkg of scopeEntries) {
|
|
5565
5610
|
if (scopedPkg.startsWith(".")) continue;
|
|
5566
|
-
const pkgDir =
|
|
5611
|
+
const pkgDir = path9.join(scopeDir, scopedPkg);
|
|
5567
5612
|
const fullName = `${entry}/${scopedPkg}`;
|
|
5568
5613
|
const pkg = await this.checkNpmPackage(pkgDir, fullName);
|
|
5569
5614
|
if (pkg) {
|
|
@@ -5571,7 +5616,7 @@ var PackageDiscoveryService = class {
|
|
|
5571
5616
|
}
|
|
5572
5617
|
}
|
|
5573
5618
|
} else {
|
|
5574
|
-
const pkgDir =
|
|
5619
|
+
const pkgDir = path9.join(nodeModulesDir, entry);
|
|
5575
5620
|
const pkg = await this.checkNpmPackage(pkgDir, entry);
|
|
5576
5621
|
if (pkg) {
|
|
5577
5622
|
packages.push(pkg);
|
|
@@ -5587,12 +5632,12 @@ var PackageDiscoveryService = class {
|
|
|
5587
5632
|
* which must contain `entryAgents` array.
|
|
5588
5633
|
*/
|
|
5589
5634
|
async checkNpmPackage(pkgDir, pkgName) {
|
|
5590
|
-
const pkgJsonPath =
|
|
5591
|
-
if (!
|
|
5635
|
+
const pkgJsonPath = path9.join(pkgDir, "package.json");
|
|
5636
|
+
if (!fs9.existsSync(pkgJsonPath)) {
|
|
5592
5637
|
return null;
|
|
5593
5638
|
}
|
|
5594
5639
|
try {
|
|
5595
|
-
const pkgJson = JSON.parse(
|
|
5640
|
+
const pkgJson = JSON.parse(fs9.readFileSync(pkgJsonPath, "utf-8"));
|
|
5596
5641
|
const isStandardAgent = (
|
|
5597
5642
|
// Has "standardagent" keyword
|
|
5598
5643
|
pkgJson.keywords?.includes("standardagent") || // Has "standardagent-*" prefix
|
|
@@ -5629,21 +5674,21 @@ var PackageDiscoveryService = class {
|
|
|
5629
5674
|
*/
|
|
5630
5675
|
async discoverLocalPackages() {
|
|
5631
5676
|
const packages = [];
|
|
5632
|
-
if (!
|
|
5677
|
+
if (!fs9.existsSync(this.config.packedDir)) {
|
|
5633
5678
|
return packages;
|
|
5634
5679
|
}
|
|
5635
5680
|
const entries = await this.scanDirectory(this.config.packedDir);
|
|
5636
5681
|
for (const entry of entries) {
|
|
5637
5682
|
if (entry.startsWith(".")) continue;
|
|
5638
|
-
const pkgDir =
|
|
5639
|
-
const stat =
|
|
5683
|
+
const pkgDir = path9.join(this.config.packedDir, entry);
|
|
5684
|
+
const stat = fs9.statSync(pkgDir);
|
|
5640
5685
|
if (!stat.isDirectory()) continue;
|
|
5641
5686
|
if (entry.startsWith("@")) {
|
|
5642
5687
|
const scopeEntries = await this.scanDirectory(pkgDir);
|
|
5643
5688
|
for (const scopedPkg of scopeEntries) {
|
|
5644
5689
|
if (scopedPkg.startsWith(".")) continue;
|
|
5645
|
-
const scopedPkgDir =
|
|
5646
|
-
const scopedStat =
|
|
5690
|
+
const scopedPkgDir = path9.join(pkgDir, scopedPkg);
|
|
5691
|
+
const scopedStat = fs9.statSync(scopedPkgDir);
|
|
5647
5692
|
if (!scopedStat.isDirectory()) continue;
|
|
5648
5693
|
const fullName = `${entry}/${scopedPkg}`;
|
|
5649
5694
|
const pkg = await this.checkLocalPackage(scopedPkgDir, fullName);
|
|
@@ -5666,12 +5711,12 @@ var PackageDiscoveryService = class {
|
|
|
5666
5711
|
* Detection is based on the `standardagent` field in package.json.
|
|
5667
5712
|
*/
|
|
5668
5713
|
async checkLocalPackage(pkgDir, dirName) {
|
|
5669
|
-
const pkgJsonPath =
|
|
5670
|
-
if (!
|
|
5714
|
+
const pkgJsonPath = path9.join(pkgDir, "package.json");
|
|
5715
|
+
if (!fs9.existsSync(pkgJsonPath)) {
|
|
5671
5716
|
return null;
|
|
5672
5717
|
}
|
|
5673
5718
|
try {
|
|
5674
|
-
const pkgJson = JSON.parse(
|
|
5719
|
+
const pkgJson = JSON.parse(fs9.readFileSync(pkgJsonPath, "utf-8"));
|
|
5675
5720
|
if (!pkgJson.standardagent?.entryAgents) {
|
|
5676
5721
|
return null;
|
|
5677
5722
|
}
|
|
@@ -5696,10 +5741,10 @@ var PackageDiscoveryService = class {
|
|
|
5696
5741
|
* Scan a directory and return entry names.
|
|
5697
5742
|
*/
|
|
5698
5743
|
async scanDirectory(dir) {
|
|
5699
|
-
if (!
|
|
5744
|
+
if (!fs9.existsSync(dir)) {
|
|
5700
5745
|
return [];
|
|
5701
5746
|
}
|
|
5702
|
-
const entries =
|
|
5747
|
+
const entries = fs9.readdirSync(dir);
|
|
5703
5748
|
return entries;
|
|
5704
5749
|
}
|
|
5705
5750
|
/**
|
|
@@ -5792,29 +5837,29 @@ var UnpackingService = class {
|
|
|
5792
5837
|
}
|
|
5793
5838
|
analysis.version = pkg.version;
|
|
5794
5839
|
analysis.source = pkg.source;
|
|
5795
|
-
const indexPath =
|
|
5796
|
-
if (!
|
|
5840
|
+
const indexPath = path9.join(pkg.path, "dist", "index.js");
|
|
5841
|
+
if (!fs9.existsSync(indexPath)) {
|
|
5797
5842
|
analysis.errors.push(`Package index not found: ${indexPath}`);
|
|
5798
5843
|
return analysis;
|
|
5799
5844
|
}
|
|
5800
|
-
const indexContent =
|
|
5845
|
+
const indexContent = fs9.readFileSync(indexPath, "utf-8");
|
|
5801
5846
|
const registryItems = await this.parseIndexExports(indexContent);
|
|
5802
5847
|
const availableItems = /* @__PURE__ */ new Map();
|
|
5803
5848
|
for (const item of registryItems) {
|
|
5804
5849
|
availableItems.set(`${item.type}:${item.name}`, item);
|
|
5805
5850
|
}
|
|
5806
|
-
const agentsDir =
|
|
5851
|
+
const agentsDir = path9.join(rootDir, "agents");
|
|
5807
5852
|
const itemsWithRelations = [];
|
|
5808
5853
|
for (const item of registryItems) {
|
|
5809
|
-
const targetPath =
|
|
5810
|
-
const sourcePath =
|
|
5854
|
+
const targetPath = resolvePathWithin(agentsDir, TYPE_TO_TARGET_DIR[item.type], `${item.name}.ts`);
|
|
5855
|
+
const sourcePath = resolvePathWithin(pkg.path, "dist", TYPE_TO_DIR[item.type], `${item.name}.js`);
|
|
5811
5856
|
const existsGlobally = this.fileExists(targetPath);
|
|
5812
|
-
const sourceExists =
|
|
5857
|
+
const sourceExists = fs9.existsSync(sourcePath);
|
|
5813
5858
|
if (!sourceExists) {
|
|
5814
5859
|
analysis.warnings.push(`Source file not found for ${item.type} "${item.name}": ${sourcePath}`);
|
|
5815
5860
|
continue;
|
|
5816
5861
|
}
|
|
5817
|
-
const bundledCode =
|
|
5862
|
+
const bundledCode = fs9.readFileSync(sourcePath, "utf-8");
|
|
5818
5863
|
const children = await this.discoverRelationships(item.type, item.name, bundledCode, availableItems);
|
|
5819
5864
|
itemsWithRelations.push({
|
|
5820
5865
|
name: item.name,
|
|
@@ -5824,10 +5869,10 @@ var UnpackingService = class {
|
|
|
5824
5869
|
action: existsGlobally ? "skip" : "generate"
|
|
5825
5870
|
});
|
|
5826
5871
|
for (const child of children) {
|
|
5827
|
-
const childTargetPath =
|
|
5828
|
-
const childSourcePath =
|
|
5872
|
+
const childTargetPath = resolvePathWithin(agentsDir, TYPE_TO_TARGET_DIR[child.type], `${child.name}.ts`);
|
|
5873
|
+
const childSourcePath = resolvePathWithin(pkg.path, "dist", TYPE_TO_DIR[child.type], `${child.name}.js`);
|
|
5829
5874
|
const childExists = this.fileExists(childTargetPath);
|
|
5830
|
-
const childSourceExists =
|
|
5875
|
+
const childSourceExists = fs9.existsSync(childSourcePath);
|
|
5831
5876
|
if (!childSourceExists) {
|
|
5832
5877
|
continue;
|
|
5833
5878
|
}
|
|
@@ -5930,8 +5975,8 @@ var UnpackingService = class {
|
|
|
5930
5975
|
return result;
|
|
5931
5976
|
}
|
|
5932
5977
|
const itemsToProcess = this.applySelections(analysis.items, itemSelections);
|
|
5933
|
-
const pkgJsonPath =
|
|
5934
|
-
const pkgJson = JSON.parse(
|
|
5978
|
+
const pkgJsonPath = path9.join(pkg.path, "package.json");
|
|
5979
|
+
const pkgJson = JSON.parse(fs9.readFileSync(pkgJsonPath, "utf-8"));
|
|
5935
5980
|
let author = "";
|
|
5936
5981
|
if (typeof pkgJson.author === "string") {
|
|
5937
5982
|
author = pkgJson.author;
|
|
@@ -5956,18 +6001,19 @@ var UnpackingService = class {
|
|
|
5956
6001
|
continue;
|
|
5957
6002
|
}
|
|
5958
6003
|
try {
|
|
5959
|
-
const sourcePath =
|
|
5960
|
-
const
|
|
6004
|
+
const sourcePath = resolvePathWithin(pkg.path, "dist", TYPE_TO_DIR[item.type], `${item.name}.js`);
|
|
6005
|
+
const targetPath = resolvePathWithin(path9.join(rootDir, "agents"), path9.relative(path9.join(rootDir, "agents"), item.targetPath));
|
|
6006
|
+
const bundledCode = fs9.readFileSync(sourcePath, "utf-8");
|
|
5961
6007
|
let tsCode = await transformBundledJs(bundledCode);
|
|
5962
6008
|
if (item.type === "agent") {
|
|
5963
6009
|
tsCode = await injectAgentMetadata(tsCode, agentMetadata);
|
|
5964
6010
|
}
|
|
5965
|
-
const dir =
|
|
5966
|
-
if (!
|
|
5967
|
-
|
|
6011
|
+
const dir = path9.dirname(targetPath);
|
|
6012
|
+
if (!fs9.existsSync(dir)) {
|
|
6013
|
+
fs9.mkdirSync(dir, { recursive: true });
|
|
5968
6014
|
}
|
|
5969
|
-
|
|
5970
|
-
result.filesGenerated.push(
|
|
6015
|
+
fs9.writeFileSync(targetPath, tsCode);
|
|
6016
|
+
result.filesGenerated.push(targetPath);
|
|
5971
6017
|
} catch (error) {
|
|
5972
6018
|
result.warnings.push(
|
|
5973
6019
|
`Failed to generate ${item.type} "${item.name}": ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -5976,7 +6022,12 @@ var UnpackingService = class {
|
|
|
5976
6022
|
}
|
|
5977
6023
|
if (deletePackage && pkg.source === "local") {
|
|
5978
6024
|
try {
|
|
5979
|
-
|
|
6025
|
+
const localPackedRoot = path9.join(rootDir, "agents", "packed");
|
|
6026
|
+
const safePackagePath = resolvePathWithin(
|
|
6027
|
+
localPackedRoot,
|
|
6028
|
+
path9.relative(localPackedRoot, pkg.path)
|
|
6029
|
+
);
|
|
6030
|
+
this.deleteDirectory(safePackagePath);
|
|
5980
6031
|
result.packageDeleted = true;
|
|
5981
6032
|
} catch (error) {
|
|
5982
6033
|
result.warnings.push(
|
|
@@ -6055,14 +6106,14 @@ var UnpackingService = class {
|
|
|
6055
6106
|
*/
|
|
6056
6107
|
async resolvePackage(pkgIdentifier, rootDir) {
|
|
6057
6108
|
if (pkgIdentifier.startsWith("/") || pkgIdentifier.startsWith("./")) {
|
|
6058
|
-
const absolutePath =
|
|
6059
|
-
const pkgJsonPath2 =
|
|
6060
|
-
if (
|
|
6109
|
+
const absolutePath = path9.isAbsolute(pkgIdentifier) ? pkgIdentifier : path9.join(rootDir, pkgIdentifier);
|
|
6110
|
+
const pkgJsonPath2 = path9.join(absolutePath, "package.json");
|
|
6111
|
+
if (fs9.existsSync(pkgJsonPath2)) {
|
|
6061
6112
|
try {
|
|
6062
|
-
const pkgJson = JSON.parse(
|
|
6113
|
+
const pkgJson = JSON.parse(fs9.readFileSync(pkgJsonPath2, "utf-8"));
|
|
6063
6114
|
if (pkgJson.standardagent?.entryAgents) {
|
|
6064
6115
|
return {
|
|
6065
|
-
packageId: pkgJson.name ||
|
|
6116
|
+
packageId: pkgJson.name || path9.basename(absolutePath),
|
|
6066
6117
|
version: pkgJson.version || "0.0.0",
|
|
6067
6118
|
source: "local",
|
|
6068
6119
|
path: absolutePath,
|
|
@@ -6074,11 +6125,12 @@ var UnpackingService = class {
|
|
|
6074
6125
|
}
|
|
6075
6126
|
return null;
|
|
6076
6127
|
}
|
|
6077
|
-
const
|
|
6078
|
-
const
|
|
6079
|
-
|
|
6128
|
+
const safeIdentifier = assertSafePackageIdentifier(pkgIdentifier);
|
|
6129
|
+
const packedDir = resolvePathWithin(path9.join(rootDir, "agents", "packed"), safeIdentifier);
|
|
6130
|
+
const pkgJsonPath = path9.join(packedDir, "package.json");
|
|
6131
|
+
if (fs9.existsSync(pkgJsonPath)) {
|
|
6080
6132
|
try {
|
|
6081
|
-
const pkgJson = JSON.parse(
|
|
6133
|
+
const pkgJson = JSON.parse(fs9.readFileSync(pkgJsonPath, "utf-8"));
|
|
6082
6134
|
if (pkgJson.standardagent?.entryAgents) {
|
|
6083
6135
|
return {
|
|
6084
6136
|
packageId: pkgJson.name || pkgIdentifier,
|
|
@@ -6119,18 +6171,18 @@ var UnpackingService = class {
|
|
|
6119
6171
|
* Check if a file exists.
|
|
6120
6172
|
*/
|
|
6121
6173
|
fileExists(filePath) {
|
|
6122
|
-
if (
|
|
6174
|
+
if (fs9.existsSync(filePath)) {
|
|
6123
6175
|
return true;
|
|
6124
6176
|
}
|
|
6125
6177
|
const withoutExt = filePath.replace(/\.(ts|js)$/, "");
|
|
6126
|
-
return
|
|
6178
|
+
return fs9.existsSync(`${withoutExt}.ts`) || fs9.existsSync(`${withoutExt}.js`);
|
|
6127
6179
|
}
|
|
6128
6180
|
/**
|
|
6129
6181
|
* Recursively delete a directory.
|
|
6130
6182
|
*/
|
|
6131
6183
|
deleteDirectory(dirPath) {
|
|
6132
|
-
if (
|
|
6133
|
-
|
|
6184
|
+
if (fs9.existsSync(dirPath)) {
|
|
6185
|
+
fs9.rmSync(dirPath, { recursive: true, force: true });
|
|
6134
6186
|
}
|
|
6135
6187
|
}
|
|
6136
6188
|
/**
|
|
@@ -6206,8 +6258,8 @@ var NpmPublishService = class {
|
|
|
6206
6258
|
error: "Registry URL must use HTTPS"
|
|
6207
6259
|
};
|
|
6208
6260
|
}
|
|
6209
|
-
const pkgJsonPath =
|
|
6210
|
-
if (!
|
|
6261
|
+
const pkgJsonPath = path9.join(packageDir, "package.json");
|
|
6262
|
+
if (!fs9.existsSync(pkgJsonPath)) {
|
|
6211
6263
|
return {
|
|
6212
6264
|
success: false,
|
|
6213
6265
|
output: "",
|
|
@@ -6217,7 +6269,7 @@ var NpmPublishService = class {
|
|
|
6217
6269
|
let packageName;
|
|
6218
6270
|
let version;
|
|
6219
6271
|
try {
|
|
6220
|
-
const pkgJson = JSON.parse(
|
|
6272
|
+
const pkgJson = JSON.parse(fs9.readFileSync(pkgJsonPath, "utf-8"));
|
|
6221
6273
|
packageName = pkgJson.name;
|
|
6222
6274
|
version = pkgJson.version;
|
|
6223
6275
|
} catch (e) {
|
|
@@ -6227,13 +6279,13 @@ var NpmPublishService = class {
|
|
|
6227
6279
|
error: `Failed to read package.json: ${e instanceof Error ? e.message : String(e)}`
|
|
6228
6280
|
};
|
|
6229
6281
|
}
|
|
6230
|
-
const npmrcPath =
|
|
6282
|
+
const npmrcPath = path9.join(packageDir, ".npmrc");
|
|
6231
6283
|
const registryHost = new URL(registry).host;
|
|
6232
6284
|
const npmrcContent = `//${registryHost}/:_authToken=${token}
|
|
6233
6285
|
registry=${registry}
|
|
6234
6286
|
`;
|
|
6235
6287
|
try {
|
|
6236
|
-
|
|
6288
|
+
fs9.writeFileSync(npmrcPath, npmrcContent, { mode: 384 });
|
|
6237
6289
|
const args = ["publish"];
|
|
6238
6290
|
if (dryRun) {
|
|
6239
6291
|
args.push("--dry-run");
|
|
@@ -6265,8 +6317,8 @@ registry=${registry}
|
|
|
6265
6317
|
};
|
|
6266
6318
|
} finally {
|
|
6267
6319
|
try {
|
|
6268
|
-
if (
|
|
6269
|
-
|
|
6320
|
+
if (fs9.existsSync(npmrcPath)) {
|
|
6321
|
+
fs9.unlinkSync(npmrcPath);
|
|
6270
6322
|
}
|
|
6271
6323
|
} catch {
|
|
6272
6324
|
}
|
|
@@ -6359,7 +6411,7 @@ async function handlePackingApiRequest(context) {
|
|
|
6359
6411
|
const body = await parseRequestBody(req);
|
|
6360
6412
|
const packingService = new PackingService();
|
|
6361
6413
|
const rootDir = process.cwd();
|
|
6362
|
-
const outputDir =
|
|
6414
|
+
const outputDir = path9__default.join(rootDir, "agents", "packed");
|
|
6363
6415
|
const result = await packingService.pack({
|
|
6364
6416
|
agentName,
|
|
6365
6417
|
rootDir,
|
|
@@ -6412,8 +6464,8 @@ async function handlePackingApiRequest(context) {
|
|
|
6412
6464
|
res.end(JSON.stringify({ error: "Cannot delete npm packages. Use npm uninstall instead." }));
|
|
6413
6465
|
return true;
|
|
6414
6466
|
}
|
|
6415
|
-
const
|
|
6416
|
-
|
|
6467
|
+
const fs19 = await import('fs');
|
|
6468
|
+
fs19.rmSync(pkg.path, { recursive: true, force: true });
|
|
6417
6469
|
await reloadAllAgentModules(context);
|
|
6418
6470
|
res.statusCode = 200;
|
|
6419
6471
|
res.setHeader("Content-Type", "application/json");
|
|
@@ -6441,8 +6493,8 @@ async function handlePackingApiRequest(context) {
|
|
|
6441
6493
|
return true;
|
|
6442
6494
|
}
|
|
6443
6495
|
const { spawn } = await import('child_process');
|
|
6444
|
-
const parentDir =
|
|
6445
|
-
const dirName =
|
|
6496
|
+
const parentDir = path9__default.dirname(pkg.path);
|
|
6497
|
+
const dirName = path9__default.basename(pkg.path);
|
|
6446
6498
|
res.setHeader("Content-Type", "application/gzip");
|
|
6447
6499
|
res.setHeader("Content-Disposition", `attachment; filename="${packageId}.tar.gz"`);
|
|
6448
6500
|
const tar = spawn("tar", ["-czf", "-", "-C", parentDir, dirName]);
|
|
@@ -6496,18 +6548,19 @@ async function handlePackingApiRequest(context) {
|
|
|
6496
6548
|
if (packPublishMatch && method === "POST") {
|
|
6497
6549
|
try {
|
|
6498
6550
|
const packageId = decodeURIComponent(packPublishMatch[1]);
|
|
6551
|
+
assertSafePackageIdentifier(packageId);
|
|
6499
6552
|
const body = await parseRequestBody(req);
|
|
6500
6553
|
const rootDir = process.cwd();
|
|
6501
|
-
const packedDir =
|
|
6502
|
-
let packageDir =
|
|
6503
|
-
if (!
|
|
6504
|
-
if (!
|
|
6554
|
+
const packedDir = path9__default.join(rootDir, "agents", "packed");
|
|
6555
|
+
let packageDir = resolvePathWithin(packedDir, packageId);
|
|
6556
|
+
if (!fs9__default.existsSync(packageDir)) {
|
|
6557
|
+
if (!fs9__default.existsSync(packedDir)) {
|
|
6505
6558
|
res.statusCode = 400;
|
|
6506
6559
|
res.setHeader("Content-Type", "application/json");
|
|
6507
6560
|
res.end(JSON.stringify({ error: "No packed packages found. Pack the agent first." }));
|
|
6508
6561
|
return true;
|
|
6509
6562
|
}
|
|
6510
|
-
const dirs =
|
|
6563
|
+
const dirs = fs9__default.readdirSync(packedDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
|
|
6511
6564
|
const matchingDir = dirs.find(
|
|
6512
6565
|
(d) => d === packageId || d === `standardagent-${packageId}` || d === `standardagent-${packageId.replace(/_/g, "-")}`
|
|
6513
6566
|
);
|
|
@@ -6519,14 +6572,14 @@ async function handlePackingApiRequest(context) {
|
|
|
6519
6572
|
}));
|
|
6520
6573
|
return true;
|
|
6521
6574
|
}
|
|
6522
|
-
packageDir =
|
|
6575
|
+
packageDir = resolvePathWithin(packedDir, matchingDir);
|
|
6523
6576
|
}
|
|
6524
6577
|
let token = body.token || process.env.NPM_TOKEN;
|
|
6525
6578
|
let tokenSource = body.token ? "provided" : "environment";
|
|
6526
6579
|
if (!token) {
|
|
6527
|
-
const devVarsPath =
|
|
6528
|
-
if (
|
|
6529
|
-
const devVars =
|
|
6580
|
+
const devVarsPath = path9__default.join(rootDir, ".dev.vars");
|
|
6581
|
+
if (fs9__default.existsSync(devVarsPath)) {
|
|
6582
|
+
const devVars = fs9__default.readFileSync(devVarsPath, "utf-8");
|
|
6530
6583
|
const match = devVars.match(/^NPM_TOKEN=(.+)$/m);
|
|
6531
6584
|
if (match) {
|
|
6532
6585
|
token = match[1].trim();
|
|
@@ -6637,27 +6690,67 @@ async function handlePackingApiRequest(context) {
|
|
|
6637
6690
|
return false;
|
|
6638
6691
|
}
|
|
6639
6692
|
|
|
6693
|
+
// src/routing/access-policy.ts
|
|
6694
|
+
function isProviderIconRoute(routePath) {
|
|
6695
|
+
return /^\/api\/providers\/[^/]+\/icon$/.test(routePath);
|
|
6696
|
+
}
|
|
6697
|
+
function isHostedInstance(env) {
|
|
6698
|
+
const value = env?.STANDARD_AGENTS_HOSTED;
|
|
6699
|
+
if (typeof value === "string") {
|
|
6700
|
+
const normalized = value.trim().toLowerCase();
|
|
6701
|
+
return normalized !== "" && normalized !== "0" && normalized !== "false";
|
|
6702
|
+
}
|
|
6703
|
+
return Boolean(value);
|
|
6704
|
+
}
|
|
6705
|
+
function isTrustedLocalDevelopmentRequest(request, env) {
|
|
6706
|
+
if (isHostedInstance(env)) return false;
|
|
6707
|
+
let hostname;
|
|
6708
|
+
try {
|
|
6709
|
+
hostname = new URL(request.url).hostname.toLowerCase();
|
|
6710
|
+
} catch {
|
|
6711
|
+
return false;
|
|
6712
|
+
}
|
|
6713
|
+
return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1" || hostname.endsWith(".localhost") || hostname.endsWith(".orb.local");
|
|
6714
|
+
}
|
|
6715
|
+
function isAdminOnlyApiRoute(routePath, method = "GET") {
|
|
6716
|
+
if (routePath === "/api/skills" || routePath.startsWith("/api/skills/")) return true;
|
|
6717
|
+
if (routePath === "/api/pack" || routePath.startsWith("/api/pack/")) return true;
|
|
6718
|
+
if (routePath === "/api/unpack" || routePath.startsWith("/api/unpack/")) return true;
|
|
6719
|
+
if (routePath === "/api/prompts" || routePath.startsWith("/api/prompts/")) return true;
|
|
6720
|
+
if (routePath === "/api/tools" || routePath.startsWith("/api/tools/")) return true;
|
|
6721
|
+
if (routePath === "/api/models" || routePath.startsWith("/api/models/")) return true;
|
|
6722
|
+
if (routePath === "/api/providers") return true;
|
|
6723
|
+
if (routePath.startsWith("/api/providers/")) {
|
|
6724
|
+
return !isProviderIconRoute(routePath);
|
|
6725
|
+
}
|
|
6726
|
+
if (routePath.startsWith("/api/agents/")) {
|
|
6727
|
+
return !/^\/api\/agents\/[^/]+\/tenvs$/.test(routePath);
|
|
6728
|
+
}
|
|
6729
|
+
if (routePath === "/api/agents" && method.toUpperCase() !== "GET") return true;
|
|
6730
|
+
return false;
|
|
6731
|
+
}
|
|
6732
|
+
|
|
6640
6733
|
// src/plugin/dev-middleware.ts
|
|
6641
6734
|
function readRawRequestBody(req) {
|
|
6642
|
-
return new Promise((
|
|
6735
|
+
return new Promise((resolve3, reject) => {
|
|
6643
6736
|
const chunks = [];
|
|
6644
6737
|
req.on("data", (chunk) => {
|
|
6645
6738
|
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
6646
6739
|
});
|
|
6647
6740
|
req.on("end", () => {
|
|
6648
|
-
|
|
6741
|
+
resolve3(chunks.length > 0 ? Buffer.concat(chunks) : void 0);
|
|
6649
6742
|
});
|
|
6650
6743
|
req.on("error", reject);
|
|
6651
6744
|
});
|
|
6652
6745
|
}
|
|
6653
6746
|
function resolveContainedFile(baseDir, requestPath) {
|
|
6654
|
-
const resolvedBase =
|
|
6655
|
-
const resolved =
|
|
6656
|
-
if (resolved !== resolvedBase && !resolved.startsWith(resolvedBase +
|
|
6747
|
+
const resolvedBase = path9__default.resolve(baseDir);
|
|
6748
|
+
const resolved = path9__default.resolve(resolvedBase, `.${path9__default.sep}${requestPath.replace(/^\/+/, "")}`);
|
|
6749
|
+
if (resolved !== resolvedBase && !resolved.startsWith(resolvedBase + path9__default.sep)) {
|
|
6657
6750
|
return null;
|
|
6658
6751
|
}
|
|
6659
6752
|
try {
|
|
6660
|
-
return
|
|
6753
|
+
return fs9__default.existsSync(resolved) && fs9__default.statSync(resolved).isFile() ? resolved : null;
|
|
6661
6754
|
} catch {
|
|
6662
6755
|
return null;
|
|
6663
6756
|
}
|
|
@@ -6707,6 +6800,21 @@ function createDevMiddleware(server, context) {
|
|
|
6707
6800
|
return;
|
|
6708
6801
|
}
|
|
6709
6802
|
}
|
|
6803
|
+
const routePath = new URL(pathWithoutMount, "http://localhost").pathname;
|
|
6804
|
+
let trustedLocalHost = false;
|
|
6805
|
+
try {
|
|
6806
|
+
trustedLocalHost = isTrustedLocalDevelopmentRequest(
|
|
6807
|
+
new Request(`http://${req.headers.host || "invalid.remote"}${routePath}`),
|
|
6808
|
+
{}
|
|
6809
|
+
);
|
|
6810
|
+
} catch {
|
|
6811
|
+
}
|
|
6812
|
+
if (isAdminOnlyApiRoute(routePath, method) && !trustedLocalHost) {
|
|
6813
|
+
res.statusCode = 403;
|
|
6814
|
+
res.setHeader("Content-Type", "application/json");
|
|
6815
|
+
res.end(JSON.stringify({ error: "Authoring APIs are available only from local development hosts" }));
|
|
6816
|
+
return;
|
|
6817
|
+
}
|
|
6710
6818
|
if (await handleConfigApiRequest({
|
|
6711
6819
|
req,
|
|
6712
6820
|
res,
|
|
@@ -6796,19 +6904,19 @@ function createDevMiddleware(server, context) {
|
|
|
6796
6904
|
const clientPath = pathWithoutMount.startsWith("/agents/") ? pathWithoutMount.slice("/agents".length) || "/" : pathWithoutMount;
|
|
6797
6905
|
const isStaticAsset = clientPath.startsWith("/assets/") || clientPath.startsWith("/vendor.js") || clientPath.startsWith("/vue.js") || clientPath.startsWith("/monaco.js") || clientPath.startsWith("/index.js") || clientPath.startsWith("/index.css") || clientPath.match(/\.(js|css|png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot|ico)$/);
|
|
6798
6906
|
{
|
|
6799
|
-
const currentDir =
|
|
6907
|
+
const currentDir = path9__default.dirname(fileURLToPath(import.meta.url));
|
|
6800
6908
|
const isInDist = currentDir.endsWith("dist");
|
|
6801
|
-
const clientDir =
|
|
6909
|
+
const clientDir = path9__default.resolve(
|
|
6802
6910
|
currentDir,
|
|
6803
6911
|
isInDist ? "./client" : "../dist/client"
|
|
6804
6912
|
);
|
|
6805
6913
|
let filePath;
|
|
6806
6914
|
if (isStaticAsset) {
|
|
6807
6915
|
const cleanUrl = clientPath.split("?")[0];
|
|
6808
|
-
filePath =
|
|
6809
|
-
if (!
|
|
6916
|
+
filePath = path9__default.join(clientDir, cleanUrl);
|
|
6917
|
+
if (!fs9__default.existsSync(filePath)) {
|
|
6810
6918
|
const projectPublicFile = resolveContainedFile(
|
|
6811
|
-
|
|
6919
|
+
path9__default.resolve(server.config.root, "public"),
|
|
6812
6920
|
cleanUrl
|
|
6813
6921
|
);
|
|
6814
6922
|
if (projectPublicFile) {
|
|
@@ -6816,12 +6924,12 @@ function createDevMiddleware(server, context) {
|
|
|
6816
6924
|
}
|
|
6817
6925
|
}
|
|
6818
6926
|
} else {
|
|
6819
|
-
filePath =
|
|
6927
|
+
filePath = path9__default.join(clientDir, "index.html");
|
|
6820
6928
|
}
|
|
6821
6929
|
try {
|
|
6822
|
-
if (
|
|
6823
|
-
let content =
|
|
6824
|
-
const ext =
|
|
6930
|
+
if (fs9__default.existsSync(filePath)) {
|
|
6931
|
+
let content = fs9__default.readFileSync(filePath);
|
|
6932
|
+
const ext = path9__default.extname(filePath).toLowerCase();
|
|
6825
6933
|
if (ext === ".html") {
|
|
6826
6934
|
content = Buffer.from(
|
|
6827
6935
|
injectUiConfigIntoHtml(content.toString())
|
|
@@ -6861,7 +6969,7 @@ async function loadBuilderVirtualModule(context) {
|
|
|
6861
6969
|
const effects = await scanEffectsDirectory(effectsDir);
|
|
6862
6970
|
const toAbsolutePath = (relativePath) => {
|
|
6863
6971
|
if (relativePath.startsWith("./")) {
|
|
6864
|
-
return
|
|
6972
|
+
return path9__default.resolve(process.cwd(), relativePath).replace(/\\/g, "/");
|
|
6865
6973
|
}
|
|
6866
6974
|
return relativePath;
|
|
6867
6975
|
};
|
|
@@ -7133,7 +7241,7 @@ async function loadRegistryVirtualModule(context) {
|
|
|
7133
7241
|
const effects = await scanEffectsDirectory(effectsDir);
|
|
7134
7242
|
const toAbsolutePath = (relativePath) => {
|
|
7135
7243
|
if (relativePath.startsWith("./")) {
|
|
7136
|
-
return
|
|
7244
|
+
return path9__default.resolve(process.cwd(), relativePath).replace(/\\/g, "/");
|
|
7137
7245
|
}
|
|
7138
7246
|
return relativePath;
|
|
7139
7247
|
};
|
|
@@ -7161,23 +7269,23 @@ async function loadRegistryVirtualModule(context) {
|
|
|
7161
7269
|
const absPath = toAbsolutePath(importPath);
|
|
7162
7270
|
return ` "${name}": async () => (await import("${absPath}")).default,`;
|
|
7163
7271
|
}).join("\n");
|
|
7164
|
-
const packedDir =
|
|
7272
|
+
const packedDir = path9__default.resolve(process.cwd(), "agents/packed");
|
|
7165
7273
|
const packedPackages = [];
|
|
7166
|
-
if (
|
|
7274
|
+
if (fs9__default.existsSync(packedDir)) {
|
|
7167
7275
|
console.log(`[vite-plugin-agent] Scanning packed directory: ${packedDir}`);
|
|
7168
7276
|
const packageDirs = discoverPackedPackageDirectories(packedDir);
|
|
7169
7277
|
console.log(`[vite-plugin-agent] Found package dirs: ${packageDirs.join(", ")}`);
|
|
7170
7278
|
for (const pkgPath of packageDirs) {
|
|
7171
|
-
const pkgJsonPath =
|
|
7172
|
-
if (
|
|
7279
|
+
const pkgJsonPath = path9__default.join(pkgPath, "package.json");
|
|
7280
|
+
if (fs9__default.existsSync(pkgJsonPath)) {
|
|
7173
7281
|
try {
|
|
7174
|
-
const pkgJson = JSON.parse(
|
|
7282
|
+
const pkgJson = JSON.parse(fs9__default.readFileSync(pkgJsonPath, "utf-8"));
|
|
7175
7283
|
console.log(`[vite-plugin-agent] Loaded ${pkgPath} package.json, standardagent:`, pkgJson.standardagent);
|
|
7176
7284
|
if (!pkgJson.standardagent) {
|
|
7177
7285
|
continue;
|
|
7178
7286
|
}
|
|
7179
7287
|
const mainEntry = pkgJson.main || "./dist/index.js";
|
|
7180
|
-
const outputDir =
|
|
7288
|
+
const outputDir = path9__default.dirname(mainEntry).replace(/^\.\//, "");
|
|
7181
7289
|
const pkg = {
|
|
7182
7290
|
packageId: pkgJson.name,
|
|
7183
7291
|
version: pkgJson.version,
|
|
@@ -7295,7 +7403,7 @@ export function getVisibleToolNames() {
|
|
|
7295
7403
|
async function loadRoutesVirtualModule(context) {
|
|
7296
7404
|
const { threadApiDir, rou3Code, hmr } = context;
|
|
7297
7405
|
const threadRoutes = scanApiDirectory(threadApiDir);
|
|
7298
|
-
const toAbsolutePath = (inputPath) =>
|
|
7406
|
+
const toAbsolutePath = (inputPath) => path9__default.resolve(process.cwd(), inputPath).replace(/\\/g, "/");
|
|
7299
7407
|
const threadRouteCode = threadRoutes.map(({ method, route, importPath }) => {
|
|
7300
7408
|
const apiRoute = `/api/threads/:threadId${route}`;
|
|
7301
7409
|
return ` addRoute(
|
|
@@ -7306,20 +7414,20 @@ async function loadRoutesVirtualModule(context) {
|
|
|
7306
7414
|
);`;
|
|
7307
7415
|
}).join("\n");
|
|
7308
7416
|
const packedThreadRoutes = [];
|
|
7309
|
-
const packedDir =
|
|
7417
|
+
const packedDir = path9__default.resolve(process.cwd(), "agents/packed");
|
|
7310
7418
|
const packedPackageDirs = discoverPackedPackageDirectories(packedDir);
|
|
7311
7419
|
for (const packagePath of packedPackageDirs) {
|
|
7312
|
-
const packageJsonPath =
|
|
7313
|
-
if (!
|
|
7420
|
+
const packageJsonPath = path9__default.join(packagePath, "package.json");
|
|
7421
|
+
if (!fs9__default.existsSync(packageJsonPath)) {
|
|
7314
7422
|
continue;
|
|
7315
7423
|
}
|
|
7316
7424
|
try {
|
|
7317
|
-
const packageJson = JSON.parse(
|
|
7425
|
+
const packageJson = JSON.parse(fs9__default.readFileSync(packageJsonPath, "utf-8"));
|
|
7318
7426
|
if (!packageJson.standardagent) {
|
|
7319
7427
|
continue;
|
|
7320
7428
|
}
|
|
7321
7429
|
const mainEntry = packageJson.main || "./dist/index.js";
|
|
7322
|
-
const outputDir =
|
|
7430
|
+
const outputDir = path9__default.dirname(mainEntry).replace(/^\.\//, "");
|
|
7323
7431
|
const threadEndpoints = scanPackedThreadEndpoints(packagePath, outputDir);
|
|
7324
7432
|
for (const endpoint of threadEndpoints) {
|
|
7325
7433
|
const apiRoute = `/api/threads/:threadId${endpoint.route}`;
|
|
@@ -7353,98 +7461,16 @@ import { providers, providerNames, providerFactories } from "virtual:@standardag
|
|
|
7353
7461
|
import { prompts, promptNames } from "virtual:@standardagents-prompts";
|
|
7354
7462
|
import { agents, agentNames } from "virtual:@standardagents-agents";
|
|
7355
7463
|
import { registry } from "virtual:@standardagents-registry";
|
|
7356
|
-
import {
|
|
7464
|
+
import {
|
|
7465
|
+
requireAuth,
|
|
7466
|
+
createThreadEndpointHandler,
|
|
7467
|
+
canAccessThread,
|
|
7468
|
+
isHostedInstance,
|
|
7469
|
+
isPublicApiRoute,
|
|
7470
|
+
isAdminOnlyApiRoute,
|
|
7471
|
+
} from "@standardagents/builder/runtime";
|
|
7357
7472
|
import { isThreadEndpoint } from "@standardagents/spec";
|
|
7358
7473
|
|
|
7359
|
-
// Routes that don't require authentication
|
|
7360
|
-
const PUBLIC_ROUTES = [
|
|
7361
|
-
'/api/auth/bootstrap',
|
|
7362
|
-
'/api/auth/login',
|
|
7363
|
-
'/api/auth/config',
|
|
7364
|
-
'/api/auth/brolly-control',
|
|
7365
|
-
'/api/auth/platform-cleanup',
|
|
7366
|
-
'/api/auth/platform-replica',
|
|
7367
|
-
'/api/auth/sa/start', // Login with Standard Agents (OAuth) \u2014 unauthenticated entry
|
|
7368
|
-
'/api/auth/sa/callback', // OAuth callback (sets the session cookie)
|
|
7369
|
-
'/api/config',
|
|
7370
|
-
'/api/auth/oauth/github',
|
|
7371
|
-
'/api/auth/oauth/google',
|
|
7372
|
-
'/api/auth/oauth/github/callback',
|
|
7373
|
-
'/api/auth/oauth/google/callback',
|
|
7374
|
-
'/api/platform-auth/bootstrap',
|
|
7375
|
-
'/api/platform-auth/login',
|
|
7376
|
-
'/api/platform-auth/logout',
|
|
7377
|
-
'/api/platform-auth/me',
|
|
7378
|
-
'/api/hooks' // Hook metadata is safe to expose publicly
|
|
7379
|
-
];
|
|
7380
|
-
|
|
7381
|
-
// True when the platform deployed this instance (injects STANDARD_AGENTS_HOSTED).
|
|
7382
|
-
// Hosted instances are internet-reachable and multi-tenant, so the thread data
|
|
7383
|
-
// API and event/stream WebSockets must NOT be anonymously public the way they
|
|
7384
|
-
// are in single-user local dev \u2014 they require a session (admin) or API key (SDK).
|
|
7385
|
-
function isHostedInstance(env) {
|
|
7386
|
-
const value = env && env.STANDARD_AGENTS_HOSTED;
|
|
7387
|
-
if (typeof value === 'string') {
|
|
7388
|
-
const trimmed = value.trim().toLowerCase();
|
|
7389
|
-
return trimmed !== '' && trimmed !== '0' && trimmed !== 'false';
|
|
7390
|
-
}
|
|
7391
|
-
return Boolean(value);
|
|
7392
|
-
}
|
|
7393
|
-
|
|
7394
|
-
// Check if a route is public (no auth required)
|
|
7395
|
-
function isPublicRoute(routePath, hosted) {
|
|
7396
|
-
// Exact match for auth routes
|
|
7397
|
-
if (PUBLIC_ROUTES.includes(routePath)) {
|
|
7398
|
-
return true;
|
|
7399
|
-
}
|
|
7400
|
-
|
|
7401
|
-
// Thread routes (REST + message/log stream WebSockets) are public in local
|
|
7402
|
-
// single-user dev, but on a hosted deployment they require auth \u2014 requireAuth
|
|
7403
|
-
// accepts the admin's session (cookie or token) or the SDK's API key, so this
|
|
7404
|
-
// only blocks anonymous access to another tenant's threads/messages/files.
|
|
7405
|
-
if (!hosted && (routePath.startsWith('/api/threads/') || routePath === '/api/threads')) {
|
|
7406
|
-
return true;
|
|
7407
|
-
}
|
|
7408
|
-
|
|
7409
|
-
// Device-code CLI login: start/poll are public by design (possession of the
|
|
7410
|
-
// one-time code is the secret) and the approve page must reach its controller
|
|
7411
|
-
// even when anonymous so it can redirect the browser through the platform
|
|
7412
|
-
// login (the controller enforces session auth itself).
|
|
7413
|
-
if (routePath === '/api/auth/device/start' || routePath.startsWith('/api/auth/device/')) {
|
|
7414
|
-
return true;
|
|
7415
|
-
}
|
|
7416
|
-
|
|
7417
|
-
// Provider icon routes are public (used by <img src>)
|
|
7418
|
-
if (routePath.startsWith('/api/providers/') && routePath.includes('/icon')) {
|
|
7419
|
-
return true;
|
|
7420
|
-
}
|
|
7421
|
-
|
|
7422
|
-
// Platform proxy routes handle their own auth in local dev only.
|
|
7423
|
-
if (hosted && (routePath.startsWith('/api/platform/') || routePath === '/api/platform')) {
|
|
7424
|
-
return false;
|
|
7425
|
-
}
|
|
7426
|
-
if (routePath.startsWith('/api/platform/') || routePath === '/api/platform') {
|
|
7427
|
-
return true;
|
|
7428
|
-
}
|
|
7429
|
-
|
|
7430
|
-
// Platform session proxy and auth bridge are local-dev helpers only.
|
|
7431
|
-
if (hosted && (routePath.startsWith('/api/platform-session/') || routePath === '/api/platform-session')) {
|
|
7432
|
-
return false;
|
|
7433
|
-
}
|
|
7434
|
-
if (routePath.startsWith('/api/platform-session/') || routePath === '/api/platform-session') {
|
|
7435
|
-
return true;
|
|
7436
|
-
}
|
|
7437
|
-
|
|
7438
|
-
if (hosted && (routePath.startsWith('/api/platform-auth/') || routePath === '/api/platform-auth')) {
|
|
7439
|
-
return false;
|
|
7440
|
-
}
|
|
7441
|
-
if (routePath.startsWith('/api/platform-auth/') || routePath === '/api/platform-auth') {
|
|
7442
|
-
return true;
|
|
7443
|
-
}
|
|
7444
|
-
|
|
7445
|
-
return false;
|
|
7446
|
-
}
|
|
7447
|
-
|
|
7448
7474
|
function platformEndpoint(env) {
|
|
7449
7475
|
const configured =
|
|
7450
7476
|
env && (env.PLATFORM_ENDPOINT || env.STANDARD_AGENTS_PLATFORM_URL || env.PLATFORM_URL || env.STANDARD_AGENTS_PUBLIC_URL);
|
|
@@ -7587,7 +7613,7 @@ ${packedThreadRouteCode}
|
|
|
7587
7613
|
|
|
7588
7614
|
if (routeMatch) {
|
|
7589
7615
|
// Check if authentication is required for this route
|
|
7590
|
-
const publicRoute =
|
|
7616
|
+
const publicRoute = isPublicApiRoute(routePath, request, env);
|
|
7591
7617
|
const isApiRoute = routePath.startsWith('/api/');
|
|
7592
7618
|
|
|
7593
7619
|
let authContext = null;
|
|
@@ -7603,6 +7629,10 @@ ${packedThreadRouteCode}
|
|
|
7603
7629
|
|
|
7604
7630
|
authContext = authResult;
|
|
7605
7631
|
|
|
7632
|
+
if (isAdminOnlyApiRoute(routePath, request.method) && authContext.user.role !== 'admin') {
|
|
7633
|
+
return addCorsHeaders(Response.json({ error: 'Forbidden: Admin access required' }, { status: 403 }));
|
|
7634
|
+
}
|
|
7635
|
+
|
|
7606
7636
|
if (routePath.startsWith('/api/threads/')) {
|
|
7607
7637
|
// Packed and user thread endpoints reserve threadId for the owning
|
|
7608
7638
|
// thread while nested endpoint parameters may also be named id.
|
|
@@ -7616,7 +7646,7 @@ ${packedThreadRouteCode}
|
|
|
7616
7646
|
if (!thread) {
|
|
7617
7647
|
return addCorsHeaders(Response.json({ error: \`Thread not found: \${threadId}\` }, { status: 404 }));
|
|
7618
7648
|
}
|
|
7619
|
-
if (authContext
|
|
7649
|
+
if (!canAccessThread(authContext, thread)) {
|
|
7620
7650
|
return addCorsHeaders(Response.json({ error: "Forbidden: You don't have access to this thread" }, { status: 403 }));
|
|
7621
7651
|
}
|
|
7622
7652
|
}
|
|
@@ -7792,13 +7822,13 @@ ${hooksCode}
|
|
|
7792
7822
|
};`;
|
|
7793
7823
|
}
|
|
7794
7824
|
if (id === RESOLVED_VIRTUAL_CONFIG_ID) {
|
|
7795
|
-
const relativeToolsDir =
|
|
7796
|
-
const relativeHooksDir =
|
|
7797
|
-
const relativeApiDir =
|
|
7798
|
-
const relativeModelsDir =
|
|
7799
|
-
const relativeProvidersDir =
|
|
7800
|
-
const relativePromptsDir =
|
|
7801
|
-
const relativeAgentsDir =
|
|
7825
|
+
const relativeToolsDir = path9__default.relative(process.cwd(), toolsDir).replace(/\\/g, "/");
|
|
7826
|
+
const relativeHooksDir = path9__default.relative(process.cwd(), hooksDir).replace(/\\/g, "/");
|
|
7827
|
+
const relativeApiDir = path9__default.relative(process.cwd(), threadApiDir).replace(/\\/g, "/");
|
|
7828
|
+
const relativeModelsDir = path9__default.relative(process.cwd(), modelsDir).replace(/\\/g, "/");
|
|
7829
|
+
const relativeProvidersDir = path9__default.relative(process.cwd(), providersDir).replace(/\\/g, "/");
|
|
7830
|
+
const relativePromptsDir = path9__default.relative(process.cwd(), promptsDir).replace(/\\/g, "/");
|
|
7831
|
+
const relativeAgentsDir = path9__default.relative(process.cwd(), agentsDir).replace(/\\/g, "/");
|
|
7802
7832
|
return `// Virtual agent config module
|
|
7803
7833
|
export const config = {
|
|
7804
7834
|
toolsDir: "${relativeToolsDir}",
|
|
@@ -8015,14 +8045,14 @@ var packingDeps = [
|
|
|
8015
8045
|
"typescript"
|
|
8016
8046
|
];
|
|
8017
8047
|
function createPluginViteConfig(pluginModuleUrl) {
|
|
8018
|
-
const currentDir =
|
|
8048
|
+
const currentDir = path9__default.dirname(fileURLToPath(pluginModuleUrl));
|
|
8019
8049
|
const isInDist = currentDir.endsWith("dist");
|
|
8020
|
-
const builderClientDir =
|
|
8050
|
+
const builderClientDir = path9__default.resolve(
|
|
8021
8051
|
currentDir,
|
|
8022
8052
|
isInDist ? "./client" : "../dist/client"
|
|
8023
8053
|
);
|
|
8024
8054
|
return {
|
|
8025
|
-
publicDir:
|
|
8055
|
+
publicDir: fs9__default.existsSync(builderClientDir) ? builderClientDir : void 0,
|
|
8026
8056
|
build: {
|
|
8027
8057
|
rollupOptions: {
|
|
8028
8058
|
external: [...packingDeps]
|
|
@@ -8169,24 +8199,24 @@ function applyPluginEnvironmentConfig(config) {
|
|
|
8169
8199
|
|
|
8170
8200
|
// src/plugin.ts
|
|
8171
8201
|
function agentbuilder(options = {}) {
|
|
8172
|
-
const toolsDir = options.toolsDir ?
|
|
8173
|
-
const hooksDir = options.hooksDir ?
|
|
8174
|
-
const threadApiDir = options.apiDir ?
|
|
8175
|
-
const modelsDir = options.modelsDir ?
|
|
8176
|
-
const providersDir = options.providersDir ?
|
|
8177
|
-
const promptsDir = options.promptsDir ?
|
|
8178
|
-
const agentsDir = options.agentsDir ?
|
|
8179
|
-
const effectsDir = options.effectsDir ?
|
|
8180
|
-
const usersDir = options.usersDir ?
|
|
8181
|
-
const outputDir =
|
|
8182
|
-
const generatedWorkerEntry =
|
|
8202
|
+
const toolsDir = options.toolsDir ? path9__default.resolve(process.cwd(), options.toolsDir) : path9__default.resolve(process.cwd(), "agents/tools");
|
|
8203
|
+
const hooksDir = options.hooksDir ? path9__default.resolve(process.cwd(), options.hooksDir) : path9__default.resolve(process.cwd(), "agents/hooks");
|
|
8204
|
+
const threadApiDir = options.apiDir ? path9__default.resolve(process.cwd(), options.apiDir) : path9__default.resolve(process.cwd(), "agents/api");
|
|
8205
|
+
const modelsDir = options.modelsDir ? path9__default.resolve(process.cwd(), options.modelsDir) : path9__default.resolve(process.cwd(), "agents/models");
|
|
8206
|
+
const providersDir = options.providersDir ? path9__default.resolve(process.cwd(), options.providersDir) : path9__default.resolve(process.cwd(), "agents/providers");
|
|
8207
|
+
const promptsDir = options.promptsDir ? path9__default.resolve(process.cwd(), options.promptsDir) : path9__default.resolve(process.cwd(), "agents/prompts");
|
|
8208
|
+
const agentsDir = options.agentsDir ? path9__default.resolve(process.cwd(), options.agentsDir) : path9__default.resolve(process.cwd(), "agents/agents");
|
|
8209
|
+
const effectsDir = options.effectsDir ? path9__default.resolve(process.cwd(), options.effectsDir) : path9__default.resolve(process.cwd(), "agents/effects");
|
|
8210
|
+
const usersDir = options.usersDir ? path9__default.resolve(process.cwd(), options.usersDir) : path9__default.resolve(process.cwd(), "agents/users");
|
|
8211
|
+
const outputDir = path9__default.resolve(process.cwd(), ".agents");
|
|
8212
|
+
const generatedWorkerEntry = path9__default.join(outputDir, "worker.ts");
|
|
8183
8213
|
const isProviderPackageInstalled = (packageName) => {
|
|
8184
8214
|
let dir = process.cwd();
|
|
8185
8215
|
for (; ; ) {
|
|
8186
|
-
if (
|
|
8216
|
+
if (fs9__default.existsSync(path9__default.join(dir, "node_modules", packageName, "package.json"))) {
|
|
8187
8217
|
return true;
|
|
8188
8218
|
}
|
|
8189
|
-
const parent =
|
|
8219
|
+
const parent = path9__default.dirname(dir);
|
|
8190
8220
|
if (parent === dir) return false;
|
|
8191
8221
|
dir = parent;
|
|
8192
8222
|
}
|
|
@@ -8221,17 +8251,17 @@ export default {
|
|
|
8221
8251
|
|
|
8222
8252
|
export { CodeExecutionBridge, DurableAgentBuilder, DurableThread, ThreadWatchdog, DurableUserHub };
|
|
8223
8253
|
`;
|
|
8224
|
-
|
|
8225
|
-
if (!
|
|
8226
|
-
|
|
8254
|
+
fs9__default.mkdirSync(outputDir, { recursive: true });
|
|
8255
|
+
if (!fs9__default.existsSync(generatedWorkerEntry) || fs9__default.readFileSync(generatedWorkerEntry, "utf-8") !== content) {
|
|
8256
|
+
fs9__default.writeFileSync(generatedWorkerEntry, content);
|
|
8227
8257
|
}
|
|
8228
8258
|
}
|
|
8229
8259
|
const __filename = fileURLToPath(import.meta.url);
|
|
8230
|
-
const __dirname =
|
|
8231
|
-
const rou3Path =
|
|
8260
|
+
const __dirname = path9__default.dirname(__filename);
|
|
8261
|
+
const rou3Path = path9__default.join(__dirname, "../dist/rou3.js");
|
|
8232
8262
|
let rou3Code = "";
|
|
8233
8263
|
try {
|
|
8234
|
-
rou3Code =
|
|
8264
|
+
rou3Code = fs9__default.readFileSync(rou3Path, "utf-8").replace(/^export \{[^}]+\};?\s*$/gm, "").replace(/\/\/# sourceMappingURL=.+$/gm, "").trim();
|
|
8235
8265
|
} catch (err) {
|
|
8236
8266
|
console.warn("[vite-plugin-agent] Could not read rou3.js for inlining:", err);
|
|
8237
8267
|
}
|
|
@@ -8274,7 +8304,7 @@ export { CodeExecutionBridge, DurableAgentBuilder, DurableThread, ThreadWatchdog
|
|
|
8274
8304
|
sourceDirs,
|
|
8275
8305
|
regenerateTypes
|
|
8276
8306
|
};
|
|
8277
|
-
const workerEntry =
|
|
8307
|
+
const workerEntry = path9__default.relative(process.cwd(), generatedWorkerEntry).split(path9__default.sep).join("/");
|
|
8278
8308
|
const corePlugin = {
|
|
8279
8309
|
name: "vite-plugin-agent",
|
|
8280
8310
|
enforce: "pre",
|
|
@@ -8349,28 +8379,28 @@ export { CodeExecutionBridge, DurableAgentBuilder, DurableThread, ThreadWatchdog
|
|
|
8349
8379
|
},
|
|
8350
8380
|
writeBundle(options2, bundle) {
|
|
8351
8381
|
const outDir = options2.dir || "dist";
|
|
8352
|
-
const mountDir =
|
|
8353
|
-
const currentDir =
|
|
8382
|
+
const mountDir = path9__default.join(outDir, "../client");
|
|
8383
|
+
const currentDir = path9__default.dirname(fileURLToPath(import.meta.url));
|
|
8354
8384
|
const isInDist = currentDir.endsWith("dist");
|
|
8355
|
-
const clientDir =
|
|
8385
|
+
const clientDir = path9__default.resolve(
|
|
8356
8386
|
currentDir,
|
|
8357
8387
|
isInDist ? "./client" : "../dist/client"
|
|
8358
8388
|
);
|
|
8359
|
-
if (!
|
|
8389
|
+
if (!fs9__default.existsSync(clientDir)) {
|
|
8360
8390
|
console.warn(`[agentbuilder] Client directory not found at ${clientDir}`);
|
|
8361
8391
|
return;
|
|
8362
8392
|
}
|
|
8363
|
-
|
|
8393
|
+
fs9__default.mkdirSync(mountDir, { recursive: true });
|
|
8364
8394
|
function copyRecursive(src, dest) {
|
|
8365
|
-
const entries =
|
|
8395
|
+
const entries = fs9__default.readdirSync(src, { withFileTypes: true });
|
|
8366
8396
|
for (const entry of entries) {
|
|
8367
|
-
const srcPath =
|
|
8368
|
-
const destPath =
|
|
8397
|
+
const srcPath = path9__default.join(src, entry.name);
|
|
8398
|
+
const destPath = path9__default.join(dest, entry.name);
|
|
8369
8399
|
if (entry.isDirectory()) {
|
|
8370
|
-
|
|
8400
|
+
fs9__default.mkdirSync(destPath, { recursive: true });
|
|
8371
8401
|
copyRecursive(srcPath, destPath);
|
|
8372
8402
|
} else {
|
|
8373
|
-
let content =
|
|
8403
|
+
let content = fs9__default.readFileSync(srcPath);
|
|
8374
8404
|
if (entry.name === "index.html") {
|
|
8375
8405
|
const configScript = `<script>window.__AGENTBUILDER_CONFIG__ = {};</script>`;
|
|
8376
8406
|
let htmlContent = content.toString();
|
|
@@ -8378,27 +8408,27 @@ export { CodeExecutionBridge, DurableAgentBuilder, DurableThread, ThreadWatchdog
|
|
|
8378
8408
|
htmlContent = htmlContent.replace("</head>", `${configScript}</head>`);
|
|
8379
8409
|
content = Buffer.from(htmlContent);
|
|
8380
8410
|
}
|
|
8381
|
-
|
|
8411
|
+
fs9__default.writeFileSync(destPath, content);
|
|
8382
8412
|
}
|
|
8383
8413
|
}
|
|
8384
8414
|
}
|
|
8385
8415
|
copyRecursive(clientDir, mountDir);
|
|
8386
|
-
const projectPublicDir =
|
|
8387
|
-
if (
|
|
8416
|
+
const projectPublicDir = path9__default.resolve(process.cwd(), "public");
|
|
8417
|
+
if (fs9__default.existsSync(projectPublicDir)) {
|
|
8388
8418
|
let copyPublicRecursive2 = function(src, dest) {
|
|
8389
|
-
const entries =
|
|
8419
|
+
const entries = fs9__default.readdirSync(src, { withFileTypes: true });
|
|
8390
8420
|
for (const entry of entries) {
|
|
8391
|
-
const srcPath =
|
|
8392
|
-
const destPath =
|
|
8421
|
+
const srcPath = path9__default.join(src, entry.name);
|
|
8422
|
+
const destPath = path9__default.join(dest, entry.name);
|
|
8393
8423
|
if (entry.isDirectory()) {
|
|
8394
|
-
|
|
8424
|
+
fs9__default.mkdirSync(destPath, { recursive: true });
|
|
8395
8425
|
copyPublicRecursive2(srcPath, destPath);
|
|
8396
|
-
} else if (
|
|
8426
|
+
} else if (fs9__default.existsSync(destPath)) {
|
|
8397
8427
|
console.warn(
|
|
8398
8428
|
`[agentbuilder] Skipping public/ file that collides with a built UI asset: ${destPath}`
|
|
8399
8429
|
);
|
|
8400
8430
|
} else {
|
|
8401
|
-
|
|
8431
|
+
fs9__default.copyFileSync(srcPath, destPath);
|
|
8402
8432
|
}
|
|
8403
8433
|
}
|
|
8404
8434
|
};
|