acrylblends 0.7.6 → 0.7.8

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.
Files changed (105) hide show
  1. package/dist/index.d.ts +1 -1
  2. package/dist/index.js +148 -24
  3. package/dist/index.js.map +1 -1
  4. package/docs/framework/README.md +1 -1
  5. package/docs/framework/UPSTREAM.md +1 -1
  6. package/docs/framework/agents/index.md +18 -3
  7. package/docs/framework/getting-started/desktop.md +2 -2
  8. package/docs/framework/guides/client-modules.md +4 -3
  9. package/docs/framework/guides/data.md +72 -8
  10. package/docs/framework/helpers/streaming.md +12 -27
  11. package/docs/framework/upstream.json +2 -2
  12. package/lib/browser/read-sse.js +84 -0
  13. package/lib/index-BLTYsyc1.d.ts +93 -0
  14. package/lib/kv/db.d.ts +12 -0
  15. package/lib/kv/db.js +57 -0
  16. package/lib/kv/json.d.ts +11 -0
  17. package/lib/kv/json.js +224 -0
  18. package/lib/kv.d.ts +2 -0
  19. package/lib/kv.js +2 -0
  20. package/lib/node-server.d.ts +3 -3
  21. package/lib/node-server.js +13 -8
  22. package/lib/read-sse.d.ts +33 -0
  23. package/lib/read-sse.js +84 -0
  24. package/lib/src-DRFVEQQb.js +90 -0
  25. package/package.json +17 -1
  26. package/plugins/acryl-db/plugin.json +1 -1
  27. package/plugins/acryl-db/upstream.json +2 -2
  28. package/plugins/acryl-db-sqlite/upstream.json +1 -1
  29. package/plugins/acryl-inspect/upstream.json +1 -1
  30. package/plugins/acryl-kv/LICENSE +47 -0
  31. package/plugins/acryl-kv/plugin.json +12 -0
  32. package/plugins/acryl-kv/src/check.ts +58 -0
  33. package/plugins/acryl-kv/src/copy.ts +39 -0
  34. package/plugins/acryl-kv/src/cordis.ts +13 -0
  35. package/plugins/acryl-kv/src/index.ts +14 -0
  36. package/plugins/acryl-kv/src/kv.ts +37 -0
  37. package/plugins/acryl-kv/upstream.json +18 -0
  38. package/plugins/acryl-kv-db/LICENSE +47 -0
  39. package/plugins/acryl-kv-db/plugin.json +13 -0
  40. package/plugins/acryl-kv-db/src/index.ts +37 -0
  41. package/plugins/acryl-kv-db/src/open.ts +80 -0
  42. package/plugins/acryl-kv-db/upstream.json +21 -0
  43. package/plugins/acryl-kv-json/LICENSE +47 -0
  44. package/plugins/acryl-kv-json/plugin.json +13 -0
  45. package/plugins/acryl-kv-json/src/index.ts +71 -0
  46. package/plugins/acryl-kv-json/src/open.ts +249 -0
  47. package/plugins/acryl-kv-json/upstream.json +22 -0
  48. package/plugins/acryl-node-server/src/client-modules.ts +10 -9
  49. package/plugins/acryl-node-server/src/index.ts +12 -1
  50. package/plugins/acryl-node-server/upstream.json +2 -2
  51. package/plugins/acryl-router/src/browser/read-sse.ts +3 -0
  52. package/plugins/acryl-router/src/helpers/read-sse.ts +111 -0
  53. package/plugins/acryl-router/upstream.json +2 -2
  54. package/plugins/acryl-router-http/upstream.json +1 -1
  55. package/plugins/acryl-state/upstream.json +1 -1
  56. package/plugins/builder/index.ts +2 -2
  57. package/plugins/builder/plugin.json +1 -1
  58. package/plugins/desktop/main.ts +3 -3
  59. package/plugins/desktop/plugin.json +2 -2
  60. package/plugins/desktop/upstream.json +1 -1
  61. package/plugins/desktop-web/main.ts +2 -2
  62. package/plugins/desktop-web/plugin.json +2 -2
  63. package/plugins/desktop-web/upstream.json +1 -1
  64. package/plugins/extensions/index.ts +19 -1
  65. package/plugins/extensions/plugin.json +1 -1
  66. package/plugins/extensions/resolve.ts +1 -1
  67. package/plugins/manifest/lock.ts +7 -3
  68. package/plugins/manifest/upgrade-cli.ts +1 -1
  69. package/plugins/save/cli.ts +1 -1
  70. package/plugins/save/plugin.json +1 -1
  71. package/plugins/tsconfig.json +2 -0
  72. package/shared/AGENTS.core.md +10 -10
  73. package/shared/DEFAULTS.md +40 -0
  74. package/shared/SKILL.md +14 -0
  75. package/templates/agent/AGENTS.md +1 -1
  76. package/templates/agent/README.md +6 -6
  77. package/templates/agent/gitignore +1 -0
  78. package/templates/agent/package.json +8 -8
  79. package/templates/agent/src/app.ts +28 -15
  80. package/templates/agent/src/main.ts +2 -2
  81. package/templates/agent/src/routes.ts +5 -5
  82. package/templates/agent/test/agent.test.ts +1 -1
  83. package/templates/agent/test/app.test.ts +1 -1
  84. package/templates/agent/test/builder.test.ts +1 -1
  85. package/templates/agent/test/model.test.ts +1 -1
  86. package/templates/agent/tsconfig.json +48 -50
  87. package/templates/blank/AGENTS.md +1 -1
  88. package/templates/blank/README.md +2 -2
  89. package/templates/blank/gitignore +1 -0
  90. package/templates/blank/package.json +8 -8
  91. package/templates/blank/src/about.tsx +2 -2
  92. package/templates/blank/src/app.ts +4 -4
  93. package/templates/blank/src/main.ts +1 -1
  94. package/templates/blank/src/routes.ts +1 -1
  95. package/templates/blank/test/app.test.ts +1 -1
  96. package/templates/blank/tsconfig.json +1 -1
  97. package/templates/todo/README.md +1 -1
  98. package/templates/todo/gitignore +1 -0
  99. package/templates/todo/package.json +8 -8
  100. package/templates/todo/src/app.ts +5 -5
  101. package/templates/todo/src/main.ts +1 -1
  102. package/templates/todo/src/todo.ts +4 -4
  103. package/templates/todo/test/todo.test.ts +1 -1
  104. package/templates/todo/tsconfig.json +1 -1
  105. package/templates/todo/upstream.json +2 -2
