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