@arbidocs/cli 0.3.108 → 0.3.110
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 +47 -0
- package/dist/index.js +106 -79
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,52 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v0.3.110
|
|
4
|
+
|
|
5
|
+
[compare changes](https://github.com/arbicity/ARBI-frontend/compare/v0.3.109...HEAD)
|
|
6
|
+
|
|
7
|
+
### 🚀 Enhancements
|
|
8
|
+
|
|
9
|
+
- Builder-composability foundation — shared block registry + adapter-pattern exemplars ([#1051](https://github.com/arbicity/ARBI-frontend/pull/1051))
|
|
10
|
+
- Monolith hosts the Puck builder + serializable DataTable block ([#1055](https://github.com/arbicity/ARBI-frontend/pull/1055))
|
|
11
|
+
- Full website block library (27 blocks) + live theme retheming (D1) ([#1057](https://github.com/arbicity/ARBI-frontend/pull/1057))
|
|
12
|
+
- Shared real-time WebSocket layer + eliminate client-side polling ([#1059](https://github.com/arbicity/ARBI-frontend/pull/1059))
|
|
13
|
+
|
|
14
|
+
### 🩹 Fixes
|
|
15
|
+
|
|
16
|
+
- Publish @arbidocs/blocks + de-flake CI integration/publish pipeline ([#1060](https://github.com/arbicity/ARBI-frontend/pull/1060))
|
|
17
|
+
- **ci:** Pass ARBI_TEST_DEPLOYMENT_DOMAIN to CLI integration tests ([#1061](https://github.com/arbicity/ARBI-frontend/pull/1061))
|
|
18
|
+
|
|
19
|
+
### 💅 Refactors
|
|
20
|
+
|
|
21
|
+
- Idiomatic Tailwind v4 + tokenize shared dropdown (Phase 3) ([#1044](https://github.com/arbicity/ARBI-frontend/pull/1044))
|
|
22
|
+
- Consume @arbidocs/react from source in monolith dev + tests ([#1045](https://github.com/arbicity/ARBI-frontend/pull/1045))
|
|
23
|
+
- **markdown:** Share the presentational component map across renderers ([#1047](https://github.com/arbicity/ARBI-frontend/pull/1047))
|
|
24
|
+
- Unify blocks builder + monolith on shared @arbidocs/react library ([#1049](https://github.com/arbicity/ARBI-frontend/pull/1049))
|
|
25
|
+
- Phase 8 extraction wave — ChatBubble, MessageArtifactCard, UserEntity to @arbidocs/react ([#1054](https://github.com/arbicity/ARBI-frontend/pull/1054))
|
|
26
|
+
|
|
27
|
+
### 📖 Documentation
|
|
28
|
+
|
|
29
|
+
- Mark Phases 0-4 complete (source-consumption + markdown unification) ([#1048](https://github.com/arbicity/ARBI-frontend/pull/1048))
|
|
30
|
+
- Mark Phase 6 complete (blocks-builder unification, #1049) ([#1050](https://github.com/arbicity/ARBI-frontend/pull/1050), [#1049](https://github.com/arbicity/ARBI-frontend/issues/1049))
|
|
31
|
+
- Mark Phase 7 composability foundation complete ([#1051](https://github.com/arbicity/ARBI-frontend/pull/1051), [#1052](https://github.com/arbicity/ARBI-frontend/pull/1052))
|
|
32
|
+
- Mark Phases 7-9 (builder hosting) complete in grand plan ([#1056](https://github.com/arbicity/ARBI-frontend/pull/1056))
|
|
33
|
+
|
|
34
|
+
### ✅ Tests
|
|
35
|
+
|
|
36
|
+
- Add GridView column-persistence round-trip regression test ([#1053](https://github.com/arbicity/ARBI-frontend/pull/1053))
|
|
37
|
+
|
|
38
|
+
## v0.3.109
|
|
39
|
+
|
|
40
|
+
[compare changes](https://github.com/arbicity/ARBI-frontend/compare/v0.3.108...HEAD)
|
|
41
|
+
|
|
42
|
+
### 🩹 Fixes
|
|
43
|
+
|
|
44
|
+
- **legal:** DraftArtifact loops the agent — draft in a single pass ([#1041](https://github.com/arbicity/ARBI-frontend/pull/1041))
|
|
45
|
+
|
|
46
|
+
### 💅 Refactors
|
|
47
|
+
|
|
48
|
+
- Rename @arbidocs/legal package to @arbidocs/blocks ([#1042](https://github.com/arbicity/ARBI-frontend/pull/1042))
|
|
49
|
+
|
|
3
50
|
## v0.3.108
|
|
4
51
|
|
|
5
52
|
[compare changes](https://github.com/arbicity/ARBI-frontend/compare/v0.3.107...HEAD)
|
package/dist/index.js
CHANGED
|
@@ -11,7 +11,7 @@ var sdk = require('@arbidocs/sdk');
|
|
|
11
11
|
var child_process = require('child_process');
|
|
12
12
|
var client = require('@arbidocs/client');
|
|
13
13
|
var url = require('url');
|
|
14
|
-
var crypto
|
|
14
|
+
var crypto = require('crypto');
|
|
15
15
|
var module$1 = require('module');
|
|
16
16
|
|
|
17
17
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
@@ -3694,7 +3694,7 @@ function getLatestVersion(skipCache = false) {
|
|
|
3694
3694
|
}
|
|
3695
3695
|
}
|
|
3696
3696
|
function getCurrentVersion() {
|
|
3697
|
-
return "0.3.
|
|
3697
|
+
return "0.3.110";
|
|
3698
3698
|
}
|
|
3699
3699
|
function readChangelog(fromVersion, toVersion) {
|
|
3700
3700
|
try {
|
|
@@ -3747,17 +3747,17 @@ function showChangelog(fromVersion, toVersion) {
|
|
|
3747
3747
|
async function checkForUpdates(autoUpdate) {
|
|
3748
3748
|
try {
|
|
3749
3749
|
const latest = getLatestVersion();
|
|
3750
|
-
if (!latest || latest === "0.3.
|
|
3750
|
+
if (!latest || latest === "0.3.110") return;
|
|
3751
3751
|
if (autoUpdate) {
|
|
3752
3752
|
warn(`
|
|
3753
|
-
Your arbi version is out of date (${"0.3.
|
|
3753
|
+
Your arbi version is out of date (${"0.3.110"} \u2192 ${latest}). Updating...`);
|
|
3754
3754
|
child_process.execSync("npm install -g @arbidocs/cli@latest", { stdio: "inherit" });
|
|
3755
|
-
showChangelog("0.3.
|
|
3755
|
+
showChangelog("0.3.110", latest);
|
|
3756
3756
|
console.log(`Updated to ${latest}.`);
|
|
3757
3757
|
} else {
|
|
3758
3758
|
warn(
|
|
3759
3759
|
`
|
|
3760
|
-
Your arbi version is out of date (${"0.3.
|
|
3760
|
+
Your arbi version is out of date (${"0.3.110"} \u2192 ${latest}).
|
|
3761
3761
|
Run "arbi update" to upgrade, or "arbi update auto" to always stay up to date.`
|
|
3762
3762
|
);
|
|
3763
3763
|
}
|
|
@@ -3789,10 +3789,10 @@ function markNagShown(latest) {
|
|
|
3789
3789
|
function hintUpdateOnError() {
|
|
3790
3790
|
try {
|
|
3791
3791
|
const cached = readCache();
|
|
3792
|
-
if (!cached || cached.latest === "0.3.
|
|
3792
|
+
if (!cached || cached.latest === "0.3.110") return;
|
|
3793
3793
|
if (!shouldShowNag(cached.latest)) return;
|
|
3794
3794
|
warn(
|
|
3795
|
-
`Your arbi version is out of date (${"0.3.
|
|
3795
|
+
`Your arbi version is out of date (${"0.3.110"} \u2192 ${cached.latest}). Run "arbi update".`
|
|
3796
3796
|
);
|
|
3797
3797
|
markNagShown(cached.latest);
|
|
3798
3798
|
} catch {
|
|
@@ -4023,8 +4023,8 @@ async function resolveDmCrypto() {
|
|
|
4023
4023
|
error("No user ID in session \u2014 cannot set up DM encryption.");
|
|
4024
4024
|
process.exit(1);
|
|
4025
4025
|
}
|
|
4026
|
-
const
|
|
4027
|
-
return { ...authCtx, crypto
|
|
4026
|
+
const crypto = sdk.dm.createDmCryptoContext(arbi, loginResult.signingPrivateKey, userExtId);
|
|
4027
|
+
return { ...authCtx, crypto };
|
|
4028
4028
|
}
|
|
4029
4029
|
function truncate(value, width) {
|
|
4030
4030
|
if (width <= 0) return "";
|
|
@@ -4256,7 +4256,7 @@ async function startListening(agentName, config) {
|
|
|
4256
4256
|
process.exit(1);
|
|
4257
4257
|
}
|
|
4258
4258
|
dim("Starting DM listener...");
|
|
4259
|
-
const { arbi, crypto
|
|
4259
|
+
const { arbi, crypto } = await resolveDmCrypto();
|
|
4260
4260
|
const fullConfig = resolveConfig();
|
|
4261
4261
|
const sessionId = arbi.session.getState().userExtId ?? "default";
|
|
4262
4262
|
const agentId = backend === "openclaw" ? sessionId.toLowerCase() : void 0;
|
|
@@ -4268,7 +4268,7 @@ async function startListening(agentName, config) {
|
|
|
4268
4268
|
const listener = await sdk.startDmListener({
|
|
4269
4269
|
arbi,
|
|
4270
4270
|
baseUrl: fullConfig.baseUrl,
|
|
4271
|
-
crypto
|
|
4271
|
+
crypto,
|
|
4272
4272
|
orchestrator,
|
|
4273
4273
|
parentExtId: creds.parentExtId,
|
|
4274
4274
|
onLog: (msg) => dim(msg),
|
|
@@ -4422,6 +4422,46 @@ Open this URL in your browser:
|
|
|
4422
4422
|
);
|
|
4423
4423
|
}
|
|
4424
4424
|
init_prompts();
|
|
4425
|
+
|
|
4426
|
+
// src/utils/central-retry.ts
|
|
4427
|
+
function isRetryableStatus(status2) {
|
|
4428
|
+
if (status2 === void 0) return false;
|
|
4429
|
+
return status2 === 429 || status2 >= 500 && status2 <= 599;
|
|
4430
|
+
}
|
|
4431
|
+
async function withRetry(fn, options) {
|
|
4432
|
+
const { shouldRetry, maxAttempts = 6, baseDelayMs = 1e3, maxDelayMs = 2e4 } = options;
|
|
4433
|
+
let lastResult;
|
|
4434
|
+
let lastError;
|
|
4435
|
+
let lastAttemptThrew = false;
|
|
4436
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
4437
|
+
let result;
|
|
4438
|
+
let error2;
|
|
4439
|
+
let threw = false;
|
|
4440
|
+
try {
|
|
4441
|
+
result = await fn();
|
|
4442
|
+
lastResult = result;
|
|
4443
|
+
lastAttemptThrew = false;
|
|
4444
|
+
} catch (err) {
|
|
4445
|
+
threw = true;
|
|
4446
|
+
error2 = err;
|
|
4447
|
+
lastError = err;
|
|
4448
|
+
lastAttemptThrew = true;
|
|
4449
|
+
}
|
|
4450
|
+
if (!shouldRetry(threw ? void 0 : result, threw ? error2 : void 0)) {
|
|
4451
|
+
if (threw) throw error2;
|
|
4452
|
+
return result;
|
|
4453
|
+
}
|
|
4454
|
+
if (attempt === maxAttempts - 1) break;
|
|
4455
|
+
const exp = Math.min(baseDelayMs * 2 ** attempt, maxDelayMs);
|
|
4456
|
+
const jitter = exp * 0.2 * (Math.random() * 2 - 1);
|
|
4457
|
+
const delay = Math.max(0, Math.round(exp + jitter));
|
|
4458
|
+
await new Promise((resolve6) => setTimeout(resolve6, delay));
|
|
4459
|
+
}
|
|
4460
|
+
if (lastAttemptThrew) throw lastError;
|
|
4461
|
+
return lastResult;
|
|
4462
|
+
}
|
|
4463
|
+
|
|
4464
|
+
// src/commands/register.ts
|
|
4425
4465
|
var CENTRAL_API_URL = "https://central.arbi.work";
|
|
4426
4466
|
var RegisterHintError = class extends Error {
|
|
4427
4467
|
constructor(message, kind) {
|
|
@@ -4437,10 +4477,11 @@ function looksLikeAgentEmail(email) {
|
|
|
4437
4477
|
}
|
|
4438
4478
|
async function getVerificationCode(email, apiKey, deploymentDomain) {
|
|
4439
4479
|
const params = new URLSearchParams({ email });
|
|
4440
|
-
const
|
|
4441
|
-
|
|
4442
|
-
headers: { "x-api-key": apiKey }
|
|
4443
|
-
|
|
4480
|
+
const url = `${CENTRAL_API_URL}/license-management/verify-ci?${params.toString()}`;
|
|
4481
|
+
const res = await withRetry(
|
|
4482
|
+
() => fetch(url, { method: "GET", headers: { "x-api-key": apiKey } }),
|
|
4483
|
+
{ shouldRetry: (result, err) => err != null || isRetryableStatus(result?.status) }
|
|
4484
|
+
);
|
|
4444
4485
|
if (!res.ok) {
|
|
4445
4486
|
const body = await res.text().catch(() => "");
|
|
4446
4487
|
if (res.status === 403 && /agent-\*/i.test(body)) {
|
|
@@ -4504,9 +4545,12 @@ async function smartRegister(config, opts) {
|
|
|
4504
4545
|
verificationCode = await promptInput("Invitation code");
|
|
4505
4546
|
} else {
|
|
4506
4547
|
console.log("Sending verification email...");
|
|
4507
|
-
const verifyResponse = await
|
|
4508
|
-
body: { email }
|
|
4509
|
-
|
|
4548
|
+
const verifyResponse = await withRetry(
|
|
4549
|
+
() => arbi.fetch.POST("/v1/user/verify-email", { body: { email } }),
|
|
4550
|
+
{
|
|
4551
|
+
shouldRetry: (result, err) => err != null || result?.error != null && isRetryableStatus(result.response?.status)
|
|
4552
|
+
}
|
|
4553
|
+
);
|
|
4510
4554
|
if (verifyResponse.error) {
|
|
4511
4555
|
error(`Failed to send verification email: ${JSON.stringify(verifyResponse.error)}`);
|
|
4512
4556
|
process.exit(1);
|
|
@@ -4627,9 +4671,12 @@ async function nonInteractiveRegister(config, opts) {
|
|
|
4627
4671
|
);
|
|
4628
4672
|
process.exit(1);
|
|
4629
4673
|
}
|
|
4630
|
-
const verifyResponse = await
|
|
4631
|
-
body: { email }
|
|
4632
|
-
|
|
4674
|
+
const verifyResponse = await withRetry(
|
|
4675
|
+
() => arbi.fetch.POST("/v1/user/verify-email", { body: { email } }),
|
|
4676
|
+
{
|
|
4677
|
+
shouldRetry: (result, err) => err != null || result?.error != null && isRetryableStatus(result.response?.status)
|
|
4678
|
+
}
|
|
4679
|
+
);
|
|
4633
4680
|
if (verifyResponse.error) {
|
|
4634
4681
|
if (opts.json) {
|
|
4635
4682
|
console.log(
|
|
@@ -4872,8 +4919,8 @@ function registerDmCommand(program2) {
|
|
|
4872
4919
|
"Show the full conversation with one peer (both directions)"
|
|
4873
4920
|
).option("--since <iso>", "Only messages newer than this ISO timestamp").option("-l, --limit <n>", "Cap to N most-recent messages", (v) => parseInt(v, 10)).option("--json", "Output as JSON (recommended for scripting / agents)").action(
|
|
4874
4921
|
(opts) => runAction(async () => {
|
|
4875
|
-
const { arbi, crypto
|
|
4876
|
-
const all = await sdk.dm.listDecryptedDMs(arbi,
|
|
4922
|
+
const { arbi, crypto } = await resolveDmCrypto();
|
|
4923
|
+
const all = await sdk.dm.listDecryptedDMs(arbi, crypto);
|
|
4877
4924
|
const myExtId = arbi.session.getState().userExtId ?? void 0;
|
|
4878
4925
|
const dms = all.filter((r) => r.type === "user_message");
|
|
4879
4926
|
const filterOpts = {
|
|
@@ -4927,7 +4974,7 @@ function registerDmCommand(program2) {
|
|
|
4927
4974
|
);
|
|
4928
4975
|
dm.command("send [recipient] [content...]").description("Send an E2E encrypted DM (interactive if no args)").action(
|
|
4929
4976
|
(recipient, contentParts) => runAction(async () => {
|
|
4930
|
-
const { arbi, crypto
|
|
4977
|
+
const { arbi, crypto } = await resolveDmCrypto();
|
|
4931
4978
|
if (!recipient) {
|
|
4932
4979
|
requireInteractive(
|
|
4933
4980
|
'Pass recipient + message as arguments: arbi dm send <email-or-id> "<message>"'
|
|
@@ -4982,7 +5029,7 @@ Try: arbi contacts add ${recipient.includes("@") ? recipient : "<their-email>"}`
|
|
|
4982
5029
|
recipient_encryption_public_key: recipientPubKey
|
|
4983
5030
|
}
|
|
4984
5031
|
],
|
|
4985
|
-
|
|
5032
|
+
crypto
|
|
4986
5033
|
);
|
|
4987
5034
|
for (const n of data) {
|
|
4988
5035
|
success(`Sent (encrypted): ${n.external_id} \u2192 ${n.recipient.email}`);
|
|
@@ -4991,14 +5038,14 @@ Try: arbi contacts add ${recipient.includes("@") ? recipient : "<their-email>"}`
|
|
|
4991
5038
|
);
|
|
4992
5039
|
dm.command("read [ids...]").description("Mark messages as read (interactive picker if no IDs given)").option("--all", "Mark every unread message as read (no picker)").action(
|
|
4993
5040
|
(ids, opts) => runAction(async () => {
|
|
4994
|
-
const { arbi, crypto
|
|
5041
|
+
const { arbi, crypto } = await resolveDmCrypto();
|
|
4995
5042
|
let msgIds = ids && ids.length > 0 ? ids : void 0;
|
|
4996
5043
|
if (!msgIds && opts?.all) {
|
|
4997
|
-
const data2 = await sdk.dm.listDecryptedDMs(arbi,
|
|
5044
|
+
const data2 = await sdk.dm.listDecryptedDMs(arbi, crypto);
|
|
4998
5045
|
msgIds = data2.filter((m) => !m.read).map((m) => m.external_id);
|
|
4999
5046
|
}
|
|
5000
5047
|
if (!msgIds) {
|
|
5001
|
-
const data2 = await sdk.dm.listDecryptedDMs(arbi,
|
|
5048
|
+
const data2 = await sdk.dm.listDecryptedDMs(arbi, crypto);
|
|
5002
5049
|
const unread = data2.filter((m) => !m.read);
|
|
5003
5050
|
if (unread.length === 0) {
|
|
5004
5051
|
process.stderr.write("No unread messages.\n");
|
|
@@ -5028,14 +5075,14 @@ Try: arbi contacts add ${recipient.includes("@") ? recipient : "<their-email>"}`
|
|
|
5028
5075
|
);
|
|
5029
5076
|
dm.command("delete [ids...]").description("Delete messages (interactive picker if no IDs given)").option("--all", "Delete every message in your DM history (no picker, no prompt)").option("--dry-run", "Preview which messages would be deleted (no SDK call)").action(
|
|
5030
5077
|
(ids, opts) => runAction(async () => {
|
|
5031
|
-
const { arbi, crypto
|
|
5078
|
+
const { arbi, crypto } = await resolveDmCrypto();
|
|
5032
5079
|
let msgIds = ids && ids.length > 0 ? ids : void 0;
|
|
5033
5080
|
if (!msgIds && opts?.all) {
|
|
5034
|
-
const data = await sdk.dm.listDecryptedDMs(arbi,
|
|
5081
|
+
const data = await sdk.dm.listDecryptedDMs(arbi, crypto);
|
|
5035
5082
|
msgIds = data.map((m) => m.external_id);
|
|
5036
5083
|
}
|
|
5037
5084
|
if (!msgIds) {
|
|
5038
|
-
const data = await sdk.dm.listDecryptedDMs(arbi,
|
|
5085
|
+
const data = await sdk.dm.listDecryptedDMs(arbi, crypto);
|
|
5039
5086
|
if (data.length === 0) {
|
|
5040
5087
|
process.stderr.write("No messages found.\n");
|
|
5041
5088
|
return;
|
|
@@ -5426,7 +5473,7 @@ function registerWorkspacesCommand(program2) {
|
|
|
5426
5473
|
"Target a specific workspace id (advanced \u2014 usually omitted; the owner picks)"
|
|
5427
5474
|
).action(
|
|
5428
5475
|
(owner, opts) => runAction(async () => {
|
|
5429
|
-
const { arbi, crypto
|
|
5476
|
+
const { arbi, crypto, loginResult } = await resolveDmCrypto();
|
|
5430
5477
|
const resolved = await resolveRecipient(arbi, owner);
|
|
5431
5478
|
if (!resolved || !resolved.pubKey) {
|
|
5432
5479
|
error(
|
|
@@ -5444,7 +5491,7 @@ Try: arbi contacts add ${owner.includes("@") ? owner : "<their-email>"}`
|
|
|
5444
5491
|
note: opts.note,
|
|
5445
5492
|
workspaceExtId: opts.workspace
|
|
5446
5493
|
},
|
|
5447
|
-
|
|
5494
|
+
crypto
|
|
5448
5495
|
);
|
|
5449
5496
|
success(
|
|
5450
5497
|
`Requested workspace access from ${owner}` + (opts.workspace ? ` (workspace ${opts.workspace})` : "") + ". They\u2019ll be notified and can grant temporary or permanent access."
|
|
@@ -7650,7 +7697,7 @@ Error: ${message}`))
|
|
|
7650
7697
|
);
|
|
7651
7698
|
}
|
|
7652
7699
|
function hashUtf8(s) {
|
|
7653
|
-
return crypto
|
|
7700
|
+
return crypto.createHash("sha256").update(s, "utf8").digest("hex");
|
|
7654
7701
|
}
|
|
7655
7702
|
function registerCiteCommand(program2) {
|
|
7656
7703
|
program2.command("cite [number]").description("Browse citations from the last `arbi ask` response in this shell").allowExcessArguments(true).option("-a, --all", "Show all citations as markdown blocks").option("--json", "Output citations as JSON (full structured payload)").action(
|
|
@@ -9121,10 +9168,11 @@ var CENTRAL_API_URL2 = "https://central.arbi.work";
|
|
|
9121
9168
|
var DEFAULT_PASSWORD = "agent-dev-1234";
|
|
9122
9169
|
async function getVerificationCode2(email, apiKey) {
|
|
9123
9170
|
const params = new URLSearchParams({ email });
|
|
9124
|
-
const
|
|
9125
|
-
|
|
9126
|
-
headers: { "x-api-key": apiKey }
|
|
9127
|
-
|
|
9171
|
+
const url = `${CENTRAL_API_URL2}/license-management/verify-ci?${params.toString()}`;
|
|
9172
|
+
const res = await withRetry(
|
|
9173
|
+
() => fetch(url, { method: "GET", headers: { "x-api-key": apiKey } }),
|
|
9174
|
+
{ shouldRetry: (result, err) => err != null || isRetryableStatus(result?.status) }
|
|
9175
|
+
);
|
|
9128
9176
|
if (!res.ok) {
|
|
9129
9177
|
const body = await res.text().catch(() => "");
|
|
9130
9178
|
throw new Error(`Failed to get verification code: ${res.status} ${body}`);
|
|
@@ -9168,9 +9216,12 @@ function registerAgentCreateCommand(program2) {
|
|
|
9168
9216
|
credentials: "omit"
|
|
9169
9217
|
});
|
|
9170
9218
|
await arbiClient.crypto.initSodium();
|
|
9171
|
-
const verifyResponse = await
|
|
9172
|
-
body: { email }
|
|
9173
|
-
|
|
9219
|
+
const verifyResponse = await withRetry(
|
|
9220
|
+
() => arbiClient.fetch.POST("/v1/user/verify-email", { body: { email } }),
|
|
9221
|
+
{
|
|
9222
|
+
shouldRetry: (result, err) => err != null || result?.error != null && isRetryableStatus(result.response?.status)
|
|
9223
|
+
}
|
|
9224
|
+
);
|
|
9174
9225
|
if (verifyResponse.error) {
|
|
9175
9226
|
error(`verify-email failed: ${JSON.stringify(verifyResponse.error)}`);
|
|
9176
9227
|
process.exit(1);
|
|
@@ -9229,12 +9280,6 @@ function registerAgentCreateCommand(program2) {
|
|
|
9229
9280
|
);
|
|
9230
9281
|
}
|
|
9231
9282
|
init_prompts();
|
|
9232
|
-
function generatePassword() {
|
|
9233
|
-
const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
|
|
9234
|
-
const bytes = new Uint8Array(20);
|
|
9235
|
-
crypto.getRandomValues(bytes);
|
|
9236
|
-
return Array.from(bytes, (b) => chars[b % chars.length]).join("");
|
|
9237
|
-
}
|
|
9238
9283
|
function registerAgentCommand(program2) {
|
|
9239
9284
|
const agent = program2.command("agent").description(
|
|
9240
9285
|
"Child agents under your user: list, create, delete (for SUPPORT_API_KEY bot accounts, use `arbi agent-create`)"
|
|
@@ -9244,7 +9289,6 @@ function registerAgentCommand(program2) {
|
|
|
9244
9289
|
).option("--name <name>", "Agent name (letters, digits, hyphens, underscores)").option("-w, --workspace <ids...>", "Workspace IDs to share with the agent").option("--role <role>", "Workspace role: collaborator or guest", "collaborator").action(
|
|
9245
9290
|
(opts) => runAction(async () => {
|
|
9246
9291
|
const { arbi, loginResult } = await resolveAuth();
|
|
9247
|
-
const config = resolveConfig();
|
|
9248
9292
|
const creds = store.requireCredentials();
|
|
9249
9293
|
let name = opts.name;
|
|
9250
9294
|
if (!name) name = await promptInput("Agent name (letters, digits, hyphens, underscores)");
|
|
@@ -9264,25 +9308,7 @@ function registerAgentCommand(program2) {
|
|
|
9264
9308
|
);
|
|
9265
9309
|
}
|
|
9266
9310
|
}
|
|
9267
|
-
await
|
|
9268
|
-
const parentExtId = arbi.session.getState().userExtId ?? "";
|
|
9269
|
-
if (!parentExtId) throw new Error("Could not determine current user ext_id");
|
|
9270
|
-
const agentEmail = `${name.trim()}.${parentExtId}@${config.deploymentDomain}`;
|
|
9271
|
-
const password2 = generatePassword();
|
|
9272
|
-
const { signingPrivateKey } = await client.generateLoginCredentials(
|
|
9273
|
-
{ email: agentEmail },
|
|
9274
|
-
password2,
|
|
9275
|
-
config.deploymentDomain
|
|
9276
|
-
);
|
|
9277
|
-
const signingPubKey = client.bytesToBase64(signingPrivateKey.slice(32));
|
|
9278
|
-
const { data: agent2, error: error2 } = await arbi.fetch.POST("/v1/user/agent", {
|
|
9279
|
-
body: {
|
|
9280
|
-
name: name.trim(),
|
|
9281
|
-
signing_key: signingPubKey,
|
|
9282
|
-
recovery_key: client.bytesToBase64(signingPrivateKey)
|
|
9283
|
-
}
|
|
9284
|
-
});
|
|
9285
|
-
if (!agent2) throw new Error(`Failed to create agent: ${JSON.stringify(error2)}`);
|
|
9311
|
+
const agent2 = await sdk.agents.createAgent(arbi, name.trim());
|
|
9286
9312
|
if (workspaceIds.length > 0) {
|
|
9287
9313
|
const { data: allWs } = await arbi.fetch.GET("/v1/user/workspaces");
|
|
9288
9314
|
for (const wsId of workspaceIds) {
|
|
@@ -9310,11 +9336,12 @@ function registerAgentCommand(program2) {
|
|
|
9310
9336
|
console.log("");
|
|
9311
9337
|
success("Agent created!");
|
|
9312
9338
|
console.log("");
|
|
9313
|
-
console.log(` Email:
|
|
9314
|
-
console.log(`
|
|
9315
|
-
if (workspaceIds.length > 0) console.log(` Workspaces:
|
|
9339
|
+
console.log(` Email: ${ref(agent2.email)}`);
|
|
9340
|
+
console.log(` Signing key: ${ref(agent2.signing_private_key)}`);
|
|
9341
|
+
if (workspaceIds.length > 0) console.log(` Workspaces: ${workspaceIds.join(", ")}`);
|
|
9316
9342
|
console.log("");
|
|
9317
|
-
dim(
|
|
9343
|
+
dim(" Save the signing key now \u2014 it is shown only once.");
|
|
9344
|
+
dim(`On the agent machine: arbi login --email ${agent2.email} --signing-key <signing-key>`);
|
|
9318
9345
|
})()
|
|
9319
9346
|
);
|
|
9320
9347
|
agent.command("list").description("List your persistent agents").option("--json", "Output as JSON (recommended for scripting / agents)").action(
|
|
@@ -9792,8 +9819,8 @@ function registerNotificationsCommand(program2) {
|
|
|
9792
9819
|
const notif = program2.command("notifications").enablePositionalOptions().description("Non-DM notifications");
|
|
9793
9820
|
notif.command("list").description("List non-DM notifications (workspace invites, contact accepts, \u2026)").option("--unread", "Only show unread notifications").option("--type <comma-list>", "Filter to specific type(s), e.g. workspaceuser_invited").option("-l, --limit <n>", "Cap to N most-recent", (v) => parseInt(v, 10)).option("--json", "Output as JSON (recommended for scripting / agents)").action(
|
|
9794
9821
|
(opts) => runAction(async () => {
|
|
9795
|
-
const { arbi, crypto
|
|
9796
|
-
const all = await sdk.dm.listDecryptedDMs(arbi,
|
|
9822
|
+
const { arbi, crypto } = await resolveDmCrypto();
|
|
9823
|
+
const all = await sdk.dm.listDecryptedDMs(arbi, crypto);
|
|
9797
9824
|
const nonDm = all.filter((r) => r.type !== "user_message");
|
|
9798
9825
|
const typeFilter = opts.type ? new Set(
|
|
9799
9826
|
opts.type.split(",").map((t) => t.trim()).filter(Boolean)
|
|
@@ -9832,10 +9859,10 @@ function registerNotificationsCommand(program2) {
|
|
|
9832
9859
|
);
|
|
9833
9860
|
notif.command("mark-read [ids...]").description("Mark notifications as read (use --all to drain the unread queue)").option("--all", "Mark every unread non-DM notification as read").action(
|
|
9834
9861
|
(ids, opts) => runAction(async () => {
|
|
9835
|
-
const { arbi, crypto
|
|
9862
|
+
const { arbi, crypto } = await resolveDmCrypto();
|
|
9836
9863
|
let toMark = ids && ids.length > 0 ? ids : void 0;
|
|
9837
9864
|
if (!toMark && opts.all) {
|
|
9838
|
-
const all = await sdk.dm.listDecryptedDMs(arbi,
|
|
9865
|
+
const all = await sdk.dm.listDecryptedDMs(arbi, crypto);
|
|
9839
9866
|
toMark = all.filter((r) => r.type !== "user_message" && !r.read).map((r) => r.external_id);
|
|
9840
9867
|
}
|
|
9841
9868
|
if (!toMark || toMark.length === 0) {
|
|
@@ -9849,10 +9876,10 @@ function registerNotificationsCommand(program2) {
|
|
|
9849
9876
|
);
|
|
9850
9877
|
notif.command("delete [ids...]").description("Delete notifications by ID (or use --all to clear non-DM noise)").option("--all", "Delete every non-DM notification (workspace invites, contact accepts, ...)").option("--dry-run", "Preview which notifications would be deleted (no SDK call)").action(
|
|
9851
9878
|
(ids, opts) => runAction(async () => {
|
|
9852
|
-
const { arbi, crypto
|
|
9879
|
+
const { arbi, crypto } = await resolveDmCrypto();
|
|
9853
9880
|
let toDelete = ids && ids.length > 0 ? ids : void 0;
|
|
9854
9881
|
if (!toDelete && opts.all) {
|
|
9855
|
-
const all = await sdk.dm.listDecryptedDMs(arbi,
|
|
9882
|
+
const all = await sdk.dm.listDecryptedDMs(arbi, crypto);
|
|
9856
9883
|
toDelete = all.filter((r) => r.type !== "user_message").map((r) => r.external_id);
|
|
9857
9884
|
}
|
|
9858
9885
|
if (!toDelete || toDelete.length === 0) {
|
|
@@ -10305,7 +10332,7 @@ console.info = (...args) => {
|
|
|
10305
10332
|
_origInfo(...args);
|
|
10306
10333
|
};
|
|
10307
10334
|
var program = new commander.Command();
|
|
10308
|
-
program.name("arbi").description("ARBI CLI \u2014 interact with ARBI from the terminal").version("0.3.
|
|
10335
|
+
program.name("arbi").description("ARBI CLI \u2014 interact with ARBI from the terminal").version("0.3.110").showHelpAfterError(true).showSuggestionAfterError(true);
|
|
10309
10336
|
registerConfigCommand(program);
|
|
10310
10337
|
registerLoginCommand(program);
|
|
10311
10338
|
registerRegisterCommand(program);
|