@deeplake/hivemind 0.7.37 → 0.7.38
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/.claude-plugin/marketplace.json +3 -3
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +11 -1
- package/bundle/cli.js +176 -32
- package/codex/bundle/commands/auth-login.js +88 -24
- package/cursor/bundle/commands/auth-login.js +88 -24
- package/hermes/bundle/commands/auth-login.js +88 -24
- package/mcp/bundle/server.js +1 -0
- package/openclaw/dist/index.js +1 -1
- package/openclaw/openclaw.plugin.json +1 -1
- package/openclaw/package.json +1 -1
- package/package.json +1 -1
|
@@ -6,18 +6,18 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "Cloud-backed persistent shared memory for AI agents powered by Deeplake",
|
|
9
|
-
"version": "0.7.
|
|
9
|
+
"version": "0.7.38"
|
|
10
10
|
},
|
|
11
11
|
"plugins": [
|
|
12
12
|
{
|
|
13
13
|
"name": "hivemind",
|
|
14
14
|
"description": "Persistent shared memory powered by Deeplake — captures all session activity and provides cross-session, cross-agent memory search",
|
|
15
|
-
"version": "0.7.
|
|
15
|
+
"version": "0.7.38",
|
|
16
16
|
"source": {
|
|
17
17
|
"source": "git-subdir",
|
|
18
18
|
"url": "https://github.com/activeloopai/hivemind.git",
|
|
19
19
|
"path": "claude-code",
|
|
20
|
-
"sha": "
|
|
20
|
+
"sha": "871fcb8d1cca4ab93ad139b93652a161d7bc3a8a"
|
|
21
21
|
},
|
|
22
22
|
"homepage": "https://github.com/activeloopai/hivemind"
|
|
23
23
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hivemind",
|
|
3
3
|
"description": "Cloud-backed persistent memory powered by Deeplake — read, write, and share memory across Claude Code sessions and agents",
|
|
4
|
-
"version": "0.7.
|
|
4
|
+
"version": "0.7.38",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Activeloop",
|
|
7
7
|
"url": "https://deeplake.ai"
|
package/README.md
CHANGED
|
@@ -43,7 +43,17 @@ One command, all your agents:
|
|
|
43
43
|
npm install -g @deeplake/hivemind && hivemind install
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
The installer detects every supported assistant on your machine (table below), wires up the hooks, and
|
|
46
|
+
The installer detects every supported assistant on your machine (table below), wires up the hooks, and shows a one-line consent prompt before opening a browser for sign-in. Restart your assistants after install.
|
|
47
|
+
|
|
48
|
+
**Headless / CI installs** — pass an API token instead of using the browser flow:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
HIVEMIND_TOKEN=<your-token> hivemind install
|
|
52
|
+
# or
|
|
53
|
+
hivemind install --token <your-token>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Get a token from your account settings on https://deeplake.ai. With no token in a non-interactive shell, the install completes with hooks but skips sign-in; run `hivemind login` later to enable shared memory.
|
|
47
57
|
|
|
48
58
|
**Install for a specific assistant only:**
|
|
49
59
|
|
package/bundle/cli.js
CHANGED
|
@@ -63,6 +63,7 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync, cpSync, symlinkSync
|
|
|
63
63
|
import { join, dirname } from "node:path";
|
|
64
64
|
import { homedir } from "node:os";
|
|
65
65
|
import { fileURLToPath } from "node:url";
|
|
66
|
+
import { createInterface } from "node:readline";
|
|
66
67
|
var HOME = homedir();
|
|
67
68
|
function pkgRoot() {
|
|
68
69
|
let dir = fileURLToPath(new URL(".", import.meta.url));
|
|
@@ -140,6 +141,29 @@ function log(msg) {
|
|
|
140
141
|
function warn(msg) {
|
|
141
142
|
process.stderr.write(msg + "\n");
|
|
142
143
|
}
|
|
144
|
+
function confirm(message, defaultYes = true) {
|
|
145
|
+
const hint = defaultYes ? "[Y/n]" : "[y/N]";
|
|
146
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
147
|
+
return new Promise((resolve2) => {
|
|
148
|
+
rl.question(`${message} ${hint} `, (answer) => {
|
|
149
|
+
rl.close();
|
|
150
|
+
const a = answer.trim().toLowerCase();
|
|
151
|
+
if (a === "")
|
|
152
|
+
resolve2(defaultYes);
|
|
153
|
+
else
|
|
154
|
+
resolve2(a === "y" || a === "yes");
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
function promptLine(message) {
|
|
159
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
160
|
+
return new Promise((resolve2) => {
|
|
161
|
+
rl.question(message, (answer) => {
|
|
162
|
+
rl.close();
|
|
163
|
+
resolve2(answer.trim());
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
}
|
|
143
167
|
|
|
144
168
|
// dist/src/cli/install-claude.js
|
|
145
169
|
var MARKETPLACE_NAME = "hivemind";
|
|
@@ -4067,6 +4091,19 @@ function deleteCredentials() {
|
|
|
4067
4091
|
|
|
4068
4092
|
// dist/src/commands/auth.js
|
|
4069
4093
|
var DEFAULT_API_URL = "https://api.deeplake.ai";
|
|
4094
|
+
function decodeJwtPayload(token) {
|
|
4095
|
+
try {
|
|
4096
|
+
const parts = token.split(".");
|
|
4097
|
+
if (parts.length !== 3)
|
|
4098
|
+
return null;
|
|
4099
|
+
let payload = parts[1].replace(/-/g, "+").replace(/_/g, "/");
|
|
4100
|
+
while (payload.length % 4)
|
|
4101
|
+
payload += "=";
|
|
4102
|
+
return JSON.parse(Buffer.from(payload, "base64").toString("utf8"));
|
|
4103
|
+
} catch {
|
|
4104
|
+
return null;
|
|
4105
|
+
}
|
|
4106
|
+
}
|
|
4070
4107
|
async function apiGet(path, token, apiUrl, orgId) {
|
|
4071
4108
|
const headers = {
|
|
4072
4109
|
Authorization: `Bearer ${token}`,
|
|
@@ -4197,17 +4234,32 @@ async function listMembers(token, orgId, apiUrl = DEFAULT_API_URL) {
|
|
|
4197
4234
|
async function removeMember(userId, token, orgId, apiUrl = DEFAULT_API_URL) {
|
|
4198
4235
|
await apiDelete(`/organizations/${orgId}/members/${userId}`, token, apiUrl, orgId);
|
|
4199
4236
|
}
|
|
4200
|
-
async function
|
|
4201
|
-
const
|
|
4202
|
-
const user = await apiGet("/me", authToken, apiUrl);
|
|
4237
|
+
async function saveCredentialsFromToken(token, apiUrl, opts = {}) {
|
|
4238
|
+
const user = await apiGet("/me", token, apiUrl);
|
|
4203
4239
|
const userName = user.name || (user.email ? user.email.split("@")[0] : "unknown");
|
|
4204
4240
|
process.stderr.write(`
|
|
4205
4241
|
Logged in as: ${userName}
|
|
4206
4242
|
`);
|
|
4207
|
-
const orgs = await listOrgs(
|
|
4243
|
+
const orgs = await listOrgs(token, apiUrl);
|
|
4244
|
+
if (orgs.length === 0)
|
|
4245
|
+
throw new Error("No organizations found for this account.");
|
|
4246
|
+
const envOrgId = process.env.HIVEMIND_ORG_ID;
|
|
4247
|
+
let preferredOrgId = envOrgId;
|
|
4248
|
+
if (!preferredOrgId && opts.skipTokenMint) {
|
|
4249
|
+
const claims = decodeJwtPayload(token);
|
|
4250
|
+
const claimOrg = claims && typeof claims.org_id === "string" ? claims.org_id : void 0;
|
|
4251
|
+
if (claimOrg)
|
|
4252
|
+
preferredOrgId = claimOrg;
|
|
4253
|
+
}
|
|
4208
4254
|
let orgId;
|
|
4209
4255
|
let orgName;
|
|
4210
|
-
|
|
4256
|
+
const matched = preferredOrgId ? orgs.find((o) => o.id === preferredOrgId) : void 0;
|
|
4257
|
+
if (matched) {
|
|
4258
|
+
orgId = matched.id;
|
|
4259
|
+
orgName = matched.name;
|
|
4260
|
+
process.stderr.write(`Organization: ${orgName}
|
|
4261
|
+
`);
|
|
4262
|
+
} else if (orgs.length === 1) {
|
|
4211
4263
|
orgId = orgs[0].id;
|
|
4212
4264
|
orgName = orgs[0].name;
|
|
4213
4265
|
process.stderr.write(`Organization: ${orgName}
|
|
@@ -4218,17 +4270,26 @@ Logged in as: ${userName}
|
|
|
4218
4270
|
`));
|
|
4219
4271
|
orgId = orgs[0].id;
|
|
4220
4272
|
orgName = orgs[0].name;
|
|
4221
|
-
|
|
4273
|
+
if (opts.skipTokenMint) {
|
|
4274
|
+
process.stderr.write(`
|
|
4275
|
+
Using: ${orgName} (set HIVEMIND_ORG_ID to override)
|
|
4276
|
+
`);
|
|
4277
|
+
} else {
|
|
4278
|
+
process.stderr.write(`
|
|
4222
4279
|
Using: ${orgName}
|
|
4223
4280
|
`);
|
|
4281
|
+
}
|
|
4282
|
+
}
|
|
4283
|
+
let apiToken = token;
|
|
4284
|
+
if (!opts.skipTokenMint) {
|
|
4285
|
+
const tokenName = `deeplake-plugin-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}`;
|
|
4286
|
+
const tokenData = await apiPost("/users/me/tokens", {
|
|
4287
|
+
name: tokenName,
|
|
4288
|
+
duration: 365 * 24 * 3600,
|
|
4289
|
+
organization_id: orgId
|
|
4290
|
+
}, token, apiUrl);
|
|
4291
|
+
apiToken = tokenData.token.token;
|
|
4224
4292
|
}
|
|
4225
|
-
const tokenName = `deeplake-plugin-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}`;
|
|
4226
|
-
const tokenData = await apiPost("/users/me/tokens", {
|
|
4227
|
-
name: tokenName,
|
|
4228
|
-
duration: 365 * 24 * 3600,
|
|
4229
|
-
organization_id: orgId
|
|
4230
|
-
}, authToken, apiUrl);
|
|
4231
|
-
const apiToken = tokenData.token.token;
|
|
4232
4293
|
const creds = {
|
|
4233
4294
|
token: apiToken,
|
|
4234
4295
|
orgId,
|
|
@@ -4241,8 +4302,16 @@ Using: ${orgName}
|
|
|
4241
4302
|
saveCredentials(creds);
|
|
4242
4303
|
return creds;
|
|
4243
4304
|
}
|
|
4305
|
+
async function login(apiUrl = DEFAULT_API_URL) {
|
|
4306
|
+
const { token: authToken } = await deviceFlowLogin(apiUrl);
|
|
4307
|
+
return saveCredentialsFromToken(authToken, apiUrl, { skipTokenMint: false });
|
|
4308
|
+
}
|
|
4244
4309
|
|
|
4245
4310
|
// dist/src/cli/auth.js
|
|
4311
|
+
var DEFAULT_API_URL2 = "https://api.deeplake.ai";
|
|
4312
|
+
function resolveApiUrl() {
|
|
4313
|
+
return process.env.HIVEMIND_API_URL ?? DEFAULT_API_URL2;
|
|
4314
|
+
}
|
|
4246
4315
|
var CREDS_PATH = join14(HOME, ".deeplake", "credentials.json");
|
|
4247
4316
|
function isLoggedIn() {
|
|
4248
4317
|
return existsSync12(CREDS_PATH) && loadCredentials() !== null;
|
|
@@ -4253,14 +4322,27 @@ async function ensureLoggedIn() {
|
|
|
4253
4322
|
log("");
|
|
4254
4323
|
log("No Deeplake credentials found. Starting login...");
|
|
4255
4324
|
try {
|
|
4256
|
-
|
|
4257
|
-
await login(apiUrl);
|
|
4325
|
+
await login(resolveApiUrl());
|
|
4258
4326
|
} catch (err) {
|
|
4259
4327
|
warn(`Login failed: ${err.message}`);
|
|
4260
4328
|
return false;
|
|
4261
4329
|
}
|
|
4262
4330
|
return isLoggedIn();
|
|
4263
4331
|
}
|
|
4332
|
+
async function loginWithProvidedToken(flagToken) {
|
|
4333
|
+
const token = flagToken ?? process.env.HIVEMIND_TOKEN;
|
|
4334
|
+
if (!token)
|
|
4335
|
+
return false;
|
|
4336
|
+
try {
|
|
4337
|
+
await saveCredentialsFromToken(token, resolveApiUrl(), { skipTokenMint: true });
|
|
4338
|
+
const source = flagToken ? "--token flag" : "HIVEMIND_TOKEN";
|
|
4339
|
+
log(`Signed in via ${source}.`);
|
|
4340
|
+
return true;
|
|
4341
|
+
} catch (err) {
|
|
4342
|
+
warn(`Token authentication failed: ${err.message}`);
|
|
4343
|
+
return false;
|
|
4344
|
+
}
|
|
4345
|
+
}
|
|
4264
4346
|
async function maybeShowOrgChoice() {
|
|
4265
4347
|
const creds = loadCredentials();
|
|
4266
4348
|
if (!creds)
|
|
@@ -4976,7 +5058,6 @@ var DeeplakeApi = class {
|
|
|
4976
5058
|
};
|
|
4977
5059
|
|
|
4978
5060
|
// dist/src/commands/session-prune.js
|
|
4979
|
-
import { createInterface } from "node:readline";
|
|
4980
5061
|
function parseArgs(argv) {
|
|
4981
5062
|
let before;
|
|
4982
5063
|
let sessionId;
|
|
@@ -4996,15 +5077,6 @@ function parseArgs(argv) {
|
|
|
4996
5077
|
}
|
|
4997
5078
|
return { before, sessionId, all, yes };
|
|
4998
5079
|
}
|
|
4999
|
-
function confirm(message) {
|
|
5000
|
-
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
5001
|
-
return new Promise((resolve2) => {
|
|
5002
|
-
rl.question(`${message} [y/N] `, (answer) => {
|
|
5003
|
-
rl.close();
|
|
5004
|
-
resolve2(answer.trim().toLowerCase() === "y");
|
|
5005
|
-
});
|
|
5006
|
-
});
|
|
5007
|
-
}
|
|
5008
5080
|
function extractSessionId(path) {
|
|
5009
5081
|
const m = path.match(/\/sessions\/[^/]+\/[^/]+_([^.]+)\.jsonl$/);
|
|
5010
5082
|
return m ? m[1] : path.split("/").pop()?.replace(/\.jsonl$/, "") ?? path;
|
|
@@ -5100,7 +5172,7 @@ To delete, use: --all, --before <date>, or --session-id <id>`);
|
|
|
5100
5172
|
}
|
|
5101
5173
|
console.log();
|
|
5102
5174
|
if (!yes) {
|
|
5103
|
-
const ok = await confirm("Proceed with deletion?");
|
|
5175
|
+
const ok = await confirm("Proceed with deletion?", false);
|
|
5104
5176
|
if (!ok) {
|
|
5105
5177
|
console.log("Aborted.");
|
|
5106
5178
|
return;
|
|
@@ -7639,9 +7711,13 @@ var USAGE = `
|
|
|
7639
7711
|
hivemind \u2014 one brain for every agent on your team
|
|
7640
7712
|
|
|
7641
7713
|
Usage:
|
|
7642
|
-
hivemind install [--only <platforms>] [--skip-auth]
|
|
7714
|
+
hivemind install [--only <platforms>] [--skip-auth] [--token <value>]
|
|
7643
7715
|
Auto-detect assistants on this machine and install hivemind into each.
|
|
7644
7716
|
--only takes a comma-separated list: ${allPlatformIds().join(",")}
|
|
7717
|
+
--token, or env HIVEMIND_TOKEN, signs in non-interactively (useful
|
|
7718
|
+
for CI / scripted installs). Without it, a TTY install shows a
|
|
7719
|
+
consent prompt; a headless install skips auth and prints a hint
|
|
7720
|
+
for 'hivemind login'.
|
|
7645
7721
|
|
|
7646
7722
|
hivemind uninstall [--only <platforms>]
|
|
7647
7723
|
Auto-detect installed assistants and remove hivemind from each.
|
|
@@ -7730,6 +7806,78 @@ function parseOnly(args) {
|
|
|
7730
7806
|
function hasFlag(args, flag) {
|
|
7731
7807
|
return args.includes(flag);
|
|
7732
7808
|
}
|
|
7809
|
+
function parseToken(args) {
|
|
7810
|
+
const idx = args.findIndex((a) => a === "--token" || a.startsWith("--token="));
|
|
7811
|
+
if (idx === -1)
|
|
7812
|
+
return void 0;
|
|
7813
|
+
const raw = args[idx].includes("=") ? args[idx].split("=", 2)[1] : args[idx + 1];
|
|
7814
|
+
return raw && raw.length > 0 ? raw : void 0;
|
|
7815
|
+
}
|
|
7816
|
+
function hasEnvToken() {
|
|
7817
|
+
return Boolean(process.env.HIVEMIND_TOKEN);
|
|
7818
|
+
}
|
|
7819
|
+
async function runAuthGate(args) {
|
|
7820
|
+
const flagToken = parseToken(args);
|
|
7821
|
+
const isTTY = Boolean(process.stdin.isTTY);
|
|
7822
|
+
if (flagToken || hasEnvToken()) {
|
|
7823
|
+
const ok = await loginWithProvidedToken(flagToken);
|
|
7824
|
+
if (ok)
|
|
7825
|
+
return;
|
|
7826
|
+
}
|
|
7827
|
+
if (!isTTY) {
|
|
7828
|
+
log("");
|
|
7829
|
+
log("No TTY detected \u2014 continuing without sign-in.");
|
|
7830
|
+
log("To sign in:");
|
|
7831
|
+
log(" 1) Visit https://app.deeplake.ai/api-keys to create an API key");
|
|
7832
|
+
log(" 2) Rerun: HIVEMIND_TOKEN=<key> hivemind install");
|
|
7833
|
+
log("Or run `hivemind login` after install.");
|
|
7834
|
+
return;
|
|
7835
|
+
}
|
|
7836
|
+
log("");
|
|
7837
|
+
log("\u{1F41D} One more step to unlock Hivemind");
|
|
7838
|
+
log("");
|
|
7839
|
+
log("To enable shared memory and auto-learning across your agents,");
|
|
7840
|
+
log("we need to sign you in. Your traces will be securely stored in");
|
|
7841
|
+
log("your private Hivemind, so all your agents can recall them.");
|
|
7842
|
+
log("");
|
|
7843
|
+
log("You can later connect your own cloud storage like S3/GCS/Azure Blob.");
|
|
7844
|
+
log("");
|
|
7845
|
+
const yes = await confirm("Sign in now?", true);
|
|
7846
|
+
let signedIn = false;
|
|
7847
|
+
if (yes) {
|
|
7848
|
+
signedIn = await ensureLoggedIn();
|
|
7849
|
+
if (!signedIn) {
|
|
7850
|
+
warn("Login did not complete.");
|
|
7851
|
+
}
|
|
7852
|
+
}
|
|
7853
|
+
if (!signedIn) {
|
|
7854
|
+
log("");
|
|
7855
|
+
log("Alternatively, sign in at https://app.deeplake.ai/api-keys, create");
|
|
7856
|
+
log("an API key, and paste it here. Press Enter to skip and continue");
|
|
7857
|
+
log("installing without sign-in (you can run `hivemind login` later).");
|
|
7858
|
+
log("");
|
|
7859
|
+
const MAX_PASTE_ATTEMPTS = 3;
|
|
7860
|
+
for (let attempt = 1; attempt <= MAX_PASTE_ATTEMPTS; attempt++) {
|
|
7861
|
+
const pasted = await promptLine("API key: ");
|
|
7862
|
+
if (!pasted)
|
|
7863
|
+
break;
|
|
7864
|
+
signedIn = await loginWithProvidedToken(pasted);
|
|
7865
|
+
if (signedIn)
|
|
7866
|
+
break;
|
|
7867
|
+
const remaining = MAX_PASTE_ATTEMPTS - attempt;
|
|
7868
|
+
if (remaining > 0) {
|
|
7869
|
+
log("");
|
|
7870
|
+
log(`That key wasn't accepted (likely invalid or revoked). Try again (${remaining} attempt${remaining === 1 ? "" : "s"} left) or press Enter to skip.`);
|
|
7871
|
+
log("");
|
|
7872
|
+
}
|
|
7873
|
+
}
|
|
7874
|
+
if (!signedIn) {
|
|
7875
|
+
log("");
|
|
7876
|
+
log("Continuing install without sign-in. Run `hivemind login` later, or");
|
|
7877
|
+
log("rerun with `HIVEMIND_TOKEN=<key> hivemind install`.");
|
|
7878
|
+
}
|
|
7879
|
+
}
|
|
7880
|
+
}
|
|
7733
7881
|
async function runInstallAll(args) {
|
|
7734
7882
|
const only = parseOnly(args);
|
|
7735
7883
|
const skipAuth = hasFlag(args, "--skip-auth");
|
|
@@ -7744,11 +7892,7 @@ async function runInstallAll(args) {
|
|
|
7744
7892
|
log(`Installing hivemind ${getVersion()} for: ${targets.join(", ")}`);
|
|
7745
7893
|
log("");
|
|
7746
7894
|
if (!skipAuth && !isLoggedIn()) {
|
|
7747
|
-
|
|
7748
|
-
if (!ok) {
|
|
7749
|
-
warn("Skipping install because login did not complete.");
|
|
7750
|
-
process.exit(1);
|
|
7751
|
-
}
|
|
7895
|
+
await runAuthGate(args);
|
|
7752
7896
|
}
|
|
7753
7897
|
for (const id of targets)
|
|
7754
7898
|
runSingleInstall(id);
|
|
@@ -96,6 +96,19 @@ function deleteCredentials() {
|
|
|
96
96
|
|
|
97
97
|
// dist/src/commands/auth.js
|
|
98
98
|
var DEFAULT_API_URL = "https://api.deeplake.ai";
|
|
99
|
+
function decodeJwtPayload(token) {
|
|
100
|
+
try {
|
|
101
|
+
const parts = token.split(".");
|
|
102
|
+
if (parts.length !== 3)
|
|
103
|
+
return null;
|
|
104
|
+
let payload = parts[1].replace(/-/g, "+").replace(/_/g, "/");
|
|
105
|
+
while (payload.length % 4)
|
|
106
|
+
payload += "=";
|
|
107
|
+
return JSON.parse(Buffer.from(payload, "base64").toString("utf8"));
|
|
108
|
+
} catch {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
99
112
|
async function apiGet(path, token, apiUrl, orgId) {
|
|
100
113
|
const headers = {
|
|
101
114
|
Authorization: `Bearer ${token}`,
|
|
@@ -226,17 +239,32 @@ async function listMembers(token, orgId, apiUrl = DEFAULT_API_URL) {
|
|
|
226
239
|
async function removeMember(userId, token, orgId, apiUrl = DEFAULT_API_URL) {
|
|
227
240
|
await apiDelete(`/organizations/${orgId}/members/${userId}`, token, apiUrl, orgId);
|
|
228
241
|
}
|
|
229
|
-
async function
|
|
230
|
-
const
|
|
231
|
-
const user = await apiGet("/me", authToken, apiUrl);
|
|
242
|
+
async function saveCredentialsFromToken(token, apiUrl, opts = {}) {
|
|
243
|
+
const user = await apiGet("/me", token, apiUrl);
|
|
232
244
|
const userName = user.name || (user.email ? user.email.split("@")[0] : "unknown");
|
|
233
245
|
process.stderr.write(`
|
|
234
246
|
Logged in as: ${userName}
|
|
235
247
|
`);
|
|
236
|
-
const orgs = await listOrgs(
|
|
248
|
+
const orgs = await listOrgs(token, apiUrl);
|
|
249
|
+
if (orgs.length === 0)
|
|
250
|
+
throw new Error("No organizations found for this account.");
|
|
251
|
+
const envOrgId = process.env.HIVEMIND_ORG_ID;
|
|
252
|
+
let preferredOrgId = envOrgId;
|
|
253
|
+
if (!preferredOrgId && opts.skipTokenMint) {
|
|
254
|
+
const claims = decodeJwtPayload(token);
|
|
255
|
+
const claimOrg = claims && typeof claims.org_id === "string" ? claims.org_id : void 0;
|
|
256
|
+
if (claimOrg)
|
|
257
|
+
preferredOrgId = claimOrg;
|
|
258
|
+
}
|
|
237
259
|
let orgId;
|
|
238
260
|
let orgName;
|
|
239
|
-
|
|
261
|
+
const matched = preferredOrgId ? orgs.find((o) => o.id === preferredOrgId) : void 0;
|
|
262
|
+
if (matched) {
|
|
263
|
+
orgId = matched.id;
|
|
264
|
+
orgName = matched.name;
|
|
265
|
+
process.stderr.write(`Organization: ${orgName}
|
|
266
|
+
`);
|
|
267
|
+
} else if (orgs.length === 1) {
|
|
240
268
|
orgId = orgs[0].id;
|
|
241
269
|
orgName = orgs[0].name;
|
|
242
270
|
process.stderr.write(`Organization: ${orgName}
|
|
@@ -247,17 +275,26 @@ Logged in as: ${userName}
|
|
|
247
275
|
`));
|
|
248
276
|
orgId = orgs[0].id;
|
|
249
277
|
orgName = orgs[0].name;
|
|
250
|
-
|
|
278
|
+
if (opts.skipTokenMint) {
|
|
279
|
+
process.stderr.write(`
|
|
280
|
+
Using: ${orgName} (set HIVEMIND_ORG_ID to override)
|
|
281
|
+
`);
|
|
282
|
+
} else {
|
|
283
|
+
process.stderr.write(`
|
|
251
284
|
Using: ${orgName}
|
|
252
285
|
`);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
let apiToken = token;
|
|
289
|
+
if (!opts.skipTokenMint) {
|
|
290
|
+
const tokenName = `deeplake-plugin-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}`;
|
|
291
|
+
const tokenData = await apiPost("/users/me/tokens", {
|
|
292
|
+
name: tokenName,
|
|
293
|
+
duration: 365 * 24 * 3600,
|
|
294
|
+
organization_id: orgId
|
|
295
|
+
}, token, apiUrl);
|
|
296
|
+
apiToken = tokenData.token.token;
|
|
253
297
|
}
|
|
254
|
-
const tokenName = `deeplake-plugin-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}`;
|
|
255
|
-
const tokenData = await apiPost("/users/me/tokens", {
|
|
256
|
-
name: tokenName,
|
|
257
|
-
duration: 365 * 24 * 3600,
|
|
258
|
-
organization_id: orgId
|
|
259
|
-
}, authToken, apiUrl);
|
|
260
|
-
const apiToken = tokenData.token.token;
|
|
261
298
|
const creds = {
|
|
262
299
|
token: apiToken,
|
|
263
300
|
orgId,
|
|
@@ -270,6 +307,10 @@ Using: ${orgName}
|
|
|
270
307
|
saveCredentials(creds);
|
|
271
308
|
return creds;
|
|
272
309
|
}
|
|
310
|
+
async function login(apiUrl = DEFAULT_API_URL) {
|
|
311
|
+
const { token: authToken } = await deviceFlowLogin(apiUrl);
|
|
312
|
+
return saveCredentialsFromToken(authToken, apiUrl, { skipTokenMint: false });
|
|
313
|
+
}
|
|
273
314
|
|
|
274
315
|
// dist/src/config.js
|
|
275
316
|
import { readFileSync as readFileSync2, existsSync } from "node:fs";
|
|
@@ -969,8 +1010,40 @@ var DeeplakeApi = class {
|
|
|
969
1010
|
}
|
|
970
1011
|
};
|
|
971
1012
|
|
|
972
|
-
// dist/src/
|
|
1013
|
+
// dist/src/cli/util.js
|
|
1014
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync4, cpSync, symlinkSync, unlinkSync as unlinkSync3, lstatSync } from "node:fs";
|
|
1015
|
+
import { join as join6, dirname } from "node:path";
|
|
1016
|
+
import { homedir as homedir5 } from "node:os";
|
|
1017
|
+
import { fileURLToPath } from "node:url";
|
|
973
1018
|
import { createInterface } from "node:readline";
|
|
1019
|
+
var HOME = homedir5();
|
|
1020
|
+
var PLATFORM_MARKERS = [
|
|
1021
|
+
{ id: "claude", markerDir: join6(HOME, ".claude") },
|
|
1022
|
+
{ id: "codex", markerDir: join6(HOME, ".codex") },
|
|
1023
|
+
{ id: "claw", markerDir: join6(HOME, ".openclaw") },
|
|
1024
|
+
{ id: "cursor", markerDir: join6(HOME, ".cursor") },
|
|
1025
|
+
{ id: "hermes", markerDir: join6(HOME, ".hermes") },
|
|
1026
|
+
// pi (badlogic/pi-mono coding-agent) — config at ~/.pi/agent/. pi exposes
|
|
1027
|
+
// a rich extension event API (session_start / input / tool_call /
|
|
1028
|
+
// tool_result / message_end / session_shutdown / etc.) — Tier 1 capable.
|
|
1029
|
+
{ id: "pi", markerDir: join6(HOME, ".pi") }
|
|
1030
|
+
];
|
|
1031
|
+
function confirm(message, defaultYes = true) {
|
|
1032
|
+
const hint = defaultYes ? "[Y/n]" : "[y/N]";
|
|
1033
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
1034
|
+
return new Promise((resolve2) => {
|
|
1035
|
+
rl.question(`${message} ${hint} `, (answer) => {
|
|
1036
|
+
rl.close();
|
|
1037
|
+
const a = answer.trim().toLowerCase();
|
|
1038
|
+
if (a === "")
|
|
1039
|
+
resolve2(defaultYes);
|
|
1040
|
+
else
|
|
1041
|
+
resolve2(a === "y" || a === "yes");
|
|
1042
|
+
});
|
|
1043
|
+
});
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
// dist/src/commands/session-prune.js
|
|
974
1047
|
function parseArgs(argv) {
|
|
975
1048
|
let before;
|
|
976
1049
|
let sessionId;
|
|
@@ -990,15 +1063,6 @@ function parseArgs(argv) {
|
|
|
990
1063
|
}
|
|
991
1064
|
return { before, sessionId, all, yes };
|
|
992
1065
|
}
|
|
993
|
-
function confirm(message) {
|
|
994
|
-
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
995
|
-
return new Promise((resolve2) => {
|
|
996
|
-
rl.question(`${message} [y/N] `, (answer) => {
|
|
997
|
-
rl.close();
|
|
998
|
-
resolve2(answer.trim().toLowerCase() === "y");
|
|
999
|
-
});
|
|
1000
|
-
});
|
|
1001
|
-
}
|
|
1002
1066
|
function extractSessionId(path) {
|
|
1003
1067
|
const m = path.match(/\/sessions\/[^/]+\/[^/]+_([^.]+)\.jsonl$/);
|
|
1004
1068
|
return m ? m[1] : path.split("/").pop()?.replace(/\.jsonl$/, "") ?? path;
|
|
@@ -1094,7 +1158,7 @@ To delete, use: --all, --before <date>, or --session-id <id>`);
|
|
|
1094
1158
|
}
|
|
1095
1159
|
console.log();
|
|
1096
1160
|
if (!yes) {
|
|
1097
|
-
const ok = await confirm("Proceed with deletion?");
|
|
1161
|
+
const ok = await confirm("Proceed with deletion?", false);
|
|
1098
1162
|
if (!ok) {
|
|
1099
1163
|
console.log("Aborted.");
|
|
1100
1164
|
return;
|
|
@@ -96,6 +96,19 @@ function deleteCredentials() {
|
|
|
96
96
|
|
|
97
97
|
// dist/src/commands/auth.js
|
|
98
98
|
var DEFAULT_API_URL = "https://api.deeplake.ai";
|
|
99
|
+
function decodeJwtPayload(token) {
|
|
100
|
+
try {
|
|
101
|
+
const parts = token.split(".");
|
|
102
|
+
if (parts.length !== 3)
|
|
103
|
+
return null;
|
|
104
|
+
let payload = parts[1].replace(/-/g, "+").replace(/_/g, "/");
|
|
105
|
+
while (payload.length % 4)
|
|
106
|
+
payload += "=";
|
|
107
|
+
return JSON.parse(Buffer.from(payload, "base64").toString("utf8"));
|
|
108
|
+
} catch {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
99
112
|
async function apiGet(path, token, apiUrl, orgId) {
|
|
100
113
|
const headers = {
|
|
101
114
|
Authorization: `Bearer ${token}`,
|
|
@@ -226,17 +239,32 @@ async function listMembers(token, orgId, apiUrl = DEFAULT_API_URL) {
|
|
|
226
239
|
async function removeMember(userId, token, orgId, apiUrl = DEFAULT_API_URL) {
|
|
227
240
|
await apiDelete(`/organizations/${orgId}/members/${userId}`, token, apiUrl, orgId);
|
|
228
241
|
}
|
|
229
|
-
async function
|
|
230
|
-
const
|
|
231
|
-
const user = await apiGet("/me", authToken, apiUrl);
|
|
242
|
+
async function saveCredentialsFromToken(token, apiUrl, opts = {}) {
|
|
243
|
+
const user = await apiGet("/me", token, apiUrl);
|
|
232
244
|
const userName = user.name || (user.email ? user.email.split("@")[0] : "unknown");
|
|
233
245
|
process.stderr.write(`
|
|
234
246
|
Logged in as: ${userName}
|
|
235
247
|
`);
|
|
236
|
-
const orgs = await listOrgs(
|
|
248
|
+
const orgs = await listOrgs(token, apiUrl);
|
|
249
|
+
if (orgs.length === 0)
|
|
250
|
+
throw new Error("No organizations found for this account.");
|
|
251
|
+
const envOrgId = process.env.HIVEMIND_ORG_ID;
|
|
252
|
+
let preferredOrgId = envOrgId;
|
|
253
|
+
if (!preferredOrgId && opts.skipTokenMint) {
|
|
254
|
+
const claims = decodeJwtPayload(token);
|
|
255
|
+
const claimOrg = claims && typeof claims.org_id === "string" ? claims.org_id : void 0;
|
|
256
|
+
if (claimOrg)
|
|
257
|
+
preferredOrgId = claimOrg;
|
|
258
|
+
}
|
|
237
259
|
let orgId;
|
|
238
260
|
let orgName;
|
|
239
|
-
|
|
261
|
+
const matched = preferredOrgId ? orgs.find((o) => o.id === preferredOrgId) : void 0;
|
|
262
|
+
if (matched) {
|
|
263
|
+
orgId = matched.id;
|
|
264
|
+
orgName = matched.name;
|
|
265
|
+
process.stderr.write(`Organization: ${orgName}
|
|
266
|
+
`);
|
|
267
|
+
} else if (orgs.length === 1) {
|
|
240
268
|
orgId = orgs[0].id;
|
|
241
269
|
orgName = orgs[0].name;
|
|
242
270
|
process.stderr.write(`Organization: ${orgName}
|
|
@@ -247,17 +275,26 @@ Logged in as: ${userName}
|
|
|
247
275
|
`));
|
|
248
276
|
orgId = orgs[0].id;
|
|
249
277
|
orgName = orgs[0].name;
|
|
250
|
-
|
|
278
|
+
if (opts.skipTokenMint) {
|
|
279
|
+
process.stderr.write(`
|
|
280
|
+
Using: ${orgName} (set HIVEMIND_ORG_ID to override)
|
|
281
|
+
`);
|
|
282
|
+
} else {
|
|
283
|
+
process.stderr.write(`
|
|
251
284
|
Using: ${orgName}
|
|
252
285
|
`);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
let apiToken = token;
|
|
289
|
+
if (!opts.skipTokenMint) {
|
|
290
|
+
const tokenName = `deeplake-plugin-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}`;
|
|
291
|
+
const tokenData = await apiPost("/users/me/tokens", {
|
|
292
|
+
name: tokenName,
|
|
293
|
+
duration: 365 * 24 * 3600,
|
|
294
|
+
organization_id: orgId
|
|
295
|
+
}, token, apiUrl);
|
|
296
|
+
apiToken = tokenData.token.token;
|
|
253
297
|
}
|
|
254
|
-
const tokenName = `deeplake-plugin-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}`;
|
|
255
|
-
const tokenData = await apiPost("/users/me/tokens", {
|
|
256
|
-
name: tokenName,
|
|
257
|
-
duration: 365 * 24 * 3600,
|
|
258
|
-
organization_id: orgId
|
|
259
|
-
}, authToken, apiUrl);
|
|
260
|
-
const apiToken = tokenData.token.token;
|
|
261
298
|
const creds = {
|
|
262
299
|
token: apiToken,
|
|
263
300
|
orgId,
|
|
@@ -270,6 +307,10 @@ Using: ${orgName}
|
|
|
270
307
|
saveCredentials(creds);
|
|
271
308
|
return creds;
|
|
272
309
|
}
|
|
310
|
+
async function login(apiUrl = DEFAULT_API_URL) {
|
|
311
|
+
const { token: authToken } = await deviceFlowLogin(apiUrl);
|
|
312
|
+
return saveCredentialsFromToken(authToken, apiUrl, { skipTokenMint: false });
|
|
313
|
+
}
|
|
273
314
|
|
|
274
315
|
// dist/src/config.js
|
|
275
316
|
import { readFileSync as readFileSync2, existsSync } from "node:fs";
|
|
@@ -969,8 +1010,40 @@ var DeeplakeApi = class {
|
|
|
969
1010
|
}
|
|
970
1011
|
};
|
|
971
1012
|
|
|
972
|
-
// dist/src/
|
|
1013
|
+
// dist/src/cli/util.js
|
|
1014
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync4, cpSync, symlinkSync, unlinkSync as unlinkSync3, lstatSync } from "node:fs";
|
|
1015
|
+
import { join as join6, dirname } from "node:path";
|
|
1016
|
+
import { homedir as homedir5 } from "node:os";
|
|
1017
|
+
import { fileURLToPath } from "node:url";
|
|
973
1018
|
import { createInterface } from "node:readline";
|
|
1019
|
+
var HOME = homedir5();
|
|
1020
|
+
var PLATFORM_MARKERS = [
|
|
1021
|
+
{ id: "claude", markerDir: join6(HOME, ".claude") },
|
|
1022
|
+
{ id: "codex", markerDir: join6(HOME, ".codex") },
|
|
1023
|
+
{ id: "claw", markerDir: join6(HOME, ".openclaw") },
|
|
1024
|
+
{ id: "cursor", markerDir: join6(HOME, ".cursor") },
|
|
1025
|
+
{ id: "hermes", markerDir: join6(HOME, ".hermes") },
|
|
1026
|
+
// pi (badlogic/pi-mono coding-agent) — config at ~/.pi/agent/. pi exposes
|
|
1027
|
+
// a rich extension event API (session_start / input / tool_call /
|
|
1028
|
+
// tool_result / message_end / session_shutdown / etc.) — Tier 1 capable.
|
|
1029
|
+
{ id: "pi", markerDir: join6(HOME, ".pi") }
|
|
1030
|
+
];
|
|
1031
|
+
function confirm(message, defaultYes = true) {
|
|
1032
|
+
const hint = defaultYes ? "[Y/n]" : "[y/N]";
|
|
1033
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
1034
|
+
return new Promise((resolve2) => {
|
|
1035
|
+
rl.question(`${message} ${hint} `, (answer) => {
|
|
1036
|
+
rl.close();
|
|
1037
|
+
const a = answer.trim().toLowerCase();
|
|
1038
|
+
if (a === "")
|
|
1039
|
+
resolve2(defaultYes);
|
|
1040
|
+
else
|
|
1041
|
+
resolve2(a === "y" || a === "yes");
|
|
1042
|
+
});
|
|
1043
|
+
});
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
// dist/src/commands/session-prune.js
|
|
974
1047
|
function parseArgs(argv) {
|
|
975
1048
|
let before;
|
|
976
1049
|
let sessionId;
|
|
@@ -990,15 +1063,6 @@ function parseArgs(argv) {
|
|
|
990
1063
|
}
|
|
991
1064
|
return { before, sessionId, all, yes };
|
|
992
1065
|
}
|
|
993
|
-
function confirm(message) {
|
|
994
|
-
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
995
|
-
return new Promise((resolve2) => {
|
|
996
|
-
rl.question(`${message} [y/N] `, (answer) => {
|
|
997
|
-
rl.close();
|
|
998
|
-
resolve2(answer.trim().toLowerCase() === "y");
|
|
999
|
-
});
|
|
1000
|
-
});
|
|
1001
|
-
}
|
|
1002
1066
|
function extractSessionId(path) {
|
|
1003
1067
|
const m = path.match(/\/sessions\/[^/]+\/[^/]+_([^.]+)\.jsonl$/);
|
|
1004
1068
|
return m ? m[1] : path.split("/").pop()?.replace(/\.jsonl$/, "") ?? path;
|
|
@@ -1094,7 +1158,7 @@ To delete, use: --all, --before <date>, or --session-id <id>`);
|
|
|
1094
1158
|
}
|
|
1095
1159
|
console.log();
|
|
1096
1160
|
if (!yes) {
|
|
1097
|
-
const ok = await confirm("Proceed with deletion?");
|
|
1161
|
+
const ok = await confirm("Proceed with deletion?", false);
|
|
1098
1162
|
if (!ok) {
|
|
1099
1163
|
console.log("Aborted.");
|
|
1100
1164
|
return;
|
|
@@ -96,6 +96,19 @@ function deleteCredentials() {
|
|
|
96
96
|
|
|
97
97
|
// dist/src/commands/auth.js
|
|
98
98
|
var DEFAULT_API_URL = "https://api.deeplake.ai";
|
|
99
|
+
function decodeJwtPayload(token) {
|
|
100
|
+
try {
|
|
101
|
+
const parts = token.split(".");
|
|
102
|
+
if (parts.length !== 3)
|
|
103
|
+
return null;
|
|
104
|
+
let payload = parts[1].replace(/-/g, "+").replace(/_/g, "/");
|
|
105
|
+
while (payload.length % 4)
|
|
106
|
+
payload += "=";
|
|
107
|
+
return JSON.parse(Buffer.from(payload, "base64").toString("utf8"));
|
|
108
|
+
} catch {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
99
112
|
async function apiGet(path, token, apiUrl, orgId) {
|
|
100
113
|
const headers = {
|
|
101
114
|
Authorization: `Bearer ${token}`,
|
|
@@ -226,17 +239,32 @@ async function listMembers(token, orgId, apiUrl = DEFAULT_API_URL) {
|
|
|
226
239
|
async function removeMember(userId, token, orgId, apiUrl = DEFAULT_API_URL) {
|
|
227
240
|
await apiDelete(`/organizations/${orgId}/members/${userId}`, token, apiUrl, orgId);
|
|
228
241
|
}
|
|
229
|
-
async function
|
|
230
|
-
const
|
|
231
|
-
const user = await apiGet("/me", authToken, apiUrl);
|
|
242
|
+
async function saveCredentialsFromToken(token, apiUrl, opts = {}) {
|
|
243
|
+
const user = await apiGet("/me", token, apiUrl);
|
|
232
244
|
const userName = user.name || (user.email ? user.email.split("@")[0] : "unknown");
|
|
233
245
|
process.stderr.write(`
|
|
234
246
|
Logged in as: ${userName}
|
|
235
247
|
`);
|
|
236
|
-
const orgs = await listOrgs(
|
|
248
|
+
const orgs = await listOrgs(token, apiUrl);
|
|
249
|
+
if (orgs.length === 0)
|
|
250
|
+
throw new Error("No organizations found for this account.");
|
|
251
|
+
const envOrgId = process.env.HIVEMIND_ORG_ID;
|
|
252
|
+
let preferredOrgId = envOrgId;
|
|
253
|
+
if (!preferredOrgId && opts.skipTokenMint) {
|
|
254
|
+
const claims = decodeJwtPayload(token);
|
|
255
|
+
const claimOrg = claims && typeof claims.org_id === "string" ? claims.org_id : void 0;
|
|
256
|
+
if (claimOrg)
|
|
257
|
+
preferredOrgId = claimOrg;
|
|
258
|
+
}
|
|
237
259
|
let orgId;
|
|
238
260
|
let orgName;
|
|
239
|
-
|
|
261
|
+
const matched = preferredOrgId ? orgs.find((o) => o.id === preferredOrgId) : void 0;
|
|
262
|
+
if (matched) {
|
|
263
|
+
orgId = matched.id;
|
|
264
|
+
orgName = matched.name;
|
|
265
|
+
process.stderr.write(`Organization: ${orgName}
|
|
266
|
+
`);
|
|
267
|
+
} else if (orgs.length === 1) {
|
|
240
268
|
orgId = orgs[0].id;
|
|
241
269
|
orgName = orgs[0].name;
|
|
242
270
|
process.stderr.write(`Organization: ${orgName}
|
|
@@ -247,17 +275,26 @@ Logged in as: ${userName}
|
|
|
247
275
|
`));
|
|
248
276
|
orgId = orgs[0].id;
|
|
249
277
|
orgName = orgs[0].name;
|
|
250
|
-
|
|
278
|
+
if (opts.skipTokenMint) {
|
|
279
|
+
process.stderr.write(`
|
|
280
|
+
Using: ${orgName} (set HIVEMIND_ORG_ID to override)
|
|
281
|
+
`);
|
|
282
|
+
} else {
|
|
283
|
+
process.stderr.write(`
|
|
251
284
|
Using: ${orgName}
|
|
252
285
|
`);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
let apiToken = token;
|
|
289
|
+
if (!opts.skipTokenMint) {
|
|
290
|
+
const tokenName = `deeplake-plugin-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}`;
|
|
291
|
+
const tokenData = await apiPost("/users/me/tokens", {
|
|
292
|
+
name: tokenName,
|
|
293
|
+
duration: 365 * 24 * 3600,
|
|
294
|
+
organization_id: orgId
|
|
295
|
+
}, token, apiUrl);
|
|
296
|
+
apiToken = tokenData.token.token;
|
|
253
297
|
}
|
|
254
|
-
const tokenName = `deeplake-plugin-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}`;
|
|
255
|
-
const tokenData = await apiPost("/users/me/tokens", {
|
|
256
|
-
name: tokenName,
|
|
257
|
-
duration: 365 * 24 * 3600,
|
|
258
|
-
organization_id: orgId
|
|
259
|
-
}, authToken, apiUrl);
|
|
260
|
-
const apiToken = tokenData.token.token;
|
|
261
298
|
const creds = {
|
|
262
299
|
token: apiToken,
|
|
263
300
|
orgId,
|
|
@@ -270,6 +307,10 @@ Using: ${orgName}
|
|
|
270
307
|
saveCredentials(creds);
|
|
271
308
|
return creds;
|
|
272
309
|
}
|
|
310
|
+
async function login(apiUrl = DEFAULT_API_URL) {
|
|
311
|
+
const { token: authToken } = await deviceFlowLogin(apiUrl);
|
|
312
|
+
return saveCredentialsFromToken(authToken, apiUrl, { skipTokenMint: false });
|
|
313
|
+
}
|
|
273
314
|
|
|
274
315
|
// dist/src/config.js
|
|
275
316
|
import { readFileSync as readFileSync2, existsSync } from "node:fs";
|
|
@@ -969,8 +1010,40 @@ var DeeplakeApi = class {
|
|
|
969
1010
|
}
|
|
970
1011
|
};
|
|
971
1012
|
|
|
972
|
-
// dist/src/
|
|
1013
|
+
// dist/src/cli/util.js
|
|
1014
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync4, cpSync, symlinkSync, unlinkSync as unlinkSync3, lstatSync } from "node:fs";
|
|
1015
|
+
import { join as join6, dirname } from "node:path";
|
|
1016
|
+
import { homedir as homedir5 } from "node:os";
|
|
1017
|
+
import { fileURLToPath } from "node:url";
|
|
973
1018
|
import { createInterface } from "node:readline";
|
|
1019
|
+
var HOME = homedir5();
|
|
1020
|
+
var PLATFORM_MARKERS = [
|
|
1021
|
+
{ id: "claude", markerDir: join6(HOME, ".claude") },
|
|
1022
|
+
{ id: "codex", markerDir: join6(HOME, ".codex") },
|
|
1023
|
+
{ id: "claw", markerDir: join6(HOME, ".openclaw") },
|
|
1024
|
+
{ id: "cursor", markerDir: join6(HOME, ".cursor") },
|
|
1025
|
+
{ id: "hermes", markerDir: join6(HOME, ".hermes") },
|
|
1026
|
+
// pi (badlogic/pi-mono coding-agent) — config at ~/.pi/agent/. pi exposes
|
|
1027
|
+
// a rich extension event API (session_start / input / tool_call /
|
|
1028
|
+
// tool_result / message_end / session_shutdown / etc.) — Tier 1 capable.
|
|
1029
|
+
{ id: "pi", markerDir: join6(HOME, ".pi") }
|
|
1030
|
+
];
|
|
1031
|
+
function confirm(message, defaultYes = true) {
|
|
1032
|
+
const hint = defaultYes ? "[Y/n]" : "[y/N]";
|
|
1033
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
1034
|
+
return new Promise((resolve2) => {
|
|
1035
|
+
rl.question(`${message} ${hint} `, (answer) => {
|
|
1036
|
+
rl.close();
|
|
1037
|
+
const a = answer.trim().toLowerCase();
|
|
1038
|
+
if (a === "")
|
|
1039
|
+
resolve2(defaultYes);
|
|
1040
|
+
else
|
|
1041
|
+
resolve2(a === "y" || a === "yes");
|
|
1042
|
+
});
|
|
1043
|
+
});
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
// dist/src/commands/session-prune.js
|
|
974
1047
|
function parseArgs(argv) {
|
|
975
1048
|
let before;
|
|
976
1049
|
let sessionId;
|
|
@@ -990,15 +1063,6 @@ function parseArgs(argv) {
|
|
|
990
1063
|
}
|
|
991
1064
|
return { before, sessionId, all, yes };
|
|
992
1065
|
}
|
|
993
|
-
function confirm(message) {
|
|
994
|
-
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
995
|
-
return new Promise((resolve2) => {
|
|
996
|
-
rl.question(`${message} [y/N] `, (answer) => {
|
|
997
|
-
rl.close();
|
|
998
|
-
resolve2(answer.trim().toLowerCase() === "y");
|
|
999
|
-
});
|
|
1000
|
-
});
|
|
1001
|
-
}
|
|
1002
1066
|
function extractSessionId(path) {
|
|
1003
1067
|
const m = path.match(/\/sessions\/[^/]+\/[^/]+_([^.]+)\.jsonl$/);
|
|
1004
1068
|
return m ? m[1] : path.split("/").pop()?.replace(/\.jsonl$/, "") ?? path;
|
|
@@ -1094,7 +1158,7 @@ To delete, use: --all, --before <date>, or --session-id <id>`);
|
|
|
1094
1158
|
}
|
|
1095
1159
|
console.log();
|
|
1096
1160
|
if (!yes) {
|
|
1097
|
-
const ok = await confirm("Proceed with deletion?");
|
|
1161
|
+
const ok = await confirm("Proceed with deletion?", false);
|
|
1098
1162
|
if (!ok) {
|
|
1099
1163
|
console.log("Aborted.");
|
|
1100
1164
|
return;
|
package/mcp/bundle/server.js
CHANGED
|
@@ -24379,6 +24379,7 @@ import { existsSync as existsSync3, mkdirSync as mkdirSync4, readFileSync as rea
|
|
|
24379
24379
|
import { join as join6, dirname } from "node:path";
|
|
24380
24380
|
import { homedir as homedir5 } from "node:os";
|
|
24381
24381
|
import { fileURLToPath } from "node:url";
|
|
24382
|
+
import { createInterface } from "node:readline";
|
|
24382
24383
|
var HOME = homedir5();
|
|
24383
24384
|
function pkgRoot() {
|
|
24384
24385
|
let dir = fileURLToPath(new URL(".", import.meta.url));
|
package/openclaw/dist/index.js
CHANGED
|
@@ -1543,7 +1543,7 @@ function extractLatestVersion(body) {
|
|
|
1543
1543
|
return typeof v === "string" && v.length > 0 ? v : null;
|
|
1544
1544
|
}
|
|
1545
1545
|
function getInstalledVersion() {
|
|
1546
|
-
return "0.7.
|
|
1546
|
+
return "0.7.38".length > 0 ? "0.7.38" : null;
|
|
1547
1547
|
}
|
|
1548
1548
|
function isNewer(latest, current) {
|
|
1549
1549
|
const parse = (v) => v.replace(/-.*$/, "").split(".").map(Number);
|
package/openclaw/package.json
CHANGED