@@ -1,23 +1,24 @@
1
+ import { existsSync } from 'node:fs'
1
2
  import { join } from 'node:path'
2
3
  import { fileURLToPath } from 'node:url'
3
4
  import { Context, type Fiber } from '@deepseek-ai/cordis'
4
- import * as nodeServer from './plugins/acryl-node-server/src/index.ts'
5
- import * as router from './plugins/acryl-router/src/index.ts'
6
- import * as state from './plugins/acryl-state/src/index.ts'
7
- import { agent, memory, model, tools } from './plugins/agent/index.ts'
8
- import { builder } from './plugins/builder/index.ts'
9
- import { extensions } from './plugins/extensions/index.ts'
10
- import { type AppInstance, instance } from './plugins/instance/index.ts'
5
+ import * as nodeServer from '../plugins/acryl-node-server/src/index.ts'
6
+ import * as router from '../plugins/acryl-router/src/index.ts'
7
+ import * as state from '../plugins/acryl-state/src/index.ts'
8
+ import { agent, memory, model, tools } from '../plugins/agent/index.ts'
9
+ import { builder } from '../plugins/builder/index.ts'
10
+ import { extensions } from '../plugins/extensions/index.ts'
11
+ import { type AppInstance, instance } from '../plugins/instance/index.ts'
11
12
  import {
12
13
  blueprintsIn,
13
14
  compose,
14
15
  loadManifest,
15
16
  type ParameterValue,
16
- } from './plugins/manifest/index.ts'
17
- import { type OpenAIConfig, openai } from './plugins/openai/index.ts'
18
- import { sandboxPlugin } from './plugins/sandbox/index.ts'
19
- import { save } from './plugins/save/index.ts'
20
- import { tasks } from './plugins/tasks/index.ts'
17
+ } from '../plugins/manifest/index.ts'
18
+ import { type OpenAIConfig, openai } from '../plugins/openai/index.ts'
19
+ import { sandboxPlugin } from '../plugins/sandbox/index.ts'
20
+ import { save } from '../plugins/save/index.ts'
21
+ import { tasks } from '../plugins/tasks/index.ts'
21
22
  import { routes } from './routes.ts'
22
23
 
23
24
  /** The plugins this app's code provides. `blend.yaml` chooses, orders and configures them. */
@@ -59,7 +60,7 @@ export interface App {
59
60
  }
60
61
 
61
62
  /**
62
- * The app: `instance` first (where it lives, chosen at run time), then the manifest's rows in order. The app's own `extensions/`
63
+ * The app: `instance` first (where it lives, chosen at run time), then the manifest's rows in order. The app's `plugins/`
63
64
  * folder is trusted to install at start, and is where the builder writes.
64
65
  */
65
66
  export async function createApp(
@@ -71,7 +72,14 @@ export async function createApp(
71
72
  } = {},
72
73
  ): Promise<App> {
73
74
  const manifest = readManifest(options.values)
74
- const extensionsDir = join(chosen.root, 'extensions')
75
+ const extensionsDir = join(chosen.root, 'plugins')
76
+ // One release of grace: an app made before 0.7.8 kept what the agent wrote in `extensions/`. It is still installed, with a warning.
77
+ const legacyDir = join(chosen.root, 'extensions')
78
+ const legacy = existsSync(legacyDir)
79
+ if (legacy)
80
+ console.warn(
81
+ 'warning: extensions/ is the old folder for plugins the agent writes; move them to plugins/ ("git mv extensions/<name> plugins/<name>"). extensions/ is read for this release only.',
82
+ )
75
83
  const root = new Context()
76
84
  const first = root.plugin(instance, chosen)
77
85
  await first.await()
@@ -83,7 +91,12 @@ export async function createApp(
83
91
  // Runtime values the manifest cannot hold: the manifest's own digest (every task records it), and who may install.
84
92
  tasks: { manifest: `sha256:${manifest.digest}` },
85
93
  // The `approval` parameter in blend.yaml (the extensions row) turns this source into one that asks.
86
- extensions: { sources: [{ dir: extensionsDir, trust: 'install' }] },
94
+ extensions: {
95
+ sources: [
96
+ { dir: extensionsDir, trust: 'install' },
97
+ ...(legacy ? [{ dir: legacyDir, trust: 'install' as const }] : []),
98
+ ],
99
+ },
87
100
  builder: { dir: extensionsDir },
88
101
  server: { port: chosen.port.start, scan: chosen.port.scan ? 20 : 0, hostname: chosen.host },
89
102
  })),
