@withone/cli 1.44.1 → 1.45.0
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 +19 -3
- package/dist/chunk-77564KWS.js +211 -0
- 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-YGOS6KEC.js → chunk-UXKF6AEG.js} +254 -85
- 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-FQVTF36N.js} +2 -1
- package/dist/index.js +303 -375
- 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
package/dist/index.js
CHANGED
|
@@ -5,22 +5,35 @@ import {
|
|
|
5
5
|
OneApi,
|
|
6
6
|
TimeoutError,
|
|
7
7
|
buildActionKnowledgeWithGuidance,
|
|
8
|
+
buildCacheMeta,
|
|
9
|
+
clearAll,
|
|
10
|
+
clearEntry,
|
|
8
11
|
filterByPermissions,
|
|
9
12
|
flowRequiresBash,
|
|
13
|
+
formatAge,
|
|
10
14
|
generateFlowGuide,
|
|
15
|
+
getAge,
|
|
11
16
|
getNestedStepsKeys,
|
|
12
17
|
getStepTypeDescriptor,
|
|
13
18
|
isActionAllowed,
|
|
19
|
+
isFresh,
|
|
14
20
|
isMethodAllowed,
|
|
21
|
+
knowledgeCachePath,
|
|
22
|
+
listCacheEntries,
|
|
15
23
|
listFlows,
|
|
16
24
|
loadFlowWithMeta,
|
|
25
|
+
makeCacheEntry,
|
|
26
|
+
readCache,
|
|
27
|
+
resolveActionDetails,
|
|
17
28
|
resolveFlowPath,
|
|
18
29
|
saveFlow,
|
|
19
|
-
|
|
20
|
-
|
|
30
|
+
searchCachePath,
|
|
31
|
+
validateActionInput,
|
|
32
|
+
writeCache
|
|
33
|
+
} from "./chunk-UXKF6AEG.js";
|
|
21
34
|
import {
|
|
22
35
|
memSqlCommand
|
|
23
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-TLRJMJGU.js";
|
|
24
37
|
import {
|
|
25
38
|
countRecords,
|
|
26
39
|
deleteDatabase,
|
|
@@ -45,7 +58,7 @@ import {
|
|
|
45
58
|
upsertRecords,
|
|
46
59
|
writeDraftProfile,
|
|
47
60
|
writeProfile
|
|
48
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-Z4HKASJT.js";
|
|
49
62
|
import {
|
|
50
63
|
getByDotPath
|
|
51
64
|
} from "./chunk-44CV5IMX.js";
|
|
@@ -68,7 +81,7 @@ import {
|
|
|
68
81
|
semanticSearchUpgradeHint,
|
|
69
82
|
semanticSearchUpgradeLine,
|
|
70
83
|
setAgentMode
|
|
71
|
-
} from "./chunk-
|
|
84
|
+
} from "./chunk-KH4ERRJ5.js";
|
|
72
85
|
import {
|
|
73
86
|
SCHEMA_VERSION,
|
|
74
87
|
addRecord,
|
|
@@ -78,44 +91,45 @@ import {
|
|
|
78
91
|
listBackendPlugins,
|
|
79
92
|
loadBackendFromConfig,
|
|
80
93
|
upsertRecord
|
|
81
|
-
} from "./chunk-
|
|
94
|
+
} from "./chunk-TGWQUBKA.js";
|
|
82
95
|
import {
|
|
83
96
|
DEFAULT_MEMORY_CONFIG,
|
|
84
|
-
configExists,
|
|
85
97
|
defaultSearchableText,
|
|
86
98
|
embed,
|
|
99
|
+
getMemoryConfig,
|
|
100
|
+
getMemoryConfigOrDefault,
|
|
101
|
+
memoryConfigExists,
|
|
102
|
+
setOpenAiApiKey,
|
|
103
|
+
updateMemoryConfig
|
|
104
|
+
} from "./chunk-77564KWS.js";
|
|
105
|
+
import {
|
|
106
|
+
configExists,
|
|
87
107
|
ensureWhoAmI,
|
|
88
108
|
getAccessControl,
|
|
89
109
|
getAccessControlFromAllSources,
|
|
90
110
|
getApiBase,
|
|
91
111
|
getApiKey,
|
|
92
|
-
getCacheTtl,
|
|
93
112
|
getEnvFromApiKey,
|
|
94
113
|
getGlobalConfigPath,
|
|
95
|
-
getMemoryConfig,
|
|
96
|
-
getMemoryConfigOrDefault,
|
|
97
114
|
getOpenAiApiKey,
|
|
98
115
|
getProjectConfigPath,
|
|
99
116
|
getProjectRoot,
|
|
100
117
|
getWhoAmI,
|
|
101
118
|
globalConfigExists,
|
|
102
|
-
memoryConfigExists,
|
|
103
119
|
projectConfigExists,
|
|
104
120
|
readConfig,
|
|
105
121
|
readGlobalConfig,
|
|
106
122
|
readProjectConfig,
|
|
107
123
|
resolveConfig,
|
|
108
|
-
setOpenAiApiKey,
|
|
109
124
|
updateAccessControl,
|
|
110
125
|
updateApiBase,
|
|
111
|
-
updateMemoryConfig,
|
|
112
126
|
updateWhoAmI,
|
|
113
127
|
writeConfig
|
|
114
|
-
} from "./chunk-
|
|
128
|
+
} from "./chunk-TVIZC7AC.js";
|
|
115
129
|
|
|
116
130
|
// src/cli.ts
|
|
117
131
|
import { createRequire as createRequire2 } from "module";
|
|
118
|
-
import
|
|
132
|
+
import path11 from "path";
|
|
119
133
|
import { Command } from "commander";
|
|
120
134
|
|
|
121
135
|
// src/commands/init.ts
|
|
@@ -621,14 +635,17 @@ import { fileURLToPath } from "url";
|
|
|
621
635
|
// src/commands/update.ts
|
|
622
636
|
import { createRequire } from "module";
|
|
623
637
|
import { spawn } from "child_process";
|
|
624
|
-
import { readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
638
|
+
import { readFileSync, writeFileSync, mkdirSync, rmSync } from "fs";
|
|
625
639
|
import { homedir } from "os";
|
|
626
640
|
import { join } from "path";
|
|
627
641
|
var require2 = createRequire(import.meta.url);
|
|
628
642
|
var { version: currentVersion } = require2("../package.json");
|
|
629
|
-
var
|
|
643
|
+
var ONE_DIR = join(homedir(), ".one");
|
|
644
|
+
var CACHE_PATH = join(ONE_DIR, "update-check.json");
|
|
645
|
+
var LOCK_PATH = join(ONE_DIR, "auto-update.lock");
|
|
630
646
|
var CHECK_INTERVAL_MS = 4 * 60 * 60 * 1e3;
|
|
631
647
|
var AGE_GATE_MS = 30 * 60 * 1e3;
|
|
648
|
+
var LOCK_TTL_MS = 10 * 60 * 1e3;
|
|
632
649
|
async function fetchLatestVersionInfo() {
|
|
633
650
|
try {
|
|
634
651
|
const res = await fetch("https://registry.npmjs.org/@withone/cli");
|
|
@@ -641,14 +658,14 @@ async function fetchLatestVersionInfo() {
|
|
|
641
658
|
return null;
|
|
642
659
|
}
|
|
643
660
|
}
|
|
644
|
-
function
|
|
661
|
+
function readCache2() {
|
|
645
662
|
try {
|
|
646
663
|
return JSON.parse(readFileSync(CACHE_PATH, "utf8"));
|
|
647
664
|
} catch {
|
|
648
665
|
return null;
|
|
649
666
|
}
|
|
650
667
|
}
|
|
651
|
-
function
|
|
668
|
+
function writeCache2(latestVersion, publishedAt) {
|
|
652
669
|
try {
|
|
653
670
|
mkdirSync(join(homedir(), ".one"), { recursive: true });
|
|
654
671
|
writeFileSync(CACHE_PATH, JSON.stringify({ lastCheck: Date.now(), latestVersion, publishedAt }));
|
|
@@ -657,16 +674,16 @@ function writeCache(latestVersion, publishedAt) {
|
|
|
657
674
|
}
|
|
658
675
|
async function checkLatestVersion() {
|
|
659
676
|
const info = await fetchLatestVersionInfo();
|
|
660
|
-
if (info)
|
|
677
|
+
if (info) writeCache2(info.version, info.publishedAt);
|
|
661
678
|
return info?.version ?? null;
|
|
662
679
|
}
|
|
663
680
|
async function checkLatestVersionCached() {
|
|
664
|
-
const cache2 =
|
|
681
|
+
const cache2 = readCache2();
|
|
665
682
|
if (cache2 && Date.now() - cache2.lastCheck < CHECK_INTERVAL_MS) {
|
|
666
683
|
return { version: cache2.latestVersion, publishedAt: cache2.publishedAt ?? null };
|
|
667
684
|
}
|
|
668
685
|
const info = await fetchLatestVersionInfo();
|
|
669
|
-
if (info)
|
|
686
|
+
if (info) writeCache2(info.version, info.publishedAt);
|
|
670
687
|
return info;
|
|
671
688
|
}
|
|
672
689
|
function getCurrentVersion() {
|
|
@@ -725,16 +742,52 @@ function isNewerVersion(latest, current) {
|
|
|
725
742
|
if (lMin !== cMin) return lMin > cMin;
|
|
726
743
|
return lPat > cPat;
|
|
727
744
|
}
|
|
745
|
+
function isAutoUpdateDisabled() {
|
|
746
|
+
const v = process.env.ONE_NO_AUTO_UPDATE ?? process.env.ONE_DISABLE_AUTO_UPDATE;
|
|
747
|
+
return v === "1" || v === "true";
|
|
748
|
+
}
|
|
749
|
+
function acquireUpdateLock(targetVersion) {
|
|
750
|
+
try {
|
|
751
|
+
mkdirSync(ONE_DIR, { recursive: true });
|
|
752
|
+
} catch {
|
|
753
|
+
}
|
|
754
|
+
try {
|
|
755
|
+
const lock = JSON.parse(readFileSync(LOCK_PATH, "utf8"));
|
|
756
|
+
const startedAt = typeof lock.startedAt === "number" ? lock.startedAt : 0;
|
|
757
|
+
if (Date.now() - startedAt < LOCK_TTL_MS) return false;
|
|
758
|
+
rmSync(LOCK_PATH, { force: true });
|
|
759
|
+
} catch {
|
|
760
|
+
}
|
|
761
|
+
try {
|
|
762
|
+
writeFileSync(
|
|
763
|
+
LOCK_PATH,
|
|
764
|
+
JSON.stringify({ pid: process.pid, startedAt: Date.now(), targetVersion }),
|
|
765
|
+
{ flag: "wx" }
|
|
766
|
+
// fail if another invocation created it first
|
|
767
|
+
);
|
|
768
|
+
return true;
|
|
769
|
+
} catch {
|
|
770
|
+
return false;
|
|
771
|
+
}
|
|
772
|
+
}
|
|
728
773
|
function autoUpdate(targetVersion, publishedAt) {
|
|
774
|
+
if (isAutoUpdateDisabled()) return;
|
|
729
775
|
if (publishedAt) {
|
|
730
776
|
const age = Date.now() - new Date(publishedAt).getTime();
|
|
731
777
|
if (age < AGE_GATE_MS) return;
|
|
732
778
|
}
|
|
779
|
+
if (!acquireUpdateLock(targetVersion)) return;
|
|
733
780
|
const child = spawn("npm", ["install", "-g", `@withone/cli@${targetVersion}`], {
|
|
734
781
|
detached: true,
|
|
735
782
|
stdio: "ignore",
|
|
736
783
|
shell: true
|
|
737
784
|
});
|
|
785
|
+
child.on("error", () => {
|
|
786
|
+
try {
|
|
787
|
+
rmSync(LOCK_PATH, { force: true });
|
|
788
|
+
} catch {
|
|
789
|
+
}
|
|
790
|
+
});
|
|
738
791
|
child.unref();
|
|
739
792
|
}
|
|
740
793
|
|
|
@@ -2301,123 +2354,6 @@ async function platformsCommand(options) {
|
|
|
2301
2354
|
// src/commands/actions.ts
|
|
2302
2355
|
import * as p6 from "@clack/prompts";
|
|
2303
2356
|
import pc6 from "picocolors";
|
|
2304
|
-
|
|
2305
|
-
// src/lib/cache.ts
|
|
2306
|
-
import fs4 from "fs";
|
|
2307
|
-
import path4 from "path";
|
|
2308
|
-
import os4 from "os";
|
|
2309
|
-
var CACHE_BASE = path4.join(os4.homedir(), ".one", "cache");
|
|
2310
|
-
var KNOWLEDGE_DIR = path4.join(CACHE_BASE, "knowledge");
|
|
2311
|
-
var SEARCH_DIR = path4.join(CACHE_BASE, "search");
|
|
2312
|
-
function sanitizeFilename(input) {
|
|
2313
|
-
return input.replace(/[^a-zA-Z0-9_\-\.]/g, "_");
|
|
2314
|
-
}
|
|
2315
|
-
function knowledgeCachePath(actionId) {
|
|
2316
|
-
return path4.join(KNOWLEDGE_DIR, `${sanitizeFilename(actionId)}.json`);
|
|
2317
|
-
}
|
|
2318
|
-
function searchCachePath(platform, query, type) {
|
|
2319
|
-
const key = `${platform}_${sanitizeFilename(query)}_${type || "knowledge"}`;
|
|
2320
|
-
return path4.join(SEARCH_DIR, `${key}.json`);
|
|
2321
|
-
}
|
|
2322
|
-
function readCache2(filePath) {
|
|
2323
|
-
try {
|
|
2324
|
-
const content = fs4.readFileSync(filePath, "utf-8");
|
|
2325
|
-
return JSON.parse(content);
|
|
2326
|
-
} catch {
|
|
2327
|
-
return null;
|
|
2328
|
-
}
|
|
2329
|
-
}
|
|
2330
|
-
function writeCache2(filePath, entry) {
|
|
2331
|
-
try {
|
|
2332
|
-
const dir = path4.dirname(filePath);
|
|
2333
|
-
fs4.mkdirSync(dir, { recursive: true });
|
|
2334
|
-
fs4.writeFileSync(filePath, JSON.stringify(entry, null, 2));
|
|
2335
|
-
} catch {
|
|
2336
|
-
}
|
|
2337
|
-
}
|
|
2338
|
-
function isFresh(entry) {
|
|
2339
|
-
const cachedTime = new Date(entry.cachedAt).getTime();
|
|
2340
|
-
const now = Date.now();
|
|
2341
|
-
return now - cachedTime < entry.ttl * 1e3;
|
|
2342
|
-
}
|
|
2343
|
-
function getAge(entry) {
|
|
2344
|
-
return Math.floor((Date.now() - new Date(entry.cachedAt).getTime()) / 1e3);
|
|
2345
|
-
}
|
|
2346
|
-
function buildCacheMeta(entry, hit) {
|
|
2347
|
-
if (!entry) {
|
|
2348
|
-
return { hit: false, age: 0, fresh: false };
|
|
2349
|
-
}
|
|
2350
|
-
return {
|
|
2351
|
-
hit,
|
|
2352
|
-
age: getAge(entry),
|
|
2353
|
-
fresh: isFresh(entry)
|
|
2354
|
-
};
|
|
2355
|
-
}
|
|
2356
|
-
function formatAge(seconds) {
|
|
2357
|
-
if (seconds < 60) return `${seconds}s`;
|
|
2358
|
-
if (seconds < 3600) return `${Math.floor(seconds / 60)}m`;
|
|
2359
|
-
if (seconds < 86400) {
|
|
2360
|
-
const h2 = Math.floor(seconds / 3600);
|
|
2361
|
-
const m = Math.floor(seconds % 3600 / 60);
|
|
2362
|
-
return m > 0 ? `${h2}h ${m}m` : `${h2}h`;
|
|
2363
|
-
}
|
|
2364
|
-
const d = Math.floor(seconds / 86400);
|
|
2365
|
-
const h = Math.floor(seconds % 86400 / 3600);
|
|
2366
|
-
return h > 0 ? `${d}d ${h}h` : `${d}d`;
|
|
2367
|
-
}
|
|
2368
|
-
function listCacheEntries() {
|
|
2369
|
-
const entries = [];
|
|
2370
|
-
for (const [dir, type] of [[KNOWLEDGE_DIR, "knowledge"], [SEARCH_DIR, "search"]]) {
|
|
2371
|
-
try {
|
|
2372
|
-
const files = fs4.readdirSync(dir);
|
|
2373
|
-
for (const file of files) {
|
|
2374
|
-
if (!file.endsWith(".json")) continue;
|
|
2375
|
-
const filePath = path4.join(dir, file);
|
|
2376
|
-
const entry = readCache2(filePath);
|
|
2377
|
-
if (entry) {
|
|
2378
|
-
entries.push({ type, filePath, entry });
|
|
2379
|
-
}
|
|
2380
|
-
}
|
|
2381
|
-
} catch {
|
|
2382
|
-
}
|
|
2383
|
-
}
|
|
2384
|
-
return entries;
|
|
2385
|
-
}
|
|
2386
|
-
function clearAll() {
|
|
2387
|
-
let count = 0;
|
|
2388
|
-
for (const dir of [KNOWLEDGE_DIR, SEARCH_DIR]) {
|
|
2389
|
-
try {
|
|
2390
|
-
const files = fs4.readdirSync(dir);
|
|
2391
|
-
for (const file of files) {
|
|
2392
|
-
fs4.unlinkSync(path4.join(dir, file));
|
|
2393
|
-
count++;
|
|
2394
|
-
}
|
|
2395
|
-
fs4.rmdirSync(dir);
|
|
2396
|
-
} catch {
|
|
2397
|
-
}
|
|
2398
|
-
}
|
|
2399
|
-
return count;
|
|
2400
|
-
}
|
|
2401
|
-
function clearEntry(actionId) {
|
|
2402
|
-
const filePath = knowledgeCachePath(actionId);
|
|
2403
|
-
try {
|
|
2404
|
-
fs4.unlinkSync(filePath);
|
|
2405
|
-
return true;
|
|
2406
|
-
} catch {
|
|
2407
|
-
return false;
|
|
2408
|
-
}
|
|
2409
|
-
}
|
|
2410
|
-
function makeCacheEntry(key, data, etag) {
|
|
2411
|
-
return {
|
|
2412
|
-
key,
|
|
2413
|
-
etag,
|
|
2414
|
-
cachedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2415
|
-
ttl: getCacheTtl(),
|
|
2416
|
-
data
|
|
2417
|
-
};
|
|
2418
|
-
}
|
|
2419
|
-
|
|
2420
|
-
// src/commands/actions.ts
|
|
2421
2357
|
function getConfig() {
|
|
2422
2358
|
const apiKey = getApiKey();
|
|
2423
2359
|
if (!apiKey) {
|
|
@@ -2447,7 +2383,7 @@ async function actionsSearchCommand(platform, query, options) {
|
|
|
2447
2383
|
const agentType = knowledgeAgent ? "knowledge" : options.type || "execute";
|
|
2448
2384
|
const useCache = options.cache !== false;
|
|
2449
2385
|
const cachePath = searchCachePath(platform, query, agentType || "knowledge");
|
|
2450
|
-
const cached = useCache ?
|
|
2386
|
+
const cached = useCache ? readCache(cachePath) : null;
|
|
2451
2387
|
let cleanedActions;
|
|
2452
2388
|
let cacheHit = false;
|
|
2453
2389
|
if (cached && isFresh(cached)) {
|
|
@@ -2463,7 +2399,7 @@ async function actionsSearchCommand(platform, query, options) {
|
|
|
2463
2399
|
);
|
|
2464
2400
|
if (result.status === 304 && cached) {
|
|
2465
2401
|
cached.cachedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2466
|
-
|
|
2402
|
+
writeCache(cachePath, cached);
|
|
2467
2403
|
cleanedActions = cached.data.actions;
|
|
2468
2404
|
cacheHit = true;
|
|
2469
2405
|
} else {
|
|
@@ -2476,7 +2412,7 @@ async function actionsSearchCommand(platform, query, options) {
|
|
|
2476
2412
|
method: action.method,
|
|
2477
2413
|
path: action.path
|
|
2478
2414
|
}));
|
|
2479
|
-
|
|
2415
|
+
writeCache(cachePath, makeCacheEntry(
|
|
2480
2416
|
`${platform}_${query}_${agentType || "knowledge"}`,
|
|
2481
2417
|
{ actions: cleanedActions },
|
|
2482
2418
|
result.etag
|
|
@@ -2500,7 +2436,7 @@ async function actionsSearchCommand(platform, query, options) {
|
|
|
2500
2436
|
if (cacheHit && cached) {
|
|
2501
2437
|
response._cache = buildCacheMeta(cached, true);
|
|
2502
2438
|
} else {
|
|
2503
|
-
const freshEntry =
|
|
2439
|
+
const freshEntry = readCache(cachePath);
|
|
2504
2440
|
response._cache = buildCacheMeta(freshEntry, false);
|
|
2505
2441
|
}
|
|
2506
2442
|
json(response);
|
|
@@ -2560,7 +2496,7 @@ Execute: ${pc6.cyan(`one actions execute ${platform} <actionId> <connectionK
|
|
|
2560
2496
|
async function actionsKnowledgeCommand(platform, actionId, options) {
|
|
2561
2497
|
const cachePath = knowledgeCachePath(actionId);
|
|
2562
2498
|
if (options.cacheStatus) {
|
|
2563
|
-
const entry =
|
|
2499
|
+
const entry = readCache(cachePath);
|
|
2564
2500
|
if (!entry) {
|
|
2565
2501
|
json({
|
|
2566
2502
|
cached: false,
|
|
@@ -2607,44 +2543,13 @@ async function actionsKnowledgeCommand(platform, actionId, options) {
|
|
|
2607
2543
|
const spinner5 = createSpinner();
|
|
2608
2544
|
spinner5.start(`Loading knowledge for action ${pc6.dim(actionId)}...`);
|
|
2609
2545
|
try {
|
|
2610
|
-
const
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
cacheHit = true;
|
|
2618
|
-
} else {
|
|
2619
|
-
try {
|
|
2620
|
-
const result = await api.getActionKnowledgeWithMeta(
|
|
2621
|
-
actionId,
|
|
2622
|
-
cached?.etag ?? void 0
|
|
2623
|
-
);
|
|
2624
|
-
if (result.status === 304 && cached) {
|
|
2625
|
-
cached.cachedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2626
|
-
writeCache2(cachePath, cached);
|
|
2627
|
-
knowledgeData = cached.data;
|
|
2628
|
-
cacheHit = true;
|
|
2629
|
-
} else {
|
|
2630
|
-
knowledgeData = result.data;
|
|
2631
|
-
const newEntry = makeCacheEntry(actionId, knowledgeData, result.etag);
|
|
2632
|
-
writeCache2(cachePath, newEntry);
|
|
2633
|
-
cacheEntry = newEntry;
|
|
2634
|
-
}
|
|
2635
|
-
} catch (fetchError) {
|
|
2636
|
-
if (cached) {
|
|
2637
|
-
process.stderr.write(
|
|
2638
|
-
`Warning: serving cached knowledge (network unavailable, cached ${formatAge(getAge(cached))} ago)
|
|
2639
|
-
`
|
|
2640
|
-
);
|
|
2641
|
-
knowledgeData = cached.data;
|
|
2642
|
-
cacheHit = true;
|
|
2643
|
-
} else {
|
|
2644
|
-
throw fetchError;
|
|
2645
|
-
}
|
|
2646
|
-
}
|
|
2647
|
-
}
|
|
2546
|
+
const { details, cacheHit, entry } = await resolveActionDetails(api, actionId, {
|
|
2547
|
+
useCache: options.cache !== false
|
|
2548
|
+
});
|
|
2549
|
+
const knowledgeData = {
|
|
2550
|
+
knowledge: details.knowledge || "No knowledge was found",
|
|
2551
|
+
method: details.method || "No method was found"
|
|
2552
|
+
};
|
|
2648
2553
|
const knowledgeWithGuidance = buildActionKnowledgeWithGuidance(
|
|
2649
2554
|
knowledgeData.knowledge,
|
|
2650
2555
|
knowledgeData.method,
|
|
@@ -2655,7 +2560,7 @@ async function actionsKnowledgeCommand(platform, actionId, options) {
|
|
|
2655
2560
|
const response = {
|
|
2656
2561
|
knowledge: knowledgeWithGuidance,
|
|
2657
2562
|
method: knowledgeData.method,
|
|
2658
|
-
_cache: buildCacheMeta(
|
|
2563
|
+
_cache: buildCacheMeta(entry, cacheHit)
|
|
2659
2564
|
};
|
|
2660
2565
|
json(response);
|
|
2661
2566
|
return;
|
|
@@ -2693,7 +2598,7 @@ async function actionsExecuteCommand(platform, actionId, connectionKey, options)
|
|
|
2693
2598
|
const spinner5 = createSpinner();
|
|
2694
2599
|
spinner5.start("Loading action details...");
|
|
2695
2600
|
try {
|
|
2696
|
-
const actionDetails = await api.
|
|
2601
|
+
const { details: actionDetails, cacheHit: preflightCacheHit } = await resolveActionDetails(api, actionId, { useCache: options.cache !== false });
|
|
2697
2602
|
if (!isMethodAllowed(actionDetails.method, permissions)) {
|
|
2698
2603
|
spinner5.stop("Permission denied");
|
|
2699
2604
|
error(
|
|
@@ -2739,7 +2644,8 @@ async function actionsExecuteCommand(platform, actionId, connectionKey, options)
|
|
|
2739
2644
|
url: actionDetails.path
|
|
2740
2645
|
},
|
|
2741
2646
|
response: mockResponse,
|
|
2742
|
-
...mockResponse === null ? { message: "No example output available for this action" } : {}
|
|
2647
|
+
...mockResponse === null ? { message: "No example output available for this action" } : {},
|
|
2648
|
+
_preflight: { cache: preflightCacheHit ? "hit" : "miss" }
|
|
2743
2649
|
});
|
|
2744
2650
|
return;
|
|
2745
2651
|
}
|
|
@@ -2780,7 +2686,8 @@ async function actionsExecuteCommand(platform, actionId, connectionKey, options)
|
|
|
2780
2686
|
headers: options.dryRun ? result.requestConfig.headers : void 0,
|
|
2781
2687
|
data: options.dryRun ? result.requestConfig.data : void 0
|
|
2782
2688
|
},
|
|
2783
|
-
response: options.dryRun ? void 0 : result.responseData
|
|
2689
|
+
response: options.dryRun ? void 0 : result.responseData,
|
|
2690
|
+
_preflight: { cache: preflightCacheHit ? "hit" : "miss" }
|
|
2784
2691
|
});
|
|
2785
2692
|
return;
|
|
2786
2693
|
}
|
|
@@ -2824,7 +2731,7 @@ function parseParallelSegments() {
|
|
|
2824
2731
|
error('Could not locate "actions execute" in argv');
|
|
2825
2732
|
}
|
|
2826
2733
|
const raw = argv.slice(execIdx + 1);
|
|
2827
|
-
const flags = { dryRun: false, mock: false, skipValidation: false, maxConcurrency: 5 };
|
|
2734
|
+
const flags = { dryRun: false, mock: false, skipValidation: false, maxConcurrency: 5, useCache: true };
|
|
2828
2735
|
const cleaned = [];
|
|
2829
2736
|
for (let i = 0; i < raw.length; i++) {
|
|
2830
2737
|
const t = raw[i];
|
|
@@ -2841,6 +2748,10 @@ function parseParallelSegments() {
|
|
|
2841
2748
|
flags.skipValidation = true;
|
|
2842
2749
|
continue;
|
|
2843
2750
|
}
|
|
2751
|
+
if (t === "--no-cache") {
|
|
2752
|
+
flags.useCache = false;
|
|
2753
|
+
continue;
|
|
2754
|
+
}
|
|
2844
2755
|
if (t === "--max-concurrency") {
|
|
2845
2756
|
flags.maxConcurrency = parseInt(raw[++i], 10) || 5;
|
|
2846
2757
|
continue;
|
|
@@ -2930,8 +2841,11 @@ async function actionsExecuteParallelCommand() {
|
|
|
2930
2841
|
segErrors.push(`Connection key "${seg.connectionKey}" is not allowed`);
|
|
2931
2842
|
}
|
|
2932
2843
|
let actionDetails;
|
|
2844
|
+
let preflightCacheHit = false;
|
|
2933
2845
|
try {
|
|
2934
|
-
|
|
2846
|
+
const resolved = await resolveActionDetails(api, seg.actionId, { useCache: flags.useCache });
|
|
2847
|
+
actionDetails = resolved.details;
|
|
2848
|
+
preflightCacheHit = resolved.cacheHit;
|
|
2935
2849
|
} catch (err) {
|
|
2936
2850
|
segErrors.push(`Action not found: ${err instanceof Error ? err.message : String(err)}`);
|
|
2937
2851
|
}
|
|
@@ -2977,7 +2891,7 @@ async function actionsExecuteParallelCommand() {
|
|
|
2977
2891
|
if (segErrors.length > 0) {
|
|
2978
2892
|
errors.push({ segment: i + 1, label, messages: segErrors });
|
|
2979
2893
|
} else if (actionDetails) {
|
|
2980
|
-
prepared.push({ segment: seg, index: i, actionDetails, data, pathVariables, queryParams, headers });
|
|
2894
|
+
prepared.push({ segment: seg, index: i, actionDetails, preflightCacheHit, data, pathVariables, queryParams, headers });
|
|
2981
2895
|
}
|
|
2982
2896
|
}
|
|
2983
2897
|
if (errors.length > 0) {
|
|
@@ -3015,7 +2929,8 @@ async function actionsExecuteParallelCommand() {
|
|
|
3015
2929
|
durationMs: Date.now() - start,
|
|
3016
2930
|
mock: true,
|
|
3017
2931
|
request: { method: action.actionDetails.method, url: action.actionDetails.path },
|
|
3018
|
-
response: mockResponse
|
|
2932
|
+
response: mockResponse,
|
|
2933
|
+
_preflight: { cache: action.preflightCacheHit ? "hit" : "miss" }
|
|
3019
2934
|
};
|
|
3020
2935
|
}
|
|
3021
2936
|
const result = await api.executePassthroughRequest({
|
|
@@ -3042,7 +2957,8 @@ async function actionsExecuteParallelCommand() {
|
|
|
3042
2957
|
url: result.requestConfig.url,
|
|
3043
2958
|
...flags.dryRun ? { headers: result.requestConfig.headers, data: result.requestConfig.data } : {}
|
|
3044
2959
|
},
|
|
3045
|
-
response: flags.dryRun ? void 0 : result.responseData
|
|
2960
|
+
response: flags.dryRun ? void 0 : result.responseData,
|
|
2961
|
+
_preflight: { cache: action.preflightCacheHit ? "hit" : "miss" }
|
|
3046
2962
|
};
|
|
3047
2963
|
})
|
|
3048
2964
|
);
|
|
@@ -3123,8 +3039,8 @@ function colorMethod(method) {
|
|
|
3123
3039
|
import pc7 from "picocolors";
|
|
3124
3040
|
|
|
3125
3041
|
// src/lib/flow-validator.ts
|
|
3126
|
-
import
|
|
3127
|
-
import
|
|
3042
|
+
import fs4 from "fs";
|
|
3043
|
+
import path4 from "path";
|
|
3128
3044
|
import { spawnSync } from "child_process";
|
|
3129
3045
|
function validateFlowSchema(flow2) {
|
|
3130
3046
|
const errors = [];
|
|
@@ -3189,32 +3105,32 @@ function validateStepsArray(steps, pathPrefix, errors) {
|
|
|
3189
3105
|
const validTypes = FLOW_SCHEMA.stepTypes.map((st) => st.type);
|
|
3190
3106
|
for (let i = 0; i < steps.length; i++) {
|
|
3191
3107
|
const step = steps[i];
|
|
3192
|
-
const
|
|
3108
|
+
const path12 = `${pathPrefix}[${i}]`;
|
|
3193
3109
|
if (!step || typeof step !== "object" || Array.isArray(step)) {
|
|
3194
|
-
errors.push({ path:
|
|
3110
|
+
errors.push({ path: path12, message: "Step must be an object" });
|
|
3195
3111
|
continue;
|
|
3196
3112
|
}
|
|
3197
3113
|
const s = step;
|
|
3198
3114
|
if (!s.id || typeof s.id !== "string") {
|
|
3199
|
-
errors.push({ path: `${
|
|
3115
|
+
errors.push({ path: `${path12}.id`, message: 'Step must have a string "id"' });
|
|
3200
3116
|
}
|
|
3201
3117
|
if (!s.name || typeof s.name !== "string") {
|
|
3202
|
-
errors.push({ path: `${
|
|
3118
|
+
errors.push({ path: `${path12}.name`, message: 'Step must have a string "name"' });
|
|
3203
3119
|
}
|
|
3204
3120
|
if (!s.type || !validTypes.includes(s.type)) {
|
|
3205
|
-
errors.push({ path: `${
|
|
3121
|
+
errors.push({ path: `${path12}.type`, message: `Step type must be one of: ${validTypes.join(", ")}` });
|
|
3206
3122
|
continue;
|
|
3207
3123
|
}
|
|
3208
3124
|
if (s.requires !== void 0) {
|
|
3209
3125
|
if (!Array.isArray(s.requires)) {
|
|
3210
|
-
errors.push({ path: `${
|
|
3126
|
+
errors.push({ path: `${path12}.requires`, message: '"requires" must be an array of selector strings (e.g. ["$.steps.foo.output.bar"])' });
|
|
3211
3127
|
} else {
|
|
3212
3128
|
for (let r = 0; r < s.requires.length; r++) {
|
|
3213
3129
|
const sel = s.requires[r];
|
|
3214
3130
|
if (typeof sel !== "string") {
|
|
3215
|
-
errors.push({ path: `${
|
|
3131
|
+
errors.push({ path: `${path12}.requires[${r}]`, message: '"requires" entry must be a selector string' });
|
|
3216
3132
|
} else if (!sel.startsWith("$.")) {
|
|
3217
|
-
errors.push({ path: `${
|
|
3133
|
+
errors.push({ path: `${path12}.requires[${r}]`, message: `"requires" entry "${sel}" must be a selector starting with "$." (e.g. "$.steps.foo.output.bar")` });
|
|
3218
3134
|
}
|
|
3219
3135
|
}
|
|
3220
3136
|
}
|
|
@@ -3222,7 +3138,7 @@ function validateStepsArray(steps, pathPrefix, errors) {
|
|
|
3222
3138
|
if (s.onError && typeof s.onError === "object") {
|
|
3223
3139
|
const oe = s.onError;
|
|
3224
3140
|
if (!FLOW_SCHEMA.errorStrategies.includes(oe.strategy)) {
|
|
3225
|
-
errors.push({ path: `${
|
|
3141
|
+
errors.push({ path: `${path12}.onError.strategy`, message: `Error strategy must be one of: ${FLOW_SCHEMA.errorStrategies.join(", ")}` });
|
|
3226
3142
|
}
|
|
3227
3143
|
}
|
|
3228
3144
|
const descriptor = getStepTypeDescriptor(s.type);
|
|
@@ -3232,14 +3148,14 @@ function validateStepsArray(steps, pathPrefix, errors) {
|
|
|
3232
3148
|
if (!configObj || typeof configObj !== "object") {
|
|
3233
3149
|
const hint = detectFlatConfigHint(s, descriptor);
|
|
3234
3150
|
errors.push({
|
|
3235
|
-
path: `${
|
|
3151
|
+
path: `${path12}.${configKey}`,
|
|
3236
3152
|
message: `${capitalize(descriptor.type)} step must have a "${configKey}" config object${hint}`
|
|
3237
3153
|
});
|
|
3238
3154
|
continue;
|
|
3239
3155
|
}
|
|
3240
3156
|
const config2 = configObj;
|
|
3241
3157
|
for (const [fieldName, fd] of Object.entries(descriptor.fields)) {
|
|
3242
|
-
const fieldPath = `${
|
|
3158
|
+
const fieldPath = `${path12}.${configKey}.${fieldName}`;
|
|
3243
3159
|
const value = config2[fieldName];
|
|
3244
3160
|
if (fd.required && (value === void 0 || value === null || value === "")) {
|
|
3245
3161
|
errors.push({ path: fieldPath, message: `${capitalize(descriptor.type)} must have ${fd.type === "string" ? "a string" : fd.type === "array" ? "a" : "a"} "${fieldName}"` });
|
|
@@ -3272,30 +3188,30 @@ function validateStepsArray(steps, pathPrefix, errors) {
|
|
|
3272
3188
|
}
|
|
3273
3189
|
}
|
|
3274
3190
|
if (descriptor.type === "action") {
|
|
3275
|
-
validateConnectionForm(config2, `${
|
|
3191
|
+
validateConnectionForm(config2, `${path12}.${configKey}`, errors);
|
|
3276
3192
|
}
|
|
3277
3193
|
if (descriptor.type === "code") {
|
|
3278
3194
|
const hasSource = typeof config2.source === "string" && config2.source.length > 0;
|
|
3279
3195
|
const hasModule = typeof config2.module === "string" && config2.module.length > 0;
|
|
3280
3196
|
if (!hasSource && !hasModule) {
|
|
3281
|
-
errors.push({ path: `${
|
|
3197
|
+
errors.push({ path: `${path12}.${configKey}`, message: 'Code step must define either "source" (inline JS) or "module" (path to .mjs file)' });
|
|
3282
3198
|
} else if (hasSource && hasModule) {
|
|
3283
|
-
errors.push({ path: `${
|
|
3199
|
+
errors.push({ path: `${path12}.${configKey}`, message: 'Code step cannot define both "source" and "module" \u2014 pick one' });
|
|
3284
3200
|
}
|
|
3285
3201
|
if (hasModule) {
|
|
3286
3202
|
const m = config2.module;
|
|
3287
3203
|
if (m.startsWith("/") || /^[a-zA-Z]:[\\/]/.test(m)) {
|
|
3288
|
-
errors.push({ path: `${
|
|
3204
|
+
errors.push({ path: `${path12}.${configKey}.module`, message: "Code module path must be relative to the flow folder (no absolute paths)" });
|
|
3289
3205
|
} else if (m.split(/[\\/]/).includes("..")) {
|
|
3290
|
-
errors.push({ path: `${
|
|
3206
|
+
errors.push({ path: `${path12}.${configKey}.module`, message: 'Code module path must not escape the flow folder ("..")' });
|
|
3291
3207
|
} else if (!m.endsWith(".mjs")) {
|
|
3292
|
-
errors.push({ path: `${
|
|
3208
|
+
errors.push({ path: `${path12}.${configKey}.module`, message: "Code module must be a .mjs file" });
|
|
3293
3209
|
}
|
|
3294
3210
|
}
|
|
3295
3211
|
if (hasSource) {
|
|
3296
3212
|
const syntaxError = checkCodeSourceSyntax(config2.source);
|
|
3297
3213
|
if (syntaxError) {
|
|
3298
|
-
errors.push({ path: `${
|
|
3214
|
+
errors.push({ path: `${path12}.${configKey}.source`, message: `Syntax error in code step: ${syntaxError}` });
|
|
3299
3215
|
}
|
|
3300
3216
|
}
|
|
3301
3217
|
}
|
|
@@ -3367,16 +3283,16 @@ function validateStepIds(flow2) {
|
|
|
3367
3283
|
function collectIds(steps, pathPrefix) {
|
|
3368
3284
|
for (let i = 0; i < steps.length; i++) {
|
|
3369
3285
|
const step = steps[i];
|
|
3370
|
-
const
|
|
3286
|
+
const path12 = `${pathPrefix}[${i}]`;
|
|
3371
3287
|
if (seen.has(step.id)) {
|
|
3372
|
-
errors.push({ path: `${
|
|
3288
|
+
errors.push({ path: `${path12}.id`, message: `Duplicate step ID: "${step.id}"` });
|
|
3373
3289
|
} else {
|
|
3374
3290
|
seen.add(step.id);
|
|
3375
3291
|
}
|
|
3376
3292
|
for (const { configKey, fieldName } of nestedKeys) {
|
|
3377
3293
|
const config2 = step[configKey];
|
|
3378
3294
|
if (config2 && Array.isArray(config2[fieldName])) {
|
|
3379
|
-
collectIds(config2[fieldName], `${
|
|
3295
|
+
collectIds(config2[fieldName], `${path12}.${configKey}.${fieldName}`);
|
|
3380
3296
|
}
|
|
3381
3297
|
}
|
|
3382
3298
|
}
|
|
@@ -3424,7 +3340,7 @@ function validateSelectorReferences(flow2) {
|
|
|
3424
3340
|
}
|
|
3425
3341
|
return selectors;
|
|
3426
3342
|
}
|
|
3427
|
-
function checkSelectors(selectors,
|
|
3343
|
+
function checkSelectors(selectors, path12, precedingStepIds) {
|
|
3428
3344
|
for (const selector of selectors) {
|
|
3429
3345
|
const parts = selector.split(".");
|
|
3430
3346
|
if (parts.length < 3) continue;
|
|
@@ -3432,15 +3348,15 @@ function validateSelectorReferences(flow2) {
|
|
|
3432
3348
|
if (root === "input") {
|
|
3433
3349
|
const inputName = parts[2];
|
|
3434
3350
|
if (!inputNames.has(inputName)) {
|
|
3435
|
-
errors.push({ path:
|
|
3351
|
+
errors.push({ path: path12, message: `Selector "${selector}" references undefined input "${inputName}"` });
|
|
3436
3352
|
}
|
|
3437
3353
|
} else if (root === "steps") {
|
|
3438
3354
|
const stepId = parts[2].replace(/[\[\]]/g, "").split(/[\[\]]/)[0];
|
|
3439
3355
|
if (!allStepIds.has(stepId)) {
|
|
3440
|
-
errors.push({ path:
|
|
3356
|
+
errors.push({ path: path12, message: `Selector "${selector}" references undefined step "${stepId}"` });
|
|
3441
3357
|
} else if (precedingStepIds && !precedingStepIds.has(stepId)) {
|
|
3442
3358
|
errors.push({
|
|
3443
|
-
path:
|
|
3359
|
+
path: path12,
|
|
3444
3360
|
message: `Selector "${selector}" references step "${stepId}" which is declared after the current step. Steps execute in declaration order, so this will always resolve to undefined at runtime \u2014 move the dependency earlier in the steps array.`
|
|
3445
3361
|
});
|
|
3446
3362
|
}
|
|
@@ -3448,20 +3364,20 @@ function validateSelectorReferences(flow2) {
|
|
|
3448
3364
|
}
|
|
3449
3365
|
}
|
|
3450
3366
|
const EXPRESSION_FIELDS = /* @__PURE__ */ new Set(["condition.expression", "while.condition"]);
|
|
3451
|
-
function checkOperatorsInSelectorField(value,
|
|
3367
|
+
function checkOperatorsInSelectorField(value, path12) {
|
|
3452
3368
|
if (typeof value === "string" && value.startsWith("$.")) {
|
|
3453
3369
|
if (value.includes("||")) {
|
|
3454
|
-
errors.push({ path:
|
|
3370
|
+
errors.push({ path: path12, message: `Selector "${value}" contains unsupported operator "||". Selectors in data fields use dot-path resolution, not JS evaluation. Use the "default" field on the input definition instead, or use a "code" step for complex expressions.` });
|
|
3455
3371
|
} else if (value.includes("&&")) {
|
|
3456
|
-
errors.push({ path:
|
|
3372
|
+
errors.push({ path: path12, message: `Selector "${value}" contains unsupported operator "&&". Selectors in data fields use dot-path resolution, not JS evaluation. Use a "condition" step or "code" step for complex expressions.` });
|
|
3457
3373
|
}
|
|
3458
3374
|
} else if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
3459
3375
|
for (const [k, v] of Object.entries(value)) {
|
|
3460
|
-
checkOperatorsInSelectorField(v, `${
|
|
3376
|
+
checkOperatorsInSelectorField(v, `${path12}.${k}`);
|
|
3461
3377
|
}
|
|
3462
3378
|
} else if (Array.isArray(value)) {
|
|
3463
3379
|
for (let i = 0; i < value.length; i++) {
|
|
3464
|
-
checkOperatorsInSelectorField(value[i], `${
|
|
3380
|
+
checkOperatorsInSelectorField(value[i], `${path12}[${i}]`);
|
|
3465
3381
|
}
|
|
3466
3382
|
}
|
|
3467
3383
|
}
|
|
@@ -3529,10 +3445,10 @@ var VALID_OUTPUT_SCHEMA_TYPES = /* @__PURE__ */ new Set(["string", "number", "bo
|
|
|
3529
3445
|
function isOutputSchemaObject(v) {
|
|
3530
3446
|
return !!v && typeof v === "object" && !Array.isArray(v);
|
|
3531
3447
|
}
|
|
3532
|
-
function walkOutputSchema(schema,
|
|
3448
|
+
function walkOutputSchema(schema, path12) {
|
|
3533
3449
|
let current = schema;
|
|
3534
|
-
for (let i = 0; i <
|
|
3535
|
-
const seg =
|
|
3450
|
+
for (let i = 0; i < path12.length; i++) {
|
|
3451
|
+
const seg = path12[i];
|
|
3536
3452
|
if (typeof current === "string") {
|
|
3537
3453
|
return current === "unknown" || current === "object" || current === "array" ? "opaque" : "opaque";
|
|
3538
3454
|
}
|
|
@@ -3683,8 +3599,8 @@ function validateCodeModules(flow2, rootDir) {
|
|
|
3683
3599
|
const stepPath = `${pathPrefix}[${i}]`;
|
|
3684
3600
|
if (step.type === "code" && step.code?.module) {
|
|
3685
3601
|
const m = step.code.module;
|
|
3686
|
-
const abs =
|
|
3687
|
-
if (!
|
|
3602
|
+
const abs = path4.resolve(rootDir, m);
|
|
3603
|
+
if (!fs4.existsSync(abs)) {
|
|
3688
3604
|
errors.push({
|
|
3689
3605
|
path: `${stepPath}.code.module`,
|
|
3690
3606
|
message: `Code module "${m}" not found at ${abs}`
|
|
@@ -3713,8 +3629,8 @@ function validateCodeModules(flow2, rootDir) {
|
|
|
3713
3629
|
}
|
|
3714
3630
|
|
|
3715
3631
|
// src/commands/flow.ts
|
|
3716
|
-
import
|
|
3717
|
-
import
|
|
3632
|
+
import fs5 from "fs";
|
|
3633
|
+
import path5 from "path";
|
|
3718
3634
|
function getConfig2() {
|
|
3719
3635
|
const apiKey = getApiKey();
|
|
3720
3636
|
if (!apiKey) {
|
|
@@ -3772,7 +3688,7 @@ async function flowCreateCommand(key, options) {
|
|
|
3772
3688
|
if (raw.startsWith("@")) {
|
|
3773
3689
|
const filePath = raw.slice(1);
|
|
3774
3690
|
try {
|
|
3775
|
-
raw =
|
|
3691
|
+
raw = fs5.readFileSync(filePath, "utf-8");
|
|
3776
3692
|
} catch (err) {
|
|
3777
3693
|
error(`Cannot read file "${filePath}": ${err.message}`);
|
|
3778
3694
|
}
|
|
@@ -4002,9 +3918,9 @@ async function flowValidateCommand(keyOrPath) {
|
|
|
4002
3918
|
rootDir = loaded.rootDir;
|
|
4003
3919
|
} catch {
|
|
4004
3920
|
const flowPath = resolveFlowPath(keyOrPath);
|
|
4005
|
-
const content =
|
|
3921
|
+
const content = fs5.readFileSync(flowPath, "utf-8");
|
|
4006
3922
|
flowData = JSON.parse(content);
|
|
4007
|
-
rootDir =
|
|
3923
|
+
rootDir = path5.dirname(flowPath);
|
|
4008
3924
|
}
|
|
4009
3925
|
} catch (err) {
|
|
4010
3926
|
spinner5.stop("Validation failed");
|
|
@@ -4827,11 +4743,11 @@ function handleId(response, config2, records) {
|
|
|
4827
4743
|
}
|
|
4828
4744
|
|
|
4829
4745
|
// src/lib/memory/sync/state.ts
|
|
4830
|
-
import
|
|
4831
|
-
import
|
|
4832
|
-
var SYNC_DIR =
|
|
4833
|
-
var STATE_DIR =
|
|
4834
|
-
var LEGACY_SINGLE_FILE =
|
|
4746
|
+
import fs6 from "fs";
|
|
4747
|
+
import path6 from "path";
|
|
4748
|
+
var SYNC_DIR = path6.join(".one", "sync");
|
|
4749
|
+
var STATE_DIR = path6.join(SYNC_DIR, "state");
|
|
4750
|
+
var LEGACY_SINGLE_FILE = path6.join(SYNC_DIR, "sync_state.json");
|
|
4835
4751
|
var legacyMigrationDone = false;
|
|
4836
4752
|
function rowToState(row) {
|
|
4837
4753
|
return {
|
|
@@ -4859,9 +4775,9 @@ function stateToRow(platform, model, state, lastError) {
|
|
|
4859
4775
|
async function migrateLegacyOnce() {
|
|
4860
4776
|
if (legacyMigrationDone) return;
|
|
4861
4777
|
legacyMigrationDone = true;
|
|
4862
|
-
if (
|
|
4778
|
+
if (fs6.existsSync(LEGACY_SINGLE_FILE)) {
|
|
4863
4779
|
try {
|
|
4864
|
-
const raw =
|
|
4780
|
+
const raw = fs6.readFileSync(LEGACY_SINGLE_FILE, "utf-8");
|
|
4865
4781
|
const legacy = JSON.parse(raw);
|
|
4866
4782
|
const backend = await getBackend();
|
|
4867
4783
|
for (const [platform, models] of Object.entries(legacy)) {
|
|
@@ -4871,32 +4787,32 @@ async function migrateLegacyOnce() {
|
|
|
4871
4787
|
await backend.setSyncState(stateToRow(platform, model, modelState));
|
|
4872
4788
|
}
|
|
4873
4789
|
}
|
|
4874
|
-
|
|
4790
|
+
fs6.unlinkSync(LEGACY_SINGLE_FILE);
|
|
4875
4791
|
} catch {
|
|
4876
4792
|
try {
|
|
4877
|
-
|
|
4793
|
+
fs6.unlinkSync(LEGACY_SINGLE_FILE);
|
|
4878
4794
|
} catch {
|
|
4879
4795
|
}
|
|
4880
4796
|
}
|
|
4881
4797
|
}
|
|
4882
|
-
if (
|
|
4798
|
+
if (fs6.existsSync(STATE_DIR)) {
|
|
4883
4799
|
try {
|
|
4884
4800
|
const backend = await getBackend();
|
|
4885
|
-
const platforms =
|
|
4801
|
+
const platforms = fs6.readdirSync(STATE_DIR);
|
|
4886
4802
|
for (const platform of platforms) {
|
|
4887
|
-
const platformDir =
|
|
4803
|
+
const platformDir = path6.join(STATE_DIR, platform);
|
|
4888
4804
|
let entries;
|
|
4889
4805
|
try {
|
|
4890
|
-
entries =
|
|
4806
|
+
entries = fs6.readdirSync(platformDir);
|
|
4891
4807
|
} catch {
|
|
4892
4808
|
continue;
|
|
4893
4809
|
}
|
|
4894
4810
|
for (const entry of entries) {
|
|
4895
4811
|
if (!entry.endsWith(".json")) continue;
|
|
4896
4812
|
const model = entry.slice(0, -".json".length);
|
|
4897
|
-
const filePath =
|
|
4813
|
+
const filePath = path6.join(platformDir, entry);
|
|
4898
4814
|
try {
|
|
4899
|
-
const raw =
|
|
4815
|
+
const raw = fs6.readFileSync(filePath, "utf-8");
|
|
4900
4816
|
const modelState = JSON.parse(raw);
|
|
4901
4817
|
const existing = await backend.getSyncState(platform, model);
|
|
4902
4818
|
if (!existing) {
|
|
@@ -4906,7 +4822,7 @@ async function migrateLegacyOnce() {
|
|
|
4906
4822
|
}
|
|
4907
4823
|
}
|
|
4908
4824
|
}
|
|
4909
|
-
|
|
4825
|
+
fs6.rmSync(STATE_DIR, { recursive: true, force: true });
|
|
4910
4826
|
} catch {
|
|
4911
4827
|
}
|
|
4912
4828
|
}
|
|
@@ -4950,12 +4866,12 @@ async function removeModelState(platform, model) {
|
|
|
4950
4866
|
}
|
|
4951
4867
|
|
|
4952
4868
|
// src/lib/memory/sync/lock.ts
|
|
4953
|
-
import
|
|
4954
|
-
import
|
|
4955
|
-
var LOCK_DIR_REL =
|
|
4869
|
+
import fs7 from "fs";
|
|
4870
|
+
import path7 from "path";
|
|
4871
|
+
var LOCK_DIR_REL = path7.join(".one", "sync", "locks");
|
|
4956
4872
|
var STALE_MS = 30 * 60 * 1e3;
|
|
4957
4873
|
function lockPath(platform, model) {
|
|
4958
|
-
return
|
|
4874
|
+
return path7.join(LOCK_DIR_REL, `${platform}_${model}`);
|
|
4959
4875
|
}
|
|
4960
4876
|
function isProcessAlive(pid) {
|
|
4961
4877
|
try {
|
|
@@ -4972,15 +4888,15 @@ var SyncLockError = class extends Error {
|
|
|
4972
4888
|
}
|
|
4973
4889
|
};
|
|
4974
4890
|
function acquireSyncLock(platform, model) {
|
|
4975
|
-
|
|
4891
|
+
fs7.mkdirSync(LOCK_DIR_REL, { recursive: true });
|
|
4976
4892
|
const dir = lockPath(platform, model);
|
|
4977
|
-
const pidFile =
|
|
4893
|
+
const pidFile = path7.join(dir, "pid");
|
|
4978
4894
|
try {
|
|
4979
|
-
|
|
4895
|
+
fs7.mkdirSync(dir);
|
|
4980
4896
|
} catch (err) {
|
|
4981
4897
|
const stat = (() => {
|
|
4982
4898
|
try {
|
|
4983
|
-
return
|
|
4899
|
+
return fs7.statSync(dir);
|
|
4984
4900
|
} catch {
|
|
4985
4901
|
return null;
|
|
4986
4902
|
}
|
|
@@ -4989,7 +4905,7 @@ function acquireSyncLock(platform, model) {
|
|
|
4989
4905
|
const age = Date.now() - stat.mtimeMs;
|
|
4990
4906
|
let ownerPid = null;
|
|
4991
4907
|
try {
|
|
4992
|
-
const raw =
|
|
4908
|
+
const raw = fs7.readFileSync(pidFile, "utf-8");
|
|
4993
4909
|
const parsed = parseInt(raw.trim(), 10);
|
|
4994
4910
|
if (!isNaN(parsed)) ownerPid = parsed;
|
|
4995
4911
|
} catch {
|
|
@@ -4998,8 +4914,8 @@ function acquireSyncLock(platform, model) {
|
|
|
4998
4914
|
const veryOld = age > STALE_MS;
|
|
4999
4915
|
if (ownerDead || veryOld) {
|
|
5000
4916
|
try {
|
|
5001
|
-
|
|
5002
|
-
|
|
4917
|
+
fs7.rmSync(dir, { recursive: true, force: true });
|
|
4918
|
+
fs7.mkdirSync(dir);
|
|
5003
4919
|
} catch {
|
|
5004
4920
|
throw new SyncLockError(
|
|
5005
4921
|
`Could not take over stale lock at ${dir}. Remove it manually if no sync is running.`
|
|
@@ -5016,13 +4932,13 @@ function acquireSyncLock(platform, model) {
|
|
|
5016
4932
|
}
|
|
5017
4933
|
}
|
|
5018
4934
|
try {
|
|
5019
|
-
|
|
4935
|
+
fs7.writeFileSync(pidFile, String(process.pid));
|
|
5020
4936
|
} catch {
|
|
5021
4937
|
}
|
|
5022
4938
|
return {
|
|
5023
4939
|
release() {
|
|
5024
4940
|
try {
|
|
5025
|
-
|
|
4941
|
+
fs7.rmSync(dir, { recursive: true, force: true });
|
|
5026
4942
|
} catch {
|
|
5027
4943
|
}
|
|
5028
4944
|
}
|
|
@@ -5031,9 +4947,9 @@ function acquireSyncLock(platform, model) {
|
|
|
5031
4947
|
|
|
5032
4948
|
// src/lib/memory/sync/hooks.ts
|
|
5033
4949
|
import { spawn as spawn2 } from "child_process";
|
|
5034
|
-
import
|
|
5035
|
-
import
|
|
5036
|
-
var EVENTS_DIR =
|
|
4950
|
+
import fs8 from "fs";
|
|
4951
|
+
import path8 from "path";
|
|
4952
|
+
var EVENTS_DIR = path8.join(".one", "sync", "events");
|
|
5037
4953
|
function classifyRecords(db, model, records, idField, tableExists2) {
|
|
5038
4954
|
if (!tableExists2 || records.length === 0) {
|
|
5039
4955
|
return { inserts: records, updates: [] };
|
|
@@ -5079,10 +4995,10 @@ async function fireHooks(hookCommand, events) {
|
|
|
5079
4995
|
function appendEventLog(events) {
|
|
5080
4996
|
if (events.length === 0) return;
|
|
5081
4997
|
const { platform, model } = events[0];
|
|
5082
|
-
|
|
5083
|
-
const logPath =
|
|
4998
|
+
fs8.mkdirSync(EVENTS_DIR, { recursive: true });
|
|
4999
|
+
const logPath = path8.join(EVENTS_DIR, `${platform}_${model}.jsonl`);
|
|
5084
5000
|
const lines = events.map((e) => JSON.stringify(e)).join("\n") + "\n";
|
|
5085
|
-
|
|
5001
|
+
fs8.appendFileSync(logPath, lines);
|
|
5086
5002
|
}
|
|
5087
5003
|
function runShellHook(command, events) {
|
|
5088
5004
|
return new Promise((resolve) => {
|
|
@@ -5105,10 +5021,10 @@ function runShellHook(command, events) {
|
|
|
5105
5021
|
}
|
|
5106
5022
|
|
|
5107
5023
|
// src/lib/memory/sync/mem-writer.ts
|
|
5108
|
-
function resolveWildcardPath(root,
|
|
5109
|
-
const segments =
|
|
5024
|
+
function resolveWildcardPath(root, path12) {
|
|
5025
|
+
const segments = path12.split("[]");
|
|
5110
5026
|
if (segments.length === 1) {
|
|
5111
|
-
return [getByDotPath(root,
|
|
5027
|
+
return [getByDotPath(root, path12)];
|
|
5112
5028
|
}
|
|
5113
5029
|
const recurse = (value, idx) => {
|
|
5114
5030
|
if (value === null || value === void 0) return [];
|
|
@@ -5134,8 +5050,8 @@ function resolveWildcardPath(root, path13) {
|
|
|
5134
5050
|
function extractSearchableFromPaths(record, paths) {
|
|
5135
5051
|
const parts = [];
|
|
5136
5052
|
const perPath = [];
|
|
5137
|
-
for (const
|
|
5138
|
-
const values = resolveWildcardPath(record,
|
|
5053
|
+
for (const path12 of paths) {
|
|
5054
|
+
const values = resolveWildcardPath(record, path12);
|
|
5139
5055
|
const collected = [];
|
|
5140
5056
|
const absorb = (v) => {
|
|
5141
5057
|
if (v === null || v === void 0) return;
|
|
@@ -5151,9 +5067,9 @@ function extractSearchableFromPaths(record, paths) {
|
|
|
5151
5067
|
for (const v of values) absorb(v);
|
|
5152
5068
|
if (collected.length > 0) {
|
|
5153
5069
|
parts.push(...collected);
|
|
5154
|
-
perPath.push({ path:
|
|
5070
|
+
perPath.push({ path: path12, found: true, sample: collected.join(" ").slice(0, 80) });
|
|
5155
5071
|
} else {
|
|
5156
|
-
perPath.push({ path:
|
|
5072
|
+
perPath.push({ path: path12, found: false, sample: "" });
|
|
5157
5073
|
}
|
|
5158
5074
|
}
|
|
5159
5075
|
const text5 = parts.join(" ").replace(/\s+/g, " ").trim();
|
|
@@ -5332,8 +5248,8 @@ function sleep(ms) {
|
|
|
5332
5248
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
5333
5249
|
}
|
|
5334
5250
|
function interpolate(template, record) {
|
|
5335
|
-
return template.replace(/\{?\{(\w+(?:\.\w+)*)\}\}?/g, (_,
|
|
5336
|
-
const parts =
|
|
5251
|
+
return template.replace(/\{?\{(\w+(?:\.\w+)*)\}\}?/g, (_, path12) => {
|
|
5252
|
+
const parts = path12.split(".");
|
|
5337
5253
|
let value = record;
|
|
5338
5254
|
for (const part of parts) {
|
|
5339
5255
|
if (typeof value !== "object" || value === null) return "";
|
|
@@ -5361,8 +5277,8 @@ function deepMerge(target, source) {
|
|
|
5361
5277
|
}
|
|
5362
5278
|
return result;
|
|
5363
5279
|
}
|
|
5364
|
-
function getByDotPath2(obj,
|
|
5365
|
-
const parts =
|
|
5280
|
+
function getByDotPath2(obj, path12) {
|
|
5281
|
+
const parts = path12.split(".");
|
|
5366
5282
|
let current = obj;
|
|
5367
5283
|
for (const part of parts) {
|
|
5368
5284
|
if (current === null || current === void 0 || typeof current !== "object") return void 0;
|
|
@@ -5371,8 +5287,8 @@ function getByDotPath2(obj, path13) {
|
|
|
5371
5287
|
return current;
|
|
5372
5288
|
}
|
|
5373
5289
|
function stripExcludedFields(obj, paths) {
|
|
5374
|
-
for (const
|
|
5375
|
-
stripOnePath(obj,
|
|
5290
|
+
for (const path12 of paths) {
|
|
5291
|
+
stripOnePath(obj, path12.replace(/\[\]/g, ".*").split("."));
|
|
5376
5292
|
}
|
|
5377
5293
|
}
|
|
5378
5294
|
function stripOnePath(obj, parts) {
|
|
@@ -5441,7 +5357,7 @@ async function enrichPhase(api, db, config2, model, idField, connectionKey, plat
|
|
|
5441
5357
|
}
|
|
5442
5358
|
let detailAction;
|
|
5443
5359
|
try {
|
|
5444
|
-
detailAction = await api
|
|
5360
|
+
detailAction = (await resolveActionDetails(api, config2.actionId)).details;
|
|
5445
5361
|
} catch (err) {
|
|
5446
5362
|
throw new Error(
|
|
5447
5363
|
`Enrich: could not load action ${config2.actionId}: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -5702,8 +5618,8 @@ function sleep2(ms) {
|
|
|
5702
5618
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
5703
5619
|
}
|
|
5704
5620
|
function stripFields(record, paths) {
|
|
5705
|
-
for (const
|
|
5706
|
-
stripOnePath2(record,
|
|
5621
|
+
for (const path12 of paths) {
|
|
5622
|
+
stripOnePath2(record, path12.split("."));
|
|
5707
5623
|
}
|
|
5708
5624
|
}
|
|
5709
5625
|
function stripOnePath2(obj, parts) {
|
|
@@ -5793,7 +5709,7 @@ async function syncModel(api, profile, options) {
|
|
|
5793
5709
|
updateModelState(platform, model, { status: "failed", pagesProcessed, lastCursor }),
|
|
5794
5710
|
(async () => {
|
|
5795
5711
|
try {
|
|
5796
|
-
const { getBackend: getBackend2 } = await import("./runtime-
|
|
5712
|
+
const { getBackend: getBackend2 } = await import("./runtime-3NDWRLXL.js");
|
|
5797
5713
|
const backend = await getBackend2();
|
|
5798
5714
|
await Promise.race([
|
|
5799
5715
|
backend.close(),
|
|
@@ -5870,7 +5786,7 @@ async function syncModel(api, profile, options) {
|
|
|
5870
5786
|
queryParams[param] = dateValue;
|
|
5871
5787
|
}
|
|
5872
5788
|
}
|
|
5873
|
-
const actionDetails = await api
|
|
5789
|
+
const { details: actionDetails } = await resolveActionDetails(api, profile.actionId);
|
|
5874
5790
|
if (actionDetails.tags?.includes("custom")) {
|
|
5875
5791
|
throw new Error(
|
|
5876
5792
|
`Sync does not support custom actions. Action ${profile.actionId} is tagged "custom". Use a passthrough action \u2014 run 'one actions search ${platform} "${model}"' to find one, or compose a flow that chains passthrough calls if the logic is complex.`
|
|
@@ -6148,7 +6064,7 @@ async function syncModel(api, profile, options) {
|
|
|
6148
6064
|
db.exec(`DROP TABLE IF EXISTS _seen_ids`);
|
|
6149
6065
|
}
|
|
6150
6066
|
if (options.toMemory !== false) {
|
|
6151
|
-
const backend = await (await import("./runtime-
|
|
6067
|
+
const backend = await (await import("./runtime-3NDWRLXL.js")).getBackend();
|
|
6152
6068
|
const type = `${platform}/${model}`;
|
|
6153
6069
|
const existing = await backend.listKeysByType(type);
|
|
6154
6070
|
const sourcePrefix = `${type}:`;
|
|
@@ -6228,7 +6144,7 @@ async function syncModel(api, profile, options) {
|
|
|
6228
6144
|
let statusCounts;
|
|
6229
6145
|
if (options.toMemory !== false) {
|
|
6230
6146
|
try {
|
|
6231
|
-
const backend = await (await import("./runtime-
|
|
6147
|
+
const backend = await (await import("./runtime-3NDWRLXL.js")).getBackend();
|
|
6232
6148
|
const typeName = `${platform}/${model}`;
|
|
6233
6149
|
const [active, archived] = await Promise.all([
|
|
6234
6150
|
backend.count(typeName, { status: "active" }),
|
|
@@ -6724,20 +6640,20 @@ function inferProfileFromKnowledge(knowledge, modelName, platform) {
|
|
|
6724
6640
|
|
|
6725
6641
|
// src/lib/memory/sync/schedule.ts
|
|
6726
6642
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
6727
|
-
import fs11 from "fs";
|
|
6728
|
-
import os6 from "os";
|
|
6729
|
-
import path11 from "path";
|
|
6730
|
-
|
|
6731
|
-
// src/lib/memory/sync/schedule-registry.ts
|
|
6732
6643
|
import fs10 from "fs";
|
|
6733
6644
|
import os5 from "os";
|
|
6734
6645
|
import path10 from "path";
|
|
6735
|
-
|
|
6736
|
-
|
|
6646
|
+
|
|
6647
|
+
// src/lib/memory/sync/schedule-registry.ts
|
|
6648
|
+
import fs9 from "fs";
|
|
6649
|
+
import os4 from "os";
|
|
6650
|
+
import path9 from "path";
|
|
6651
|
+
var REGISTRY_DIR = path9.join(os4.homedir(), ".one", "sync");
|
|
6652
|
+
var REGISTRY_FILE = path9.join(REGISTRY_DIR, "schedules.json");
|
|
6737
6653
|
function readRaw() {
|
|
6738
6654
|
try {
|
|
6739
|
-
if (!
|
|
6740
|
-
const raw =
|
|
6655
|
+
if (!fs9.existsSync(REGISTRY_FILE)) return { schedules: [] };
|
|
6656
|
+
const raw = fs9.readFileSync(REGISTRY_FILE, "utf-8");
|
|
6741
6657
|
const parsed = JSON.parse(raw);
|
|
6742
6658
|
if (!parsed || !Array.isArray(parsed.schedules)) return { schedules: [] };
|
|
6743
6659
|
return parsed;
|
|
@@ -6746,13 +6662,13 @@ function readRaw() {
|
|
|
6746
6662
|
}
|
|
6747
6663
|
}
|
|
6748
6664
|
function writeRaw(file) {
|
|
6749
|
-
|
|
6665
|
+
fs9.mkdirSync(REGISTRY_DIR, { recursive: true });
|
|
6750
6666
|
const tmp = REGISTRY_FILE + ".tmp";
|
|
6751
|
-
|
|
6752
|
-
|
|
6667
|
+
fs9.writeFileSync(tmp, JSON.stringify(file, null, 2));
|
|
6668
|
+
fs9.renameSync(tmp, REGISTRY_FILE);
|
|
6753
6669
|
}
|
|
6754
6670
|
function makeScheduleId(platform, cwd) {
|
|
6755
|
-
const slug =
|
|
6671
|
+
const slug = path9.basename(cwd).replace(/[^a-zA-Z0-9_-]/g, "-").toLowerCase();
|
|
6756
6672
|
return `${platform}-${slug}`;
|
|
6757
6673
|
}
|
|
6758
6674
|
function listRegistered() {
|
|
@@ -6786,7 +6702,7 @@ function removeRegistered(id) {
|
|
|
6786
6702
|
|
|
6787
6703
|
// src/lib/memory/sync/schedule.ts
|
|
6788
6704
|
var MARKER = "# one-sync";
|
|
6789
|
-
var LOG_DIR_REL =
|
|
6705
|
+
var LOG_DIR_REL = path10.join(".one", "sync", "logs");
|
|
6790
6706
|
function durationToCron(every) {
|
|
6791
6707
|
const match = every.match(/^(\d+)([mhd])$/);
|
|
6792
6708
|
if (!match) return null;
|
|
@@ -6819,13 +6735,13 @@ function cronExprToDuration(expr) {
|
|
|
6819
6735
|
return null;
|
|
6820
6736
|
}
|
|
6821
6737
|
function isWindows() {
|
|
6822
|
-
return
|
|
6738
|
+
return os5.platform() === "win32";
|
|
6823
6739
|
}
|
|
6824
6740
|
function resolveOneBinary() {
|
|
6825
6741
|
try {
|
|
6826
6742
|
const entry = process.argv[1];
|
|
6827
|
-
if (entry &&
|
|
6828
|
-
return
|
|
6743
|
+
if (entry && fs10.existsSync(entry)) {
|
|
6744
|
+
return fs10.realpathSync(entry);
|
|
6829
6745
|
}
|
|
6830
6746
|
} catch {
|
|
6831
6747
|
}
|
|
@@ -6903,7 +6819,7 @@ function migrateLegacyCronEntries() {
|
|
|
6903
6819
|
const modelsMatch = command.match(/--models\s+(\S+)/);
|
|
6904
6820
|
const models = modelsMatch ? modelsMatch[1].split(",") : void 0;
|
|
6905
6821
|
const logMatch = command.match(/>>\s+"([^"]+)"/);
|
|
6906
|
-
const logFile = logMatch ? logMatch[1] :
|
|
6822
|
+
const logFile = logMatch ? logMatch[1] : path10.resolve(cwd, LOG_DIR_REL, `${platform}.log`);
|
|
6907
6823
|
const id = makeScheduleId(platform, cwd);
|
|
6908
6824
|
if (registeredIds.has(id)) continue;
|
|
6909
6825
|
upsertRegistered({
|
|
@@ -6937,9 +6853,9 @@ function addSchedule(opts) {
|
|
|
6937
6853
|
const cwd = process.cwd();
|
|
6938
6854
|
const id = makeScheduleId(opts.platform, cwd);
|
|
6939
6855
|
const replaced = getRegistered(id) !== void 0;
|
|
6940
|
-
const logDir =
|
|
6941
|
-
|
|
6942
|
-
const logFile =
|
|
6856
|
+
const logDir = path10.join(cwd, LOG_DIR_REL);
|
|
6857
|
+
fs10.mkdirSync(logDir, { recursive: true });
|
|
6858
|
+
const logFile = path10.join(logDir, `${opts.platform}.log`);
|
|
6943
6859
|
const entry = {
|
|
6944
6860
|
id,
|
|
6945
6861
|
platform: opts.platform,
|
|
@@ -6993,15 +6909,15 @@ function removeSchedule(idOrPlatform, options) {
|
|
|
6993
6909
|
function scheduleStatus() {
|
|
6994
6910
|
const entries = listSchedules();
|
|
6995
6911
|
return entries.map((entry) => {
|
|
6996
|
-
const logExists =
|
|
6997
|
-
const logSize = logExists ?
|
|
6912
|
+
const logExists = fs10.existsSync(entry.logFile);
|
|
6913
|
+
const logSize = logExists ? fs10.statSync(entry.logFile).size : 0;
|
|
6998
6914
|
let logTail = [];
|
|
6999
6915
|
let lastRunAt = null;
|
|
7000
6916
|
if (logExists) {
|
|
7001
6917
|
try {
|
|
7002
|
-
lastRunAt =
|
|
6918
|
+
lastRunAt = fs10.statSync(entry.logFile).mtime.toISOString();
|
|
7003
6919
|
if (logSize > 0) {
|
|
7004
|
-
const content =
|
|
6920
|
+
const content = fs10.readFileSync(entry.logFile, "utf-8");
|
|
7005
6921
|
logTail = content.trim().split("\n").slice(-10);
|
|
7006
6922
|
}
|
|
7007
6923
|
} catch {
|
|
@@ -7009,8 +6925,8 @@ function scheduleStatus() {
|
|
|
7009
6925
|
}
|
|
7010
6926
|
let drift = "ok";
|
|
7011
6927
|
if (!entry.cronInstalled) drift = "missing-cron";
|
|
7012
|
-
else if (!
|
|
7013
|
-
else if (!
|
|
6928
|
+
else if (!fs10.existsSync(entry.nodeBin)) drift = "stale-node-bin";
|
|
6929
|
+
else if (!fs10.existsSync(entry.cliBin)) drift = "stale-cli-bin";
|
|
7014
6930
|
return { entry, logExists, logSize, logTail, lastRunAt, drift };
|
|
7015
6931
|
});
|
|
7016
6932
|
}
|
|
@@ -7283,11 +7199,11 @@ function isNoise(s) {
|
|
|
7283
7199
|
if (/^-?\d+(\.\d+)?([eE][-+]?\d+)?$/.test(s)) return true;
|
|
7284
7200
|
return false;
|
|
7285
7201
|
}
|
|
7286
|
-
function recordSample(stats,
|
|
7287
|
-
let s = stats.get(
|
|
7202
|
+
function recordSample(stats, path12, value, jsType, recordIndex, totalSamples) {
|
|
7203
|
+
let s = stats.get(path12);
|
|
7288
7204
|
if (!s) {
|
|
7289
7205
|
s = {
|
|
7290
|
-
path:
|
|
7206
|
+
path: path12,
|
|
7291
7207
|
total: totalSamples,
|
|
7292
7208
|
recordIndices: /* @__PURE__ */ new Set(),
|
|
7293
7209
|
lenSum: 0,
|
|
@@ -7296,7 +7212,7 @@ function recordSample(stats, path13, value, jsType, recordIndex, totalSamples) {
|
|
|
7296
7212
|
primaryType: jsType,
|
|
7297
7213
|
examples: []
|
|
7298
7214
|
};
|
|
7299
|
-
stats.set(
|
|
7215
|
+
stats.set(path12, s);
|
|
7300
7216
|
}
|
|
7301
7217
|
s.recordIndices.add(recordIndex);
|
|
7302
7218
|
s.lenSum += value.length;
|
|
@@ -7305,28 +7221,28 @@ function recordSample(stats, path13, value, jsType, recordIndex, totalSamples) {
|
|
|
7305
7221
|
if (s.primaryType !== jsType) s.primaryType = "mixed";
|
|
7306
7222
|
if (s.examples.length < 3 && value.length < 200) s.examples.push(value);
|
|
7307
7223
|
}
|
|
7308
|
-
function walkRecord(record,
|
|
7224
|
+
function walkRecord(record, path12, stats, recordIndex, totalSamples) {
|
|
7309
7225
|
if (record === null || record === void 0) return;
|
|
7310
7226
|
if (typeof record === "string") {
|
|
7311
7227
|
const trimmed = record.trim();
|
|
7312
|
-
if (trimmed) recordSample(stats,
|
|
7228
|
+
if (trimmed) recordSample(stats, path12, trimmed, "string", recordIndex, totalSamples);
|
|
7313
7229
|
return;
|
|
7314
7230
|
}
|
|
7315
7231
|
if (typeof record === "number" || typeof record === "boolean") {
|
|
7316
7232
|
const str = String(record);
|
|
7317
7233
|
const kind = typeof record === "number" ? "number" : "boolean";
|
|
7318
|
-
if (str) recordSample(stats,
|
|
7234
|
+
if (str) recordSample(stats, path12, str, kind, recordIndex, totalSamples);
|
|
7319
7235
|
return;
|
|
7320
7236
|
}
|
|
7321
7237
|
if (Array.isArray(record)) {
|
|
7322
|
-
const childPath =
|
|
7238
|
+
const childPath = path12 ? `${path12}[]` : "[]";
|
|
7323
7239
|
for (const item of record) walkRecord(item, childPath, stats, recordIndex, totalSamples);
|
|
7324
7240
|
return;
|
|
7325
7241
|
}
|
|
7326
7242
|
if (typeof record === "object") {
|
|
7327
7243
|
for (const [key, value] of Object.entries(record)) {
|
|
7328
7244
|
if (key.startsWith("_")) continue;
|
|
7329
|
-
const childPath =
|
|
7245
|
+
const childPath = path12 ? `${path12}.${key}` : key;
|
|
7330
7246
|
walkRecord(value, childPath, stats, recordIndex, totalSamples);
|
|
7331
7247
|
}
|
|
7332
7248
|
}
|
|
@@ -7535,8 +7451,8 @@ async function syncInitCommand(platform, model, options) {
|
|
|
7535
7451
|
}
|
|
7536
7452
|
if (actionId && !builtin) {
|
|
7537
7453
|
try {
|
|
7538
|
-
const
|
|
7539
|
-
inferred = inferProfileFromKnowledge(
|
|
7454
|
+
const { details } = await resolveActionDetails(api, actionId);
|
|
7455
|
+
inferred = inferProfileFromKnowledge(details.knowledge, model, platform);
|
|
7540
7456
|
if (inferred.pagination) template.pagination = inferred.pagination;
|
|
7541
7457
|
if (inferred.resultsPath) template.resultsPath = inferred.resultsPath;
|
|
7542
7458
|
if (inferred.idField) template.idField = inferred.idField;
|
|
@@ -7732,7 +7648,7 @@ function buildSearchablePreview(profile, samples) {
|
|
|
7732
7648
|
const first = samples[0];
|
|
7733
7649
|
const paths = getSearchablePaths(profile);
|
|
7734
7650
|
if (paths) {
|
|
7735
|
-
const perPathAgg = paths.map((
|
|
7651
|
+
const perPathAgg = paths.map((path12) => ({ path: path12, hits: 0, total: samples.length, sample: "" }));
|
|
7736
7652
|
for (const record of samples) {
|
|
7737
7653
|
const { paths: perPath } = extractSearchableFromPaths(record, paths);
|
|
7738
7654
|
perPath.forEach((p10, i) => {
|
|
@@ -7861,7 +7777,7 @@ ${result.total} results`);
|
|
|
7861
7777
|
}
|
|
7862
7778
|
}
|
|
7863
7779
|
async function syncSqlCommand(platformModel, sql) {
|
|
7864
|
-
const { syncSqlCommand: runSyncSql } = await import("./sql-
|
|
7780
|
+
const { syncSqlCommand: runSyncSql } = await import("./sql-ZABEXIXW.js");
|
|
7865
7781
|
await runSyncSql(platformModel, sql);
|
|
7866
7782
|
}
|
|
7867
7783
|
async function syncDeleteCommand(platformModel, options) {
|
|
@@ -7939,7 +7855,7 @@ async function syncDeleteCommand(platformModel, options) {
|
|
|
7939
7855
|
async function maybeAutoMigrateLegacy(platform, models) {
|
|
7940
7856
|
const dbSize = getDatabaseSize(platform);
|
|
7941
7857
|
if (!dbSize || dbSize === "0 B") return;
|
|
7942
|
-
const { getBackend: getBackend2 } = await import("./runtime-
|
|
7858
|
+
const { getBackend: getBackend2 } = await import("./runtime-3NDWRLXL.js");
|
|
7943
7859
|
const backend = await getBackend2();
|
|
7944
7860
|
let memoryHasData = false;
|
|
7945
7861
|
for (const model of models) {
|
|
@@ -7955,7 +7871,7 @@ async function maybeAutoMigrateLegacy(platform, models) {
|
|
|
7955
7871
|
` detected legacy .one/sync/data/${platform}.db (${dbSize}) \u2014 auto-migrating into memory before sync.
|
|
7956
7872
|
`
|
|
7957
7873
|
);
|
|
7958
|
-
const { memMigrateCommand: memMigrateCommand3 } = await import("./migrate-
|
|
7874
|
+
const { memMigrateCommand: memMigrateCommand3 } = await import("./migrate-VV3VOXWJ.js");
|
|
7959
7875
|
await memMigrateCommand3({ platform, yes: true });
|
|
7960
7876
|
return;
|
|
7961
7877
|
}
|
|
@@ -7964,7 +7880,7 @@ async function maybeAutoMigrateLegacy(platform, models) {
|
|
|
7964
7880
|
initialValue: true
|
|
7965
7881
|
});
|
|
7966
7882
|
if (p7.isCancel(shouldMigrate) || !shouldMigrate) return;
|
|
7967
|
-
const { memMigrateCommand: memMigrateCommand2 } = await import("./migrate-
|
|
7883
|
+
const { memMigrateCommand: memMigrateCommand2 } = await import("./migrate-VV3VOXWJ.js");
|
|
7968
7884
|
await memMigrateCommand2({ platform, yes: true });
|
|
7969
7885
|
}
|
|
7970
7886
|
async function syncSuggestSearchableCommand(platformModel, options = {}) {
|
|
@@ -8025,7 +7941,7 @@ async function syncSuggestSearchableCommand(platformModel, options = {}) {
|
|
|
8025
7941
|
async function syncListCommand(platform) {
|
|
8026
7942
|
const profiles = listProfiles(platform);
|
|
8027
7943
|
const state = await readSyncState();
|
|
8028
|
-
const { getBackend: getBackend2 } = await import("./runtime-
|
|
7944
|
+
const { getBackend: getBackend2 } = await import("./runtime-3NDWRLXL.js");
|
|
8029
7945
|
const backend = await getBackend2();
|
|
8030
7946
|
const syncs = await Promise.all(profiles.map(async (p10) => {
|
|
8031
7947
|
const modelState = state[p10.platform]?.[p10.model];
|
|
@@ -8663,16 +8579,16 @@ function projectEmbeddingApiKey(cfg) {
|
|
|
8663
8579
|
}
|
|
8664
8580
|
function redactSecrets(cfg) {
|
|
8665
8581
|
const copy = JSON.parse(JSON.stringify(cfg));
|
|
8666
|
-
for (const
|
|
8667
|
-
const val = getPath(copy,
|
|
8582
|
+
for (const path12 of SECRET_PATHS) {
|
|
8583
|
+
const val = getPath(copy, path12);
|
|
8668
8584
|
if (typeof val === "string" && val.length > 0) {
|
|
8669
|
-
setPath(copy,
|
|
8585
|
+
setPath(copy, path12, `${val.slice(0, 6)}\u2026(redacted, use --show-secrets)`);
|
|
8670
8586
|
}
|
|
8671
8587
|
}
|
|
8672
8588
|
return copy;
|
|
8673
8589
|
}
|
|
8674
|
-
function getPath(obj,
|
|
8675
|
-
const parts =
|
|
8590
|
+
function getPath(obj, path12) {
|
|
8591
|
+
const parts = path12.split(".");
|
|
8676
8592
|
let cur = obj;
|
|
8677
8593
|
for (const part of parts) {
|
|
8678
8594
|
if (cur == null || typeof cur !== "object") return void 0;
|
|
@@ -8680,8 +8596,8 @@ function getPath(obj, path13) {
|
|
|
8680
8596
|
}
|
|
8681
8597
|
return cur;
|
|
8682
8598
|
}
|
|
8683
|
-
function setPath(obj,
|
|
8684
|
-
const parts =
|
|
8599
|
+
function setPath(obj, path12, value) {
|
|
8600
|
+
const parts = path12.split(".");
|
|
8685
8601
|
let cur = obj;
|
|
8686
8602
|
for (let i = 0; i < parts.length - 1; i++) {
|
|
8687
8603
|
const part = parts[i];
|
|
@@ -8691,8 +8607,8 @@ function setPath(obj, path13, value) {
|
|
|
8691
8607
|
cur[parts[parts.length - 1]] = value;
|
|
8692
8608
|
return obj;
|
|
8693
8609
|
}
|
|
8694
|
-
function unsetPath(obj,
|
|
8695
|
-
const parts =
|
|
8610
|
+
function unsetPath(obj, path12) {
|
|
8611
|
+
const parts = path12.split(".");
|
|
8696
8612
|
let cur = obj;
|
|
8697
8613
|
for (let i = 0; i < parts.length - 1; i++) {
|
|
8698
8614
|
const part = parts[i];
|
|
@@ -8943,7 +8859,7 @@ async function memDoctorCommand() {
|
|
|
8943
8859
|
}
|
|
8944
8860
|
if (cfg.embedding.provider === "openai") {
|
|
8945
8861
|
try {
|
|
8946
|
-
const { embed: embed2 } = await import("./embedding-
|
|
8862
|
+
const { embed: embed2 } = await import("./embedding-C3E4EAQ7.js");
|
|
8947
8863
|
const result = await embed2("connectivity check");
|
|
8948
8864
|
checks.push({
|
|
8949
8865
|
name: "OpenAI embedding provider reachable",
|
|
@@ -9001,7 +8917,7 @@ ${pc10.dim(line)}`);
|
|
|
9001
8917
|
}
|
|
9002
8918
|
|
|
9003
8919
|
// src/commands/mem/export.ts
|
|
9004
|
-
import
|
|
8920
|
+
import fs11 from "fs";
|
|
9005
8921
|
async function memExportCommand(outfile) {
|
|
9006
8922
|
requireMemoryInit();
|
|
9007
8923
|
const backend = await getBackend();
|
|
@@ -9034,14 +8950,14 @@ async function memExportCommand(outfile) {
|
|
|
9034
8950
|
}
|
|
9035
8951
|
return;
|
|
9036
8952
|
}
|
|
9037
|
-
|
|
8953
|
+
fs11.writeFileSync(outfile, lines, "utf-8");
|
|
9038
8954
|
okJson({ status: "ok", file: outfile, recordsWritten: records.length, storeTotal: stats.recordCount });
|
|
9039
8955
|
}
|
|
9040
8956
|
async function memImportCommand(file) {
|
|
9041
8957
|
requireMemoryInit();
|
|
9042
|
-
if (!
|
|
8958
|
+
if (!fs11.existsSync(file)) error(`File not found: ${file}`);
|
|
9043
8959
|
const backend = await getBackend();
|
|
9044
|
-
const raw =
|
|
8960
|
+
const raw = fs11.readFileSync(file, "utf-8");
|
|
9045
8961
|
const lines = raw.split("\n").filter((l) => l.trim().length > 0);
|
|
9046
8962
|
let inserted = 0;
|
|
9047
8963
|
let updated = 0;
|
|
@@ -9305,13 +9221,13 @@ async function cacheUpdateAllCommand() {
|
|
|
9305
9221
|
for (const e of entries) {
|
|
9306
9222
|
try {
|
|
9307
9223
|
if (e.type === "knowledge") {
|
|
9308
|
-
const result = await api.
|
|
9224
|
+
const result = await api.getActionDetailsWithMeta(e.entry.key);
|
|
9309
9225
|
const newEntry = makeCacheEntry(e.entry.key, result.data, result.etag);
|
|
9310
|
-
|
|
9226
|
+
writeCache(e.filePath, newEntry);
|
|
9311
9227
|
updated++;
|
|
9312
9228
|
} else {
|
|
9313
9229
|
const refreshed = { ...e.entry, cachedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
9314
|
-
|
|
9230
|
+
writeCache(e.filePath, refreshed);
|
|
9315
9231
|
updated++;
|
|
9316
9232
|
}
|
|
9317
9233
|
} catch (err) {
|
|
@@ -9397,6 +9313,7 @@ one --agent actions execute <platform> <actionId> <key> -d '{}' # Execute it
|
|
|
9397
9313
|
- \`--mock\` \u2014 Return example response without making an API call (useful for building UI against a response shape)
|
|
9398
9314
|
- \`--skip-validation\` \u2014 Skip input validation against the action schema
|
|
9399
9315
|
- \`--output <path>\` \u2014 Save response to a file (for binary downloads like PDFs, images, documents)
|
|
9316
|
+
- \`--no-cache\` \u2014 Fetch action details fresh instead of from the local cache (execution itself is never cached)
|
|
9400
9317
|
|
|
9401
9318
|
The CLI validates required parameters against the action schema before executing. If you're missing a required path variable, query param, or body field, you'll get a clear error listing what's missing and which flag to use. Pass \`--skip-validation\` to bypass.
|
|
9402
9319
|
|
|
@@ -9522,6 +9439,9 @@ one --agent actions execute <platform> <actionId> <connectionKey> [options]
|
|
|
9522
9439
|
- \`--mock\` \u2014 Return example response without making an API call
|
|
9523
9440
|
- \`--skip-validation\` \u2014 Skip input validation against the action schema
|
|
9524
9441
|
- \`--output <path>\` \u2014 Save response to a file (for binary downloads like PDFs, images, documents)
|
|
9442
|
+
- \`--no-cache\` \u2014 Fetch action details fresh instead of from the local cache (execution itself is never cached)
|
|
9443
|
+
|
|
9444
|
+
Execute reuses the action details cached by \`actions knowledge\` (method, path, schema), so in the standard search \u2192 knowledge \u2192 execute flow it makes a single API call \u2014 the action being executed. The live response is never cached. In \`--agent\` mode the response includes \`"_preflight": {"cache": "hit"|"miss"}\` showing whether the lookup was served from disk.
|
|
9525
9445
|
|
|
9526
9446
|
**Do NOT** pass path or query parameters in \`-d\`. Use the correct flags.
|
|
9527
9447
|
|
|
@@ -9536,13 +9456,13 @@ one --agent actions execute --parallel \\
|
|
|
9536
9456
|
-- google-sheets append-row conn789 -d '{"values":["x"]}'
|
|
9537
9457
|
\`\`\`
|
|
9538
9458
|
|
|
9539
|
-
Each segment separated by \`--\` follows the same format: \`<platform> <actionId> <connectionKey> [-d ...] [--path-vars ...] [--query-params ...]\`. Global flags (\`--dry-run\`, \`--mock\`, \`--skip-validation\`) apply to all segments.
|
|
9459
|
+
Each segment separated by \`--\` follows the same format: \`<platform> <actionId> <connectionKey> [-d ...] [--path-vars ...] [--query-params ...]\`. Global flags (\`--dry-run\`, \`--mock\`, \`--skip-validation\`, \`--no-cache\`) apply to all segments.
|
|
9540
9460
|
|
|
9541
9461
|
All segments are validated upfront before any execution starts \u2014 if one segment has bad params, nothing runs. Execution uses \`Promise.allSettled\` so if one action fails the rest still complete. Use \`--max-concurrency <n>\` (default 5) to control batch size.
|
|
9542
9462
|
|
|
9543
|
-
Agent-mode output:
|
|
9463
|
+
Agent-mode output (each result carries its own \`_preflight\` showing whether that action's details were served from cache):
|
|
9544
9464
|
\`\`\`json
|
|
9545
|
-
{"parallel":true,"totalDurationMs":1234,"succeeded":2,"failed":0,"results":[{"segment":1,"platform":"gmail","actionId":"send-email","status":"success","durationMs":800,"response":{...}},{"segment":2,"platform":"slack","actionId":"post-message","status":"success","durationMs":600,"response":{...}}]}
|
|
9465
|
+
{"parallel":true,"totalDurationMs":1234,"succeeded":2,"failed":0,"results":[{"segment":1,"platform":"gmail","actionId":"send-email","status":"success","durationMs":800,"response":{...},"_preflight":{"cache":"hit"}},{"segment":2,"platform":"slack","actionId":"post-message","status":"success","durationMs":600,"response":{...},"_preflight":{"cache":"miss"}}]}
|
|
9546
9466
|
\`\`\`
|
|
9547
9467
|
|
|
9548
9468
|
## Input Validation
|
|
@@ -9675,7 +9595,7 @@ var GUIDE_CACHE = `# One Cache \u2014 Reference
|
|
|
9675
9595
|
|
|
9676
9596
|
## Overview
|
|
9677
9597
|
|
|
9678
|
-
The One CLI caches \`actions knowledge\` and \`actions search\` responses locally so repeated calls serve instantly from disk instead of hitting the API.
|
|
9598
|
+
The One CLI caches \`actions knowledge\` and \`actions search\` responses locally so repeated calls serve instantly from disk instead of hitting the API. The knowledge cache stores the action's full details (docs, method, path, schema), so \`actions execute\` reuses it for its preflight lookup \u2014 in the standard search \u2192 knowledge \u2192 execute flow, execute makes exactly one API call: the action itself.
|
|
9679
9599
|
|
|
9680
9600
|
Cache location: \`~/.one/cache/knowledge/\` and \`~/.one/cache/search/\`
|
|
9681
9601
|
|
|
@@ -9685,6 +9605,7 @@ Cache location: \`~/.one/cache/knowledge/\` and \`~/.one/cache/search/\`
|
|
|
9685
9605
|
- **Subsequent calls (within TTL)**: serves from cache instantly, no API call
|
|
9686
9606
|
- **After TTL expires**: makes a conditional request (ETag). If content unchanged, refreshes the cache timestamp. If changed, writes fresh data.
|
|
9687
9607
|
- **Network failure with stale cache**: serves the stale cache with a warning \u2014 never fails hard when a cache exists
|
|
9608
|
+
- **Shared preflight**: \`actions execute\`, flow action steps, and \`sync\` all read action details (method, path, validation schema) from the same cache and warm it on a miss \u2014 so a knowledge call, a flow run, and a later execute of the same action all reuse one cached lookup
|
|
9688
9609
|
|
|
9689
9610
|
Default TTL: 3600 seconds (1 hour). Configure via \`ONE_CACHE_TTL\` env var or \`cacheTtl\` in \`~/.one/config.json\`.
|
|
9690
9611
|
|
|
@@ -9692,8 +9613,9 @@ Default TTL: 3600 seconds (1 hour). Configure via \`ONE_CACHE_TTL\` env var or \
|
|
|
9692
9613
|
|
|
9693
9614
|
| Cached | Not Cached |
|
|
9694
9615
|
|--------|-----------|
|
|
9695
|
-
| \`actions knowledge\` (API docs, change infrequently) | \`actions execute\` (live data, always fresh) |
|
|
9616
|
+
| \`actions knowledge\` (API docs, change infrequently) | \`actions execute\` responses (live data, always fresh) |
|
|
9696
9617
|
| \`actions search\` results | \`connection list\` (changes with add/remove) |
|
|
9618
|
+
| Action details used by execute / flow / sync preflight (method, path, schema) | |
|
|
9697
9619
|
|
|
9698
9620
|
## Agent Mode \`_cache\` Metadata
|
|
9699
9621
|
|
|
@@ -9724,8 +9646,13 @@ one --agent actions knowledge <platform> <actionId> --cache-status
|
|
|
9724
9646
|
|
|
9725
9647
|
# Same for search
|
|
9726
9648
|
one --agent actions search <platform> "<query>" --no-cache
|
|
9649
|
+
|
|
9650
|
+
# Same for execute's action-details preflight (the action itself always runs live)
|
|
9651
|
+
one --agent actions execute <platform> <actionId> <key> --no-cache
|
|
9727
9652
|
\`\`\`
|
|
9728
9653
|
|
|
9654
|
+
In \`--agent\` mode, execute responses include \`"_preflight": {"cache": "hit"|"miss"}\` showing whether the action details came from disk.
|
|
9655
|
+
|
|
9729
9656
|
## Cache Management Commands
|
|
9730
9657
|
|
|
9731
9658
|
\`\`\`bash
|
|
@@ -10637,7 +10564,7 @@ function buildWorkflowIdeas(connections) {
|
|
|
10637
10564
|
}
|
|
10638
10565
|
|
|
10639
10566
|
// src/commands/logout.ts
|
|
10640
|
-
import
|
|
10567
|
+
import fs12 from "fs";
|
|
10641
10568
|
import * as p9 from "@clack/prompts";
|
|
10642
10569
|
function formatWhoami(config2, apiKey, pc13) {
|
|
10643
10570
|
const whoami = config2.whoami;
|
|
@@ -10670,12 +10597,12 @@ async function logoutCommand() {
|
|
|
10670
10597
|
const globalPath = getGlobalConfigPath();
|
|
10671
10598
|
const projectPath = getProjectConfigPath();
|
|
10672
10599
|
let cleared = false;
|
|
10673
|
-
if (
|
|
10674
|
-
|
|
10600
|
+
if (fs12.existsSync(projectPath)) {
|
|
10601
|
+
fs12.unlinkSync(projectPath);
|
|
10675
10602
|
cleared = true;
|
|
10676
10603
|
}
|
|
10677
|
-
if (
|
|
10678
|
-
|
|
10604
|
+
if (fs12.existsSync(globalPath)) {
|
|
10605
|
+
fs12.unlinkSync(globalPath);
|
|
10679
10606
|
cleared = true;
|
|
10680
10607
|
}
|
|
10681
10608
|
json({ status: cleared ? "logged_out" : "not_logged_in", message: cleared ? "Credentials cleared." : "No config found." });
|
|
@@ -10744,11 +10671,11 @@ async function logoutCommand() {
|
|
|
10744
10671
|
}
|
|
10745
10672
|
if (targetScope === "project" || targetScope === "both") {
|
|
10746
10673
|
const projectPath = getProjectConfigPath();
|
|
10747
|
-
if (
|
|
10674
|
+
if (fs12.existsSync(projectPath)) fs12.unlinkSync(projectPath);
|
|
10748
10675
|
}
|
|
10749
10676
|
if (targetScope === "global" || targetScope === "both") {
|
|
10750
10677
|
const globalPath = getGlobalConfigPath();
|
|
10751
|
-
if (
|
|
10678
|
+
if (fs12.existsSync(globalPath)) fs12.unlinkSync(globalPath);
|
|
10752
10679
|
}
|
|
10753
10680
|
p9.log.success("Credentials cleared.");
|
|
10754
10681
|
p9.log.info("Your API key is still active. Manage keys at app.withone.ai/settings");
|
|
@@ -10966,8 +10893,8 @@ config.command("reset").description("Remove the project config for the current d
|
|
|
10966
10893
|
return;
|
|
10967
10894
|
}
|
|
10968
10895
|
}
|
|
10969
|
-
const
|
|
10970
|
-
|
|
10896
|
+
const fs14 = await import("fs");
|
|
10897
|
+
fs14.unlinkSync(globalPath);
|
|
10971
10898
|
if (isAgentMode()) {
|
|
10972
10899
|
json({ deleted: true, scope: "global" });
|
|
10973
10900
|
} else {
|
|
@@ -10984,15 +10911,15 @@ config.command("reset").description("Remove the project config for the current d
|
|
|
10984
10911
|
}
|
|
10985
10912
|
return;
|
|
10986
10913
|
}
|
|
10987
|
-
const
|
|
10988
|
-
const configContent =
|
|
10989
|
-
|
|
10914
|
+
const fs13 = await import("fs");
|
|
10915
|
+
const configContent = fs13.readFileSync(resolved.path, "utf-8");
|
|
10916
|
+
fs13.unlinkSync(resolved.path);
|
|
10990
10917
|
const next = resolveConfig();
|
|
10991
|
-
|
|
10992
|
-
|
|
10918
|
+
fs13.mkdirSync(path11.dirname(resolved.path), { recursive: true });
|
|
10919
|
+
fs13.writeFileSync(resolved.path, configContent);
|
|
10993
10920
|
let fallbackLabel;
|
|
10994
10921
|
if (next.scope === "project") {
|
|
10995
|
-
fallbackLabel = `parent project config (${
|
|
10922
|
+
fallbackLabel = `parent project config (${path11.basename(next.projectRoot)})`;
|
|
10996
10923
|
} else if (next.scope === "global") {
|
|
10997
10924
|
fallbackLabel = "global config";
|
|
10998
10925
|
} else {
|
|
@@ -11001,7 +10928,7 @@ config.command("reset").description("Remove the project config for the current d
|
|
|
11001
10928
|
if (!isAgentMode()) {
|
|
11002
10929
|
const p10 = await import("@clack/prompts");
|
|
11003
10930
|
const confirmed = await p10.confirm({
|
|
11004
|
-
message: `Delete project config for ${
|
|
10931
|
+
message: `Delete project config for ${path11.basename(resolved.projectRoot)}? Will fall back to ${fallbackLabel}.`,
|
|
11005
10932
|
initialValue: false
|
|
11006
10933
|
});
|
|
11007
10934
|
if (p10.isCancel(confirmed) || !confirmed) {
|
|
@@ -11009,9 +10936,9 @@ config.command("reset").description("Remove the project config for the current d
|
|
|
11009
10936
|
return;
|
|
11010
10937
|
}
|
|
11011
10938
|
}
|
|
11012
|
-
|
|
10939
|
+
fs13.unlinkSync(resolved.path);
|
|
11013
10940
|
try {
|
|
11014
|
-
|
|
10941
|
+
fs13.rmdirSync(path11.dirname(resolved.path));
|
|
11015
10942
|
} catch {
|
|
11016
10943
|
}
|
|
11017
10944
|
if (isAgentMode()) {
|
|
@@ -11040,7 +10967,7 @@ actions.command("search <platform> <query>").description('Search for actions on
|
|
|
11040
10967
|
actions.command("knowledge <platform> <actionId>").alias("k").description("Get full docs for an action \u2014 MUST call before execute to know required params").option("--no-cache", "Skip cache, fetch fresh from API").option("--cache-status", "Print cache metadata without fetching").action(async (platform, actionId, options) => {
|
|
11041
10968
|
await actionsKnowledgeCommand(platform, actionId, options);
|
|
11042
10969
|
});
|
|
11043
|
-
actions.command("execute [platform] [actionId] [connectionKey]").alias("x").allowUnknownOption(true).allowExcessArguments(true).description("Execute an action (or multiple with --parallel, separated by --)").option("-d, --data <json>", "Request body as JSON").option("--path-vars <json>", "Path variables as JSON").option("--query-params <json>", "Query parameters as JSON").option("--headers <json>", "Additional headers as JSON").option("--form-data", "Send as multipart/form-data").option("--form-url-encoded", "Send as application/x-www-form-urlencoded").option("--dry-run", "Show request that would be sent without executing").option("--mock", "Return example response without making an API call").option("--skip-validation", "Skip input validation against the action schema").option("--output <path>", "Save binary response to a file (for non-JSON responses like file downloads)").option("--parallel", "Execute multiple actions concurrently (separate actions with --)").option("--max-concurrency <n>", "Max concurrent actions when using --parallel (default: 5)", "5").action(async (platform, actionId, connectionKey, options) => {
|
|
10970
|
+
actions.command("execute [platform] [actionId] [connectionKey]").alias("x").allowUnknownOption(true).allowExcessArguments(true).description("Execute an action (or multiple with --parallel, separated by --)").option("-d, --data <json>", "Request body as JSON").option("--path-vars <json>", "Path variables as JSON").option("--query-params <json>", "Query parameters as JSON").option("--headers <json>", "Additional headers as JSON").option("--form-data", "Send as multipart/form-data").option("--form-url-encoded", "Send as application/x-www-form-urlencoded").option("--dry-run", "Show request that would be sent without executing").option("--mock", "Return example response without making an API call").option("--skip-validation", "Skip input validation against the action schema").option("--no-cache", "Fetch action details fresh instead of using the local cache (execution itself is never cached)").option("--output <path>", "Save binary response to a file (for non-JSON responses like file downloads)").option("--parallel", "Execute multiple actions concurrently (separate actions with --)").option("--max-concurrency <n>", "Max concurrent actions when using --parallel (default: 5)", "5").action(async (platform, actionId, connectionKey, options) => {
|
|
11044
10971
|
if (options.parallel) {
|
|
11045
10972
|
await actionsExecuteParallelCommand();
|
|
11046
10973
|
return;
|
|
@@ -11058,7 +10985,8 @@ actions.command("execute [platform] [actionId] [connectionKey]").alias("x").allo
|
|
|
11058
10985
|
dryRun: options.dryRun,
|
|
11059
10986
|
mock: options.mock,
|
|
11060
10987
|
skipValidation: options.skipValidation,
|
|
11061
|
-
output: options.output
|
|
10988
|
+
output: options.output,
|
|
10989
|
+
cache: options.cache
|
|
11062
10990
|
});
|
|
11063
10991
|
});
|
|
11064
10992
|
var flow = program.command("flow").alias("f").description("Create, execute, and manage multi-step workflows");
|
|
@@ -11135,7 +11063,7 @@ program.command("guide [topic]").description("Full CLI usage guide for agents (t
|
|
|
11135
11063
|
program.command("onboard").description("Agent onboarding \u2014 teaches your agent what the One CLI can do").option("--step <number>", "Run a specific onboarding step (1, 2, or 3)").action(async (options) => {
|
|
11136
11064
|
await onboardCommand(options.step ? parseInt(options.step, 10) : void 0);
|
|
11137
11065
|
});
|
|
11138
|
-
program.command("update").description("Update the One CLI to the latest version").action(async () => {
|
|
11066
|
+
program.command("update").description("Update the One CLI to the latest version (background auto-update can be disabled with ONE_NO_AUTO_UPDATE=1)").action(async () => {
|
|
11139
11067
|
await updateCommand();
|
|
11140
11068
|
});
|
|
11141
11069
|
program.command("whoami").description("Show the user, organization, and project for the current API key").action(async () => {
|