harborloop 0.3.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/checksums.json +12 -0
- package/bin/harbor.mjs +188 -0
- package/package.json +14 -30
- package/dist/api.d.ts +0 -109
- package/dist/api.js +0 -409
- package/dist/auth/login.d.ts +0 -14
- package/dist/auth/login.js +0 -158
- package/dist/auth/loopback.d.ts +0 -11
- package/dist/auth/loopback.js +0 -87
- package/dist/auth/pkce.d.ts +0 -7
- package/dist/auth/pkce.js +0 -14
- package/dist/auth/store.d.ts +0 -26
- package/dist/auth/store.js +0 -107
- package/dist/cli-release.d.ts +0 -31
- package/dist/cli-release.js +0 -102
- package/dist/commands/bind.d.ts +0 -23
- package/dist/commands/bind.js +0 -86
- package/dist/commands/context.d.ts +0 -12
- package/dist/commands/context.js +0 -80
- package/dist/commands/daemon.d.ts +0 -39
- package/dist/commands/daemon.js +0 -140
- package/dist/commands/doctor.d.ts +0 -16
- package/dist/commands/doctor.js +0 -937
- package/dist/commands/init.d.ts +0 -36
- package/dist/commands/init.js +0 -192
- package/dist/commands/status.d.ts +0 -5
- package/dist/commands/status.js +0 -164
- package/dist/commands/sync.d.ts +0 -40
- package/dist/commands/sync.js +0 -242
- package/dist/commands/toggle.d.ts +0 -16
- package/dist/commands/toggle.js +0 -69
- package/dist/commands/unbind.d.ts +0 -14
- package/dist/commands/unbind.js +0 -60
- package/dist/commands/workspaces.d.ts +0 -18
- package/dist/commands/workspaces.js +0 -41
- package/dist/context-budget.d.ts +0 -40
- package/dist/context-budget.js +0 -259
- package/dist/daemon/install.d.ts +0 -50
- package/dist/daemon/install.js +0 -192
- package/dist/daemon/loop.d.ts +0 -15
- package/dist/daemon/loop.js +0 -84
- package/dist/daemon/state.d.ts +0 -79
- package/dist/daemon/state.js +0 -213
- package/dist/daemon/tick.d.ts +0 -37
- package/dist/daemon/tick.js +0 -231
- package/dist/documents/apply.d.ts +0 -21
- package/dist/documents/apply.js +0 -58
- package/dist/documents/bundle.d.ts +0 -41
- package/dist/documents/bundle.js +0 -43
- package/dist/documents/inspect.d.ts +0 -12
- package/dist/documents/inspect.js +0 -33
- package/dist/documents/manifest.d.ts +0 -14
- package/dist/documents/manifest.js +0 -52
- package/dist/documents/pointer.d.ts +0 -32
- package/dist/documents/pointer.js +0 -135
- package/dist/documents/write.d.ts +0 -57
- package/dist/documents/write.js +0 -211
- package/dist/endpoints.d.ts +0 -7
- package/dist/endpoints.js +0 -15
- package/dist/env-bundle.d.ts +0 -25
- package/dist/env-bundle.js +0 -33
- package/dist/env-scan.d.ts +0 -27
- package/dist/env-scan.js +0 -41
- package/dist/env-sync.d.ts +0 -31
- package/dist/env-sync.js +0 -37
- package/dist/index.d.ts +0 -11
- package/dist/index.js +0 -282
- package/dist/install-hooks.d.ts +0 -11
- package/dist/install-hooks.js +0 -64
- package/dist/lock.d.ts +0 -31
- package/dist/lock.js +0 -192
- package/dist/machine.d.ts +0 -13
- package/dist/machine.js +0 -53
- package/dist/memories.d.ts +0 -31
- package/dist/memories.js +0 -74
- package/dist/origin.d.ts +0 -4
- package/dist/origin.js +0 -59
- package/dist/paths.d.ts +0 -12
- package/dist/paths.js +0 -45
- package/dist/providers/claude.d.ts +0 -65
- package/dist/providers/claude.js +0 -412
- package/dist/providers/codex-trust.d.ts +0 -36
- package/dist/providers/codex-trust.js +0 -141
- package/dist/providers/codex.d.ts +0 -46
- package/dist/providers/codex.js +0 -520
- package/dist/providers/cursor.d.ts +0 -45
- package/dist/providers/cursor.js +0 -344
- package/dist/providers/detect.d.ts +0 -16
- package/dist/providers/detect.js +0 -70
- package/dist/providers/hook-coverage.d.ts +0 -5
- package/dist/providers/hook-coverage.js +0 -47
- package/dist/providers/hook-entry.d.ts +0 -1
- package/dist/providers/hook-entry.js +0 -8
- package/dist/providers/surfaces.d.ts +0 -19
- package/dist/providers/surfaces.js +0 -91
- package/dist/reclaim.d.ts +0 -17
- package/dist/reclaim.js +0 -33
- package/dist/render.d.ts +0 -17
- package/dist/render.js +0 -61
- package/dist/repo-sync.d.ts +0 -27
- package/dist/repo-sync.js +0 -34
- package/dist/repos.d.ts +0 -11
- package/dist/repos.js +0 -82
- package/dist/skills.d.ts +0 -84
- package/dist/skills.js +0 -383
- package/dist/slugify.d.ts +0 -1
- package/dist/slugify.js +0 -8
- package/dist/state.d.ts +0 -23
- package/dist/state.js +0 -161
- package/dist/sync-report.d.ts +0 -59
- package/dist/sync-report.js +0 -87
- package/hooks/_recall.mjs +0 -288
- package/hooks/_receipt.mjs +0 -47
- package/hooks/_shared.mjs +0 -1610
- package/hooks/_upgrade.mjs +0 -51
- package/hooks/session-capture.mjs +0 -60
- package/hooks/session-compact.mjs +0 -19
- package/hooks/session-context.mjs +0 -258
- package/hooks/session-report.mjs +0 -42
- package/hooks/session-toolcontext.mjs +0 -183
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "0.4.1",
|
|
3
|
+
"algorithm": "sha256",
|
|
4
|
+
"binaries": {
|
|
5
|
+
"@gethrbr/harborloop-darwin-arm64": "d72a976949c98fb1410dd2f6bec31f9cebebf30ff3f73b056b3a4012bacedd64",
|
|
6
|
+
"@gethrbr/harborloop-darwin-x64": "e76a70f27d75038ba55c41d5f78d429fd09a82349dc851506fbdc4e0e197f865",
|
|
7
|
+
"@gethrbr/harborloop-linux-x64": "449c5b3ae98dd2d45f3cf541bc3a4a0a6a8b3968b3a383e09e317d0a94c1dec6",
|
|
8
|
+
"@gethrbr/harborloop-linux-arm64": "719cce2ae6d78db23a89c1b700c6258090b40267acefe259cf3590b26195f5ba",
|
|
9
|
+
"@gethrbr/harborloop-linux-x64-musl": "26d7862226f11b897a4604c038859bdbff0e23dde8eeb162ae5ae0635ac32d2d",
|
|
10
|
+
"@gethrbr/harborloop-win32-x64": "c2e0652c69f8332f947936916215d8b0e780e16b1a3b9cccd826a795a6a61a09"
|
|
11
|
+
}
|
|
12
|
+
}
|
package/bin/harbor.mjs
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* The published `harbor` command: find this machine's binary, prove it is ours,
|
|
4
|
+
* and run it.
|
|
5
|
+
*
|
|
6
|
+
* The binary is 60-86 MB per platform, so shipping all six in one tarball would
|
|
7
|
+
* be a 435 MB install to use one of them. Instead each platform is its own
|
|
8
|
+
* package, declared as an OPTIONAL dependency with `os`/`cpu` fields; npm
|
|
9
|
+
* installs exactly the one that matches and skips the rest. This shim is the
|
|
10
|
+
* only JavaScript that ships.
|
|
11
|
+
*
|
|
12
|
+
* The hooks do NOT come through here. `harbor init` hardlinks them straight to
|
|
13
|
+
* the binary, so the per-prompt path pays nothing for this indirection, which
|
|
14
|
+
* matters because it runs on every prompt and every tool call.
|
|
15
|
+
*/
|
|
16
|
+
import { createHash } from 'node:crypto';
|
|
17
|
+
import { spawnSync } from 'node:child_process';
|
|
18
|
+
import { closeSync, openSync, readFileSync, readSync, realpathSync } from 'node:fs';
|
|
19
|
+
import { dirname, join } from 'node:path';
|
|
20
|
+
import { createRequire } from 'node:module';
|
|
21
|
+
import { fileURLToPath } from 'node:url';
|
|
22
|
+
|
|
23
|
+
const require = createRequire(import.meta.url);
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* musl and glibc need different binaries and both report `linux`/`x64`.
|
|
27
|
+
*
|
|
28
|
+
* `process.report` names the glibc it is running against; on Alpine there is no
|
|
29
|
+
* glibc and the field is absent. Getting this wrong is not a graceful
|
|
30
|
+
* degradation, it is a binary that dies with a linker error most users cannot
|
|
31
|
+
* read, so the check is explicit rather than inferred from a distro name.
|
|
32
|
+
*/
|
|
33
|
+
export function isMusl(platform = process.platform, report = () => process.report?.getReport()) {
|
|
34
|
+
if (platform !== 'linux') return false;
|
|
35
|
+
try {
|
|
36
|
+
const r = report();
|
|
37
|
+
const header = typeof r === 'object' && r !== null ? r.header : null;
|
|
38
|
+
return !(header && typeof header.glibcVersionRuntime === 'string');
|
|
39
|
+
} catch {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function platformPackage(platform = process.platform, arch = process.arch, musl = isMusl(platform)) {
|
|
45
|
+
if (platform === 'darwin' && arch === 'arm64') return '@gethrbr/harborloop-darwin-arm64';
|
|
46
|
+
if (platform === 'darwin' && arch === 'x64') return '@gethrbr/harborloop-darwin-x64';
|
|
47
|
+
if (platform === 'linux' && arch === 'arm64') return '@gethrbr/harborloop-linux-arm64';
|
|
48
|
+
if (platform === 'linux' && arch === 'x64')
|
|
49
|
+
return musl ? '@gethrbr/harborloop-linux-x64-musl' : '@gethrbr/harborloop-linux-x64';
|
|
50
|
+
if (platform === 'win32' && arch === 'x64') return '@gethrbr/harborloop-win32-x64';
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Hash a file in 1 MB chunks rather than reading it whole.
|
|
56
|
+
*
|
|
57
|
+
* 62-86 MB through `readFileSync` is 86 MB of resident memory a moment before
|
|
58
|
+
* we spawn a second process that needs its own. Chunked is the same 40 ms and a
|
|
59
|
+
* bounded footprint.
|
|
60
|
+
*/
|
|
61
|
+
export function sha256File(path) {
|
|
62
|
+
const hash = createHash('sha256');
|
|
63
|
+
const buf = Buffer.allocUnsafe(1024 * 1024);
|
|
64
|
+
const fd = openSync(path, 'r');
|
|
65
|
+
try {
|
|
66
|
+
let read;
|
|
67
|
+
while ((read = readSync(fd, buf, 0, buf.length, null)) > 0) hash.update(buf.subarray(0, read));
|
|
68
|
+
} finally {
|
|
69
|
+
closeSync(fd);
|
|
70
|
+
}
|
|
71
|
+
return hash.digest('hex');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* 🔒 **Does the binary on disk match the one this release published?**
|
|
76
|
+
*
|
|
77
|
+
* The threat is not hypothetical enough to skip. This shim `require.resolve`s an
|
|
78
|
+
* executable out of a SEPARATE npm package and runs it with the user's full
|
|
79
|
+
* privileges, and the program it runs edits `~/.claude.json` and installs hooks
|
|
80
|
+
* that fire on every prompt. Six extra package names is six extra ways in: a
|
|
81
|
+
* leaked token scoped to one of them, an internal registry mirror that rewrites
|
|
82
|
+
* tarballs, or anything with write access to `node_modules` after install.
|
|
83
|
+
*
|
|
84
|
+
* `checksums.json` is generated from the exact bytes packed into each platform
|
|
85
|
+
* package and ships INSIDE this wrapper, so the two travel together in one
|
|
86
|
+
* publish. An attacker who controls a platform package but not the wrapper
|
|
87
|
+
* cannot make this function say yes.
|
|
88
|
+
*
|
|
89
|
+
* ⚠️ It fails CLOSED, including when the manifest is missing or has no entry for
|
|
90
|
+
* this platform. A build of ours always has one — `release.mjs` refuses to
|
|
91
|
+
* publish otherwise and a test asserts it — so absence is not a version of ours
|
|
92
|
+
* running, it is the signature the check exists to catch.
|
|
93
|
+
*/
|
|
94
|
+
export function verifyIntegrity(binary, manifestPath, pkg) {
|
|
95
|
+
let manifest;
|
|
96
|
+
try {
|
|
97
|
+
manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
|
|
98
|
+
} catch {
|
|
99
|
+
return { ok: false, reason: `integrity manifest is missing or unreadable at ${manifestPath}` };
|
|
100
|
+
}
|
|
101
|
+
if (manifest.algorithm !== 'sha256') {
|
|
102
|
+
return { ok: false, reason: `integrity manifest uses unknown algorithm ${String(manifest.algorithm)}` };
|
|
103
|
+
}
|
|
104
|
+
const expected = manifest.binaries?.[pkg];
|
|
105
|
+
if (typeof expected !== 'string' || expected.length !== 64) {
|
|
106
|
+
return { ok: false, reason: `integrity manifest has no sha256 for ${pkg}` };
|
|
107
|
+
}
|
|
108
|
+
let actual;
|
|
109
|
+
try {
|
|
110
|
+
actual = sha256File(binary);
|
|
111
|
+
} catch (err) {
|
|
112
|
+
return { ok: false, reason: `could not read ${binary}: ${err.message}` };
|
|
113
|
+
}
|
|
114
|
+
if (actual !== expected) {
|
|
115
|
+
return { ok: false, reason: `${binary}\n expected sha256 ${expected}\n found sha256 ${actual}` };
|
|
116
|
+
}
|
|
117
|
+
return { ok: true };
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function main(argv = process.argv.slice(2)) {
|
|
121
|
+
const pkg = platformPackage();
|
|
122
|
+
if (pkg === null) {
|
|
123
|
+
process.stderr.write(
|
|
124
|
+
`harbor: no build for ${process.platform}/${process.arch}.\n` +
|
|
125
|
+
`Supported: macOS (arm64, x64), Linux (x64, arm64, x64-musl), Windows (x64).\n`
|
|
126
|
+
);
|
|
127
|
+
return 1;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
let binary;
|
|
131
|
+
try {
|
|
132
|
+
binary = require.resolve(`${pkg}/bin/harbor${process.platform === 'win32' ? '.exe' : ''}`);
|
|
133
|
+
} catch {
|
|
134
|
+
// An optional dependency that failed to install is SILENT by design, so this
|
|
135
|
+
// is the only place a user ever learns it happened. Naming the package is the
|
|
136
|
+
// difference between an actionable message and a mystery.
|
|
137
|
+
process.stderr.write(
|
|
138
|
+
`harbor: the binary for ${process.platform}/${process.arch} is not installed.\n` +
|
|
139
|
+
`It ships as the optional dependency ${pkg}.\n` +
|
|
140
|
+
`Reinstall with: npm install ${pkg}\n` +
|
|
141
|
+
`If you installed with --no-optional, that flag is why.\n`
|
|
142
|
+
);
|
|
143
|
+
return 1;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// The escape hatch exists so a mismatch is a support ticket rather than an
|
|
147
|
+
// unusable install, and it is loud on every run so it cannot become the
|
|
148
|
+
// permanent state of someone's machine without them knowing.
|
|
149
|
+
if (process.env.HARBOR_SKIP_INTEGRITY === '1') {
|
|
150
|
+
process.stderr.write('harbor: HARBOR_SKIP_INTEGRITY=1 — running an UNVERIFIED binary.\n');
|
|
151
|
+
} else {
|
|
152
|
+
const manifest = join(dirname(fileURLToPath(import.meta.url)), 'checksums.json');
|
|
153
|
+
const verdict = verifyIntegrity(binary, manifest, pkg);
|
|
154
|
+
if (!verdict.ok) {
|
|
155
|
+
process.stderr.write(
|
|
156
|
+
`harbor: refusing to run — the binary does not match this release.\n` +
|
|
157
|
+
` ${verdict.reason}\n` +
|
|
158
|
+
`Reinstall with: npm install --force harborloop\n` +
|
|
159
|
+
`If you build harbor yourself, run the binary directly instead of through this shim.\n`
|
|
160
|
+
);
|
|
161
|
+
return 1;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// `stdio: 'inherit'` so the child owns the real terminal: `harbor login` opens a
|
|
166
|
+
// browser and prints a URL, and `doctor` renders a table. Neither survives being
|
|
167
|
+
// piped through a parent that buffers.
|
|
168
|
+
const result = spawnSync(binary, argv, { stdio: 'inherit' });
|
|
169
|
+
if (result.error) {
|
|
170
|
+
process.stderr.write(`harbor: could not run ${binary}: ${result.error.message}\n`);
|
|
171
|
+
return 1;
|
|
172
|
+
}
|
|
173
|
+
// A signalled child has a null status. Report it the way a shell would, so a
|
|
174
|
+
// Ctrl-C is not reported as a clean exit.
|
|
175
|
+
return result.status === null ? 1 : result.status;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// npm links this file into `node_modules/.bin` as a SYMLINK, so `argv[1]` is the
|
|
179
|
+
// link and `import.meta.url` is the target. `realpath` is what makes them equal.
|
|
180
|
+
// A shim that cannot tell must still run: refusing would brick the command.
|
|
181
|
+
let isEntry = true;
|
|
182
|
+
try {
|
|
183
|
+
isEntry =
|
|
184
|
+
process.argv[1] === undefined || realpathSync(process.argv[1]) === fileURLToPath(import.meta.url);
|
|
185
|
+
} catch {
|
|
186
|
+
isEntry = true;
|
|
187
|
+
}
|
|
188
|
+
if (isEntry) process.exit(main());
|
package/package.json
CHANGED
|
@@ -1,43 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "harborloop",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Install and health-check the harbor knowledge loop in your terminal. Recall in Claude Code, Codex and Cursor; a doctor that can say no.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"homepage": "https://gethrbr.com",
|
|
8
8
|
"bin": {
|
|
9
|
-
"harbor": "
|
|
9
|
+
"harbor": "bin/harbor.mjs"
|
|
10
10
|
},
|
|
11
|
-
"main": "dist/api.js",
|
|
12
|
-
"types": "dist/api.d.ts",
|
|
13
11
|
"files": [
|
|
14
|
-
"
|
|
15
|
-
"hooks",
|
|
12
|
+
"bin",
|
|
16
13
|
"LICENSE",
|
|
17
14
|
"README.md"
|
|
18
15
|
],
|
|
19
16
|
"engines": {
|
|
20
17
|
"node": ">=18"
|
|
21
18
|
},
|
|
22
|
-
"publishConfig": {
|
|
23
|
-
"//": "A scoped package defaults to RESTRICTED, and `npm publish` on a scope with no paid plan fails outright rather than publishing privately. This is the whole difference between a wedge anybody can `npx` and a 402.",
|
|
24
|
-
"access": "public"
|
|
25
|
-
},
|
|
26
|
-
"scripts": {
|
|
27
|
-
"build": "tsc -p tsconfig.build.json && tsc -p tsconfig.hooks.json",
|
|
28
|
-
"dev": "tsx src/index.ts",
|
|
29
|
-
"typecheck": "tsc --noEmit && tsc -p tsconfig.test.json",
|
|
30
|
-
"//pretest": "Three suites EXECUTE hooks/*.mjs by path (recall-redelivery.test.ts:29 and friends). Those used to be tracked source, so a checkout was enough; they are build output now, and CI runs tests BEFORE build. Without this, npm test passes locally off a stale hooks/ and fails on a clean clone.",
|
|
31
|
-
"pretest": "tsc -p tsconfig.hooks.json",
|
|
32
|
-
"test": "vitest run",
|
|
33
|
-
"test:watch": "vitest",
|
|
34
|
-
"e2e": "npm run e2e:offline && node e2e/loop.e2e.mjs",
|
|
35
|
-
"e2e:offline": "node e2e/offline.mjs",
|
|
36
|
-
"e2e:hooks": "node e2e/hooks.e2e.mjs",
|
|
37
|
-
"e2e:loop": "node e2e/loop.e2e.mjs",
|
|
38
|
-
"//prepublishOnly": "`files` ships `dist`, and NOTHING re-derived it from the tree being published \u2014 a stale `dist` was one `npm publish` away, and the tarball is exactly what nobody looks inside. Not `prepack`, which would also fire on the `npm pack` the e2e harness runs.",
|
|
39
|
-
"prepublishOnly": "npm run typecheck && npm run test && npm run build && npm run e2e:offline"
|
|
40
|
-
},
|
|
41
19
|
"keywords": [
|
|
42
20
|
"claude-code",
|
|
43
21
|
"codex",
|
|
@@ -47,10 +25,16 @@
|
|
|
47
25
|
"knowledge-graph",
|
|
48
26
|
"agents.md"
|
|
49
27
|
],
|
|
50
|
-
"
|
|
51
|
-
"@
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
28
|
+
"optionalDependencies": {
|
|
29
|
+
"@gethrbr/harborloop-darwin-arm64": "0.4.1",
|
|
30
|
+
"@gethrbr/harborloop-darwin-x64": "0.4.1",
|
|
31
|
+
"@gethrbr/harborloop-linux-x64": "0.4.1",
|
|
32
|
+
"@gethrbr/harborloop-linux-arm64": "0.4.1",
|
|
33
|
+
"@gethrbr/harborloop-linux-x64-musl": "0.4.1",
|
|
34
|
+
"@gethrbr/harborloop-win32-x64": "0.4.1"
|
|
35
|
+
},
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"//": "A scoped package defaults to RESTRICTED, and `npm publish` on a scope with no paid plan fails outright rather than publishing privately. This is the whole difference between a wedge anybody can `npx` and a 402.",
|
|
38
|
+
"access": "public"
|
|
55
39
|
}
|
|
56
40
|
}
|
package/dist/api.d.ts
DELETED
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
export type ApiFailureKind = 'unauthorized' | 'forbidden' | 'payment_required' | 'not_found' | 'rate_limited' | 'server' | 'network' | 'shape';
|
|
2
|
-
export declare class ApiError extends Error {
|
|
3
|
-
readonly kind: ApiFailureKind;
|
|
4
|
-
readonly status: number | null;
|
|
5
|
-
readonly body: unknown;
|
|
6
|
-
constructor(kind: ApiFailureKind, message: string, status?: number | null, body?: unknown);
|
|
7
|
-
}
|
|
8
|
-
export interface RequestOptions {
|
|
9
|
-
readonly method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
10
|
-
readonly body?: unknown;
|
|
11
|
-
readonly bearer?: string | null;
|
|
12
|
-
readonly timeoutMs?: number;
|
|
13
|
-
readonly fetchImpl?: typeof fetch;
|
|
14
|
-
}
|
|
15
|
-
export declare function apiRequest<T>(url: string, opts?: RequestOptions): Promise<T>;
|
|
16
|
-
export declare function describeRetryAfter(headers: Headers, now?: number): string;
|
|
17
|
-
export interface ExchangeResult {
|
|
18
|
-
readonly token: string;
|
|
19
|
-
}
|
|
20
|
-
export declare function exchangeAuthCode(apiUrl: string, code: string, codeVerifier: string, fetchImpl?: typeof fetch): Promise<string>;
|
|
21
|
-
export declare function refreshRunnerToken(apiUrl: string, runnerToken: string, fetchImpl?: typeof fetch): Promise<string>;
|
|
22
|
-
export interface Workspace {
|
|
23
|
-
readonly id: string;
|
|
24
|
-
readonly name: string;
|
|
25
|
-
}
|
|
26
|
-
export interface CurrentUser {
|
|
27
|
-
readonly id: string;
|
|
28
|
-
readonly email: string;
|
|
29
|
-
readonly name: string;
|
|
30
|
-
readonly lastWorkspaceId: string | null;
|
|
31
|
-
}
|
|
32
|
-
export declare function fetchCurrentUser(apiUrl: string, runnerToken: string, fetchImpl?: typeof fetch): Promise<CurrentUser>;
|
|
33
|
-
export declare function listWorkspaces(apiUrl: string, runnerToken: string, fetchImpl?: typeof fetch): Promise<Workspace[]>;
|
|
34
|
-
export interface MintedToken {
|
|
35
|
-
readonly token: string;
|
|
36
|
-
readonly expiresIn: string;
|
|
37
|
-
readonly connectionId: string;
|
|
38
|
-
}
|
|
39
|
-
export declare function mintMcpToken(apiUrl: string, runnerToken: string, workspaceId: string, provider: string, fetchImpl?: typeof fetch): Promise<MintedToken>;
|
|
40
|
-
export interface RepoBinding {
|
|
41
|
-
readonly id: string;
|
|
42
|
-
readonly originUrl: string;
|
|
43
|
-
readonly displayName: string | null;
|
|
44
|
-
readonly projectId: string | null;
|
|
45
|
-
readonly projectName: string | null;
|
|
46
|
-
}
|
|
47
|
-
export declare function listRepoBindings(apiUrl: string, runnerToken: string, workspaceId: string, fetchImpl?: typeof fetch): Promise<RepoBinding[]>;
|
|
48
|
-
export declare function createRepoBinding(apiUrl: string, runnerToken: string, workspaceId: string, input: {
|
|
49
|
-
originUrl: string;
|
|
50
|
-
displayName?: string;
|
|
51
|
-
projectId?: string | null;
|
|
52
|
-
}, fetchImpl?: typeof fetch): Promise<RepoBinding>;
|
|
53
|
-
export interface Project {
|
|
54
|
-
readonly id: string;
|
|
55
|
-
readonly name: string;
|
|
56
|
-
}
|
|
57
|
-
export declare function listProjects(apiUrl: string, runnerToken: string, workspaceId: string, fetchImpl?: typeof fetch): Promise<Project[]>;
|
|
58
|
-
export interface LoopMetrics {
|
|
59
|
-
readonly windowDays: number;
|
|
60
|
-
readonly projectId: string | null;
|
|
61
|
-
readonly recall: {
|
|
62
|
-
sessions: number;
|
|
63
|
-
served: number;
|
|
64
|
-
};
|
|
65
|
-
readonly fit: {
|
|
66
|
-
servedAtoms: number;
|
|
67
|
-
citedAtoms: number;
|
|
68
|
-
avgBundle: number | null;
|
|
69
|
-
};
|
|
70
|
-
readonly attribution: {
|
|
71
|
-
recalls: number;
|
|
72
|
-
keyed: number;
|
|
73
|
-
};
|
|
74
|
-
readonly contributed: {
|
|
75
|
-
total: number;
|
|
76
|
-
approved: number;
|
|
77
|
-
pending: number;
|
|
78
|
-
};
|
|
79
|
-
readonly corpus?: {
|
|
80
|
-
admitted: number;
|
|
81
|
-
retired: number;
|
|
82
|
-
liveAtoms: number;
|
|
83
|
-
retiredByCause?: {
|
|
84
|
-
cause: string;
|
|
85
|
-
count: number;
|
|
86
|
-
}[];
|
|
87
|
-
ledgerEmpty: boolean;
|
|
88
|
-
};
|
|
89
|
-
readonly byTransport?: {
|
|
90
|
-
transport: string;
|
|
91
|
-
label: string;
|
|
92
|
-
recalls: number;
|
|
93
|
-
keyed: number;
|
|
94
|
-
clients: string[];
|
|
95
|
-
}[];
|
|
96
|
-
readonly spend?: {
|
|
97
|
-
writeSpendCents: number;
|
|
98
|
-
writeSpendUsd: number;
|
|
99
|
-
spendRows: number;
|
|
100
|
-
unpricedRows: number;
|
|
101
|
-
citedAtoms: number;
|
|
102
|
-
costPerCitedAtomUsd: number | null;
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
export declare function parseLoopMetrics(data: unknown): LoopMetrics;
|
|
106
|
-
export declare function fetchLoopMetrics(apiUrl: string, mcpToken: string, params?: {
|
|
107
|
-
originUrl?: string;
|
|
108
|
-
windowDays?: number;
|
|
109
|
-
}, fetchImpl?: typeof fetch): Promise<LoopMetrics>;
|