@@ -1,7 +1,7 @@
1
1
  import { fileURLToPath } from 'node:url'
2
+ import { selectInstance } from '../plugins/instance/index.ts'
3
+ import { modelConfigFrom } from '../plugins/openai/index.ts'
2
4
  import { createApp } from './app.ts'
3
- import { selectInstance } from './plugins/instance/index.ts'
4
- import { modelConfigFrom } from './plugins/openai/index.ts'
5
5
  import { APP_NAME } from './routes.ts'
6
6
 
7
7
  // The composition root: the one place that reads the environment. selectInstance chooses where the app lives;
@@ -1,9 +1,9 @@
1
1
  import type { Context } from '@deepseek-ai/cordis'
2
- import { Acryl } from './plugins/acryl-router/src/index.ts'
3
- import { bodyLimit } from './plugins/acryl-router/src/middleware/index.ts'
4
- import type {} from './plugins/agent/index.ts'
5
- import type {} from './plugins/extensions/index.ts'
6
- import type {} from './plugins/tasks/index.ts'
2
+ import { Acryl } from '../plugins/acryl-router/src/index.ts'
3
+ import { bodyLimit } from '../plugins/acryl-router/src/middleware/index.ts'
4
+ import type {} from '../plugins/agent/index.ts'
5
+ import type {} from '../plugins/extensions/index.ts'
6
+ import type {} from '../plugins/tasks/index.ts'
7
7
 
8
8
  export const APP_NAME = '__APP_NAME__'
9
9
 
@@ -4,8 +4,8 @@ import { tmpdir } from 'node:os'
4
4
  import { join } from 'node:path'
5
5
  import { test } from 'node:test'
6
6
  import { fileURLToPath } from 'node:url'
7
+ import { pinnedInstance, withPort } from '../plugins/instance/index.ts'
7
8
  import { type App, createApp } from '../src/app.ts'
8
- import { pinnedInstance, withPort } from '../src/plugins/instance/index.ts'
9
9
 
10
10
  const projectRoot = fileURLToPath(new URL('..', import.meta.url))
11
11
 
@@ -4,8 +4,8 @@ import { tmpdir } from 'node:os'
4
4
  import { join } from 'node:path'
5
5
  import { test } from 'node:test'
6
6
  import { fileURLToPath } from 'node:url'
7
+ import { pinnedInstance, withPort } from '../plugins/instance/index.ts'
7
8
  import { type App, createApp } from '../src/app.ts'
8
- import { pinnedInstance, withPort } from '../src/plugins/instance/index.ts'
9
9
  import { APP_NAME } from '../src/routes.ts'
10
10
 
11
11
  const projectRoot = fileURLToPath(new URL('..', import.meta.url))
@@ -3,8 +3,8 @@ import { mkdtemp, rm } from 'node:fs/promises'
3
3
  import { tmpdir } from 'node:os'
4
4
  import { join } from 'node:path'
5
5
  import { test } from 'node:test'
6
+ import { pinnedInstance, withPort } from '../plugins/instance/index.ts'
6
7
  import { createApp } from '../src/app.ts'
7
- import { pinnedInstance, withPort } from '../src/plugins/instance/index.ts'
8
8
 
9
9
  /** The agent extends the running app through POST /ask; a restart keeps what it built. */
