@mnmal-ai/cortext-opencode 1.0.0-alpha.5 → 1.0.0-alpha.7
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/plugin.js +59 -25
- package/instructions/substrate-conventions.md +1 -1
- package/package.json +2 -2
package/dist/plugin.js
CHANGED
|
@@ -49,7 +49,7 @@ function claimList(raw) {
|
|
|
49
49
|
function b64url(buf) {
|
|
50
50
|
return buf.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
51
51
|
}
|
|
52
|
-
function mint(kid, key, ns, capabilities) {
|
|
52
|
+
function mint(kid, key, ns, capabilities, aud) {
|
|
53
53
|
const now = Math.floor(Date.now() / 1e3);
|
|
54
54
|
const exp = now + TTL_SECONDS;
|
|
55
55
|
const signingInput = `${b64url(Buffer.from(JSON.stringify({
|
|
@@ -58,6 +58,7 @@ function mint(kid, key, ns, capabilities) {
|
|
|
58
58
|
kid
|
|
59
59
|
}), "utf8"))}.${b64url(Buffer.from(JSON.stringify({
|
|
60
60
|
sub: kid,
|
|
61
|
+
aud,
|
|
61
62
|
iat: now,
|
|
62
63
|
exp,
|
|
63
64
|
ns,
|
|
@@ -68,6 +69,15 @@ function mint(kid, key, ns, capabilities) {
|
|
|
68
69
|
exp
|
|
69
70
|
};
|
|
70
71
|
}
|
|
72
|
+
/** The origin a token for `url` names as its `aud`; throws rather than mint a token without one. */
|
|
73
|
+
function audienceOf(url) {
|
|
74
|
+
const raw = typeof url === "object" && url !== null && "url" in url ? url.url : url;
|
|
75
|
+
try {
|
|
76
|
+
return new URL(String(raw)).origin;
|
|
77
|
+
} catch {
|
|
78
|
+
throw new Error(`cannot mint an agent token without an audience: '${raw}' is not a URL`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
71
81
|
function misconfigured(detail) {
|
|
72
82
|
return {
|
|
73
83
|
claim: null,
|
|
@@ -118,12 +128,18 @@ function createAgentAuth(env, opts) {
|
|
|
118
128
|
const capabilities = opts.capabilities ?? claimList(env.SUBSTRATE_AGENT_CAPABILITIES) ?? DEFAULT_CAPABILITIES;
|
|
119
129
|
const ns = opts.namespaces ?? claimList(env.SYNOPTIC_AGENT_NAMESPACES) ?? DEFAULT_NAMESPACES;
|
|
120
130
|
if (capabilities.includes("*")) return misconfigured(`capabilities cannot be claimed as '*' — the capability gates do a bare \`includes\` with no wildcard branch, so a wildcard claim is refused everything. Enumerate them instead, e.g. SUBSTRATE_AGENT_CAPABILITIES=${DEFAULT_CAPABILITIES.join(",")}`);
|
|
121
|
-
|
|
131
|
+
const cached = /* @__PURE__ */ new Map();
|
|
122
132
|
return {
|
|
123
|
-
|
|
133
|
+
/** @param {string|URL|Request} [url] The request URL; its origin is the token's `aud`. */
|
|
134
|
+
getAuthHeader: (url = env.SUBSTRATE_URL) => {
|
|
135
|
+
const aud = audienceOf(url);
|
|
124
136
|
const now = Math.floor(Date.now() / 1e3);
|
|
125
|
-
|
|
126
|
-
|
|
137
|
+
let entry = cached.get(aud);
|
|
138
|
+
if (entry === void 0 || entry.exp - REFRESH_SKEW <= now) {
|
|
139
|
+
entry = mint(kid, key, ns, capabilities, aud);
|
|
140
|
+
cached.set(aud, entry);
|
|
141
|
+
}
|
|
142
|
+
return `Bearer ${entry.jwt}`;
|
|
127
143
|
},
|
|
128
144
|
warning: null,
|
|
129
145
|
/** What this identity CLAIMS — the request, never the grant. See `probeWhoami` for the grant. */
|
|
@@ -140,7 +156,7 @@ function createAgentAuth(env, opts) {
|
|
|
140
156
|
*/
|
|
141
157
|
function makeSignedFetch(getAuthHeader, fetchImpl = fetch) {
|
|
142
158
|
return (url, init = {}) => {
|
|
143
|
-
const header = getAuthHeader();
|
|
159
|
+
const header = getAuthHeader(url);
|
|
144
160
|
if (header === null) return fetchImpl(url, init);
|
|
145
161
|
return fetchImpl(url, {
|
|
146
162
|
...init,
|
|
@@ -2655,26 +2671,44 @@ async function runColdStart(opts) {
|
|
|
2655
2671
|
}
|
|
2656
2672
|
})();
|
|
2657
2673
|
const rulesKey = `${namespace}/AgentRule`;
|
|
2658
|
-
const rulesP =
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2674
|
+
const rulesP = (async () => {
|
|
2675
|
+
const rows = [];
|
|
2676
|
+
let cursor;
|
|
2677
|
+
for (let page = 0; page < 20; page++) {
|
|
2678
|
+
let pagination = {};
|
|
2679
|
+
const data = await substrateQuery(substrateUrl, { [rulesKey]: {
|
|
2680
|
+
params: {
|
|
2681
|
+
where: {
|
|
2682
|
+
...projectWhere(projectSlug),
|
|
2683
|
+
active: { eq: true }
|
|
2684
|
+
},
|
|
2685
|
+
limit: 200,
|
|
2686
|
+
...cursor !== void 0 ? { cursor } : {}
|
|
2687
|
+
},
|
|
2688
|
+
fields: {
|
|
2689
|
+
shortId: true,
|
|
2690
|
+
category: true,
|
|
2691
|
+
severity: true,
|
|
2692
|
+
pinned: true,
|
|
2693
|
+
synopsis: true
|
|
2694
|
+
}
|
|
2695
|
+
} }, {
|
|
2696
|
+
fetchImpl,
|
|
2697
|
+
onUnexpectedProjection: (entries) => projectionAudit.record(entries),
|
|
2698
|
+
onFrameFailure: (k, d) => projectionAudit.recordFailure(k, d),
|
|
2699
|
+
onPagination: (p) => {
|
|
2700
|
+
pagination = p;
|
|
2701
|
+
}
|
|
2702
|
+
});
|
|
2703
|
+
if (!(rulesKey in data)) return data;
|
|
2704
|
+
rows.push(...data[rulesKey]);
|
|
2705
|
+
const { hasMore, nextCursor } = pagination[rulesKey] ?? {};
|
|
2706
|
+
if (!hasMore) return { [rulesKey]: rows };
|
|
2707
|
+
if (nextCursor === void 0) throw new Error(`${rulesKey}: hasMore with no nextCursor`);
|
|
2708
|
+
cursor = nextCursor;
|
|
2672
2709
|
}
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
onUnexpectedProjection: (entries) => projectionAudit.record(entries),
|
|
2676
|
-
onFrameFailure: (k, d) => projectionAudit.recordFailure(k, d)
|
|
2677
|
-
});
|
|
2710
|
+
throw new Error(`${rulesKey}: more than 20 pages of rules`);
|
|
2711
|
+
})();
|
|
2678
2712
|
const [data, inboxMd] = await Promise.all([rulesP, inboxP]);
|
|
2679
2713
|
await hostReportP;
|
|
2680
2714
|
const body = [
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- substrate-conventions vsynoptic-1.0.0-alpha.
|
|
1
|
+
<!-- substrate-conventions vsynoptic-1.0.0-alpha.7+9d0bf8e1 — opencode skin; plugin-owned, do not edit. Edit your own AGENTS.md instead. Body is shared with the Claude skin's fragment (test/instructions-sync.test.ts enforces it). -->
|
|
2
2
|
|
|
3
3
|
# Substrate interaction conventions
|
|
4
4
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mnmal-ai/cortext-opencode",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.7",
|
|
4
4
|
"description": "Cortext — the OpenCode skin: cold-start injection via experimental.chat.system.transform, bundling the @mnmal-ai/synoptic host into a committed dist artifact. Installed as an OpenCode plugin (\"plugin\": [\"@mnmal-ai/cortext-opencode\"]). Published to npm, not the Claude marketplace.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"access": "public"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@mnmal-ai/synoptic": "1.0.0-alpha.
|
|
28
|
+
"@mnmal-ai/synoptic": "1.0.0-alpha.7",
|
|
29
29
|
"@opencode-ai/plugin": "^1.18.35",
|
|
30
30
|
"@opencode/plugin": "^2.0.24",
|
|
31
31
|
"@types/node": "^26.6.4",
|