@arbidocs/cli 0.3.4 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{index.cjs → index.js} +251 -153
- package/dist/index.js.map +1 -0
- package/package.json +7 -7
- package/dist/index.cjs.map +0 -1
|
@@ -6,6 +6,7 @@ var fs = require('fs');
|
|
|
6
6
|
var os = require('os');
|
|
7
7
|
var path = require('path');
|
|
8
8
|
var core = require('@arbidocs/core');
|
|
9
|
+
var chalk = require('chalk');
|
|
9
10
|
var prompts = require('@inquirer/prompts');
|
|
10
11
|
var child_process = require('child_process');
|
|
11
12
|
var sdk = require('@arbidocs/sdk');
|
|
@@ -17,6 +18,7 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
|
17
18
|
var fs__default = /*#__PURE__*/_interopDefault(fs);
|
|
18
19
|
var os__default = /*#__PURE__*/_interopDefault(os);
|
|
19
20
|
var path__default = /*#__PURE__*/_interopDefault(path);
|
|
21
|
+
var chalk__default = /*#__PURE__*/_interopDefault(chalk);
|
|
20
22
|
|
|
21
23
|
var store = new core.FileConfigStore();
|
|
22
24
|
function getConfig() {
|
|
@@ -51,6 +53,34 @@ function updateChatSession(updates) {
|
|
|
51
53
|
function clearChatSession() {
|
|
52
54
|
store.clearChatSession();
|
|
53
55
|
}
|
|
56
|
+
function success(msg) {
|
|
57
|
+
console.log(chalk__default.default.green(msg));
|
|
58
|
+
}
|
|
59
|
+
function error(msg) {
|
|
60
|
+
console.error(chalk__default.default.red(msg));
|
|
61
|
+
}
|
|
62
|
+
function warn(msg) {
|
|
63
|
+
console.error(chalk__default.default.yellow(msg));
|
|
64
|
+
}
|
|
65
|
+
function label(key, value) {
|
|
66
|
+
console.log(`${chalk__default.default.bold(key)} ${value}`);
|
|
67
|
+
}
|
|
68
|
+
function dim(msg) {
|
|
69
|
+
console.log(chalk__default.default.dim(msg));
|
|
70
|
+
}
|
|
71
|
+
function bold(msg) {
|
|
72
|
+
console.log(chalk__default.default.bold(msg));
|
|
73
|
+
}
|
|
74
|
+
function status(s) {
|
|
75
|
+
const lower = s.toLowerCase();
|
|
76
|
+
if (["healthy", "completed", "available", "online", "on"].includes(lower)) return chalk__default.default.green(s);
|
|
77
|
+
if (["failed", "error", "unavailable", "offline"].includes(lower)) return chalk__default.default.red(s);
|
|
78
|
+
if (["processing", "pending", "degraded", "warning"].includes(lower)) return chalk__default.default.yellow(s);
|
|
79
|
+
return s;
|
|
80
|
+
}
|
|
81
|
+
function ref(s) {
|
|
82
|
+
return chalk__default.default.cyan(s);
|
|
83
|
+
}
|
|
54
84
|
|
|
55
85
|
// src/commands/config-cmd.ts
|
|
56
86
|
var ALIAS_LINE = 'alias A="arbi ask"';
|
|
@@ -72,41 +102,55 @@ function registerConfigCommand(program2) {
|
|
|
72
102
|
const parsed = new URL(url);
|
|
73
103
|
const deploymentDomain = parsed.hostname;
|
|
74
104
|
updateConfig({ baseUrl: url.replace(/\/+$/, ""), deploymentDomain });
|
|
75
|
-
|
|
76
|
-
|
|
105
|
+
label("Server URL:", url);
|
|
106
|
+
label("Domain:", deploymentDomain);
|
|
77
107
|
} catch {
|
|
78
|
-
|
|
108
|
+
error(`Invalid URL: ${url}`);
|
|
79
109
|
process.exit(1);
|
|
80
110
|
}
|
|
81
111
|
});
|
|
82
112
|
config.command("show").description("Show current configuration").action(() => {
|
|
83
113
|
const cfg = getConfig();
|
|
84
114
|
if (!cfg) {
|
|
85
|
-
|
|
115
|
+
dim("Not configured. Run: arbi config set-url <url>");
|
|
86
116
|
return;
|
|
87
117
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
118
|
+
label("Server URL:", cfg.baseUrl);
|
|
119
|
+
label("Domain:", cfg.deploymentDomain);
|
|
120
|
+
label("Auto-update:", cfg.autoUpdate ? "on" : "off");
|
|
121
|
+
label("Notifications:", cfg.notifications ? "on" : "off");
|
|
91
122
|
if (cfg.selectedWorkspaceId) {
|
|
92
|
-
|
|
123
|
+
label("Workspace:", cfg.selectedWorkspaceId);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
config.command("notifications [on|off]").description("Toggle background WebSocket notifications").action((toggle) => {
|
|
127
|
+
const cfg = getConfig();
|
|
128
|
+
if (!toggle) {
|
|
129
|
+
label("Notifications:", cfg?.notifications ? "on" : "off");
|
|
130
|
+
return;
|
|
93
131
|
}
|
|
132
|
+
if (toggle !== "on" && toggle !== "off") {
|
|
133
|
+
error("Usage: arbi config notifications [on|off]");
|
|
134
|
+
process.exit(1);
|
|
135
|
+
}
|
|
136
|
+
updateConfig({ notifications: toggle === "on" });
|
|
137
|
+
success(`Notifications: ${toggle}`);
|
|
94
138
|
});
|
|
95
139
|
config.command("alias").description('Set up shell alias A for "arbi ask"').action(() => {
|
|
96
140
|
const rcPath = getShellRcPath();
|
|
97
141
|
if (isAliasInstalled(rcPath)) {
|
|
98
|
-
|
|
99
|
-
|
|
142
|
+
success(`Alias already set up in ${rcPath}`);
|
|
143
|
+
dim("Usage: A what is the meaning of life");
|
|
100
144
|
return;
|
|
101
145
|
}
|
|
102
146
|
fs.appendFileSync(rcPath, `
|
|
103
147
|
${ALIAS_MARKER}
|
|
104
148
|
${ALIAS_LINE}
|
|
105
149
|
`);
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
150
|
+
success(`Added alias A="arbi ask" to ${rcPath}`);
|
|
151
|
+
dim("");
|
|
152
|
+
dim(`Run: source ${rcPath}`);
|
|
153
|
+
dim("Then: A what is the meaning of life");
|
|
110
154
|
});
|
|
111
155
|
}
|
|
112
156
|
|
|
@@ -122,8 +166,8 @@ var messages = {
|
|
|
122
166
|
TransactionInactiveError: "A request was placed against a transaction which is currently not active, or which is finished.",
|
|
123
167
|
VersionError: "An attempt was made to open a database using a lower version than the existing version."
|
|
124
168
|
};
|
|
125
|
-
var setErrorCode = (
|
|
126
|
-
Object.defineProperty(
|
|
169
|
+
var setErrorCode = (error2, value) => {
|
|
170
|
+
Object.defineProperty(error2, "code", {
|
|
127
171
|
value,
|
|
128
172
|
writable: false,
|
|
129
173
|
enumerable: true,
|
|
@@ -3457,7 +3501,7 @@ function getLatestVersion() {
|
|
|
3457
3501
|
}
|
|
3458
3502
|
}
|
|
3459
3503
|
function getCurrentVersion() {
|
|
3460
|
-
return "0.3.
|
|
3504
|
+
return "0.3.5";
|
|
3461
3505
|
}
|
|
3462
3506
|
async function fetchChangelog(fromVersion, toVersion) {
|
|
3463
3507
|
try {
|
|
@@ -3501,19 +3545,17 @@ async function showChangelog(fromVersion, toVersion) {
|
|
|
3501
3545
|
async function checkForUpdates(autoUpdate) {
|
|
3502
3546
|
try {
|
|
3503
3547
|
const latest = getLatestVersion();
|
|
3504
|
-
if (!latest || latest === "0.3.
|
|
3548
|
+
if (!latest || latest === "0.3.5") return;
|
|
3505
3549
|
if (autoUpdate) {
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
);
|
|
3510
|
-
await showChangelog("0.3.4", latest);
|
|
3550
|
+
warn(`
|
|
3551
|
+
Your arbi version is out of date (${"0.3.5"} \u2192 ${latest}). Updating...`);
|
|
3552
|
+
await showChangelog("0.3.5", latest);
|
|
3511
3553
|
child_process.execSync("npm install -g @arbidocs/cli@latest", { stdio: "inherit" });
|
|
3512
3554
|
console.log(`Updated to ${latest}.`);
|
|
3513
3555
|
} else {
|
|
3514
|
-
|
|
3556
|
+
warn(
|
|
3515
3557
|
`
|
|
3516
|
-
Your arbi version is out of date (${"0.3.
|
|
3558
|
+
Your arbi version is out of date (${"0.3.5"} \u2192 ${latest}).
|
|
3517
3559
|
Run "arbi update" to upgrade, or "arbi update auto" to always stay up to date.`
|
|
3518
3560
|
);
|
|
3519
3561
|
}
|
|
@@ -3523,9 +3565,9 @@ Run "arbi update" to upgrade, or "arbi update auto" to always stay up to date.`
|
|
|
3523
3565
|
function hintUpdateOnError() {
|
|
3524
3566
|
try {
|
|
3525
3567
|
const cached = readCache();
|
|
3526
|
-
if (cached && cached.latest !== "0.3.
|
|
3527
|
-
|
|
3528
|
-
`Your arbi version is out of date (${"0.3.
|
|
3568
|
+
if (cached && cached.latest !== "0.3.5") {
|
|
3569
|
+
warn(
|
|
3570
|
+
`Your arbi version is out of date (${"0.3.5"} \u2192 ${cached.latest}). Run "arbi update".`
|
|
3529
3571
|
);
|
|
3530
3572
|
}
|
|
3531
3573
|
} catch {
|
|
@@ -3542,7 +3584,7 @@ function registerLoginCommand(program2) {
|
|
|
3542
3584
|
const { arbi } = await core.performPasswordLogin(config, email, pw, store);
|
|
3543
3585
|
const { data: workspaces2 } = await arbi.fetch.GET("/api/user/workspaces");
|
|
3544
3586
|
const wsList = workspaces2 || [];
|
|
3545
|
-
|
|
3587
|
+
success(`Logged in as ${email}`);
|
|
3546
3588
|
if (wsList.length === 0) {
|
|
3547
3589
|
console.log("No workspaces found.");
|
|
3548
3590
|
return;
|
|
@@ -3550,26 +3592,26 @@ function registerLoginCommand(program2) {
|
|
|
3550
3592
|
if (opts.workspace) {
|
|
3551
3593
|
const ws2 = wsList.find((w) => w.external_id === opts.workspace);
|
|
3552
3594
|
if (!ws2) {
|
|
3553
|
-
|
|
3595
|
+
error(`Workspace ${opts.workspace} not found.`);
|
|
3554
3596
|
process.exit(1);
|
|
3555
3597
|
}
|
|
3556
3598
|
updateConfig({ selectedWorkspaceId: ws2.external_id });
|
|
3557
|
-
|
|
3599
|
+
success(`Workspace: ${ws2.name} (${ref(ws2.external_id)})`);
|
|
3558
3600
|
return;
|
|
3559
3601
|
}
|
|
3560
3602
|
if (wsList.length === 1) {
|
|
3561
3603
|
updateConfig({ selectedWorkspaceId: wsList[0].external_id });
|
|
3562
|
-
|
|
3604
|
+
success(`Workspace: ${wsList[0].name} (${ref(wsList[0].external_id)})`);
|
|
3563
3605
|
return;
|
|
3564
3606
|
}
|
|
3565
3607
|
const choices = core.formatWorkspaceChoices(wsList);
|
|
3566
3608
|
const selected = await promptSelect("Select workspace", choices);
|
|
3567
3609
|
updateConfig({ selectedWorkspaceId: selected });
|
|
3568
3610
|
const ws = wsList.find((w) => w.external_id === selected);
|
|
3569
|
-
|
|
3570
|
-
|
|
3611
|
+
success(`Workspace: ${ws.name} (${ref(selected)})`);
|
|
3612
|
+
dim('\nTip: Run "arbi config alias" to use A as a shortcut for "arbi ask"');
|
|
3571
3613
|
} catch (err) {
|
|
3572
|
-
|
|
3614
|
+
error(`Login failed: ${core.getErrorMessage(err)}`);
|
|
3573
3615
|
process.exit(1);
|
|
3574
3616
|
} finally {
|
|
3575
3617
|
await checkForUpdates(getConfig()?.autoUpdate);
|
|
@@ -3626,10 +3668,10 @@ async function smartRegister(config, opts) {
|
|
|
3626
3668
|
body: { email }
|
|
3627
3669
|
});
|
|
3628
3670
|
if (verifyResponse.error) {
|
|
3629
|
-
|
|
3671
|
+
error(`Failed to send verification email: ${JSON.stringify(verifyResponse.error)}`);
|
|
3630
3672
|
process.exit(1);
|
|
3631
3673
|
}
|
|
3632
|
-
|
|
3674
|
+
success("Verification email sent. Check your inbox.");
|
|
3633
3675
|
verificationCode = await promptInput("Verification code");
|
|
3634
3676
|
}
|
|
3635
3677
|
}
|
|
@@ -3641,7 +3683,7 @@ async function smartRegister(config, opts) {
|
|
|
3641
3683
|
pw = await promptPassword("Password");
|
|
3642
3684
|
const confirmPw = await promptPassword("Confirm password");
|
|
3643
3685
|
if (pw !== confirmPw) {
|
|
3644
|
-
|
|
3686
|
+
error("Passwords do not match.");
|
|
3645
3687
|
process.exit(1);
|
|
3646
3688
|
}
|
|
3647
3689
|
}
|
|
@@ -3656,10 +3698,10 @@ async function smartRegister(config, opts) {
|
|
|
3656
3698
|
firstName,
|
|
3657
3699
|
lastName
|
|
3658
3700
|
});
|
|
3659
|
-
|
|
3701
|
+
success(`
|
|
3660
3702
|
Registered successfully as ${email}`);
|
|
3661
3703
|
} catch (err) {
|
|
3662
|
-
|
|
3704
|
+
error(`Registration failed: ${core.getErrorMessage(err)}`);
|
|
3663
3705
|
process.exit(1);
|
|
3664
3706
|
}
|
|
3665
3707
|
const allFlagsProvided = !!(opts.email || process.env.ARBI_EMAIL) && !!(opts.password || process.env.ARBI_PASSWORD) && !!opts.verificationCode;
|
|
@@ -3673,11 +3715,11 @@ async function nonInteractiveRegister(config, opts) {
|
|
|
3673
3715
|
const password2 = opts.password || process.env.ARBI_PASSWORD;
|
|
3674
3716
|
const supportApiKey = process.env.SUPPORT_API_KEY;
|
|
3675
3717
|
if (!email) {
|
|
3676
|
-
|
|
3718
|
+
error("Email required. Use --email <email> or set ARBI_EMAIL");
|
|
3677
3719
|
process.exit(1);
|
|
3678
3720
|
}
|
|
3679
3721
|
if (!password2) {
|
|
3680
|
-
|
|
3722
|
+
error("Password required. Use --password <password> or set ARBI_PASSWORD");
|
|
3681
3723
|
process.exit(1);
|
|
3682
3724
|
}
|
|
3683
3725
|
const arbi = sdk.createArbiClient({
|
|
@@ -3691,7 +3733,7 @@ async function nonInteractiveRegister(config, opts) {
|
|
|
3691
3733
|
verificationCode = opts.verificationCode;
|
|
3692
3734
|
} else {
|
|
3693
3735
|
if (!supportApiKey) {
|
|
3694
|
-
|
|
3736
|
+
error(
|
|
3695
3737
|
"Verification code required. Use --verification-code <code> or set SUPPORT_API_KEY for CI mode"
|
|
3696
3738
|
);
|
|
3697
3739
|
process.exit(1);
|
|
@@ -3700,7 +3742,7 @@ async function nonInteractiveRegister(config, opts) {
|
|
|
3700
3742
|
body: { email }
|
|
3701
3743
|
});
|
|
3702
3744
|
if (verifyResponse.error) {
|
|
3703
|
-
|
|
3745
|
+
error(`verify-email failed: ${JSON.stringify(verifyResponse.error)}`);
|
|
3704
3746
|
process.exit(1);
|
|
3705
3747
|
}
|
|
3706
3748
|
verificationCode = await getVerificationCode(email, supportApiKey);
|
|
@@ -3713,38 +3755,38 @@ async function nonInteractiveRegister(config, opts) {
|
|
|
3713
3755
|
firstName: opts.firstName ?? "Test",
|
|
3714
3756
|
lastName: opts.lastName ?? "User"
|
|
3715
3757
|
});
|
|
3716
|
-
|
|
3758
|
+
success(`Registered: ${email}`);
|
|
3717
3759
|
} catch (err) {
|
|
3718
|
-
|
|
3760
|
+
error(`Registration failed: ${core.getErrorMessage(err)}`);
|
|
3719
3761
|
process.exit(1);
|
|
3720
3762
|
}
|
|
3721
3763
|
}
|
|
3722
3764
|
async function loginAfterRegister(config, email, password2) {
|
|
3723
3765
|
try {
|
|
3724
3766
|
const { arbi } = await core.performPasswordLogin(config, email, password2, store);
|
|
3725
|
-
|
|
3767
|
+
success(`Logged in as ${email}`);
|
|
3726
3768
|
const { data: workspaces2 } = await arbi.fetch.GET("/api/user/workspaces");
|
|
3727
3769
|
const wsList = workspaces2 || [];
|
|
3728
3770
|
if (wsList.length === 0) {
|
|
3729
3771
|
console.log("Creating your first workspace...");
|
|
3730
3772
|
const ws2 = await core.workspaces.createWorkspace(arbi, "My First Workspace");
|
|
3731
3773
|
updateConfig({ selectedWorkspaceId: ws2.external_id });
|
|
3732
|
-
|
|
3774
|
+
success(`Workspace: ${ws2.name} (${ref(ws2.external_id)})`);
|
|
3733
3775
|
return;
|
|
3734
3776
|
}
|
|
3735
3777
|
if (wsList.length === 1) {
|
|
3736
3778
|
updateConfig({ selectedWorkspaceId: wsList[0].external_id });
|
|
3737
|
-
|
|
3779
|
+
success(`Workspace: ${wsList[0].name} (${ref(wsList[0].external_id)})`);
|
|
3738
3780
|
return;
|
|
3739
3781
|
}
|
|
3740
3782
|
const choices = core.formatWorkspaceChoices(wsList);
|
|
3741
3783
|
const selected = await promptSelect("Select workspace", choices);
|
|
3742
3784
|
updateConfig({ selectedWorkspaceId: selected });
|
|
3743
3785
|
const ws = wsList.find((w) => w.external_id === selected);
|
|
3744
|
-
|
|
3786
|
+
success(`Workspace: ${ws.name} (${ref(selected)})`);
|
|
3745
3787
|
} catch (err) {
|
|
3746
|
-
|
|
3747
|
-
|
|
3788
|
+
error(`Login failed: ${core.getErrorMessage(err)}`);
|
|
3789
|
+
error("You can log in later with: arbi login");
|
|
3748
3790
|
}
|
|
3749
3791
|
}
|
|
3750
3792
|
|
|
@@ -3753,7 +3795,7 @@ function registerLogoutCommand(program2) {
|
|
|
3753
3795
|
program2.command("logout").description("Log out of ARBI").action(() => {
|
|
3754
3796
|
deleteCredentials();
|
|
3755
3797
|
updateConfig({ selectedWorkspaceId: void 0 });
|
|
3756
|
-
|
|
3798
|
+
success("Logged out.");
|
|
3757
3799
|
});
|
|
3758
3800
|
}
|
|
3759
3801
|
|
|
@@ -3763,28 +3805,85 @@ function registerStatusCommand(program2) {
|
|
|
3763
3805
|
const config = getConfig();
|
|
3764
3806
|
const creds = getCredentials();
|
|
3765
3807
|
if (!config?.baseUrl) {
|
|
3766
|
-
|
|
3808
|
+
dim("Not configured. Run: arbi config set-url <url>");
|
|
3767
3809
|
return;
|
|
3768
3810
|
}
|
|
3769
|
-
|
|
3811
|
+
label("Server:", config.baseUrl);
|
|
3770
3812
|
if (creds) {
|
|
3771
|
-
|
|
3813
|
+
label("User:", creds.email);
|
|
3772
3814
|
} else {
|
|
3773
|
-
|
|
3815
|
+
label("User:", "(not logged in)");
|
|
3774
3816
|
}
|
|
3775
3817
|
if (config.selectedWorkspaceId) {
|
|
3776
|
-
|
|
3818
|
+
label("Workspace:", config.selectedWorkspaceId);
|
|
3777
3819
|
} else {
|
|
3778
|
-
|
|
3820
|
+
label("Workspace:", "(none selected)");
|
|
3779
3821
|
}
|
|
3780
3822
|
});
|
|
3781
3823
|
}
|
|
3824
|
+
var activeConnection = null;
|
|
3825
|
+
function timestamp() {
|
|
3826
|
+
return (/* @__PURE__ */ new Date()).toLocaleTimeString("en-GB", { hour12: false });
|
|
3827
|
+
}
|
|
3828
|
+
function colorize(level, text) {
|
|
3829
|
+
if (level === "success") return chalk__default.default.green(text);
|
|
3830
|
+
if (level === "error") return chalk__default.default.red(text);
|
|
3831
|
+
if (level === "warning") return chalk__default.default.yellow(text);
|
|
3832
|
+
return text;
|
|
3833
|
+
}
|
|
3834
|
+
async function startBackgroundNotifications(baseUrl, accessToken) {
|
|
3835
|
+
if (activeConnection) return;
|
|
3836
|
+
try {
|
|
3837
|
+
activeConnection = await core.connectWithReconnect({
|
|
3838
|
+
baseUrl,
|
|
3839
|
+
accessToken,
|
|
3840
|
+
onMessage: (msg) => {
|
|
3841
|
+
const { text, level } = core.formatWsMessage(msg);
|
|
3842
|
+
process.stderr.write(`
|
|
3843
|
+
${colorize(level, `[${timestamp()}] ${text}`)}
|
|
3844
|
+
`);
|
|
3845
|
+
},
|
|
3846
|
+
onClose: () => {
|
|
3847
|
+
activeConnection = null;
|
|
3848
|
+
},
|
|
3849
|
+
onReconnecting: (attempt, maxRetries) => {
|
|
3850
|
+
process.stderr.write(
|
|
3851
|
+
`
|
|
3852
|
+
${chalk__default.default.yellow(`[${timestamp()}] Reconnecting... (${attempt}/${maxRetries})`)}
|
|
3853
|
+
`
|
|
3854
|
+
);
|
|
3855
|
+
},
|
|
3856
|
+
onReconnected: () => {
|
|
3857
|
+
process.stderr.write(`
|
|
3858
|
+
${chalk__default.default.green(`[${timestamp()}] Reconnected`)}
|
|
3859
|
+
`);
|
|
3860
|
+
},
|
|
3861
|
+
onReconnectFailed: () => {
|
|
3862
|
+
process.stderr.write(`
|
|
3863
|
+
${chalk__default.default.red(`[${timestamp()}] Reconnection failed`)}
|
|
3864
|
+
`);
|
|
3865
|
+
}
|
|
3866
|
+
});
|
|
3867
|
+
} catch {
|
|
3868
|
+
}
|
|
3869
|
+
}
|
|
3870
|
+
function stopBackgroundNotifications() {
|
|
3871
|
+
activeConnection?.close();
|
|
3872
|
+
activeConnection = null;
|
|
3873
|
+
}
|
|
3874
|
+
process.on("exit", stopBackgroundNotifications);
|
|
3875
|
+
process.on("SIGINT", () => {
|
|
3876
|
+
stopBackgroundNotifications();
|
|
3877
|
+
process.exit(0);
|
|
3878
|
+
});
|
|
3879
|
+
|
|
3880
|
+
// src/helpers.ts
|
|
3782
3881
|
function runAction(fn) {
|
|
3783
3882
|
return async () => {
|
|
3784
3883
|
try {
|
|
3785
3884
|
await fn();
|
|
3786
3885
|
} catch (err) {
|
|
3787
|
-
|
|
3886
|
+
error(`Error: ${core.getErrorMessage(err)}`);
|
|
3788
3887
|
hintUpdateOnError();
|
|
3789
3888
|
process.exit(1);
|
|
3790
3889
|
}
|
|
@@ -3795,7 +3894,7 @@ async function resolveAuth() {
|
|
|
3795
3894
|
return await core.resolveAuth(store);
|
|
3796
3895
|
} catch (err) {
|
|
3797
3896
|
if (err instanceof core.ArbiError) {
|
|
3798
|
-
|
|
3897
|
+
error(err.message);
|
|
3799
3898
|
process.exit(1);
|
|
3800
3899
|
}
|
|
3801
3900
|
throw err;
|
|
@@ -3803,17 +3902,22 @@ async function resolveAuth() {
|
|
|
3803
3902
|
}
|
|
3804
3903
|
async function resolveWorkspace(workspaceOpt) {
|
|
3805
3904
|
try {
|
|
3806
|
-
|
|
3905
|
+
const ctx = await core.resolveWorkspace(store, workspaceOpt);
|
|
3906
|
+
if (getConfig()?.notifications) {
|
|
3907
|
+
startBackgroundNotifications(ctx.config.baseUrl, ctx.accessToken).catch(() => {
|
|
3908
|
+
});
|
|
3909
|
+
}
|
|
3910
|
+
return ctx;
|
|
3807
3911
|
} catch (err) {
|
|
3808
3912
|
if (err instanceof core.ArbiError) {
|
|
3809
|
-
|
|
3913
|
+
error(err.message);
|
|
3810
3914
|
process.exit(1);
|
|
3811
3915
|
}
|
|
3812
3916
|
throw err;
|
|
3813
3917
|
}
|
|
3814
3918
|
}
|
|
3815
3919
|
function printTable(columns, rows) {
|
|
3816
|
-
console.log(columns.map((c) => c.header.padEnd(c.width)).join(""));
|
|
3920
|
+
console.log(chalk__default.default.bold(columns.map((c) => c.header.padEnd(c.width)).join("")));
|
|
3817
3921
|
for (const row of rows) {
|
|
3818
3922
|
console.log(
|
|
3819
3923
|
columns.map((c) => {
|
|
@@ -3827,7 +3931,7 @@ function parseJsonArg(input2, example) {
|
|
|
3827
3931
|
try {
|
|
3828
3932
|
return JSON.parse(input2);
|
|
3829
3933
|
} catch {
|
|
3830
|
-
|
|
3934
|
+
error(`Invalid JSON. Example: ${example}`);
|
|
3831
3935
|
process.exit(1);
|
|
3832
3936
|
}
|
|
3833
3937
|
}
|
|
@@ -3874,9 +3978,9 @@ function registerWorkspacesCommand(program2) {
|
|
|
3874
3978
|
if (id) {
|
|
3875
3979
|
const ws2 = data.find((w) => w.external_id === id);
|
|
3876
3980
|
if (!ws2) {
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
for (const w of data)
|
|
3981
|
+
error(`Workspace ${id} not found.`);
|
|
3982
|
+
error("Available workspaces:");
|
|
3983
|
+
for (const w of data) error(` ${w.external_id} ${w.name}`);
|
|
3880
3984
|
process.exit(1);
|
|
3881
3985
|
}
|
|
3882
3986
|
selectedId = id;
|
|
@@ -3886,7 +3990,7 @@ function registerWorkspacesCommand(program2) {
|
|
|
3886
3990
|
}
|
|
3887
3991
|
updateConfig({ selectedWorkspaceId: selectedId });
|
|
3888
3992
|
const ws = data.find((w) => w.external_id === selectedId);
|
|
3889
|
-
|
|
3993
|
+
success(`Selected: ${ws.name} (${ref(selectedId)})`);
|
|
3890
3994
|
})()
|
|
3891
3995
|
);
|
|
3892
3996
|
workspace.command("create <name>").description("Create a new workspace").option("-d, --description <text>", "Workspace description").option("--public", "Make workspace public", false).action(
|
|
@@ -3898,14 +4002,14 @@ function registerWorkspacesCommand(program2) {
|
|
|
3898
4002
|
opts.description,
|
|
3899
4003
|
opts.public ?? false
|
|
3900
4004
|
);
|
|
3901
|
-
|
|
4005
|
+
success(`Created: ${data.name} (${ref(data.external_id)})`);
|
|
3902
4006
|
})()
|
|
3903
4007
|
);
|
|
3904
4008
|
workspace.command("delete <id>").description("Delete a workspace").action(
|
|
3905
4009
|
(id) => runAction(async () => {
|
|
3906
4010
|
const { arbi } = await resolveAuth();
|
|
3907
4011
|
const data = await core.workspaces.deleteWorkspace(arbi, id);
|
|
3908
|
-
|
|
4012
|
+
success(data?.detail ?? `Deleted workspace ${id}`);
|
|
3909
4013
|
})()
|
|
3910
4014
|
);
|
|
3911
4015
|
workspace.command("update <id> <json>").description("Update workspace properties (pass JSON)").action(
|
|
@@ -3913,7 +4017,7 @@ function registerWorkspacesCommand(program2) {
|
|
|
3913
4017
|
const body = parseJsonArg(json, `arbi workspace update wrk-123 '{"name": "New Name"}'`);
|
|
3914
4018
|
const { arbi } = await resolveWorkspace(id);
|
|
3915
4019
|
const data = await core.workspaces.updateWorkspace(arbi, id, body);
|
|
3916
|
-
|
|
4020
|
+
success(`Updated: ${data.name} (${ref(data.external_id)})`);
|
|
3917
4021
|
})()
|
|
3918
4022
|
);
|
|
3919
4023
|
workspace.command("users").description("List users in the active workspace").option("-w, --workspace <id>", "Workspace ID (defaults to selected workspace)").action(
|
|
@@ -3957,14 +4061,14 @@ function registerWorkspacesCommand(program2) {
|
|
|
3957
4061
|
const { arbi, workspaceId } = await resolveWorkspace(opts.workspace);
|
|
3958
4062
|
const role = opts.role ?? "collaborator";
|
|
3959
4063
|
const data = await core.workspaces.addWorkspaceUsers(arbi, workspaceId, emails, role);
|
|
3960
|
-
for (const u of data)
|
|
4064
|
+
for (const u of data) success(`Added: ${u.user.email} as ${u.role}`);
|
|
3961
4065
|
})()
|
|
3962
4066
|
);
|
|
3963
4067
|
workspace.command("remove-user <user-ids...>").description("Remove users from the active workspace").option("-w, --workspace <id>", "Workspace ID (defaults to selected workspace)").action(
|
|
3964
4068
|
(userIds, opts) => runAction(async () => {
|
|
3965
4069
|
const { arbi, workspaceId } = await resolveWorkspace(opts.workspace);
|
|
3966
4070
|
await core.workspaces.removeWorkspaceUsers(arbi, workspaceId, userIds);
|
|
3967
|
-
|
|
4071
|
+
success(`Removed ${userIds.length} user(s).`);
|
|
3968
4072
|
})()
|
|
3969
4073
|
);
|
|
3970
4074
|
workspace.command("set-role <role> <user-ids...>").description("Update user roles (owner, collaborator, guest)").option("-w, --workspace <id>", "Workspace ID (defaults to selected workspace)").action(
|
|
@@ -3976,19 +4080,19 @@ function registerWorkspacesCommand(program2) {
|
|
|
3976
4080
|
userIds,
|
|
3977
4081
|
role
|
|
3978
4082
|
);
|
|
3979
|
-
for (const u of data)
|
|
4083
|
+
for (const u of data) success(`Updated: ${u.user.email} \u2192 ${u.role}`);
|
|
3980
4084
|
})()
|
|
3981
4085
|
);
|
|
3982
4086
|
workspace.command("copy <target-workspace-id> <doc-ids...>").description("Copy documents to another workspace").option("-w, --workspace <id>", "Source workspace ID (defaults to selected workspace)").action(
|
|
3983
4087
|
(targetId, docIds, opts) => runAction(async () => {
|
|
3984
4088
|
const { arbi, workspaceId } = await resolveWorkspace(opts.workspace);
|
|
3985
4089
|
const data = await core.workspaces.copyDocuments(arbi, workspaceId, targetId, docIds);
|
|
3986
|
-
|
|
4090
|
+
success(`${data.detail} (${data.documents_copied} document(s) copied)`);
|
|
3987
4091
|
})()
|
|
3988
4092
|
);
|
|
3989
4093
|
}
|
|
3990
|
-
function statusSymbol(
|
|
3991
|
-
switch (
|
|
4094
|
+
function statusSymbol(status2) {
|
|
4095
|
+
switch (status2) {
|
|
3992
4096
|
case "completed":
|
|
3993
4097
|
return "\u2713";
|
|
3994
4098
|
// ✓
|
|
@@ -4085,7 +4189,7 @@ function registerDocsCommand(program2) {
|
|
|
4085
4189
|
docIds = selected;
|
|
4086
4190
|
}
|
|
4087
4191
|
await core.documents.deleteDocuments(arbi, docIds);
|
|
4088
|
-
|
|
4192
|
+
success(`Deleted ${docIds.length} document(s).`);
|
|
4089
4193
|
})()
|
|
4090
4194
|
);
|
|
4091
4195
|
doc.command("update [json]").description("Update documents (interactive form if no JSON given)").action(
|
|
@@ -4095,7 +4199,7 @@ function registerDocsCommand(program2) {
|
|
|
4095
4199
|
const docs = Array.isArray(parsed) ? parsed : parsed.documents;
|
|
4096
4200
|
const { arbi } = await resolveWorkspace();
|
|
4097
4201
|
const data = await core.documents.updateDocuments(arbi, docs);
|
|
4098
|
-
|
|
4202
|
+
success(`Updated ${data.length} document(s).`);
|
|
4099
4203
|
} else {
|
|
4100
4204
|
const { arbi, workspaceId } = await resolveWorkspace();
|
|
4101
4205
|
const choices = await fetchDocChoices(arbi, workspaceId);
|
|
@@ -4121,7 +4225,7 @@ function registerDocsCommand(program2) {
|
|
|
4121
4225
|
const data = await core.documents.updateDocuments(arbi, [
|
|
4122
4226
|
{ external_id: docId, [field]: value }
|
|
4123
4227
|
]);
|
|
4124
|
-
|
|
4228
|
+
success(`Updated ${data.length} document(s).`);
|
|
4125
4229
|
}
|
|
4126
4230
|
})()
|
|
4127
4231
|
);
|
|
@@ -4129,9 +4233,9 @@ function registerDocsCommand(program2) {
|
|
|
4129
4233
|
(urls, opts) => runAction(async () => {
|
|
4130
4234
|
const { arbi, workspaceId } = await resolveWorkspace(opts.workspace);
|
|
4131
4235
|
const data = await core.documents.uploadUrl(arbi, urls, workspaceId, opts.shared ?? false);
|
|
4132
|
-
|
|
4236
|
+
success(`Uploaded: ${data.doc_ext_ids.join(", ")}`);
|
|
4133
4237
|
if (data.duplicates && data.duplicates.length > 0) {
|
|
4134
|
-
|
|
4238
|
+
warn(`Duplicates: ${data.duplicates.join(", ")}`);
|
|
4135
4239
|
}
|
|
4136
4240
|
})()
|
|
4137
4241
|
);
|
|
@@ -4150,7 +4254,7 @@ function registerDocsCommand(program2) {
|
|
|
4150
4254
|
{ name: "Marker (raw)", value: "marker" }
|
|
4151
4255
|
]);
|
|
4152
4256
|
} else if (!validStages.includes(stage)) {
|
|
4153
|
-
|
|
4257
|
+
error(`Invalid stage: ${stage}. Must be one of: ${validStages.join(", ")}`);
|
|
4154
4258
|
process.exit(1);
|
|
4155
4259
|
}
|
|
4156
4260
|
const data = await core.documents.getParsedContent(
|
|
@@ -4167,7 +4271,7 @@ function registerUploadCommand(program2) {
|
|
|
4167
4271
|
(files, opts) => runAction(async () => {
|
|
4168
4272
|
for (const f of files) {
|
|
4169
4273
|
if (!fs__default.default.existsSync(f)) {
|
|
4170
|
-
|
|
4274
|
+
error(`File not found: ${f}`);
|
|
4171
4275
|
process.exit(1);
|
|
4172
4276
|
}
|
|
4173
4277
|
}
|
|
@@ -4178,9 +4282,9 @@ function registerUploadCommand(program2) {
|
|
|
4178
4282
|
const auth = { baseUrl: config.baseUrl, accessToken, workspaceKeyHeader };
|
|
4179
4283
|
for (const filePath of files) {
|
|
4180
4284
|
const result = await core.documents.uploadLocalFile(auth, workspaceId, filePath);
|
|
4181
|
-
|
|
4285
|
+
success(`Uploaded: ${result.fileName} (${result.doc_ext_ids.join(", ")})`);
|
|
4182
4286
|
if (result.duplicates && result.duplicates.length > 0) {
|
|
4183
|
-
|
|
4287
|
+
warn(` Duplicates: ${result.duplicates.join(", ")}`);
|
|
4184
4288
|
}
|
|
4185
4289
|
for (const id of result.doc_ext_ids) uploadedDocs.set(id, result.fileName);
|
|
4186
4290
|
}
|
|
@@ -4195,12 +4299,12 @@ Watching ${pending.size} document(s)...`);
|
|
|
4195
4299
|
if (sdk.isMessageType(msg, "task_update")) {
|
|
4196
4300
|
if (!pending.has(msg.doc_ext_id)) return;
|
|
4197
4301
|
console.log(
|
|
4198
|
-
` ${uploadedDocs.get(msg.doc_ext_id) || msg.file_name}: ${msg.status} (${msg.progress}%)`
|
|
4302
|
+
` ${uploadedDocs.get(msg.doc_ext_id) || msg.file_name}: ${status(msg.status)} (${msg.progress}%)`
|
|
4199
4303
|
);
|
|
4200
4304
|
if (msg.status === "completed" || msg.status === "failed") {
|
|
4201
4305
|
pending.delete(msg.doc_ext_id);
|
|
4202
4306
|
if (pending.size === 0) {
|
|
4203
|
-
|
|
4307
|
+
success("\nAll documents processed.");
|
|
4204
4308
|
conn.close();
|
|
4205
4309
|
}
|
|
4206
4310
|
}
|
|
@@ -4208,7 +4312,7 @@ Watching ${pending.size} document(s)...`);
|
|
|
4208
4312
|
},
|
|
4209
4313
|
onClose: () => {
|
|
4210
4314
|
if (pending.size > 0)
|
|
4211
|
-
|
|
4315
|
+
warn(`
|
|
4212
4316
|
Connection closed. ${pending.size} document(s) still processing.`);
|
|
4213
4317
|
}
|
|
4214
4318
|
});
|
|
@@ -4246,7 +4350,7 @@ function registerDownloadCommand(program2) {
|
|
|
4246
4350
|
const outputPath = opts.output || path__default.default.join(process.cwd(), filename);
|
|
4247
4351
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
4248
4352
|
fs__default.default.writeFileSync(outputPath, buffer);
|
|
4249
|
-
|
|
4353
|
+
success(
|
|
4250
4354
|
`Downloaded: ${path__default.default.basename(outputPath)} (${(buffer.length / (1024 * 1024)).toFixed(1)} MB)`
|
|
4251
4355
|
);
|
|
4252
4356
|
})()
|
|
@@ -4279,12 +4383,12 @@ function registerAskCommand(program2) {
|
|
|
4279
4383
|
onAgentStep: (data) => {
|
|
4280
4384
|
if (opts.verbose) {
|
|
4281
4385
|
const focus = data.focus || data.status || "";
|
|
4282
|
-
console.error(`
|
|
4283
|
-
[agent] ${focus}`);
|
|
4386
|
+
console.error(chalk__default.default.dim(`
|
|
4387
|
+
[agent] ${focus}`));
|
|
4284
4388
|
}
|
|
4285
4389
|
},
|
|
4286
|
-
onError: (message) => console.error(`
|
|
4287
|
-
Error: ${message}`)
|
|
4390
|
+
onError: (message) => console.error(chalk__default.default.red(`
|
|
4391
|
+
Error: ${message}`))
|
|
4288
4392
|
});
|
|
4289
4393
|
process.stdout.write("\n");
|
|
4290
4394
|
if (result.assistantMessageExtId) {
|
|
@@ -4300,8 +4404,11 @@ Error: ${message}`)
|
|
|
4300
4404
|
})()
|
|
4301
4405
|
);
|
|
4302
4406
|
}
|
|
4303
|
-
function
|
|
4304
|
-
|
|
4407
|
+
function colorize2(level, text) {
|
|
4408
|
+
if (level === "success") return chalk__default.default.green(text);
|
|
4409
|
+
if (level === "error") return chalk__default.default.red(text);
|
|
4410
|
+
if (level === "warning") return chalk__default.default.yellow(text);
|
|
4411
|
+
return text;
|
|
4305
4412
|
}
|
|
4306
4413
|
function registerWatchCommand(program2) {
|
|
4307
4414
|
program2.command("watch").description("Watch workspace activity in real time").option("-w, --workspace <id>", "Workspace ID (defaults to selected workspace)").action(
|
|
@@ -4312,23 +4419,14 @@ function registerWatchCommand(program2) {
|
|
|
4312
4419
|
baseUrl: config.baseUrl,
|
|
4313
4420
|
accessToken,
|
|
4314
4421
|
onMessage: (msg) => {
|
|
4315
|
-
|
|
4316
|
-
|
|
4317
|
-
`[${timestamp()}] task_update: ${msg.file_name} - ${msg.status} (${msg.progress}%)`
|
|
4318
|
-
);
|
|
4319
|
-
} else if (sdk.isMessageType(msg, "batch_complete")) {
|
|
4320
|
-
console.log(
|
|
4321
|
-
`[${timestamp()}] batch_complete: ${msg.batch_type} - ${msg.doc_ext_ids.length} docs`
|
|
4322
|
-
);
|
|
4323
|
-
} else if (sdk.isMessageType(msg, "error")) {
|
|
4324
|
-
console.log(`[${timestamp()}] error: ${msg.message}`);
|
|
4325
|
-
} else {
|
|
4326
|
-
console.log(`[${timestamp()}] ${msg.type}: ${JSON.stringify(msg)}`);
|
|
4327
|
-
}
|
|
4422
|
+
const { text, level } = core.formatWsMessage(msg);
|
|
4423
|
+
console.log(colorize2(level, text));
|
|
4328
4424
|
},
|
|
4329
4425
|
onClose: (code, reason) => {
|
|
4330
|
-
console.log(
|
|
4331
|
-
|
|
4426
|
+
console.log(
|
|
4427
|
+
chalk__default.default.yellow(`
|
|
4428
|
+
Connection closed (code ${code}${reason ? ": " + reason : ""})`)
|
|
4429
|
+
);
|
|
4332
4430
|
}
|
|
4333
4431
|
});
|
|
4334
4432
|
})()
|
|
@@ -4369,7 +4467,7 @@ function registerContactsCommand(program2) {
|
|
|
4369
4467
|
}
|
|
4370
4468
|
const data = await core.contacts.addContacts(arbi, emails);
|
|
4371
4469
|
for (const c of data) {
|
|
4372
|
-
|
|
4470
|
+
success(`Added: ${c.email} (${c.external_id}) \u2014 ${c.status}`);
|
|
4373
4471
|
}
|
|
4374
4472
|
})()
|
|
4375
4473
|
);
|
|
@@ -4396,7 +4494,7 @@ function registerContactsCommand(program2) {
|
|
|
4396
4494
|
if (contactIds.length === 0) return;
|
|
4397
4495
|
}
|
|
4398
4496
|
await core.contacts.removeContacts(arbi, contactIds);
|
|
4399
|
-
|
|
4497
|
+
success(`Removed ${contactIds.length} contact(s).`);
|
|
4400
4498
|
})()
|
|
4401
4499
|
);
|
|
4402
4500
|
contacts.action(async () => {
|
|
@@ -4438,7 +4536,7 @@ function registerDmCommand(program2) {
|
|
|
4438
4536
|
if (!recipient) {
|
|
4439
4537
|
const contacts = await core.contacts.listContacts(arbi);
|
|
4440
4538
|
if (contacts.length === 0) {
|
|
4441
|
-
|
|
4539
|
+
error("No contacts found. Add contacts first: arbi contacts add <email>");
|
|
4442
4540
|
process.exit(1);
|
|
4443
4541
|
}
|
|
4444
4542
|
recipient = await promptSelect(
|
|
@@ -4462,15 +4560,15 @@ function registerDmCommand(program2) {
|
|
|
4462
4560
|
const contacts = await core.contacts.listContacts(arbi);
|
|
4463
4561
|
const match = contacts.find((c) => c.email === recipient);
|
|
4464
4562
|
if (!match) {
|
|
4465
|
-
|
|
4466
|
-
|
|
4563
|
+
error(`No contact found with email: ${recipient}`);
|
|
4564
|
+
error("Add them first: arbi contacts add " + recipient);
|
|
4467
4565
|
process.exit(1);
|
|
4468
4566
|
}
|
|
4469
4567
|
recipientExtId = match.user?.external_id ?? match.external_id;
|
|
4470
4568
|
}
|
|
4471
4569
|
const data = await core.dm.sendDM(arbi, [{ recipient_ext_id: recipientExtId, content }]);
|
|
4472
4570
|
for (const n of data) {
|
|
4473
|
-
|
|
4571
|
+
success(`Sent: ${n.external_id} \u2192 ${n.recipient.email}`);
|
|
4474
4572
|
}
|
|
4475
4573
|
})()
|
|
4476
4574
|
);
|
|
@@ -4499,7 +4597,7 @@ function registerDmCommand(program2) {
|
|
|
4499
4597
|
if (msgIds.length === 0) return;
|
|
4500
4598
|
}
|
|
4501
4599
|
const data = await core.dm.markRead(arbi, msgIds);
|
|
4502
|
-
|
|
4600
|
+
success(`Marked ${data.length} message(s) as read.`);
|
|
4503
4601
|
})()
|
|
4504
4602
|
);
|
|
4505
4603
|
dm.command("delete [ids...]").description("Delete messages (interactive picker if no IDs given)").action(
|
|
@@ -4526,7 +4624,7 @@ function registerDmCommand(program2) {
|
|
|
4526
4624
|
if (msgIds.length === 0) return;
|
|
4527
4625
|
}
|
|
4528
4626
|
await core.dm.deleteDMs(arbi, msgIds);
|
|
4529
|
-
|
|
4627
|
+
success(`Deleted ${msgIds.length} message(s).`);
|
|
4530
4628
|
})()
|
|
4531
4629
|
);
|
|
4532
4630
|
dm.action(async () => {
|
|
@@ -4604,7 +4702,7 @@ function registerTagsCommand(program2) {
|
|
|
4604
4702
|
instruction,
|
|
4605
4703
|
shared
|
|
4606
4704
|
});
|
|
4607
|
-
|
|
4705
|
+
success(`Created: ${data.name} (${ref(data.external_id)})`);
|
|
4608
4706
|
})()
|
|
4609
4707
|
);
|
|
4610
4708
|
tags.command("delete [id]").description("Delete a tag (interactive picker if no ID given)").action(
|
|
@@ -4615,7 +4713,7 @@ function registerTagsCommand(program2) {
|
|
|
4615
4713
|
id = await promptSelect("Select tag to delete", choices);
|
|
4616
4714
|
}
|
|
4617
4715
|
const data = await core.tags.deleteTag(arbi, id);
|
|
4618
|
-
|
|
4716
|
+
success(data?.detail ?? `Deleted tag ${id}`);
|
|
4619
4717
|
})()
|
|
4620
4718
|
);
|
|
4621
4719
|
tags.command("update [id] [json]").description("Update a tag (interactive picker + form if no args)").action(
|
|
@@ -4641,7 +4739,7 @@ function registerTagsCommand(program2) {
|
|
|
4641
4739
|
}
|
|
4642
4740
|
}
|
|
4643
4741
|
const data = await core.tags.updateTag(arbi, id, body);
|
|
4644
|
-
|
|
4742
|
+
success(`Updated: ${data.name} (${ref(data.external_id)})`);
|
|
4645
4743
|
})()
|
|
4646
4744
|
);
|
|
4647
4745
|
tags.action(async (_opts, cmd) => {
|
|
@@ -4687,7 +4785,7 @@ function registerDoctagsCommand(program2) {
|
|
|
4687
4785
|
docIds = await pickDocs(arbi, workspaceId, "Select documents to tag");
|
|
4688
4786
|
if (docIds.length === 0) return;
|
|
4689
4787
|
const data = await core.doctags.assignDocTags(arbi, tagId, docIds, opts?.note);
|
|
4690
|
-
|
|
4788
|
+
success(`Created ${data.length} doctag(s) for tag ${tagId}.`);
|
|
4691
4789
|
})()
|
|
4692
4790
|
);
|
|
4693
4791
|
doctagsCmd.command("delete [tag-id] [doc-ids...]").description("Remove a tag from documents (interactive pickers if no args)").action(
|
|
@@ -4698,7 +4796,7 @@ function registerDoctagsCommand(program2) {
|
|
|
4698
4796
|
docIds = await pickDocs(arbi, workspaceId, "Select documents to untag");
|
|
4699
4797
|
if (docIds.length === 0) return;
|
|
4700
4798
|
await core.doctags.removeDocTags(arbi, tagId, docIds);
|
|
4701
|
-
|
|
4799
|
+
success(`Removed tag ${tagId} from ${docIds.length} document(s).`);
|
|
4702
4800
|
})()
|
|
4703
4801
|
);
|
|
4704
4802
|
doctagsCmd.command("generate").description("AI-generate doctags (interactive pickers if no flags)").option("--tags <ids>", "Comma-separated tag IDs").option("--docs <ids>", "Comma-separated document IDs").action(
|
|
@@ -4790,7 +4888,7 @@ function registerConversationsCommand(program2) {
|
|
|
4790
4888
|
"Select conversation to delete"
|
|
4791
4889
|
);
|
|
4792
4890
|
const data = await core.conversations.deleteConversation(arbi, conversationId);
|
|
4793
|
-
|
|
4891
|
+
success(data?.detail ?? `Deleted conversation ${conversationId}`);
|
|
4794
4892
|
})()
|
|
4795
4893
|
);
|
|
4796
4894
|
conv.command("share [conversation-id]").description("Share a conversation (interactive picker if no ID given)").action(
|
|
@@ -4799,7 +4897,7 @@ function registerConversationsCommand(program2) {
|
|
|
4799
4897
|
if (!conversationId)
|
|
4800
4898
|
conversationId = await pickConversation(arbi, workspaceId, "Select conversation to share");
|
|
4801
4899
|
const data = await core.conversations.shareConversation(arbi, conversationId);
|
|
4802
|
-
|
|
4900
|
+
success(data?.detail ?? `Shared conversation ${conversationId}`);
|
|
4803
4901
|
})()
|
|
4804
4902
|
);
|
|
4805
4903
|
conv.command("title [conversation-id] [title]").description("Update conversation title (interactive if no args)").action(
|
|
@@ -4808,7 +4906,7 @@ function registerConversationsCommand(program2) {
|
|
|
4808
4906
|
if (!conversationId) conversationId = await pickConversation(arbi, workspaceId);
|
|
4809
4907
|
if (!title) title = await promptInput("New title");
|
|
4810
4908
|
const data = await core.conversations.updateConversationTitle(arbi, conversationId, title);
|
|
4811
|
-
|
|
4909
|
+
success(data?.detail ?? `Updated title to: ${title}`);
|
|
4812
4910
|
})()
|
|
4813
4911
|
);
|
|
4814
4912
|
conv.command("add-user [conversation-id] [user-id]").description("Add a user to a conversation (interactive if no args)").action(
|
|
@@ -4817,7 +4915,7 @@ function registerConversationsCommand(program2) {
|
|
|
4817
4915
|
if (!conversationId) conversationId = await pickConversation(arbi, workspaceId);
|
|
4818
4916
|
if (!userId) userId = await promptInput("User ext_id or email");
|
|
4819
4917
|
const data = await core.conversations.addConversationUser(arbi, conversationId, userId);
|
|
4820
|
-
|
|
4918
|
+
success(data?.detail ?? `Added user ${userId} to conversation`);
|
|
4821
4919
|
})()
|
|
4822
4920
|
);
|
|
4823
4921
|
conv.command("remove-user [conversation-id] [user-id]").description("Remove a user from a conversation (interactive if no args)").action(
|
|
@@ -4826,7 +4924,7 @@ function registerConversationsCommand(program2) {
|
|
|
4826
4924
|
if (!conversationId) conversationId = await pickConversation(arbi, workspaceId);
|
|
4827
4925
|
if (!userId) userId = await promptInput("User ext_id");
|
|
4828
4926
|
const data = await core.conversations.removeConversationUser(arbi, conversationId, userId);
|
|
4829
|
-
|
|
4927
|
+
success(data?.detail ?? `Removed user ${userId} from conversation`);
|
|
4830
4928
|
})()
|
|
4831
4929
|
);
|
|
4832
4930
|
conv.command("message <message-id>").description("Get message details").action(
|
|
@@ -4840,7 +4938,7 @@ function registerConversationsCommand(program2) {
|
|
|
4840
4938
|
(messageId) => runAction(async () => {
|
|
4841
4939
|
const { arbi } = await resolveAuth();
|
|
4842
4940
|
const data = await core.conversations.deleteMessage(arbi, messageId);
|
|
4843
|
-
|
|
4941
|
+
success(data?.detail ?? `Deleted message ${messageId}`);
|
|
4844
4942
|
})()
|
|
4845
4943
|
);
|
|
4846
4944
|
conv.action(async (_opts, cmd) => {
|
|
@@ -4861,7 +4959,7 @@ function registerSettingsCommand(program2) {
|
|
|
4861
4959
|
const body = parseJsonArg(json, `arbi settings set '{"hide_online_status": true}'`);
|
|
4862
4960
|
const { arbi } = await resolveAuth();
|
|
4863
4961
|
await core.settings.updateSettings(arbi, body);
|
|
4864
|
-
|
|
4962
|
+
success("Settings updated.");
|
|
4865
4963
|
})()
|
|
4866
4964
|
);
|
|
4867
4965
|
settings.action(async () => {
|
|
@@ -5066,7 +5164,7 @@ function registerAgentconfigCommand(program2) {
|
|
|
5066
5164
|
if (opts?.tag) body.tag_ext_id = opts.tag;
|
|
5067
5165
|
if (opts?.message) body.parent_message_ext_id = opts.message;
|
|
5068
5166
|
const data = await core.agentconfig.saveConfig(arbi, body);
|
|
5069
|
-
|
|
5167
|
+
success(`Saved: ${data.title || "(untitled)"} (${ref(data.external_id)})`);
|
|
5070
5168
|
})()
|
|
5071
5169
|
);
|
|
5072
5170
|
ac.command("delete [config-id]").description("Delete a configuration (picker if no ID)").action(
|
|
@@ -5074,7 +5172,7 @@ function registerAgentconfigCommand(program2) {
|
|
|
5074
5172
|
const { arbi } = await resolveAuth();
|
|
5075
5173
|
if (!configId) configId = await pickConfig(arbi, "Select configuration to delete");
|
|
5076
5174
|
const data = await core.agentconfig.deleteConfig(arbi, configId);
|
|
5077
|
-
|
|
5175
|
+
success(data.detail);
|
|
5078
5176
|
})()
|
|
5079
5177
|
);
|
|
5080
5178
|
ac.command("schema").description("Show JSON schema for all configuration models").action(
|
|
@@ -5093,20 +5191,20 @@ function registerHealthCommand(program2) {
|
|
|
5093
5191
|
runAction(async () => {
|
|
5094
5192
|
const { arbi } = await resolveAuth();
|
|
5095
5193
|
const data = await core.health.getHealth(arbi);
|
|
5096
|
-
|
|
5097
|
-
if (data.backend_git_hash)
|
|
5098
|
-
if (data.frontend_docker_version)
|
|
5194
|
+
label("Status:", status(data.status));
|
|
5195
|
+
if (data.backend_git_hash) label("Backend:", data.backend_git_hash);
|
|
5196
|
+
if (data.frontend_docker_version) label("Frontend:", data.frontend_docker_version);
|
|
5099
5197
|
if (data.services.length > 0) {
|
|
5100
|
-
|
|
5198
|
+
bold("\nServices:");
|
|
5101
5199
|
for (const s of data.services) {
|
|
5102
|
-
console.log(` ${s.name}: ${s.status}${s.detail ? ` \u2014 ${s.detail}` : ""}`);
|
|
5200
|
+
console.log(` ${s.name}: ${status(s.status)}${s.detail ? ` \u2014 ${s.detail}` : ""}`);
|
|
5103
5201
|
}
|
|
5104
5202
|
}
|
|
5105
5203
|
if (data.models_health) {
|
|
5106
|
-
|
|
5204
|
+
bold(`
|
|
5107
5205
|
Models (${data.models_health.application}):`);
|
|
5108
5206
|
for (const m of data.models_health.models) {
|
|
5109
|
-
console.log(` ${m.model}: ${m.status}${m.detail ? ` \u2014 ${m.detail}` : ""}`);
|
|
5207
|
+
console.log(` ${m.model}: ${status(m.status)}${m.detail ? ` \u2014 ${m.detail}` : ""}`);
|
|
5110
5208
|
}
|
|
5111
5209
|
}
|
|
5112
5210
|
})
|
|
@@ -5132,7 +5230,7 @@ Models (${data.models_health.application}):`);
|
|
|
5132
5230
|
}
|
|
5133
5231
|
function registerTuiCommand(program2) {
|
|
5134
5232
|
program2.command("tui").description("Launch interactive terminal UI").option("-w, --workspace <id>", "Workspace ID to use").allowUnknownOption(true).action((opts, cmd) => {
|
|
5135
|
-
const require2 = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.
|
|
5233
|
+
const require2 = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.js', document.baseURI).href)));
|
|
5136
5234
|
const entryPoint = require2.resolve("@arbidocs/tui");
|
|
5137
5235
|
const args = [];
|
|
5138
5236
|
if (opts.workspace) {
|
|
@@ -5149,31 +5247,31 @@ function registerTuiCommand(program2) {
|
|
|
5149
5247
|
function registerUpdateCommand(program2) {
|
|
5150
5248
|
const update = program2.command("update").description("Update ARBI CLI to the latest version").action(async () => {
|
|
5151
5249
|
const current = getCurrentVersion();
|
|
5152
|
-
|
|
5250
|
+
label("Current version:", current);
|
|
5153
5251
|
console.log("Checking for updates...\n");
|
|
5154
5252
|
try {
|
|
5155
5253
|
const latest = getLatestVersion() || child_process.execSync("npm view @arbidocs/cli version", { encoding: "utf8" }).trim();
|
|
5156
5254
|
if (latest === current) {
|
|
5157
|
-
|
|
5255
|
+
success("Already up to date.");
|
|
5158
5256
|
return;
|
|
5159
5257
|
}
|
|
5160
|
-
|
|
5258
|
+
success(`New version available: ${latest}`);
|
|
5161
5259
|
await showChangelog(current, latest);
|
|
5162
5260
|
console.log("\nUpdating...\n");
|
|
5163
5261
|
child_process.execSync("npm install -g @arbidocs/cli@latest", { stdio: "inherit" });
|
|
5164
|
-
|
|
5262
|
+
success(`
|
|
5165
5263
|
Updated to ${latest}.`);
|
|
5166
5264
|
} catch (err) {
|
|
5167
5265
|
const msg = err instanceof Error ? err.message : String(err);
|
|
5168
|
-
|
|
5169
|
-
|
|
5170
|
-
|
|
5266
|
+
error(`Update failed: ${msg}`);
|
|
5267
|
+
error("\nYou can update manually with:");
|
|
5268
|
+
dim(" npm install -g @arbidocs/cli@latest");
|
|
5171
5269
|
process.exit(1);
|
|
5172
5270
|
}
|
|
5173
5271
|
});
|
|
5174
5272
|
update.command("auto").description("Enable automatic updates on login").action(() => {
|
|
5175
5273
|
updateConfig({ autoUpdate: true });
|
|
5176
|
-
|
|
5274
|
+
success("Auto-update enabled. ARBI CLI will update automatically on login.");
|
|
5177
5275
|
});
|
|
5178
5276
|
}
|
|
5179
5277
|
|
|
@@ -5186,7 +5284,7 @@ console.info = (...args) => {
|
|
|
5186
5284
|
_origInfo(...args);
|
|
5187
5285
|
};
|
|
5188
5286
|
var program = new commander.Command();
|
|
5189
|
-
program.name("arbi").description("ARBI CLI \u2014 interact with ARBI from the terminal").version("0.3.
|
|
5287
|
+
program.name("arbi").description("ARBI CLI \u2014 interact with ARBI from the terminal").version("0.3.5");
|
|
5190
5288
|
registerConfigCommand(program);
|
|
5191
5289
|
registerLoginCommand(program);
|
|
5192
5290
|
registerRegisterCommand(program);
|
|
@@ -5209,5 +5307,5 @@ registerHealthCommand(program);
|
|
|
5209
5307
|
registerTuiCommand(program);
|
|
5210
5308
|
registerUpdateCommand(program);
|
|
5211
5309
|
program.parse();
|
|
5212
|
-
//# sourceMappingURL=index.
|
|
5213
|
-
//# sourceMappingURL=index.
|
|
5310
|
+
//# sourceMappingURL=index.js.map
|
|
5311
|
+
//# sourceMappingURL=index.js.map
|