10
10
  test('the agent builds, updates, protects and removes a plugin in the running app, and a restart keeps it', async () => {
@@ -5,8 +5,8 @@ import type { AddressInfo } from 'node:net'
5
5
  import { tmpdir } from 'node:os'
6
6
  import { join } from 'node:path'
7
7
  import { test } from 'node:test'
8
+ import { pinnedInstance, withPort } from '../plugins/instance/index.ts'
8
9
  import { createApp } from '../src/app.ts'
9
- import { pinnedInstance, withPort } from '../src/plugins/instance/index.ts'
10
10
 
11
11
  /** A plugin no scripted command knows: the model writes it from scratch. */
12
12
  const COUNTER = `import type { Context } from '@deepseek-ai/cordis'
@@ -13,58 +13,56 @@
13
13
  "skipLibCheck": true,
14
14
  "types": ["node"],
15
15
  "paths": {
16
- "acrylblends": ["./src/plugins/acryl-router/src/index.ts"],
17
- "acrylblends/conninfo": ["./src/plugins/acryl-router/src/index.ts"],
18
- "acrylblends/http-exception": ["./src/plugins/acryl-router/src/index.ts"],
19
- "acrylblends/types": ["./src/plugins/acryl-router/src/index.ts"],
20
- "acrylblends/client": ["./src/plugins/acryl-router/src/client.ts"],
21
- "acrylblends/basic-auth": ["./src/plugins/acryl-router/src/middleware/index.ts"],
22
- "acrylblends/bearer-auth": ["./src/plugins/acryl-router/src/middleware/index.ts"],
23
- "acrylblends/body-limit": ["./src/plugins/acryl-router/src/middleware/index.ts"],
24
- "acrylblends/combine": ["./src/plugins/acryl-router/src/middleware/index.ts"],
25
- "acrylblends/compress": ["./src/plugins/acryl-router/src/middleware/index.ts"],
26
- "acrylblends/context-storage": ["./src/plugins/acryl-router/src/middleware/index.ts"],
27
- "acrylblends/cors": ["./src/plugins/acryl-router/src/middleware/index.ts"],
28
- "acrylblends/csrf": ["./src/plugins/acryl-router/src/middleware/index.ts"],
29
- "acrylblends/etag": ["./src/plugins/acryl-router/src/middleware/index.ts"],
30
- "acrylblends/ip-restriction": ["./src/plugins/acryl-router/src/middleware/index.ts"],
31
- "acrylblends/jwk": ["./src/plugins/acryl-router/src/middleware/index.ts"],
32
- "acrylblends/jwt": ["./src/plugins/acryl-router/src/middleware/index.ts"],
33
- "acrylblends/language": ["./src/plugins/acryl-router/src/middleware/index.ts"],
34
- "acrylblends/logger": ["./src/plugins/acryl-router/src/middleware/index.ts"],
35
- "acrylblends/loopback-only": ["./src/plugins/acryl-router/src/middleware/index.ts"],
36
- "acrylblends/method-not-allowed": ["./src/plugins/acryl-router/src/middleware/index.ts"],
37
- "acrylblends/method-override": ["./src/plugins/acryl-router/src/middleware/index.ts"],
38
- "acrylblends/powered-by": ["./src/plugins/acryl-router/src/middleware/index.ts"],
39
- "acrylblends/pretty-json": ["./src/plugins/acryl-router/src/middleware/index.ts"],
40
- "acrylblends/request-id": ["./src/plugins/acryl-router/src/middleware/index.ts"],
41
- "acrylblends/secure-headers": ["./src/plugins/acryl-router/src/middleware/index.ts"],
42
- "acrylblends/serve-static": ["./src/plugins/acryl-router/src/middleware/index.ts"],
43
- "acrylblends/timeout": ["./src/plugins/acryl-router/src/middleware/index.ts"],
44
- "acrylblends/timing": ["./src/plugins/acryl-router/src/middleware/index.ts"],
45
- "acrylblends/trailing-slash": ["./src/plugins/acryl-router/src/middleware/index.ts"],
46
- "acrylblends/accepts": ["./src/plugins/acryl-router/src/helpers/index.ts"],
47
- "acrylblends/cookie": ["./src/plugins/acryl-router/src/helpers/index.ts"],
48
- "acrylblends/factory": ["./src/plugins/acryl-router/src/helpers/index.ts"],
49
- "acrylblends/html": ["./src/plugins/acryl-router/src/helpers/index.ts"],
50
- "acrylblends/route": ["./src/plugins/acryl-router/src/helpers/index.ts"],
51
- "acrylblends/schema-validator": ["./src/plugins/acryl-router/src/helpers/index.ts"],
52
- "acrylblends/streaming": ["./src/plugins/acryl-router/src/helpers/index.ts"],
53
- "acrylblends/testing": ["./src/plugins/acryl-router/src/helpers/index.ts"],
54
- "acrylblends/validator": ["./src/plugins/acryl-router/src/helpers/index.ts"],
55
- "acrylblends/ws": ["./src/plugins/acryl-router/src/helpers/index.ts"],
56
- "acryl-router": ["./src/plugins/acryl-router/src/index.ts"],
57
- "acryl-router/middleware": ["./src/plugins/acryl-router/src/middleware/index.ts"],
58
- "acryl-router/helpers": ["./src/plugins/acryl-router/src/helpers/index.ts"],
59
- "acrylblends/jsx": ["./src/plugins/acryl-router/src/core/jsx/index.ts"],
60
- "acrylblends/jsx/jsx-runtime": ["./src/plugins/acryl-router/src/core/jsx/jsx-runtime.ts"],
61
- "acrylblends/jsx/jsx-dev-runtime": [
62
- "./src/plugins/acryl-router/src/core/jsx/jsx-dev-runtime.ts"
63
- ],
64
- "acrylblends/jsx/streaming": ["./src/plugins/acryl-router/src/core/jsx/streaming.ts"]
16
+ "acrylblends": ["./plugins/acryl-router/src/index.ts"],
17
+ "acrylblends/conninfo": ["./plugins/acryl-router/src/index.ts"],
18
+ "acrylblends/http-exception": ["./plugins/acryl-router/src/index.ts"],
19
+ "acrylblends/types": ["./plugins/acryl-router/src/index.ts"],
20
+ "acrylblends/client": ["./plugins/acryl-router/src/client.ts"],
21
+ "acrylblends/basic-auth": ["./plugins/acryl-router/src/middleware/index.ts"],
22
+ "acrylblends/bearer-auth": ["./plugins/acryl-router/src/middleware/index.ts"],
23
+ "acrylblends/body-limit": ["./plugins/acryl-router/src/middleware/index.ts"],
24
+ "acrylblends/combine": ["./plugins/acryl-router/src/middleware/index.ts"],
25
+ "acrylblends/compress": ["./plugins/acryl-router/src/middleware/index.ts"],
26
+ "acrylblends/context-storage": ["./plugins/acryl-router/src/middleware/index.ts"],
27
+ "acrylblends/cors": ["./plugins/acryl-router/src/middleware/index.ts"],
28
+ "acrylblends/csrf": ["./plugins/acryl-router/src/middleware/index.ts"],
29
+ "acrylblends/etag": ["./plugins/acryl-router/src/middleware/index.ts"],
30
+ "acrylblends/ip-restriction": ["./plugins/acryl-router/src/middleware/index.ts"],
31
+ "acrylblends/jwk": ["./plugins/acryl-router/src/middleware/index.ts"],
32
+ "acrylblends/jwt": ["./plugins/acryl-router/src/middleware/index.ts"],
33
+ "acrylblends/language": ["./plugins/acryl-router/src/middleware/index.ts"],
34
+ "acrylblends/logger": ["./plugins/acryl-router/src/middleware/index.ts"],
35
+ "acrylblends/loopback-only": ["./plugins/acryl-router/src/middleware/index.ts"],
36
+ "acrylblends/method-not-allowed": ["./plugins/acryl-router/src/middleware/index.ts"],
37
+ "acrylblends/method-override": ["./plugins/acryl-router/src/middleware/index.ts"],
38
+ "acrylblends/powered-by": ["./plugins/acryl-router/src/middleware/index.ts"],
39
+ "acrylblends/pretty-json": ["./plugins/acryl-router/src/middleware/index.ts"],
40
+ "acrylblends/request-id": ["./plugins/acryl-router/src/middleware/index.ts"],
41
+ "acrylblends/secure-headers": ["./plugins/acryl-router/src/middleware/index.ts"],
42
+ "acrylblends/serve-static": ["./plugins/acryl-router/src/middleware/index.ts"],
43
+ "acrylblends/timeout": ["./plugins/acryl-router/src/middleware/index.ts"],
44
+ "acrylblends/timing": ["./plugins/acryl-router/src/middleware/index.ts"],
45
+ "acrylblends/trailing-slash": ["./plugins/acryl-router/src/middleware/index.ts"],
46
+ "acrylblends/accepts": ["./plugins/acryl-router/src/helpers/index.ts"],
47
+ "acrylblends/cookie": ["./plugins/acryl-router/src/helpers/index.ts"],
48
+ "acrylblends/factory": ["./plugins/acryl-router/src/helpers/index.ts"],
49
+ "acrylblends/html": ["./plugins/acryl-router/src/helpers/index.ts"],
50
+ "acrylblends/route": ["./plugins/acryl-router/src/helpers/index.ts"],
51
+ "acrylblends/schema-validator": ["./plugins/acryl-router/src/helpers/index.ts"],
52
+ "acrylblends/streaming": ["./plugins/acryl-router/src/helpers/index.ts"],
53
+ "acrylblends/testing": ["./plugins/acryl-router/src/helpers/index.ts"],
54
+ "acrylblends/validator": ["./plugins/acryl-router/src/helpers/index.ts"],
55
+ "acrylblends/ws": ["./plugins/acryl-router/src/helpers/index.ts"],
56
+ "acryl-router": ["./plugins/acryl-router/src/index.ts"],
57
+ "acryl-router/middleware": ["./plugins/acryl-router/src/middleware/index.ts"],
58
+ "acryl-router/helpers": ["./plugins/acryl-router/src/helpers/index.ts"],
59
+ "acrylblends/jsx": ["./plugins/acryl-router/src/core/jsx/index.ts"],
60
+ "acrylblends/jsx/jsx-runtime": ["./plugins/acryl-router/src/core/jsx/jsx-runtime.ts"],
61
+ "acrylblends/jsx/jsx-dev-runtime": ["./plugins/acryl-router/src/core/jsx/jsx-dev-runtime.ts"],
62
+ "acrylblends/jsx/streaming": ["./plugins/acryl-router/src/core/jsx/streaming.ts"]
65
63
  },
66
64
  "jsx": "react-jsx",
67
65
  "jsxImportSource": "#acryl-jsx"
68
66
  },
69
- "include": ["src", "test", "extensions"]
67
+ "include": ["src", "test", "plugins"]
70
68
  }
@@ -2,4 +2,4 @@
2
2
  ## This app (blank)
3
3
 
4
4
  `src/routes.ts` is the app's own plugin: add routes to its `App`. `blend.yaml` lists the plugins that are mounted. `acrylblends add <plugin>` copies
5
- another library plugin (for example `acryl-state`) into `src/plugins/`.
5
+ another library plugin (for example `acryl-state`) into `plugins/`.
@@ -10,13 +10,13 @@ npm test
10
10
  npm run check # type-check
11
11
  ```
12
12
 
13
- - `src/main.ts` chooses where the app lives (`src/plugins/instance`) and starts it.
13
+ - `src/main.ts` chooses where the app lives (`plugins/instance`) and starts it.
14
14
  - `blend.yaml` is the app as data: which plugins it mounts, in what order, with what config and parameters. Switch
15
15
  one off with `disabled: true`. `npm run lock` writes `blend.lock.json`: the manifest's digest and a digest of
16
16
  every plugin folder, so a diff of the lock shows what changed.
17
17
  - `src/app.ts` holds the registry of plugins the code provides, and mounts the manifest's rows.
18
18
  - `src/routes.ts` is your own plugin: it builds an `App` (`import { App } from './plugins/acryl-router/src/index.ts'`) and mounts it with `ctx.router.route(prefix, app)`. Routes added to the app after it is mounted are not served. A page mounted at `/x` answers `/x`, not `/x/` (trailing slashes are strict). The router API is documented at https://acrylblends.github.io/docs/framework/the-acryl-framework and in `docs/framework` of the acrylblends repository.
19
- - `src/plugins/` holds the plugins copied from the ACRYLBLENDS library. They are yours now; edit them freely.
19
+ - `plugins/` holds the plugins copied from the ACRYLBLENDS library. They are yours now; edit them freely.
20
20
  Add more with `acrylblends add <plugin>`.
21
21
 
22
22
  `npm run save -- "message"` commits the app with git (and pushes when it has a remote). It refuses a file that looks like
@@ -1,2 +1,3 @@
1
1
  node_modules/
2
2
  .acrylblends/
3
+ .acryl/
@@ -4,20 +4,20 @@
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "imports": {
7
- "#acryl-jsx/jsx-runtime": "./src/plugins/acryl-router/src/core/jsx/jsx-runtime.ts",
8
- "#acryl-jsx/jsx-dev-runtime": "./src/plugins/acryl-router/src/core/jsx/jsx-dev-runtime.ts"
7
+ "#acryl-jsx/jsx-runtime": "./plugins/acryl-router/src/core/jsx/jsx-runtime.ts",
8
+ "#acryl-jsx/jsx-dev-runtime": "./plugins/acryl-router/src/core/jsx/jsx-dev-runtime.ts"
9
9
  },
10
10
  "engines": {
11
11
  "node": ">=22.19.0"
12
12
  },
13
13
  "scripts": {
14
- "start": "node --import ./src/plugins/acryl-node-server/src/register.ts src/main.ts",
15
- "dev": "node --watch --import ./src/plugins/acryl-node-server/src/register.ts src/main.ts",
16
- "test": "node --import ./src/plugins/acryl-node-server/src/register.ts --test \"test/**/*.test.{ts,tsx}\"",
14
+ "start": "node --import ./plugins/acryl-node-server/src/register.ts src/main.ts",
15
+ "dev": "node --watch --import ./plugins/acryl-node-server/src/register.ts src/main.ts",
16
+ "test": "node --import ./plugins/acryl-node-server/src/register.ts --test \"test/**/*.test.{ts,tsx}\"",
17
17
  "check": "tsc --noEmit",
18
- "lock": "node src/plugins/manifest/lock.ts",
19
- "save": "node src/plugins/save/cli.ts",
20
- "upgrade": "node src/plugins/manifest/upgrade-cli.ts"
18
+ "lock": "node plugins/manifest/lock.ts",
19
+ "save": "node plugins/save/cli.ts",
20
+ "upgrade": "node plugins/manifest/upgrade-cli.ts"
21
21
  },
22
22
  "dependencies": {
23
23
  "typescript": "6.0.3"
@@ -1,8 +1,8 @@
1
- /** A page written in JSX: the scripts in package.json run Node.js with the vendored register hook (src/plugins/acryl-node-server/src/register.ts), which compiles .tsx with this app's own typescript. */
1
+ /** A page written in JSX: the scripts in package.json run Node.js with the vendored register hook (plugins/acryl-node-server/src/register.ts), which compiles .tsx with this app's own typescript. */
2
2
  const About = () => (
3
3
  <main>
4
4
  <h1>About</h1>
5
- <p>Rendered on the server with the JSX runtime in src/plugins/acryl-router.</p>
5
+ <p>Rendered on the server with the JSX runtime in plugins/acryl-router.</p>
6
6
  </main>
7
7
  )
8
8
 
@@ -1,15 +1,15 @@
1
1
  import { join } from 'node:path'
2
2
  import { fileURLToPath } from 'node:url'
3
3
  import { Context, type Fiber } from '@deepseek-ai/cordis'
4
- import * as nodeServer from './plugins/acryl-node-server/src/index.ts'
5
- import * as router from './plugins/acryl-router/src/index.ts'
6
- import { type AppInstance, instance } from './plugins/instance/index.ts'
4
+ import * as nodeServer from '../plugins/acryl-node-server/src/index.ts'
5
+ import * as router from '../plugins/acryl-router/src/index.ts'
6
+ import { type AppInstance, instance } from '../plugins/instance/index.ts'
7
7
  import {
8
8
  blueprintsIn,
9
9
  compose,
10
10
  loadManifest,
11
11
  type ParameterValue,
12
- } from './plugins/manifest/index.ts'
12
+ } from '../plugins/manifest/index.ts'
13
13
  import { routes } from './routes.ts'
14
14
 
15
15
  /** The plugins this app's code provides. `blend.yaml` chooses, orders and configures them. */
@@ -1,6 +1,6 @@
1
1
  import { fileURLToPath } from 'node:url'
2
+ import { selectInstance } from '../plugins/instance/index.ts'
2
3
  import { createApp } from './app.ts'
3
- import { selectInstance } from './plugins/instance/index.ts'
4
4
  import { APP_NAME } from './routes.ts'
5
5
 
6
6
  // The composition root: the one place that reads the environment (through selectInstance) and chooses where the app lives.
@@ -1,6 +1,6 @@
1
1
  import type { Context } from '@deepseek-ai/cordis'
2
+ import { Acryl } from '../plugins/acryl-router/src/index.ts'
2
3
  import { aboutPage } from './about.tsx'
3
- import { Acryl } from './plugins/acryl-router/src/index.ts'
4
4
 
5
5
  export const APP_NAME = '__APP_NAME__'
6
6
 
@@ -4,8 +4,8 @@ import { tmpdir } from 'node:os'
4
4
  import { join } from 'node:path'
5
5
  import { test } from 'node:test'
6
6
  import { fileURLToPath } from 'node:url'
7
+ import { pinnedInstance, withPort } from '../plugins/instance/index.ts'
7
8
  import { type App, createApp } from '../src/app.ts'
8
- import { pinnedInstance, withPort } from '../src/plugins/instance/index.ts'
9
9
  import { APP_NAME } from '../src/routes.ts'
10
10
 
11
11
  const projectRoot = fileURLToPath(new URL('..', import.meta.url))
@@ -15,5 +15,5 @@
15
15
  "jsx": "react-jsx",
16
16
  "jsxImportSource": "#acryl-jsx"
17
17
  },
18
- "include": ["src", "test"]
18
+ "include": ["src", "test", "plugins"]
19
19
  }
