@adonis-agora/agent 0.25.4 → 0.26.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.
@@ -1,3 +1,4 @@
1
+ import { resolveAccessDeniedPage } from './access_denied_page.js';
1
2
  /**
2
3
  * Decide whether a request may reach the dashboard, WITHOUT touching the response — so it is unit
3
4
  * testable free of the AdonisJS router/app: resolve the actor through the agent config's resolver
@@ -68,4 +69,58 @@ export async function evaluateDashboardGate(ctx, actorResolver, authorize, debug
68
69
  }
69
70
  return { ok: true };
70
71
  }
72
+ /**
73
+ * Write a refused {@link DashboardGateVerdict} to the response — shared by BOTH dashboard providers
74
+ * (embedded and standalone) so they refuse identically. A browser is what hits these routes (the
75
+ * SPA shell and its assets), so the body is the built-in access-denied page (or the host's
76
+ * `accessDenied` customisation of it), not the JSON the governance API answers with.
77
+ *
78
+ * Stands down when the request is already answered: `onUnauthenticated`/`authorize` (or the
79
+ * renderer) writing a redirect keeps it — the `location`-header rule the providers have always
80
+ * honoured. The verdict's `error` is shown on the page as a developer detail only when it is more
81
+ * than the generic word (i.e. the `debug` message outside production, or the static "no actor
82
+ * resolver configured" operator hint).
83
+ */
84
+ export async function answerDashboardDenial(ctx, verdict, options) {
85
+ const answered = () => responseAnswered(ctx);
86
+ if (answered())
87
+ return;
88
+ const nonce = cspNonce(ctx);
89
+ const generic = verdict.error === 'unauthorized' || verdict.error === 'forbidden';
90
+ const info = {
91
+ status: verdict.status,
92
+ reason: verdict.status === 401 ? 'unauthenticated' : 'forbidden',
93
+ basePath: options.basePath,
94
+ ...(generic ? {} : { detail: verdict.error }),
95
+ ...(nonce !== undefined ? { nonce } : {}),
96
+ };
97
+ const html = await resolveAccessDeniedPage(info, options.accessDenied, ctx, answered);
98
+ if (html === null)
99
+ return;
100
+ ctx.response
101
+ .status(info.status)
102
+ .header('content-type', 'text/html; charset=utf-8')
103
+ .header('cache-control', 'no-store, must-revalidate')
104
+ .send(html);
105
+ }
106
+ /**
107
+ * Whether something already answered this request: a redirect (`location` header) or a body queued
108
+ * on the response. The body check reads AdonisJS's `response.hasLazyBody` structurally so a
109
+ * plain-object `ctx` double in a unit test (which has neither) still works.
110
+ */
111
+ function responseAnswered(ctx) {
112
+ if (ctx.response.getHeader('location'))
113
+ return true;
114
+ const response = ctx.response;
115
+ return response.hasLazyBody === true || response.headersSent === true;
116
+ }
117
+ /**
118
+ * The request's CSP nonce when the host runs `@adonisjs/shield` with `@nonce` in its policy (shield
119
+ * exposes it as `response.nonce`). Read structurally: this package neither depends on shield nor
120
+ * cares which middleware minted the nonce — only that the page's inline `<style>` carries it.
121
+ */
122
+ function cspNonce(ctx) {
123
+ const nonce = ctx.response.nonce;
124
+ return typeof nonce === 'string' && nonce !== '' ? nonce : undefined;
125
+ }
71
126
  //# sourceMappingURL=gate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"gate.js","sourceRoot":"","sources":["../../../src/dashboard/gate.ts"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,GAAgB,EAChB,aAAwC,EACxC,SAAmC,EACnC,KAAK,GAAG,KAAK,EACb,iBAAqD;IAErD,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,iBAAiB,EAAE,CAAC,GAAG,CAAC,CAAC;QAC/B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,8BAA8B,EAAE,CAAC;IAC3E,CAAC;IACD,IAAI,KAAoD,CAAC;IACzD,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC3C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,iBAAiB,EAAE,CAAC,GAAG,CAAC,CAAC;QAC/B,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,GAAG;YACX,KAAK,EAAE,KAAK,IAAI,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc;SACxE,CAAC;IACJ,CAAC;IACD,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,IAAI,CAAC,CAAC,MAAM,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;gBACnC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;YACxD,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,GAAG;gBACX,KAAK,EAAE,KAAK,IAAI,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW;aACrE,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AACtB,CAAC"}
