@skaile/forge-app 0.0.0-stage → 1.0.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 ADDED
@@ -0,0 +1,9 @@
1
+ # Changelog
2
+
3
+ ## 1.0.0
4
+
5
+ Initial release: an optional Nuxt layer for Skaile forge apps.
6
+
7
+ - `extends: ['@skaile/forge-app']` registers `modules: ['@nuxt/ui', '@skaile/forge-app-actions']` in that order.
8
+ - One shared stylesheet (`@import "tailwindcss"; @import "@nuxt/ui"; @import "@skaile/brand/nuxt-ui.css";`) registered once. Capability stylesheets stay in their own modules.
9
+ - No HTTP or MCP action endpoint, no principal or deps resolver, no settings or provider route, no editor or chat wiring: hosts add each feature explicitly.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Matthias Ortegro
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,101 @@
1
- # Temporary Holding Version
1
+ # @skaile/forge-app
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ An optional Nuxt layer for Skaile forge apps. It saves the same three lines of setup in every host and nothing else.
4
+
5
+ ## What the layer gives you
6
+
7
+ ```ts
8
+ // nuxt.config.ts
9
+ export default defineNuxtConfig({
10
+ extends: ['@skaile/forge-app'],
11
+ })
12
+ ```
13
+
14
+ - `modules: ['@nuxt/ui', '@skaile/forge-app-actions']`, in that order (the actions module refuses to load unless Nuxt UI came first). Hosts keep their own `modules`; entries are merged, the layer's first.
15
+ - One stylesheet, registered once:
16
+
17
+ ```css
18
+ @import "tailwindcss";
19
+ @import "@nuxt/ui";
20
+ @import "@skaile/brand/nuxt-ui.css";
21
+ ```
22
+
23
+ The brand bridge comes after Nuxt UI on purpose (equal specificity, source order decides). Capability stylesheets (editor, chat, inbox) stay in the modules that own them.
24
+
25
+ Install:
26
+
27
+ ```sh
28
+ bun add @skaile/forge-app @nuxt/ui nuxt tailwindcss
29
+ ```
30
+
31
+ Peers: `nuxt ^4`, `@nuxt/ui ^4.11`, `tailwindcss ^4`. Dependencies: `@skaile/forge-app-actions ^0.4.0`, `@skaile/brand ^0.7.0`. Wrap the root in `<UApp>` as Nuxt UI requires.
32
+
33
+ ## What the layer does not do
34
+
35
+ No HTTP or MCP action endpoint, no principal or deps resolver, no settings or provider route, no annotation or editor authorization, no chat handler, no central dependency list. Identity, grants and per-feature permission checks stay in the host. Compose chat with `createAiSdkChatHandler` yourself; the layer has no wrapper for it. Express/Vite apps do not use this layer; they use the framework-neutral packages directly.
36
+
37
+ ## What hosts add explicitly
38
+
39
+ Each feature is opt-in in the host's own `nuxt.config.ts`.
40
+
41
+ **HTTP actions** (typed client, `forge-actions` CLI). Deny by default until your hook allows:
42
+
43
+ ```ts
44
+ export default defineNuxtConfig({
45
+ extends: ['@skaile/forge-app'],
46
+ forgeAppActions: { http: { route: '/api/actions' } },
47
+ })
48
+ ```
49
+
50
+ ```ts
51
+ // server/plugins/actions-auth.ts
52
+ export default defineNitroPlugin((nitro) => {
53
+ nitro.hooks.hook('forge-app-actions:http:authorize', async (decision) => {
54
+ // decision: { event, bearer, allowed, principal?, deps? }
55
+ // Cookie sessions: do the same-origin check here.
56
+ decision.allowed = await isAllowed(decision.event, decision.bearer)
57
+ })
58
+ })
59
+ ```
60
+
61
+ **MCP** (serves the `llm`-audience actions):
62
+
63
+ ```ts
64
+ forgeAppActions: { mcp: { route: '/mcp', name: 'my-app' } },
65
+ // plus a Nitro hook on 'forge-app-actions:mcp:authorize' that sets decision.allowed
66
+ ```
67
+
68
+ **Provider settings** (installed after `@nuxt/ui`, provides `<ForgeProvidersPanel>`):
69
+
70
+ ```ts
71
+ extends: ['@skaile/forge-app'],
72
+ modules: ['@skaile/forge-settings/nuxt'],
73
+ ```
74
+
75
+ Settings storage, scopes and permissions stay in the host; see `@skaile/forge-settings`.
76
+
77
+ **Editor** (chat-free by default; the sidebar lives at `@skaile/forge-editor/ai/vue/chat` and needs `@skaile/forge-chat`):
78
+
79
+ ```ts
80
+ extends: ['@skaile/forge-app'],
81
+ modules: ['@skaile/forge-editor/nuxt'],
82
+ ```
83
+
84
+ A plain editor host installs no settings storage and no agent runtime.
85
+
86
+ ## Proof
87
+
88
+ `scripts/packed-consumer.mjs` packs the layer with `npm pack`, installs the tarball into a throwaway Nuxt app under `.scratch/packed-consumer/` (gitignored), runs `nuxi build`, boots `.output/server/index.mjs` on a free port and checks:
89
+
90
+ - Nuxt UI registered before `@skaile/forge-app-actions`; the packed layer is the extended layer; the stylesheet is registered once
91
+ - no HTTP/MCP options set; `GET/POST /api/actions` and `/mcp` answer 404
92
+ - the brand bridge is in the built CSS once, after Nuxt UI's defaults
93
+ - a second variant adds `@skaile/forge-editor` (and its Nuxt module): the build output and dependency tree contain no `@skaile/forge-settings`, `@skaile/forge-agent-runtime`, `@skaile/forge-common`, `@skaile/workspaces` or `@skaile/forge-chat`
94
+
95
+ ```sh
96
+ node scripts/packed-consumer.mjs # both variants (~40s, needs registry access)
97
+ node scripts/packed-consumer.mjs base # layer only
98
+ node scripts/packed-consumer.mjs editor # layer + @skaile/forge-editor
99
+ ```
100
+
101
+ Exit 0 only when every check prints `PASS`. Unit tests (`bun run test`) cover the layer config itself.
@@ -0,0 +1,9 @@
1
+ /*
2
+ * @skaile/forge-app shared stylesheet, registered once by the layer.
3
+ * Order matters: the brand bridge must come after "@nuxt/ui" (equal
4
+ * specificity, source order decides). Capability stylesheets (chat, editor,
5
+ * inbox) stay in the modules that own them.
6
+ */
7
+ @import "tailwindcss";
8
+ @import "@nuxt/ui";
9
+ @import "@skaile/brand/nuxt-ui.css";
package/nuxt.config.ts ADDED
@@ -0,0 +1,14 @@
1
+ import { fileURLToPath } from "node:url";
2
+ import { defineNuxtConfig } from "nuxt/config";
3
+
4
+ // Optional layer: `extends: ['@skaile/forge-app']`.
5
+ //
6
+ // - `@nuxt/ui` MUST precede `@skaile/forge-app-actions` (the actions module
7
+ // refuses to load otherwise and renders Nuxt UI primitives).
8
+ // - `forgeAppActions` is deliberately left unset: no HTTP or MCP endpoint, no
9
+ // principal/deps resolver. Hosts opt in per feature.
10
+ // - No dependency list, no settings/provider route, no chat or editor wiring.
11
+ export default defineNuxtConfig({
12
+ modules: ["@nuxt/ui", "@skaile/forge-app-actions"],
13
+ css: [fileURLToPath(new URL("./assets/css/forge-app.css", import.meta.url))],
14
+ });
package/package.json CHANGED
@@ -1,6 +1,52 @@
1
1
  {
2
2
  "name": "@skaile/forge-app",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.0.0",
4
+ "description": "Optional Nuxt layer for Skaile forge apps: Nuxt UI, @skaile/forge-app-actions and the shared Tailwind + brand stylesheet, registered once. Adds no routes, resolvers or permissions.",
5
+ "type": "module",
6
+ "packageManager": "bun@1.3.9",
7
+ "main": "./nuxt.config.ts",
8
+ "files": [
9
+ "nuxt.config.ts",
10
+ "assets",
11
+ "README.md",
12
+ "CHANGELOG.md",
13
+ "LICENSE"
14
+ ],
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/skaile-ai/forge-app.git"
18
+ },
19
+ "publishConfig": {
20
+ "access": "public"
21
+ },
22
+ "license": "MIT",
23
+ "scripts": {
24
+ "test": "bun x --bun vitest run",
25
+ "typecheck": "tsc --noEmit",
26
+ "proof:packed": "node scripts/packed-consumer.mjs",
27
+ "check": "bun run format && bun run lint",
28
+ "format": "biome format --write nuxt.config.ts tests scripts",
29
+ "lint": "biome lint --fix --unsafe nuxt.config.ts tests scripts"
30
+ },
31
+ "dependencies": {
32
+ "@skaile/brand": "^0.7.0",
33
+ "@skaile/forge-app-actions": "^0.4.0"
34
+ },
35
+ "peerDependencies": {
36
+ "@nuxt/ui": "^4.11.1",
37
+ "nuxt": "^4.0.0",
38
+ "tailwindcss": "^4.0.0"
39
+ },
40
+ "devDependencies": {
41
+ "@biomejs/biome": "^2.4.9",
42
+ "@nuxt/ui": "^4.11.1",
43
+ "@types/node": "^22.0.0",
44
+ "nuxt": "^4.0.0",
45
+ "tailwindcss": "^4.0.0",
46
+ "typescript": "^5.0.0",
47
+ "vitest": "^3.2.0"
48
+ },
49
+ "engines": {
50
+ "node": ">=20"
51
+ }
52
+ }