@jterrats/open-orchestra 0.4.0 → 0.4.2-beta.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/CHANGELOG.md +21 -0
- package/dist/assets/web-console.js +91 -1
- package/dist/autonomous-phase-lifecycle.d.ts +26 -0
- package/dist/autonomous-phase-lifecycle.js +214 -0
- package/dist/autonomous-phase-lifecycle.js.map +1 -0
- package/dist/autonomous-run-state.d.ts +8 -0
- package/dist/autonomous-run-state.js +162 -0
- package/dist/autonomous-run-state.js.map +1 -0
- package/dist/autonomous-run-store.d.ts +17 -0
- package/dist/autonomous-run-store.js +89 -0
- package/dist/autonomous-run-store.js.map +1 -0
- package/dist/autonomous-workflow-constants.d.ts +7 -0
- package/dist/autonomous-workflow-constants.js +36 -0
- package/dist/autonomous-workflow-constants.js.map +1 -0
- package/dist/autonomous-workflow.d.ts +6 -45
- package/dist/autonomous-workflow.js +4 -394
- package/dist/autonomous-workflow.js.map +1 -1
- package/dist/benchmark.js +16 -0
- package/dist/benchmark.js.map +1 -1
- package/dist/clarification.d.ts +2 -0
- package/dist/clarification.js +23 -5
- package/dist/clarification.js.map +1 -1
- package/dist/cli.js +101 -14
- package/dist/cli.js.map +1 -1
- package/dist/command-manifest.js +8 -0
- package/dist/command-manifest.js.map +1 -1
- package/dist/command-utils.d.ts +6 -0
- package/dist/command-utils.js +19 -0
- package/dist/command-utils.js.map +1 -0
- package/dist/commands.d.ts +15 -43
- package/dist/commands.js +466 -912
- package/dist/commands.js.map +1 -1
- package/dist/constants.js +20 -0
- package/dist/constants.js.map +1 -1
- package/dist/defaults.d.ts +11 -0
- package/dist/defaults.js +11 -0
- package/dist/defaults.js.map +1 -1
- package/dist/instruction-commands.d.ts +5 -0
- package/dist/instruction-commands.js +98 -0
- package/dist/instruction-commands.js.map +1 -0
- package/dist/mcp-oauth-proxy.d.ts +47 -0
- package/dist/mcp-oauth-proxy.js +276 -0
- package/dist/mcp-oauth-proxy.js.map +1 -1
- package/dist/memory.d.ts +11 -0
- package/dist/memory.js +224 -0
- package/dist/memory.js.map +1 -0
- package/dist/metrics-commands.d.ts +3 -0
- package/dist/metrics-commands.js +123 -0
- package/dist/metrics-commands.js.map +1 -0
- package/dist/model-commands.d.ts +13 -0
- package/dist/model-commands.js +216 -0
- package/dist/model-commands.js.map +1 -0
- package/dist/notifications.d.ts +25 -0
- package/dist/notifications.js +187 -11
- package/dist/notifications.js.map +1 -1
- package/dist/package-update-check.d.ts +19 -0
- package/dist/package-update-check.js +123 -0
- package/dist/package-update-check.js.map +1 -0
- package/dist/runtime-adapters.d.ts +5 -1
- package/dist/runtime-adapters.js +27 -0
- package/dist/runtime-adapters.js.map +1 -1
- package/dist/runtime-bootstrap.js +4 -2
- package/dist/runtime-bootstrap.js.map +1 -1
- package/dist/runtime-commands.d.ts +9 -0
- package/dist/runtime-commands.js +156 -0
- package/dist/runtime-commands.js.map +1 -0
- package/dist/runtime-execution-adapters.d.ts +2 -0
- package/dist/runtime-execution-adapters.js +163 -0
- package/dist/runtime-execution-adapters.js.map +1 -0
- package/dist/runtime-execution-renderer.d.ts +10 -0
- package/dist/runtime-execution-renderer.js +113 -0
- package/dist/runtime-execution-renderer.js.map +1 -0
- package/dist/runtime-execution.d.ts +27 -0
- package/dist/runtime-execution.js +153 -0
- package/dist/runtime-execution.js.map +1 -0
- package/dist/skills-commands.d.ts +10 -0
- package/dist/skills-commands.js +138 -0
- package/dist/skills-commands.js.map +1 -0
- package/dist/skills.d.ts +7 -1
- package/dist/skills.js +120 -11
- package/dist/skills.js.map +1 -1
- package/dist/sprint-commands.d.ts +5 -0
- package/dist/sprint-commands.js +120 -0
- package/dist/sprint-commands.js.map +1 -0
- package/dist/subagent-protocol.js +6 -0
- package/dist/subagent-protocol.js.map +1 -1
- package/dist/telemetry-commands.d.ts +7 -0
- package/dist/telemetry-commands.js +82 -0
- package/dist/telemetry-commands.js.map +1 -0
- package/dist/tool-commands.d.ts +5 -0
- package/dist/tool-commands.js +159 -0
- package/dist/tool-commands.js.map +1 -0
- package/dist/types.d.ts +206 -4
- package/dist/types.js.map +1 -1
- package/dist/web-api.js +93 -1
- package/dist/web-api.js.map +1 -1
- package/dist/web-chart-contracts.d.ts +3 -1
- package/dist/web-chart-contracts.js +6 -0
- package/dist/web-chart-contracts.js.map +1 -1
- package/dist/web-console.js +2 -2
- package/dist/workflow-services.d.ts +21 -3
- package/dist/workflow-services.js +474 -10
- package/dist/workflow-services.js.map +1 -1
- package/docs/runtime-llm-flow.md +46 -0
- package/package.json +2 -1
- package/skills/proactive-orchestra/SKILL.md +27 -0
- package/skills/proactive-orchestra/manifest.json +41 -0
|
@@ -4,6 +4,11 @@ export interface McpOAuthProxyConfig {
|
|
|
4
4
|
enabled: boolean;
|
|
5
5
|
mode: McpProxyMode;
|
|
6
6
|
serverUrl: string;
|
|
7
|
+
authorizationUrl?: string;
|
|
8
|
+
tokenUrl?: string;
|
|
9
|
+
clientId?: string;
|
|
10
|
+
clientSecret?: string;
|
|
11
|
+
scopes?: string[];
|
|
7
12
|
tokenStorage: McpSecretStorage;
|
|
8
13
|
tokenPath?: string;
|
|
9
14
|
refreshWindowSeconds: number;
|
|
@@ -29,8 +34,50 @@ export interface McpTokenRefreshResult {
|
|
|
29
34
|
reason: string;
|
|
30
35
|
token: McpTokenState;
|
|
31
36
|
}
|
|
37
|
+
export interface McpTokenStatus {
|
|
38
|
+
exists: boolean;
|
|
39
|
+
expiresAt?: string;
|
|
40
|
+
needsRefresh?: boolean;
|
|
41
|
+
}
|
|
42
|
+
export interface McpOAuthStartResult {
|
|
43
|
+
mode: McpProxyMode;
|
|
44
|
+
serverUrl: string;
|
|
45
|
+
token: McpTokenStatus;
|
|
46
|
+
proxyReady: boolean;
|
|
47
|
+
}
|
|
48
|
+
export interface McpAuthenticatedRequest {
|
|
49
|
+
method?: string;
|
|
50
|
+
path: string;
|
|
51
|
+
body?: string;
|
|
52
|
+
headers?: Record<string, string>;
|
|
53
|
+
}
|
|
54
|
+
export interface McpAuthenticatedResponse {
|
|
55
|
+
status: number;
|
|
56
|
+
body: string;
|
|
57
|
+
contentType?: string;
|
|
58
|
+
}
|
|
32
59
|
export declare function evaluateMcpOAuthProxy(config: McpOAuthProxyConfig): McpProxyEvaluation;
|
|
33
60
|
export declare function validateMcpOAuthProxyConfig(config: McpOAuthProxyConfig): string[];
|
|
61
|
+
export declare function readMcpTokenStatus(config: McpOAuthProxyConfig, now?: Date): Promise<McpTokenStatus>;
|
|
62
|
+
export declare function loadMcpToken(config: McpOAuthProxyConfig): Promise<McpTokenState>;
|
|
63
|
+
export declare function saveMcpToken(config: McpOAuthProxyConfig, token: McpTokenState): Promise<void>;
|
|
64
|
+
export declare function clearMcpToken(config: McpOAuthProxyConfig): Promise<{
|
|
65
|
+
cleared: true;
|
|
66
|
+
}>;
|
|
67
|
+
export declare function forceRefreshMcpToken({ config, fetchFn, }: {
|
|
68
|
+
config: McpOAuthProxyConfig;
|
|
69
|
+
fetchFn?: typeof fetch;
|
|
70
|
+
}): Promise<McpTokenRefreshResult>;
|
|
71
|
+
export declare function startMcpOAuthProxy({ config, fetchFn, openBrowser, }: {
|
|
72
|
+
config: McpOAuthProxyConfig;
|
|
73
|
+
fetchFn?: typeof fetch;
|
|
74
|
+
openBrowser?: boolean;
|
|
75
|
+
}): Promise<McpOAuthStartResult>;
|
|
76
|
+
export declare function proxyMcpHttpRequest({ config, request, fetchFn, }: {
|
|
77
|
+
config: McpOAuthProxyConfig;
|
|
78
|
+
request: McpAuthenticatedRequest;
|
|
79
|
+
fetchFn?: typeof fetch;
|
|
80
|
+
}): Promise<McpAuthenticatedResponse>;
|
|
34
81
|
export declare function refreshMcpTokenIfNeeded({ token, now, refreshWindowSeconds, refresh, }: {
|
|
35
82
|
token: McpTokenState;
|
|
36
83
|
now?: Date;
|
package/dist/mcp-oauth-proxy.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { createHash, randomBytes } from "node:crypto";
|
|
2
|
+
import { createServer } from "node:http";
|
|
3
|
+
import { chmod, mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
4
|
+
import { spawn } from "node:child_process";
|
|
1
5
|
import path from "node:path";
|
|
2
6
|
export function evaluateMcpOAuthProxy(config) {
|
|
3
7
|
const risks = validateMcpOAuthProxyConfig(config);
|
|
@@ -39,6 +43,13 @@ export function validateMcpOAuthProxyConfig(config) {
|
|
|
39
43
|
if (!config.serverUrl.startsWith("https://")) {
|
|
40
44
|
risks.push("serverUrl must use https");
|
|
41
45
|
}
|
|
46
|
+
if (config.authorizationUrl &&
|
|
47
|
+
!config.authorizationUrl.startsWith("https://")) {
|
|
48
|
+
risks.push("authorizationUrl must use https");
|
|
49
|
+
}
|
|
50
|
+
if (config.tokenUrl && !config.tokenUrl.startsWith("https://")) {
|
|
51
|
+
risks.push("tokenUrl must use https");
|
|
52
|
+
}
|
|
42
53
|
if (config.refreshWindowSeconds < 30) {
|
|
43
54
|
risks.push("refreshWindowSeconds must be at least 30");
|
|
44
55
|
}
|
|
@@ -52,6 +63,90 @@ export function validateMcpOAuthProxyConfig(config) {
|
|
|
52
63
|
}
|
|
53
64
|
return risks;
|
|
54
65
|
}
|
|
66
|
+
export async function readMcpTokenStatus(config, now = new Date()) {
|
|
67
|
+
const token = await loadMcpToken(config).catch(() => undefined);
|
|
68
|
+
if (!token) {
|
|
69
|
+
return { exists: false };
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
exists: true,
|
|
73
|
+
expiresAt: token.expiresAt,
|
|
74
|
+
needsRefresh: tokenNeedsRefresh(token, now, config.refreshWindowSeconds),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
export async function loadMcpToken(config) {
|
|
78
|
+
assertSecureFileStorage(config);
|
|
79
|
+
const content = await readFile(config.tokenPath, "utf8");
|
|
80
|
+
return JSON.parse(content);
|
|
81
|
+
}
|
|
82
|
+
export async function saveMcpToken(config, token) {
|
|
83
|
+
assertSecureFileStorage(config);
|
|
84
|
+
await mkdir(path.dirname(config.tokenPath), {
|
|
85
|
+
recursive: true,
|
|
86
|
+
mode: 0o700,
|
|
87
|
+
});
|
|
88
|
+
await writeFile(config.tokenPath, JSON.stringify(token, null, 2), {
|
|
89
|
+
mode: 0o600,
|
|
90
|
+
});
|
|
91
|
+
await chmod(config.tokenPath, 0o600);
|
|
92
|
+
}
|
|
93
|
+
export async function clearMcpToken(config) {
|
|
94
|
+
assertSecureFileStorage(config);
|
|
95
|
+
await rm(config.tokenPath, { force: true });
|
|
96
|
+
return { cleared: true };
|
|
97
|
+
}
|
|
98
|
+
export async function forceRefreshMcpToken({ config, fetchFn = fetch, }) {
|
|
99
|
+
const token = await loadMcpToken(config);
|
|
100
|
+
const refreshed = await refreshTokenWithEndpoint(config, token, fetchFn);
|
|
101
|
+
await saveMcpToken(config, refreshed);
|
|
102
|
+
return {
|
|
103
|
+
refreshed: true,
|
|
104
|
+
reason: "token refresh forced",
|
|
105
|
+
token: refreshed,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
export async function startMcpOAuthProxy({ config, fetchFn = fetch, openBrowser = true, }) {
|
|
109
|
+
const risks = validateMcpOAuthProxyConfig(config);
|
|
110
|
+
if (risks.length > 0) {
|
|
111
|
+
throw new Error("invalid MCP OAuth proxy config: " + risks.join("; "));
|
|
112
|
+
}
|
|
113
|
+
const token = await ensureMcpToken({ config, fetchFn, openBrowser });
|
|
114
|
+
return {
|
|
115
|
+
mode: config.mode,
|
|
116
|
+
serverUrl: config.serverUrl,
|
|
117
|
+
token: {
|
|
118
|
+
exists: true,
|
|
119
|
+
expiresAt: token.expiresAt,
|
|
120
|
+
needsRefresh: false,
|
|
121
|
+
},
|
|
122
|
+
proxyReady: config.mode === "stdio-proxy",
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
export async function proxyMcpHttpRequest({ config, request, fetchFn = fetch, }) {
|
|
126
|
+
const token = await ensureMcpToken({ config, fetchFn, openBrowser: false });
|
|
127
|
+
const target = new URL(request.path, ensureTrailingSlash(config.serverUrl));
|
|
128
|
+
if (target.protocol !== "https:") {
|
|
129
|
+
throw new Error("MCP proxy target must use https");
|
|
130
|
+
}
|
|
131
|
+
const headers = new Headers(request.headers);
|
|
132
|
+
headers.set("authorization", "Bearer " + token.accessToken);
|
|
133
|
+
const init = {
|
|
134
|
+
method: request.method ?? "POST",
|
|
135
|
+
headers,
|
|
136
|
+
};
|
|
137
|
+
if (request.body !== undefined) {
|
|
138
|
+
init.body = request.body;
|
|
139
|
+
}
|
|
140
|
+
const response = await fetchFn(target, {
|
|
141
|
+
...init,
|
|
142
|
+
});
|
|
143
|
+
const contentType = response.headers.get("content-type") ?? undefined;
|
|
144
|
+
return removeUndefinedResponse({
|
|
145
|
+
status: response.status,
|
|
146
|
+
body: await response.text(),
|
|
147
|
+
...(contentType ? { contentType } : {}),
|
|
148
|
+
});
|
|
149
|
+
}
|
|
55
150
|
export async function refreshMcpTokenIfNeeded({ token, now = new Date(), refreshWindowSeconds, refresh, }) {
|
|
56
151
|
const expiresAt = new Date(token.expiresAt);
|
|
57
152
|
const refreshAt = expiresAt.getTime() - refreshWindowSeconds * 1000;
|
|
@@ -68,6 +163,187 @@ export async function refreshMcpTokenIfNeeded({ token, now = new Date(), refresh
|
|
|
68
163
|
token: await refresh(token),
|
|
69
164
|
};
|
|
70
165
|
}
|
|
166
|
+
async function ensureMcpToken({ config, fetchFn, openBrowser, }) {
|
|
167
|
+
const existing = await loadMcpToken(config).catch(() => undefined);
|
|
168
|
+
if (existing) {
|
|
169
|
+
const refreshed = await refreshMcpTokenIfNeeded({
|
|
170
|
+
token: existing,
|
|
171
|
+
refreshWindowSeconds: config.refreshWindowSeconds,
|
|
172
|
+
refresh: (token) => refreshTokenWithEndpoint(config, token, fetchFn),
|
|
173
|
+
});
|
|
174
|
+
if (refreshed.refreshed) {
|
|
175
|
+
await saveMcpToken(config, refreshed.token);
|
|
176
|
+
}
|
|
177
|
+
return refreshed.token;
|
|
178
|
+
}
|
|
179
|
+
const token = await acquireTokenWithAuthorizationCode({
|
|
180
|
+
config,
|
|
181
|
+
fetchFn,
|
|
182
|
+
openBrowser,
|
|
183
|
+
});
|
|
184
|
+
await saveMcpToken(config, token);
|
|
185
|
+
return token;
|
|
186
|
+
}
|
|
187
|
+
async function acquireTokenWithAuthorizationCode({ config, fetchFn, openBrowser, }) {
|
|
188
|
+
if (!config.authorizationUrl || !config.tokenUrl || !config.clientId) {
|
|
189
|
+
throw new Error("authorizationUrl, tokenUrl, and clientId are required");
|
|
190
|
+
}
|
|
191
|
+
const verifier = base64Url(randomBytes(32));
|
|
192
|
+
const challenge = base64Url(createHash("sha256").update(verifier).digest());
|
|
193
|
+
const state = base64Url(randomBytes(18));
|
|
194
|
+
const callback = await waitForOAuthCallback();
|
|
195
|
+
const authorizationUrl = new URL(config.authorizationUrl);
|
|
196
|
+
authorizationUrl.searchParams.set("response_type", "code");
|
|
197
|
+
authorizationUrl.searchParams.set("client_id", config.clientId);
|
|
198
|
+
authorizationUrl.searchParams.set("redirect_uri", callback.redirectUri);
|
|
199
|
+
authorizationUrl.searchParams.set("code_challenge", challenge);
|
|
200
|
+
authorizationUrl.searchParams.set("code_challenge_method", "S256");
|
|
201
|
+
authorizationUrl.searchParams.set("state", state);
|
|
202
|
+
if (config.scopes?.length) {
|
|
203
|
+
authorizationUrl.searchParams.set("scope", config.scopes.join(" "));
|
|
204
|
+
}
|
|
205
|
+
if (openBrowser) {
|
|
206
|
+
openSystemBrowser(authorizationUrl.toString());
|
|
207
|
+
}
|
|
208
|
+
const code = await callback.code;
|
|
209
|
+
if (code.state !== state) {
|
|
210
|
+
throw new Error("OAuth callback state mismatch");
|
|
211
|
+
}
|
|
212
|
+
return exchangeAuthorizationCode(config, code.code, callback.redirectUri, verifier, fetchFn);
|
|
213
|
+
}
|
|
214
|
+
async function waitForOAuthCallback() {
|
|
215
|
+
let resolveCode;
|
|
216
|
+
let rejectCode;
|
|
217
|
+
const code = new Promise((resolve, reject) => {
|
|
218
|
+
resolveCode = resolve;
|
|
219
|
+
rejectCode = reject;
|
|
220
|
+
});
|
|
221
|
+
const server = createServer((request, response) => {
|
|
222
|
+
const url = new URL(request.url ?? "/", "http://127.0.0.1");
|
|
223
|
+
if (url.pathname !== "/callback") {
|
|
224
|
+
response.writeHead(404).end("Not found");
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
const oauthCode = url.searchParams.get("code");
|
|
228
|
+
const state = url.searchParams.get("state");
|
|
229
|
+
if (!oauthCode || !state) {
|
|
230
|
+
response.writeHead(400).end("Missing code or state");
|
|
231
|
+
rejectCode(new Error("OAuth callback missing code or state"));
|
|
232
|
+
server.close();
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
response
|
|
236
|
+
.writeHead(200, { "content-type": "text/plain" })
|
|
237
|
+
.end("OAuth complete. You can close this window.");
|
|
238
|
+
resolveCode({ code: oauthCode, state });
|
|
239
|
+
server.close();
|
|
240
|
+
});
|
|
241
|
+
await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));
|
|
242
|
+
const address = server.address();
|
|
243
|
+
if (!address || typeof address === "string") {
|
|
244
|
+
server.close();
|
|
245
|
+
throw new Error("failed to bind OAuth callback");
|
|
246
|
+
}
|
|
247
|
+
return {
|
|
248
|
+
redirectUri: `http://127.0.0.1:${address.port}/callback`,
|
|
249
|
+
code,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
async function exchangeAuthorizationCode(config, code, redirectUri, verifier, fetchFn) {
|
|
253
|
+
const body = new URLSearchParams({
|
|
254
|
+
grant_type: "authorization_code",
|
|
255
|
+
code,
|
|
256
|
+
redirect_uri: redirectUri,
|
|
257
|
+
client_id: config.clientId ?? "",
|
|
258
|
+
code_verifier: verifier,
|
|
259
|
+
});
|
|
260
|
+
if (config.clientSecret) {
|
|
261
|
+
body.set("client_secret", config.clientSecret);
|
|
262
|
+
}
|
|
263
|
+
return tokenFromResponse(await postToken(config, body, fetchFn));
|
|
264
|
+
}
|
|
265
|
+
async function refreshTokenWithEndpoint(config, token, fetchFn) {
|
|
266
|
+
if (!config.tokenUrl || !config.clientId) {
|
|
267
|
+
throw new Error("tokenUrl and clientId are required for refresh");
|
|
268
|
+
}
|
|
269
|
+
const body = new URLSearchParams({
|
|
270
|
+
grant_type: "refresh_token",
|
|
271
|
+
refresh_token: token.refreshToken,
|
|
272
|
+
client_id: config.clientId,
|
|
273
|
+
});
|
|
274
|
+
if (config.clientSecret) {
|
|
275
|
+
body.set("client_secret", config.clientSecret);
|
|
276
|
+
}
|
|
277
|
+
return tokenFromResponse(await postToken(config, body, fetchFn), token);
|
|
278
|
+
}
|
|
279
|
+
async function postToken(config, body, fetchFn) {
|
|
280
|
+
if (!config.tokenUrl?.startsWith("https://")) {
|
|
281
|
+
throw new Error("tokenUrl must use https");
|
|
282
|
+
}
|
|
283
|
+
const response = await fetchFn(config.tokenUrl, {
|
|
284
|
+
method: "POST",
|
|
285
|
+
headers: { "content-type": "application/x-www-form-urlencoded" },
|
|
286
|
+
body,
|
|
287
|
+
});
|
|
288
|
+
if (!response.ok) {
|
|
289
|
+
throw new Error(`OAuth token endpoint returned HTTP ${response.status}`);
|
|
290
|
+
}
|
|
291
|
+
return (await response.json());
|
|
292
|
+
}
|
|
293
|
+
function tokenFromResponse(payload, previous) {
|
|
294
|
+
const accessToken = stringField(payload, "access_token");
|
|
295
|
+
const refreshToken = typeof payload.refresh_token === "string"
|
|
296
|
+
? payload.refresh_token
|
|
297
|
+
: previous?.refreshToken;
|
|
298
|
+
const expiresIn = typeof payload.expires_in === "number" ? payload.expires_in : 3600;
|
|
299
|
+
if (!refreshToken) {
|
|
300
|
+
throw new Error("OAuth token response missing refresh_token");
|
|
301
|
+
}
|
|
302
|
+
return {
|
|
303
|
+
accessToken,
|
|
304
|
+
refreshToken,
|
|
305
|
+
expiresAt: new Date(Date.now() + expiresIn * 1000).toISOString(),
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
function stringField(payload, key) {
|
|
309
|
+
const value = payload[key];
|
|
310
|
+
if (typeof value !== "string" || value.trim() === "") {
|
|
311
|
+
throw new Error(`OAuth token response missing ${key}`);
|
|
312
|
+
}
|
|
313
|
+
return value;
|
|
314
|
+
}
|
|
315
|
+
function tokenNeedsRefresh(token, now, refreshWindowSeconds) {
|
|
316
|
+
return (now.getTime() >=
|
|
317
|
+
new Date(token.expiresAt).getTime() - refreshWindowSeconds * 1000);
|
|
318
|
+
}
|
|
319
|
+
function assertSecureFileStorage(config) {
|
|
320
|
+
if (config.tokenStorage !== "secure-file") {
|
|
321
|
+
throw new Error("only secure-file token storage is implemented");
|
|
322
|
+
}
|
|
323
|
+
if (!config.tokenPath || !isSecureLocalTokenPath(config.tokenPath)) {
|
|
324
|
+
throw new Error("tokenPath must stay under an approved local secret directory");
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
function openSystemBrowser(url) {
|
|
328
|
+
const platform = process.platform;
|
|
329
|
+
const command = platform === "darwin" ? "open" : platform === "win32" ? "cmd" : "xdg-open";
|
|
330
|
+
const args = platform === "win32" ? ["/c", "start", "", url] : [url];
|
|
331
|
+
const child = spawn(command, args, { detached: true, stdio: "ignore" });
|
|
332
|
+
child.unref();
|
|
333
|
+
}
|
|
334
|
+
function ensureTrailingSlash(value) {
|
|
335
|
+
return value.endsWith("/") ? value : value + "/";
|
|
336
|
+
}
|
|
337
|
+
function removeUndefinedResponse(response) {
|
|
338
|
+
return Object.fromEntries(Object.entries(response).filter(([, value]) => value !== undefined));
|
|
339
|
+
}
|
|
340
|
+
function base64Url(input) {
|
|
341
|
+
return input
|
|
342
|
+
.toString("base64")
|
|
343
|
+
.replace(/\+/g, "-")
|
|
344
|
+
.replace(/\//g, "_")
|
|
345
|
+
.replace(/=+$/g, "");
|
|
346
|
+
}
|
|
71
347
|
function isSecureLocalTokenPath(tokenPath) {
|
|
72
348
|
const normalized = path.normalize(tokenPath);
|
|
73
349
|
const home = process.env.HOME ? path.normalize(process.env.HOME) : "";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-oauth-proxy.js","sourceRoot":"","sources":["../src/mcp-oauth-proxy.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"mcp-oauth-proxy.js","sourceRoot":"","sources":["../src/mcp-oauth-proxy.ts"],"names":[],"mappings":"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"}
|
package/dist/memory.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { EventEntry, MemoryHookPoint, MemoryPacket } from "./types.js";
|
|
2
|
+
export interface MemoryQueryInput {
|
|
3
|
+
taskId?: string;
|
|
4
|
+
hook?: MemoryHookPoint;
|
|
5
|
+
query?: string;
|
|
6
|
+
tokenBudget?: number;
|
|
7
|
+
root?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function queryMemory({ taskId, hook, query, tokenBudget, root, }: MemoryQueryInput): Promise<MemoryPacket>;
|
|
10
|
+
export declare function recordMemoryEvent(root: string, packet: MemoryPacket, type: "MEMORY_QUERIED" | "MEMORY_HOOK_RAN"): Promise<EventEntry | undefined>;
|
|
11
|
+
export declare function renderMemoryPacket(packet: MemoryPacket): string;
|
package/dist/memory.js
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { FILES } from "./constants.js";
|
|
4
|
+
import { exists, readJson, resolveWorkflowPath } from "./fs-utils.js";
|
|
5
|
+
import { PROMPT_REGISTRY_DIR } from "./prompt-registry.js";
|
|
6
|
+
import { appendEvent } from "./workspace.js";
|
|
7
|
+
const DEFAULT_TOKEN_BUDGET = 900;
|
|
8
|
+
const MAX_LESSONS = 5;
|
|
9
|
+
const MAX_PROMPTS = 5;
|
|
10
|
+
const REDACTION_PATTERNS = [
|
|
11
|
+
"openai-key",
|
|
12
|
+
"github-token",
|
|
13
|
+
"slack-webhook",
|
|
14
|
+
"generic-secret",
|
|
15
|
+
];
|
|
16
|
+
export async function queryMemory({ taskId, hook = "before_implementation", query, tokenBudget = DEFAULT_TOKEN_BUDGET, root = process.cwd(), }) {
|
|
17
|
+
const task = taskId ? await readTask(root, taskId) : undefined;
|
|
18
|
+
const queryTerms = uniqueTerms([
|
|
19
|
+
hook.replace(/_/g, " "),
|
|
20
|
+
query,
|
|
21
|
+
task?.id,
|
|
22
|
+
task?.title,
|
|
23
|
+
task?.goal,
|
|
24
|
+
task?.scope,
|
|
25
|
+
task?.testStrategy,
|
|
26
|
+
...(task?.paths ?? []),
|
|
27
|
+
...(task?.acceptanceCriteria ?? []),
|
|
28
|
+
...(task?.risks ?? []),
|
|
29
|
+
]);
|
|
30
|
+
const lessons = (await readLessons(root))
|
|
31
|
+
.map((lesson) => scoreLesson(lesson, queryTerms, taskId))
|
|
32
|
+
.filter((item) => Boolean(item))
|
|
33
|
+
.sort(byScoreThenRecent)
|
|
34
|
+
.slice(0, MAX_LESSONS);
|
|
35
|
+
const prompts = (await readPromptEntries(root))
|
|
36
|
+
.map((prompt) => scorePrompt(prompt, queryTerms))
|
|
37
|
+
.filter((item) => Boolean(item))
|
|
38
|
+
.sort((left, right) => right.score - left.score)
|
|
39
|
+
.slice(0, MAX_PROMPTS);
|
|
40
|
+
return trimPacket({
|
|
41
|
+
...(taskId ? { taskId } : {}),
|
|
42
|
+
hook,
|
|
43
|
+
queryTerms,
|
|
44
|
+
tokenBudget,
|
|
45
|
+
estimatedTokens: 0,
|
|
46
|
+
lessons,
|
|
47
|
+
prompts,
|
|
48
|
+
redaction: {
|
|
49
|
+
applied: false,
|
|
50
|
+
patterns: REDACTION_PATTERNS,
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
export async function recordMemoryEvent(root, packet, type) {
|
|
55
|
+
if (!(await exists(resolveWorkflowPath(root, FILES.config)))) {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
return appendEvent(root, {
|
|
59
|
+
type,
|
|
60
|
+
...(packet.taskId ? { taskId: packet.taskId } : {}),
|
|
61
|
+
actor: "parent",
|
|
62
|
+
summary: `${packet.hook} memory packet (${packet.estimatedTokens}/${packet.tokenBudget} tokens)`,
|
|
63
|
+
metadata: {
|
|
64
|
+
hook: packet.hook,
|
|
65
|
+
tokenBudget: packet.tokenBudget,
|
|
66
|
+
estimatedTokens: packet.estimatedTokens,
|
|
67
|
+
lessonCount: packet.lessons.length,
|
|
68
|
+
promptCount: packet.prompts.length,
|
|
69
|
+
queryTerms: packet.queryTerms.slice(0, 12),
|
|
70
|
+
redacted: packet.redaction.applied,
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
export function renderMemoryPacket(packet) {
|
|
75
|
+
return [
|
|
76
|
+
"## Compact Memory",
|
|
77
|
+
`- Hook: ${packet.hook}`,
|
|
78
|
+
`- Estimated tokens: ${packet.estimatedTokens}/${packet.tokenBudget}`,
|
|
79
|
+
"",
|
|
80
|
+
"### Relevant Lessons",
|
|
81
|
+
...(packet.lessons.length === 0
|
|
82
|
+
? ["- none"]
|
|
83
|
+
: packet.lessons.map((lesson) => `- ${lesson.operation}: ${lesson.errorSignature}; fix=${lesson.fix}; prevent=${lesson.prevention}`)),
|
|
84
|
+
"",
|
|
85
|
+
"### Prompt Registry",
|
|
86
|
+
...(packet.prompts.length === 0
|
|
87
|
+
? ["- none"]
|
|
88
|
+
: packet.prompts.map((prompt) => `- ${prompt.file}#${prompt.artifact}: ${prompt.summary}`)),
|
|
89
|
+
].join("\n");
|
|
90
|
+
}
|
|
91
|
+
async function readTask(root, taskId) {
|
|
92
|
+
const tasks = await readJson(resolveWorkflowPath(root, FILES.tasks), []).catch(() => []);
|
|
93
|
+
return tasks.find((task) => task.id === taskId);
|
|
94
|
+
}
|
|
95
|
+
async function readLessons(root) {
|
|
96
|
+
const file = resolveWorkflowPath(root, FILES.agentLessons);
|
|
97
|
+
if (!(await exists(file)))
|
|
98
|
+
return [];
|
|
99
|
+
const content = await readFile(file, "utf8");
|
|
100
|
+
return content
|
|
101
|
+
.split("\n")
|
|
102
|
+
.filter((line) => line.trim() !== "")
|
|
103
|
+
.map((line) => JSON.parse(line));
|
|
104
|
+
}
|
|
105
|
+
async function readPromptEntries(root) {
|
|
106
|
+
const registryRoot = path.join(root, PROMPT_REGISTRY_DIR);
|
|
107
|
+
if (!(await exists(registryRoot)))
|
|
108
|
+
return [];
|
|
109
|
+
const files = (await readdir(registryRoot)).filter((file) => file.endsWith(".md"));
|
|
110
|
+
const entries = [];
|
|
111
|
+
for (const file of files) {
|
|
112
|
+
const content = await readFile(path.join(registryRoot, file), "utf8");
|
|
113
|
+
const maintained = content.split("<!-- Entries below this line are maintained by agents -->")[1];
|
|
114
|
+
if (!maintained)
|
|
115
|
+
continue;
|
|
116
|
+
const matches = maintained
|
|
117
|
+
.split(/\n(?=##\s+)/)
|
|
118
|
+
.map((section) => /^##\s+(.+)\n([\s\S]*)$/.exec(section));
|
|
119
|
+
for (const match of matches) {
|
|
120
|
+
if (!match)
|
|
121
|
+
continue;
|
|
122
|
+
const artifact = match[1]?.trim();
|
|
123
|
+
const body = match[2]?.trim();
|
|
124
|
+
if (artifact && body) {
|
|
125
|
+
entries.push({ file, artifact, body });
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return entries;
|
|
130
|
+
}
|
|
131
|
+
function scoreLesson(lesson, terms, taskId) {
|
|
132
|
+
const text = JSON.stringify(lesson).toLowerCase();
|
|
133
|
+
const score = matchScore(text, terms) +
|
|
134
|
+
(taskId && lesson.taskId === taskId ? 8 : 0) +
|
|
135
|
+
lesson.appliesTo.filter((item) => terms.some((term) => item.toLowerCase().includes(term))).length;
|
|
136
|
+
if (score <= 0)
|
|
137
|
+
return null;
|
|
138
|
+
return {
|
|
139
|
+
type: "lesson",
|
|
140
|
+
score,
|
|
141
|
+
operation: redact(lesson.operation),
|
|
142
|
+
errorSignature: redact(lesson.errorSignature),
|
|
143
|
+
fix: redact(lesson.fix),
|
|
144
|
+
prevention: redact(lesson.prevention),
|
|
145
|
+
appliesTo: lesson.appliesTo.map(redact),
|
|
146
|
+
...(lesson.taskId ? { taskId: lesson.taskId } : {}),
|
|
147
|
+
timestamp: lesson.timestamp,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
function scorePrompt(prompt, terms) {
|
|
151
|
+
const text = `${prompt.file} ${prompt.artifact} ${prompt.body}`.toLowerCase();
|
|
152
|
+
const score = matchScore(text, terms);
|
|
153
|
+
if (score <= 0)
|
|
154
|
+
return null;
|
|
155
|
+
return {
|
|
156
|
+
type: "prompt",
|
|
157
|
+
score,
|
|
158
|
+
file: prompt.file,
|
|
159
|
+
artifact: redact(prompt.artifact),
|
|
160
|
+
summary: summarize(redact(prompt.body)),
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function trimPacket(packet) {
|
|
164
|
+
const redacted = JSON.stringify(packet).includes("[REDACTED]");
|
|
165
|
+
const lessons = [...packet.lessons];
|
|
166
|
+
const prompts = [...packet.prompts];
|
|
167
|
+
let estimatedTokens = estimateTokens({ ...packet, lessons, prompts });
|
|
168
|
+
while (estimatedTokens > packet.tokenBudget &&
|
|
169
|
+
(prompts.length || lessons.length)) {
|
|
170
|
+
if (prompts.length >= lessons.length) {
|
|
171
|
+
prompts.pop();
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
lessons.pop();
|
|
175
|
+
}
|
|
176
|
+
estimatedTokens = estimateTokens({ ...packet, lessons, prompts });
|
|
177
|
+
}
|
|
178
|
+
return {
|
|
179
|
+
...packet,
|
|
180
|
+
lessons,
|
|
181
|
+
prompts,
|
|
182
|
+
estimatedTokens,
|
|
183
|
+
redaction: { ...packet.redaction, applied: redacted },
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
function estimateTokens(value) {
|
|
187
|
+
return Math.ceil(JSON.stringify(value).length / 4);
|
|
188
|
+
}
|
|
189
|
+
function uniqueTerms(values) {
|
|
190
|
+
const stop = new Set([
|
|
191
|
+
"the",
|
|
192
|
+
"and",
|
|
193
|
+
"for",
|
|
194
|
+
"with",
|
|
195
|
+
"task",
|
|
196
|
+
"before",
|
|
197
|
+
"after",
|
|
198
|
+
"none",
|
|
199
|
+
]);
|
|
200
|
+
return Array.from(new Set(values
|
|
201
|
+
.join(" ")
|
|
202
|
+
.toLowerCase()
|
|
203
|
+
.split(/[^a-z0-9_-]+/)
|
|
204
|
+
.filter((term) => term.length >= 3 && !stop.has(term)))).slice(0, 30);
|
|
205
|
+
}
|
|
206
|
+
function matchScore(text, terms) {
|
|
207
|
+
return terms.reduce((score, term) => score + (text.includes(term) ? 1 : 0), 0);
|
|
208
|
+
}
|
|
209
|
+
function summarize(value) {
|
|
210
|
+
const compact = value.replace(/\s+/g, " ").trim();
|
|
211
|
+
return compact.length > 240 ? `${compact.slice(0, 237)}...` : compact;
|
|
212
|
+
}
|
|
213
|
+
function redact(value) {
|
|
214
|
+
return value
|
|
215
|
+
.replace(/sk-[A-Za-z0-9_-]{8,}/g, "[REDACTED]")
|
|
216
|
+
.replace(/gh[pousr]_[A-Za-z0-9_]{8,}/g, "[REDACTED]")
|
|
217
|
+
.replace(/xox[baprs]-[A-Za-z0-9-]{8,}/g, "[REDACTED]")
|
|
218
|
+
.replace(/https:\/\/hooks\.slack\.com\/services\/\S+/g, "[REDACTED]")
|
|
219
|
+
.replace(/(?:secret|token|password)=\S+/gi, "$1=[REDACTED]");
|
|
220
|
+
}
|
|
221
|
+
function byScoreThenRecent(left, right) {
|
|
222
|
+
return (right.score - left.score || right.timestamp.localeCompare(left.timestamp));
|
|
223
|
+
}
|
|
224
|
+
//# sourceMappingURL=memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"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"}
|