@@ -24,4 +24,4 @@ The routes only answer a caller on this machine: a request from another site's p
24
24
  Open `$URL/todo` for the page. Stop the app and start it again: the list is still there (`<home>/todo.json`, `.acrylblends/` unless `ACRYLBLENDS_HOME` says otherwise).
25
25
 
26
26
  - `blend.yaml` is the app as data. `npm run lock` records what it is built from; `npm run save` commits it, refusing secrets and public remotes for a private app.
27
- - The framework plugins are in `src/plugins/acryl-*/src`. Do not edit them: they are ACRYL's, vendored; the text that explains them is in the ACRYLBLENDS docs.
27
+ - The framework plugins are in `plugins/acryl-*/src`. Do not edit them: they are ACRYL's, vendored; the text that explains them is in the ACRYLBLENDS docs.
@@ -1,2 +1,3 @@
1
1
  node_modules/
2
2
  .acrylblends/
3
+ .acryl/
@@ -4,20 +4,20 @@
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "imports": {
7
- "#acryl-jsx/jsx-runtime": "./src/plugins/acryl-router/src/core/jsx/jsx-runtime.ts",
8
- "#acryl-jsx/jsx-dev-runtime": "./src/plugins/acryl-router/src/core/jsx/jsx-dev-runtime.ts"
7
+ "#acryl-jsx/jsx-runtime": "./plugins/acryl-router/src/core/jsx/jsx-runtime.ts",
8
+ "#acryl-jsx/jsx-dev-runtime": "./plugins/acryl-router/src/core/jsx/jsx-dev-runtime.ts"
9
9
  },