1
+ {"version":3,"file":"gate.js","sourceRoot":"","sources":["../../../src/dashboard/gate.ts"],"names":[],"mappings":"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"}
@@ -14,7 +14,9 @@
14
14
  * so a package.json edge back from here to there would be circular. See
15
15
  * `providers/dashboard_provider.ts`'s module doc for the full story.
16
16
  */
17
- export { type AgentDashboardAuthorize, type AgentDashboardConfig, type AgentDashboardUnauthenticatedHook, type DashboardMountDecision, decideDashboardMount, type ResolvedAgentDashboardConfig, resolveDashboardConfig, } from './define_config.js';
18
- export { type DashboardGateVerdict, evaluateDashboardGate } from './gate.js';
19
- export { apiBaseFor, contentTypeFor, injectApiBase, injectBaseHref, mountPathFor, safeAssetSegments, trimSlashes, } from './paths.js';
17
+ export type { AccessDeniedInfo, AccessDeniedPageOptions, AccessDeniedReason, } from './access_denied_page.js';
18
+ export { CONSOLE as ACCESS_DENIED_CONSOLE, escapeHtml, renderAccessDeniedPage, resolveAccessDeniedPage, } from './access_denied_page.js';
19
+ export { type AccessDeniedOption, type AccessDeniedRenderer, type AgentDashboardAuthorize, type AgentDashboardConfig, type AgentDashboardUnauthenticatedHook, type DashboardMountDecision, decideDashboardMount, type ResolvedAgentDashboardConfig, resolveDashboardConfig, } from './define_config.js';
20
+ export { answerDashboardDenial, type DashboardDenialOptions, type DashboardGateVerdict, evaluateDashboardGate, } from './gate.js';
21
+ export { apiBaseFor, CONFIG_ELEMENT_ID, contentTypeFor, injectApiBase, injectBaseHref, mountPathFor, safeAssetSegments, trimSlashes, } from './paths.js';
20
22
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/dashboard/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EACzB,KAAK,iCAAiC,EACtC,KAAK,sBAAsB,EAC3B,oBAAoB,EACpB,KAAK,4BAA4B,EACjC,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,KAAK,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAC7E,OAAO,EACL,UAAU,EACV,cAAc,EACd,aAAa,EACb,cAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,WAAW,GACZ,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/dashboard/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,YAAY,EACV,gBAAgB,EAChB,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,OAAO,IAAI,qBAAqB,EAChC,UAAU,EACV,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EACzB,KAAK,iCAAiC,EACtC,KAAK,sBAAsB,EAC3B,oBAAoB,EACpB,KAAK,4BAA4B,EACjC,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,qBAAqB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,qBAAqB,GACtB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,cAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,WAAW,GACZ,MAAM,YAAY,CAAC"}
@@ -1,20 +1,6 @@
1
- /**
2
- * Serving helpers for the `@adonis-agora/agent-dashboard` governance SPA — the config shape, the
3
- * mount/gate decisions, and the pure path/asset helpers. Framework-light (no AdonisJS router/app
4
- * dependency), so they're unit-testable in isolation and reusable by BOTH dashboard providers:
5
- *
6
- * - `@adonis-agora/agent/dashboard_provider` (this package, `providers/dashboard_provider.ts`) —
7
- * embedded: registered automatically by `node ace configure @adonis-agora/agent`, serves the SPA
8
- * bundle copied into THIS package's own `dist/assets/spa` at build time.
9
- * - `@adonis-agora/agent-dashboard`'s own provider (`agent_dashboard_provider.ts`) — standalone: an
10
- * independently installable/registrable package some apps already depend on directly.
11
- *
12
- * Living here (rather than in `@adonis-agora/agent-dashboard`) keeps the dependency direction
13
- * one-way: the dashboard package already depends on this one for `AgentConfig`/`ActorResolver`/etc.,
14
- * so a package.json edge back from here to there would be circular. See
15
- * `providers/dashboard_provider.ts`'s module doc for the full story.
16
- */
1
+ // The built-in "access denied" page (what a browser sees on a refused page navigation).
2
+ export { CONSOLE as ACCESS_DENIED_CONSOLE, escapeHtml, renderAccessDeniedPage, resolveAccessDeniedPage, } from './access_denied_page.js';
17
3
  export { decideDashboardMount, resolveDashboardConfig, } from './define_config.js';
