@adonis-agora/agent-dashboard 0.5.0 → 0.6.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/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @adonis-agora/agent-dashboard
2
2
 
3
+ ## 0.6.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`58783fb`](https://github.com/DavideCarvalho/adonis-agora-agent/commit/58783fb433fd3c641dc9a42b80eaba09f2c9a62b) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - `@adonis-agora/agent` now ships its own governance dashboard — `node ace configure @adonis-agora/agent` registers an embedded `dashboard_provider` that serves the `@adonis-agora/agent-dashboard` SPA straight out of `@adonis-agora/agent`'s own build (`../dashboard/dist/spa` is copied into `dist/assets/spa` at build time), so a new app needs no separate install or provider registration to get the console. Configure it via the same optional `config('agent').dashboard` block as before.
8
+
9
+ This is purely additive: the standalone `@adonis-agora/agent-dashboard` package and its own `agent_dashboard_provider` keep working exactly as before for apps that already install and register it directly — both providers now share one implementation (`@adonis-agora/agent/dashboard`, a new subpath export) so their behavior is byte-for-byte identical. Register only one of the two in a given app; mounting both at the same path throws AdonisJS's "duplicate route" error at boot.
10
+
11
+ `@adonis-agora/agent-dashboard`'s peer dependency floor on `@adonis-agora/agent` moves to `>=0.21.0` (the version that introduces the shared `@adonis-agora/agent/dashboard` export its provider now imports from); already-published `agent-dashboard` versions are unaffected.
12
+
3
13
  ## 0.5.0
4
14
 
5
15
  ### Minor Changes
package/README.md CHANGED
@@ -20,7 +20,17 @@ All data comes from the agent provider's **real** routes — the SPA is a pure c
20
20
 
21
21
  ## Install
22
22
 