10
10
  "engines": {
11
11
  "node": ">=22.19.0"
12
12
  },
13
13
  "scripts": {
14
- "start": "node --import ./src/plugins/acryl-node-server/src/register.ts src/main.ts",
15
- "dev": "node --watch --import ./src/plugins/acryl-node-server/src/register.ts src/main.ts",
16
- "test": "node --import ./src/plugins/acryl-node-server/src/register.ts --test \"test/**/*.test.{ts,tsx}\"",
14
+ "start": "node --import ./plugins/acryl-node-server/src/register.ts src/main.ts",
15
+ "dev": "node --watch --import ./plugins/acryl-node-server/src/register.ts src/main.ts",
16
+ "test": "node --import ./plugins/acryl-node-server/src/register.ts --test \"test/**/*.test.{ts,tsx}\"",
17
17
  "check": "tsc --noEmit",
18
- "lock": "node src/plugins/manifest/lock.ts",
19
- "save": "node src/plugins/save/cli.ts",
20
- "upgrade": "node src/plugins/manifest/upgrade-cli.ts"
18
+ "lock": "node plugins/manifest/lock.ts",
19
+ "save": "node plugins/save/cli.ts",
20
+ "upgrade": "node plugins/manifest/upgrade-cli.ts"
21
21
  },
