@withone/cli 1.44.2 → 1.45.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/README.md +5 -3
- package/dist/chunk-77564KWS.js +211 -0
- package/dist/{chunk-YGOS6KEC.js → chunk-DZK56R5R.js} +257 -85
- package/dist/{chunk-MNNKOQ6V.js → chunk-KH4ERRJ5.js} +4 -2
- package/dist/{chunk-YBEVCY4D.js → chunk-TGWQUBKA.js} +4 -2
- package/dist/{chunk-7ZILTQQO.js → chunk-TLRJMJGU.js} +2 -2
- package/dist/{chunk-ZD5S4IWT.js → chunk-TVIZC7AC.js} +2 -203
- package/dist/{chunk-VQPV5XET.js → chunk-Z4HKASJT.js} +2 -2
- package/dist/{embedding-GZGDGIUA.js → embedding-C3E4EAQ7.js} +2 -1
- package/dist/{flow-runner-EXZ77YLF.js → flow-runner-6KN2ZVXB.js} +2 -1
- package/dist/index.js +311 -380
- package/dist/{migrate-J2ZRDEFB.js → migrate-VV3VOXWJ.js} +5 -4
- package/dist/{runtime-RVXAPQAZ.js → runtime-3NDWRLXL.js} +3 -2
- package/dist/sql-ZABEXIXW.js +12 -0
- package/package.json +2 -2
- package/skills/one/SKILL.md +6 -5
- package/dist/sql-V44IVBHX.js +0 -11
|
@@ -2,16 +2,19 @@ import {
|
|
|
2
2
|
getByDotPath,
|
|
3
3
|
setByDotPath
|
|
4
4
|
} from "./chunk-44CV5IMX.js";
|
|
5
|
+
import {
|
|
6
|
+
getCacheTtl
|
|
7
|
+
} from "./chunk-TVIZC7AC.js";
|
|
5
8
|
|
|
6
9
|
// src/lib/flow-runner.ts
|
|
7
|
-
import
|
|
8
|
-
import
|
|
10
|
+
import fs3 from "fs";
|
|
11
|
+
import path3 from "path";
|
|
9
12
|
import crypto from "crypto";
|
|
10
13
|
|
|
11
14
|
// src/lib/flow-engine.ts
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
+
import fs2 from "fs";
|
|
16
|
+
import os2 from "os";
|
|
17
|
+
import path2 from "path";
|
|
15
18
|
import { exec, spawn } from "child_process";
|
|
16
19
|
import { promisify } from "util";
|
|
17
20
|
|
|
@@ -45,8 +48,8 @@ var OneApi = class {
|
|
|
45
48
|
this.apiBase = apiBase ?? "https://api.withone.ai/v1";
|
|
46
49
|
}
|
|
47
50
|
apiBase;
|
|
48
|
-
async request(
|
|
49
|
-
return this.requestFull({ path:
|
|
51
|
+
async request(path4) {
|
|
52
|
+
return this.requestFull({ path: path4 });
|
|
50
53
|
}
|
|
51
54
|
async requestFull(opts) {
|
|
52
55
|
let url = `${this.apiBase}${opts.path}`;
|
|
@@ -231,7 +234,12 @@ var OneApi = class {
|
|
|
231
234
|
const data = text ? JSON.parse(text) : {};
|
|
232
235
|
return { data, etag, status: response.status };
|
|
233
236
|
}
|
|
234
|
-
|
|
237
|
+
/**
|
|
238
|
+
* Full action details (method, path, tags, ioSchema, knowledge) with ETag
|
|
239
|
+
* support. This is what the knowledge cache stores: caching the complete
|
|
240
|
+
* object lets `actions execute` reuse it and skip its preflight round trip.
|
|
241
|
+
*/
|
|
242
|
+
async getActionDetailsWithMeta(actionId, ifNoneMatch) {
|
|
235
243
|
const result = await this.requestWithMeta({
|
|
236
244
|
path: "/knowledge",
|
|
237
245
|
queryParams: { _id: actionId },
|
|
@@ -244,12 +252,7 @@ var OneApi = class {
|
|
|
244
252
|
if (actions.length === 0) {
|
|
245
253
|
throw new ApiError(404, `Action with ID ${actionId} not found`);
|
|
246
254
|
}
|
|
247
|
-
|
|
248
|
-
const knowledge = {
|
|
249
|
-
knowledge: action.knowledge || "No knowledge was found",
|
|
250
|
-
method: action.method || "No method was found"
|
|
251
|
-
};
|
|
252
|
-
return { data: knowledge, etag: result.etag, status: result.status };
|
|
255
|
+
return { data: actions[0], etag: result.etag, status: result.status };
|
|
253
256
|
}
|
|
254
257
|
async searchActionsWithMeta(platform, query, agentType, ifNoneMatch) {
|
|
255
258
|
const isKnowledgeAgent = agentType === "knowledge";
|
|
@@ -478,9 +481,9 @@ var TimeoutError = class extends Error {
|
|
|
478
481
|
function sleep(ms) {
|
|
479
482
|
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
480
483
|
}
|
|
481
|
-
function replacePathVariables(
|
|
482
|
-
if (!
|
|
483
|
-
let result =
|
|
484
|
+
function replacePathVariables(path4, variables) {
|
|
485
|
+
if (!path4) return path4;
|
|
486
|
+
let result = path4;
|
|
484
487
|
result = result.replace(/\{\{([^}]+)\}\}/g, (_match, variable) => {
|
|
485
488
|
const trimmedVariable = variable.trim();
|
|
486
489
|
const value = variables[trimmedVariable];
|
|
@@ -544,6 +547,162 @@ Read the API documentation below to identify which parameters are path variables
|
|
|
544
547
|
${knowledge}`;
|
|
545
548
|
}
|
|
546
549
|
|
|
550
|
+
// src/lib/cache.ts
|
|
551
|
+
import fs from "fs";
|
|
552
|
+
import path from "path";
|
|
553
|
+
import os from "os";
|
|
554
|
+
function knowledgeDir() {
|
|
555
|
+
return path.join(os.homedir(), ".one", "cache", "knowledge");
|
|
556
|
+
}
|
|
557
|
+
function searchDir() {
|
|
558
|
+
return path.join(os.homedir(), ".one", "cache", "search");
|
|
559
|
+
}
|
|
560
|
+
function sanitizeFilename(input) {
|
|
561
|
+
return input.replace(/[^a-zA-Z0-9_\-\.]/g, "_");
|
|
562
|
+
}
|
|
563
|
+
function knowledgeCachePath(actionId) {
|
|
564
|
+
return path.join(knowledgeDir(), `${sanitizeFilename(actionId)}.json`);
|
|
565
|
+
}
|
|
566
|
+
function searchCachePath(platform, query, type) {
|
|
567
|
+
const key = `${platform}_${sanitizeFilename(query)}_${type || "knowledge"}`;
|
|
568
|
+
return path.join(searchDir(), `${key}.json`);
|
|
569
|
+
}
|
|
570
|
+
function readCache(filePath) {
|
|
571
|
+
try {
|
|
572
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
573
|
+
return JSON.parse(content);
|
|
574
|
+
} catch {
|
|
575
|
+
return null;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
function writeCache(filePath, entry) {
|
|
579
|
+
try {
|
|
580
|
+
const dir = path.dirname(filePath);
|
|
581
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
582
|
+
fs.writeFileSync(filePath, JSON.stringify(entry, null, 2));
|
|
583
|
+
} catch {
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
function isFresh(entry) {
|
|
587
|
+
const cachedTime = new Date(entry.cachedAt).getTime();
|
|
588
|
+
const now = Date.now();
|
|
589
|
+
return now - cachedTime < entry.ttl * 1e3;
|
|
590
|
+
}
|
|
591
|
+
function getAge(entry) {
|
|
592
|
+
return Math.floor((Date.now() - new Date(entry.cachedAt).getTime()) / 1e3);
|
|
593
|
+
}
|
|
594
|
+
function buildCacheMeta(entry, hit) {
|
|
595
|
+
if (!entry) {
|
|
596
|
+
return { hit: false, age: 0, fresh: false };
|
|
597
|
+
}
|
|
598
|
+
return {
|
|
599
|
+
hit,
|
|
600
|
+
age: getAge(entry),
|
|
601
|
+
fresh: isFresh(entry)
|
|
602
|
+
};
|
|
603
|
+
}
|
|
604
|
+
function formatAge(seconds) {
|
|
605
|
+
if (seconds < 60) return `${seconds}s`;
|
|
606
|
+
if (seconds < 3600) return `${Math.floor(seconds / 60)}m`;
|
|
607
|
+
if (seconds < 86400) {
|
|
608
|
+
const h2 = Math.floor(seconds / 3600);
|
|
609
|
+
const m = Math.floor(seconds % 3600 / 60);
|
|
610
|
+
return m > 0 ? `${h2}h ${m}m` : `${h2}h`;
|
|
611
|
+
}
|
|
612
|
+
const d = Math.floor(seconds / 86400);
|
|
613
|
+
const h = Math.floor(seconds % 86400 / 3600);
|
|
614
|
+
return h > 0 ? `${d}d ${h}h` : `${d}d`;
|
|
615
|
+
}
|
|
616
|
+
function listCacheEntries() {
|
|
617
|
+
const entries = [];
|
|
618
|
+
for (const [dir, type] of [[knowledgeDir(), "knowledge"], [searchDir(), "search"]]) {
|
|
619
|
+
try {
|
|
620
|
+
const files = fs.readdirSync(dir);
|
|
621
|
+
for (const file of files) {
|
|
622
|
+
if (!file.endsWith(".json")) continue;
|
|
623
|
+
const filePath = path.join(dir, file);
|
|
624
|
+
const entry = readCache(filePath);
|
|
625
|
+
if (entry) {
|
|
626
|
+
entries.push({ type, filePath, entry });
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
} catch {
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
return entries;
|
|
633
|
+
}
|
|
634
|
+
function clearAll() {
|
|
635
|
+
let count = 0;
|
|
636
|
+
for (const dir of [knowledgeDir(), searchDir()]) {
|
|
637
|
+
try {
|
|
638
|
+
const files = fs.readdirSync(dir);
|
|
639
|
+
for (const file of files) {
|
|
640
|
+
fs.unlinkSync(path.join(dir, file));
|
|
641
|
+
count++;
|
|
642
|
+
}
|
|
643
|
+
fs.rmdirSync(dir);
|
|
644
|
+
} catch {
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
return count;
|
|
648
|
+
}
|
|
649
|
+
function clearEntry(actionId) {
|
|
650
|
+
const filePath = knowledgeCachePath(actionId);
|
|
651
|
+
try {
|
|
652
|
+
fs.unlinkSync(filePath);
|
|
653
|
+
return true;
|
|
654
|
+
} catch {
|
|
655
|
+
return false;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
function makeCacheEntry(key, data, etag) {
|
|
659
|
+
return {
|
|
660
|
+
key,
|
|
661
|
+
etag,
|
|
662
|
+
cachedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
663
|
+
ttl: getCacheTtl(),
|
|
664
|
+
data
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
// src/lib/action-details.ts
|
|
669
|
+
function isActionDetailsEntry(entry) {
|
|
670
|
+
const data = entry?.data;
|
|
671
|
+
return !!data && typeof data._id === "string" && typeof data.path === "string" && typeof data.method === "string";
|
|
672
|
+
}
|
|
673
|
+
async function resolveActionDetails(api, actionId, opts = {}) {
|
|
674
|
+
const useCache = opts.useCache !== false;
|
|
675
|
+
const warn = opts.warn ?? ((m) => {
|
|
676
|
+
process.stderr.write(m);
|
|
677
|
+
});
|
|
678
|
+
const cachePath = knowledgeCachePath(actionId);
|
|
679
|
+
const raw = useCache ? readCache(cachePath) : null;
|
|
680
|
+
const cached = isActionDetailsEntry(raw) ? raw : null;
|
|
681
|
+
if (cached && isFresh(cached)) {
|
|
682
|
+
return { details: cached.data, cacheHit: true, stale: false, entry: cached };
|
|
683
|
+
}
|
|
684
|
+
try {
|
|
685
|
+
const result = await api.getActionDetailsWithMeta(actionId, cached?.etag ?? void 0);
|
|
686
|
+
if (result.status === 304 && cached) {
|
|
687
|
+
cached.cachedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
688
|
+
writeCache(cachePath, cached);
|
|
689
|
+
return { details: cached.data, cacheHit: true, stale: false, entry: cached };
|
|
690
|
+
}
|
|
691
|
+
const entry = makeCacheEntry(actionId, result.data, result.etag);
|
|
692
|
+
writeCache(cachePath, entry);
|
|
693
|
+
return { details: result.data, cacheHit: false, stale: false, entry };
|
|
694
|
+
} catch (fetchError) {
|
|
695
|
+
if (cached) {
|
|
696
|
+
warn(
|
|
697
|
+
`Warning: serving cached action details (network unavailable, cached ${formatAge(getAge(cached))} ago)
|
|
698
|
+
`
|
|
699
|
+
);
|
|
700
|
+
return { details: cached.data, cacheHit: true, stale: true, entry: cached };
|
|
701
|
+
}
|
|
702
|
+
throw fetchError;
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
|
|
547
706
|
// src/lib/validate.ts
|
|
548
707
|
var SCHEMA_GROUP_TO_FLAG = {
|
|
549
708
|
path: "--path-vars",
|
|
@@ -816,7 +975,7 @@ async function executeActionStep(step, context, api, permissions, allowedActionI
|
|
|
816
975
|
if (!isActionAllowed(actionId, allowedActionIds)) {
|
|
817
976
|
throw new Error(`Action "${actionId}" is not in the allowed action list`);
|
|
818
977
|
}
|
|
819
|
-
const actionDetails = await api
|
|
978
|
+
const { details: actionDetails } = await resolveActionDetails(api, actionId);
|
|
820
979
|
if (!isMethodAllowed(actionDetails.method, permissions)) {
|
|
821
980
|
throw new Error(`Method "${actionDetails.method}" is not allowed under "${permissions}" permission level`);
|
|
822
981
|
}
|
|
@@ -899,15 +1058,15 @@ async function executeCodeModule(stepId, modulePath, context, options) {
|
|
|
899
1058
|
if (!rootDir) {
|
|
900
1059
|
throw new Error(`Code step "${stepId}" uses module "${modulePath}" but no flow rootDir is available. Flows that use code modules must be loaded via loadFlowWithMeta.`);
|
|
901
1060
|
}
|
|
902
|
-
if (
|
|
1061
|
+
if (path2.isAbsolute(modulePath)) {
|
|
903
1062
|
throw new Error(`Code module path must be relative to the flow root, got absolute: "${modulePath}"`);
|
|
904
1063
|
}
|
|
905
|
-
const absPath =
|
|
906
|
-
const relFromRoot =
|
|
907
|
-
if (relFromRoot.startsWith("..") ||
|
|
1064
|
+
const absPath = path2.resolve(rootDir, modulePath);
|
|
1065
|
+
const relFromRoot = path2.relative(rootDir, absPath);
|
|
1066
|
+
if (relFromRoot.startsWith("..") || path2.isAbsolute(relFromRoot)) {
|
|
908
1067
|
throw new Error(`Code module "${modulePath}" resolves outside the flow directory`);
|
|
909
1068
|
}
|
|
910
|
-
if (!
|
|
1069
|
+
if (!fs2.existsSync(absPath)) {
|
|
911
1070
|
throw new Error(`Code module not found: ${absPath}`);
|
|
912
1071
|
}
|
|
913
1072
|
const { env: _omitEnv, ...safeContext } = context;
|
|
@@ -1055,8 +1214,8 @@ async function executeParallelStep(step, context, api, permissions, allowedActio
|
|
|
1055
1214
|
function executeFileReadStep(step, context) {
|
|
1056
1215
|
const config = step.fileRead;
|
|
1057
1216
|
const filePath = resolveValue(config.path, context);
|
|
1058
|
-
const resolvedPath =
|
|
1059
|
-
const content =
|
|
1217
|
+
const resolvedPath = path2.resolve(filePath);
|
|
1218
|
+
const content = fs2.readFileSync(resolvedPath, "utf-8");
|
|
1060
1219
|
const output = config.parseJson ? JSON.parse(stripCodeFences(content)) : content;
|
|
1061
1220
|
return { status: "success", output, response: output };
|
|
1062
1221
|
}
|
|
@@ -1064,16 +1223,16 @@ function executeFileWriteStep(step, context) {
|
|
|
1064
1223
|
const config = step.fileWrite;
|
|
1065
1224
|
const filePath = resolveValue(config.path, context);
|
|
1066
1225
|
const content = resolveValue(config.content, context);
|
|
1067
|
-
const resolvedPath =
|
|
1068
|
-
const dir =
|
|
1069
|
-
if (!
|
|
1070
|
-
|
|
1226
|
+
const resolvedPath = path2.resolve(filePath);
|
|
1227
|
+
const dir = path2.dirname(resolvedPath);
|
|
1228
|
+
if (!fs2.existsSync(dir)) {
|
|
1229
|
+
fs2.mkdirSync(dir, { recursive: true });
|
|
1071
1230
|
}
|
|
1072
1231
|
const stringContent = typeof content === "string" ? content : JSON.stringify(content, null, 2);
|
|
1073
1232
|
if (config.append) {
|
|
1074
|
-
|
|
1233
|
+
fs2.appendFileSync(resolvedPath, stringContent);
|
|
1075
1234
|
} else {
|
|
1076
|
-
|
|
1235
|
+
fs2.writeFileSync(resolvedPath, stringContent);
|
|
1077
1236
|
}
|
|
1078
1237
|
return { status: "success", output: { path: resolvedPath, bytesWritten: stringContent.length }, response: { path: resolvedPath } };
|
|
1079
1238
|
}
|
|
@@ -1112,7 +1271,7 @@ async function executeSubflowStep(step, context, api, permissions, allowedAction
|
|
|
1112
1271
|
if (flowStack.includes(resolvedKey)) {
|
|
1113
1272
|
throw new Error(`Circular flow detected: ${[...flowStack, resolvedKey].join(" \u2192 ")}`);
|
|
1114
1273
|
}
|
|
1115
|
-
const { loadFlowWithMeta: loadFlowWithMeta2 } = await import("./flow-runner-
|
|
1274
|
+
const { loadFlowWithMeta: loadFlowWithMeta2 } = await import("./flow-runner-6KN2ZVXB.js");
|
|
1116
1275
|
const { flow: subFlow, rootDir: subRootDir } = loadFlowWithMeta2(resolvedKey);
|
|
1117
1276
|
const subContext = await executeFlow(
|
|
1118
1277
|
subFlow,
|
|
@@ -1215,11 +1374,11 @@ function resolveBashEnv(envConfig, context, stepId) {
|
|
|
1215
1374
|
if ("json" in obj) {
|
|
1216
1375
|
const resolved2 = resolveValue(obj.json, context);
|
|
1217
1376
|
const json = JSON.stringify(resolved2 ?? null);
|
|
1218
|
-
const tmp =
|
|
1219
|
-
|
|
1377
|
+
const tmp = path2.join(
|
|
1378
|
+
os2.tmpdir(),
|
|
1220
1379
|
`one-flow-${stepId}-${key}-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.json`
|
|
1221
1380
|
);
|
|
1222
|
-
|
|
1381
|
+
fs2.writeFileSync(tmp, json, { encoding: "utf-8" });
|
|
1223
1382
|
tempFiles.push(tmp);
|
|
1224
1383
|
out[key] = tmp;
|
|
1225
1384
|
continue;
|
|
@@ -1266,7 +1425,7 @@ async function executeBashStep(step, context, options) {
|
|
|
1266
1425
|
} finally {
|
|
1267
1426
|
for (const tmp of tempFiles) {
|
|
1268
1427
|
try {
|
|
1269
|
-
|
|
1428
|
+
fs2.unlinkSync(tmp);
|
|
1270
1429
|
} catch {
|
|
1271
1430
|
}
|
|
1272
1431
|
}
|
|
@@ -1347,7 +1506,7 @@ async function executeSingleStep(step, context, api, permissions, allowedActionI
|
|
|
1347
1506
|
if (step.type === "action" && step.action) {
|
|
1348
1507
|
const actionId = resolveValue(step.action.actionId, context);
|
|
1349
1508
|
try {
|
|
1350
|
-
const actionDetails = await api
|
|
1509
|
+
const { details: actionDetails } = await resolveActionDetails(api, actionId);
|
|
1351
1510
|
if (!options.skipValidation) {
|
|
1352
1511
|
const data = step.action.data ? resolveValue(step.action.data, context) : void 0;
|
|
1353
1512
|
const pathVars = step.action.pathVars ? resolveValue(step.action.pathVars, context) : void 0;
|
|
@@ -2389,8 +2548,8 @@ var FLOWS_DIR = ".one/flows";
|
|
|
2389
2548
|
var RUNS_DIR = ".one/flows/.runs";
|
|
2390
2549
|
var LOGS_DIR = ".one/flows/.logs";
|
|
2391
2550
|
function ensureDir(dir) {
|
|
2392
|
-
if (!
|
|
2393
|
-
|
|
2551
|
+
if (!fs3.existsSync(dir)) {
|
|
2552
|
+
fs3.mkdirSync(dir, { recursive: true });
|
|
2394
2553
|
}
|
|
2395
2554
|
}
|
|
2396
2555
|
function generateRunId() {
|
|
@@ -2408,8 +2567,8 @@ var FlowRunner = class _FlowRunner {
|
|
|
2408
2567
|
this.flowKey = flow.key;
|
|
2409
2568
|
ensureDir(RUNS_DIR);
|
|
2410
2569
|
ensureDir(LOGS_DIR);
|
|
2411
|
-
this.statePath =
|
|
2412
|
-
this.logPath =
|
|
2570
|
+
this.statePath = path3.join(RUNS_DIR, `${flow.key}-${this.runId}.state.json`);
|
|
2571
|
+
this.logPath = path3.join(LOGS_DIR, `${flow.key}-${this.runId}.log`);
|
|
2413
2572
|
const resolvedInputs = { ...inputs };
|
|
2414
2573
|
for (const [name, decl] of Object.entries(flow.inputs)) {
|
|
2415
2574
|
if (resolvedInputs[name] === void 0 && decl.default !== void 0) {
|
|
@@ -2450,10 +2609,10 @@ var FlowRunner = class _FlowRunner {
|
|
|
2450
2609
|
msg,
|
|
2451
2610
|
...data
|
|
2452
2611
|
};
|
|
2453
|
-
|
|
2612
|
+
fs3.appendFileSync(this.logPath, JSON.stringify(entry) + "\n");
|
|
2454
2613
|
}
|
|
2455
2614
|
saveState() {
|
|
2456
|
-
|
|
2615
|
+
fs3.writeFileSync(this.statePath, JSON.stringify(this.state, null, 2));
|
|
2457
2616
|
}
|
|
2458
2617
|
createEventHandler(externalHandler) {
|
|
2459
2618
|
return (event) => {
|
|
@@ -2551,10 +2710,10 @@ var FlowRunner = class _FlowRunner {
|
|
|
2551
2710
|
}
|
|
2552
2711
|
static loadRunState(runId) {
|
|
2553
2712
|
ensureDir(RUNS_DIR);
|
|
2554
|
-
const files =
|
|
2713
|
+
const files = fs3.readdirSync(RUNS_DIR).filter((f) => f.includes(runId) && f.endsWith(".state.json"));
|
|
2555
2714
|
if (files.length === 0) return null;
|
|
2556
2715
|
try {
|
|
2557
|
-
const content =
|
|
2716
|
+
const content = fs3.readFileSync(path3.join(RUNS_DIR, files[0]), "utf-8");
|
|
2558
2717
|
return JSON.parse(content);
|
|
2559
2718
|
} catch {
|
|
2560
2719
|
return null;
|
|
@@ -2566,17 +2725,17 @@ var FlowRunner = class _FlowRunner {
|
|
|
2566
2725
|
runner.flowKey = state.flowKey;
|
|
2567
2726
|
runner.state = state;
|
|
2568
2727
|
runner.paused = false;
|
|
2569
|
-
runner.statePath =
|
|
2570
|
-
runner.logPath =
|
|
2728
|
+
runner.statePath = path3.join(RUNS_DIR, `${state.flowKey}-${state.runId}.state.json`);
|
|
2729
|
+
runner.logPath = path3.join(LOGS_DIR, `${state.flowKey}-${state.runId}.log`);
|
|
2571
2730
|
return runner;
|
|
2572
2731
|
}
|
|
2573
2732
|
static listRuns(flowKey) {
|
|
2574
2733
|
ensureDir(RUNS_DIR);
|
|
2575
|
-
const files =
|
|
2734
|
+
const files = fs3.readdirSync(RUNS_DIR).filter((f) => f.endsWith(".state.json"));
|
|
2576
2735
|
const runs = [];
|
|
2577
2736
|
for (const file of files) {
|
|
2578
2737
|
try {
|
|
2579
|
-
const content =
|
|
2738
|
+
const content = fs3.readFileSync(path3.join(RUNS_DIR, file), "utf-8");
|
|
2580
2739
|
const state = JSON.parse(content);
|
|
2581
2740
|
if (!flowKey || state.flowKey === flowKey) {
|
|
2582
2741
|
runs.push(state);
|
|
@@ -2589,44 +2748,44 @@ var FlowRunner = class _FlowRunner {
|
|
|
2589
2748
|
};
|
|
2590
2749
|
function resolveFlowPath(keyOrPath) {
|
|
2591
2750
|
if (keyOrPath.endsWith(".json")) {
|
|
2592
|
-
return
|
|
2751
|
+
return path3.resolve(keyOrPath);
|
|
2593
2752
|
}
|
|
2594
2753
|
if (keyOrPath.includes("\\")) {
|
|
2595
|
-
return
|
|
2754
|
+
return path3.resolve(keyOrPath);
|
|
2596
2755
|
}
|
|
2597
2756
|
if (keyOrPath.includes("/")) {
|
|
2598
|
-
const nestedFolder =
|
|
2599
|
-
if (
|
|
2600
|
-
const literal =
|
|
2601
|
-
if (
|
|
2757
|
+
const nestedFolder = path3.resolve(FLOWS_DIR, keyOrPath, "flow.json");
|
|
2758
|
+
if (fs3.existsSync(nestedFolder)) return nestedFolder;
|
|
2759
|
+
const literal = path3.resolve(keyOrPath);
|
|
2760
|
+
if (fs3.existsSync(literal)) return literal;
|
|
2602
2761
|
return nestedFolder;
|
|
2603
2762
|
}
|
|
2604
|
-
const folderPath =
|
|
2605
|
-
if (
|
|
2606
|
-
const legacyPath =
|
|
2607
|
-
if (
|
|
2608
|
-
const flowsDir =
|
|
2609
|
-
if (
|
|
2610
|
-
for (const entry of
|
|
2763
|
+
const folderPath = path3.resolve(FLOWS_DIR, keyOrPath, "flow.json");
|
|
2764
|
+
if (fs3.existsSync(folderPath)) return folderPath;
|
|
2765
|
+
const legacyPath = path3.resolve(FLOWS_DIR, `${keyOrPath}.flow.json`);
|
|
2766
|
+
if (fs3.existsSync(legacyPath)) return legacyPath;
|
|
2767
|
+
const flowsDir = path3.resolve(FLOWS_DIR);
|
|
2768
|
+
if (fs3.existsSync(flowsDir)) {
|
|
2769
|
+
for (const entry of fs3.readdirSync(flowsDir, { withFileTypes: true })) {
|
|
2611
2770
|
if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
|
|
2612
|
-
const nested =
|
|
2613
|
-
if (
|
|
2771
|
+
const nested = path3.join(flowsDir, entry.name, keyOrPath, "flow.json");
|
|
2772
|
+
if (fs3.existsSync(nested)) return nested;
|
|
2614
2773
|
}
|
|
2615
2774
|
}
|
|
2616
2775
|
return folderPath;
|
|
2617
2776
|
}
|
|
2618
2777
|
function getFlowRootDir(flowFilePath) {
|
|
2619
|
-
const dir =
|
|
2620
|
-
const base =
|
|
2778
|
+
const dir = path3.dirname(flowFilePath);
|
|
2779
|
+
const base = path3.basename(flowFilePath);
|
|
2621
2780
|
if (base === "flow.json") return dir;
|
|
2622
2781
|
return dir;
|
|
2623
2782
|
}
|
|
2624
2783
|
function loadFlowWithMeta(keyOrPath) {
|
|
2625
2784
|
const filePath = resolveFlowPath(keyOrPath);
|
|
2626
|
-
if (!
|
|
2785
|
+
if (!fs3.existsSync(filePath)) {
|
|
2627
2786
|
throw new Error(`Flow not found: ${filePath}`);
|
|
2628
2787
|
}
|
|
2629
|
-
const content =
|
|
2788
|
+
const content = fs3.readFileSync(filePath, "utf-8");
|
|
2630
2789
|
const flow = JSON.parse(content);
|
|
2631
2790
|
return { flow, filePath, rootDir: getFlowRootDir(filePath) };
|
|
2632
2791
|
}
|
|
@@ -2673,13 +2832,13 @@ function summarizeFlowInputs(flow) {
|
|
|
2673
2832
|
}));
|
|
2674
2833
|
}
|
|
2675
2834
|
function listFlows() {
|
|
2676
|
-
const flowsDir =
|
|
2677
|
-
if (!
|
|
2835
|
+
const flowsDir = path3.resolve(FLOWS_DIR);
|
|
2836
|
+
if (!fs3.existsSync(flowsDir)) return [];
|
|
2678
2837
|
const flows = [];
|
|
2679
2838
|
const seenKeys = /* @__PURE__ */ new Set();
|
|
2680
2839
|
const readFlowFile = (filePath, group) => {
|
|
2681
2840
|
try {
|
|
2682
|
-
const content =
|
|
2841
|
+
const content = fs3.readFileSync(filePath, "utf-8");
|
|
2683
2842
|
const flow = JSON.parse(content);
|
|
2684
2843
|
const nsKey = group ? `${group}/${flow.key}` : flow.key;
|
|
2685
2844
|
if (seenKeys.has(nsKey)) return;
|
|
@@ -2691,7 +2850,7 @@ function listFlows() {
|
|
|
2691
2850
|
inputCount: Object.keys(flow.inputs).length,
|
|
2692
2851
|
stepCount: flow.steps.length,
|
|
2693
2852
|
path: filePath,
|
|
2694
|
-
layout:
|
|
2853
|
+
layout: path3.basename(filePath) === "flow.json" ? "folder" : "legacy",
|
|
2695
2854
|
group,
|
|
2696
2855
|
stepTypes: collectStepTypes(flow),
|
|
2697
2856
|
requiresBash: flowRequiresBash(flow),
|
|
@@ -2702,12 +2861,12 @@ function listFlows() {
|
|
|
2702
2861
|
}
|
|
2703
2862
|
};
|
|
2704
2863
|
const scanDir = (dir, group) => {
|
|
2705
|
-
for (const entry of
|
|
2864
|
+
for (const entry of fs3.readdirSync(dir, { withFileTypes: true })) {
|
|
2706
2865
|
if (entry.name.startsWith(".")) continue;
|
|
2707
|
-
const full =
|
|
2866
|
+
const full = path3.join(dir, entry.name);
|
|
2708
2867
|
if (entry.isDirectory()) {
|
|
2709
|
-
const flowJson =
|
|
2710
|
-
if (
|
|
2868
|
+
const flowJson = path3.join(full, "flow.json");
|
|
2869
|
+
if (fs3.existsSync(flowJson)) {
|
|
2711
2870
|
readFlowFile(flowJson, group);
|
|
2712
2871
|
} else {
|
|
2713
2872
|
if (!group) {
|
|
@@ -2725,7 +2884,7 @@ function listFlows() {
|
|
|
2725
2884
|
function saveFlow(flow, outputPath, group) {
|
|
2726
2885
|
let flowPath;
|
|
2727
2886
|
if (outputPath) {
|
|
2728
|
-
flowPath =
|
|
2887
|
+
flowPath = path3.resolve(outputPath);
|
|
2729
2888
|
} else {
|
|
2730
2889
|
let bareKey = flow.key;
|
|
2731
2890
|
let resolvedGroup = group;
|
|
@@ -2735,21 +2894,21 @@ function saveFlow(flow, outputPath, group) {
|
|
|
2735
2894
|
resolvedGroup = resolvedGroup || parts.join("/");
|
|
2736
2895
|
flow.key = bareKey;
|
|
2737
2896
|
}
|
|
2738
|
-
const basePath = resolvedGroup ?
|
|
2739
|
-
const legacyPath =
|
|
2740
|
-
const folderPath =
|
|
2741
|
-
if (!resolvedGroup &&
|
|
2897
|
+
const basePath = resolvedGroup ? path3.resolve(FLOWS_DIR, resolvedGroup, bareKey) : path3.resolve(FLOWS_DIR, bareKey);
|
|
2898
|
+
const legacyPath = path3.resolve(FLOWS_DIR, `${bareKey}.flow.json`);
|
|
2899
|
+
const folderPath = path3.join(basePath, "flow.json");
|
|
2900
|
+
if (!resolvedGroup && fs3.existsSync(legacyPath) && !fs3.existsSync(folderPath)) {
|
|
2742
2901
|
flowPath = legacyPath;
|
|
2743
2902
|
} else {
|
|
2744
2903
|
flowPath = folderPath;
|
|
2745
2904
|
}
|
|
2746
2905
|
}
|
|
2747
|
-
const dir =
|
|
2906
|
+
const dir = path3.dirname(flowPath);
|
|
2748
2907
|
ensureDir(dir);
|
|
2749
|
-
if (
|
|
2750
|
-
ensureDir(
|
|
2908
|
+
if (path3.basename(flowPath) === "flow.json") {
|
|
2909
|
+
ensureDir(path3.join(dir, "lib"));
|
|
2751
2910
|
}
|
|
2752
|
-
|
|
2911
|
+
fs3.writeFileSync(flowPath, JSON.stringify(flow, null, 2) + "\n");
|
|
2753
2912
|
return flowPath;
|
|
2754
2913
|
}
|
|
2755
2914
|
|
|
@@ -2762,6 +2921,19 @@ export {
|
|
|
2762
2921
|
isActionAllowed,
|
|
2763
2922
|
buildActionKnowledgeWithGuidance,
|
|
2764
2923
|
validateActionInput,
|
|
2924
|
+
knowledgeCachePath,
|
|
2925
|
+
searchCachePath,
|
|
2926
|
+
readCache,
|
|
2927
|
+
writeCache,
|
|
2928
|
+
isFresh,
|
|
2929
|
+
getAge,
|
|
2930
|
+
buildCacheMeta,
|
|
2931
|
+
formatAge,
|
|
2932
|
+
listCacheEntries,
|
|
2933
|
+
clearAll,
|
|
2934
|
+
clearEntry,
|
|
2935
|
+
makeCacheEntry,
|
|
2936
|
+
resolveActionDetails,
|
|
2765
2937
|
FLOW_SCHEMA,
|
|
2766
2938
|
getStepTypeDescriptor,
|
|
2767
2939
|
getNestedStepsKeys,
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
|
-
getMemoryConfigOrDefault
|
|
2
|
+
getMemoryConfigOrDefault
|
|
3
|
+
} from "./chunk-77564KWS.js";
|
|
4
|
+
import {
|
|
3
5
|
getOpenAiApiKey,
|
|
4
6
|
readConfig
|
|
5
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-TVIZC7AC.js";
|
|
6
8
|
|
|
7
9
|
// src/lib/output.ts
|
|
8
10
|
import * as p from "@clack/prompts";
|
|
@@ -4,9 +4,11 @@ import {
|
|
|
4
4
|
embed,
|
|
5
5
|
getMemoryConfig,
|
|
6
6
|
getMemoryConfigOrDefault,
|
|
7
|
-
getOpenAiApiKey,
|
|
8
7
|
updateMemoryConfig
|
|
9
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-77564KWS.js";
|
|
9
|
+
import {
|
|
10
|
+
getOpenAiApiKey
|
|
11
|
+
} from "./chunk-TVIZC7AC.js";
|
|
10
12
|
|
|
11
13
|
// src/lib/memory/schema.ts
|
|
12
14
|
var SCHEMA_VERSION = "2.1.0";
|
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
isAgentMode,
|
|
4
4
|
json,
|
|
5
5
|
requireMemoryInit
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-KH4ERRJ5.js";
|
|
7
7
|
import {
|
|
8
8
|
getBackend
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-TGWQUBKA.js";
|
|
10
10
|
|
|
11
11
|
// src/commands/mem/sql.ts
|
|
12
12
|
async function memSqlCommand(sql) {
|