18
- export { evaluateDashboardGate } from './gate.js';
19
- export { apiBaseFor, contentTypeFor, injectApiBase, injectBaseHref, mountPathFor, safeAssetSegments, trimSlashes, } from './paths.js';
4
+ export { answerDashboardDenial, evaluateDashboardGate, } from './gate.js';
5
+ export { apiBaseFor, CONFIG_ELEMENT_ID, contentTypeFor, injectApiBase, injectBaseHref, mountPathFor, safeAssetSegments, trimSlashes, } from './paths.js';
20
6
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/dashboard/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAKL,oBAAoB,EAEpB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAA6B,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAC7E,OAAO,EACL,UAAU,EACV,cAAc,EACd,aAAa,EACb,cAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,WAAW,GACZ,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/dashboard/index.ts"],"names":[],"mappings":"AAqBA,wFAAwF;AACxF,OAAO,EACL,OAAO,IAAI,qBAAqB,EAChC,UAAU,EACV,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAOL,oBAAoB,EAEpB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,qBAAqB,EAGrB,qBAAqB,GACtB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,cAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,WAAW,GACZ,MAAM,YAAY,CAAC"}
@@ -23,10 +23,19 @@ export declare function contentTypeFor(filename: string): string;
23
23
  * Returns the safe, normalized relative segments (never starting with `..`), or `null` to deny.
24
24
  */
25
25
  export declare function safeAssetSegments(wildcard: string | string[] | undefined): string[] | null;
26
+ /** `id` of the JSON data block {@link injectApiBase} emits; the SPA's `resolveApiBase()` reads it. */
27
+ export declare const CONFIG_ELEMENT_ID = "agent-dashboard-config";
26
28
  /**
27
- * Inject the resolved agent API base into the served `index.html` as a global the SPA reads before
28
- * boot, so the client calls the exact base the provider mounted (no build-time coupling). Idempotent
29
- * per response — inserted right before `</head>`.
29
+ * Hand the resolved agent API base to the served `index.html`, so the client calls the exact base
30
+ * the provider mounted (no build-time coupling). Inserted right before `</head>`.
31
+ *
32
+ * It goes in as a JSON DATA BLOCK (`<script type="application/json">{"apiBase":…}</script>`), not
33
+ * as an inline script assigning `window.__AGENT_DASHBOARD_BASE__`. A data block is never executed,
34
+ * so no Content-Security-Policy can refuse it; an inline script IS, and a host with
35
+ * `script-src 'self' 'nonce-…'` (`@adonisjs/shield`'s `@nonce`, the recommended setup) silently
36
+ * dropped ours — the SPA then derived a base from its own URL, which is right only for the default
37
+ * mount, and on any other every request from a console that had rendered perfectly answered 404.
38
+ * The global is still read by the SPA as a fallback, but this is no longer how the provider speaks.
30
39
  */
31
40
  export declare function injectApiBase(html: string, apiBase: string): string;