22
22
  "dependencies": {
23
23
  "typescript": "6.0.3"
@@ -1,16 +1,16 @@
1
1
  import { join } from 'node:path'
2
2
  import { fileURLToPath } from 'node:url'
3
3
  import { Context, type Fiber } from '@deepseek-ai/cordis'
4
- import * as nodeServer from './plugins/acryl-node-server/src/index.ts'
5
- import * as router from './plugins/acryl-router/src/index.ts'
6
- import * as state from './plugins/acryl-state/src/index.ts'
7
- import { type AppInstance, instance } from './plugins/instance/index.ts'
4
+ import * as nodeServer from '../plugins/acryl-node-server/src/index.ts'
5
+ import * as router from '../plugins/acryl-router/src/index.ts'
6
+ import * as state from '../plugins/acryl-state/src/index.ts'
7
+ import { type AppInstance, instance } from '../plugins/instance/index.ts'
8
8
  import {
9
9
  blueprintsIn,
10
10
  compose,
11
11
  loadManifest,
12
12
  type ParameterValue,
13
- } from './plugins/manifest/index.ts'
13
+ } from '../plugins/manifest/index.ts'
14
14
  import * as todo from './todo.ts'
15
15
 
16
16
  /** The plugins this app's code provides. `blend.yaml` chooses, orders and configures them. */
