@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
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-DZK56R5R.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
|
|
@@ -644,14 +658,14 @@ async function fetchLatestVersionInfo() {
|
|
|
644
658
|
return null;
|
|
645
659
|
}
|
|
646
660
|
}
|
|
647
|
-
function
|
|
661
|
+
function readCache2() {
|
|
648
662
|
try {
|
|
649
663
|
return JSON.parse(readFileSync(CACHE_PATH, "utf8"));
|
|
650
664
|
} catch {
|
|
651
665
|
return null;
|
|
652
666
|
}
|
|
653
667
|
}
|
|
654
|
-
function
|
|
668
|
+
function writeCache2(latestVersion, publishedAt) {
|
|
655
669
|
try {
|
|
656
670
|
mkdirSync(join(homedir(), ".one"), { recursive: true });
|
|
657
671
|
writeFileSync(CACHE_PATH, JSON.stringify({ lastCheck: Date.now(), latestVersion, publishedAt }));
|
|
@@ -660,16 +674,16 @@ function writeCache(latestVersion, publishedAt) {
|
|
|
660
674
|
}
|
|
661
675
|
async function checkLatestVersion() {
|
|
662
676
|
const info = await fetchLatestVersionInfo();
|
|
663
|
-
if (info)
|
|
677
|
+
if (info) writeCache2(info.version, info.publishedAt);
|
|
664
678
|
return info?.version ?? null;
|
|
665
679
|
}
|
|
666
680
|
async function checkLatestVersionCached() {
|
|
667
|
-
const cache2 =
|
|
681
|
+
const cache2 = readCache2();
|
|
668
682
|
if (cache2 && Date.now() - cache2.lastCheck < CHECK_INTERVAL_MS) {
|
|
669
683
|
return { version: cache2.latestVersion, publishedAt: cache2.publishedAt ?? null };
|
|
670
684
|
}
|
|
671
685
|
const info = await fetchLatestVersionInfo();
|
|
672
|
-
if (info)
|
|
686
|
+
if (info) writeCache2(info.version, info.publishedAt);
|
|
673
687
|
return info;
|
|
674
688
|
}
|
|
675
689
|
function getCurrentVersion() {
|
|
@@ -2340,123 +2354,6 @@ async function platformsCommand(options) {
|
|
|
2340
2354
|
// src/commands/actions.ts
|
|
2341
2355
|
import * as p6 from "@clack/prompts";
|
|
2342
2356
|
import pc6 from "picocolors";
|
|
2343
|
-
|
|
2344
|
-
// src/lib/cache.ts
|
|
2345
|
-
import fs4 from "fs";
|
|
2346
|
-
import path4 from "path";
|
|
2347
|
-
import os4 from "os";
|
|
2348
|
-
var CACHE_BASE = path4.join(os4.homedir(), ".one", "cache");
|
|
2349
|
-
var KNOWLEDGE_DIR = path4.join(CACHE_BASE, "knowledge");
|
|
2350
|
-
var SEARCH_DIR = path4.join(CACHE_BASE, "search");
|
|
2351
|
-
function sanitizeFilename(input) {
|
|
2352
|
-
return input.replace(/[^a-zA-Z0-9_\-\.]/g, "_");
|
|
2353
|
-
}
|
|
2354
|
-
function knowledgeCachePath(actionId) {
|
|
2355
|
-
return path4.join(KNOWLEDGE_DIR, `${sanitizeFilename(actionId)}.json`);
|
|
2356
|
-
}
|
|
2357
|
-
function searchCachePath(platform, query, type) {
|
|
2358
|
-
const key = `${platform}_${sanitizeFilename(query)}_${type || "knowledge"}`;
|
|
2359
|
-
return path4.join(SEARCH_DIR, `${key}.json`);
|
|
2360
|
-
}
|
|
2361
|
-
function readCache2(filePath) {
|
|
2362
|
-
try {
|
|
2363
|
-
const content = fs4.readFileSync(filePath, "utf-8");
|
|
2364
|
-
return JSON.parse(content);
|
|
2365
|
-
} catch {
|
|
2366
|
-
return null;
|
|
2367
|
-
}
|
|
2368
|
-
}
|
|
2369
|
-
function writeCache2(filePath, entry) {
|
|
2370
|
-
try {
|
|
2371
|
-
const dir = path4.dirname(filePath);
|
|
2372
|
-
fs4.mkdirSync(dir, { recursive: true });
|
|
2373
|
-
fs4.writeFileSync(filePath, JSON.stringify(entry, null, 2));
|
|
2374
|
-
} catch {
|
|
2375
|
-
}
|
|
2376
|
-
}
|
|
2377
|
-
function isFresh(entry) {
|
|
2378
|
-
const cachedTime = new Date(entry.cachedAt).getTime();
|
|
2379
|
-
const now = Date.now();
|
|
2380
|
-
return now - cachedTime < entry.ttl * 1e3;
|
|
2381
|
-
}
|
|
2382
|
-
function getAge(entry) {
|
|
2383
|
-
return Math.floor((Date.now() - new Date(entry.cachedAt).getTime()) / 1e3);
|
|
2384
|
-
}
|
|
2385
|
-
function buildCacheMeta(entry, hit) {
|
|
2386
|
-
if (!entry) {
|
|
2387
|
-
return { hit: false, age: 0, fresh: false };
|
|
2388
|
-
}
|
|
2389
|
-
return {
|
|
2390
|
-
hit,
|
|
2391
|
-
age: getAge(entry),
|
|
2392
|
-
fresh: isFresh(entry)
|
|
2393
|
-
};
|
|
2394
|
-
}
|
|
2395
|
-
function formatAge(seconds) {
|
|
2396
|
-
if (seconds < 60) return `${seconds}s`;
|
|
2397
|
-
if (seconds < 3600) return `${Math.floor(seconds / 60)}m`;
|
|
2398
|
-
if (seconds < 86400) {
|
|
2399
|
-
const h2 = Math.floor(seconds / 3600);
|
|
2400
|
-
const m = Math.floor(seconds % 3600 / 60);
|
|
2401
|
-
return m > 0 ? `${h2}h ${m}m` : `${h2}h`;
|
|
2402
|
-
}
|
|
2403
|
-
const d = Math.floor(seconds / 86400);
|
|
2404
|
-
const h = Math.floor(seconds % 86400 / 3600);
|
|
2405
|
-
return h > 0 ? `${d}d ${h}h` : `${d}d`;
|
|
2406
|
-
}
|
|
2407
|
-
function listCacheEntries() {
|
|
2408
|
-
const entries = [];
|
|
2409
|
-
for (const [dir, type] of [[KNOWLEDGE_DIR, "knowledge"], [SEARCH_DIR, "search"]]) {
|
|
2410
|
-
try {
|
|
2411
|
-
const files = fs4.readdirSync(dir);
|
|
2412
|
-
for (const file of files) {
|
|
2413
|
-
if (!file.endsWith(".json")) continue;
|
|
2414
|
-
const filePath = path4.join(dir, file);
|
|
2415
|
-
const entry = readCache2(filePath);
|
|
2416
|
-
if (entry) {
|
|
2417
|
-
entries.push({ type, filePath, entry });
|
|
2418
|
-
}
|
|
2419
|
-
}
|
|
2420
|
-
} catch {
|
|
2421
|
-
}
|
|
2422
|
-
}
|
|
2423
|
-
return entries;
|
|
2424
|
-
}
|
|
2425
|
-
function clearAll() {
|
|
2426
|
-
let count = 0;
|
|
2427
|
-
for (const dir of [KNOWLEDGE_DIR, SEARCH_DIR]) {
|
|
2428
|
-
try {
|
|
2429
|
-
const files = fs4.readdirSync(dir);
|
|
2430
|
-
for (const file of files) {
|
|
2431
|
-
fs4.unlinkSync(path4.join(dir, file));
|
|
2432
|
-
count++;
|
|
2433
|
-
}
|
|
2434
|
-
fs4.rmdirSync(dir);
|
|
2435
|
-
} catch {
|
|
2436
|
-
}
|
|
2437
|
-
}
|
|
2438
|
-
return count;
|
|
2439
|
-
}
|
|
2440
|
-
function clearEntry(actionId) {
|
|
2441
|
-
const filePath = knowledgeCachePath(actionId);
|
|
2442
|
-
try {
|
|
2443
|
-
fs4.unlinkSync(filePath);
|
|
2444
|
-
return true;
|
|
2445
|
-
} catch {
|
|
2446
|
-
return false;
|
|
2447
|
-
}
|
|
2448
|
-
}
|
|
2449
|
-
function makeCacheEntry(key, data, etag) {
|
|
2450
|
-
return {
|
|
2451
|
-
key,
|
|
2452
|
-
etag,
|
|
2453
|
-
cachedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2454
|
-
ttl: getCacheTtl(),
|
|
2455
|
-
data
|
|
2456
|
-
};
|
|
2457
|
-
}
|
|
2458
|
-
|
|
2459
|
-
// src/commands/actions.ts
|
|
2460
2357
|
function getConfig() {
|
|
2461
2358
|
const apiKey = getApiKey();
|
|
2462
2359
|
if (!apiKey) {
|
|
@@ -2485,8 +2382,9 @@ async function actionsSearchCommand(platform, query, options) {
|
|
|
2485
2382
|
try {
|
|
2486
2383
|
const agentType = knowledgeAgent ? "knowledge" : options.type || "execute";
|
|
2487
2384
|
const useCache = options.cache !== false;
|
|
2488
|
-
const
|
|
2489
|
-
const
|
|
2385
|
+
const searchType = agentType || "knowledge";
|
|
2386
|
+
const cachePath = searchCachePath(platform, query, searchType);
|
|
2387
|
+
const cached = useCache ? readCache(cachePath) : null;
|
|
2490
2388
|
let cleanedActions;
|
|
2491
2389
|
let cacheHit = false;
|
|
2492
2390
|
if (cached && isFresh(cached)) {
|
|
@@ -2502,7 +2400,7 @@ async function actionsSearchCommand(platform, query, options) {
|
|
|
2502
2400
|
);
|
|
2503
2401
|
if (result.status === 304 && cached) {
|
|
2504
2402
|
cached.cachedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2505
|
-
|
|
2403
|
+
writeCache(cachePath, cached);
|
|
2506
2404
|
cleanedActions = cached.data.actions;
|
|
2507
2405
|
cacheHit = true;
|
|
2508
2406
|
} else {
|
|
@@ -2515,9 +2413,9 @@ async function actionsSearchCommand(platform, query, options) {
|
|
|
2515
2413
|
method: action.method,
|
|
2516
2414
|
path: action.path
|
|
2517
2415
|
}));
|
|
2518
|
-
|
|
2519
|
-
`${platform}_${query}_${
|
|
2520
|
-
{ actions: cleanedActions },
|
|
2416
|
+
writeCache(cachePath, makeCacheEntry(
|
|
2417
|
+
`${platform}_${query}_${searchType}`,
|
|
2418
|
+
{ actions: cleanedActions, platform, query, searchType },
|
|
2521
2419
|
result.etag
|
|
2522
2420
|
));
|
|
2523
2421
|
}
|
|
@@ -2539,7 +2437,7 @@ async function actionsSearchCommand(platform, query, options) {
|
|
|
2539
2437
|
if (cacheHit && cached) {
|
|
2540
2438
|
response._cache = buildCacheMeta(cached, true);
|
|
2541
2439
|
} else {
|
|
2542
|
-
const freshEntry =
|
|
2440
|
+
const freshEntry = readCache(cachePath);
|
|
2543
2441
|
response._cache = buildCacheMeta(freshEntry, false);
|
|
2544
2442
|
}
|
|
2545
2443
|
json(response);
|
|
@@ -2599,7 +2497,7 @@ Execute: ${pc6.cyan(`one actions execute ${platform} <actionId> <connectionK
|
|
|
2599
2497
|
async function actionsKnowledgeCommand(platform, actionId, options) {
|
|
2600
2498
|
const cachePath = knowledgeCachePath(actionId);
|
|
2601
2499
|
if (options.cacheStatus) {
|
|
2602
|
-
const entry =
|
|
2500
|
+
const entry = readCache(cachePath);
|
|
2603
2501
|
if (!entry) {
|
|
2604
2502
|
json({
|
|
2605
2503
|
cached: false,
|
|
@@ -2646,44 +2544,13 @@ async function actionsKnowledgeCommand(platform, actionId, options) {
|
|
|
2646
2544
|
const spinner5 = createSpinner();
|
|
2647
2545
|
spinner5.start(`Loading knowledge for action ${pc6.dim(actionId)}...`);
|
|
2648
2546
|
try {
|
|
2649
|
-
const
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
cacheHit = true;
|
|
2657
|
-
} else {
|
|
2658
|
-
try {
|
|
2659
|
-
const result = await api.getActionKnowledgeWithMeta(
|
|
2660
|
-
actionId,
|
|
2661
|
-
cached?.etag ?? void 0
|
|
2662
|
-
);
|
|
2663
|
-
if (result.status === 304 && cached) {
|
|
2664
|
-
cached.cachedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2665
|
-
writeCache2(cachePath, cached);
|
|
2666
|
-
knowledgeData = cached.data;
|
|
2667
|
-
cacheHit = true;
|
|
2668
|
-
} else {
|
|
2669
|
-
knowledgeData = result.data;
|
|
2670
|
-
const newEntry = makeCacheEntry(actionId, knowledgeData, result.etag);
|
|
2671
|
-
writeCache2(cachePath, newEntry);
|
|
2672
|
-
cacheEntry = newEntry;
|
|
2673
|
-
}
|
|
2674
|
-
} catch (fetchError) {
|
|
2675
|
-
if (cached) {
|
|
2676
|
-
process.stderr.write(
|
|
2677
|
-
`Warning: serving cached knowledge (network unavailable, cached ${formatAge(getAge(cached))} ago)
|
|
2678
|
-
`
|
|
2679
|
-
);
|
|
2680
|
-
knowledgeData = cached.data;
|
|
2681
|
-
cacheHit = true;
|
|
2682
|
-
} else {
|
|
2683
|
-
throw fetchError;
|
|
2684
|
-
}
|
|
2685
|
-
}
|
|
2686
|
-
}
|
|
2547
|
+
const { details, cacheHit, entry } = await resolveActionDetails(api, actionId, {
|
|
2548
|
+
useCache: options.cache !== false
|
|
2549
|
+
});
|
|
2550
|
+
const knowledgeData = {
|
|
2551
|
+
knowledge: details.knowledge || "No knowledge was found",
|
|
2552
|
+
method: details.method || "No method was found"
|
|
2553
|
+
};
|
|
2687
2554
|
const knowledgeWithGuidance = buildActionKnowledgeWithGuidance(
|
|
2688
2555
|
knowledgeData.knowledge,
|
|
2689
2556
|
knowledgeData.method,
|
|
@@ -2694,7 +2561,7 @@ async function actionsKnowledgeCommand(platform, actionId, options) {
|
|
|
2694
2561
|
const response = {
|
|
2695
2562
|
knowledge: knowledgeWithGuidance,
|
|
2696
2563
|
method: knowledgeData.method,
|
|
2697
|
-
_cache: buildCacheMeta(
|
|
2564
|
+
_cache: buildCacheMeta(entry, cacheHit)
|
|
2698
2565
|
};
|
|
2699
2566
|
json(response);
|
|
2700
2567
|
return;
|
|
@@ -2730,16 +2597,18 @@ async function actionsExecuteCommand(platform, actionId, connectionKey, options)
|
|
|
2730
2597
|
}
|
|
2731
2598
|
const api = new OneApi(apiKey, getApiBase());
|
|
2732
2599
|
const spinner5 = createSpinner();
|
|
2733
|
-
spinner5.start("
|
|
2600
|
+
spinner5.start("Resolving action details...");
|
|
2734
2601
|
try {
|
|
2735
|
-
const actionDetails = await api.
|
|
2602
|
+
const { details: actionDetails, cacheHit: preflightCacheHit } = await resolveActionDetails(api, actionId, { useCache: options.cache !== false });
|
|
2736
2603
|
if (!isMethodAllowed(actionDetails.method, permissions)) {
|
|
2737
2604
|
spinner5.stop("Permission denied");
|
|
2738
2605
|
error(
|
|
2739
2606
|
`Method "${actionDetails.method}" is not allowed under "${permissions}" permission level.`
|
|
2740
2607
|
);
|
|
2741
2608
|
}
|
|
2742
|
-
spinner5.stop(
|
|
2609
|
+
spinner5.stop(
|
|
2610
|
+
`Action: ${actionDetails.title} [${actionDetails.method}]` + (preflightCacheHit ? pc6.dim(" (cached)") : "")
|
|
2611
|
+
);
|
|
2743
2612
|
const data = options.data ? parseJsonArg2(options.data, "--data") : void 0;
|
|
2744
2613
|
const pathVariables = options.pathVars ? parseJsonArg2(options.pathVars, "--path-vars") : void 0;
|
|
2745
2614
|
const queryParams = options.queryParams ? parseJsonArg2(options.queryParams, "--query-params") : void 0;
|
|
@@ -2778,7 +2647,8 @@ async function actionsExecuteCommand(platform, actionId, connectionKey, options)
|
|
|
2778
2647
|
url: actionDetails.path
|
|
2779
2648
|
},
|
|
2780
2649
|
response: mockResponse,
|
|
2781
|
-
...mockResponse === null ? { message: "No example output available for this action" } : {}
|
|
2650
|
+
...mockResponse === null ? { message: "No example output available for this action" } : {},
|
|
2651
|
+
_preflight: { cache: preflightCacheHit ? "hit" : "miss" }
|
|
2782
2652
|
});
|
|
2783
2653
|
return;
|
|
2784
2654
|
}
|
|
@@ -2819,7 +2689,8 @@ async function actionsExecuteCommand(platform, actionId, connectionKey, options)
|
|
|
2819
2689
|
headers: options.dryRun ? result.requestConfig.headers : void 0,
|
|
2820
2690
|
data: options.dryRun ? result.requestConfig.data : void 0
|
|
2821
2691
|
},
|
|
2822
|
-
response: options.dryRun ? void 0 : result.responseData
|
|
2692
|
+
response: options.dryRun ? void 0 : result.responseData,
|
|
2693
|
+
_preflight: { cache: preflightCacheHit ? "hit" : "miss" }
|
|
2823
2694
|
});
|
|
2824
2695
|
return;
|
|
2825
2696
|
}
|
|
@@ -2863,7 +2734,7 @@ function parseParallelSegments() {
|
|
|
2863
2734
|
error('Could not locate "actions execute" in argv');
|
|
2864
2735
|
}
|
|
2865
2736
|
const raw = argv.slice(execIdx + 1);
|
|
2866
|
-
const flags = { dryRun: false, mock: false, skipValidation: false, maxConcurrency: 5 };
|
|
2737
|
+
const flags = { dryRun: false, mock: false, skipValidation: false, maxConcurrency: 5, useCache: true };
|
|
2867
2738
|
const cleaned = [];
|
|
2868
2739
|
for (let i = 0; i < raw.length; i++) {
|
|
2869
2740
|
const t = raw[i];
|
|
@@ -2880,6 +2751,10 @@ function parseParallelSegments() {
|
|
|
2880
2751
|
flags.skipValidation = true;
|
|
2881
2752
|
continue;
|
|
2882
2753
|
}
|
|
2754
|
+
if (t === "--no-cache") {
|
|
2755
|
+
flags.useCache = false;
|
|
2756
|
+
continue;
|
|
2757
|
+
}
|
|
2883
2758
|
if (t === "--max-concurrency") {
|
|
2884
2759
|
flags.maxConcurrency = parseInt(raw[++i], 10) || 5;
|
|
2885
2760
|
continue;
|
|
@@ -2958,6 +2833,7 @@ async function actionsExecuteParallelCommand() {
|
|
|
2958
2833
|
const api = new OneApi(apiKey, getApiBase());
|
|
2959
2834
|
const prepared = [];
|
|
2960
2835
|
const errors = [];
|
|
2836
|
+
const staleWarned = /* @__PURE__ */ new Set();
|
|
2961
2837
|
for (let i = 0; i < segments.length; i++) {
|
|
2962
2838
|
const seg = segments[i];
|
|
2963
2839
|
const label = `${seg.platform}/${seg.actionId}`;
|
|
@@ -2969,8 +2845,18 @@ async function actionsExecuteParallelCommand() {
|
|
|
2969
2845
|
segErrors.push(`Connection key "${seg.connectionKey}" is not allowed`);
|
|
2970
2846
|
}
|
|
2971
2847
|
let actionDetails;
|
|
2848
|
+
let preflightCacheHit = false;
|
|
2972
2849
|
try {
|
|
2973
|
-
|
|
2850
|
+
const resolved = await resolveActionDetails(api, seg.actionId, {
|
|
2851
|
+
useCache: flags.useCache,
|
|
2852
|
+
warn: (msg) => {
|
|
2853
|
+
if (staleWarned.has(seg.actionId)) return;
|
|
2854
|
+
staleWarned.add(seg.actionId);
|
|
2855
|
+
process.stderr.write(msg);
|
|
2856
|
+
}
|
|
2857
|
+
});
|
|
2858
|
+
actionDetails = resolved.details;
|
|
2859
|
+
preflightCacheHit = resolved.cacheHit;
|
|
2974
2860
|
} catch (err) {
|
|
2975
2861
|
segErrors.push(`Action not found: ${err instanceof Error ? err.message : String(err)}`);
|
|
2976
2862
|
}
|
|
@@ -3016,7 +2902,7 @@ async function actionsExecuteParallelCommand() {
|
|
|
3016
2902
|
if (segErrors.length > 0) {
|
|
3017
2903
|
errors.push({ segment: i + 1, label, messages: segErrors });
|
|
3018
2904
|
} else if (actionDetails) {
|
|
3019
|
-
prepared.push({ segment: seg, index: i, actionDetails, data, pathVariables, queryParams, headers });
|
|
2905
|
+
prepared.push({ segment: seg, index: i, actionDetails, preflightCacheHit, data, pathVariables, queryParams, headers });
|
|
3020
2906
|
}
|
|
3021
2907
|
}
|
|
3022
2908
|
if (errors.length > 0) {
|
|
@@ -3054,7 +2940,8 @@ async function actionsExecuteParallelCommand() {
|
|
|
3054
2940
|
durationMs: Date.now() - start,
|
|
3055
2941
|
mock: true,
|
|
3056
2942
|
request: { method: action.actionDetails.method, url: action.actionDetails.path },
|
|
3057
|
-
response: mockResponse
|
|
2943
|
+
response: mockResponse,
|
|
2944
|
+
_preflight: { cache: action.preflightCacheHit ? "hit" : "miss" }
|
|
3058
2945
|
};
|
|
3059
2946
|
}
|
|
3060
2947
|
const result = await api.executePassthroughRequest({
|
|
@@ -3081,7 +2968,8 @@ async function actionsExecuteParallelCommand() {
|
|
|
3081
2968
|
url: result.requestConfig.url,
|
|
3082
2969
|
...flags.dryRun ? { headers: result.requestConfig.headers, data: result.requestConfig.data } : {}
|
|
3083
2970
|
},
|
|
3084
|
-
response: flags.dryRun ? void 0 : result.responseData
|
|
2971
|
+
response: flags.dryRun ? void 0 : result.responseData,
|
|
2972
|
+
_preflight: { cache: action.preflightCacheHit ? "hit" : "miss" }
|
|
3085
2973
|
};
|
|
3086
2974
|
})
|
|
3087
2975
|
);
|
|
@@ -3162,8 +3050,8 @@ function colorMethod(method) {
|
|
|
3162
3050
|
import pc7 from "picocolors";
|
|
3163
3051
|
|
|
3164
3052
|
// src/lib/flow-validator.ts
|
|
3165
|
-
import
|
|
3166
|
-
import
|
|
3053
|
+
import fs4 from "fs";
|
|
3054
|
+
import path4 from "path";
|
|
3167
3055
|
import { spawnSync } from "child_process";
|
|
3168
3056
|
function validateFlowSchema(flow2) {
|
|
3169
3057
|
const errors = [];
|
|
@@ -3228,32 +3116,32 @@ function validateStepsArray(steps, pathPrefix, errors) {
|
|
|
3228
3116
|
const validTypes = FLOW_SCHEMA.stepTypes.map((st) => st.type);
|
|
3229
3117
|
for (let i = 0; i < steps.length; i++) {
|
|
3230
3118
|
const step = steps[i];
|
|
3231
|
-
const
|
|
3119
|
+
const path12 = `${pathPrefix}[${i}]`;
|
|
3232
3120
|
if (!step || typeof step !== "object" || Array.isArray(step)) {
|
|
3233
|
-
errors.push({ path:
|
|
3121
|
+
errors.push({ path: path12, message: "Step must be an object" });
|
|
3234
3122
|
continue;
|
|
3235
3123
|
}
|
|
3236
3124
|
const s = step;
|
|
3237
3125
|
if (!s.id || typeof s.id !== "string") {
|
|
3238
|
-
errors.push({ path: `${
|
|
3126
|
+
errors.push({ path: `${path12}.id`, message: 'Step must have a string "id"' });
|
|
3239
3127
|
}
|
|
3240
3128
|
if (!s.name || typeof s.name !== "string") {
|
|
3241
|
-
errors.push({ path: `${
|
|
3129
|
+
errors.push({ path: `${path12}.name`, message: 'Step must have a string "name"' });
|
|
3242
3130
|
}
|
|
3243
3131
|
if (!s.type || !validTypes.includes(s.type)) {
|
|
3244
|
-
errors.push({ path: `${
|
|
3132
|
+
errors.push({ path: `${path12}.type`, message: `Step type must be one of: ${validTypes.join(", ")}` });
|
|
3245
3133
|
continue;
|
|
3246
3134
|
}
|
|
3247
3135
|
if (s.requires !== void 0) {
|
|
3248
3136
|
if (!Array.isArray(s.requires)) {
|
|
3249
|
-
errors.push({ path: `${
|
|
3137
|
+
errors.push({ path: `${path12}.requires`, message: '"requires" must be an array of selector strings (e.g. ["$.steps.foo.output.bar"])' });
|
|
3250
3138
|
} else {
|
|
3251
3139
|
for (let r = 0; r < s.requires.length; r++) {
|
|
3252
3140
|
const sel = s.requires[r];
|
|
3253
3141
|
if (typeof sel !== "string") {
|
|
3254
|
-
errors.push({ path: `${
|
|
3142
|
+
errors.push({ path: `${path12}.requires[${r}]`, message: '"requires" entry must be a selector string' });
|
|
3255
3143
|
} else if (!sel.startsWith("$.")) {
|
|
3256
|
-
errors.push({ path: `${
|
|
3144
|
+
errors.push({ path: `${path12}.requires[${r}]`, message: `"requires" entry "${sel}" must be a selector starting with "$." (e.g. "$.steps.foo.output.bar")` });
|
|
3257
3145
|
}
|
|
3258
3146
|
}
|
|
3259
3147
|
}
|
|
@@ -3261,7 +3149,7 @@ function validateStepsArray(steps, pathPrefix, errors) {
|
|
|
3261
3149
|
if (s.onError && typeof s.onError === "object") {
|
|
3262
3150
|
const oe = s.onError;
|
|
3263
3151
|
if (!FLOW_SCHEMA.errorStrategies.includes(oe.strategy)) {
|
|
3264
|
-
errors.push({ path: `${
|
|
3152
|
+
errors.push({ path: `${path12}.onError.strategy`, message: `Error strategy must be one of: ${FLOW_SCHEMA.errorStrategies.join(", ")}` });
|
|
3265
3153
|
}
|
|
3266
3154
|
}
|
|
3267
3155
|
const descriptor = getStepTypeDescriptor(s.type);
|
|
@@ -3271,14 +3159,14 @@ function validateStepsArray(steps, pathPrefix, errors) {
|
|
|
3271
3159
|
if (!configObj || typeof configObj !== "object") {
|
|
3272
3160
|
const hint = detectFlatConfigHint(s, descriptor);
|
|
3273
3161
|
errors.push({
|
|
3274
|
-
path: `${
|
|
3162
|
+
path: `${path12}.${configKey}`,
|
|
3275
3163
|
message: `${capitalize(descriptor.type)} step must have a "${configKey}" config object${hint}`
|
|
3276
3164
|
});
|
|
3277
3165
|
continue;
|
|
3278
3166
|
}
|
|
3279
3167
|
const config2 = configObj;
|
|
3280
3168
|
for (const [fieldName, fd] of Object.entries(descriptor.fields)) {
|
|
3281
|
-
const fieldPath = `${
|
|
3169
|
+
const fieldPath = `${path12}.${configKey}.${fieldName}`;
|
|
3282
3170
|
const value = config2[fieldName];
|
|
3283
3171
|
if (fd.required && (value === void 0 || value === null || value === "")) {
|
|
3284
3172
|
errors.push({ path: fieldPath, message: `${capitalize(descriptor.type)} must have ${fd.type === "string" ? "a string" : fd.type === "array" ? "a" : "a"} "${fieldName}"` });
|
|
@@ -3311,30 +3199,30 @@ function validateStepsArray(steps, pathPrefix, errors) {
|
|
|
3311
3199
|
}
|
|
3312
3200
|
}
|
|
3313
3201
|
if (descriptor.type === "action") {
|
|
3314
|
-
validateConnectionForm(config2, `${
|
|
3202
|
+
validateConnectionForm(config2, `${path12}.${configKey}`, errors);
|
|
3315
3203
|
}
|
|
3316
3204
|
if (descriptor.type === "code") {
|
|
3317
3205
|
const hasSource = typeof config2.source === "string" && config2.source.length > 0;
|
|
3318
3206
|
const hasModule = typeof config2.module === "string" && config2.module.length > 0;
|
|
3319
3207
|
if (!hasSource && !hasModule) {
|
|
3320
|
-
errors.push({ path: `${
|
|
3208
|
+
errors.push({ path: `${path12}.${configKey}`, message: 'Code step must define either "source" (inline JS) or "module" (path to .mjs file)' });
|
|
3321
3209
|
} else if (hasSource && hasModule) {
|
|
3322
|
-
errors.push({ path: `${
|
|
3210
|
+
errors.push({ path: `${path12}.${configKey}`, message: 'Code step cannot define both "source" and "module" \u2014 pick one' });
|
|
3323
3211
|
}
|
|
3324
3212
|
if (hasModule) {
|
|
3325
3213
|
const m = config2.module;
|
|
3326
3214
|
if (m.startsWith("/") || /^[a-zA-Z]:[\\/]/.test(m)) {
|
|
3327
|
-
errors.push({ path: `${
|
|
3215
|
+
errors.push({ path: `${path12}.${configKey}.module`, message: "Code module path must be relative to the flow folder (no absolute paths)" });
|
|
3328
3216
|
} else if (m.split(/[\\/]/).includes("..")) {
|
|
3329
|
-
errors.push({ path: `${
|
|
3217
|
+
errors.push({ path: `${path12}.${configKey}.module`, message: 'Code module path must not escape the flow folder ("..")' });
|
|
3330
3218
|
} else if (!m.endsWith(".mjs")) {
|
|
3331
|
-
errors.push({ path: `${
|
|
3219
|
+
errors.push({ path: `${path12}.${configKey}.module`, message: "Code module must be a .mjs file" });
|
|
3332
3220
|
}
|
|
3333
3221
|
}
|
|
3334
3222
|
if (hasSource) {
|
|
3335
3223
|
const syntaxError = checkCodeSourceSyntax(config2.source);
|
|
3336
3224
|
if (syntaxError) {
|
|
3337
|
-
errors.push({ path: `${
|
|
3225
|
+
errors.push({ path: `${path12}.${configKey}.source`, message: `Syntax error in code step: ${syntaxError}` });
|
|
3338
3226
|
}
|
|
3339
3227
|
}
|
|
3340
3228
|
}
|
|
@@ -3406,16 +3294,16 @@ function validateStepIds(flow2) {
|
|
|
3406
3294
|
function collectIds(steps, pathPrefix) {
|
|
3407
3295
|
for (let i = 0; i < steps.length; i++) {
|
|
3408
3296
|
const step = steps[i];
|
|
3409
|
-
const
|
|
3297
|
+
const path12 = `${pathPrefix}[${i}]`;
|
|
3410
3298
|
if (seen.has(step.id)) {
|
|
3411
|
-
errors.push({ path: `${
|
|
3299
|
+
errors.push({ path: `${path12}.id`, message: `Duplicate step ID: "${step.id}"` });
|
|
3412
3300
|
} else {
|
|
3413
3301
|
seen.add(step.id);
|
|
3414
3302
|
}
|
|
3415
3303
|
for (const { configKey, fieldName } of nestedKeys) {
|
|
3416
3304
|
const config2 = step[configKey];
|
|
3417
3305
|
if (config2 && Array.isArray(config2[fieldName])) {
|
|
3418
|
-
collectIds(config2[fieldName], `${
|
|
3306
|
+
collectIds(config2[fieldName], `${path12}.${configKey}.${fieldName}`);
|
|
3419
3307
|
}
|
|
3420
3308
|
}
|
|
3421
3309
|
}
|
|
@@ -3463,7 +3351,7 @@ function validateSelectorReferences(flow2) {
|
|
|
3463
3351
|
}
|
|
3464
3352
|
return selectors;
|
|
3465
3353
|
}
|
|
3466
|
-
function checkSelectors(selectors,
|
|
3354
|
+
function checkSelectors(selectors, path12, precedingStepIds) {
|
|
3467
3355
|
for (const selector of selectors) {
|
|
3468
3356
|
const parts = selector.split(".");
|
|
3469
3357
|
if (parts.length < 3) continue;
|
|
@@ -3471,15 +3359,15 @@ function validateSelectorReferences(flow2) {
|
|
|
3471
3359
|
if (root === "input") {
|
|
3472
3360
|
const inputName = parts[2];
|
|
3473
3361
|
if (!inputNames.has(inputName)) {
|
|
3474
|
-
errors.push({ path:
|
|
3362
|
+
errors.push({ path: path12, message: `Selector "${selector}" references undefined input "${inputName}"` });
|
|
3475
3363
|
}
|
|
3476
3364
|
} else if (root === "steps") {
|
|
3477
3365
|
const stepId = parts[2].replace(/[\[\]]/g, "").split(/[\[\]]/)[0];
|
|
3478
3366
|
if (!allStepIds.has(stepId)) {
|
|
3479
|
-
errors.push({ path:
|
|
3367
|
+
errors.push({ path: path12, message: `Selector "${selector}" references undefined step "${stepId}"` });
|
|
3480
3368
|
} else if (precedingStepIds && !precedingStepIds.has(stepId)) {
|
|
3481
3369
|
errors.push({
|
|
3482
|
-
path:
|
|
3370
|
+
path: path12,
|
|
3483
3371
|
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.`
|
|
3484
3372
|
});
|
|
3485
3373
|
}
|
|
@@ -3487,20 +3375,20 @@ function validateSelectorReferences(flow2) {
|
|
|
3487
3375
|
}
|
|
3488
3376
|
}
|
|
3489
3377
|
const EXPRESSION_FIELDS = /* @__PURE__ */ new Set(["condition.expression", "while.condition"]);
|
|
3490
|
-
function checkOperatorsInSelectorField(value,
|
|
3378
|
+
function checkOperatorsInSelectorField(value, path12) {
|
|
3491
3379
|
if (typeof value === "string" && value.startsWith("$.")) {
|
|
3492
3380
|
if (value.includes("||")) {
|
|
3493
|
-
errors.push({ path:
|
|
3381
|
+
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.` });
|
|
3494
3382
|
} else if (value.includes("&&")) {
|
|
3495
|
-
errors.push({ path:
|
|
3383
|
+
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.` });
|
|
3496
3384
|
}
|
|
3497
3385
|
} else if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
3498
3386
|
for (const [k, v] of Object.entries(value)) {
|
|
3499
|
-
checkOperatorsInSelectorField(v, `${
|
|
3387
|
+
checkOperatorsInSelectorField(v, `${path12}.${k}`);
|
|
3500
3388
|
}
|
|
3501
3389
|
} else if (Array.isArray(value)) {
|
|
3502
3390
|
for (let i = 0; i < value.length; i++) {
|
|
3503
|
-
checkOperatorsInSelectorField(value[i], `${
|
|
3391
|
+
checkOperatorsInSelectorField(value[i], `${path12}[${i}]`);
|
|
3504
3392
|
}
|
|
3505
3393
|
}
|
|
3506
3394
|
}
|
|
@@ -3568,10 +3456,10 @@ var VALID_OUTPUT_SCHEMA_TYPES = /* @__PURE__ */ new Set(["string", "number", "bo
|
|
|
3568
3456
|
function isOutputSchemaObject(v) {
|
|
3569
3457
|
return !!v && typeof v === "object" && !Array.isArray(v);
|
|
3570
3458
|
}
|
|
3571
|
-
function walkOutputSchema(schema,
|
|
3459
|
+
function walkOutputSchema(schema, path12) {
|
|
3572
3460
|
let current = schema;
|
|
3573
|
-
for (let i = 0; i <
|
|
3574
|
-
const seg =
|
|
3461
|
+
for (let i = 0; i < path12.length; i++) {
|
|
3462
|
+
const seg = path12[i];
|
|
3575
3463
|
if (typeof current === "string") {
|
|
3576
3464
|
return current === "unknown" || current === "object" || current === "array" ? "opaque" : "opaque";
|
|
3577
3465
|
}
|
|
@@ -3722,8 +3610,8 @@ function validateCodeModules(flow2, rootDir) {
|
|
|
3722
3610
|
const stepPath = `${pathPrefix}[${i}]`;
|
|
3723
3611
|
if (step.type === "code" && step.code?.module) {
|
|
3724
3612
|
const m = step.code.module;
|
|
3725
|
-
const abs =
|
|
3726
|
-
if (!
|
|
3613
|
+
const abs = path4.resolve(rootDir, m);
|
|
3614
|
+
if (!fs4.existsSync(abs)) {
|
|
3727
3615
|
errors.push({
|
|
3728
3616
|
path: `${stepPath}.code.module`,
|
|
3729
3617
|
message: `Code module "${m}" not found at ${abs}`
|
|
@@ -3752,8 +3640,8 @@ function validateCodeModules(flow2, rootDir) {
|
|
|
3752
3640
|
}
|
|
3753
3641
|
|
|
3754
3642
|
// src/commands/flow.ts
|
|
3755
|
-
import
|
|
3756
|
-
import
|
|
3643
|
+
import fs5 from "fs";
|
|
3644
|
+
import path5 from "path";
|
|
3757
3645
|
function getConfig2() {
|
|
3758
3646
|
const apiKey = getApiKey();
|
|
3759
3647
|
if (!apiKey) {
|
|
@@ -3811,7 +3699,7 @@ async function flowCreateCommand(key, options) {
|
|
|
3811
3699
|
if (raw.startsWith("@")) {
|
|
3812
3700
|
const filePath = raw.slice(1);
|
|
3813
3701
|
try {
|
|
3814
|
-
raw =
|
|
3702
|
+
raw = fs5.readFileSync(filePath, "utf-8");
|
|
3815
3703
|
} catch (err) {
|
|
3816
3704
|
error(`Cannot read file "${filePath}": ${err.message}`);
|
|
3817
3705
|
}
|
|
@@ -4041,9 +3929,9 @@ async function flowValidateCommand(keyOrPath) {
|
|
|
4041
3929
|
rootDir = loaded.rootDir;
|
|
4042
3930
|
} catch {
|
|
4043
3931
|
const flowPath = resolveFlowPath(keyOrPath);
|
|
4044
|
-
const content =
|
|
3932
|
+
const content = fs5.readFileSync(flowPath, "utf-8");
|
|
4045
3933
|
flowData = JSON.parse(content);
|
|
4046
|
-
rootDir =
|
|
3934
|
+
rootDir = path5.dirname(flowPath);
|
|
4047
3935
|
}
|
|
4048
3936
|
} catch (err) {
|
|
4049
3937
|
spinner5.stop("Validation failed");
|
|
@@ -4866,11 +4754,11 @@ function handleId(response, config2, records) {
|
|
|
4866
4754
|
}
|
|
4867
4755
|
|
|
4868
4756
|
// src/lib/memory/sync/state.ts
|
|
4869
|
-
import
|
|
4870
|
-
import
|
|
4871
|
-
var SYNC_DIR =
|
|
4872
|
-
var STATE_DIR =
|
|
4873
|
-
var LEGACY_SINGLE_FILE =
|
|
4757
|
+
import fs6 from "fs";
|
|
4758
|
+
import path6 from "path";
|
|
4759
|
+
var SYNC_DIR = path6.join(".one", "sync");
|
|
4760
|
+
var STATE_DIR = path6.join(SYNC_DIR, "state");
|
|
4761
|
+
var LEGACY_SINGLE_FILE = path6.join(SYNC_DIR, "sync_state.json");
|
|
4874
4762
|
var legacyMigrationDone = false;
|
|
4875
4763
|
function rowToState(row) {
|
|
4876
4764
|
return {
|
|
@@ -4898,9 +4786,9 @@ function stateToRow(platform, model, state, lastError) {
|
|
|
4898
4786
|
async function migrateLegacyOnce() {
|
|
4899
4787
|
if (legacyMigrationDone) return;
|
|
4900
4788
|
legacyMigrationDone = true;
|
|
4901
|
-
if (
|
|
4789
|
+
if (fs6.existsSync(LEGACY_SINGLE_FILE)) {
|
|
4902
4790
|
try {
|
|
4903
|
-
const raw =
|
|
4791
|
+
const raw = fs6.readFileSync(LEGACY_SINGLE_FILE, "utf-8");
|
|
4904
4792
|
const legacy = JSON.parse(raw);
|
|
4905
4793
|
const backend = await getBackend();
|
|
4906
4794
|
for (const [platform, models] of Object.entries(legacy)) {
|
|
@@ -4910,32 +4798,32 @@ async function migrateLegacyOnce() {
|
|
|
4910
4798
|
await backend.setSyncState(stateToRow(platform, model, modelState));
|
|
4911
4799
|
}
|
|
4912
4800
|
}
|
|
4913
|
-
|
|
4801
|
+
fs6.unlinkSync(LEGACY_SINGLE_FILE);
|
|
4914
4802
|
} catch {
|
|
4915
4803
|
try {
|
|
4916
|
-
|
|
4804
|
+
fs6.unlinkSync(LEGACY_SINGLE_FILE);
|
|
4917
4805
|
} catch {
|
|
4918
4806
|
}
|
|
4919
4807
|
}
|
|
4920
4808
|
}
|
|
4921
|
-
if (
|
|
4809
|
+
if (fs6.existsSync(STATE_DIR)) {
|
|
4922
4810
|
try {
|
|
4923
4811
|
const backend = await getBackend();
|
|
4924
|
-
const platforms =
|
|
4812
|
+
const platforms = fs6.readdirSync(STATE_DIR);
|
|
4925
4813
|
for (const platform of platforms) {
|
|
4926
|
-
const platformDir =
|
|
4814
|
+
const platformDir = path6.join(STATE_DIR, platform);
|
|
4927
4815
|
let entries;
|
|
4928
4816
|
try {
|
|
4929
|
-
entries =
|
|
4817
|
+
entries = fs6.readdirSync(platformDir);
|
|
4930
4818
|
} catch {
|
|
4931
4819
|
continue;
|
|
4932
4820
|
}
|
|
4933
4821
|
for (const entry of entries) {
|
|
4934
4822
|
if (!entry.endsWith(".json")) continue;
|
|
4935
4823
|
const model = entry.slice(0, -".json".length);
|
|
4936
|
-
const filePath =
|
|
4824
|
+
const filePath = path6.join(platformDir, entry);
|
|
4937
4825
|
try {
|
|
4938
|
-
const raw =
|
|
4826
|
+
const raw = fs6.readFileSync(filePath, "utf-8");
|
|
4939
4827
|
const modelState = JSON.parse(raw);
|
|
4940
4828
|
const existing = await backend.getSyncState(platform, model);
|
|
4941
4829
|
if (!existing) {
|
|
@@ -4945,7 +4833,7 @@ async function migrateLegacyOnce() {
|
|
|
4945
4833
|
}
|
|
4946
4834
|
}
|
|
4947
4835
|
}
|
|
4948
|
-
|
|
4836
|
+
fs6.rmSync(STATE_DIR, { recursive: true, force: true });
|
|
4949
4837
|
} catch {
|
|
4950
4838
|
}
|
|
4951
4839
|
}
|
|
@@ -4989,12 +4877,12 @@ async function removeModelState(platform, model) {
|
|
|
4989
4877
|
}
|
|
4990
4878
|
|
|
4991
4879
|
// src/lib/memory/sync/lock.ts
|
|
4992
|
-
import
|
|
4993
|
-
import
|
|
4994
|
-
var LOCK_DIR_REL =
|
|
4880
|
+
import fs7 from "fs";
|
|
4881
|
+
import path7 from "path";
|
|
4882
|
+
var LOCK_DIR_REL = path7.join(".one", "sync", "locks");
|
|
4995
4883
|
var STALE_MS = 30 * 60 * 1e3;
|
|
4996
4884
|
function lockPath(platform, model) {
|
|
4997
|
-
return
|
|
4885
|
+
return path7.join(LOCK_DIR_REL, `${platform}_${model}`);
|
|
4998
4886
|
}
|
|
4999
4887
|
function isProcessAlive(pid) {
|
|
5000
4888
|
try {
|
|
@@ -5011,15 +4899,15 @@ var SyncLockError = class extends Error {
|
|
|
5011
4899
|
}
|
|
5012
4900
|
};
|
|
5013
4901
|
function acquireSyncLock(platform, model) {
|
|
5014
|
-
|
|
4902
|
+
fs7.mkdirSync(LOCK_DIR_REL, { recursive: true });
|
|
5015
4903
|
const dir = lockPath(platform, model);
|
|
5016
|
-
const pidFile =
|
|
4904
|
+
const pidFile = path7.join(dir, "pid");
|
|
5017
4905
|
try {
|
|
5018
|
-
|
|
4906
|
+
fs7.mkdirSync(dir);
|
|
5019
4907
|
} catch (err) {
|
|
5020
4908
|
const stat = (() => {
|
|
5021
4909
|
try {
|
|
5022
|
-
return
|
|
4910
|
+
return fs7.statSync(dir);
|
|
5023
4911
|
} catch {
|
|
5024
4912
|
return null;
|
|
5025
4913
|
}
|
|
@@ -5028,7 +4916,7 @@ function acquireSyncLock(platform, model) {
|
|
|
5028
4916
|
const age = Date.now() - stat.mtimeMs;
|
|
5029
4917
|
let ownerPid = null;
|
|
5030
4918
|
try {
|
|
5031
|
-
const raw =
|
|
4919
|
+
const raw = fs7.readFileSync(pidFile, "utf-8");
|
|
5032
4920
|
const parsed = parseInt(raw.trim(), 10);
|
|
5033
4921
|
if (!isNaN(parsed)) ownerPid = parsed;
|
|
5034
4922
|
} catch {
|
|
@@ -5037,8 +4925,8 @@ function acquireSyncLock(platform, model) {
|
|
|
5037
4925
|
const veryOld = age > STALE_MS;
|
|
5038
4926
|
if (ownerDead || veryOld) {
|
|
5039
4927
|
try {
|
|
5040
|
-
|
|
5041
|
-
|
|
4928
|
+
fs7.rmSync(dir, { recursive: true, force: true });
|
|
4929
|
+
fs7.mkdirSync(dir);
|
|
5042
4930
|
} catch {
|
|
5043
4931
|
throw new SyncLockError(
|
|
5044
4932
|
`Could not take over stale lock at ${dir}. Remove it manually if no sync is running.`
|
|
@@ -5055,13 +4943,13 @@ function acquireSyncLock(platform, model) {
|
|
|
5055
4943
|
}
|
|
5056
4944
|
}
|
|
5057
4945
|
try {
|
|
5058
|
-
|
|
4946
|
+
fs7.writeFileSync(pidFile, String(process.pid));
|
|
5059
4947
|
} catch {
|
|
5060
4948
|
}
|
|
5061
4949
|
return {
|
|
5062
4950
|
release() {
|
|
5063
4951
|
try {
|
|
5064
|
-
|
|
4952
|
+
fs7.rmSync(dir, { recursive: true, force: true });
|
|
5065
4953
|
} catch {
|
|
5066
4954
|
}
|
|
5067
4955
|
}
|
|
@@ -5070,9 +4958,9 @@ function acquireSyncLock(platform, model) {
|
|
|
5070
4958
|
|
|
5071
4959
|
// src/lib/memory/sync/hooks.ts
|
|
5072
4960
|
import { spawn as spawn2 } from "child_process";
|
|
5073
|
-
import
|
|
5074
|
-
import
|
|
5075
|
-
var EVENTS_DIR =
|
|
4961
|
+
import fs8 from "fs";
|
|
4962
|
+
import path8 from "path";
|
|
4963
|
+
var EVENTS_DIR = path8.join(".one", "sync", "events");
|
|
5076
4964
|
function classifyRecords(db, model, records, idField, tableExists2) {
|
|
5077
4965
|
if (!tableExists2 || records.length === 0) {
|
|
5078
4966
|
return { inserts: records, updates: [] };
|
|
@@ -5118,10 +5006,10 @@ async function fireHooks(hookCommand, events) {
|
|
|
5118
5006
|
function appendEventLog(events) {
|
|
5119
5007
|
if (events.length === 0) return;
|
|
5120
5008
|
const { platform, model } = events[0];
|
|
5121
|
-
|
|
5122
|
-
const logPath =
|
|
5009
|
+
fs8.mkdirSync(EVENTS_DIR, { recursive: true });
|
|
5010
|
+
const logPath = path8.join(EVENTS_DIR, `${platform}_${model}.jsonl`);
|
|
5123
5011
|
const lines = events.map((e) => JSON.stringify(e)).join("\n") + "\n";
|
|
5124
|
-
|
|
5012
|
+
fs8.appendFileSync(logPath, lines);
|
|
5125
5013
|
}
|
|
5126
5014
|
function runShellHook(command, events) {
|
|
5127
5015
|
return new Promise((resolve) => {
|
|
@@ -5144,10 +5032,10 @@ function runShellHook(command, events) {
|
|
|
5144
5032
|
}
|
|
5145
5033
|
|
|
5146
5034
|
// src/lib/memory/sync/mem-writer.ts
|
|
5147
|
-
function resolveWildcardPath(root,
|
|
5148
|
-
const segments =
|
|
5035
|
+
function resolveWildcardPath(root, path12) {
|
|
5036
|
+
const segments = path12.split("[]");
|
|
5149
5037
|
if (segments.length === 1) {
|
|
5150
|
-
return [getByDotPath(root,
|
|
5038
|
+
return [getByDotPath(root, path12)];
|
|
5151
5039
|
}
|
|
5152
5040
|
const recurse = (value, idx) => {
|
|
5153
5041
|
if (value === null || value === void 0) return [];
|
|
@@ -5173,8 +5061,8 @@ function resolveWildcardPath(root, path13) {
|
|
|
5173
5061
|
function extractSearchableFromPaths(record, paths) {
|
|
5174
5062
|
const parts = [];
|
|
5175
5063
|
const perPath = [];
|
|
5176
|
-
for (const
|
|
5177
|
-
const values = resolveWildcardPath(record,
|
|
5064
|
+
for (const path12 of paths) {
|
|
5065
|
+
const values = resolveWildcardPath(record, path12);
|
|
5178
5066
|
const collected = [];
|
|
5179
5067
|
const absorb = (v) => {
|
|
5180
5068
|
if (v === null || v === void 0) return;
|
|
@@ -5190,9 +5078,9 @@ function extractSearchableFromPaths(record, paths) {
|
|
|
5190
5078
|
for (const v of values) absorb(v);
|
|
5191
5079
|
if (collected.length > 0) {
|
|
5192
5080
|
parts.push(...collected);
|
|
5193
|
-
perPath.push({ path:
|
|
5081
|
+
perPath.push({ path: path12, found: true, sample: collected.join(" ").slice(0, 80) });
|
|
5194
5082
|
} else {
|
|
5195
|
-
perPath.push({ path:
|
|
5083
|
+
perPath.push({ path: path12, found: false, sample: "" });
|
|
5196
5084
|
}
|
|
5197
5085
|
}
|
|
5198
5086
|
const text5 = parts.join(" ").replace(/\s+/g, " ").trim();
|
|
@@ -5371,8 +5259,8 @@ function sleep(ms) {
|
|
|
5371
5259
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
5372
5260
|
}
|
|
5373
5261
|
function interpolate(template, record) {
|
|
5374
|
-
return template.replace(/\{?\{(\w+(?:\.\w+)*)\}\}?/g, (_,
|
|
5375
|
-
const parts =
|
|
5262
|
+
return template.replace(/\{?\{(\w+(?:\.\w+)*)\}\}?/g, (_, path12) => {
|
|
5263
|
+
const parts = path12.split(".");
|
|
5376
5264
|
let value = record;
|
|
5377
5265
|
for (const part of parts) {
|
|
5378
5266
|
if (typeof value !== "object" || value === null) return "";
|
|
@@ -5400,8 +5288,8 @@ function deepMerge(target, source) {
|
|
|
5400
5288
|
}
|
|
5401
5289
|
return result;
|
|
5402
5290
|
}
|
|
5403
|
-
function getByDotPath2(obj,
|
|
5404
|
-
const parts =
|
|
5291
|
+
function getByDotPath2(obj, path12) {
|
|
5292
|
+
const parts = path12.split(".");
|
|
5405
5293
|
let current = obj;
|
|
5406
5294
|
for (const part of parts) {
|
|
5407
5295
|
if (current === null || current === void 0 || typeof current !== "object") return void 0;
|
|
@@ -5410,8 +5298,8 @@ function getByDotPath2(obj, path13) {
|
|
|
5410
5298
|
return current;
|
|
5411
5299
|
}
|
|
5412
5300
|
function stripExcludedFields(obj, paths) {
|
|
5413
|
-
for (const
|
|
5414
|
-
stripOnePath(obj,
|
|
5301
|
+
for (const path12 of paths) {
|
|
5302
|
+
stripOnePath(obj, path12.replace(/\[\]/g, ".*").split("."));
|
|
5415
5303
|
}
|
|
5416
5304
|
}
|
|
5417
5305
|
function stripOnePath(obj, parts) {
|
|
@@ -5480,7 +5368,7 @@ async function enrichPhase(api, db, config2, model, idField, connectionKey, plat
|
|
|
5480
5368
|
}
|
|
5481
5369
|
let detailAction;
|
|
5482
5370
|
try {
|
|
5483
|
-
detailAction = await api
|
|
5371
|
+
detailAction = (await resolveActionDetails(api, config2.actionId)).details;
|
|
5484
5372
|
} catch (err) {
|
|
5485
5373
|
throw new Error(
|
|
5486
5374
|
`Enrich: could not load action ${config2.actionId}: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -5741,8 +5629,8 @@ function sleep2(ms) {
|
|
|
5741
5629
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
5742
5630
|
}
|
|
5743
5631
|
function stripFields(record, paths) {
|
|
5744
|
-
for (const
|
|
5745
|
-
stripOnePath2(record,
|
|
5632
|
+
for (const path12 of paths) {
|
|
5633
|
+
stripOnePath2(record, path12.split("."));
|
|
5746
5634
|
}
|
|
5747
5635
|
}
|
|
5748
5636
|
function stripOnePath2(obj, parts) {
|
|
@@ -5832,7 +5720,7 @@ async function syncModel(api, profile, options) {
|
|
|
5832
5720
|
updateModelState(platform, model, { status: "failed", pagesProcessed, lastCursor }),
|
|
5833
5721
|
(async () => {
|
|
5834
5722
|
try {
|
|
5835
|
-
const { getBackend: getBackend2 } = await import("./runtime-
|
|
5723
|
+
const { getBackend: getBackend2 } = await import("./runtime-3NDWRLXL.js");
|
|
5836
5724
|
const backend = await getBackend2();
|
|
5837
5725
|
await Promise.race([
|
|
5838
5726
|
backend.close(),
|
|
@@ -5909,7 +5797,7 @@ async function syncModel(api, profile, options) {
|
|
|
5909
5797
|
queryParams[param] = dateValue;
|
|
5910
5798
|
}
|
|
5911
5799
|
}
|
|
5912
|
-
const actionDetails = await api
|
|
5800
|
+
const { details: actionDetails } = await resolveActionDetails(api, profile.actionId);
|
|
5913
5801
|
if (actionDetails.tags?.includes("custom")) {
|
|
5914
5802
|
throw new Error(
|
|
5915
5803
|
`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.`
|
|
@@ -6187,7 +6075,7 @@ async function syncModel(api, profile, options) {
|
|
|
6187
6075
|
db.exec(`DROP TABLE IF EXISTS _seen_ids`);
|
|
6188
6076
|
}
|
|
6189
6077
|
if (options.toMemory !== false) {
|
|
6190
|
-
const backend = await (await import("./runtime-
|
|
6078
|
+
const backend = await (await import("./runtime-3NDWRLXL.js")).getBackend();
|
|
6191
6079
|
const type = `${platform}/${model}`;
|
|
6192
6080
|
const existing = await backend.listKeysByType(type);
|
|
6193
6081
|
const sourcePrefix = `${type}:`;
|
|
@@ -6267,7 +6155,7 @@ async function syncModel(api, profile, options) {
|
|
|
6267
6155
|
let statusCounts;
|
|
6268
6156
|
if (options.toMemory !== false) {
|
|
6269
6157
|
try {
|
|
6270
|
-
const backend = await (await import("./runtime-
|
|
6158
|
+
const backend = await (await import("./runtime-3NDWRLXL.js")).getBackend();
|
|
6271
6159
|
const typeName = `${platform}/${model}`;
|
|
6272
6160
|
const [active, archived] = await Promise.all([
|
|
6273
6161
|
backend.count(typeName, { status: "active" }),
|
|
@@ -6763,20 +6651,20 @@ function inferProfileFromKnowledge(knowledge, modelName, platform) {
|
|
|
6763
6651
|
|
|
6764
6652
|
// src/lib/memory/sync/schedule.ts
|
|
6765
6653
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
6766
|
-
import fs11 from "fs";
|
|
6767
|
-
import os6 from "os";
|
|
6768
|
-
import path11 from "path";
|
|
6769
|
-
|
|
6770
|
-
// src/lib/memory/sync/schedule-registry.ts
|
|
6771
6654
|
import fs10 from "fs";
|
|
6772
6655
|
import os5 from "os";
|
|
6773
6656
|
import path10 from "path";
|
|
6774
|
-
|
|
6775
|
-
|
|
6657
|
+
|
|
6658
|
+
// src/lib/memory/sync/schedule-registry.ts
|
|
6659
|
+
import fs9 from "fs";
|
|
6660
|
+
import os4 from "os";
|
|
6661
|
+
import path9 from "path";
|
|
6662
|
+
var REGISTRY_DIR = path9.join(os4.homedir(), ".one", "sync");
|
|
6663
|
+
var REGISTRY_FILE = path9.join(REGISTRY_DIR, "schedules.json");
|
|
6776
6664
|
function readRaw() {
|
|
6777
6665
|
try {
|
|
6778
|
-
if (!
|
|
6779
|
-
const raw =
|
|
6666
|
+
if (!fs9.existsSync(REGISTRY_FILE)) return { schedules: [] };
|
|
6667
|
+
const raw = fs9.readFileSync(REGISTRY_FILE, "utf-8");
|
|
6780
6668
|
const parsed = JSON.parse(raw);
|
|
6781
6669
|
if (!parsed || !Array.isArray(parsed.schedules)) return { schedules: [] };
|
|
6782
6670
|
return parsed;
|
|
@@ -6785,13 +6673,13 @@ function readRaw() {
|
|
|
6785
6673
|
}
|
|
6786
6674
|
}
|
|
6787
6675
|
function writeRaw(file) {
|
|
6788
|
-
|
|
6676
|
+
fs9.mkdirSync(REGISTRY_DIR, { recursive: true });
|
|
6789
6677
|
const tmp = REGISTRY_FILE + ".tmp";
|
|
6790
|
-
|
|
6791
|
-
|
|
6678
|
+
fs9.writeFileSync(tmp, JSON.stringify(file, null, 2));
|
|
6679
|
+
fs9.renameSync(tmp, REGISTRY_FILE);
|
|
6792
6680
|
}
|
|
6793
6681
|
function makeScheduleId(platform, cwd) {
|
|
6794
|
-
const slug =
|
|
6682
|
+
const slug = path9.basename(cwd).replace(/[^a-zA-Z0-9_-]/g, "-").toLowerCase();
|
|
6795
6683
|
return `${platform}-${slug}`;
|
|
6796
6684
|
}
|
|
6797
6685
|
function listRegistered() {
|
|
@@ -6825,7 +6713,7 @@ function removeRegistered(id) {
|
|
|
6825
6713
|
|
|
6826
6714
|
// src/lib/memory/sync/schedule.ts
|
|
6827
6715
|
var MARKER = "# one-sync";
|
|
6828
|
-
var LOG_DIR_REL =
|
|
6716
|
+
var LOG_DIR_REL = path10.join(".one", "sync", "logs");
|
|
6829
6717
|
function durationToCron(every) {
|
|
6830
6718
|
const match = every.match(/^(\d+)([mhd])$/);
|
|
6831
6719
|
if (!match) return null;
|
|
@@ -6858,13 +6746,13 @@ function cronExprToDuration(expr) {
|
|
|
6858
6746
|
return null;
|
|
6859
6747
|
}
|
|
6860
6748
|
function isWindows() {
|
|
6861
|
-
return
|
|
6749
|
+
return os5.platform() === "win32";
|
|
6862
6750
|
}
|
|
6863
6751
|
function resolveOneBinary() {
|
|
6864
6752
|
try {
|
|
6865
6753
|
const entry = process.argv[1];
|
|
6866
|
-
if (entry &&
|
|
6867
|
-
return
|
|
6754
|
+
if (entry && fs10.existsSync(entry)) {
|
|
6755
|
+
return fs10.realpathSync(entry);
|
|
6868
6756
|
}
|
|
6869
6757
|
} catch {
|
|
6870
6758
|
}
|
|
@@ -6942,7 +6830,7 @@ function migrateLegacyCronEntries() {
|
|
|
6942
6830
|
const modelsMatch = command.match(/--models\s+(\S+)/);
|
|
6943
6831
|
const models = modelsMatch ? modelsMatch[1].split(",") : void 0;
|
|
6944
6832
|
const logMatch = command.match(/>>\s+"([^"]+)"/);
|
|
6945
|
-
const logFile = logMatch ? logMatch[1] :
|
|
6833
|
+
const logFile = logMatch ? logMatch[1] : path10.resolve(cwd, LOG_DIR_REL, `${platform}.log`);
|
|
6946
6834
|
const id = makeScheduleId(platform, cwd);
|
|
6947
6835
|
if (registeredIds.has(id)) continue;
|
|
6948
6836
|
upsertRegistered({
|
|
@@ -6976,9 +6864,9 @@ function addSchedule(opts) {
|
|
|
6976
6864
|
const cwd = process.cwd();
|
|
6977
6865
|
const id = makeScheduleId(opts.platform, cwd);
|
|
6978
6866
|
const replaced = getRegistered(id) !== void 0;
|
|
6979
|
-
const logDir =
|
|
6980
|
-
|
|
6981
|
-
const logFile =
|
|
6867
|
+
const logDir = path10.join(cwd, LOG_DIR_REL);
|
|
6868
|
+
fs10.mkdirSync(logDir, { recursive: true });
|
|
6869
|
+
const logFile = path10.join(logDir, `${opts.platform}.log`);
|
|
6982
6870
|
const entry = {
|
|
6983
6871
|
id,
|
|
6984
6872
|
platform: opts.platform,
|
|
@@ -7032,15 +6920,15 @@ function removeSchedule(idOrPlatform, options) {
|
|
|
7032
6920
|
function scheduleStatus() {
|
|
7033
6921
|
const entries = listSchedules();
|
|
7034
6922
|
return entries.map((entry) => {
|
|
7035
|
-
const logExists =
|
|
7036
|
-
const logSize = logExists ?
|
|
6923
|
+
const logExists = fs10.existsSync(entry.logFile);
|
|
6924
|
+
const logSize = logExists ? fs10.statSync(entry.logFile).size : 0;
|
|
7037
6925
|
let logTail = [];
|
|
7038
6926
|
let lastRunAt = null;
|
|
7039
6927
|
if (logExists) {
|
|
7040
6928
|
try {
|
|
7041
|
-
lastRunAt =
|
|
6929
|
+
lastRunAt = fs10.statSync(entry.logFile).mtime.toISOString();
|
|
7042
6930
|
if (logSize > 0) {
|
|
7043
|
-
const content =
|
|
6931
|
+
const content = fs10.readFileSync(entry.logFile, "utf-8");
|
|
7044
6932
|
logTail = content.trim().split("\n").slice(-10);
|
|
7045
6933
|
}
|
|
7046
6934
|
} catch {
|
|
@@ -7048,8 +6936,8 @@ function scheduleStatus() {
|
|
|
7048
6936
|
}
|
|
7049
6937
|
let drift = "ok";
|
|
7050
6938
|
if (!entry.cronInstalled) drift = "missing-cron";
|
|
7051
|
-
else if (!
|
|
7052
|
-
else if (!
|
|
6939
|
+
else if (!fs10.existsSync(entry.nodeBin)) drift = "stale-node-bin";
|
|
6940
|
+
else if (!fs10.existsSync(entry.cliBin)) drift = "stale-cli-bin";
|
|
7053
6941
|
return { entry, logExists, logSize, logTail, lastRunAt, drift };
|
|
7054
6942
|
});
|
|
7055
6943
|
}
|
|
@@ -7322,11 +7210,11 @@ function isNoise(s) {
|
|
|
7322
7210
|
if (/^-?\d+(\.\d+)?([eE][-+]?\d+)?$/.test(s)) return true;
|
|
7323
7211
|
return false;
|
|
7324
7212
|
}
|
|
7325
|
-
function recordSample(stats,
|
|
7326
|
-
let s = stats.get(
|
|
7213
|
+
function recordSample(stats, path12, value, jsType, recordIndex, totalSamples) {
|
|
7214
|
+
let s = stats.get(path12);
|
|
7327
7215
|
if (!s) {
|
|
7328
7216
|
s = {
|
|
7329
|
-
path:
|
|
7217
|
+
path: path12,
|
|
7330
7218
|
total: totalSamples,
|
|
7331
7219
|
recordIndices: /* @__PURE__ */ new Set(),
|
|
7332
7220
|
lenSum: 0,
|
|
@@ -7335,7 +7223,7 @@ function recordSample(stats, path13, value, jsType, recordIndex, totalSamples) {
|
|
|
7335
7223
|
primaryType: jsType,
|
|
7336
7224
|
examples: []
|
|
7337
7225
|
};
|
|
7338
|
-
stats.set(
|
|
7226
|
+
stats.set(path12, s);
|
|
7339
7227
|
}
|
|
7340
7228
|
s.recordIndices.add(recordIndex);
|
|
7341
7229
|
s.lenSum += value.length;
|
|
@@ -7344,28 +7232,28 @@ function recordSample(stats, path13, value, jsType, recordIndex, totalSamples) {
|
|
|
7344
7232
|
if (s.primaryType !== jsType) s.primaryType = "mixed";
|
|
7345
7233
|
if (s.examples.length < 3 && value.length < 200) s.examples.push(value);
|
|
7346
7234
|
}
|
|
7347
|
-
function walkRecord(record,
|
|
7235
|
+
function walkRecord(record, path12, stats, recordIndex, totalSamples) {
|
|
7348
7236
|
if (record === null || record === void 0) return;
|
|
7349
7237
|
if (typeof record === "string") {
|
|
7350
7238
|
const trimmed = record.trim();
|
|
7351
|
-
if (trimmed) recordSample(stats,
|
|
7239
|
+
if (trimmed) recordSample(stats, path12, trimmed, "string", recordIndex, totalSamples);
|
|
7352
7240
|
return;
|
|
7353
7241
|
}
|
|
7354
7242
|
if (typeof record === "number" || typeof record === "boolean") {
|
|
7355
7243
|
const str = String(record);
|
|
7356
7244
|
const kind = typeof record === "number" ? "number" : "boolean";
|
|
7357
|
-
if (str) recordSample(stats,
|
|
7245
|
+
if (str) recordSample(stats, path12, str, kind, recordIndex, totalSamples);
|
|
7358
7246
|
return;
|
|
7359
7247
|
}
|
|
7360
7248
|
if (Array.isArray(record)) {
|
|
7361
|
-
const childPath =
|
|
7249
|
+
const childPath = path12 ? `${path12}[]` : "[]";
|
|
7362
7250
|
for (const item of record) walkRecord(item, childPath, stats, recordIndex, totalSamples);
|
|
7363
7251
|
return;
|
|
7364
7252
|
}
|
|
7365
7253
|
if (typeof record === "object") {
|
|
7366
7254
|
for (const [key, value] of Object.entries(record)) {
|
|
7367
7255
|
if (key.startsWith("_")) continue;
|
|
7368
|
-
const childPath =
|
|
7256
|
+
const childPath = path12 ? `${path12}.${key}` : key;
|
|
7369
7257
|
walkRecord(value, childPath, stats, recordIndex, totalSamples);
|
|
7370
7258
|
}
|
|
7371
7259
|
}
|
|
@@ -7574,8 +7462,8 @@ async function syncInitCommand(platform, model, options) {
|
|
|
7574
7462
|
}
|
|
7575
7463
|
if (actionId && !builtin) {
|
|
7576
7464
|
try {
|
|
7577
|
-
const
|
|
7578
|
-
inferred = inferProfileFromKnowledge(
|
|
7465
|
+
const { details } = await resolveActionDetails(api, actionId);
|
|
7466
|
+
inferred = inferProfileFromKnowledge(details.knowledge, model, platform);
|
|
7579
7467
|
if (inferred.pagination) template.pagination = inferred.pagination;
|
|
7580
7468
|
if (inferred.resultsPath) template.resultsPath = inferred.resultsPath;
|
|
7581
7469
|
if (inferred.idField) template.idField = inferred.idField;
|
|
@@ -7771,7 +7659,7 @@ function buildSearchablePreview(profile, samples) {
|
|
|
7771
7659
|
const first = samples[0];
|
|
7772
7660
|
const paths = getSearchablePaths(profile);
|
|
7773
7661
|
if (paths) {
|
|
7774
|
-
const perPathAgg = paths.map((
|
|
7662
|
+
const perPathAgg = paths.map((path12) => ({ path: path12, hits: 0, total: samples.length, sample: "" }));
|
|
7775
7663
|
for (const record of samples) {
|
|
7776
7664
|
const { paths: perPath } = extractSearchableFromPaths(record, paths);
|
|
7777
7665
|
perPath.forEach((p10, i) => {
|
|
@@ -7900,7 +7788,7 @@ ${result.total} results`);
|
|
|
7900
7788
|
}
|
|
7901
7789
|
}
|
|
7902
7790
|
async function syncSqlCommand(platformModel, sql) {
|
|
7903
|
-
const { syncSqlCommand: runSyncSql } = await import("./sql-
|
|
7791
|
+
const { syncSqlCommand: runSyncSql } = await import("./sql-ZABEXIXW.js");
|
|
7904
7792
|
await runSyncSql(platformModel, sql);
|
|
7905
7793
|
}
|
|
7906
7794
|
async function syncDeleteCommand(platformModel, options) {
|
|
@@ -7978,7 +7866,7 @@ async function syncDeleteCommand(platformModel, options) {
|
|
|
7978
7866
|
async function maybeAutoMigrateLegacy(platform, models) {
|
|
7979
7867
|
const dbSize = getDatabaseSize(platform);
|
|
7980
7868
|
if (!dbSize || dbSize === "0 B") return;
|
|
7981
|
-
const { getBackend: getBackend2 } = await import("./runtime-
|
|
7869
|
+
const { getBackend: getBackend2 } = await import("./runtime-3NDWRLXL.js");
|
|
7982
7870
|
const backend = await getBackend2();
|
|
7983
7871
|
let memoryHasData = false;
|
|
7984
7872
|
for (const model of models) {
|
|
@@ -7994,7 +7882,7 @@ async function maybeAutoMigrateLegacy(platform, models) {
|
|
|
7994
7882
|
` detected legacy .one/sync/data/${platform}.db (${dbSize}) \u2014 auto-migrating into memory before sync.
|
|
7995
7883
|
`
|
|
7996
7884
|
);
|
|
7997
|
-
const { memMigrateCommand: memMigrateCommand3 } = await import("./migrate-
|
|
7885
|
+
const { memMigrateCommand: memMigrateCommand3 } = await import("./migrate-VV3VOXWJ.js");
|
|
7998
7886
|
await memMigrateCommand3({ platform, yes: true });
|
|
7999
7887
|
return;
|
|
8000
7888
|
}
|
|
@@ -8003,7 +7891,7 @@ async function maybeAutoMigrateLegacy(platform, models) {
|
|
|
8003
7891
|
initialValue: true
|
|
8004
7892
|
});
|
|
8005
7893
|
if (p7.isCancel(shouldMigrate) || !shouldMigrate) return;
|
|
8006
|
-
const { memMigrateCommand: memMigrateCommand2 } = await import("./migrate-
|
|
7894
|
+
const { memMigrateCommand: memMigrateCommand2 } = await import("./migrate-VV3VOXWJ.js");
|
|
8007
7895
|
await memMigrateCommand2({ platform, yes: true });
|
|
8008
7896
|
}
|
|
8009
7897
|
async function syncSuggestSearchableCommand(platformModel, options = {}) {
|
|
@@ -8064,7 +7952,7 @@ async function syncSuggestSearchableCommand(platformModel, options = {}) {
|
|
|
8064
7952
|
async function syncListCommand(platform) {
|
|
8065
7953
|
const profiles = listProfiles(platform);
|
|
8066
7954
|
const state = await readSyncState();
|
|
8067
|
-
const { getBackend: getBackend2 } = await import("./runtime-
|
|
7955
|
+
const { getBackend: getBackend2 } = await import("./runtime-3NDWRLXL.js");
|
|
8068
7956
|
const backend = await getBackend2();
|
|
8069
7957
|
const syncs = await Promise.all(profiles.map(async (p10) => {
|
|
8070
7958
|
const modelState = state[p10.platform]?.[p10.model];
|
|
@@ -8702,16 +8590,16 @@ function projectEmbeddingApiKey(cfg) {
|
|
|
8702
8590
|
}
|
|
8703
8591
|
function redactSecrets(cfg) {
|
|
8704
8592
|
const copy = JSON.parse(JSON.stringify(cfg));
|
|
8705
|
-
for (const
|
|
8706
|
-
const val = getPath(copy,
|
|
8593
|
+
for (const path12 of SECRET_PATHS) {
|
|
8594
|
+
const val = getPath(copy, path12);
|
|
8707
8595
|
if (typeof val === "string" && val.length > 0) {
|
|
8708
|
-
setPath(copy,
|
|
8596
|
+
setPath(copy, path12, `${val.slice(0, 6)}\u2026(redacted, use --show-secrets)`);
|
|
8709
8597
|
}
|
|
8710
8598
|
}
|
|
8711
8599
|
return copy;
|
|
8712
8600
|
}
|
|
8713
|
-
function getPath(obj,
|
|
8714
|
-
const parts =
|
|
8601
|
+
function getPath(obj, path12) {
|
|
8602
|
+
const parts = path12.split(".");
|
|
8715
8603
|
let cur = obj;
|
|
8716
8604
|
for (const part of parts) {
|
|
8717
8605
|
if (cur == null || typeof cur !== "object") return void 0;
|
|
@@ -8719,8 +8607,8 @@ function getPath(obj, path13) {
|
|
|
8719
8607
|
}
|
|
8720
8608
|
return cur;
|
|
8721
8609
|
}
|
|
8722
|
-
function setPath(obj,
|
|
8723
|
-
const parts =
|
|
8610
|
+
function setPath(obj, path12, value) {
|
|
8611
|
+
const parts = path12.split(".");
|
|
8724
8612
|
let cur = obj;
|
|
8725
8613
|
for (let i = 0; i < parts.length - 1; i++) {
|
|
8726
8614
|
const part = parts[i];
|
|
@@ -8730,8 +8618,8 @@ function setPath(obj, path13, value) {
|
|
|
8730
8618
|
cur[parts[parts.length - 1]] = value;
|
|
8731
8619
|
return obj;
|
|
8732
8620
|
}
|
|
8733
|
-
function unsetPath(obj,
|
|
8734
|
-
const parts =
|
|
8621
|
+
function unsetPath(obj, path12) {
|
|
8622
|
+
const parts = path12.split(".");
|
|
8735
8623
|
let cur = obj;
|
|
8736
8624
|
for (let i = 0; i < parts.length - 1; i++) {
|
|
8737
8625
|
const part = parts[i];
|
|
@@ -8982,7 +8870,7 @@ async function memDoctorCommand() {
|
|
|
8982
8870
|
}
|
|
8983
8871
|
if (cfg.embedding.provider === "openai") {
|
|
8984
8872
|
try {
|
|
8985
|
-
const { embed: embed2 } = await import("./embedding-
|
|
8873
|
+
const { embed: embed2 } = await import("./embedding-C3E4EAQ7.js");
|
|
8986
8874
|
const result = await embed2("connectivity check");
|
|
8987
8875
|
checks.push({
|
|
8988
8876
|
name: "OpenAI embedding provider reachable",
|
|
@@ -9040,7 +8928,7 @@ ${pc10.dim(line)}`);
|
|
|
9040
8928
|
}
|
|
9041
8929
|
|
|
9042
8930
|
// src/commands/mem/export.ts
|
|
9043
|
-
import
|
|
8931
|
+
import fs11 from "fs";
|
|
9044
8932
|
async function memExportCommand(outfile) {
|
|
9045
8933
|
requireMemoryInit();
|
|
9046
8934
|
const backend = await getBackend();
|
|
@@ -9073,14 +8961,14 @@ async function memExportCommand(outfile) {
|
|
|
9073
8961
|
}
|
|
9074
8962
|
return;
|
|
9075
8963
|
}
|
|
9076
|
-
|
|
8964
|
+
fs11.writeFileSync(outfile, lines, "utf-8");
|
|
9077
8965
|
okJson({ status: "ok", file: outfile, recordsWritten: records.length, storeTotal: stats.recordCount });
|
|
9078
8966
|
}
|
|
9079
8967
|
async function memImportCommand(file) {
|
|
9080
8968
|
requireMemoryInit();
|
|
9081
|
-
if (!
|
|
8969
|
+
if (!fs11.existsSync(file)) error(`File not found: ${file}`);
|
|
9082
8970
|
const backend = await getBackend();
|
|
9083
|
-
const raw =
|
|
8971
|
+
const raw = fs11.readFileSync(file, "utf-8");
|
|
9084
8972
|
const lines = raw.split("\n").filter((l) => l.trim().length > 0);
|
|
9085
8973
|
let inserted = 0;
|
|
9086
8974
|
let updated = 0;
|
|
@@ -9327,6 +9215,9 @@ async function cacheUpdateAllCommand() {
|
|
|
9327
9215
|
error("Not configured. Run `one init` first.");
|
|
9328
9216
|
}
|
|
9329
9217
|
const api = new OneApi(apiKey, getApiBase());
|
|
9218
|
+
const ac = getAccessControlFromAllSources();
|
|
9219
|
+
const permissions = ac.permissions || "admin";
|
|
9220
|
+
const actionIds = ac.actionIds || ["*"];
|
|
9330
9221
|
const entries = listCacheEntries();
|
|
9331
9222
|
if (entries.length === 0) {
|
|
9332
9223
|
if (isAgentMode()) {
|
|
@@ -9344,13 +9235,41 @@ async function cacheUpdateAllCommand() {
|
|
|
9344
9235
|
for (const e of entries) {
|
|
9345
9236
|
try {
|
|
9346
9237
|
if (e.type === "knowledge") {
|
|
9347
|
-
const result = await api.
|
|
9238
|
+
const result = await api.getActionDetailsWithMeta(e.entry.key);
|
|
9348
9239
|
const newEntry = makeCacheEntry(e.entry.key, result.data, result.etag);
|
|
9349
|
-
|
|
9240
|
+
writeCache(e.filePath, newEntry);
|
|
9350
9241
|
updated++;
|
|
9351
9242
|
} else {
|
|
9352
|
-
const
|
|
9353
|
-
|
|
9243
|
+
const data = e.entry.data;
|
|
9244
|
+
if (data?.platform && data?.query) {
|
|
9245
|
+
const searchType = data.searchType ?? "knowledge";
|
|
9246
|
+
const result = await api.searchActionsWithMeta(
|
|
9247
|
+
data.platform,
|
|
9248
|
+
data.query,
|
|
9249
|
+
searchType,
|
|
9250
|
+
e.entry.etag ?? void 0
|
|
9251
|
+
);
|
|
9252
|
+
if (result.status === 304) {
|
|
9253
|
+
writeCache(e.filePath, { ...e.entry, cachedAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
9254
|
+
} else {
|
|
9255
|
+
let actions2 = result.data;
|
|
9256
|
+
actions2 = filterByPermissions(actions2, permissions);
|
|
9257
|
+
actions2 = actions2.filter((a) => isActionAllowed(a.systemId, actionIds));
|
|
9258
|
+
const cleaned = actions2.map((a) => ({
|
|
9259
|
+
actionId: a.systemId,
|
|
9260
|
+
title: a.title,
|
|
9261
|
+
method: a.method,
|
|
9262
|
+
path: a.path
|
|
9263
|
+
}));
|
|
9264
|
+
writeCache(e.filePath, makeCacheEntry(
|
|
9265
|
+
e.entry.key,
|
|
9266
|
+
{ actions: cleaned, platform: data.platform, query: data.query, searchType },
|
|
9267
|
+
result.etag
|
|
9268
|
+
));
|
|
9269
|
+
}
|
|
9270
|
+
} else {
|
|
9271
|
+
writeCache(e.filePath, { ...e.entry, cachedAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
9272
|
+
}
|
|
9354
9273
|
updated++;
|
|
9355
9274
|
}
|
|
9356
9275
|
} catch (err) {
|
|
@@ -9436,6 +9355,7 @@ one --agent actions execute <platform> <actionId> <key> -d '{}' # Execute it
|
|
|
9436
9355
|
- \`--mock\` \u2014 Return example response without making an API call (useful for building UI against a response shape)
|
|
9437
9356
|
- \`--skip-validation\` \u2014 Skip input validation against the action schema
|
|
9438
9357
|
- \`--output <path>\` \u2014 Save response to a file (for binary downloads like PDFs, images, documents)
|
|
9358
|
+
- \`--no-cache\` \u2014 Bypass the cached action details and re-fetch them; the fresh details still refresh the cache (execution itself is never cached)
|
|
9439
9359
|
|
|
9440
9360
|
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.
|
|
9441
9361
|
|
|
@@ -9561,6 +9481,9 @@ one --agent actions execute <platform> <actionId> <connectionKey> [options]
|
|
|
9561
9481
|
- \`--mock\` \u2014 Return example response without making an API call
|
|
9562
9482
|
- \`--skip-validation\` \u2014 Skip input validation against the action schema
|
|
9563
9483
|
- \`--output <path>\` \u2014 Save response to a file (for binary downloads like PDFs, images, documents)
|
|
9484
|
+
- \`--no-cache\` \u2014 Bypass the cached action details and re-fetch them; the fresh details still refresh the cache (execution itself is never cached)
|
|
9485
|
+
|
|
9486
|
+
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.
|
|
9564
9487
|
|
|
9565
9488
|
**Do NOT** pass path or query parameters in \`-d\`. Use the correct flags.
|
|
9566
9489
|
|
|
@@ -9575,13 +9498,13 @@ one --agent actions execute --parallel \\
|
|
|
9575
9498
|
-- google-sheets append-row conn789 -d '{"values":["x"]}'
|
|
9576
9499
|
\`\`\`
|
|
9577
9500
|
|
|
9578
|
-
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.
|
|
9501
|
+
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.
|
|
9579
9502
|
|
|
9580
9503
|
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.
|
|
9581
9504
|
|
|
9582
|
-
Agent-mode output:
|
|
9505
|
+
Agent-mode output (each result carries its own \`_preflight\` showing whether that action's details were served from cache):
|
|
9583
9506
|
\`\`\`json
|
|
9584
|
-
{"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":{...}}]}
|
|
9507
|
+
{"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"}}]}
|
|
9585
9508
|
\`\`\`
|
|
9586
9509
|
|
|
9587
9510
|
## Input Validation
|
|
@@ -9714,7 +9637,7 @@ var GUIDE_CACHE = `# One Cache \u2014 Reference
|
|
|
9714
9637
|
|
|
9715
9638
|
## Overview
|
|
9716
9639
|
|
|
9717
|
-
The One CLI caches \`actions knowledge\` and \`actions search\` responses locally so repeated calls serve instantly from disk instead of hitting the API.
|
|
9640
|
+
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.
|
|
9718
9641
|
|
|
9719
9642
|
Cache location: \`~/.one/cache/knowledge/\` and \`~/.one/cache/search/\`
|
|
9720
9643
|
|
|
@@ -9724,6 +9647,7 @@ Cache location: \`~/.one/cache/knowledge/\` and \`~/.one/cache/search/\`
|
|
|
9724
9647
|
- **Subsequent calls (within TTL)**: serves from cache instantly, no API call
|
|
9725
9648
|
- **After TTL expires**: makes a conditional request (ETag). If content unchanged, refreshes the cache timestamp. If changed, writes fresh data.
|
|
9726
9649
|
- **Network failure with stale cache**: serves the stale cache with a warning \u2014 never fails hard when a cache exists
|
|
9650
|
+
- **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
|
|
9727
9651
|
|
|
9728
9652
|
Default TTL: 3600 seconds (1 hour). Configure via \`ONE_CACHE_TTL\` env var or \`cacheTtl\` in \`~/.one/config.json\`.
|
|
9729
9653
|
|
|
@@ -9731,8 +9655,9 @@ Default TTL: 3600 seconds (1 hour). Configure via \`ONE_CACHE_TTL\` env var or \
|
|
|
9731
9655
|
|
|
9732
9656
|
| Cached | Not Cached |
|
|
9733
9657
|
|--------|-----------|
|
|
9734
|
-
| \`actions knowledge\` (API docs, change infrequently) | \`actions execute\` (live data, always fresh) |
|
|
9658
|
+
| \`actions knowledge\` (API docs, change infrequently) | \`actions execute\` responses (live data, always fresh) |
|
|
9735
9659
|
| \`actions search\` results | \`connection list\` (changes with add/remove) |
|
|
9660
|
+
| Action details used by execute / flow / sync preflight (method, path, schema) | |
|
|
9736
9661
|
|
|
9737
9662
|
## Agent Mode \`_cache\` Metadata
|
|
9738
9663
|
|
|
@@ -9763,8 +9688,13 @@ one --agent actions knowledge <platform> <actionId> --cache-status
|
|
|
9763
9688
|
|
|
9764
9689
|
# Same for search
|
|
9765
9690
|
one --agent actions search <platform> "<query>" --no-cache
|
|
9691
|
+
|
|
9692
|
+
# Same for execute's action-details preflight (the action itself always runs live)
|
|
9693
|
+
one --agent actions execute <platform> <actionId> <key> --no-cache
|
|
9766
9694
|
\`\`\`
|
|
9767
9695
|
|
|
9696
|
+
In \`--agent\` mode, execute responses include \`"_preflight": {"cache": "hit"|"miss"}\` showing whether the action details came from disk.
|
|
9697
|
+
|
|
9768
9698
|
## Cache Management Commands
|
|
9769
9699
|
|
|
9770
9700
|
\`\`\`bash
|
|
@@ -10676,7 +10606,7 @@ function buildWorkflowIdeas(connections) {
|
|
|
10676
10606
|
}
|
|
10677
10607
|
|
|
10678
10608
|
// src/commands/logout.ts
|
|
10679
|
-
import
|
|
10609
|
+
import fs12 from "fs";
|
|
10680
10610
|
import * as p9 from "@clack/prompts";
|
|
10681
10611
|
function formatWhoami(config2, apiKey, pc13) {
|
|
10682
10612
|
const whoami = config2.whoami;
|
|
@@ -10709,12 +10639,12 @@ async function logoutCommand() {
|
|
|
10709
10639
|
const globalPath = getGlobalConfigPath();
|
|
10710
10640
|
const projectPath = getProjectConfigPath();
|
|
10711
10641
|
let cleared = false;
|
|
10712
|
-
if (
|
|
10713
|
-
|
|
10642
|
+
if (fs12.existsSync(projectPath)) {
|
|
10643
|
+
fs12.unlinkSync(projectPath);
|
|
10714
10644
|
cleared = true;
|
|
10715
10645
|
}
|
|
10716
|
-
if (
|
|
10717
|
-
|
|
10646
|
+
if (fs12.existsSync(globalPath)) {
|
|
10647
|
+
fs12.unlinkSync(globalPath);
|
|
10718
10648
|
cleared = true;
|
|
10719
10649
|
}
|
|
10720
10650
|
json({ status: cleared ? "logged_out" : "not_logged_in", message: cleared ? "Credentials cleared." : "No config found." });
|
|
@@ -10783,11 +10713,11 @@ async function logoutCommand() {
|
|
|
10783
10713
|
}
|
|
10784
10714
|
if (targetScope === "project" || targetScope === "both") {
|
|
10785
10715
|
const projectPath = getProjectConfigPath();
|
|
10786
|
-
if (
|
|
10716
|
+
if (fs12.existsSync(projectPath)) fs12.unlinkSync(projectPath);
|
|
10787
10717
|
}
|
|
10788
10718
|
if (targetScope === "global" || targetScope === "both") {
|
|
10789
10719
|
const globalPath = getGlobalConfigPath();
|
|
10790
|
-
if (
|
|
10720
|
+
if (fs12.existsSync(globalPath)) fs12.unlinkSync(globalPath);
|
|
10791
10721
|
}
|
|
10792
10722
|
p9.log.success("Credentials cleared.");
|
|
10793
10723
|
p9.log.info("Your API key is still active. Manage keys at app.withone.ai/settings");
|
|
@@ -11005,8 +10935,8 @@ config.command("reset").description("Remove the project config for the current d
|
|
|
11005
10935
|
return;
|
|
11006
10936
|
}
|
|
11007
10937
|
}
|
|
11008
|
-
const
|
|
11009
|
-
|
|
10938
|
+
const fs14 = await import("fs");
|
|
10939
|
+
fs14.unlinkSync(globalPath);
|
|
11010
10940
|
if (isAgentMode()) {
|
|
11011
10941
|
json({ deleted: true, scope: "global" });
|
|
11012
10942
|
} else {
|
|
@@ -11023,15 +10953,15 @@ config.command("reset").description("Remove the project config for the current d
|
|
|
11023
10953
|
}
|
|
11024
10954
|
return;
|
|
11025
10955
|
}
|
|
11026
|
-
const
|
|
11027
|
-
const configContent =
|
|
11028
|
-
|
|
10956
|
+
const fs13 = await import("fs");
|
|
10957
|
+
const configContent = fs13.readFileSync(resolved.path, "utf-8");
|
|
10958
|
+
fs13.unlinkSync(resolved.path);
|
|
11029
10959
|
const next = resolveConfig();
|
|
11030
|
-
|
|
11031
|
-
|
|
10960
|
+
fs13.mkdirSync(path11.dirname(resolved.path), { recursive: true });
|
|
10961
|
+
fs13.writeFileSync(resolved.path, configContent);
|
|
11032
10962
|
let fallbackLabel;
|
|
11033
10963
|
if (next.scope === "project") {
|
|
11034
|
-
fallbackLabel = `parent project config (${
|
|
10964
|
+
fallbackLabel = `parent project config (${path11.basename(next.projectRoot)})`;
|
|
11035
10965
|
} else if (next.scope === "global") {
|
|
11036
10966
|
fallbackLabel = "global config";
|
|
11037
10967
|
} else {
|
|
@@ -11040,7 +10970,7 @@ config.command("reset").description("Remove the project config for the current d
|
|
|
11040
10970
|
if (!isAgentMode()) {
|
|
11041
10971
|
const p10 = await import("@clack/prompts");
|
|
11042
10972
|
const confirmed = await p10.confirm({
|
|
11043
|
-
message: `Delete project config for ${
|
|
10973
|
+
message: `Delete project config for ${path11.basename(resolved.projectRoot)}? Will fall back to ${fallbackLabel}.`,
|
|
11044
10974
|
initialValue: false
|
|
11045
10975
|
});
|
|
11046
10976
|
if (p10.isCancel(confirmed) || !confirmed) {
|
|
@@ -11048,9 +10978,9 @@ config.command("reset").description("Remove the project config for the current d
|
|
|
11048
10978
|
return;
|
|
11049
10979
|
}
|
|
11050
10980
|
}
|
|
11051
|
-
|
|
10981
|
+
fs13.unlinkSync(resolved.path);
|
|
11052
10982
|
try {
|
|
11053
|
-
|
|
10983
|
+
fs13.rmdirSync(path11.dirname(resolved.path));
|
|
11054
10984
|
} catch {
|
|
11055
10985
|
}
|
|
11056
10986
|
if (isAgentMode()) {
|
|
@@ -11073,13 +11003,13 @@ program.command("platforms").alias("p").description("List available platforms").
|
|
|
11073
11003
|
await platformsCommand(options);
|
|
11074
11004
|
});
|
|
11075
11005
|
var actions = program.command("actions").alias("a").description("Search, explore, and execute platform actions (workflow: search \u2192 knowledge \u2192 execute)");
|
|
11076
|
-
actions.command("search <platform> <query>").description('Search for actions on a platform (e.g. one actions search gmail "send email")').option("-t, --type <type>", "execute (to run it) or knowledge (to learn about it). Default: knowledge").option("--no-cache", "
|
|
11006
|
+
actions.command("search <platform> <query>").description('Search for actions on a platform (e.g. one actions search gmail "send email")').option("-t, --type <type>", "execute (to run it) or knowledge (to learn about it). Default: knowledge").option("--no-cache", "Bypass the cache and re-fetch from the API (the fresh response still refreshes the cache)").action(async (platform, query, options) => {
|
|
11077
11007
|
await actionsSearchCommand(platform, query, options);
|
|
11078
11008
|
});
|
|
11079
|
-
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", "
|
|
11009
|
+
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", "Bypass the cache and re-fetch from the API (the fresh response still refreshes the cache)").option("--cache-status", "Print cache metadata without fetching").action(async (platform, actionId, options) => {
|
|
11080
11010
|
await actionsKnowledgeCommand(platform, actionId, options);
|
|
11081
11011
|
});
|
|
11082
|
-
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) => {
|
|
11012
|
+
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", "Bypass the cached action details and re-fetch them (the fresh details still refresh the 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) => {
|
|
11083
11013
|
if (options.parallel) {
|
|
11084
11014
|
await actionsExecuteParallelCommand();
|
|
11085
11015
|
return;
|
|
@@ -11097,7 +11027,8 @@ actions.command("execute [platform] [actionId] [connectionKey]").alias("x").allo
|
|
|
11097
11027
|
dryRun: options.dryRun,
|
|
11098
11028
|
mock: options.mock,
|
|
11099
11029
|
skipValidation: options.skipValidation,
|
|
11100
|
-
output: options.output
|
|
11030
|
+
output: options.output,
|
|
11031
|
+
cache: options.cache
|
|
11101
11032
|
});
|
|
11102
11033
|
});
|
|
11103
11034
|
var flow = program.command("flow").alias("f").description("Create, execute, and manage multi-step workflows");
|