32
41
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../src/dashboard/paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,wFAAwF;AACxF,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,8FAA8F;AAC9F,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAGpD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAM9E;AAsBD,8FAA8F;AAC9F,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAIvD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,GAAG,MAAM,EAAE,GAAG,IAAI,CAU1F;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAInE;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAQlE"}
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../src/dashboard/paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,wFAAwF;AACxF,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,8FAA8F;AAC9F,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAGpD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAM9E;AAsBD,8FAA8F;AAC9F,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAIvD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,GAAG,MAAM,EAAE,GAAG,IAAI,CAU1F;AAED,sGAAsG;AACtG,eAAO,MAAM,iBAAiB,2BAA2B,CAAC;AAE1D;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAOnE;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAQlE"}
@@ -69,13 +69,25 @@ export function safeAssetSegments(wildcard) {
69
69
  }
70
70
  return segments;
71
71
  }
72
+ /** `id` of the JSON data block {@link injectApiBase} emits; the SPA's `resolveApiBase()` reads it. */
73
+ export const CONFIG_ELEMENT_ID = 'agent-dashboard-config';
72
74
  /**
73
- * Inject the resolved agent API base into the served `index.html` as a global the SPA reads before
74
- * boot, so the client calls the exact base the provider mounted (no build-time coupling). Idempotent
75
- * per response — inserted right before `</head>`.
75
+ * Hand the resolved agent API base to the served `index.html`, so the client calls the exact base
76
+ * the provider mounted (no build-time coupling). Inserted right before `</head>`.
77
+ *
78
+ * It goes in as a JSON DATA BLOCK (`<script type="application/json">{"apiBase":…}</script>`), not
79
+ * as an inline script assigning `window.__AGENT_DASHBOARD_BASE__`. A data block is never executed,
80
+ * so no Content-Security-Policy can refuse it; an inline script IS, and a host with
81
+ * `script-src 'self' 'nonce-…'` (`@adonisjs/shield`'s `@nonce`, the recommended setup) silently
82
+ * dropped ours — the SPA then derived a base from its own URL, which is right only for the default
83
+ * mount, and on any other every request from a console that had rendered perfectly answered 404.
84
+ * The global is still read by the SPA as a fallback, but this is no longer how the provider speaks.
76
85
  */
77
86
  export function injectApiBase(html, apiBase) {
78
- const tag = `<script>window.__AGENT_DASHBOARD_BASE__=${JSON.stringify(apiBase)}</script>`;
87
+ // `<` escaped as `\u003c` inside the JSON: a data block ends at the first `</script`, and a
88
+ // config value must not be able to close it early. Valid JSON either way.
89
+ const json = JSON.stringify({ apiBase }).replace(/</g, '\\u003c');
90
+ const tag = `<script type="application/json" id="${CONFIG_ELEMENT_ID}">${json}</script>`;
79
91
  if (html.includes('</head>'))
80
92
  return html.replace('</head>', `${tag}</head>`);
81
93
  return `${tag}${html}`;
@@ -1 +1 @@
1
- {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/dashboard/paths.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/dashboard/paths.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- export declare const VERSION = "0.25.4";
1
+ export declare const VERSION = "0.26.0";
2
2
  export { configure } from '../configure.js';
3
3
  export * from './actor-labels.js';
4
4
  export type { AuthActorResolverOptions } from './actor-resolver.js';
package/dist/src/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export const VERSION = '0.25.4';
1
+ export const VERSION = '0.26.0';
2
2
  // Re-export the configure hook from the package root so `node ace configure` finds it.
3
3
  // AdonisJS imports the package MAIN and reads `configure` off the module namespace —
4
4
  // the `./configure` subpath alone is never consulted.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adonis-agora/agent",
3
- "version": "0.25.4",
3
+ "version": "0.26.0",
4
4
  "description": "Governed, durable-backed AI agent (chat + tool-calling + governance) for AdonisJS — part of the Agora ecosystem.",
5
5
  "license": "MIT",
6
6
  "repository": {