@@ -1,6 +1,6 @@
1
1
  import { fileURLToPath } from 'node:url'
2
+ import { selectInstance } from '../plugins/instance/index.ts'
2
3
  import { APP_NAME, createApp } from './app.ts'
3
- import { selectInstance } from './plugins/instance/index.ts'
4
4
 
5
5
  // The composition root: the one place that reads the environment (through selectInstance) and chooses where the app lives.
6
6
  const chosen = selectInstance({
@@ -6,10 +6,10 @@
6
6
  import { mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs'
7
7
  import { dirname } from 'node:path'
8
8
  import type { Context } from '@deepseek-ai/cordis'
9
- import { Acryl, HTTPException } from './plugins/acryl-router/src/index.ts'
10
- import { bodyLimit, loopbackOnly, trimTrailingSlash } from './plugins/acryl-router/src/middleware/index.ts'
11
- import { schemaValidator, streamSSE, type StandardSchema } from './plugins/acryl-router/src/helpers/index.ts'
12
- import type {} from './plugins/acryl-state/src/index.ts'
9
+ import { Acryl, HTTPException } from '../plugins/acryl-router/src/index.ts'
10
+ import { bodyLimit, loopbackOnly, trimTrailingSlash } from '../plugins/acryl-router/src/middleware/index.ts'
11
+ import { schemaValidator, streamSSE, type StandardSchema } from '../plugins/acryl-router/src/helpers/index.ts'
12
+ import type {} from '../plugins/acryl-state/src/index.ts'
13
13
  import { PAGE } from './page.ts'
14
14
 
15
15
  /** Stable Cordis plugin name, equal to the package name and the Loader row id. */
@@ -4,8 +4,8 @@ import { tmpdir } from 'node:os'
4
4
  import { join } from 'node:path'
5
5
  import { test } from 'node:test'
6
6
  import { fileURLToPath } from 'node:url'
7
+ import { pinnedInstance, withPort } from '../plugins/instance/index.ts'
7
8
  import { type App, createApp, readManifest } from '../src/app.ts'
8
- import { pinnedInstance, withPort } from '../src/plugins/instance/index.ts'
9
9
 
10
10
  const projectRoot = fileURLToPath(new URL('..', import.meta.url))
11
11
 
@@ -15,5 +15,5 @@
15
15
  "jsx": "react-jsx",
16
16
  "jsxImportSource": "#acryl-jsx"
17
17
  },
18
- "include": ["src", "test"]
18
+ "include": ["src", "test", "plugins"]
19
19
  }
@@ -5,8 +5,8 @@
5
5
  "examples/acryl-todo/src/index.ts": "src/todo.ts",
6
6
  "examples/acryl-todo/src/page.ts": "src/page.ts"
7
7
  },
8
- "commit": "8e23e14336647943d4232047e3ea253e434535d3"
8
+ "commit": "f132283c43337f5e1d58dfbbbc15786efb5e756c"
9
9
  },
10
10
  "rewrittenSpecifiers": 4,
11
- "digest": "sha256:9093704776563001f7f472f94cc5c2fdd79206342c1cb59c11fce62aa74df3ed"
11
+ "digest": "sha256:48d10af77d542ea0bf18cd3476ec9dc1f1225c8e7644c21492236de8c1d4a73c"
12
12
  }