@arbidocs/cli 0.4.74 → 0.4.76
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/CHANGELOG.md +34 -0
- package/SKILL.md +41 -4
- package/dist/index.js +371 -80
- package/dist/index.js.map +1 -1
- package/package.json +6 -5
package/dist/index.js
CHANGED
|
@@ -13,6 +13,7 @@ var client = require('@arbidocs/client');
|
|
|
13
13
|
var url = require('url');
|
|
14
14
|
var crypto = require('crypto');
|
|
15
15
|
var module$1 = require('module');
|
|
16
|
+
var yaml = require('yaml');
|
|
16
17
|
|
|
17
18
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
18
19
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -3694,7 +3695,7 @@ function getLatestVersion(skipCache = false) {
|
|
|
3694
3695
|
}
|
|
3695
3696
|
}
|
|
3696
3697
|
function getCurrentVersion() {
|
|
3697
|
-
return "0.4.
|
|
3698
|
+
return "0.4.76";
|
|
3698
3699
|
}
|
|
3699
3700
|
function readChangelog(fromVersion, toVersion) {
|
|
3700
3701
|
try {
|
|
@@ -3747,17 +3748,17 @@ function showChangelog(fromVersion, toVersion) {
|
|
|
3747
3748
|
async function checkForUpdates(autoUpdate) {
|
|
3748
3749
|
try {
|
|
3749
3750
|
const latest = getLatestVersion();
|
|
3750
|
-
if (!latest || latest === "0.4.
|
|
3751
|
+
if (!latest || latest === "0.4.76") return;
|
|
3751
3752
|
if (autoUpdate) {
|
|
3752
3753
|
warn(`
|
|
3753
|
-
Your arbi version is out of date (${"0.4.
|
|
3754
|
+
Your arbi version is out of date (${"0.4.76"} \u2192 ${latest}). Updating...`);
|
|
3754
3755
|
child_process.execSync("npm install -g @arbidocs/cli@latest", { stdio: "inherit" });
|
|
3755
|
-
showChangelog("0.4.
|
|
3756
|
+
showChangelog("0.4.76", latest);
|
|
3756
3757
|
console.log(`Updated to ${latest}.`);
|
|
3757
3758
|
} else {
|
|
3758
3759
|
warn(
|
|
3759
3760
|
`
|
|
3760
|
-
Your arbi version is out of date (${"0.4.
|
|
3761
|
+
Your arbi version is out of date (${"0.4.76"} \u2192 ${latest}).
|
|
3761
3762
|
Run "arbi update" to upgrade, or "arbi update auto" to always stay up to date.`
|
|
3762
3763
|
);
|
|
3763
3764
|
}
|
|
@@ -3789,10 +3790,10 @@ function markNagShown(latest) {
|
|
|
3789
3790
|
function hintUpdateOnError() {
|
|
3790
3791
|
try {
|
|
3791
3792
|
const cached = readCache();
|
|
3792
|
-
if (!cached || cached.latest === "0.4.
|
|
3793
|
+
if (!cached || cached.latest === "0.4.76") return;
|
|
3793
3794
|
if (!shouldShowNag(cached.latest)) return;
|
|
3794
3795
|
warn(
|
|
3795
|
-
`Your arbi version is out of date (${"0.4.
|
|
3796
|
+
`Your arbi version is out of date (${"0.4.76"} \u2192 ${cached.latest}). Run "arbi update".`
|
|
3796
3797
|
);
|
|
3797
3798
|
markNagShown(cached.latest);
|
|
3798
3799
|
} catch {
|
|
@@ -6322,10 +6323,10 @@ function registerDocsCommand(program2) {
|
|
|
6322
6323
|
if (!opts.quiet && statusIntervalMs > 0) {
|
|
6323
6324
|
statusTimer = setInterval(() => printStatus(" "), statusIntervalMs);
|
|
6324
6325
|
}
|
|
6325
|
-
const
|
|
6326
|
+
const sleep2 = (ms) => new Promise((resolve6) => setTimeout(resolve6, ms));
|
|
6326
6327
|
const backoff = async (attempt) => {
|
|
6327
6328
|
const delayMs = Math.min(1e3 * Math.pow(2, attempt), 3e4);
|
|
6328
|
-
await
|
|
6329
|
+
await sleep2(delayMs);
|
|
6329
6330
|
};
|
|
6330
6331
|
const submitBatch = async (batchIds) => {
|
|
6331
6332
|
const updates = batchIds.map((id) => ({
|
|
@@ -6437,12 +6438,12 @@ function registerDocsCommand(program2) {
|
|
|
6437
6438
|
}
|
|
6438
6439
|
submitted += 1;
|
|
6439
6440
|
if (intervalMs > 0 && j < batch.length - 1) {
|
|
6440
|
-
await
|
|
6441
|
+
await sleep2(intervalMs);
|
|
6441
6442
|
}
|
|
6442
6443
|
}
|
|
6443
6444
|
}
|
|
6444
6445
|
if (intervalMs > 0 && i + batchSize < docIds.length) {
|
|
6445
|
-
await
|
|
6446
|
+
await sleep2(intervalMs);
|
|
6446
6447
|
}
|
|
6447
6448
|
}
|
|
6448
6449
|
} finally {
|
|
@@ -6520,19 +6521,19 @@ Processing complete: completed=${procCompleted} failed=0 elapsed=${totalElapsed
|
|
|
6520
6521
|
}
|
|
6521
6522
|
|
|
6522
6523
|
// src/commands/upload-shared.ts
|
|
6523
|
-
function printSummary(
|
|
6524
|
+
function printSummary(summary2) {
|
|
6524
6525
|
console.log("");
|
|
6525
6526
|
console.log("Upload summary:");
|
|
6526
|
-
console.log(` Files found: ${
|
|
6527
|
-
success(` Uploaded: ${
|
|
6528
|
-
if (
|
|
6529
|
-
warn(` Skipped: ${
|
|
6527
|
+
console.log(` Files found: ${summary2.totalFiles}`);
|
|
6528
|
+
success(` Uploaded: ${summary2.uploaded}`);
|
|
6529
|
+
if (summary2.skipped > 0) {
|
|
6530
|
+
warn(` Skipped: ${summary2.skipped}`);
|
|
6530
6531
|
}
|
|
6531
|
-
console.log(` Folders: ${
|
|
6532
|
-
if (
|
|
6532
|
+
console.log(` Folders: ${summary2.folders}`);
|
|
6533
|
+
if (summary2.skippedDetails.length > 0) {
|
|
6533
6534
|
console.log("");
|
|
6534
6535
|
warn("Skipped files:");
|
|
6535
|
-
for (const s of
|
|
6536
|
+
for (const s of summary2.skippedDetails) {
|
|
6536
6537
|
warn(` ${s.file_name}: ${s.reason}`);
|
|
6537
6538
|
}
|
|
6538
6539
|
}
|
|
@@ -6550,10 +6551,10 @@ function countSupportedFiles(dirPath) {
|
|
|
6550
6551
|
}
|
|
6551
6552
|
return count;
|
|
6552
6553
|
}
|
|
6553
|
-
function mergeBatchResult(
|
|
6554
|
+
function mergeBatchResult(summary2, uploadedDocs, result, sourceLabel, opts) {
|
|
6554
6555
|
for (const [folder, info] of result.folders) {
|
|
6555
|
-
|
|
6556
|
-
|
|
6556
|
+
summary2.folders += 1;
|
|
6557
|
+
summary2.totalFiles += info.fileCount;
|
|
6557
6558
|
if (!opts.json) {
|
|
6558
6559
|
success(
|
|
6559
6560
|
` ${folder || "<root>"}: ${info.fileCount} file(s) \u2192 ${info.doc_ext_ids.length} uploaded`
|
|
@@ -6564,10 +6565,10 @@ function mergeBatchResult(summary, uploadedDocs, result, sourceLabel, opts) {
|
|
|
6564
6565
|
}
|
|
6565
6566
|
for (const docId of info.doc_ext_ids) uploadedDocs.set(docId, sourceLabel);
|
|
6566
6567
|
}
|
|
6567
|
-
|
|
6568
|
-
|
|
6569
|
-
|
|
6570
|
-
|
|
6568
|
+
summary2.uploaded += result.doc_ext_ids.length;
|
|
6569
|
+
summary2.skipped += result.skipped.length;
|
|
6570
|
+
summary2.docIds.push(...result.doc_ext_ids);
|
|
6571
|
+
summary2.skippedDetails.push(...result.skipped);
|
|
6571
6572
|
}
|
|
6572
6573
|
function classifyDirectInputs(inputPaths) {
|
|
6573
6574
|
const out = [];
|
|
@@ -6632,7 +6633,7 @@ async function runDirectUploadMode(inputPaths, opts) {
|
|
|
6632
6633
|
});
|
|
6633
6634
|
const creds = store.requireCredentials();
|
|
6634
6635
|
const workspaceKey = await sdk.getRawWorkspaceKey(arbi, workspaceId, creds.signingPrivateKeyBase64);
|
|
6635
|
-
const
|
|
6636
|
+
const summary2 = {
|
|
6636
6637
|
totalFiles: 0,
|
|
6637
6638
|
uploaded: 0,
|
|
6638
6639
|
skipped: 0,
|
|
@@ -6669,7 +6670,7 @@ async function runDirectUploadMode(inputPaths, opts) {
|
|
|
6669
6670
|
warn(`No supported files found in directory: ${inp.originalPath}`);
|
|
6670
6671
|
continue;
|
|
6671
6672
|
}
|
|
6672
|
-
mergeBatchResult(
|
|
6673
|
+
mergeBatchResult(summary2, uploadedDocs, result2, inp.originalPath, opts);
|
|
6673
6674
|
if (!opts.json) {
|
|
6674
6675
|
success(
|
|
6675
6676
|
`Uploaded directory: ${inp.originalPath} (${result2.doc_ext_ids.length} document(s) total)`
|
|
@@ -6688,7 +6689,7 @@ async function runDirectUploadMode(inputPaths, opts) {
|
|
|
6688
6689
|
warn(`No supported files found in zip: ${inp.originalPath}`);
|
|
6689
6690
|
continue;
|
|
6690
6691
|
}
|
|
6691
|
-
mergeBatchResult(
|
|
6692
|
+
mergeBatchResult(summary2, uploadedDocs, result2, inp.originalPath, opts);
|
|
6692
6693
|
if (!opts.json) {
|
|
6693
6694
|
success(
|
|
6694
6695
|
`Uploaded zip: ${inp.originalPath} (${result2.doc_ext_ids.length} document(s) total)`
|
|
@@ -6706,7 +6707,7 @@ async function runDirectUploadMode(inputPaths, opts) {
|
|
|
6706
6707
|
warn(`No supported files found in archive: ${inp.originalPath}`);
|
|
6707
6708
|
continue;
|
|
6708
6709
|
}
|
|
6709
|
-
mergeBatchResult(
|
|
6710
|
+
mergeBatchResult(summary2, uploadedDocs, result, inp.originalPath, opts);
|
|
6710
6711
|
if (!opts.json) {
|
|
6711
6712
|
success(
|
|
6712
6713
|
`Uploaded archive: ${inp.originalPath} (${result.doc_ext_ids.length} document(s) total)`
|
|
@@ -6723,11 +6724,11 @@ async function runDirectUploadMode(inputPaths, opts) {
|
|
|
6723
6724
|
folder: opts.folder,
|
|
6724
6725
|
configExtId: opts.config
|
|
6725
6726
|
});
|
|
6726
|
-
|
|
6727
|
-
|
|
6728
|
-
|
|
6729
|
-
|
|
6730
|
-
|
|
6727
|
+
summary2.totalFiles += plainFiles.length;
|
|
6728
|
+
summary2.uploaded += result.doc_ext_ids.length;
|
|
6729
|
+
summary2.skipped += result.skipped.length;
|
|
6730
|
+
summary2.docIds.push(...result.doc_ext_ids);
|
|
6731
|
+
summary2.skippedDetails.push(...result.skipped);
|
|
6731
6732
|
for (let i = 0; i < result.doc_ext_ids.length && i < plainFiles.length; i++) {
|
|
6732
6733
|
uploadedDocs.set(result.doc_ext_ids[i], path6__default.default.basename(plainFiles[i]));
|
|
6733
6734
|
}
|
|
@@ -6738,9 +6739,9 @@ async function runDirectUploadMode(inputPaths, opts) {
|
|
|
6738
6739
|
}
|
|
6739
6740
|
}
|
|
6740
6741
|
if (opts.json) {
|
|
6741
|
-
console.log(JSON.stringify(
|
|
6742
|
+
console.log(JSON.stringify(summary2));
|
|
6742
6743
|
} else {
|
|
6743
|
-
printSummary(
|
|
6744
|
+
printSummary(summary2);
|
|
6744
6745
|
}
|
|
6745
6746
|
if (willWatch && uploadedDocs.size > 0) {
|
|
6746
6747
|
const pending = new Set(uploadedDocs.keys());
|
|
@@ -6849,7 +6850,7 @@ function registerUploadCommand(program2) {
|
|
|
6849
6850
|
});
|
|
6850
6851
|
const uploadedDocs = /* @__PURE__ */ new Map();
|
|
6851
6852
|
const auth = { baseUrl: config.baseUrl, accessToken };
|
|
6852
|
-
const
|
|
6853
|
+
const summary2 = {
|
|
6853
6854
|
totalFiles: 0,
|
|
6854
6855
|
uploaded: 0,
|
|
6855
6856
|
skipped: 0,
|
|
@@ -6883,7 +6884,7 @@ function registerUploadCommand(program2) {
|
|
|
6883
6884
|
if (opts.dryRun) {
|
|
6884
6885
|
const count = countSupportedFiles2(filePath);
|
|
6885
6886
|
console.log(`${filePath}: ${count} supported file(s) would be uploaded`);
|
|
6886
|
-
|
|
6887
|
+
summary2.totalFiles += count;
|
|
6887
6888
|
continue;
|
|
6888
6889
|
}
|
|
6889
6890
|
const result = await sdk.documentsNode.uploadDirectory(auth, filePath, progressCallbacks);
|
|
@@ -6906,7 +6907,7 @@ function registerUploadCommand(program2) {
|
|
|
6906
6907
|
`Uploaded directory: ${filePath} (${result.doc_ext_ids.length} document(s) total)`
|
|
6907
6908
|
);
|
|
6908
6909
|
}
|
|
6909
|
-
updateSummary(
|
|
6910
|
+
updateSummary(summary2, result);
|
|
6910
6911
|
for (const id of result.doc_ext_ids) uploadedDocs.set(id, filePath);
|
|
6911
6912
|
} else if (filePath.toLowerCase().endsWith(".zip")) {
|
|
6912
6913
|
if (opts.dryRun) {
|
|
@@ -6931,7 +6932,7 @@ function registerUploadCommand(program2) {
|
|
|
6931
6932
|
}
|
|
6932
6933
|
success(`Uploaded zip: ${filePath} (${result.doc_ext_ids.length} document(s) total)`);
|
|
6933
6934
|
}
|
|
6934
|
-
updateSummary(
|
|
6935
|
+
updateSummary(summary2, result);
|
|
6935
6936
|
for (const id of result.doc_ext_ids) uploadedDocs.set(id, filePath);
|
|
6936
6937
|
} else if (sdk.documentsNode.ARCHIVE_EXTENSIONS.has(
|
|
6937
6938
|
filePath.slice(filePath.lastIndexOf(".")).toLowerCase()
|
|
@@ -6960,12 +6961,12 @@ function registerUploadCommand(program2) {
|
|
|
6960
6961
|
`Uploaded archive: ${filePath} (${result.doc_ext_ids.length} document(s) total)`
|
|
6961
6962
|
);
|
|
6962
6963
|
}
|
|
6963
|
-
updateSummary(
|
|
6964
|
+
updateSummary(summary2, result);
|
|
6964
6965
|
for (const id of result.doc_ext_ids) uploadedDocs.set(id, filePath);
|
|
6965
6966
|
} else {
|
|
6966
6967
|
if (opts.dryRun) {
|
|
6967
6968
|
console.log(`${filePath}: single file would be uploaded`);
|
|
6968
|
-
|
|
6969
|
+
summary2.totalFiles += 1;
|
|
6969
6970
|
continue;
|
|
6970
6971
|
}
|
|
6971
6972
|
const result = await sdk.documentsNode.uploadLocalFile(auth, filePath, {
|
|
@@ -6981,12 +6982,12 @@ function registerUploadCommand(program2) {
|
|
|
6981
6982
|
);
|
|
6982
6983
|
}
|
|
6983
6984
|
}
|
|
6984
|
-
|
|
6985
|
-
|
|
6986
|
-
|
|
6985
|
+
summary2.totalFiles += 1;
|
|
6986
|
+
summary2.uploaded += result.doc_ext_ids?.length ?? 0;
|
|
6987
|
+
summary2.docIds.push(...result.doc_ext_ids ?? []);
|
|
6987
6988
|
if (result.skipped) {
|
|
6988
|
-
|
|
6989
|
-
|
|
6989
|
+
summary2.skipped += result.skipped.length;
|
|
6990
|
+
summary2.skippedDetails.push(...result.skipped);
|
|
6990
6991
|
}
|
|
6991
6992
|
for (const id of result.doc_ext_ids ?? []) uploadedDocs.set(id, result.fileName);
|
|
6992
6993
|
}
|
|
@@ -6995,9 +6996,9 @@ function registerUploadCommand(program2) {
|
|
|
6995
6996
|
return;
|
|
6996
6997
|
}
|
|
6997
6998
|
if (opts.json) {
|
|
6998
|
-
console.log(JSON.stringify(
|
|
6999
|
+
console.log(JSON.stringify(summary2));
|
|
6999
7000
|
} else {
|
|
7000
|
-
printSummary(
|
|
7001
|
+
printSummary(summary2);
|
|
7001
7002
|
}
|
|
7002
7003
|
if (willWatch && uploadedDocs.size > 0) {
|
|
7003
7004
|
const pending = new Set(uploadedDocs.keys());
|
|
@@ -7059,17 +7060,17 @@ Connection closed. ${pending.size} document(s) still processing.`);
|
|
|
7059
7060
|
})()
|
|
7060
7061
|
);
|
|
7061
7062
|
}
|
|
7062
|
-
function updateSummary(
|
|
7063
|
+
function updateSummary(summary2, result) {
|
|
7063
7064
|
let totalFiles = 0;
|
|
7064
7065
|
for (const [, info] of result.folders) {
|
|
7065
7066
|
totalFiles += info.fileCount;
|
|
7066
|
-
|
|
7067
|
+
summary2.folders += 1;
|
|
7067
7068
|
}
|
|
7068
|
-
|
|
7069
|
-
|
|
7070
|
-
|
|
7071
|
-
|
|
7072
|
-
|
|
7069
|
+
summary2.totalFiles += totalFiles;
|
|
7070
|
+
summary2.uploaded += result.doc_ext_ids.length;
|
|
7071
|
+
summary2.skipped += result.skipped.length;
|
|
7072
|
+
summary2.docIds.push(...result.doc_ext_ids);
|
|
7073
|
+
summary2.skippedDetails.push(...result.skipped);
|
|
7073
7074
|
}
|
|
7074
7075
|
function countSupportedFiles2(dirPath) {
|
|
7075
7076
|
let count = 0;
|
|
@@ -7752,10 +7753,10 @@ Error: ${message}`))
|
|
|
7752
7753
|
saveLastMetadata(result.metadata);
|
|
7753
7754
|
}
|
|
7754
7755
|
const refs = sdk.countCitations(result.metadata);
|
|
7755
|
-
const
|
|
7756
|
-
if (
|
|
7756
|
+
const summary2 = opts.quiet !== true ? sdk.formatStreamSummary(result, elapsedTime) : "";
|
|
7757
|
+
if (summary2) {
|
|
7757
7758
|
const refSuffix = refs > 0 ? ` \xB7 ${refs} ref${refs === 1 ? "" : "s"}` : "";
|
|
7758
|
-
const text = `[${
|
|
7759
|
+
const text = `[${summary2}${refSuffix}]`;
|
|
7759
7760
|
const cols = process.stderr.columns || 80;
|
|
7760
7761
|
const pad = Math.max(0, cols - text.length);
|
|
7761
7762
|
console.error(chalk2__default.default.dim(" ".repeat(pad) + text));
|
|
@@ -9427,6 +9428,9 @@ async function runQuickstart(url) {
|
|
|
9427
9428
|
console.log(` Workspace: ${workspaceName} (${ref(workspaceId)})`);
|
|
9428
9429
|
console.log("");
|
|
9429
9430
|
dim('Try: arbi ask "hello"');
|
|
9431
|
+
dim(
|
|
9432
|
+
"Workflows with steps: arbi workflow create --name <n> --steps steps.yaml (see arbi run --help)"
|
|
9433
|
+
);
|
|
9430
9434
|
} catch (err) {
|
|
9431
9435
|
if (isExitPromptError(err)) throw err;
|
|
9432
9436
|
error(`Login failed: ${sdk.getErrorMessage(err)}`);
|
|
@@ -9793,14 +9797,59 @@ function registerTaskCommand(program2) {
|
|
|
9793
9797
|
})()
|
|
9794
9798
|
);
|
|
9795
9799
|
}
|
|
9800
|
+
function readStructured(path8) {
|
|
9801
|
+
let text;
|
|
9802
|
+
try {
|
|
9803
|
+
text = fs7.readFileSync(path8, "utf8");
|
|
9804
|
+
} catch (err) {
|
|
9805
|
+
throw new Error(`Cannot read ${path8}: ${err.message}`);
|
|
9806
|
+
}
|
|
9807
|
+
const ext = path6.extname(path8).toLowerCase();
|
|
9808
|
+
try {
|
|
9809
|
+
return ext === ".json" ? JSON.parse(text) : yaml.parse(text);
|
|
9810
|
+
} catch (err) {
|
|
9811
|
+
throw new Error(
|
|
9812
|
+
`${path8} is not valid ${ext === ".json" ? "JSON" : "YAML"}: ${err.message}`
|
|
9813
|
+
);
|
|
9814
|
+
}
|
|
9815
|
+
}
|
|
9816
|
+
function readStepsFile(path8) {
|
|
9817
|
+
try {
|
|
9818
|
+
return sdk.workflowSteps.parsePlanSteps(readStructured(path8));
|
|
9819
|
+
} catch (err) {
|
|
9820
|
+
if (err instanceof sdk.PlanStepsError) throw new Error(`${path8}: ${err.message}`);
|
|
9821
|
+
throw err;
|
|
9822
|
+
}
|
|
9823
|
+
}
|
|
9824
|
+
function readInputsFile(path8) {
|
|
9825
|
+
const value = readStructured(path8);
|
|
9826
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
9827
|
+
throw new Error(`${path8}: expected an object of input values, e.g. {"client": "Acme"}`);
|
|
9828
|
+
return value;
|
|
9829
|
+
}
|
|
9830
|
+
function collect(value, previous = []) {
|
|
9831
|
+
return [...previous, value];
|
|
9832
|
+
}
|
|
9833
|
+
|
|
9834
|
+
// src/commands/workflow.ts
|
|
9796
9835
|
function registerWorkflowCommand(program2) {
|
|
9797
|
-
const workflow = program2.command("workflow").alias("automation").description(
|
|
9798
|
-
|
|
9836
|
+
const workflow = program2.command("workflow").alias("automation").description(
|
|
9837
|
+
"Workflows (/v1/workflow): create (optionally with steps), list, update, resume, pause, run, delete"
|
|
9838
|
+
);
|
|
9839
|
+
workflow.command("create").description(
|
|
9840
|
+
"Create a workflow: at most one trigger (none = started by hand) and what it runs: --steps, --prompt, --skill or --action"
|
|
9841
|
+
).requiredOption("--name <name>", "Workflow name (required)").option(
|
|
9842
|
+
"--steps <file>",
|
|
9843
|
+
"Named steps (form/upload/agent/review) as a TaskPlanStep list in .json, .yaml or .yml"
|
|
9844
|
+
).option("--rrule <RRULE>", "Trigger: RFC-5545 recurrence rule").option("--run-at <ISO>", "Trigger: run once at this time (ISO-8601)").option("--event-kind <kind>", "Trigger: a notification type to react to").option("--after <con-id>", "Trigger: when this task (conversation) is done").option("--timezone <tz>", "IANA timezone for --rrule", "UTC").option("--action <type>", "Action: annotate_documents or email_documents").option("--documents <ids>", "Comma-separated document IDs").option("--labels <ids>", "Select documents matching these label IDs at execution time").option("--latest", "Select documents uploaded since the previous successful run").option("--tags <ids>", "Annotation field IDs for AI review").option("--overwrite", "Regenerate existing annotation answers").option(
|
|
9799
9845
|
"--auth-mode <mode>",
|
|
9800
9846
|
"scheduled_require_auth or scheduled_permanent",
|
|
9801
9847
|
"scheduled_require_auth"
|
|
9802
9848
|
).option("--event-filter <json>", "Notification attribute filters as a JSON object").option("--prompt <text>", "Instruction the agent runs").option("--skill <ref>", "Skill reference to run").option("--agent <agt-id>", "Agent to run it as (external id)").option("--workspace <wrk-id>", "Workspace to scope the workflow to (default: the current one)").option("--shared", "Share it with the workspace").option("--json", "Output as JSON").action(
|
|
9803
9849
|
(opts) => runAction(async () => {
|
|
9850
|
+
if (opts.steps && (opts.prompt || opts.skill || opts.action))
|
|
9851
|
+
throw new Error("Use --steps, or --prompt / --skill / --action, not both");
|
|
9852
|
+
const steps = opts.steps ? readStepsFile(opts.steps) : void 0;
|
|
9804
9853
|
const { arbi, workspaceId } = await resolveWorkspace();
|
|
9805
9854
|
const body = {
|
|
9806
9855
|
name: opts.name,
|
|
@@ -9842,12 +9891,16 @@ function registerWorkflowCommand(program2) {
|
|
|
9842
9891
|
if (opts.after) body.after_conversation_ext_id = opts.after;
|
|
9843
9892
|
if (opts.skill) body.skill_ref = opts.skill;
|
|
9844
9893
|
if (opts.agent) body.agent_ext_id = opts.agent;
|
|
9894
|
+
if (steps) body.plan = sdk.workflowSteps.stepsPlan(steps);
|
|
9845
9895
|
const data = await sdk.workflows.createWorkflow(arbi, body);
|
|
9846
9896
|
if (opts.json) {
|
|
9847
9897
|
printJson(data);
|
|
9848
9898
|
return;
|
|
9849
9899
|
}
|
|
9850
|
-
success(
|
|
9900
|
+
success(
|
|
9901
|
+
`Created workflow: ${data.name} (${ref(data.external_id)})${steps ? ` with ${steps.length} steps` : ""}`
|
|
9902
|
+
);
|
|
9903
|
+
if (steps) dim(`Run it: arbi workflow run ${data.external_id}`);
|
|
9851
9904
|
})()
|
|
9852
9905
|
);
|
|
9853
9906
|
workflow.command("list").description("List your workflows").option("--json", "Output as JSON").action(
|
|
@@ -9880,7 +9933,9 @@ function registerWorkflowCommand(program2) {
|
|
|
9880
9933
|
})()
|
|
9881
9934
|
);
|
|
9882
9935
|
}
|
|
9883
|
-
workflow.command("run <id>").description(
|
|
9936
|
+
workflow.command("run <id>").description(
|
|
9937
|
+
"Run a workflow now: a thread (a stepped one waits for its steps), or a document action without one"
|
|
9938
|
+
).option("--json", "Output as JSON").action(
|
|
9884
9939
|
(id, opts) => runAction(async () => {
|
|
9885
9940
|
const { arbi } = await resolveAuth();
|
|
9886
9941
|
const data = await sdk.workflows.runWorkflow(arbi, id);
|
|
@@ -9890,11 +9945,17 @@ function registerWorkflowCommand(program2) {
|
|
|
9890
9945
|
}
|
|
9891
9946
|
if (data.error) throw new Error(data.error);
|
|
9892
9947
|
success(
|
|
9893
|
-
`${data.started ? "Started" : "Submitted"}
|
|
9948
|
+
`${data.started ? "Started" : "Submitted"} workflow ${ref(id)}${data.execution_id ? ` \u2014 execution ${data.execution_id}` : ""}${data.conversation_ext_id ? ` \u2014 thread ${ref(data.conversation_ext_id)}` : ""}`
|
|
9894
9949
|
);
|
|
9950
|
+
if (!data.conversation_ext_id) return;
|
|
9951
|
+
const saved = await sdk.workflows.getWorkflow(arbi, id);
|
|
9952
|
+
if (saved.plan?.steps?.length) {
|
|
9953
|
+
dim(`Its steps: arbi run steps ${data.conversation_ext_id}`);
|
|
9954
|
+
dim(`Follow it: arbi run steps ${data.conversation_ext_id} --watch --answers`);
|
|
9955
|
+
}
|
|
9895
9956
|
})()
|
|
9896
9957
|
);
|
|
9897
|
-
workflow.command("get <id>").description("Read the complete saved
|
|
9958
|
+
workflow.command("get <id>").description("Read the complete saved workflow configuration").action(
|
|
9898
9959
|
(id) => runAction(async () => {
|
|
9899
9960
|
const { arbi } = await resolveAuth();
|
|
9900
9961
|
printJson(await sdk.workflows.getWorkflow(arbi, id));
|
|
@@ -9904,7 +9965,7 @@ function registerWorkflowCommand(program2) {
|
|
|
9904
9965
|
(id, opts) => runAction(async () => {
|
|
9905
9966
|
const { arbi } = await resolveAuth();
|
|
9906
9967
|
const data = await sdk.workflows.listWorkflowRuns(arbi, id);
|
|
9907
|
-
if (!emitListOrTable(data, opts, "This
|
|
9968
|
+
if (!emitListOrTable(data, opts, "This workflow has not run yet.")) return;
|
|
9908
9969
|
printTable(
|
|
9909
9970
|
[
|
|
9910
9971
|
{ header: "RUN", width: 10, value: (r) => String(r.id) },
|
|
@@ -9922,13 +9983,22 @@ function registerWorkflowCommand(program2) {
|
|
|
9922
9983
|
);
|
|
9923
9984
|
})()
|
|
9924
9985
|
);
|
|
9925
|
-
workflow.command("update <id>").description("Update
|
|
9986
|
+
workflow.command("update <id>").description("Update a saved workflow: its steps (--steps), and any setting from a JSON file").option("--steps <file>", "Replace its steps (TaskPlanStep list in .json, .yaml or .yml)").option("--file <path>", "JSON UpdateWorkflowRequest file").option("--json", "Output as JSON").action(
|
|
9926
9987
|
(id, opts) => runAction(async () => {
|
|
9988
|
+
if (!opts.file && !opts.steps) throw new Error("Pass --steps <file> and/or --file <path>");
|
|
9989
|
+
const steps = opts.steps ? readStepsFile(opts.steps) : void 0;
|
|
9990
|
+
const body = opts.file ? JSON.parse(fs7.readFileSync(opts.file, "utf8")) : {};
|
|
9991
|
+
if (steps)
|
|
9992
|
+
Object.assign(body, {
|
|
9993
|
+
plan: sdk.workflowSteps.stepsPlan(steps),
|
|
9994
|
+
prompt: "",
|
|
9995
|
+
skill_ref: null,
|
|
9996
|
+
skill_inputs: null
|
|
9997
|
+
});
|
|
9927
9998
|
const { arbi } = await resolveAuth();
|
|
9928
|
-
const body = JSON.parse(fs7.readFileSync(opts.file, "utf8"));
|
|
9929
9999
|
const data = await sdk.workflows.updateWorkflow(arbi, id, body);
|
|
9930
10000
|
if (opts.json) printJson(data);
|
|
9931
|
-
else success(`Updated
|
|
10001
|
+
else success(`Updated workflow ${ref(id)}${steps ? ` \u2014 ${steps.length} steps` : ""}`);
|
|
9932
10002
|
})()
|
|
9933
10003
|
);
|
|
9934
10004
|
workflow.command("delete <id>").description("Delete a workflow (tasks it already created stay)").action(
|
|
@@ -9939,6 +10009,226 @@ function registerWorkflowCommand(program2) {
|
|
|
9939
10009
|
})()
|
|
9940
10010
|
);
|
|
9941
10011
|
}
|
|
10012
|
+
function runJson(progress, answers = {}) {
|
|
10013
|
+
const c = progress.conversation;
|
|
10014
|
+
return {
|
|
10015
|
+
conversation_ext_id: c.external_id,
|
|
10016
|
+
title: c.title,
|
|
10017
|
+
waiting_on: progress.waitingOn,
|
|
10018
|
+
in_progress: c.in_progress,
|
|
10019
|
+
pending_auth_request_id: c.pending_auth_request_id ?? null,
|
|
10020
|
+
last_error: c.last_error ?? null,
|
|
10021
|
+
steps: progress.steps.map((s) => ({
|
|
10022
|
+
id: s.id,
|
|
10023
|
+
title: s.title,
|
|
10024
|
+
kind: s.kind,
|
|
10025
|
+
state: s.phase,
|
|
10026
|
+
after: s.after,
|
|
10027
|
+
answer_id: s.responseId,
|
|
10028
|
+
error: s.error,
|
|
10029
|
+
...s.responseId && answers[s.responseId] !== void 0 ? { answer: answers[s.responseId] } : {}
|
|
10030
|
+
}))
|
|
10031
|
+
};
|
|
10032
|
+
}
|
|
10033
|
+
function nextHint(progress, planSteps = []) {
|
|
10034
|
+
const id = progress.conversation.external_id;
|
|
10035
|
+
if (progress.conversation.pending_auth_request_id)
|
|
10036
|
+
return "The run is waiting for access to the workspace: approve the request in ARBI.";
|
|
10037
|
+
switch (progress.waitingOn) {
|
|
10038
|
+
case "finished":
|
|
10039
|
+
return "Every step is done or skipped.";
|
|
10040
|
+
case "agent": {
|
|
10041
|
+
const next = progress.steps.find((s) => s.phase === "running") ?? progress.steps.find((s) => s.kind === "agent" && s.phase === "ready");
|
|
10042
|
+
return `Step ${next ? `"${next.id}" ` : ""}is on its way: arbi run steps ${id} --watch`;
|
|
10043
|
+
}
|
|
10044
|
+
case "person": {
|
|
10045
|
+
const step = progress.steps.find((s) => s.kind !== "agent" && s.phase === "ready");
|
|
10046
|
+
const planned = planSteps.find((p) => p.id === step.id);
|
|
10047
|
+
const have = progress.conversation.skill_inputs ?? {};
|
|
10048
|
+
const fields = (planned ? sdk.workflowSteps.stepFields(planned) : []).filter(
|
|
10049
|
+
(f) => have[f.name] === void 0 || have[f.name] === null || have[f.name] === ""
|
|
10050
|
+
);
|
|
10051
|
+
const inputs = fields.map((f) => ` --input ${f.name}=\u2026`).join("");
|
|
10052
|
+
return `Waiting on ${step.kind} step "${step.id}": arbi run step ${id} ${step.id} complete${inputs}`;
|
|
10053
|
+
}
|
|
10054
|
+
default: {
|
|
10055
|
+
const failed = progress.steps.find((s) => s.phase === "failed");
|
|
10056
|
+
return failed ? `Step "${failed.id}" failed${failed.error ? ` (${failed.error})` : ""}: arbi run step ${id} ${failed.id} skip` : "Nothing can move: a step it waits for has not finished.";
|
|
10057
|
+
}
|
|
10058
|
+
}
|
|
10059
|
+
}
|
|
10060
|
+
function printRun(progress, answers) {
|
|
10061
|
+
const c = progress.conversation;
|
|
10062
|
+
bold(`Run ${c.external_id}${c.title ? ` \u2014 ${c.title}` : ""}`);
|
|
10063
|
+
printTable(
|
|
10064
|
+
[
|
|
10065
|
+
{ header: "STEP", width: 16, value: (r) => r.id },
|
|
10066
|
+
{ header: "KIND", width: 8, value: (r) => r.kind },
|
|
10067
|
+
{ header: "STATE", width: 9, value: (r) => r.phase },
|
|
10068
|
+
{ header: "ANSWER", width: 16, value: (r) => r.responseId ?? "" },
|
|
10069
|
+
{ header: "TITLE", width: 40, value: (r) => r.title }
|
|
10070
|
+
],
|
|
10071
|
+
progress.steps
|
|
10072
|
+
);
|
|
10073
|
+
for (const s of progress.steps) {
|
|
10074
|
+
if (s.phase === "failed" && s.error) warn(`${s.id}: ${s.error}`);
|
|
10075
|
+
if (!s.responseId || answers[s.responseId] === void 0) continue;
|
|
10076
|
+
console.log("");
|
|
10077
|
+
bold(`\u2500\u2500 ${s.id}: ${s.title} (${s.responseId})`);
|
|
10078
|
+
console.log(answers[s.responseId]);
|
|
10079
|
+
}
|
|
10080
|
+
console.log("");
|
|
10081
|
+
dim(nextHint(progress, c.plan?.steps ?? []));
|
|
10082
|
+
}
|
|
10083
|
+
async function answersFor(arbi, progress) {
|
|
10084
|
+
const ids = progress.steps.filter((s) => s.kind === "agent" && s.phase === "done" && s.responseId).map((s) => s.responseId);
|
|
10085
|
+
return sdk.work.getStepAnswers(arbi, progress.conversation.external_id, ids);
|
|
10086
|
+
}
|
|
10087
|
+
var sleep = (ms) => new Promise((resolve6) => setTimeout(resolve6, ms));
|
|
10088
|
+
var summary = (p) => p.steps.map((s) => `${s.id}:${s.phase}`).join(" ");
|
|
10089
|
+
async function watchRun(arbi, conversationId, { intervalMs, timeoutMs, quiet }) {
|
|
10090
|
+
const deadline = Date.now() + timeoutMs;
|
|
10091
|
+
let progress = await sdk.work.getRunProgress(arbi, conversationId);
|
|
10092
|
+
let last = "";
|
|
10093
|
+
const report = () => {
|
|
10094
|
+
const now = summary(progress);
|
|
10095
|
+
if (!quiet && now !== last) process.stderr.write(`${(/* @__PURE__ */ new Date()).toISOString()} ${now}
|
|
10096
|
+
`);
|
|
10097
|
+
last = now;
|
|
10098
|
+
};
|
|
10099
|
+
report();
|
|
10100
|
+
while (progress.waitingOn === "agent" && !progress.conversation.pending_auth_request_id) {
|
|
10101
|
+
if (Date.now() >= deadline) return { progress, timedOut: true };
|
|
10102
|
+
await sleep(intervalMs);
|
|
10103
|
+
progress = await sdk.work.getRunProgress(arbi, conversationId);
|
|
10104
|
+
report();
|
|
10105
|
+
}
|
|
10106
|
+
return { progress, timedOut: false };
|
|
10107
|
+
}
|
|
10108
|
+
function seconds(value, flag) {
|
|
10109
|
+
const n = Number(value);
|
|
10110
|
+
if (!Number.isFinite(n) || n <= 0) throw new Error(`${flag} must be a positive number of seconds`);
|
|
10111
|
+
return n * 1e3;
|
|
10112
|
+
}
|
|
10113
|
+
function gatherInputs(pairs, file, fields) {
|
|
10114
|
+
return {
|
|
10115
|
+
...file ? readInputsFile(file) : {},
|
|
10116
|
+
...sdk.workflowSteps.parseInputPairs(pairs, fields)
|
|
10117
|
+
};
|
|
10118
|
+
}
|
|
10119
|
+
function registerRunCommand(program2) {
|
|
10120
|
+
const run = program2.command("run").description(
|
|
10121
|
+
"Stepped workflow runs: start one from a steps file, see its steps, complete or skip a step"
|
|
10122
|
+
);
|
|
10123
|
+
run.command("start").description("Start a one-off stepped run as a work thread, without saving a workflow").requiredOption("--steps <file>", "Plan steps (TaskPlanStep list) as .json, .yaml or .yml").requiredOption("--title <title>", "The run thread's title").option("--input <name=value>", "A run input, e.g. a form field (repeatable)", collect, []).option("--inputs-file <file>", "Run inputs as a JSON or YAML object").option("--agent <agt-id>", "Agent to run the agent steps as (external id)").option("--shared", "Share the thread with the workspace").option("--json", "Output as JSON").action(
|
|
10124
|
+
(opts) => runAction(async () => {
|
|
10125
|
+
const steps = readStepsFile(opts.steps);
|
|
10126
|
+
const inputs = gatherInputs(
|
|
10127
|
+
opts.input,
|
|
10128
|
+
opts.inputsFile,
|
|
10129
|
+
steps.flatMap((s) => sdk.workflowSteps.stepFields(s))
|
|
10130
|
+
);
|
|
10131
|
+
const { arbi } = await resolveWorkspace();
|
|
10132
|
+
const created = await sdk.work.createWork(arbi, {
|
|
10133
|
+
title: opts.title,
|
|
10134
|
+
plan: sdk.workflowSteps.stepsPlan(steps),
|
|
10135
|
+
skill_inputs: Object.keys(inputs).length ? inputs : null,
|
|
10136
|
+
agent_ext_id: opts.agent ?? null,
|
|
10137
|
+
shared: opts.shared ?? null,
|
|
10138
|
+
auth_mode: "run_now_temp"
|
|
10139
|
+
});
|
|
10140
|
+
const progress = await sdk.work.getRunProgress(arbi, created.external_id);
|
|
10141
|
+
if (opts.json) {
|
|
10142
|
+
printJson(runJson(progress));
|
|
10143
|
+
return;
|
|
10144
|
+
}
|
|
10145
|
+
success(`Started run ${ref(created.external_id)} \u2014 ${opts.title}`);
|
|
10146
|
+
dim(`Follow it: arbi run steps ${created.external_id} --watch`);
|
|
10147
|
+
dim(nextHint(progress, steps));
|
|
10148
|
+
})()
|
|
10149
|
+
);
|
|
10150
|
+
run.command("steps <con-id>").description(
|
|
10151
|
+
"A run's steps and their state (pending, ready, running, done, skipped, failed), with each done agent step's answer id"
|
|
10152
|
+
).option("--answers", "Print the done agent steps' answers from the thread").option("--watch", "Poll until the run stops waiting on an agent step").option("--interval <seconds>", "Poll interval for --watch", "3").option("--timeout <seconds>", "Stop watching after this long", "600").option("--json", "Output as JSON").action(
|
|
10153
|
+
(conversationId, opts) => runAction(async () => {
|
|
10154
|
+
const intervalMs = seconds(opts.interval, "--interval");
|
|
10155
|
+
const timeoutMs = seconds(opts.timeout, "--timeout");
|
|
10156
|
+
const { arbi } = await resolveWorkspace();
|
|
10157
|
+
let progress;
|
|
10158
|
+
let timedOut = false;
|
|
10159
|
+
if (opts.watch) {
|
|
10160
|
+
;
|
|
10161
|
+
({ progress, timedOut } = await watchRun(arbi, conversationId, {
|
|
10162
|
+
intervalMs,
|
|
10163
|
+
timeoutMs,
|
|
10164
|
+
quiet: !!opts.json
|
|
10165
|
+
}));
|
|
10166
|
+
} else progress = await sdk.work.getRunProgress(arbi, conversationId);
|
|
10167
|
+
const answers = opts.answers ? await answersFor(arbi, progress) : {};
|
|
10168
|
+
if (opts.json) printJson({ ...runJson(progress, answers), timed_out: timedOut });
|
|
10169
|
+
else {
|
|
10170
|
+
printRun(progress, answers);
|
|
10171
|
+
if (timedOut) warn(`Stopped watching after ${opts.timeout}s; the run is still going.`);
|
|
10172
|
+
}
|
|
10173
|
+
})()
|
|
10174
|
+
);
|
|
10175
|
+
run.command("step <con-id> <step-id> <action>").description(
|
|
10176
|
+
"Act on a step: complete a form, upload or review step (a form takes its inputs), or skip any step"
|
|
10177
|
+
).option("--input <name=value>", "A form input (repeatable)", collect, []).option("--inputs-file <file>", "Form inputs as a JSON or YAML object").option("--json", "Output as JSON").action(
|
|
10178
|
+
(conversationId, stepId, action, opts) => runAction(async () => {
|
|
10179
|
+
if (action !== "complete" && action !== "skip")
|
|
10180
|
+
throw new Error(`Unknown action "${action}": use complete or skip`);
|
|
10181
|
+
const { arbi } = await resolveWorkspace();
|
|
10182
|
+
const before = await sdk.work.getRunProgress(arbi, conversationId);
|
|
10183
|
+
const plan = before.conversation.plan?.steps ?? [];
|
|
10184
|
+
const step = plan.find((s) => s.id === stepId);
|
|
10185
|
+
if (!step)
|
|
10186
|
+
throw new Error(
|
|
10187
|
+
`No step "${stepId}" in ${conversationId}. Its steps: ${plan.map((s) => s.id).join(", ")}`
|
|
10188
|
+
);
|
|
10189
|
+
const hasInputs = opts.input.length > 0 || !!opts.inputsFile;
|
|
10190
|
+
if (hasInputs && (action === "skip" || step.kind !== "form"))
|
|
10191
|
+
throw new Error("Only completing a form step takes --input / --inputs-file");
|
|
10192
|
+
let inputs;
|
|
10193
|
+
if (action === "complete") {
|
|
10194
|
+
if (step.kind === "agent")
|
|
10195
|
+
throw new Error(
|
|
10196
|
+
`"${stepId}" is an agent step: it runs itself. Skip it with: arbi run step ${conversationId} ${stepId} skip`
|
|
10197
|
+
);
|
|
10198
|
+
const phase = before.steps.find((s) => s.id === stepId)?.phase;
|
|
10199
|
+
if (phase === "pending") {
|
|
10200
|
+
const waits = before.steps.find((s) => s.id === stepId)?.after ?? [];
|
|
10201
|
+
throw new Error(`"${stepId}" waits for ${waits.join(", ")} to finish first`);
|
|
10202
|
+
}
|
|
10203
|
+
if (step.kind === "form") {
|
|
10204
|
+
inputs = gatherInputs(opts.input, opts.inputsFile, sdk.workflowSteps.stepFields(step));
|
|
10205
|
+
const missing = sdk.workflowSteps.missingRequiredFields(step, {
|
|
10206
|
+
...before.conversation.skill_inputs ?? {},
|
|
10207
|
+
...inputs
|
|
10208
|
+
});
|
|
10209
|
+
if (missing.length)
|
|
10210
|
+
throw new Error(
|
|
10211
|
+
`Missing required input${missing.length > 1 ? "s" : ""}: ${missing.join(", ")}. Pass ${missing.map((m) => `--input ${m}=\u2026`).join(" ")}`
|
|
10212
|
+
);
|
|
10213
|
+
}
|
|
10214
|
+
}
|
|
10215
|
+
await sdk.work.actOnStep(arbi, conversationId, {
|
|
10216
|
+
step: stepId,
|
|
10217
|
+
action,
|
|
10218
|
+
...inputs && Object.keys(inputs).length ? { inputs } : {}
|
|
10219
|
+
});
|
|
10220
|
+
const progress = await sdk.work.getRunProgress(arbi, conversationId);
|
|
10221
|
+
if (opts.json) {
|
|
10222
|
+
printJson(runJson(progress));
|
|
10223
|
+
return;
|
|
10224
|
+
}
|
|
10225
|
+
success(
|
|
10226
|
+
`${action === "complete" ? "Completed" : "Skipped"} step "${stepId}" of ${ref(conversationId)}`
|
|
10227
|
+
);
|
|
10228
|
+
dim(nextHint(progress, plan));
|
|
10229
|
+
})()
|
|
10230
|
+
);
|
|
10231
|
+
}
|
|
9942
10232
|
var MARKER_START = "# arbi-cli completion start";
|
|
9943
10233
|
var MARKER_END = "# arbi-cli completion end";
|
|
9944
10234
|
var BASH_COMPLETION = `
|
|
@@ -10172,12 +10462,12 @@ function printTree(dir, prefix, maxDepth, depth) {
|
|
|
10172
10462
|
}
|
|
10173
10463
|
}
|
|
10174
10464
|
}
|
|
10175
|
-
function humanizeTtl(
|
|
10176
|
-
if (!Number.isFinite(
|
|
10177
|
-
if (
|
|
10178
|
-
if (
|
|
10179
|
-
if (
|
|
10180
|
-
return `${Math.round(
|
|
10465
|
+
function humanizeTtl(seconds2) {
|
|
10466
|
+
if (!Number.isFinite(seconds2) || seconds2 < 0) return "";
|
|
10467
|
+
if (seconds2 < 60) return `${seconds2}s`;
|
|
10468
|
+
if (seconds2 < 3600) return `${Math.round(seconds2 / 60)}m`;
|
|
10469
|
+
if (seconds2 < 86400) return `${Math.round(seconds2 / 3600)}h`;
|
|
10470
|
+
return `${Math.round(seconds2 / 86400)}d`;
|
|
10181
10471
|
}
|
|
10182
10472
|
function registerSessionCommand(program2) {
|
|
10183
10473
|
const session = program2.command("session").description("List and manage sessions");
|
|
@@ -10239,7 +10529,7 @@ function parseAddress(value) {
|
|
|
10239
10529
|
const name = match?.[1].replace(/^"|"$/g, "");
|
|
10240
10530
|
return name ? { email, name } : { email };
|
|
10241
10531
|
}
|
|
10242
|
-
function
|
|
10532
|
+
function collect2(value, previous = []) {
|
|
10243
10533
|
return [...previous, ...value.split(",").filter((v) => v.trim())];
|
|
10244
10534
|
}
|
|
10245
10535
|
var readTextFile = (path8) => fs7__default.default.readFileSync(path8 === "-" ? 0 : path8, "utf8");
|
|
@@ -10265,7 +10555,7 @@ function buildCompose(options) {
|
|
|
10265
10555
|
};
|
|
10266
10556
|
}
|
|
10267
10557
|
function addComposeOptions(command) {
|
|
10268
|
-
return command.option("--to <addresses>", "Recipient(s), comma-separated or repeated",
|
|
10558
|
+
return command.option("--to <addresses>", "Recipient(s), comma-separated or repeated", collect2).option("--cc <addresses>", "Cc recipient(s)", collect2).option("--bcc <addresses>", "Bcc recipient(s)", collect2).option("-s, --subject <subject>", "Subject").option("--text <text>", "Plain-text body").option("--text-file <path>", "Read the plain-text body from a file (- for stdin)").option("--html <html>", "HTML body (the plain text stays as the fallback)").option("--html-file <path>", "Read the HTML body from a file (- for stdin)").option("-a, --attach <path>", "Attach a file (repeatable)", (v, prev = []) => [
|
|
10269
10559
|
...prev,
|
|
10270
10560
|
v
|
|
10271
10561
|
]).option("--json", "Output as JSON (recommended for scripting / agents)");
|
|
@@ -10997,7 +11287,7 @@ console.info = (...args) => {
|
|
|
10997
11287
|
_origInfo(...args);
|
|
10998
11288
|
};
|
|
10999
11289
|
var program = new commander.Command();
|
|
11000
|
-
program.name("arbi").description("ARBI CLI \u2014 interact with ARBI from the terminal").version("0.4.
|
|
11290
|
+
program.name("arbi").description("ARBI CLI \u2014 interact with ARBI from the terminal").version("0.4.76").showHelpAfterError(true).showSuggestionAfterError(true);
|
|
11001
11291
|
registerConfigCommand(program);
|
|
11002
11292
|
registerLoginCommand(program);
|
|
11003
11293
|
registerRegisterCommand(program);
|
|
@@ -11027,6 +11317,7 @@ registerAgentCreateCommand(program);
|
|
|
11027
11317
|
registerAgentCommand(program);
|
|
11028
11318
|
registerTaskCommand(program);
|
|
11029
11319
|
registerWorkflowCommand(program);
|
|
11320
|
+
registerRunCommand(program);
|
|
11030
11321
|
registerCompletionCommand(program);
|
|
11031
11322
|
registerListenCommand(program);
|
|
11032
11323
|
registerSessionCommand(program);
|
|
@@ -11053,7 +11344,7 @@ applyHelpGroups(program, {
|
|
|
11053
11344
|
"Search & ask:": ["ask", "find", "cite", "watch"],
|
|
11054
11345
|
"Tagging:": ["tags", "doctags"],
|
|
11055
11346
|
"Conversations & messaging:": ["convo", "dm", "listen", "notifications", "contacts"],
|
|
11056
|
-
"Agents & tasks:": ["agent", "agent-create", "task", "workflow", "agentconfig", "session"],
|
|
11347
|
+
"Agents & tasks:": ["agent", "agent-create", "task", "workflow", "run", "agentconfig", "session"],
|
|
11057
11348
|
"Account:": ["auth", "usage", "files"],
|
|
11058
11349
|
"System:": ["health", "models", "settings", "tui", "local", "update"]
|
|
11059
11350
|
});
|