23
+ As of `@adonis-agora/agent@0.21.0`, **you don't need to install this package at all**:
24
+ `node ace configure @adonis-agora/agent` registers an embedded dashboard provider that serves this
25
+ exact SPA (bundled straight into `@adonis-agora/agent`'s own `dist/` at build time) at
26
+ `<agentPath>/dashboard` — no separate install, no separate provider registration. See the
27
+ [`@adonis-agora/agent` README's Dashboard section](../adonis/README.md#dashboard).
28
+
29
+ This package still ships and installs standalone, for apps that configured it before the embedded
30
+ provider existed, or that want its independent release cadence:
31
+
23
32
  ```sh
33
+ pnpm add @adonis-agora/agent-dashboard
24
34
  node ace add @adonis-agora/agent-dashboard
25
35
  ```
26
36
 
@@ -35,7 +45,8 @@ providers: [
35
45
 
36
46
  The dashboard reads `config/agent.ts` for the agent `path` and `actorResolver`, mounts the SPA at
37
47
  `<agentPath>/dashboard` (default `/agent/dashboard`), and gates every request through the **same**
38
- actor resolver as the governance routes. Toggle or relocate it with an optional block:
48
+ actor resolver as the governance routes. Toggle or relocate it with an optional block — the SAME block
49
+ the embedded provider reads, so switching between the two needs no config change:
39
50
 
40
51
  ```ts
41
52
  // config/agent.ts
@@ -45,6 +56,9 @@ export default defineConfig({
45
56
  })
46
57
  ```
47
58
 
59
+ Register only ONE of the two providers (the embedded one from `@adonis-agora/agent`, or this
60
+ package's): mounting both at the same path throws AdonisJS's "duplicate route" error at boot.
61
+
48
62
  ## Browser client
49
63
 
50
64
  The framework-free fetch client is exported for reuse:
@@ -17,6 +17,16 @@ import type { ApplicationService } from '@adonisjs/core/types';
17
17
  * every panel but Quota. The provider declines and logs why (see `decideDashboardMount`).
18
18
  *
19
19
  * Enable/disable and override the mount via the optional `config('agent').dashboard` block.
20
+ *
21
+ * As of `@adonis-agora/agent@0.21.0`, THIS is no longer the only way to get the console: the agent
22
+ * package now ALSO ships its own embedded `@adonis-agora/agent/dashboard_provider`, wired
23
+ * automatically by `node ace configure @adonis-agora/agent`, that serves the identical SPA bundled
24
+ * straight into `@adonis-agora/agent`'s own `dist/`. This standalone package keeps working exactly as
25
+ * before for apps that already install and register it directly — nothing here changed except WHERE
26
+ * the shared config/gate/path logic lives (`@adonis-agora/agent/dashboard`, imported above, rather
27
+ * than a local `src/server/*` copy) so both providers stay byte-for-byte identical in behavior. An
28
+ * app should register ONE of the two: registering both at the same mount path throws AdonisJS's
29
+ * "duplicate route" error at boot.
20
30
  */
21
31
  export default class AgentDashboardProvider {
22
32
  protected app: ApplicationService;
@@ -1 +1 @@
1
- {"version":3,"file":"agent_dashboard_provider.d.ts","sourceRoot":"","sources":["../../providers/agent_dashboard_provider.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAiB/D;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,OAAO,OAAO,sBAAsB;IAC7B,SAAS,CAAC,GAAG,EAAE,kBAAkB;gBAAvB,GAAG,EAAE,kBAAkB;IAE7C,+FAA+F;IAC/F,OAAO,CAAC,SAAS,CAAuC;IAElD,IAAI;IAsDV;;;;;OAKG;YACW,IAAI;IAalB;;;OAGG;YACW,SAAS;IAOvB,4FAA4F;YAC9E,SAAS;CAmBxB"}
1
+ {"version":3,"file":"agent_dashboard_provider.d.ts","sourceRoot":"","sources":["../../providers/agent_dashboard_provider.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,CAAC,OAAO,OAAO,sBAAsB;IAC7B,SAAS,CAAC,GAAG,EAAE,kBAAkB;gBAAvB,GAAG,EAAE,kBAAkB;IAE7C,+FAA+F;IAC/F,OAAO,CAAC,SAAS,CAAuC;IAElD,IAAI;IAsDV;;;;;OAKG;YACW,IAAI;IAalB;;;OAGG;YACW,SAAS;IAOvB,4FAA4F;YAC9E,SAAS;CAmBxB"}
@@ -1,7 +1,5 @@
1
1
  import { readFile } from 'node:fs/promises';
2
- import { decideDashboardMount, resolveDashboardConfig, } from '../src/server/define_config.js';
3
- import { evaluateDashboardGate } from '../src/server/gate.js';
4
- import { apiBaseFor, contentTypeFor, injectApiBase, injectBaseHref, mountPathFor, safeAssetSegments, } from '../src/server/paths.js';
2
+ import { apiBaseFor, contentTypeFor, decideDashboardMount, evaluateDashboardGate, injectApiBase, injectBaseHref, mountPathFor, resolveDashboardConfig, safeAssetSegments, } from '@adonis-agora/agent/dashboard';
5
3
  /**
6
4
  * Serves the `@adonis-agora/agent-dashboard` governance SPA (a Vite build in `dist/spa`) as static
7
5
  * assets under `<agentPath>/dashboard`, behind the SAME actor gating as the agent's governance
@@ -20,6 +18,16 @@ import { apiBaseFor, contentTypeFor, injectApiBase, injectBaseHref, mountPathFor
20
18
  * every panel but Quota. The provider declines and logs why (see `decideDashboardMount`).
21
19
  *
22
20
  * Enable/disable and override the mount via the optional `config('agent').dashboard` block.
21
+ *
22
+ * As of `@adonis-agora/agent@0.21.0`, THIS is no longer the only way to get the console: the agent
23
+ * package now ALSO ships its own embedded `@adonis-agora/agent/dashboard_provider`, wired
24
+ * automatically by `node ace configure @adonis-agora/agent`, that serves the identical SPA bundled
25
+ * straight into `@adonis-agora/agent`'s own `dist/`. This standalone package keeps working exactly as
26
+ * before for apps that already install and register it directly — nothing here changed except WHERE
27
+ * the shared config/gate/path logic lives (`@adonis-agora/agent/dashboard`, imported above, rather
28
+ * than a local `src/server/*` copy) so both providers stay byte-for-byte identical in behavior. An
29
+ * app should register ONE of the two: registering both at the same mount path throws AdonisJS's
30
+ * "duplicate route" error at boot.
23
31
  */
24
32
  export default class AgentDashboardProvider {
25
33
  app;
@@ -1 +1 @@
1
- {"version":3,"file":"agent_dashboard_provider.js","sourceRoot":"","sources":["../../providers/agent_dashboard_provider.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent_dashboard_provider.js","sourceRoot":"","sources":["../../providers/agent_dashboard_provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAGL,UAAU,EACV,cAAc,EACd,oBAAoB,EACpB,qBAAqB,EACrB,aAAa,EACb,cAAc,EACd,YAAY,EACZ,sBAAsB,EACtB,iBAAiB,GAClB,MAAM,+BAA+B,CAAC;AAIvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,CAAC,OAAO,OAAO,sBAAsB;IACnB;IAAtB,YAAsB,GAAuB;QAAvB,QAAG,GAAH,GAAG,CAAoB;IAAG,CAAC;IAEjD,+FAA+F;IACvF,SAAS,GAAG,IAAI,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAExD,KAAK,CAAC,IAAI;QACR,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAc,OAAO,EAAE,EAAiB,CAAC,CAAC;QACjF,MAAM,eAAe,GAAG,sBAAsB,CAC5C,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAuB,iBAAiB,EAAE,EAAE,CAAC,CACjE,CAAC;QAEF,yFAAyF;QACzF,mGAAmG;QACnG,mGAAmG;QACnG,MAAM,QAAQ,GAAG,oBAAoB,CACnC,eAAe,CAAC,OAAO,EACvB,WAAW,CAAC,mBAAmB,EAC/B,WAAW,CAAC,iBAAiB,CAC9B,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;YACpB,IAAI,QAAQ,CAAC,MAAM,KAAK,UAAU;gBAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YACnE,OAAO;QACT,CAAC;QAED,mGAAmG;QACnG,8FAA8F;QAC9F,oGAAoG;QACpG,gGAAgG;QAChG,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEvD,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,IAAI,OAAO,CAAC;QAC9C,MAAM,OAAO,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;QACtC,MAAM,KAAK,GAAG,YAAY,CAAC,SAAS,EAAE,eAAe,CAAC,IAAI,CAAC,CAAC;QAC5D,MAAM,aAAa,GAAG,WAAW,CAAC,aAAa,CAAC;QAEhD,MAAM,SAAS,GAAG,eAAe,CAAC,SAAS,CAAC;QAE5C,+FAA+F;QAC/F,6FAA6F;QAC7F,qFAAqF;QACrF,+FAA+F;QAC/F,8EAA8E;QAC9E,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YAC9B,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,EAAE,SAAS,CAAC,CAAC;gBAAE,OAAO;YAC9D,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,wFAAwF;QACxF,sDAAsD;QACtD,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YACrC,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,EAAE,SAAS,CAAC,CAAC;gBAAE,OAAO;YAC9D,MAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YACpD,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;gBACtB,OAAO,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;YACpE,CAAC;YACD,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACK,KAAK,CAAC,IAAI,CAChB,GAAgB,EAChB,aAAwC,EACxC,SAAmC;QAEnC,MAAM,OAAO,GAAG,MAAM,qBAAqB,CAAC,GAAG,EAAE,aAAa,EAAE,SAAS,CAAC,CAAC;QAC3E,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;YAChB,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;YACnE,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,SAAS,CAAC,GAAgB,EAAE,OAAe,EAAE,KAAa;QACtE,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC;QAC3E,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,cAAc,EAAE,0BAA0B,CAAC,CAAC;QAChE,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,eAAe,EAAE,2BAA2B,CAAC,CAAC;QAClE,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;IACzE,CAAC;IAED,4FAA4F;IACpF,KAAK,CAAC,SAAS,CACrB,GAAgB,EAChB,QAAkB,EAClB,OAAe,EACf,KAAa;QAEb,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,YAAY,CAAC;QAC/D,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;YAC3E,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,cAAc,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC9D,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC5B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACvD,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;gBAC1C,OAAO;YACT,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;CACF"}
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@adonis-agora/agent-dashboard",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Read-only governance console (spend by model/actor, usage trend, recent threads & tool calls, quota) for @adonis-agora/agent — a dependency-light React SPA served by a thin AdonisJS provider. Part of the Agora ecosystem.",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
8
- "url": "git+https://github.com/DavideCarvalho/adonis-agent.git",
8
+ "url": "git+https://github.com/DavideCarvalho/adonis-agora-agent.git",
9
9
  "directory": "packages/dashboard"
10
10
  },
11
11
  "author": "Davi Carvalho <davi@goflip.ai>",
@@ -37,7 +37,7 @@
37
37
  "sideEffects": false,
38
38
  "peerDependencies": {
39
39
  "@adonisjs/core": "^7.3.0",
40
- "@adonis-agora/agent": ">=0.4.0 <1.0.0"
40
+ "@adonis-agora/agent": ">=0.21.0 <1.0.0"
41
41
  },
42
42
  "peerDependenciesMeta": {
43
43
  "@adonisjs/core": {
@@ -46,21 +46,21 @@
46
46
  },
47
47
  "devDependencies": {
48
48
  "@adonisjs/core": "7.4.0",
49
- "@testing-library/react": "^16.1.0",
50
- "@types/node": "^22.0.0",
49
+ "@testing-library/react": "16.3.2",
50
+ "@types/node": "22.20.0",
51
51
  "@types/react": "19.2.18",
52
52
  "@types/react-dom": "19.2.4",
53
- "@vitejs/plugin-react": "^4.3.4",
54
- "jsdom": "^25.0.1",
53
+ "@vitejs/plugin-react": "4.7.0",
54
+ "jsdom": "25.0.1",
55
55
  "react": "19.2.8",
56
56
  "react-dom": "19.2.8",
57
- "typescript": "^5.4.0",
58
- "vite": "^7.0.0",
59
- "vitest": "^3.0.0",
60
- "@adonis-agora/agent": "0.20.0"
57
+ "typescript": "5.9.3",
58
+ "vite": "7.3.6",
59
+ "vitest": "3.2.7",
60
+ "@adonis-agora/agent": "0.21.0"
61
61
  },
62
62
  "engines": {
63
- "node": ">=22.0.0"
63
+ "node": "v26.7.0"
64
64
  },
65
65
  "keywords": [
66
66
  "adonisjs",
@@ -76,7 +76,8 @@
76
76
  "agora"
77
77
  ],
78
78
  "scripts": {
79
- "build": "pnpm run clean && vite build && tsc -p tsconfig.build.json && pnpm run check:dist",
79
+ "build": "pnpm run clean && pnpm run build:spa && tsc -p tsconfig.build.json && pnpm run check:dist",
80
+ "build:spa": "vite build",
80
81
  "check:dist": "node ../../scripts/assert-build-output.mjs dist providers/agent_dashboard_provider.js",
81
82
  "clean": "rm -rf dist",
82
83
  "test": "vitest run --passWithNoTests",
@@ -1,69 +0,0 @@
1
- import type { Actor, AgentGovernanceAuthorize } from '@adonis-agora/agent';
2
- import type { HttpContext } from '@adonisjs/core/http';
3
- /**
4
- * An extra authorization gate for the dashboard, run AFTER the agent config's `actorResolver` has
5
- * resolved the caller. Return `false` (or throw) to deny — the request gets `403`. The governance
6
- * read-model the SPA serves spans EVERY actor's spend/usage, so most apps restrict the console beyond
7
- * mere authentication, e.g. `(actor) => actor.roles?.includes('ADMIN') ?? false`.
8
- */
9
- export type AgentDashboardAuthorize = (actor: Actor, ctx: HttpContext) => boolean | Promise<boolean>;
10
- /**
11
- * Optional `config('agent').dashboard` block. The dashboard reuses the agent config's `path` and
12
- * `actorResolver` (so it sits behind the SAME actor gating as the governance routes); this block
13
- * toggles it on/off, optionally overrides the mount path, and optionally adds an `authorize` gate.
14
- */
15
- export interface AgentDashboardConfig {
16
- /**
17
- * Mount the SPA. Default `true` — set `false` to keep the routes off entirely. Note `true` is
18
- * necessary but not sufficient: the console also needs the agent's `governanceAuthorize` gate, see
19
- * {@link decideDashboardMount}.
20
- */
21
- enabled?: boolean;
22
- /** Override the mount path. Default `<agentPath>/dashboard`. */
23
- path?: string;
24
- /**
25
- * Extra authorization run after the actor resolves. Return `false` to deny (`403`). Omit to allow
26
- * any resolved actor (the default) — note this is only an EXTRA gate on the SPA shell; whether the
27
- * console mounts at all, and whether its data is readable, is decided by the agent config's
28
- * `governanceAuthorize`.
29
- */
30
- authorize?: AgentDashboardAuthorize;
31
- }
32
- export interface ResolvedAgentDashboardConfig {
33
- enabled: boolean;
34
- path?: string;
35
- authorize?: AgentDashboardAuthorize;
36
- }
37
- /** Fill defaults for the optional dashboard config block. */
38
- export declare function resolveDashboardConfig(config: AgentDashboardConfig | undefined): ResolvedAgentDashboardConfig;
39
- /** Whether the provider registers the console's routes, and (when it refuses) what to say about it. */
40
- export type DashboardMountDecision = {
41
- mount: true;
42
- } | {
43
- mount: false;
44
- reason: 'disabled';
45
- } | {
46
- mount: false;
47
- reason: 'no-governance-gate';
48
- warning: string;
49
- } | {
50
- mount: false;
51
- reason: 'no-governance-queries';
52
- warning: string;
53
- };
54
- /**
55
- * Decide whether to register the console's routes at all — the router-free core of the provider's
56
- * mount check, extracted so it can be unit tested without booting an app.
57
- *
58
- * The console is a pure consumer of the agent's cross-actor `/agent/governance/*` read routes, and
59
- * those routes are not mounted unless the agent config carries a `governanceAuthorize` gate. Serving
60
- * a shell that can only 404 its own data is worse than not serving it: the failure shows up as seven
61
- * dead panels at click time with nothing anywhere explaining why. So the console follows the same
62
- * fail-closed-by-omission rule one layer down — no gate, no routes — and says so at boot.
63
- *
64
- * This costs nothing that still works: every app affected is an app whose console is ALREADY dead in
65
- * every view but Quota. `dashboard.authorize` is deliberately NOT the trigger; it gates the shell,
66
- * not the data, and an app can set it and still have a console with nothing to render.
67
- */
68
- export declare function decideDashboardMount(enabled: boolean, governanceAuthorize: AgentGovernanceAuthorize | undefined, governanceQueries?: unknown): DashboardMountDecision;
69
- //# sourceMappingURL=define_config.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"define_config.d.ts","sourceRoot":"","sources":["../../../src/server/define_config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD;;;;;GAKG;AACH,MAAM,MAAM,uBAAuB,GAAG,CACpC,KAAK,EAAE,KAAK,EACZ,GAAG,EAAE,WAAW,KACb,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEhC;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gEAAgE;IAChE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,SAAS,CAAC,EAAE,uBAAuB,CAAC;CACrC;AAED,MAAM,WAAW,4BAA4B;IAC3C,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,uBAAuB,CAAC;CACrC;AAED,6DAA6D;AAC7D,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,oBAAoB,GAAG,SAAS,GACvC,4BAA4B,CAK9B;AAED,uGAAuG;AACvG,MAAM,MAAM,sBAAsB,GAC9B;IAAE,KAAK,EAAE,IAAI,CAAA;CAAE,GACf;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,UAAU,CAAA;CAAE,GACpC;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,oBAAoB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC/D;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,uBAAuB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAoBvE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,EAChB,mBAAmB,EAAE,wBAAwB,GAAG,SAAS,EACzD,iBAAiB,CAAC,EAAE,OAAO,GAC1B,sBAAsB,CAgBxB"}
@@ -1,56 +0,0 @@
1
- /** Fill defaults for the optional dashboard config block. */
2
- export function resolveDashboardConfig(config) {
3
- const resolved = { enabled: config?.enabled ?? true };
4
- if (config?.path !== undefined)
5
- resolved.path = config.path;
6
- if (config?.authorize !== undefined)
7
- resolved.authorize = config.authorize;
8
- return resolved;
9
- }
10
- /**
11
- * The exact wording the provider logs when it declines to mount. Mirrors the agent provider's own
12
- * governance boot warning — same three facts, same vocabulary — so a reader who sees one recognises
13
- * the other.
14
- */
15
- const NO_GOVERNANCE_GATE_WARNING = '[@adonis-agora/agent-dashboard] the governance console was NOT mounted: every panel but Quota reads the cross-actor `/agent/governance/*` routes, and those are themselves not mounted because no `governanceAuthorize` gate is configured — so the console would load and then fail on every panel. Set `governanceAuthorize` in config/agent.ts (e.g. an ADMIN check) to mount the routes and this console gated, or `governanceAuthorize: () => true` to deliberately restore the old behaviour of letting ANY authenticated actor read them. `GET /agent/approvals/mine` is unaffected — it stays mounted and scoped to the calling actor. To keep the console off on purpose and silence this, set `dashboard: { enabled: false }`.';
16
- /**
17
- * The wording logged when the read-model itself was turned off. Deliberately distinct from
18
- * {@link NO_GOVERNANCE_GATE_WARNING}: both produce the same dead console, and an operator staring at
19
- * a 404 must be able to tell from the log ALONE which of the two knobs is responsible. A shared
20
- * "governance is not configured" message would recreate exactly the diagnosability problem this
21
- * check exists to remove.
22
- */
23
- const NO_GOVERNANCE_QUERIES_WARNING = '[@adonis-agora/agent-dashboard] the governance console was NOT mounted: `governanceQueries` is set to `false` in config/agent.ts, so the cross-actor read-model was never built and the `/agent/governance/*` routes it serves do not exist — the console would load and then fail on every panel but Quota. A `governanceAuthorize` gate is NOT the missing piece here; it is already configured. Remove `governanceQueries: false` (omit it to get the Lucid read-model when the main store is Lucid, or pass a store/factory explicitly) to mount the read-model and this console. To keep the console off on purpose and silence this, set `dashboard: { enabled: false }`.';
24
- /**
25
- * Decide whether to register the console's routes at all — the router-free core of the provider's
26
- * mount check, extracted so it can be unit tested without booting an app.
27
- *
28
- * The console is a pure consumer of the agent's cross-actor `/agent/governance/*` read routes, and
29
- * those routes are not mounted unless the agent config carries a `governanceAuthorize` gate. Serving
30
- * a shell that can only 404 its own data is worse than not serving it: the failure shows up as seven
31
- * dead panels at click time with nothing anywhere explaining why. So the console follows the same
32
- * fail-closed-by-omission rule one layer down — no gate, no routes — and says so at boot.
33
- *
34
- * This costs nothing that still works: every app affected is an app whose console is ALREADY dead in
35
- * every view but Quota. `dashboard.authorize` is deliberately NOT the trigger; it gates the shell,
36
- * not the data, and an app can set it and still have a console with nothing to render.
37
- */
38
- export function decideDashboardMount(enabled, governanceAuthorize, governanceQueries) {
39
- if (!enabled)
40
- return { mount: false, reason: 'disabled' };
41
- if (governanceAuthorize === undefined) {
42
- return { mount: false, reason: 'no-governance-gate', warning: NO_GOVERNANCE_GATE_WARNING };
43
- }
44
- // ONLY an explicit `false` is decidable here. `undefined` does NOT mean "no read-model": the agent
45
- // provider's `#resolveGovernance` defaults it to the Lucid read-model whenever the main store is
46
- // Lucid, and reproducing that resolution would duplicate provider logic in the dashboard.
47
- if (governanceQueries === false) {
48
- return {
49
- mount: false,
50
- reason: 'no-governance-queries',
51
- warning: NO_GOVERNANCE_QUERIES_WARNING,
52
- };
53
- }
54
- return { mount: true };
55
- }
56
- //# sourceMappingURL=define_config.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"define_config.js","sourceRoot":"","sources":["../../../src/server/define_config.ts"],"names":[],"mappings":"AA2CA,6DAA6D;AAC7D,MAAM,UAAU,sBAAsB,CACpC,MAAwC;IAExC,MAAM,QAAQ,GAAiC,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,IAAI,IAAI,EAAE,CAAC;IACpF,IAAI,MAAM,EAAE,IAAI,KAAK,SAAS;QAAE,QAAQ,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;IAC5D,IAAI,MAAM,EAAE,SAAS,KAAK,SAAS;QAAE,QAAQ,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;IAC3E,OAAO,QAAQ,CAAC;AAClB,CAAC;AASD;;;;GAIG;AACH,MAAM,0BAA0B,GAC9B,0sBAA0sB,CAAC;AAE7sB;;;;;;GAMG;AACH,MAAM,6BAA6B,GACjC,ipBAAipB,CAAC;AAEppB;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,oBAAoB,CAClC,OAAgB,EAChB,mBAAyD,EACzD,iBAA2B;IAE3B,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IAC1D,IAAI,mBAAmB,KAAK,SAAS,EAAE,CAAC;QACtC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,oBAAoB,EAAE,OAAO,EAAE,0BAA0B,EAAE,CAAC;IAC7F,CAAC;IACD,mGAAmG;IACnG,iGAAiG;IACjG,0FAA0F;IAC1F,IAAI,iBAAiB,KAAK,KAAK,EAAE,CAAC;QAChC,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,MAAM,EAAE,uBAAuB;YAC/B,OAAO,EAAE,6BAA6B;SACvC,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACzB,CAAC"}
@@ -1,33 +0,0 @@
1
- import type { ActorResolver } from '@adonis-agora/agent';
2
- import type { HttpContext } from '@adonisjs/core/http';
3
- import type { AgentDashboardAuthorize } from './define_config.js';
4
- /** The outcome of the dashboard access gate: proceed, or deny with an HTTP status + message. */
5
- export type DashboardGateVerdict = {
6
- ok: true;
7
- } | {
8
- ok: false;
9
- status: 401 | 403;
10
- error: string;
11
- };
12
- /**
13
- * Decide whether a request may reach the dashboard, WITHOUT touching the response — so it is unit
14
- * testable free of the AdonisJS router/app: resolve the actor through the agent config's resolver
15
- * (missing/failed → `401`), then run the optional `authorize` gate over the resolved actor
16
- * (denied/threw → `403`).
17
- *
18
- * This gates the SPA **shell**, and only the shell. It is NOT what decides whether the console's data
19
- * is readable, and it is no longer the last line of defence it once had to be:
20
- *
21
- * - Whether the console mounts at all is decided earlier, by {@link decideDashboardMount} — the
22
- * routes are not registered unless the agent config carries a `governanceAuthorize` gate AND its
23
- * `governanceQueries` read-model exists. So this function never runs for a console that could only
24
- * 404 its own panels.
25
- * - Whether the DATA is readable is decided by the agent's own `governanceAuthorize` on the
26
- * `/agent/governance/*` routes, not here. Omitting `authorize` while a gate is configured leaves
27
- * the shell open to any resolved actor but exposes no cross-actor data.
28
- *
29
- * Omitting BOTH the resolver and `authorize` would expose the shell to any request; the provider is
30
- * expected to short-circuit on a missing resolver via the `401` here.
31
- */
32
- export declare function evaluateDashboardGate(ctx: HttpContext, actorResolver: ActorResolver | undefined, authorize?: AgentDashboardAuthorize): Promise<DashboardGateVerdict>;
33
- //# sourceMappingURL=gate.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../../../src/server/gate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAElE,gGAAgG;AAChG,MAAM,MAAM,oBAAoB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,GAAG,GAAG,GAAG,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAElG;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,WAAW,EAChB,aAAa,EAAE,aAAa,GAAG,SAAS,EACxC,SAAS,CAAC,EAAE,uBAAuB,GAClC,OAAO,CAAC,oBAAoB,CAAC,CA4B/B"}
@@ -1,52 +0,0 @@
1
- /**
2
- * Decide whether a request may reach the dashboard, WITHOUT touching the response — so it is unit
3
- * testable free of the AdonisJS router/app: resolve the actor through the agent config's resolver
4
- * (missing/failed → `401`), then run the optional `authorize` gate over the resolved actor
5
- * (denied/threw → `403`).
6
- *
7
- * This gates the SPA **shell**, and only the shell. It is NOT what decides whether the console's data
8
- * is readable, and it is no longer the last line of defence it once had to be:
9
- *
10
- * - Whether the console mounts at all is decided earlier, by {@link decideDashboardMount} — the
11
- * routes are not registered unless the agent config carries a `governanceAuthorize` gate AND its
12
- * `governanceQueries` read-model exists. So this function never runs for a console that could only
13
- * 404 its own panels.
14
- * - Whether the DATA is readable is decided by the agent's own `governanceAuthorize` on the
15
- * `/agent/governance/*` routes, not here. Omitting `authorize` while a gate is configured leaves
16
- * the shell open to any resolved actor but exposes no cross-actor data.
17
- *
18
- * Omitting BOTH the resolver and `authorize` would expose the shell to any request; the provider is
19
- * expected to short-circuit on a missing resolver via the `401` here.
20
- */
21
- export async function evaluateDashboardGate(ctx, actorResolver, authorize) {
22
- if (actorResolver === undefined) {
23
- return { ok: false, status: 401, error: 'no actor resolver configured' };
24
- }
25
- let actor;
26
- try {
27
- actor = await actorResolver.resolve(ctx);
28
- }
29
- catch (error) {
30
- return {
31
- ok: false,
32
- status: 401,
33
- error: error instanceof Error ? error.message : 'unauthorized',
34
- };
35
- }
36
- if (authorize !== undefined) {
37
- try {
38
- if (!(await authorize(actor, ctx))) {
39
- return { ok: false, status: 403, error: 'forbidden' };
40
- }
41
- }
42
- catch (error) {
43
- return {
44
- ok: false,
45
- status: 403,
46
- error: error instanceof Error ? error.message : 'forbidden',
47
- };
48
- }
49
- }
50
- return { ok: true };
51
- }
52
- //# sourceMappingURL=gate.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"gate.js","sourceRoot":"","sources":["../../../src/server/gate.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,GAAgB,EAChB,aAAwC,EACxC,SAAmC;IAEnC,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;QAChC,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,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,GAAG;YACX,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc;SAC/D,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,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW;aAC5D,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AACtB,CAAC"}
@@ -1,35 +0,0 @@
1
- /**
2
- * Pure path/asset helpers for the dashboard provider — extracted so they can be unit-tested without
3
- * booting an AdonisJS app. The provider composes these; it holds only the router wiring + I/O.
4
- */
5
- /** Collapse duplicate slashes and strip leading/trailing ones: `/agent//` → `agent`. */
6
- export declare function trimSlashes(path: string): string;
7
- /** The agent API base as an absolute path with a single leading slash: `agent` → `/agent`. */
8
- export declare function apiBaseFor(agentPath: string): string;
9
- /**
10
- * The canonical dashboard mount path (no trailing slash), default `<agentPath>/dashboard`. A caller
11
- * may override with an explicit `dashboardPath`; both are normalized to a single leading slash.
12
- */
13
- export declare function mountPathFor(agentPath: string, dashboardPath?: string): string;
14
- /** MIME type for a filename by extension; `application/octet-stream` for anything unknown. */
15
- export declare function contentTypeFor(filename: string): string;
16
- /**
17
- * Reject a wildcard asset request that tries to escape the SPA root via `..` or an absolute path.
18
- * Returns the safe, normalized relative segments (never starting with `..`), or `null` to deny.
19
- */
20
- export declare function safeAssetSegments(wildcard: string | string[] | undefined): string[] | null;
21
- /**
22
- * Inject the resolved agent API base into the served `index.html` as a global the SPA reads before
23
- * boot, so the client calls the exact base the provider mounted (no build-time coupling). Idempotent
24
- * per response — inserted right before `</head>`.
25
- */
26
- export declare function injectApiBase(html: string, apiBase: string): string;
27
- /**
28
- * Inject a `<base href="${mount}/">` as the FIRST thing inside `<head>`, so the SPA's relative
29
- * `./assets/*` URLs (Vite `base: './'`) resolve against the mount directory no matter whether the
30
- * browser's URL carries a trailing slash. This replaces the old trailing-slash redirect, which the
31
- * AdonisJS router (it normalizes trailing slashes) turned into a duplicate-route crash. `mount` is a
32
- * leading-slash, no-trailing-slash path (e.g. `/agent/dashboard`).
33
- */
34
- export declare function injectBaseHref(html: string, mount: string): string;
35
- //# sourceMappingURL=paths.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../src/server/paths.ts"],"names":[],"mappings":"AAAA;;;GAGG;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,94 +0,0 @@
1
- /**
2
- * Pure path/asset helpers for the dashboard provider — extracted so they can be unit-tested without
3
- * booting an AdonisJS app. The provider composes these; it holds only the router wiring + I/O.
4
- */
5
- /** Collapse duplicate slashes and strip leading/trailing ones: `/agent//` → `agent`. */
6
- export function trimSlashes(path) {
7
- return path.replace(/\/+/g, '/').replace(/^\/+|\/+$/g, '');
8
- }
9
- /** The agent API base as an absolute path with a single leading slash: `agent` → `/agent`. */
10
- export function apiBaseFor(agentPath) {
11
- const trimmed = trimSlashes(agentPath);
12
- return trimmed === '' ? '/' : `/${trimmed}`;
13
- }
14
- /**
15
- * The canonical dashboard mount path (no trailing slash), default `<agentPath>/dashboard`. A caller
16
- * may override with an explicit `dashboardPath`; both are normalized to a single leading slash.
17
- */
18
- export function mountPathFor(agentPath, dashboardPath) {
19
- if (dashboardPath !== undefined && trimSlashes(dashboardPath) !== '') {
20
- return `/${trimSlashes(dashboardPath)}`;
21
- }
22
- const trimmed = trimSlashes(agentPath);
23
- return trimmed === '' ? '/dashboard' : `/${trimmed}/dashboard`;
24
- }
25
- const CONTENT_TYPES = {
26
- html: 'text/html; charset=utf-8',
27
- js: 'text/javascript; charset=utf-8',
28
- mjs: 'text/javascript; charset=utf-8',
29
- css: 'text/css; charset=utf-8',
30
- json: 'application/json; charset=utf-8',
31
- svg: 'image/svg+xml',
32
- png: 'image/png',
33
- jpg: 'image/jpeg',
34
- jpeg: 'image/jpeg',
35
- gif: 'image/gif',
36
- webp: 'image/webp',
37
- ico: 'image/x-icon',
38
- woff: 'font/woff',
39
- woff2: 'font/woff2',
40
- ttf: 'font/ttf',
41
- map: 'application/json; charset=utf-8',
42
- txt: 'text/plain; charset=utf-8',
43
- };
44
- /** MIME type for a filename by extension; `application/octet-stream` for anything unknown. */
45
- export function contentTypeFor(filename) {
46
- const dot = filename.lastIndexOf('.');
47
- const ext = dot === -1 ? '' : filename.slice(dot + 1).toLowerCase();
48
- return CONTENT_TYPES[ext] ?? 'application/octet-stream';
49
- }
50
- /**
51
- * Reject a wildcard asset request that tries to escape the SPA root via `..` or an absolute path.
52
- * Returns the safe, normalized relative segments (never starting with `..`), or `null` to deny.
53
- */
54
- export function safeAssetSegments(wildcard) {
55
- const parts = Array.isArray(wildcard) ? wildcard : (wildcard ?? '').split('/');
56
- const segments = [];
57
- for (const raw of parts) {
58
- const part = raw.trim();
59
- if (part === '' || part === '.')
60
- continue;
61
- if (part === '..' || part.includes('\0') || part.includes('\\'))
62
- return null;
63
- segments.push(part);
64
- }
65
- return segments;
66
- }
67
- /**
68
- * Inject the resolved agent API base into the served `index.html` as a global the SPA reads before
69
- * boot, so the client calls the exact base the provider mounted (no build-time coupling). Idempotent
70
- * per response — inserted right before `</head>`.
71
- */
72
- export function injectApiBase(html, apiBase) {
73
- const tag = `<script>window.__AGENT_DASHBOARD_BASE__=${JSON.stringify(apiBase)}</script>`;
74
- if (html.includes('</head>'))
75
- return html.replace('</head>', `${tag}</head>`);
76
- return `${tag}${html}`;
77
- }
78
- /**
79
- * Inject a `<base href="${mount}/">` as the FIRST thing inside `<head>`, so the SPA's relative
80
- * `./assets/*` URLs (Vite `base: './'`) resolve against the mount directory no matter whether the
81
- * browser's URL carries a trailing slash. This replaces the old trailing-slash redirect, which the
82
- * AdonisJS router (it normalizes trailing slashes) turned into a duplicate-route crash. `mount` is a
83
- * leading-slash, no-trailing-slash path (e.g. `/agent/dashboard`).
84
- */
85
- export function injectBaseHref(html, mount) {
86
- const tag = `<base href="${mount}/">`;
87
- const headOpen = html.match(/<head[^>]*>/i);
88
- if (headOpen?.index !== undefined) {
89
- const at = headOpen.index + headOpen[0].length;
90
- return html.slice(0, at) + tag + html.slice(at);
91
- }
92
- return `${tag}${html}`;
93
- }
94
- //# sourceMappingURL=paths.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/server/paths.ts"],"names":[],"mappings":"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"}