@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 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
- let cached = null;
131
+ const cached = /* @__PURE__ */ new Map();
122
132
  return {
123
- getAuthHeader: () => {
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
- if (cached === null || cached.exp - REFRESH_SKEW <= now) cached = mint(kid, key, ns, capabilities);
126
- return `Bearer ${cached.jwt}`;
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 = substrateQuery(substrateUrl, { [rulesKey]: {
2659
- params: {
2660
- where: {
2661
- ...projectWhere(projectSlug),
2662
- active: { eq: true }
2663
- },
2664
- limit: 200
2665
- },
2666
- fields: {
2667
- shortId: true,
2668
- category: true,
2669
- severity: true,
2670
- pinned: true,
2671
- synopsis: true
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
- fetchImpl,
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.5+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). -->
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.5",
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.5",
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",