@rynfar/meridian 1.63.0 → 1.65.0
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/README.md +3 -2
- package/dist/{cli-hdyptm7z.js → cli-7cts44b5.js} +15672 -4267
- package/dist/cli-n8t34zmq.js +939 -0
- package/dist/{cli-m0p2bc8v.js → cli-pdpry6q0.js} +16 -3
- package/dist/cli.js +72 -13
- package/dist/meridian-v2.js +347 -0
- package/dist/{profileCli-39vshwdn.js → profileCli-ap7eg985.js} +2 -2
- package/dist/{profiles-0pyeqayw.js → profiles-4ajzjqhm.js} +1 -1
- package/dist/proxy/adapter.d.ts +16 -0
- package/dist/proxy/adapter.d.ts.map +1 -1
- package/dist/proxy/adapters/opencode.d.ts.map +1 -1
- package/dist/proxy/errors.d.ts.map +1 -1
- package/dist/proxy/passthroughTools.d.ts.map +1 -1
- package/dist/proxy/priorityAttestation.d.ts +35 -0
- package/dist/proxy/priorityAttestation.d.ts.map +1 -0
- package/dist/proxy/routing.d.ts +16 -2
- package/dist/proxy/routing.d.ts.map +1 -1
- package/dist/proxy/server.d.ts.map +1 -1
- package/dist/proxy/session/cache.d.ts +25 -2
- package/dist/proxy/session/cache.d.ts.map +1 -1
- package/dist/proxy/session/lineage.d.ts +1 -1
- package/dist/proxy/session/lineage.d.ts.map +1 -1
- package/dist/proxy/session/turnCoordinator.d.ts +2 -0
- package/dist/proxy/session/turnCoordinator.d.ts.map +1 -1
- package/dist/proxy/sessionStore.d.ts +133 -0
- package/dist/proxy/sessionStore.d.ts.map +1 -1
- package/dist/proxy/settings.d.ts +2 -0
- package/dist/proxy/settings.d.ts.map +1 -1
- package/dist/proxy/setup.d.ts +35 -10
- package/dist/proxy/setup.d.ts.map +1 -1
- package/dist/server.js +5 -5
- package/dist/setup-8fwgwhqh.js +33 -0
- package/package.json +9 -5
- package/plugin/meridian-v2.ts +335 -0
- package/plugin/meridian.ts +125 -20
- package/plugin/priority-attestation.ts +150 -0
- package/dist/cli-pc0mtjjv.js +0 -167
- package/dist/setup-0x573t61.js +0 -19
- package/dist/{cli-xfbhn15a.js → cli-0ed6j0vk.js} +3 -3
|
@@ -18,6 +18,12 @@ function getRoutingMode(raw) {
|
|
|
18
18
|
return "priority";
|
|
19
19
|
return "active";
|
|
20
20
|
}
|
|
21
|
+
function getPriorityFailbackPolicy(raw) {
|
|
22
|
+
return raw?.toLowerCase() === "next-user-turn" ? "next-user-turn" : "new-conversation";
|
|
23
|
+
}
|
|
24
|
+
function shouldPromotePriorityAssignment(input) {
|
|
25
|
+
return input.policy === "next-user-turn" && input.requestKind === "human" && input.requestId !== undefined && input.requestId !== input.assignment.requestId;
|
|
26
|
+
}
|
|
21
27
|
function rendezvousScore(sessionKey, profileId) {
|
|
22
28
|
const digest = createHash("sha256").update(`${sessionKey}\x00${profileId}`).digest();
|
|
23
29
|
return digest.readBigUInt64BE(0);
|
|
@@ -54,13 +60,14 @@ function resolvePriorityOrder(configuredIds, orderSetting) {
|
|
|
54
60
|
return { order, unknown };
|
|
55
61
|
}
|
|
56
62
|
function choosePriorityProfile(order, isExhausted) {
|
|
57
|
-
|
|
63
|
+
const preferred = order[0];
|
|
64
|
+
if (preferred === undefined)
|
|
58
65
|
return;
|
|
59
66
|
for (const id of order) {
|
|
60
67
|
if (!isExhausted(id))
|
|
61
68
|
return { id, allExhausted: false };
|
|
62
69
|
}
|
|
63
|
-
return { id:
|
|
70
|
+
return { id: preferred, allExhausted: true };
|
|
64
71
|
}
|
|
65
72
|
|
|
66
73
|
class ProfileExhaustion {
|
|
@@ -121,6 +128,12 @@ class AssignmentStore {
|
|
|
121
128
|
this.entries.delete(oldest);
|
|
122
129
|
}
|
|
123
130
|
}
|
|
131
|
+
compareAndSet(key, expected, value) {
|
|
132
|
+
if (this.entries.get(key) !== expected)
|
|
133
|
+
return false;
|
|
134
|
+
this.set(key, value);
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
124
137
|
get size() {
|
|
125
138
|
return this.entries.size;
|
|
126
139
|
}
|
|
@@ -258,4 +271,4 @@ function listProfiles(profiles, defaultProfile) {
|
|
|
258
271
|
}));
|
|
259
272
|
}
|
|
260
273
|
|
|
261
|
-
export { getRoutingMode, resolvePriorityOrder, choosePriorityProfile, ProfileExhaustion, AssignmentStore, resolveCooldownUntil, loadProfilesFromDisk, setActiveProfile, getActiveProfileId, resetActiveProfile, restoreActiveProfile, enableDiskProfileDiscovery, getEffectiveProfiles, hasProfiles, resolveProfile, listProfiles };
|
|
274
|
+
export { getRoutingMode, getPriorityFailbackPolicy, shouldPromotePriorityAssignment, resolvePriorityOrder, choosePriorityProfile, ProfileExhaustion, AssignmentStore, resolveCooldownUntil, loadProfilesFromDisk, setActiveProfile, getActiveProfileId, resetActiveProfile, restoreActiveProfile, enableDiskProfileDiscovery, getEffectiveProfiles, hasProfiles, resolveProfile, listProfiles };
|
package/dist/cli.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
startProxyServer
|
|
4
|
-
} from "./cli-
|
|
5
|
-
import"./cli-
|
|
4
|
+
} from "./cli-7cts44b5.js";
|
|
5
|
+
import"./cli-pdpry6q0.js";
|
|
6
6
|
import"./cli-sry5aqdj.js";
|
|
7
7
|
import"./cli-8yp89fan.js";
|
|
8
8
|
import {
|
|
9
9
|
resolveClaudeExecutableAsync
|
|
10
|
-
} from "./cli-
|
|
11
|
-
import"./cli-vj9cv18n.js";
|
|
12
|
-
import"./cli-pc0mtjjv.js";
|
|
10
|
+
} from "./cli-0ed6j0vk.js";
|
|
13
11
|
import"./cli-khhjyk04.js";
|
|
12
|
+
import"./cli-vj9cv18n.js";
|
|
13
|
+
import"./cli-n8t34zmq.js";
|
|
14
14
|
import {
|
|
15
15
|
__require
|
|
16
16
|
} from "./cli-p9swy5t3.js";
|
|
@@ -39,6 +39,11 @@ Commands:
|
|
|
39
39
|
profile Manage Claude account profiles (add, list, switch, remove)
|
|
40
40
|
refresh-token Refresh the Claude Code OAuth token
|
|
41
41
|
|
|
42
|
+
Setup options:
|
|
43
|
+
--v1 Install the OpenCode V1 plugin
|
|
44
|
+
--v2 Install the pinned OpenCode V2 beta plugin
|
|
45
|
+
--opencode-bin <executable> Probe this OpenCode executable
|
|
46
|
+
|
|
42
47
|
Options:
|
|
43
48
|
-v, --version Show version
|
|
44
49
|
-h, --help Show this help
|
|
@@ -55,7 +60,7 @@ See https://github.com/rynfar/meridian for full documentation.`);
|
|
|
55
60
|
process.exit(0);
|
|
56
61
|
}
|
|
57
62
|
if (args[0] === "profile") {
|
|
58
|
-
const { profileAdd, profileAddOauthToken, profileList, profileRemove, profileSwitch, profileLogin, profileHelp } = await import("./profileCli-
|
|
63
|
+
const { profileAdd, profileAddOauthToken, profileList, profileRemove, profileSwitch, profileLogin, profileHelp } = await import("./profileCli-ap7eg985.js");
|
|
59
64
|
const subcommand = args[1];
|
|
60
65
|
const profileId = args[2];
|
|
61
66
|
const headless = args.includes("--headless");
|
|
@@ -80,11 +85,57 @@ if (args[0] === "profile") {
|
|
|
80
85
|
process.exit(0);
|
|
81
86
|
}
|
|
82
87
|
if (args[0] === "setup") {
|
|
83
|
-
const {
|
|
84
|
-
|
|
88
|
+
const {
|
|
89
|
+
detectOpenCodeGeneration,
|
|
90
|
+
DuplicateMeridianConfigError,
|
|
91
|
+
MissingV2PluginError,
|
|
92
|
+
pluginPathForGeneration,
|
|
93
|
+
runSetup,
|
|
94
|
+
SUPPORTED_OPENCODE_V2_VERSION,
|
|
95
|
+
UnparseableConfigError
|
|
96
|
+
} = await import("./setup-8fwgwhqh.js");
|
|
97
|
+
const forceV1 = args.includes("--v1");
|
|
98
|
+
const forceV2 = args.includes("--v2");
|
|
99
|
+
if (forceV1 && forceV2) {
|
|
100
|
+
console.error("Choose only one OpenCode generation: --v1 or --v2");
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
const binaryIndex = args.indexOf("--opencode-bin");
|
|
104
|
+
const binary = binaryIndex >= 0 ? args[binaryIndex + 1] : undefined;
|
|
105
|
+
if (binaryIndex >= 0 && (!binary || binary.startsWith("--"))) {
|
|
106
|
+
console.error("--opencode-bin requires an executable path");
|
|
107
|
+
process.exit(1);
|
|
108
|
+
}
|
|
109
|
+
const environmentBinary = process.env.OPENCODE_BIN;
|
|
110
|
+
const commands = binary ? [binary] : environmentBinary ? [environmentBinary] : forceV2 ? ["opencode2", "opencode"] : undefined;
|
|
111
|
+
const detected = forceV1 ? { generation: "v1" } : detectOpenCodeGeneration(commands);
|
|
112
|
+
if (!forceV1 && (binary || environmentBinary) && !detected.version) {
|
|
113
|
+
console.error(`Could not read a supported OpenCode version from ${binary ?? environmentBinary}.`);
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
if (forceV2 && detected.generation !== "v2") {
|
|
117
|
+
console.error("Could not find an OpenCode V2 beta. Install the pinned beta or pass --opencode-bin <path>.");
|
|
118
|
+
process.exit(1);
|
|
119
|
+
}
|
|
120
|
+
if (detected.generation === "v2" && detected.version !== SUPPORTED_OPENCODE_V2_VERSION) {
|
|
121
|
+
console.error(`OpenCode V2 ${detected.version ?? "unknown"} is not supported by this Meridian build.`);
|
|
122
|
+
console.error(`Install @opencode-ai/cli@${SUPPORTED_OPENCODE_V2_VERSION}, then re-run meridian setup --v2.`);
|
|
123
|
+
process.exit(1);
|
|
124
|
+
}
|
|
125
|
+
let pluginPath;
|
|
126
|
+
try {
|
|
127
|
+
pluginPath = pluginPathForGeneration(import.meta.url, detected.generation);
|
|
128
|
+
} catch (err) {
|
|
129
|
+
if (err instanceof MissingV2PluginError) {
|
|
130
|
+
console.error(`OpenCode V2 plugin bundle is missing: ${err.expectedPath}`);
|
|
131
|
+
console.error("Reinstall Meridian, then re-run meridian setup --v2.");
|
|
132
|
+
process.exit(1);
|
|
133
|
+
}
|
|
134
|
+
throw err;
|
|
135
|
+
}
|
|
85
136
|
let result;
|
|
86
137
|
try {
|
|
87
|
-
result = runSetup(pluginPath);
|
|
138
|
+
result = runSetup(pluginPath, undefined, detected.generation);
|
|
88
139
|
} catch (err) {
|
|
89
140
|
if (err instanceof UnparseableConfigError) {
|
|
90
141
|
console.error(`\x1B[31m✗ Could not parse ${err.configPath}\x1B[0m`);
|
|
@@ -93,16 +144,24 @@ if (args[0] === "setup") {
|
|
|
93
144
|
console.error(` "plugin": ["${pluginPath}"]`);
|
|
94
145
|
process.exit(1);
|
|
95
146
|
}
|
|
147
|
+
if (err instanceof DuplicateMeridianConfigError) {
|
|
148
|
+
console.error("\x1B[31m✗ Meridian is already present in the other OpenCode config file\x1B[0m");
|
|
149
|
+
console.error(` OpenCode loads both ${err.configPath} and ${err.siblingPath}.`);
|
|
150
|
+
console.error(` Remove the Meridian entry from ${err.siblingPath}, then re-run 'meridian setup'.`);
|
|
151
|
+
console.error(" Both files were left untouched.");
|
|
152
|
+
process.exit(1);
|
|
153
|
+
}
|
|
96
154
|
throw err;
|
|
97
155
|
}
|
|
156
|
+
const generationLabel = detected.generation === "v2" ? "OpenCode V2" : "OpenCode V1";
|
|
98
157
|
if (result.alreadyConfigured) {
|
|
99
|
-
console.log(`\x1B[32m✓ Meridian plugin already configured\x1B[0m`);
|
|
158
|
+
console.log(`\x1B[32m✓ Meridian plugin already configured for ${generationLabel}\x1B[0m`);
|
|
100
159
|
console.log(` ${result.configPath}`);
|
|
101
160
|
} else {
|
|
102
161
|
if (result.removedStale.length > 0) {
|
|
103
162
|
console.log(` Removed ${result.removedStale.length} stale plugin entr${result.removedStale.length === 1 ? "y" : "ies"}`);
|
|
104
163
|
}
|
|
105
|
-
console.log(`\x1B[32m✓ Meridian plugin configured\x1B[0m`);
|
|
164
|
+
console.log(`\x1B[32m✓ Meridian plugin configured for ${generationLabel}\x1B[0m`);
|
|
106
165
|
console.log(` Config: ${result.configPath}`);
|
|
107
166
|
console.log(` Plugin: ${result.pluginPath}`);
|
|
108
167
|
if (!result.created) {
|
|
@@ -146,7 +205,7 @@ async function runCli(start = startProxyServer, runAuthCheck = async () => {
|
|
|
146
205
|
return execFile(claudePath, ["auth", "status"], { timeout: 5000 });
|
|
147
206
|
}) {
|
|
148
207
|
try {
|
|
149
|
-
const { findOpencodeConfigPath, checkPluginConfigured, findPluginPath } = await import("./setup-
|
|
208
|
+
const { findOpencodeConfigPath, checkPluginConfigured, findPluginPath } = await import("./setup-8fwgwhqh.js");
|
|
150
209
|
const configPath = findOpencodeConfigPath();
|
|
151
210
|
const { existsSync } = await import("fs");
|
|
152
211
|
if (existsSync(configPath) && !checkPluginConfigured(configPath)) {
|
|
@@ -171,7 +230,7 @@ async function runCli(start = startProxyServer, runAuthCheck = async () => {
|
|
|
171
230
|
console.error("\x1B[33m⚠ Could not verify Claude auth status. If requests fail, run: claude login\x1B[0m");
|
|
172
231
|
}
|
|
173
232
|
if (!profiles) {
|
|
174
|
-
const { enableDiskProfileDiscovery } = await import("./profiles-
|
|
233
|
+
const { enableDiskProfileDiscovery } = await import("./profiles-4ajzjqhm.js");
|
|
175
234
|
enableDiskProfileDiscovery();
|
|
176
235
|
}
|
|
177
236
|
const proxy = await start({ port, host, idleTimeoutSeconds, pluginDir, pluginConfigPath, profiles, defaultProfile, version, installProcessErrorHandlers: true });
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
import"./cli-p9swy5t3.js";
|
|
2
|
+
|
|
3
|
+
// node_modules/@opencode-ai/plugin/dist/promise/plugin.js
|
|
4
|
+
function define(plugin) {
|
|
5
|
+
return plugin;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// plugin/priority-attestation.ts
|
|
9
|
+
import { createHash, createHmac } from "node:crypto";
|
|
10
|
+
import { readFileSync } from "node:fs";
|
|
11
|
+
import { homedir } from "node:os";
|
|
12
|
+
import { join } from "node:path";
|
|
13
|
+
var PRIORITY_ATTESTATION_HEADER = "x-meridian-opencode-turn";
|
|
14
|
+
var PRIORITY_ATTESTATION_KEY_ENV = "MERIDIAN_OPENCODE_ATTESTATION_KEY";
|
|
15
|
+
var PRIORITY_ATTESTATION_KEY_FILE = "opencode-turn.key";
|
|
16
|
+
var TOKEN_PREFIX = "v1";
|
|
17
|
+
var MAC_DOMAIN = "meridian.opencode.turn.v1\x00";
|
|
18
|
+
var TURN_DOMAIN = "meridian.opencode.human.v1\x00";
|
|
19
|
+
var MAX_HEADER_BYTES = 768;
|
|
20
|
+
var MAX_PAYLOAD_BYTES = 384;
|
|
21
|
+
var TURN_DIGEST_PATTERN = /^[A-Za-z0-9_-]{43}$/;
|
|
22
|
+
var SAFE_ID_PATTERN = /^[A-Za-z0-9._:-]{1,128}$/;
|
|
23
|
+
function configDirectory() {
|
|
24
|
+
return process.env.MERIDIAN_CONFIG_DIR ?? join(homedir(), ".config", "meridian");
|
|
25
|
+
}
|
|
26
|
+
function priorityAttestationKeyPath() {
|
|
27
|
+
return join(configDirectory(), PRIORITY_ATTESTATION_KEY_FILE);
|
|
28
|
+
}
|
|
29
|
+
function isSafeAgentId(value) {
|
|
30
|
+
return value.length >= 1 && value.length <= 64 && value.trim() === value && /^[\x20-\x7E]+$/.test(value);
|
|
31
|
+
}
|
|
32
|
+
function decodeCanonicalBase64Url(raw) {
|
|
33
|
+
if (!/^[A-Za-z0-9_-]+$/.test(raw))
|
|
34
|
+
return;
|
|
35
|
+
const decoded = Buffer.from(raw, "base64url");
|
|
36
|
+
return decoded.toString("base64url") === raw ? decoded : undefined;
|
|
37
|
+
}
|
|
38
|
+
function decodePriorityAttestationKey(raw) {
|
|
39
|
+
if (raw === undefined)
|
|
40
|
+
return;
|
|
41
|
+
const normalized = raw.trim();
|
|
42
|
+
const decoded = decodeCanonicalBase64Url(normalized);
|
|
43
|
+
return decoded?.length === 32 ? decoded : undefined;
|
|
44
|
+
}
|
|
45
|
+
function loadPriorityAttestationKey() {
|
|
46
|
+
const fromEnv = process.env[PRIORITY_ATTESTATION_KEY_ENV];
|
|
47
|
+
if (fromEnv !== undefined)
|
|
48
|
+
return decodePriorityAttestationKey(fromEnv);
|
|
49
|
+
try {
|
|
50
|
+
return decodePriorityAttestationKey(readFileSync(priorityAttestationKeyPath(), "utf8"));
|
|
51
|
+
} catch {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function computePriorityTurnDigest(input) {
|
|
56
|
+
if (!SAFE_ID_PATTERN.test(input.sessionId) || !SAFE_ID_PATTERN.test(input.humanMessageId)) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
return createHash("sha256").update(TURN_DOMAIN).update(input.generation).update("\x00").update(input.sessionId).update("\x00").update(input.humanMessageId).digest("base64url");
|
|
60
|
+
}
|
|
61
|
+
function createPriorityAttestation(input, key = loadPriorityAttestationKey() ?? Buffer.alloc(0)) {
|
|
62
|
+
if (key.length !== 32)
|
|
63
|
+
return;
|
|
64
|
+
if (!SAFE_ID_PATTERN.test(input.sessionId) || !isSafeAgentId(input.agentId))
|
|
65
|
+
return;
|
|
66
|
+
const turnDigest = computePriorityTurnDigest(input);
|
|
67
|
+
if (!turnDigest || !TURN_DIGEST_PATTERN.test(turnDigest))
|
|
68
|
+
return;
|
|
69
|
+
const issuedAt = input.issuedAt;
|
|
70
|
+
if (!Number.isSafeInteger(issuedAt) || issuedAt < 0)
|
|
71
|
+
return;
|
|
72
|
+
const payload = JSON.stringify({
|
|
73
|
+
v: 1,
|
|
74
|
+
g: input.generation,
|
|
75
|
+
s: input.sessionId,
|
|
76
|
+
a: input.agentId,
|
|
77
|
+
t: turnDigest,
|
|
78
|
+
iat: issuedAt
|
|
79
|
+
});
|
|
80
|
+
if (Buffer.byteLength(payload) > MAX_PAYLOAD_BYTES)
|
|
81
|
+
return;
|
|
82
|
+
const encodedPayload = Buffer.from(payload).toString("base64url");
|
|
83
|
+
const mac = createHmac("sha256", key).update(MAC_DOMAIN).update(payload).digest("base64url");
|
|
84
|
+
const token = `${TOKEN_PREFIX}.${encodedPayload}.${mac}`;
|
|
85
|
+
return Buffer.byteLength(token) <= MAX_HEADER_BYTES ? token : undefined;
|
|
86
|
+
}
|
|
87
|
+
function deleteHeader(headers, name) {
|
|
88
|
+
if (headers instanceof Headers) {
|
|
89
|
+
headers.delete(name);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const lower = name.toLowerCase();
|
|
93
|
+
for (const key of Object.keys(headers)) {
|
|
94
|
+
if (key.toLowerCase() === lower)
|
|
95
|
+
delete headers[key];
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function getHeader(headers, name) {
|
|
99
|
+
if (headers instanceof Headers)
|
|
100
|
+
return headers.get(name) ?? undefined;
|
|
101
|
+
const lower = name.toLowerCase();
|
|
102
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
103
|
+
if (key.toLowerCase() === lower)
|
|
104
|
+
return value;
|
|
105
|
+
}
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
function setHeader(headers, name, value) {
|
|
109
|
+
deleteHeader(headers, name);
|
|
110
|
+
if (headers instanceof Headers)
|
|
111
|
+
headers.set(name, value);
|
|
112
|
+
else
|
|
113
|
+
headers[name] = value;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// plugin/meridian-v2.ts
|
|
117
|
+
var SUPPORTED_OPENCODE_V2_VERSION = "0.0.0-beta-18314";
|
|
118
|
+
var MERIDIAN_PROVIDERS = new Set(["anthropic", "meridian"]);
|
|
119
|
+
var PARENT_SESSION_ONE_SHOTS = new Set(["title", "summary"]);
|
|
120
|
+
var ATTACHED_COMPACTION_AGENT = "compaction";
|
|
121
|
+
var SESSION_AFFINITY_HEADERS = [
|
|
122
|
+
"x-opencode-session",
|
|
123
|
+
"x-session-affinity",
|
|
124
|
+
"x-session-id",
|
|
125
|
+
"x-parent-session-id"
|
|
126
|
+
];
|
|
127
|
+
var MERIDIAN_CONTROL_HEADERS = [
|
|
128
|
+
"x-meridian-source",
|
|
129
|
+
"x-opencode-agent-name",
|
|
130
|
+
"x-opencode-agent-mode",
|
|
131
|
+
PRIORITY_ATTESTATION_HEADER
|
|
132
|
+
];
|
|
133
|
+
var BUILTIN_AGENT_TRAITS = {
|
|
134
|
+
build: { mode: "primary", hidden: false },
|
|
135
|
+
plan: { mode: "primary", hidden: false },
|
|
136
|
+
general: { mode: "subagent", hidden: false },
|
|
137
|
+
explore: { mode: "subagent", hidden: false },
|
|
138
|
+
title: { mode: "primary", hidden: true },
|
|
139
|
+
summary: { mode: "primary", hidden: true },
|
|
140
|
+
compaction: { mode: "primary", hidden: true }
|
|
141
|
+
};
|
|
142
|
+
function fallbackAgentTraits(agent) {
|
|
143
|
+
return BUILTIN_AGENT_TRAITS[agent] ?? { mode: "primary", hidden: false };
|
|
144
|
+
}
|
|
145
|
+
function safeAgentName(agent) {
|
|
146
|
+
return agent.replace(/[^\x20-\x7E]/g, "").trim() || "unknown";
|
|
147
|
+
}
|
|
148
|
+
function shouldDetachFromParentSession(agent, _traits) {
|
|
149
|
+
return PARENT_SESSION_ONE_SHOTS.has(agent);
|
|
150
|
+
}
|
|
151
|
+
function applyMeridianV2Headers(headers, input) {
|
|
152
|
+
for (const name2 of SESSION_AFFINITY_HEADERS)
|
|
153
|
+
deleteHeader(headers, name2);
|
|
154
|
+
for (const name2 of MERIDIAN_CONTROL_HEADERS)
|
|
155
|
+
deleteHeader(headers, name2);
|
|
156
|
+
const name = safeAgentName(input.agent);
|
|
157
|
+
const detached = shouldDetachFromParentSession(input.agent, input.traits);
|
|
158
|
+
if (detached) {
|
|
159
|
+
setHeader(headers, "x-meridian-source", `subagent-${name}`);
|
|
160
|
+
} else {
|
|
161
|
+
setHeader(headers, "x-opencode-session", input.sessionID);
|
|
162
|
+
setHeader(headers, "x-session-affinity", input.sessionID);
|
|
163
|
+
setHeader(headers, "x-session-id", input.sessionID);
|
|
164
|
+
if (input.agent === ATTACHED_COMPACTION_AGENT) {
|
|
165
|
+
setHeader(headers, "x-meridian-source", "subagent-compaction");
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
const internalMode = PARENT_SESSION_ONE_SHOTS.has(input.agent) ? "subagent" : input.agent === ATTACHED_COMPACTION_AGENT ? "primary" : input.traits.mode;
|
|
169
|
+
setHeader(headers, "x-opencode-agent-name", name);
|
|
170
|
+
setHeader(headers, "x-opencode-agent-mode", internalMode);
|
|
171
|
+
}
|
|
172
|
+
var INTERNAL_ROUTING_AGENT_IDS = new Set(["title", "summary", "compaction"]);
|
|
173
|
+
var AGENT_CACHE_MAX = 256;
|
|
174
|
+
var AGENT_CACHE_TTL_MS = 5000;
|
|
175
|
+
var LOOKUP_TIMEOUT_MS = 250;
|
|
176
|
+
var MAX_CONTEXT_ENTRIES = 2048;
|
|
177
|
+
var SAFE_ID_PATTERN2 = /^[A-Za-z0-9._:-]{1,128}$/;
|
|
178
|
+
function isRecord(value) {
|
|
179
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
180
|
+
}
|
|
181
|
+
async function withTimeout(pending, timeoutMs) {
|
|
182
|
+
let timer;
|
|
183
|
+
const timedOut = new Promise((resolve) => {
|
|
184
|
+
timer = setTimeout(() => resolve(undefined), timeoutMs);
|
|
185
|
+
timer.unref?.();
|
|
186
|
+
});
|
|
187
|
+
try {
|
|
188
|
+
return await Promise.race([pending, timedOut]);
|
|
189
|
+
} finally {
|
|
190
|
+
if (timer)
|
|
191
|
+
clearTimeout(timer);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
function isRootV2Session(value, sessionID) {
|
|
195
|
+
return isRecord(value) && value.id === sessionID && value.parentID === undefined && value.fork === undefined;
|
|
196
|
+
}
|
|
197
|
+
function findLatestV2HumanTurn(value) {
|
|
198
|
+
if (!Array.isArray(value) || value.length === 0 || value.length > MAX_CONTEXT_ENTRIES)
|
|
199
|
+
return;
|
|
200
|
+
for (let index = value.length - 1;index >= 0; index -= 1) {
|
|
201
|
+
const message = value[index];
|
|
202
|
+
if (!isRecord(message) || typeof message.type !== "string")
|
|
203
|
+
return;
|
|
204
|
+
if (message.type === "assistant" || message.type === "agent-switched" || message.type === "model-switched" || message.type === "location-switched") {
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
if (message.type !== "user" || typeof message.id !== "string" || !SAFE_ID_PATTERN2.test(message.id)) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const time = isRecord(message.time) ? message.time : undefined;
|
|
211
|
+
const createdAt = time?.created;
|
|
212
|
+
if (typeof createdAt !== "number" || !Number.isSafeInteger(createdAt) || createdAt < 0)
|
|
213
|
+
return;
|
|
214
|
+
return { id: message.id, issuedAt: Math.floor(createdAt / 1000) };
|
|
215
|
+
}
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
function findLatestV2HumanMessageId(value) {
|
|
219
|
+
return findLatestV2HumanTurn(value)?.id;
|
|
220
|
+
}
|
|
221
|
+
var MeridianV2Plugin = define({
|
|
222
|
+
id: "meridian",
|
|
223
|
+
setup: async (context) => {
|
|
224
|
+
const traitsByAgent = new Map;
|
|
225
|
+
const registered = [];
|
|
226
|
+
const resolveAgentTraits = (agent, refresh = false) => {
|
|
227
|
+
const cached = traitsByAgent.get(agent);
|
|
228
|
+
if (!refresh && cached && cached.expiresAt > Date.now())
|
|
229
|
+
return cached.pending;
|
|
230
|
+
if (refresh)
|
|
231
|
+
traitsByAgent.delete(agent);
|
|
232
|
+
const request = Symbol(agent);
|
|
233
|
+
const pending = (async () => {
|
|
234
|
+
const controller = new AbortController;
|
|
235
|
+
try {
|
|
236
|
+
const result = await withTimeout(context.agent.get({ agentID: agent }, { signal: controller.signal }), LOOKUP_TIMEOUT_MS);
|
|
237
|
+
const data = result?.data;
|
|
238
|
+
if (!data || data.mode !== "primary" && data.mode !== "subagent" && data.mode !== "all" || typeof data.hidden !== "boolean") {
|
|
239
|
+
if (traitsByAgent.get(agent)?.request === request)
|
|
240
|
+
traitsByAgent.delete(agent);
|
|
241
|
+
return { traits: fallbackAgentTraits(agent), exactMode: undefined, authoritative: false };
|
|
242
|
+
}
|
|
243
|
+
return {
|
|
244
|
+
traits: {
|
|
245
|
+
mode: data.mode === "subagent" ? "subagent" : "primary",
|
|
246
|
+
hidden: data.hidden
|
|
247
|
+
},
|
|
248
|
+
exactMode: data.mode,
|
|
249
|
+
authoritative: true
|
|
250
|
+
};
|
|
251
|
+
} catch {
|
|
252
|
+
if (traitsByAgent.get(agent)?.request === request)
|
|
253
|
+
traitsByAgent.delete(agent);
|
|
254
|
+
return { traits: fallbackAgentTraits(agent), exactMode: undefined, authoritative: false };
|
|
255
|
+
} finally {
|
|
256
|
+
controller.abort();
|
|
257
|
+
}
|
|
258
|
+
})();
|
|
259
|
+
traitsByAgent.delete(agent);
|
|
260
|
+
traitsByAgent.set(agent, { request, expiresAt: Date.now() + AGENT_CACHE_TTL_MS, pending });
|
|
261
|
+
while (traitsByAgent.size > AGENT_CACHE_MAX) {
|
|
262
|
+
const oldest = traitsByAgent.keys().next().value;
|
|
263
|
+
if (oldest === undefined)
|
|
264
|
+
break;
|
|
265
|
+
traitsByAgent.delete(oldest);
|
|
266
|
+
}
|
|
267
|
+
return pending;
|
|
268
|
+
};
|
|
269
|
+
const apply = async (input, headers, refreshTraits = false) => {
|
|
270
|
+
if (!MERIDIAN_PROVIDERS.has(String(input.model.providerID)))
|
|
271
|
+
return;
|
|
272
|
+
const agent = String(input.agent);
|
|
273
|
+
const metadata = await resolveAgentTraits(agent, refreshTraits);
|
|
274
|
+
applyMeridianV2Headers(headers, {
|
|
275
|
+
sessionID: String(input.sessionID),
|
|
276
|
+
agent,
|
|
277
|
+
traits: metadata.traits
|
|
278
|
+
});
|
|
279
|
+
return metadata;
|
|
280
|
+
};
|
|
281
|
+
const resolveHumanTurn = async (input, headers, metadata) => {
|
|
282
|
+
const sessionID = String(input.sessionID);
|
|
283
|
+
const agent = String(input.agent);
|
|
284
|
+
if (!metadata.authoritative || metadata.exactMode !== "primary" || metadata.traits.hidden || INTERNAL_ROUTING_AGENT_IDS.has(agent) || safeAgentName(agent) !== agent || getHeader(headers, "x-meridian-profile") !== undefined) {
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
const controller = new AbortController;
|
|
288
|
+
try {
|
|
289
|
+
const result = await withTimeout(Promise.all([
|
|
290
|
+
context.session.get({ sessionID }, { signal: controller.signal }),
|
|
291
|
+
context.session.context({ sessionID }, { signal: controller.signal })
|
|
292
|
+
]), LOOKUP_TIMEOUT_MS);
|
|
293
|
+
if (!result || !isRootV2Session(result[0], sessionID))
|
|
294
|
+
return;
|
|
295
|
+
return findLatestV2HumanTurn(result[1]);
|
|
296
|
+
} catch {
|
|
297
|
+
return;
|
|
298
|
+
} finally {
|
|
299
|
+
controller.abort();
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
try {
|
|
303
|
+
for (const providerID of MERIDIAN_PROVIDERS) {
|
|
304
|
+
registered.push(await context.session.hook("model.request", async (input) => {
|
|
305
|
+
await apply(input, input.headers);
|
|
306
|
+
}, { providerID }));
|
|
307
|
+
registered.push(await context.session.hook("http.request", async (input) => {
|
|
308
|
+
const metadata = await apply(input, input.request.headers, true);
|
|
309
|
+
if (!metadata)
|
|
310
|
+
return;
|
|
311
|
+
const humanTurn = await resolveHumanTurn(input, input.request.headers, metadata);
|
|
312
|
+
if (!humanTurn)
|
|
313
|
+
return;
|
|
314
|
+
const token = createPriorityAttestation({
|
|
315
|
+
generation: "oc2b18314",
|
|
316
|
+
sessionId: String(input.sessionID),
|
|
317
|
+
agentId: String(input.agent),
|
|
318
|
+
humanMessageId: humanTurn.id,
|
|
319
|
+
issuedAt: humanTurn.issuedAt
|
|
320
|
+
});
|
|
321
|
+
if (token)
|
|
322
|
+
setHeader(input.request.headers, PRIORITY_ATTESTATION_HEADER, token);
|
|
323
|
+
}, { providerID }));
|
|
324
|
+
}
|
|
325
|
+
} catch (error) {
|
|
326
|
+
await Promise.allSettled(registered.map(({ dispose }) => dispose()));
|
|
327
|
+
throw error;
|
|
328
|
+
}
|
|
329
|
+
return async () => {
|
|
330
|
+
const results = await Promise.allSettled(registered.map(({ dispose }) => dispose()));
|
|
331
|
+
const failures = results.flatMap((result) => result.status === "rejected" ? [result.reason] : []);
|
|
332
|
+
if (failures.length > 0)
|
|
333
|
+
throw new AggregateError(failures, "Failed to dispose Meridian V2 hooks");
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
var meridian_v2_default = MeridianV2Plugin;
|
|
338
|
+
export {
|
|
339
|
+
shouldDetachFromParentSession,
|
|
340
|
+
isRootV2Session,
|
|
341
|
+
findLatestV2HumanTurn,
|
|
342
|
+
findLatestV2HumanMessageId,
|
|
343
|
+
fallbackAgentTraits,
|
|
344
|
+
meridian_v2_default as default,
|
|
345
|
+
applyMeridianV2Headers,
|
|
346
|
+
SUPPORTED_OPENCODE_V2_VERSION
|
|
347
|
+
};
|
|
@@ -13,9 +13,9 @@ import {
|
|
|
13
13
|
profileLogin,
|
|
14
14
|
profileRemove,
|
|
15
15
|
profileSwitch
|
|
16
|
-
} from "./cli-
|
|
17
|
-
import"./cli-vj9cv18n.js";
|
|
16
|
+
} from "./cli-0ed6j0vk.js";
|
|
18
17
|
import"./cli-khhjyk04.js";
|
|
18
|
+
import"./cli-vj9cv18n.js";
|
|
19
19
|
import"./cli-p9swy5t3.js";
|
|
20
20
|
export {
|
|
21
21
|
profileSwitch,
|
package/dist/proxy/adapter.d.ts
CHANGED
|
@@ -6,6 +6,14 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import type { Context } from "hono";
|
|
8
8
|
import type { SettingSource } from "@anthropic-ai/claude-agent-sdk";
|
|
9
|
+
export type RoutingTurnIdentity = Readonly<{
|
|
10
|
+
readonly kind: "human";
|
|
11
|
+
/** Fixed-width, session-bound digest of the host's genuine human message ID. */
|
|
12
|
+
readonly turnId: string;
|
|
13
|
+
/** Signed wall-clock issue time used as a durable anti-replay high-water mark. */
|
|
14
|
+
readonly issuedAt: number;
|
|
15
|
+
readonly generation: "opencode-v1" | "opencode-v2-beta-18314";
|
|
16
|
+
}>;
|
|
9
17
|
/**
|
|
10
18
|
* Core identity of an agent — detection, session tracking, CWD extraction.
|
|
11
19
|
* This is the minimal interface for agent recognition. Behavioral customization
|
|
@@ -24,6 +32,14 @@ export interface AgentIdentity {
|
|
|
24
32
|
* details; the proxy uses the normalized value for model-tier selection.
|
|
25
33
|
*/
|
|
26
34
|
getAgentMode?(c: Context, body?: unknown): string | undefined;
|
|
35
|
+
/**
|
|
36
|
+
* Optional trusted identity for a visible human turn.
|
|
37
|
+
*
|
|
38
|
+
* This is deliberately a positive, normalized assertion. Callers must treat
|
|
39
|
+
* undefined as ineligible for user-turn routing changes. An adapter must not
|
|
40
|
+
* return raw client-declared kind/ID headers without authenticating them.
|
|
41
|
+
*/
|
|
42
|
+
getRoutingTurnIdentity?(c: Context, body?: unknown): RoutingTurnIdentity | undefined;
|
|
27
43
|
/**
|
|
28
44
|
* Extract the SDK subprocess working directory from the request body.
|
|
29
45
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/proxy/adapter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACnC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;AAEnE;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IAErB;;;OAGG;IACH,YAAY,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAA;IAE5D;;;OAGG;IACH,YAAY,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAA;IAE7D;;;;;;;;;;;;;;;;OAgBG;IACH,uBAAuB,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM,GAAG,SAAS,CAAA;IAEtD;;;;;;;;;;;OAWG;IACH,6BAA6B,CAAC,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM,GAAG,SAAS,CAAA;IAE7D;;;OAGG;IACH,gBAAgB,CAAC,OAAO,EAAE,GAAG,GAAG,MAAM,CAAA;IAEtC;;;;;OAKG;IACH,8BAA8B,CAAC,CAC7B,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,GAClD,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAA;IAE5C;;;OAGG;IACH,gBAAgB,IAAI,MAAM,CAAA;CAC3B;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAa,SAAQ,aAAa;IACjD;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAE1B,6EAA6E;IAC7E,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC,OAAO,eAAe,EAAE,eAAe,CAAC,CAAA;IAE5E,6EAA6E;IAC7E,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAEtC;;;OAGG;IACH,sBAAsB,IAAI,SAAS,MAAM,EAAE,CAAA;IAE3C;;;;OAIG;IACH,yBAAyB,IAAI,SAAS,MAAM,EAAE,CAAA;IAE9C;;OAEG;IACH,kBAAkB,IAAI,SAAS,MAAM,EAAE,CAAA;IAEvC;;;;OAIG;IACH,cAAc,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,YAAY,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAEhF;;;OAGG;IACH,aAAa,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,CAAA;IAE9D;;;OAGG;IACH,0BAA0B,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAA;IAE9E;;;;;;OAMG;IACH,gBAAgB,CAAC,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAA;IAErC;;;;;;;;OAQG;IACH,eAAe,CAAC,IAAI,OAAO,CAAA;IAE3B;;;;;;;OAOG;IACH,gBAAgB,CAAC,IAAI,SAAS,MAAM,EAAE,CAAA;IAEtC;;;;;;;;;;;;;;OAcG;IACH,iBAAiB,CAAC,IAAI,aAAa,EAAE,CAAA;IAErC;;;;;;;OAOG;IACH,gBAAgB,CAAC,IAAI,OAAO,CAAA;IAE5B;;;;;;OAMG;IACH,sBAAsB,CAAC,IAAI,OAAO,CAAA;IAElC;;;;;;;;OAQG;IACH,yBAAyB,CAAC,IAAI,OAAO,CAAA;IAErC;;;;;;;;;;;;;;;OAeG;IACH,6BAA6B,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,eAAe,EAAE,UAAU,EAAE,CAAA;CAC3G"}
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/proxy/adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opencode.d.ts","sourceRoot":"","sources":["../../../src/proxy/adapters/opencode.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"opencode.d.ts","sourceRoot":"","sources":["../../../src/proxy/adapters/opencode.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAuB,MAAM,YAAY,CAAA;AAsCnE,wBAAgB,sCAAsC,CACpD,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,GAClD,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAU3C;AAED,eAAO,MAAM,eAAe,EAAE,YAqM7B,CAAA;AAED,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAC3D,OAAO,EAAE,kBAAkB,EAAE,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/proxy/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAc1D;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/proxy/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAc1D;AAsCD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,eAAe,CAkI7E;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAM3D;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,aAAa,GAAG,iBAAiB,CAAA;AAEtE;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAahG;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAI3E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGxD;AAuBD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,SAAS,IAAI,MAAM,CAEhG;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAE5E;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGjE;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,WAAW,GAAG,cAAc,GAAG,SAAS,GAAG,eAAe,GAAG,SAAS,CAAA;IAC9E,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;wCAEoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAuBD;;;;;;GAMG;AACH;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE;IAChD,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAA;IAChC,WAAW,EAAE,OAAO,CAAA;IACpB,gBAAgB,EAAE,MAAM,CAAA;IACxB,WAAW,EAAE,OAAO,CAAA;CACrB,GAAG,OAAO,CAYV;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAuDpE;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,CAAC,EAAE,cAAc,EACjB,GAAG,EAAE;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,GACA,MAAM,CAYR"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"passthroughTools.d.ts","sourceRoot":"","sources":["../../src/proxy/passthroughTools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,eAAO,MAAM,oBAAoB,OAAO,CAAA;AACxC,eAAO,MAAM,sBAAsB,cAAmC,CAAA;AA0CtE,wBAAgB,qBAAqB,IAAI,MAAM,CAM9C;AAED;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,GAAG,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,EACjG,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE;;;;
|
|
1
|
+
{"version":3,"file":"passthroughTools.d.ts","sourceRoot":"","sources":["../../src/proxy/passthroughTools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,eAAO,MAAM,oBAAoB,OAAO,CAAA;AACxC,eAAO,MAAM,sBAAsB,cAAmC,CAAA;AA0CtE,wBAAgB,qBAAqB,IAAI,MAAM,CAM9C;AAED;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,GAAG,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,EACjG,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE;;;;EA8ClC;AAqBD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,GAC9E,MAAM,CASR;AAUD;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAErE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAKvD;AAUD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAC1C,YAAY,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,SAAS,GACtF,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAgCrC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verify and provision OpenCode priority-failback attestations.
|
|
3
|
+
*
|
|
4
|
+
* The OpenCode plugin signs a bounded positive assertion at its final outbound
|
|
5
|
+
* hook. Meridian verifies it before treating a request as a new human turn.
|
|
6
|
+
* Missing or invalid attestations fail closed to normal profile affinity.
|
|
7
|
+
*/
|
|
8
|
+
export declare const PRIORITY_ATTESTATION_HEADER = "x-meridian-opencode-turn";
|
|
9
|
+
export declare const PRIORITY_ATTESTATION_KEY_ENV = "MERIDIAN_OPENCODE_ATTESTATION_KEY";
|
|
10
|
+
export declare const PRIORITY_ATTESTATION_KEY_FILE = "opencode-turn.key";
|
|
11
|
+
export type OpenCodeAttestationGeneration = "oc1" | "oc2b18314";
|
|
12
|
+
export interface VerifiedPriorityAttestation {
|
|
13
|
+
readonly generation: OpenCodeAttestationGeneration;
|
|
14
|
+
readonly sessionId: string;
|
|
15
|
+
readonly agentId: string;
|
|
16
|
+
readonly turnId: string;
|
|
17
|
+
readonly issuedAt: number;
|
|
18
|
+
}
|
|
19
|
+
export declare class InvalidPriorityAttestationKeyError extends Error {
|
|
20
|
+
readonly keyPath: string;
|
|
21
|
+
constructor(keyPath: string);
|
|
22
|
+
}
|
|
23
|
+
export declare function priorityAttestationKeyPath(): string;
|
|
24
|
+
export declare function decodePriorityAttestationKey(raw: string | undefined): Buffer | undefined;
|
|
25
|
+
export declare function loadPriorityAttestationKey(): Buffer | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* Ensure setup has a durable 32-byte signing key without ever rotating an
|
|
28
|
+
* existing valid key. An environment key wins and avoids touching disk.
|
|
29
|
+
*/
|
|
30
|
+
export declare function ensurePriorityAttestationKey(): {
|
|
31
|
+
readonly key: Buffer;
|
|
32
|
+
readonly path?: string;
|
|
33
|
+
};
|
|
34
|
+
export declare function verifyPriorityAttestation(token: string | undefined, key?: Buffer, nowSeconds?: number): VerifiedPriorityAttestation | undefined;
|
|
35
|
+
//# sourceMappingURL=priorityAttestation.d.ts.map
|