@mickey-kras/hindsight-memory-router-coding-agents 0.8.9 → 0.8.14
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/antigravity-hook.js +70 -24
- package/dist/antigravity-statusline.js +60 -14
- package/dist/antigravity-stop-hook.js +70 -24
- package/dist/claude-hook.js +70 -24
- package/dist/claude-sessionstart-hook.js +70 -24
- package/dist/claude-stop-hook.js +70 -24
- package/dist/cline.js +70 -24
- package/dist/codebuddy-hook.js +70 -24
- package/dist/codebuddy-sessionstart-hook.js +70 -24
- package/dist/codebuddy-stop-hook.js +70 -24
- package/dist/codex-hook.js +70 -24
- package/dist/codex-sessionstart-hook.js +70 -24
- package/dist/codex-stop-hook.js +70 -24
- package/dist/copilot-hook.js +70 -24
- package/dist/copilot-sessionstart-hook.js +70 -24
- package/dist/copilot-stop-hook.js +70 -24
- package/dist/cursor-hook.js +70 -24
- package/dist/cursor-sessionstart-hook.js +70 -24
- package/dist/cursor-stop-hook.js +70 -24
- package/dist/dcode-hook.js +70 -24
- package/dist/dcode-sessionstart-hook.js +70 -24
- package/dist/dcode-stop-hook.js +70 -24
- package/dist/deepen.js +70 -68
- package/dist/devin-hook.js +70 -24
- package/dist/devin-sessionstart-hook.js +70 -24
- package/dist/devin-stop-hook.js +70 -24
- package/dist/droid-hook.js +70 -24
- package/dist/droid-sessionstart-hook.js +70 -24
- package/dist/droid-stop-hook.js +70 -24
- package/dist/dsh.js +70 -24
- package/dist/grok-hook.js +70 -24
- package/dist/grok-sessionstart-hook.js +70 -24
- package/dist/grok-stop-hook.js +70 -24
- package/dist/hindsight-seed.js +60 -14
- package/dist/index.js +70 -24
- package/dist/installer.js +70 -21
- package/dist/kilo.js +70 -24
- package/dist/kimi-hook.js +70 -24
- package/dist/kimi-sessionstart-hook.js +70 -24
- package/dist/kimi-stop-hook.js +70 -24
- package/dist/mcp-server.js +79 -24
- package/dist/opencode2.js +70 -24
- package/dist/pi.js +70 -24
- package/dist/prime-agent.js +70 -24
- package/dist/qwen-hook.js +70 -24
- package/dist/qwen-sessionstart-hook.js +70 -24
- package/dist/qwen-stop-hook.js +70 -24
- package/dist/status.js +70 -24
- package/dist/traecode-hook.js +70 -24
- package/dist/traecode-sessionstart-hook.js +70 -24
- package/dist/traecode-stop-hook.js +70 -24
- package/dist/workbuddy-hook.js +70 -24
- package/dist/workbuddy-sessionstart-hook.js +70 -24
- package/dist/workbuddy-stop-hook.js +70 -24
- package/dist/zcode-hook.js +70 -24
- package/dist/zcode-sessionstart-hook.js +70 -24
- package/dist/zcode-stop-hook.js +70 -24
- package/npm-shrinkwrap.json +257 -711
- package/package.json +8 -5
package/dist/installer.js
CHANGED
|
@@ -2456,12 +2456,10 @@ function requireBank(access, bank, operation) {
|
|
|
2456
2456
|
}
|
|
2457
2457
|
function classifyOperation(method, suffix) {
|
|
2458
2458
|
if (method === "POST" && ["/memories/recall", "/reflect"].includes(suffix)) return "read";
|
|
2459
|
-
if (method === "GET" && /^\/(?:config|stats|tags|graph|documents|operations|memories|mental-models|
|
|
2460
|
-
suffix
|
|
2461
|
-
))
|
|
2459
|
+
if (method === "GET" && /^\/(?:config|stats|tags|graph|documents|operations|memories|mental-models|pages)(?:\/[^/]+)*$/.test(suffix))
|
|
2462
2460
|
return "read";
|
|
2463
2461
|
if (method === "GET" && suffix === "") return "read";
|
|
2464
|
-
if (["POST", "PUT", "PATCH", "DELETE"].includes(method) && /^(?:\/(?:config|import|memories|documents|mental-models|
|
|
2462
|
+
if (["POST", "PUT", "PATCH", "DELETE"].includes(method) && /^(?:\/(?:config|import|memories|documents|mental-models|pages|consolidate|consolidation)(?:\/[^/]+)*)?$/.test(
|
|
2465
2463
|
suffix
|
|
2466
2464
|
))
|
|
2467
2465
|
return "write";
|
|
@@ -2756,6 +2754,54 @@ var RouterTransport = class {
|
|
|
2756
2754
|
// ../../coding-agents/human-session.ts
|
|
2757
2755
|
import { createHash as createHash2 } from "crypto";
|
|
2758
2756
|
import { createRequire } from "module";
|
|
2757
|
+
|
|
2758
|
+
// src/harness/names.ts
|
|
2759
|
+
var HARNESS_NAMES = [
|
|
2760
|
+
"opencode",
|
|
2761
|
+
// opencode v2 (binary `opencode2`) — a ground-up rewrite of the plugin API, loaded from the
|
|
2762
|
+
// package's root index.js (src/opencode2.ts). Like opencode it has NO hook binary.
|
|
2763
|
+
"opencode2",
|
|
2764
|
+
// Kilo CLI is an opencode fork loaded as a persistent plugin (src/kilo.ts), so like opencode it
|
|
2765
|
+
// has NO hook binary — deliberately absent from HOOK_BINS below.
|
|
2766
|
+
"kilo",
|
|
2767
|
+
// Cline CLI loads dist/cline.js through its native plugin manager; file hooks cannot inject.
|
|
2768
|
+
"cline-cli",
|
|
2769
|
+
// DeepSeek Harness loads dist/dsh.js as a native Cordis plugin (src/dsh.ts). Its Claude Code /
|
|
2770
|
+
// Codex hook bridges are optional packages, so there is no hook binary to install either.
|
|
2771
|
+
"dsh",
|
|
2772
|
+
// pi loads dist/pi.js as an extension (src/pi.ts), and Prime Agent — a fork of pi — loads
|
|
2773
|
+
// dist/prime-agent.js the same way (src/prime-agent.ts). Neither has a hook binary.
|
|
2774
|
+
"pi",
|
|
2775
|
+
"prime-agent",
|
|
2776
|
+
"claude-code",
|
|
2777
|
+
"cursor-cli",
|
|
2778
|
+
"codex",
|
|
2779
|
+
"dcode",
|
|
2780
|
+
"antigravity-cli",
|
|
2781
|
+
"devin-cli",
|
|
2782
|
+
"copilot-cli",
|
|
2783
|
+
"grok-build",
|
|
2784
|
+
"qwen-code",
|
|
2785
|
+
// Factory Droid is a per-prompt HOOK host: the installer wires ~/.factory/hooks.json and the
|
|
2786
|
+
// stdio MCP registration in ~/.factory/mcp.json (see src/installer.ts).
|
|
2787
|
+
"factory-droid",
|
|
2788
|
+
// ZCode is a per-prompt HOOK host too, registered in its own CLI config
|
|
2789
|
+
// (~/.zcode/cli/config.json) under `hooks.events` — never the user's real Claude Code settings.
|
|
2790
|
+
"zcode",
|
|
2791
|
+
// TraeCode is a per-prompt HOOK host registered in ~/.trae-cn/hooks.json (see src/installer.ts).
|
|
2792
|
+
"traecode",
|
|
2793
|
+
"kimi-code",
|
|
2794
|
+
// WorkBuddy is a per-prompt HOOK host too: the installer wires ~/.workbuddy/settings.json and
|
|
2795
|
+
// the stdio MCP registration in ~/.workbuddy/mcp.json (see src/installer.ts).
|
|
2796
|
+
"workbuddy",
|
|
2797
|
+
// CodeBuddy Code is the SAME @genie/agent-cli HOOK host, one product config apart (WorkBuddy only
|
|
2798
|
+
// renames the home folder): the installer wires ~/.codebuddy/settings.json and the stdio MCP
|
|
2799
|
+
// registration in CodeBuddy's priority-chained MCP file (see src/installer.ts). The CLI
|
|
2800
|
+
// writes WorkBuddy's transcript format; the CodeBuddy IDE has a reader of its own.
|
|
2801
|
+
"codebuddy"
|
|
2802
|
+
];
|
|
2803
|
+
|
|
2804
|
+
// ../../coding-agents/human-session.ts
|
|
2759
2805
|
var HUMAN_TOKEN_PATTERN = /^mrh_[0-9a-f]{32}_[0-9a-f]{64}$/;
|
|
2760
2806
|
var HumanLoginRequiredError = class extends AccessDeniedError {
|
|
2761
2807
|
constructor() {
|
|
@@ -2781,14 +2827,14 @@ function humanRouterUrl(value) {
|
|
|
2781
2827
|
if (url.search || url.hash) throw new HumanLoginRequiredError();
|
|
2782
2828
|
return canonical;
|
|
2783
2829
|
}
|
|
2784
|
-
function secureEntry(routerUrl, credentialRef) {
|
|
2830
|
+
function secureEntry(routerUrl, credentialRef, harness) {
|
|
2785
2831
|
try {
|
|
2786
|
-
if (!["darwin", "win32", "linux"].includes(process.platform) || !/^[A-Za-z0-9._-]{1,64}$/.test(credentialRef)) {
|
|
2832
|
+
if (!["darwin", "win32", "linux"].includes(process.platform) || !/^[A-Za-z0-9._-]{1,64}$/.test(credentialRef) || !HARNESS_NAMES.includes(harness)) {
|
|
2787
2833
|
throw new HumanLoginRequiredError();
|
|
2788
2834
|
}
|
|
2789
2835
|
const { Entry: NativeEntry } = createRequire(import.meta.url)("@napi-rs/keyring");
|
|
2790
|
-
const service = `hindsight-memory-router:${createHash2("sha256").update(humanRouterUrl(routerUrl)).digest("hex")}`;
|
|
2791
|
-
return new NativeEntry(service, credentialRef
|
|
2836
|
+
const service = `hindsight-memory-router:human-v2:${createHash2("sha256").update(humanRouterUrl(routerUrl)).digest("hex")}`;
|
|
2837
|
+
return new NativeEntry(service, `${harness}:${credentialRef}`, { linux: { store: "secret-service" } });
|
|
2792
2838
|
} catch {
|
|
2793
2839
|
throw new HumanLoginRequiredError();
|
|
2794
2840
|
}
|
|
@@ -2806,9 +2852,9 @@ function validateHumanSession(value, routerUrl, allowExpired = false) {
|
|
|
2806
2852
|
routerUrl: session.routerUrl
|
|
2807
2853
|
};
|
|
2808
2854
|
}
|
|
2809
|
-
function readHumanSession(routerUrl, credentialRef) {
|
|
2855
|
+
function readHumanSession(routerUrl, credentialRef, harness) {
|
|
2810
2856
|
try {
|
|
2811
|
-
const password = secureEntry(routerUrl, credentialRef).getPassword();
|
|
2857
|
+
const password = secureEntry(routerUrl, credentialRef, harness).getPassword();
|
|
2812
2858
|
if (!password || password.length > 4096) throw new HumanLoginRequiredError();
|
|
2813
2859
|
return validateHumanSession(JSON.parse(password), routerUrl);
|
|
2814
2860
|
} catch {
|
|
@@ -2820,11 +2866,11 @@ function readHumanSession(routerUrl, credentialRef) {
|
|
|
2820
2866
|
function harnessTransport(harness) {
|
|
2821
2867
|
return transportForConfig(harness, loadManagedConfig(process.env, harness));
|
|
2822
2868
|
}
|
|
2823
|
-
function transportForConfig(harness, { config: config2, principal }) {
|
|
2869
|
+
function transportForConfig(harness, { config: config2, principal, principalId }) {
|
|
2824
2870
|
if (principal.human) {
|
|
2825
2871
|
const routerUrl = humanRouterUrl(config2.routerUrl);
|
|
2826
2872
|
const reference = principal.human.credentialRef;
|
|
2827
|
-
let session = readHumanSession(routerUrl, reference);
|
|
2873
|
+
let session = readHumanSession(routerUrl, reference, principalId);
|
|
2828
2874
|
return new RouterTransport({
|
|
2829
2875
|
routerUrl,
|
|
2830
2876
|
access: principal,
|
|
@@ -2832,7 +2878,7 @@ function transportForConfig(harness, { config: config2, principal }) {
|
|
|
2832
2878
|
tokenPattern: HUMAN_TOKEN_PATTERN,
|
|
2833
2879
|
unauthorizedError: () => new HumanLoginRequiredError(),
|
|
2834
2880
|
token: () => {
|
|
2835
|
-
session = readHumanSession(routerUrl, reference);
|
|
2881
|
+
session = readHumanSession(routerUrl, reference, principalId);
|
|
2836
2882
|
return session.token;
|
|
2837
2883
|
}
|
|
2838
2884
|
});
|
|
@@ -2978,9 +3024,9 @@ async function openLoginBrowser(url) {
|
|
|
2978
3024
|
});
|
|
2979
3025
|
});
|
|
2980
3026
|
}
|
|
2981
|
-
async function loginHuman(routerUrl, credentialRef, openBrowser = openLoginBrowser) {
|
|
3027
|
+
async function loginHuman(routerUrl, credentialRef, harness, openBrowser = openLoginBrowser) {
|
|
2982
3028
|
const base = humanRouterUrl(routerUrl);
|
|
2983
|
-
const entry = secureEntry(base, credentialRef);
|
|
3029
|
+
const entry = secureEntry(base, credentialRef, harness);
|
|
2984
3030
|
entry.getPassword();
|
|
2985
3031
|
const state = randomBytes(32).toString("base64url");
|
|
2986
3032
|
const verifier = randomBytes(32).toString("base64url");
|
|
@@ -3068,9 +3114,9 @@ async function loginHuman(routerUrl, credentialRef, openBrowser = openLoginBrows
|
|
|
3068
3114
|
if (server.listening) await new Promise((resolve6) => server.close(() => resolve6()));
|
|
3069
3115
|
}
|
|
3070
3116
|
}
|
|
3071
|
-
async function signOutHuman(routerUrl, credentialRef) {
|
|
3117
|
+
async function signOutHuman(routerUrl, credentialRef, harness) {
|
|
3072
3118
|
const base = humanRouterUrl(routerUrl);
|
|
3073
|
-
const entry = secureEntry(base, credentialRef);
|
|
3119
|
+
const entry = secureEntry(base, credentialRef, harness);
|
|
3074
3120
|
let revoked = false;
|
|
3075
3121
|
try {
|
|
3076
3122
|
const stored = entry.getPassword();
|
|
@@ -3094,17 +3140,20 @@ async function runHumanAuth(argv, log2, interactive) {
|
|
|
3094
3140
|
if (!["login", "sign-out"].includes(command) || args.length > 1 || args.some((arg) => arg.startsWith("--"))) {
|
|
3095
3141
|
throw new HumanLoginRequiredError();
|
|
3096
3142
|
}
|
|
3097
|
-
const { config: config2, principal } = loadManagedConfig(
|
|
3143
|
+
const { config: config2, principal, principalId } = loadManagedConfig(
|
|
3144
|
+
process.env,
|
|
3145
|
+
args[0] ?? process.env.HINDSIGHT_MCP_HARNESS
|
|
3146
|
+
);
|
|
3098
3147
|
if (!principal.human) throw new HumanLoginRequiredError();
|
|
3099
3148
|
if (command === "login") {
|
|
3100
3149
|
if (!interactive) throw new HumanLoginRequiredError();
|
|
3101
|
-
await loginHuman(config2.routerUrl, principal.human.credentialRef);
|
|
3150
|
+
await loginHuman(config2.routerUrl, principal.human.credentialRef, principalId);
|
|
3102
3151
|
log2(
|
|
3103
3152
|
"Signed in. Run install for the configured coding agent. Sessions expire within one hour; login again when required."
|
|
3104
3153
|
);
|
|
3105
3154
|
return 0;
|
|
3106
3155
|
}
|
|
3107
|
-
const revoked = await signOutHuman(config2.routerUrl, principal.human.credentialRef);
|
|
3156
|
+
const revoked = await signOutHuman(config2.routerUrl, principal.human.credentialRef, principalId);
|
|
3108
3157
|
log2(
|
|
3109
3158
|
revoked ? "Signed out." : "Local credential removed; server revocation could not be confirmed. The session remains valid until expiry or operator revocation."
|
|
3110
3159
|
);
|
|
@@ -3407,7 +3456,7 @@ var PAGE_TAXONOMY = [
|
|
|
3407
3456
|
var PAGE_NAMES = PAGE_TAXONOMY.map((page) => page.name);
|
|
3408
3457
|
|
|
3409
3458
|
// package.json
|
|
3410
|
-
var version = "0.8.
|
|
3459
|
+
var version = "0.8.14";
|
|
3411
3460
|
|
|
3412
3461
|
// src/core/util.ts
|
|
3413
3462
|
import { accessSync, constants } from "fs";
|
package/dist/kilo.js
CHANGED
|
@@ -34,12 +34,10 @@ function requireBank(access, bank, operation) {
|
|
|
34
34
|
}
|
|
35
35
|
function classifyOperation(method, suffix) {
|
|
36
36
|
if (method === "POST" && ["/memories/recall", "/reflect"].includes(suffix)) return "read";
|
|
37
|
-
if (method === "GET" && /^\/(?:config|stats|tags|graph|documents|operations|memories|mental-models|
|
|
38
|
-
suffix
|
|
39
|
-
))
|
|
37
|
+
if (method === "GET" && /^\/(?:config|stats|tags|graph|documents|operations|memories|mental-models|pages)(?:\/[^/]+)*$/.test(suffix))
|
|
40
38
|
return "read";
|
|
41
39
|
if (method === "GET" && suffix === "") return "read";
|
|
42
|
-
if (["POST", "PUT", "PATCH", "DELETE"].includes(method) && /^(?:\/(?:config|import|memories|documents|mental-models|
|
|
40
|
+
if (["POST", "PUT", "PATCH", "DELETE"].includes(method) && /^(?:\/(?:config|import|memories|documents|mental-models|pages|consolidate|consolidation)(?:\/[^/]+)*)?$/.test(
|
|
43
41
|
suffix
|
|
44
42
|
))
|
|
45
43
|
return "write";
|
|
@@ -451,6 +449,54 @@ var RouterTransport = class {
|
|
|
451
449
|
// ../../coding-agents/human-session.ts
|
|
452
450
|
import { createHash as createHash2 } from "crypto";
|
|
453
451
|
import { createRequire } from "module";
|
|
452
|
+
|
|
453
|
+
// src/harness/names.ts
|
|
454
|
+
var HARNESS_NAMES = [
|
|
455
|
+
"opencode",
|
|
456
|
+
// opencode v2 (binary `opencode2`) — a ground-up rewrite of the plugin API, loaded from the
|
|
457
|
+
// package's root index.js (src/opencode2.ts). Like opencode it has NO hook binary.
|
|
458
|
+
"opencode2",
|
|
459
|
+
// Kilo CLI is an opencode fork loaded as a persistent plugin (src/kilo.ts), so like opencode it
|
|
460
|
+
// has NO hook binary — deliberately absent from HOOK_BINS below.
|
|
461
|
+
"kilo",
|
|
462
|
+
// Cline CLI loads dist/cline.js through its native plugin manager; file hooks cannot inject.
|
|
463
|
+
"cline-cli",
|
|
464
|
+
// DeepSeek Harness loads dist/dsh.js as a native Cordis plugin (src/dsh.ts). Its Claude Code /
|
|
465
|
+
// Codex hook bridges are optional packages, so there is no hook binary to install either.
|
|
466
|
+
"dsh",
|
|
467
|
+
// pi loads dist/pi.js as an extension (src/pi.ts), and Prime Agent — a fork of pi — loads
|
|
468
|
+
// dist/prime-agent.js the same way (src/prime-agent.ts). Neither has a hook binary.
|
|
469
|
+
"pi",
|
|
470
|
+
"prime-agent",
|
|
471
|
+
"claude-code",
|
|
472
|
+
"cursor-cli",
|
|
473
|
+
"codex",
|
|
474
|
+
"dcode",
|
|
475
|
+
"antigravity-cli",
|
|
476
|
+
"devin-cli",
|
|
477
|
+
"copilot-cli",
|
|
478
|
+
"grok-build",
|
|
479
|
+
"qwen-code",
|
|
480
|
+
// Factory Droid is a per-prompt HOOK host: the installer wires ~/.factory/hooks.json and the
|
|
481
|
+
// stdio MCP registration in ~/.factory/mcp.json (see src/installer.ts).
|
|
482
|
+
"factory-droid",
|
|
483
|
+
// ZCode is a per-prompt HOOK host too, registered in its own CLI config
|
|
484
|
+
// (~/.zcode/cli/config.json) under `hooks.events` — never the user's real Claude Code settings.
|
|
485
|
+
"zcode",
|
|
486
|
+
// TraeCode is a per-prompt HOOK host registered in ~/.trae-cn/hooks.json (see src/installer.ts).
|
|
487
|
+
"traecode",
|
|
488
|
+
"kimi-code",
|
|
489
|
+
// WorkBuddy is a per-prompt HOOK host too: the installer wires ~/.workbuddy/settings.json and
|
|
490
|
+
// the stdio MCP registration in ~/.workbuddy/mcp.json (see src/installer.ts).
|
|
491
|
+
"workbuddy",
|
|
492
|
+
// CodeBuddy Code is the SAME @genie/agent-cli HOOK host, one product config apart (WorkBuddy only
|
|
493
|
+
// renames the home folder): the installer wires ~/.codebuddy/settings.json and the stdio MCP
|
|
494
|
+
// registration in CodeBuddy's priority-chained MCP file (see src/installer.ts). The CLI
|
|
495
|
+
// writes WorkBuddy's transcript format; the CodeBuddy IDE has a reader of its own.
|
|
496
|
+
"codebuddy"
|
|
497
|
+
];
|
|
498
|
+
|
|
499
|
+
// ../../coding-agents/human-session.ts
|
|
454
500
|
var HUMAN_TOKEN_PATTERN = /^mrh_[0-9a-f]{32}_[0-9a-f]{64}$/;
|
|
455
501
|
var HumanLoginRequiredError = class extends AccessDeniedError {
|
|
456
502
|
constructor() {
|
|
@@ -476,14 +522,14 @@ function humanRouterUrl(value) {
|
|
|
476
522
|
if (url2.search || url2.hash) throw new HumanLoginRequiredError();
|
|
477
523
|
return canonical2;
|
|
478
524
|
}
|
|
479
|
-
function secureEntry(routerUrl, credentialRef) {
|
|
525
|
+
function secureEntry(routerUrl, credentialRef, harness) {
|
|
480
526
|
try {
|
|
481
|
-
if (!["darwin", "win32", "linux"].includes(process.platform) || !/^[A-Za-z0-9._-]{1,64}$/.test(credentialRef)) {
|
|
527
|
+
if (!["darwin", "win32", "linux"].includes(process.platform) || !/^[A-Za-z0-9._-]{1,64}$/.test(credentialRef) || !HARNESS_NAMES.includes(harness)) {
|
|
482
528
|
throw new HumanLoginRequiredError();
|
|
483
529
|
}
|
|
484
530
|
const { Entry: NativeEntry } = createRequire(import.meta.url)("@napi-rs/keyring");
|
|
485
|
-
const service = `hindsight-memory-router:${createHash2("sha256").update(humanRouterUrl(routerUrl)).digest("hex")}`;
|
|
486
|
-
return new NativeEntry(service, credentialRef
|
|
531
|
+
const service = `hindsight-memory-router:human-v2:${createHash2("sha256").update(humanRouterUrl(routerUrl)).digest("hex")}`;
|
|
532
|
+
return new NativeEntry(service, `${harness}:${credentialRef}`, { linux: { store: "secret-service" } });
|
|
487
533
|
} catch {
|
|
488
534
|
throw new HumanLoginRequiredError();
|
|
489
535
|
}
|
|
@@ -501,9 +547,9 @@ function validateHumanSession(value, routerUrl, allowExpired = false) {
|
|
|
501
547
|
routerUrl: session.routerUrl
|
|
502
548
|
};
|
|
503
549
|
}
|
|
504
|
-
function readHumanSession(routerUrl, credentialRef) {
|
|
550
|
+
function readHumanSession(routerUrl, credentialRef, harness) {
|
|
505
551
|
try {
|
|
506
|
-
const password = secureEntry(routerUrl, credentialRef).getPassword();
|
|
552
|
+
const password = secureEntry(routerUrl, credentialRef, harness).getPassword();
|
|
507
553
|
if (!password || password.length > 4096) throw new HumanLoginRequiredError();
|
|
508
554
|
return validateHumanSession(JSON.parse(password), routerUrl);
|
|
509
555
|
} catch {
|
|
@@ -515,11 +561,11 @@ function readHumanSession(routerUrl, credentialRef) {
|
|
|
515
561
|
function harnessTransport(harness) {
|
|
516
562
|
return transportForConfig(harness, loadManagedConfig(process.env, harness));
|
|
517
563
|
}
|
|
518
|
-
function transportForConfig(harness, { config: config2, principal }) {
|
|
564
|
+
function transportForConfig(harness, { config: config2, principal, principalId }) {
|
|
519
565
|
if (principal.human) {
|
|
520
566
|
const routerUrl = humanRouterUrl(config2.routerUrl);
|
|
521
567
|
const reference = principal.human.credentialRef;
|
|
522
|
-
let session = readHumanSession(routerUrl, reference);
|
|
568
|
+
let session = readHumanSession(routerUrl, reference, principalId);
|
|
523
569
|
return new RouterTransport({
|
|
524
570
|
routerUrl,
|
|
525
571
|
access: principal,
|
|
@@ -527,7 +573,7 @@ function transportForConfig(harness, { config: config2, principal }) {
|
|
|
527
573
|
tokenPattern: HUMAN_TOKEN_PATTERN,
|
|
528
574
|
unauthorizedError: () => new HumanLoginRequiredError(),
|
|
529
575
|
token: () => {
|
|
530
|
-
session = readHumanSession(routerUrl, reference);
|
|
576
|
+
session = readHumanSession(routerUrl, reference, principalId);
|
|
531
577
|
return session.token;
|
|
532
578
|
}
|
|
533
579
|
});
|
|
@@ -1334,7 +1380,7 @@ var PLUGIN_GOVERNED_BANK_FIELDS = [
|
|
|
1334
1380
|
];
|
|
1335
1381
|
|
|
1336
1382
|
// package.json
|
|
1337
|
-
var version = "0.8.
|
|
1383
|
+
var version = "0.8.14";
|
|
1338
1384
|
|
|
1339
1385
|
// src/core/util.ts
|
|
1340
1386
|
import { accessSync, constants } from "fs";
|
|
@@ -1867,7 +1913,7 @@ var HindsightClient = class _HindsightClient {
|
|
|
1867
1913
|
*/
|
|
1868
1914
|
async tree() {
|
|
1869
1915
|
if (this.knowledgePagesSupported === false) throw new KnowledgePagesUnavailableError();
|
|
1870
|
-
const r = await this.req("GET", this.bankUrl("/
|
|
1916
|
+
const r = await this.req("GET", this.bankUrl("/pages/tree"));
|
|
1871
1917
|
if (await this.pagesUnsupported(r)) throw new KnowledgePagesUnavailableError();
|
|
1872
1918
|
if (r.status === 404) return [];
|
|
1873
1919
|
this.knowledgePagesSupported = true;
|
|
@@ -1915,7 +1961,7 @@ var HindsightClient = class _HindsightClient {
|
|
|
1915
1961
|
if (this.knowledgePagesSupported === false) throw new KnowledgePagesUnavailableError();
|
|
1916
1962
|
const r = await this.req(
|
|
1917
1963
|
"GET",
|
|
1918
|
-
this.bankUrl(`/
|
|
1964
|
+
this.bankUrl(`/pages/${encodeURIComponent(pageId)}`)
|
|
1919
1965
|
);
|
|
1920
1966
|
if (r.status === 404) throw new Error(`knowledge page not found: ${pageId}`);
|
|
1921
1967
|
return shapePage(await r.json());
|
|
@@ -1928,7 +1974,7 @@ var HindsightClient = class _HindsightClient {
|
|
|
1928
1974
|
const q = `?q=${encodeURIComponent(query)}&limit=${opts.limit ?? this.pageSearchLimit}`;
|
|
1929
1975
|
const r = await this.req(
|
|
1930
1976
|
"GET",
|
|
1931
|
-
this.bankUrl(`/
|
|
1977
|
+
this.bankUrl(`/pages/search${q}`),
|
|
1932
1978
|
void 0,
|
|
1933
1979
|
[],
|
|
1934
1980
|
opts.timeoutMs
|
|
@@ -1947,7 +1993,7 @@ var HindsightClient = class _HindsightClient {
|
|
|
1947
1993
|
/**
|
|
1948
1994
|
* Seed the fixed page taxonomy as knowledge-base pages at the tree root, idempotently.
|
|
1949
1995
|
*
|
|
1950
|
-
* Matched by NAME, not id: `/
|
|
1996
|
+
* Matched by NAME, not id: `/pages` mints its own `kp-…` id, so a stable
|
|
1951
1997
|
* client-chosen id isn't available to match on (unlike the old mental-model path, which keyed
|
|
1952
1998
|
* off a slug). Names are unique per folder server-side, which makes them a sound key.
|
|
1953
1999
|
*
|
|
@@ -1986,7 +2032,7 @@ var HindsightClient = class _HindsightClient {
|
|
|
1986
2032
|
trigger: pageTriggerFor(pageTrigger, this.bank, page.name)
|
|
1987
2033
|
};
|
|
1988
2034
|
if (!hit) {
|
|
1989
|
-
const r = await this.req("POST", this.bankUrl("/
|
|
2035
|
+
const r = await this.req("POST", this.bankUrl("/pages"), body, [409]);
|
|
1990
2036
|
if (await this.pagesUnsupported(r)) {
|
|
1991
2037
|
this.log(
|
|
1992
2038
|
`[bank] knowledge pages unavailable on ${this.apiUrl}; continuing without pages`
|
|
@@ -2013,7 +2059,7 @@ var HindsightClient = class _HindsightClient {
|
|
|
2013
2059
|
if (triggerDrift) patch.trigger = pageTriggerPatch(body.trigger);
|
|
2014
2060
|
const r = await this.req(
|
|
2015
2061
|
"PATCH",
|
|
2016
|
-
this.bankUrl(`/
|
|
2062
|
+
this.bankUrl(`/pages/nodes/${encodeURIComponent(hit.id)}`),
|
|
2017
2063
|
patch
|
|
2018
2064
|
);
|
|
2019
2065
|
if (await this.pagesUnsupported(r)) {
|
|
@@ -2067,7 +2113,7 @@ var HindsightClient = class _HindsightClient {
|
|
|
2067
2113
|
if (!patch.trigger && !patch.source_query) continue;
|
|
2068
2114
|
const r = await this.req(
|
|
2069
2115
|
"PATCH",
|
|
2070
|
-
this.bankUrl(`/
|
|
2116
|
+
this.bankUrl(`/pages/nodes/${encodeURIComponent(page.id)}`),
|
|
2071
2117
|
patch
|
|
2072
2118
|
);
|
|
2073
2119
|
if (r.status === 404) continue;
|
|
@@ -2096,7 +2142,7 @@ var HindsightClient = class _HindsightClient {
|
|
|
2096
2142
|
let pageId = args.relatesToPageId;
|
|
2097
2143
|
if (!pageId) {
|
|
2098
2144
|
const folderId = await this.ensureFolder("Initiatives");
|
|
2099
|
-
const r = await this.req("POST", this.bankUrl("/
|
|
2145
|
+
const r = await this.req("POST", this.bankUrl("/pages"), {
|
|
2100
2146
|
name: args.title,
|
|
2101
2147
|
source_query: `Summarize the "${args.title}" initiative: what is being built or changed and why, and its current state \u2014 drawn from the project's memory.` + pageScopeRule(this.project),
|
|
2102
2148
|
parent_id: folderId,
|
|
@@ -2124,7 +2170,7 @@ var HindsightClient = class _HindsightClient {
|
|
|
2124
2170
|
/** Find a root folder by name (case-insensitive) or create it; returns its id. Fail-open to undefined. */
|
|
2125
2171
|
async ensureFolder(name) {
|
|
2126
2172
|
try {
|
|
2127
|
-
const tree = await (await this.req("GET", this.bankUrl("/
|
|
2173
|
+
const tree = await (await this.req("GET", this.bankUrl("/pages/tree"))).json();
|
|
2128
2174
|
const hit = (tree.roots || []).find(
|
|
2129
2175
|
(n) => n.kind === "folder" && (n.name || "").toLowerCase() === name.toLowerCase()
|
|
2130
2176
|
);
|
|
@@ -2133,7 +2179,7 @@ var HindsightClient = class _HindsightClient {
|
|
|
2133
2179
|
if (error62 instanceof AccessDeniedError) throw error62;
|
|
2134
2180
|
}
|
|
2135
2181
|
try {
|
|
2136
|
-
const r = await this.req("POST", this.bankUrl("/
|
|
2182
|
+
const r = await this.req("POST", this.bankUrl("/pages/folders"), { name });
|
|
2137
2183
|
return (await r.json()).id;
|
|
2138
2184
|
} catch (error62) {
|
|
2139
2185
|
if (error62 instanceof AccessDeniedError) throw error62;
|
package/dist/kimi-hook.js
CHANGED
|
@@ -36,12 +36,10 @@ function requireBank(access, bank, operation) {
|
|
|
36
36
|
}
|
|
37
37
|
function classifyOperation(method, suffix) {
|
|
38
38
|
if (method === "POST" && ["/memories/recall", "/reflect"].includes(suffix)) return "read";
|
|
39
|
-
if (method === "GET" && /^\/(?:config|stats|tags|graph|documents|operations|memories|mental-models|
|
|
40
|
-
suffix
|
|
41
|
-
))
|
|
39
|
+
if (method === "GET" && /^\/(?:config|stats|tags|graph|documents|operations|memories|mental-models|pages)(?:\/[^/]+)*$/.test(suffix))
|
|
42
40
|
return "read";
|
|
43
41
|
if (method === "GET" && suffix === "") return "read";
|
|
44
|
-
if (["POST", "PUT", "PATCH", "DELETE"].includes(method) && /^(?:\/(?:config|import|memories|documents|mental-models|
|
|
42
|
+
if (["POST", "PUT", "PATCH", "DELETE"].includes(method) && /^(?:\/(?:config|import|memories|documents|mental-models|pages|consolidate|consolidation)(?:\/[^/]+)*)?$/.test(
|
|
45
43
|
suffix
|
|
46
44
|
))
|
|
47
45
|
return "write";
|
|
@@ -393,6 +391,54 @@ var RouterTransport = class {
|
|
|
393
391
|
// ../../coding-agents/human-session.ts
|
|
394
392
|
import { createHash as createHash2 } from "crypto";
|
|
395
393
|
import { createRequire } from "module";
|
|
394
|
+
|
|
395
|
+
// src/harness/names.ts
|
|
396
|
+
var HARNESS_NAMES = [
|
|
397
|
+
"opencode",
|
|
398
|
+
// opencode v2 (binary `opencode2`) — a ground-up rewrite of the plugin API, loaded from the
|
|
399
|
+
// package's root index.js (src/opencode2.ts). Like opencode it has NO hook binary.
|
|
400
|
+
"opencode2",
|
|
401
|
+
// Kilo CLI is an opencode fork loaded as a persistent plugin (src/kilo.ts), so like opencode it
|
|
402
|
+
// has NO hook binary — deliberately absent from HOOK_BINS below.
|
|
403
|
+
"kilo",
|
|
404
|
+
// Cline CLI loads dist/cline.js through its native plugin manager; file hooks cannot inject.
|
|
405
|
+
"cline-cli",
|
|
406
|
+
// DeepSeek Harness loads dist/dsh.js as a native Cordis plugin (src/dsh.ts). Its Claude Code /
|
|
407
|
+
// Codex hook bridges are optional packages, so there is no hook binary to install either.
|
|
408
|
+
"dsh",
|
|
409
|
+
// pi loads dist/pi.js as an extension (src/pi.ts), and Prime Agent — a fork of pi — loads
|
|
410
|
+
// dist/prime-agent.js the same way (src/prime-agent.ts). Neither has a hook binary.
|
|
411
|
+
"pi",
|
|
412
|
+
"prime-agent",
|
|
413
|
+
"claude-code",
|
|
414
|
+
"cursor-cli",
|
|
415
|
+
"codex",
|
|
416
|
+
"dcode",
|
|
417
|
+
"antigravity-cli",
|
|
418
|
+
"devin-cli",
|
|
419
|
+
"copilot-cli",
|
|
420
|
+
"grok-build",
|
|
421
|
+
"qwen-code",
|
|
422
|
+
// Factory Droid is a per-prompt HOOK host: the installer wires ~/.factory/hooks.json and the
|
|
423
|
+
// stdio MCP registration in ~/.factory/mcp.json (see src/installer.ts).
|
|
424
|
+
"factory-droid",
|
|
425
|
+
// ZCode is a per-prompt HOOK host too, registered in its own CLI config
|
|
426
|
+
// (~/.zcode/cli/config.json) under `hooks.events` — never the user's real Claude Code settings.
|
|
427
|
+
"zcode",
|
|
428
|
+
// TraeCode is a per-prompt HOOK host registered in ~/.trae-cn/hooks.json (see src/installer.ts).
|
|
429
|
+
"traecode",
|
|
430
|
+
"kimi-code",
|
|
431
|
+
// WorkBuddy is a per-prompt HOOK host too: the installer wires ~/.workbuddy/settings.json and
|
|
432
|
+
// the stdio MCP registration in ~/.workbuddy/mcp.json (see src/installer.ts).
|
|
433
|
+
"workbuddy",
|
|
434
|
+
// CodeBuddy Code is the SAME @genie/agent-cli HOOK host, one product config apart (WorkBuddy only
|
|
435
|
+
// renames the home folder): the installer wires ~/.codebuddy/settings.json and the stdio MCP
|
|
436
|
+
// registration in CodeBuddy's priority-chained MCP file (see src/installer.ts). The CLI
|
|
437
|
+
// writes WorkBuddy's transcript format; the CodeBuddy IDE has a reader of its own.
|
|
438
|
+
"codebuddy"
|
|
439
|
+
];
|
|
440
|
+
|
|
441
|
+
// ../../coding-agents/human-session.ts
|
|
396
442
|
var HUMAN_TOKEN_PATTERN = /^mrh_[0-9a-f]{32}_[0-9a-f]{64}$/;
|
|
397
443
|
var HumanLoginRequiredError = class extends AccessDeniedError {
|
|
398
444
|
constructor() {
|
|
@@ -418,14 +464,14 @@ function humanRouterUrl(value) {
|
|
|
418
464
|
if (url.search || url.hash) throw new HumanLoginRequiredError();
|
|
419
465
|
return canonical2;
|
|
420
466
|
}
|
|
421
|
-
function secureEntry(routerUrl, credentialRef) {
|
|
467
|
+
function secureEntry(routerUrl, credentialRef, harness) {
|
|
422
468
|
try {
|
|
423
|
-
if (!["darwin", "win32", "linux"].includes(process.platform) || !/^[A-Za-z0-9._-]{1,64}$/.test(credentialRef)) {
|
|
469
|
+
if (!["darwin", "win32", "linux"].includes(process.platform) || !/^[A-Za-z0-9._-]{1,64}$/.test(credentialRef) || !HARNESS_NAMES.includes(harness)) {
|
|
424
470
|
throw new HumanLoginRequiredError();
|
|
425
471
|
}
|
|
426
472
|
const { Entry: NativeEntry } = createRequire(import.meta.url)("@napi-rs/keyring");
|
|
427
|
-
const service = `hindsight-memory-router:${createHash2("sha256").update(humanRouterUrl(routerUrl)).digest("hex")}`;
|
|
428
|
-
return new NativeEntry(service, credentialRef
|
|
473
|
+
const service = `hindsight-memory-router:human-v2:${createHash2("sha256").update(humanRouterUrl(routerUrl)).digest("hex")}`;
|
|
474
|
+
return new NativeEntry(service, `${harness}:${credentialRef}`, { linux: { store: "secret-service" } });
|
|
429
475
|
} catch {
|
|
430
476
|
throw new HumanLoginRequiredError();
|
|
431
477
|
}
|
|
@@ -443,9 +489,9 @@ function validateHumanSession(value, routerUrl, allowExpired = false) {
|
|
|
443
489
|
routerUrl: session.routerUrl
|
|
444
490
|
};
|
|
445
491
|
}
|
|
446
|
-
function readHumanSession(routerUrl, credentialRef) {
|
|
492
|
+
function readHumanSession(routerUrl, credentialRef, harness) {
|
|
447
493
|
try {
|
|
448
|
-
const password = secureEntry(routerUrl, credentialRef).getPassword();
|
|
494
|
+
const password = secureEntry(routerUrl, credentialRef, harness).getPassword();
|
|
449
495
|
if (!password || password.length > 4096) throw new HumanLoginRequiredError();
|
|
450
496
|
return validateHumanSession(JSON.parse(password), routerUrl);
|
|
451
497
|
} catch {
|
|
@@ -457,11 +503,11 @@ function readHumanSession(routerUrl, credentialRef) {
|
|
|
457
503
|
function harnessTransport(harness) {
|
|
458
504
|
return transportForConfig(harness, loadManagedConfig(process.env, harness));
|
|
459
505
|
}
|
|
460
|
-
function transportForConfig(harness, { config: config2, principal }) {
|
|
506
|
+
function transportForConfig(harness, { config: config2, principal, principalId }) {
|
|
461
507
|
if (principal.human) {
|
|
462
508
|
const routerUrl = humanRouterUrl(config2.routerUrl);
|
|
463
509
|
const reference = principal.human.credentialRef;
|
|
464
|
-
let session = readHumanSession(routerUrl, reference);
|
|
510
|
+
let session = readHumanSession(routerUrl, reference, principalId);
|
|
465
511
|
return new RouterTransport({
|
|
466
512
|
routerUrl,
|
|
467
513
|
access: principal,
|
|
@@ -469,7 +515,7 @@ function transportForConfig(harness, { config: config2, principal }) {
|
|
|
469
515
|
tokenPattern: HUMAN_TOKEN_PATTERN,
|
|
470
516
|
unauthorizedError: () => new HumanLoginRequiredError(),
|
|
471
517
|
token: () => {
|
|
472
|
-
session = readHumanSession(routerUrl, reference);
|
|
518
|
+
session = readHumanSession(routerUrl, reference, principalId);
|
|
473
519
|
return session.token;
|
|
474
520
|
}
|
|
475
521
|
});
|
|
@@ -1277,7 +1323,7 @@ var PLUGIN_GOVERNED_BANK_FIELDS = [
|
|
|
1277
1323
|
];
|
|
1278
1324
|
|
|
1279
1325
|
// package.json
|
|
1280
|
-
var version = "0.8.
|
|
1326
|
+
var version = "0.8.14";
|
|
1281
1327
|
|
|
1282
1328
|
// src/core/util.ts
|
|
1283
1329
|
import { accessSync, constants } from "fs";
|
|
@@ -1791,7 +1837,7 @@ var HindsightClient = class _HindsightClient {
|
|
|
1791
1837
|
*/
|
|
1792
1838
|
async tree() {
|
|
1793
1839
|
if (this.knowledgePagesSupported === false) throw new KnowledgePagesUnavailableError();
|
|
1794
|
-
const r = await this.req("GET", this.bankUrl("/
|
|
1840
|
+
const r = await this.req("GET", this.bankUrl("/pages/tree"));
|
|
1795
1841
|
if (await this.pagesUnsupported(r)) throw new KnowledgePagesUnavailableError();
|
|
1796
1842
|
if (r.status === 404) return [];
|
|
1797
1843
|
this.knowledgePagesSupported = true;
|
|
@@ -1839,7 +1885,7 @@ var HindsightClient = class _HindsightClient {
|
|
|
1839
1885
|
if (this.knowledgePagesSupported === false) throw new KnowledgePagesUnavailableError();
|
|
1840
1886
|
const r = await this.req(
|
|
1841
1887
|
"GET",
|
|
1842
|
-
this.bankUrl(`/
|
|
1888
|
+
this.bankUrl(`/pages/${encodeURIComponent(pageId)}`)
|
|
1843
1889
|
);
|
|
1844
1890
|
if (r.status === 404) throw new Error(`knowledge page not found: ${pageId}`);
|
|
1845
1891
|
return shapePage(await r.json());
|
|
@@ -1852,7 +1898,7 @@ var HindsightClient = class _HindsightClient {
|
|
|
1852
1898
|
const q = `?q=${encodeURIComponent(query)}&limit=${opts.limit ?? this.pageSearchLimit}`;
|
|
1853
1899
|
const r = await this.req(
|
|
1854
1900
|
"GET",
|
|
1855
|
-
this.bankUrl(`/
|
|
1901
|
+
this.bankUrl(`/pages/search${q}`),
|
|
1856
1902
|
void 0,
|
|
1857
1903
|
[],
|
|
1858
1904
|
opts.timeoutMs
|
|
@@ -1871,7 +1917,7 @@ var HindsightClient = class _HindsightClient {
|
|
|
1871
1917
|
/**
|
|
1872
1918
|
* Seed the fixed page taxonomy as knowledge-base pages at the tree root, idempotently.
|
|
1873
1919
|
*
|
|
1874
|
-
* Matched by NAME, not id: `/
|
|
1920
|
+
* Matched by NAME, not id: `/pages` mints its own `kp-…` id, so a stable
|
|
1875
1921
|
* client-chosen id isn't available to match on (unlike the old mental-model path, which keyed
|
|
1876
1922
|
* off a slug). Names are unique per folder server-side, which makes them a sound key.
|
|
1877
1923
|
*
|
|
@@ -1910,7 +1956,7 @@ var HindsightClient = class _HindsightClient {
|
|
|
1910
1956
|
trigger: pageTriggerFor(pageTrigger, this.bank, page.name)
|
|
1911
1957
|
};
|
|
1912
1958
|
if (!hit) {
|
|
1913
|
-
const r = await this.req("POST", this.bankUrl("/
|
|
1959
|
+
const r = await this.req("POST", this.bankUrl("/pages"), body, [409]);
|
|
1914
1960
|
if (await this.pagesUnsupported(r)) {
|
|
1915
1961
|
this.log(
|
|
1916
1962
|
`[bank] knowledge pages unavailable on ${this.apiUrl}; continuing without pages`
|
|
@@ -1937,7 +1983,7 @@ var HindsightClient = class _HindsightClient {
|
|
|
1937
1983
|
if (triggerDrift) patch.trigger = pageTriggerPatch(body.trigger);
|
|
1938
1984
|
const r = await this.req(
|
|
1939
1985
|
"PATCH",
|
|
1940
|
-
this.bankUrl(`/
|
|
1986
|
+
this.bankUrl(`/pages/nodes/${encodeURIComponent(hit.id)}`),
|
|
1941
1987
|
patch
|
|
1942
1988
|
);
|
|
1943
1989
|
if (await this.pagesUnsupported(r)) {
|
|
@@ -1991,7 +2037,7 @@ var HindsightClient = class _HindsightClient {
|
|
|
1991
2037
|
if (!patch.trigger && !patch.source_query) continue;
|
|
1992
2038
|
const r = await this.req(
|
|
1993
2039
|
"PATCH",
|
|
1994
|
-
this.bankUrl(`/
|
|
2040
|
+
this.bankUrl(`/pages/nodes/${encodeURIComponent(page.id)}`),
|
|
1995
2041
|
patch
|
|
1996
2042
|
);
|
|
1997
2043
|
if (r.status === 404) continue;
|
|
@@ -2020,7 +2066,7 @@ var HindsightClient = class _HindsightClient {
|
|
|
2020
2066
|
let pageId = args.relatesToPageId;
|
|
2021
2067
|
if (!pageId) {
|
|
2022
2068
|
const folderId = await this.ensureFolder("Initiatives");
|
|
2023
|
-
const r = await this.req("POST", this.bankUrl("/
|
|
2069
|
+
const r = await this.req("POST", this.bankUrl("/pages"), {
|
|
2024
2070
|
name: args.title,
|
|
2025
2071
|
source_query: `Summarize the "${args.title}" initiative: what is being built or changed and why, and its current state \u2014 drawn from the project's memory.` + pageScopeRule(this.project),
|
|
2026
2072
|
parent_id: folderId,
|
|
@@ -2048,7 +2094,7 @@ var HindsightClient = class _HindsightClient {
|
|
|
2048
2094
|
/** Find a root folder by name (case-insensitive) or create it; returns its id. Fail-open to undefined. */
|
|
2049
2095
|
async ensureFolder(name) {
|
|
2050
2096
|
try {
|
|
2051
|
-
const tree = await (await this.req("GET", this.bankUrl("/
|
|
2097
|
+
const tree = await (await this.req("GET", this.bankUrl("/pages/tree"))).json();
|
|
2052
2098
|
const hit = (tree.roots || []).find(
|
|
2053
2099
|
(n) => n.kind === "folder" && (n.name || "").toLowerCase() === name.toLowerCase()
|
|
2054
2100
|
);
|
|
@@ -2057,7 +2103,7 @@ var HindsightClient = class _HindsightClient {
|
|
|
2057
2103
|
if (error instanceof AccessDeniedError) throw error;
|
|
2058
2104
|
}
|
|
2059
2105
|
try {
|
|
2060
|
-
const r = await this.req("POST", this.bankUrl("/
|
|
2106
|
+
const r = await this.req("POST", this.bankUrl("/pages/folders"), { name });
|
|
2061
2107
|
return (await r.json()).id;
|
|
2062
2108
|
} catch (error) {
|
|
2063
2109
|
if (error instanceof AccessDeniedError) throw error;
|