@plurnk/plurnk-service 0.43.0 → 0.45.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.
Files changed (141) hide show
  1. package/.env.example +28 -28
  2. package/README.md +37 -18
  3. package/SPEC.md +64 -35
  4. package/dist/core/ChannelWrite.d.ts +4 -0
  5. package/dist/core/ChannelWrite.d.ts.map +1 -1
  6. package/dist/core/ChannelWrite.js +9 -0
  7. package/dist/core/ChannelWrite.js.map +1 -1
  8. package/dist/core/ChannelWrite.sql +69 -0
  9. package/dist/core/Engine.d.ts.map +1 -1
  10. package/dist/core/Engine.js +115 -77
  11. package/dist/core/Engine.js.map +1 -1
  12. package/dist/core/Engine.sql +291 -0
  13. package/dist/core/ExecutorRegistry.d.ts +4 -2
  14. package/dist/core/ExecutorRegistry.d.ts.map +1 -1
  15. package/dist/core/ExecutorRegistry.js +14 -4
  16. package/dist/core/ExecutorRegistry.js.map +1 -1
  17. package/dist/core/SchemeRegistry.d.ts +1 -0
  18. package/dist/core/SchemeRegistry.d.ts.map +1 -1
  19. package/dist/core/SchemeRegistry.js +22 -21
  20. package/dist/core/SchemeRegistry.js.map +1 -1
  21. package/dist/core/fork.d.ts.map +1 -1
  22. package/dist/core/fork.js +8 -1
  23. package/dist/core/fork.js.map +1 -1
  24. package/dist/core/fork.sql +50 -0
  25. package/dist/core/plugin-attribution.d.ts +5 -0
  26. package/dist/core/plugin-attribution.d.ts.map +1 -0
  27. package/dist/core/plugin-attribution.js +39 -0
  28. package/dist/core/plugin-attribution.js.map +1 -0
  29. package/dist/core/run-ops.sql +16 -0
  30. package/dist/core/session-settings.d.ts +1 -0
  31. package/dist/core/session-settings.d.ts.map +1 -1
  32. package/dist/core/session-settings.js +2 -1
  33. package/dist/core/session-settings.js.map +1 -1
  34. package/dist/schemes/Exec.d.ts +1 -1
  35. package/dist/schemes/Exec.d.ts.map +1 -1
  36. package/dist/schemes/Exec.js +19 -6
  37. package/dist/schemes/Exec.js.map +1 -1
  38. package/dist/schemes/File.d.ts +0 -1
  39. package/dist/schemes/File.d.ts.map +1 -1
  40. package/dist/schemes/File.js +29 -4
  41. package/dist/schemes/File.js.map +1 -1
  42. package/dist/schemes/Known.d.ts +0 -1
  43. package/dist/schemes/Known.d.ts.map +1 -1
  44. package/dist/schemes/Known.js +2 -1
  45. package/dist/schemes/Known.js.map +1 -1
  46. package/dist/schemes/Log.d.ts +0 -1
  47. package/dist/schemes/Log.d.ts.map +1 -1
  48. package/dist/schemes/Log.js +2 -1
  49. package/dist/schemes/Log.js.map +1 -1
  50. package/dist/schemes/Log.sql +37 -0
  51. package/dist/schemes/Plurnk.d.ts +0 -1
  52. package/dist/schemes/Plurnk.d.ts.map +1 -1
  53. package/dist/schemes/Plurnk.js +2 -1
  54. package/dist/schemes/Plurnk.js.map +1 -1
  55. package/dist/schemes/Run.d.ts +0 -1
  56. package/dist/schemes/Run.d.ts.map +1 -1
  57. package/dist/schemes/Run.js +2 -1
  58. package/dist/schemes/Run.js.map +1 -1
  59. package/dist/schemes/Unknown.d.ts +0 -1
  60. package/dist/schemes/Unknown.d.ts.map +1 -1
  61. package/dist/schemes/Unknown.js +2 -1
  62. package/dist/schemes/Unknown.js.map +1 -1
  63. package/dist/schemes/_entry-crud.sql +88 -0
  64. package/dist/schemes/_entry-find.sql +31 -0
  65. package/dist/schemes/_entry-graph.sql +60 -0
  66. package/dist/schemes/_entry-manifest.d.ts.map +1 -1
  67. package/dist/schemes/_entry-manifest.js +4 -1
  68. package/dist/schemes/_entry-manifest.js.map +1 -1
  69. package/dist/schemes/_entry-ops.sql +20 -0
  70. package/dist/schemes/_entry-semantic.sql +64 -0
  71. package/dist/schemes/exec-env.js +1 -1
  72. package/dist/schemes/exec-env.js.map +1 -1
  73. package/dist/server/Daemon.d.ts.map +1 -1
  74. package/dist/server/Daemon.js +103 -37
  75. package/dist/server/Daemon.js.map +1 -1
  76. package/dist/server/clientTurn.sql +10 -0
  77. package/dist/server/drain.sql +82 -0
  78. package/dist/server/dsl.d.ts.map +1 -1
  79. package/dist/server/dsl.js +11 -4
  80. package/dist/server/dsl.js.map +1 -1
  81. package/dist/server/envelope.sql +75 -0
  82. package/dist/server/logEntry.sql +10 -0
  83. package/dist/server/methods/_dispatchAsClient.d.ts.map +1 -1
  84. package/dist/server/methods/_dispatchAsClient.js +11 -6
  85. package/dist/server/methods/_dispatchAsClient.js.map +1 -1
  86. package/dist/server/methods/entry_read.sql +21 -0
  87. package/dist/server/methods/log_read.sql +11 -0
  88. package/dist/server/methods/loop_run.d.ts.map +1 -1
  89. package/dist/server/methods/loop_run.js +4 -0
  90. package/dist/server/methods/loop_run.js.map +1 -1
  91. package/dist/server/methods/loop_run.sql +9 -0
  92. package/dist/server/methods/session_create.d.ts.map +1 -1
  93. package/dist/server/methods/session_create.js +10 -3
  94. package/dist/server/methods/session_create.js.map +1 -1
  95. package/dist/service.d.ts +6 -0
  96. package/dist/service.d.ts.map +1 -0
  97. package/dist/service.js +221 -0
  98. package/dist/service.js.map +1 -0
  99. package/package.json +29 -15
  100. package/requirements.md +2 -1
  101. package/bin/plurnk-service.ts +0 -176
  102. package/dist/core/ProviderRegistry.d.ts +0 -42
  103. package/dist/core/ProviderRegistry.d.ts.map +0 -1
  104. package/dist/core/ProviderRegistry.js +0 -72
  105. package/dist/core/ProviderRegistry.js.map +0 -1
  106. package/dist/core/line-marker.d.ts +0 -23
  107. package/dist/core/line-marker.d.ts.map +0 -1
  108. package/dist/core/line-marker.js +0 -321
  109. package/dist/core/line-marker.js.map +0 -1
  110. package/dist/core/matcher.d.ts +0 -12
  111. package/dist/core/matcher.d.ts.map +0 -1
  112. package/dist/core/matcher.js +0 -72
  113. package/dist/core/matcher.js.map +0 -1
  114. package/dist/core/mimetype-binary.d.ts +0 -6
  115. package/dist/core/mimetype-binary.d.ts.map +0 -1
  116. package/dist/core/mimetype-binary.js +0 -82
  117. package/dist/core/mimetype-binary.js.map +0 -1
  118. package/dist/core/path-mimetype.d.ts +0 -3
  119. package/dist/core/path-mimetype.d.ts.map +0 -1
  120. package/dist/core/path-mimetype.js +0 -47
  121. package/dist/core/path-mimetype.js.map +0 -1
  122. package/dist/core/plugin-trust.d.ts +0 -4
  123. package/dist/core/plugin-trust.d.ts.map +0 -1
  124. package/dist/core/plugin-trust.js +0 -23
  125. package/dist/core/plugin-trust.js.map +0 -1
  126. package/dist/providers/Mock.d.ts +0 -43
  127. package/dist/providers/Mock.d.ts.map +0 -1
  128. package/dist/providers/Mock.js +0 -36
  129. package/dist/providers/Mock.js.map +0 -1
  130. package/dist/server/methods/op_hide.d.ts +0 -5
  131. package/dist/server/methods/op_hide.d.ts.map +0 -1
  132. package/dist/server/methods/op_hide.js +0 -24
  133. package/dist/server/methods/op_hide.js.map +0 -1
  134. package/dist/server/methods/op_show.d.ts +0 -5
  135. package/dist/server/methods/op_show.d.ts.map +0 -1
  136. package/dist/server/methods/op_show.js +0 -24
  137. package/dist/server/methods/op_show.js.map +0 -1
  138. package/dist/server/methods/session_set_persona.d.ts +0 -5
  139. package/dist/server/methods/session_set_persona.d.ts.map +0 -1
  140. package/dist/server/methods/session_set_persona.js +0 -29
  141. package/dist/server/methods/session_set_persona.js.map +0 -1
@@ -0,0 +1,221 @@
1
+ #!/usr/bin/env node
2
+ import { parseArgs } from "node:util";
3
+ import { existsSync, mkdirSync, copyFileSync, writeFileSync } from "node:fs";
4
+ import { fileURLToPath } from "node:url";
5
+ import { dirname, resolve } from "node:path";
6
+ import { homedir } from "node:os";
7
+ import { createRequire } from "node:module";
8
+ import SqlRite from "@possumtech/sqlrite";
9
+ import Daemon from "./server/Daemon.js";
10
+ import EnvFlags from "./core/EnvFlags.js";
11
+ import ProviderInstantiate from "./core/ProviderInstantiate.js";
12
+ import { resolveActiveAlias } from "@plurnk/plurnk-providers";
13
+ // The `plurnk-service` executable: launches the daemon (start) or runs migrations.
14
+ // Not the user-facing client — that is the separate `plurnk` project.
15
+ export default class Service {
16
+ // This file's own directory holds the runtime code + its .sql (src/ in dev, dist/ in a
17
+ // published install); its parent is the package root (migrations/, requirements.md, .env.example).
18
+ static #codeDir = dirname(fileURLToPath(import.meta.url));
19
+ static #projectRoot = resolve(Service.#codeDir, "..");
20
+ static #ext = import.meta.url.endsWith(".ts") ? ".ts" : ".js";
21
+ static #homeDir = resolve(homedir(), ".plurnk");
22
+ // First-run bootstrap — run-time, NOT an install script: seed ~/.plurnk so a global
23
+ // install has a stable home for config + the DB. Idempotent (only acts when absent).
24
+ static #ensureHome() {
25
+ // Seed ONCE, on first run (the home is absent). After that the user owns ~/.plurnk —
26
+ // edits and deletions stick, no silent re-seed. `~/.plurnk/.env.example` is the cascade
27
+ // FLOOR (the visible legend); the node_modules copy is the seed + CLI-flag source only.
28
+ // Wiping the whole dir is a deliberate reset. A deleted floor stays deleted; a missing
29
+ // required knob then surfaces as a clear `missing PLURNK_X` error, not a crash.
30
+ if (existsSync(Service.#homeDir))
31
+ return;
32
+ mkdirSync(Service.#homeDir, { recursive: true });
33
+ const shipped = resolve(Service.#projectRoot, ".env.example");
34
+ if (existsSync(shipped))
35
+ copyFileSync(shipped, resolve(Service.#homeDir, ".env.example"));
36
+ writeFileSync(resolve(Service.#homeDir, ".env"), "# plurnk config — overrides the shipped defaults. e.g.\n# PLURNK_MODEL=gemma\n");
37
+ process.stderr.write(`plurnk-service: created ${Service.#homeDir} — config in ${resolve(Service.#homeDir, ".env")}\n`);
38
+ }
39
+ static #expandHome(p) {
40
+ if (p === "~")
41
+ return homedir();
42
+ return p.startsWith("~/") ? resolve(homedir(), p.slice(2)) : p;
43
+ }
44
+ // The node_modules holding the service's plugin deps (exec/scheme/mimetype), resolved
45
+ // package-relative so a global install finds them regardless of run-CWD. Falls back to CWD.
46
+ static #pluginsNodeModules() {
47
+ try {
48
+ const execs = createRequire(import.meta.url).resolve("@plurnk/plurnk-execs/package.json");
49
+ return resolve(dirname(execs), "..", "..");
50
+ }
51
+ catch {
52
+ return resolve(process.cwd(), "node_modules");
53
+ }
54
+ }
55
+ static #die(code, message) {
56
+ process.stderr.write(`${message}\n`);
57
+ process.exit(code);
58
+ }
59
+ static #loadEnv(path, required) {
60
+ if (existsSync(path)) {
61
+ try {
62
+ process.loadEnvFile(path);
63
+ }
64
+ catch (cause) {
65
+ Service.#die(64, `failed to load ${path}: ${cause instanceof Error ? cause.message : String(cause)}`);
66
+ }
67
+ }
68
+ else if (required) {
69
+ Service.#die(64, `${path} does not exist`);
70
+ }
71
+ }
72
+ // node-style env-file flags: --env-file=<path> (required) / --env-file-if-exists=<path>
73
+ // (skip if missing), repeatable, in command-line order. node only loads pre-script files;
74
+ // a published `plurnk-service --env-file=…` needs this post-script loader.
75
+ static #envFileArgs() {
76
+ return process.argv.flatMap((a) => {
77
+ if (a.startsWith("--env-file-if-exists="))
78
+ return [{ path: a.slice(a.indexOf("=") + 1), required: false }];
79
+ if (a.startsWith("--env-file="))
80
+ return [{ path: a.slice(a.indexOf("=") + 1), required: true }];
81
+ return [];
82
+ });
83
+ }
84
+ static #requireEnv(name) {
85
+ const value = process.env[name];
86
+ if (value === undefined || value.length === 0)
87
+ Service.#die(78, `missing required env ${name} (declare it in .env.example)`);
88
+ return value;
89
+ }
90
+ static #sqliteKnob(name) {
91
+ const raw = process.env[name];
92
+ if (raw === undefined || raw.trim() === "")
93
+ return undefined;
94
+ const n = Number(raw);
95
+ if (!Number.isInteger(n))
96
+ Service.#die(78, `${name} must be an integer, got ${JSON.stringify(raw)}`);
97
+ return n;
98
+ }
99
+ static async #openDb(dbPath) {
100
+ const tuning = {};
101
+ for (const [env, opt] of [
102
+ ["PLURNK_SQLITE_TIMEOUT", "timeout"],
103
+ ["PLURNK_SQLITE_CACHE_SIZE", "cacheSize"],
104
+ ["PLURNK_SQLITE_MMAP_SIZE", "mmapSize"],
105
+ ["PLURNK_SQLITE_MAX_PAGE_COUNT", "maxPageCount"],
106
+ ]) {
107
+ const v = Service.#sqliteKnob(env);
108
+ if (v !== undefined)
109
+ tuning[opt] = v;
110
+ }
111
+ mkdirSync(dirname(dbPath), { recursive: true });
112
+ const db = await SqlRite.open({
113
+ path: dbPath,
114
+ dir: [resolve(Service.#projectRoot, "migrations"), Service.#codeDir],
115
+ functions: [resolve(Service.#codeDir, `schemes/cosine${Service.#ext}`)],
116
+ ...tuning,
117
+ });
118
+ return db;
119
+ }
120
+ static async #migrate() {
121
+ const dbPath = Service.#expandHome(Service.#requireEnv("PLURNK_DB_PATH"));
122
+ const db = await Service.#openDb(dbPath);
123
+ try {
124
+ process.stdout.write(`migrated: ${dbPath}\n`);
125
+ }
126
+ finally {
127
+ await db.close();
128
+ }
129
+ }
130
+ static async #start() {
131
+ const dbPath = Service.#expandHome(Service.#requireEnv("PLURNK_DB_PATH"));
132
+ const host = Service.#requireEnv("PLURNK_HOST");
133
+ const port = Number(Service.#requireEnv("PLURNK_PORT"));
134
+ const db = await Service.#openDb(dbPath);
135
+ const alias = resolveActiveAlias();
136
+ const provider = alias === null ? null : await ProviderInstantiate.loadActiveProvider();
137
+ const daemon = new Daemon({ db, provider, nodeModulesPath: Service.#pluginsNodeModules() });
138
+ const addr = await daemon.start({ host, port });
139
+ if (await daemon.mimetypes.embedderInfo() === null) {
140
+ process.stderr.write("plurnk-service: embedder inactive — semantic search (FIND) is degraded. Install @plurnk/plurnk-mimetypes-embeddings, or see README.md#semantic-search\n");
141
+ }
142
+ if (alias === null) {
143
+ process.stderr.write(`plurnk-service: no model configured — set PLURNK_MODEL in ${resolve(Service.#homeDir, ".env")} (e.g. PLURNK_MODEL=gemma). Bring your own provider; the hosted default isn't live yet.\n`);
144
+ }
145
+ const aliasStr = alias === null ? "no model" : `${alias.alias}=${alias.provider}/${alias.model}`;
146
+ process.stdout.write(`plurnk-service ws://${addr.host}:${addr.port} db=${dbPath} ${aliasStr}\n`);
147
+ const shutdown = async () => { await daemon.stop(); await db.close(); process.exit(0); };
148
+ process.on("SIGINT", shutdown);
149
+ process.on("SIGTERM", shutdown);
150
+ }
151
+ static async main() {
152
+ if (!process.argv.includes("--help") && !process.argv.includes("-h"))
153
+ Service.#ensureHome();
154
+ // Env cascade — first write wins (loadEnvFile is set-if-unset), so load highest first.
155
+ // Precedence high→low: CLI --flags > shell env > --env-file/--config > ./.env >
156
+ // ~/.plurnk/.env > ~/.plurnk/.env.example > package .env.example (the floor).
157
+ for (const { path: envFile, required } of Service.#envFileArgs())
158
+ Service.#loadEnv(envFile, required);
159
+ const configFlagIndex = process.argv.findIndex((a) => a === "--config" || a.startsWith("--config="));
160
+ const configFile = (() => {
161
+ if (configFlagIndex === -1)
162
+ return null;
163
+ const arg = process.argv[configFlagIndex];
164
+ if (arg.includes("="))
165
+ return arg.slice(arg.indexOf("=") + 1);
166
+ return process.argv[configFlagIndex + 1] ?? null;
167
+ })();
168
+ if (configFile !== null)
169
+ Service.#loadEnv(configFile, true);
170
+ Service.#loadEnv(".env", false);
171
+ Service.#loadEnv(resolve(Service.#homeDir, ".env"), false);
172
+ Service.#loadEnv(resolve(Service.#homeDir, ".env.example"), false); // the cascade floor (NOT the node_modules copy)
173
+ const flagDescriptors = await EnvFlags.parseEnvExample(resolve(Service.#projectRoot, ".env.example"));
174
+ const flagOptions = {};
175
+ for (const f of flagDescriptors) {
176
+ flagOptions[f.flagName.replace(/^--/, "")] = { type: "string" };
177
+ }
178
+ const usage = `usage: plurnk-service [options] [migrate]
179
+
180
+ ${EnvFlags.formatFlagsHelp(flagDescriptors)}
181
+
182
+ --env-file=<path> layer env from <path> (repeatable; errors if missing)
183
+ --env-file-if-exists=<path> layer env from <path> if present (repeatable)
184
+ --config=<path> layer additional env from <path>
185
+ -h, --help show this help
186
+ `;
187
+ const { positionals, values } = parseArgs({
188
+ allowPositionals: true,
189
+ strict: false,
190
+ options: { help: { type: "boolean", short: "h" }, config: { type: "string" }, ...flagOptions },
191
+ });
192
+ for (const f of flagDescriptors) {
193
+ const key = f.flagName.replace(/^--/, "");
194
+ const v = values[key];
195
+ if (typeof v === "string")
196
+ process.env[f.envName] = v;
197
+ }
198
+ if (values.help) {
199
+ process.stdout.write(usage);
200
+ process.exit(0);
201
+ }
202
+ const dispatch = { migrate: Service.#migrate, start: Service.#start };
203
+ const subcommand = typeof positionals[0] === "string" ? positionals[0] : "start";
204
+ const handler = dispatch[subcommand];
205
+ if (handler === undefined)
206
+ Service.#die(64, `unknown subcommand: ${subcommand}\n\n${usage}`);
207
+ if (positionals.length > 1)
208
+ Service.#die(64, `unexpected arguments: ${positionals.slice(1).join(" ")}`);
209
+ try {
210
+ await handler();
211
+ }
212
+ catch (cause) {
213
+ process.stderr.write(`${subcommand}: ${cause instanceof Error ? cause.message : String(cause)}\n`);
214
+ if (cause instanceof Error && cause.cause)
215
+ process.stderr.write(` cause: ${cause.cause instanceof Error ? cause.cause.message : String(cause.cause)}\n`);
216
+ process.exit(1);
217
+ }
218
+ }
219
+ }
220
+ await Service.main();
221
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plurnk/plurnk-service",
3
- "version": "0.43.0",
3
+ "version": "0.45.0",
4
4
  "description": "Plurnk agent runtime — the server / engine / core. Implements the @plurnk/plurnk-grammar contract.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -15,11 +15,10 @@
15
15
  "./package.json": "./package.json"
16
16
  },
17
17
  "bin": {
18
- "plurnk-service": "./bin/plurnk-service.ts"
18
+ "plurnk-service": "./dist/service.js"
19
19
  },
20
20
  "files": [
21
21
  ".env.example",
22
- "bin/plurnk-service.ts",
23
22
  "dist/**/*",
24
23
  "migrations/**/*.sql",
25
24
  "requirements.md",
@@ -30,39 +29,54 @@
30
29
  "access": "public"
31
30
  },
32
31
  "scripts": {
33
- "start": "node bin/plurnk-service.ts",
32
+ "start": "node src/service.ts",
34
33
  "test:lint": "tsc --noEmit",
35
34
  "test:unit": "node --env-file-if-exists=.env.example --env-file-if-exists=.env --env-file-if-exists=.env.test --test --test-timeout=30000 src/**/*.test.ts",
36
35
  "test:intg": "npm run test:clean-tmp && PLURNK_MANIFEST_ITEMS=0 node --env-file-if-exists=.env.example --env-file-if-exists=.env --env-file-if-exists=.env.test --test --test-timeout=30000 test/intg/*.test.ts",
37
- "test:live": "npm run test:clean-tmp && node --env-file-if-exists=.env.example --env-file-if-exists=.env --env-file-if-exists=.env.test --test --test-concurrency=1 test/live/*.test.ts",
38
- "test:demo": "npm run test:clean-tmp && node --env-file-if-exists=.env.example --env-file-if-exists=.env --env-file-if-exists=.env.test --test --test-concurrency=1 test/demo/*.test.ts",
36
+ "test:live": "npm run test:clean-tmp && node --env-file-if-exists=.env.example --env-file-if-exists=.env --env-file-if-exists=.env.test --test --test-force-exit --test-concurrency=1 test/live/*.test.ts",
37
+ "test:demo": "npm run test:clean-tmp && node --env-file-if-exists=.env.example --env-file-if-exists=.env --env-file-if-exists=.env.test --test --test-force-exit --test-concurrency=1 test/demo/*.test.ts",
39
38
  "test:all": "npm run test:lint && npm run test:unit && npm run test:intg && npm run test:demo",
40
39
  "test:digest": "node bin/digest.ts",
41
40
  "test:clean-tmp": "rm -rf test/intg/.tmp",
42
41
  "dev:digest": "node bin/digest.ts",
42
+ "build:clean": "rm -rf dist",
43
43
  "build:dist": "tsc -p tsconfig.build.json",
44
- "build": "npm run build:dist",
44
+ "build:sql": "node scripts/copy-sql.mjs",
45
+ "build": "npm run build:clean && npm run build:dist && npm run build:sql",
46
+ "build:global:install": "npm run build && npm install -g .",
47
+ "build:global:uninstall": "npm uninstall -g @plurnk/plurnk-service",
48
+ "build:local:install": "node scripts/install-sandbox.mjs install",
49
+ "build:local:uninstall": "node scripts/install-sandbox.mjs uninstall",
50
+ "test:installation": "node scripts/test-installation.mjs",
45
51
  "prepare": "npm run build"
46
52
  },
47
53
  "dependencies": {
48
- "@plurnk/plurnk-execs": "0.4.9",
54
+ "@plurnk/plurnk-execs": "0.4.11",
49
55
  "@plurnk/plurnk-execs-all": "0.1.5",
50
- "@plurnk/plurnk-grammar": "0.67.0",
51
- "@plurnk/plurnk-mimetypes": "0.15.19",
52
- "@plurnk/plurnk-mimetypes-all": "0.5.0",
53
- "@plurnk/plurnk-mimetypes-embeddings": "0.2.0",
54
- "@plurnk/plurnk-providers": "0.12.0",
56
+ "@plurnk/plurnk-grammar": "0.73.0",
57
+ "@plurnk/plurnk-mimetypes": "0.15.21",
58
+ "@plurnk/plurnk-mimetypes-all": "0.5.1",
59
+ "@plurnk/plurnk-providers": "0.13.0",
55
60
  "@plurnk/plurnk-providers-all": "0.8.0",
56
- "@plurnk/plurnk-schemes": "0.21.0",
57
- "@plurnk/plurnk-schemes-all": "0.1.5",
61
+ "@plurnk/plurnk-schemes": "0.28.0",
62
+ "@plurnk/plurnk-schemes-all": "0.1.11",
58
63
  "@possumtech/sqlrite": "5.2.0",
59
64
  "diff": "^9.0.0",
60
65
  "ws": "^8.20.1"
61
66
  },
62
67
  "devDependencies": {
68
+ "@plurnk/plurnk-mimetypes-embeddings": "0.3.0",
63
69
  "@types/diff": "^7.0.2",
64
70
  "@types/node": "^25.8.0",
65
71
  "@types/ws": "^8.18.1",
66
72
  "typescript": "^6.0.3"
73
+ },
74
+ "peerDependencies": {
75
+ "@plurnk/plurnk-mimetypes-embeddings": "0.3.0"
76
+ },
77
+ "peerDependenciesMeta": {
78
+ "@plurnk/plurnk-mimetypes-embeddings": {
79
+ "optional": true
80
+ }
67
81
  }
68
82
  }
package/requirements.md CHANGED
@@ -1,2 +1,3 @@
1
- YOU MUST use OPEN and FOLD to keep your context budget healthy, optimized, topical, and below the `tokensFree` limit.
1
+ YOU MUST begin the turn with <<PLAN:...:PLAN
2
+ YOU MUST use OPEN and FOLD to keep your context budget healthy, optimized, topical, and below the `TokensFree` limit.
2
3
  YOU MUST terminate the turn by SENDing a status code containing the results, answer, or a status update: `<<SEND[{102|200|202|499}]:...:SEND`
@@ -1,176 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { parseArgs } from "node:util";
4
- import { existsSync } from "node:fs";
5
- import { fileURLToPath } from "node:url";
6
- import { dirname, resolve } from "node:path";
7
- import SqlRite from "@possumtech/sqlrite";
8
- import type { Db } from "../src/core/Db.ts";
9
- import Daemon from "../src/server/Daemon.ts";
10
- import EnvFlags from "../src/core/EnvFlags.ts";
11
- import ProviderInstantiate from "../src/core/ProviderInstantiate.ts";
12
- import { resolveActiveAlias } from "@plurnk/plurnk-providers";
13
-
14
- export default class Cli {
15
- static #projectRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
16
-
17
- static #die(code: number, message: string): never {
18
- process.stderr.write(`${message}\n`);
19
- process.exit(code);
20
- }
21
-
22
- static #loadEnv(path: string, required: boolean): void {
23
- if (existsSync(path)) {
24
- try { process.loadEnvFile(path); }
25
- catch (cause) { Cli.#die(64, `failed to load ${path}: ${cause instanceof Error ? cause.message : String(cause)}`); }
26
- } else if (required) {
27
- Cli.#die(64, `${path} does not exist`);
28
- }
29
- }
30
-
31
- // node-style env-file flags: --env-file=<path> (required) / --env-file-if-exists=<path>
32
- // (skip if missing), repeatable, in command-line order. They layer extra files ABOVE
33
- // the .env cascade but BELOW shell env (loadEnvFile is set-if-unset) and the --<knob>
34
- // CLI flags (assigned last). The `=` form only — node's canonical syntax (so it never
35
- // leaks a positional). NB: node validates these paths from the full argv (and exits on
36
- // a missing *required* one), but only LOADS pre-script files — the post-script loading
37
- // a published `plurnk-service --env-file=…` needs is this.
38
- static #envFileArgs(): Array<{ path: string; required: boolean }> {
39
- return process.argv.flatMap((a): Array<{ path: string; required: boolean }> => {
40
- if (a.startsWith("--env-file-if-exists=")) return [{ path: a.slice(a.indexOf("=") + 1), required: false }];
41
- if (a.startsWith("--env-file=")) return [{ path: a.slice(a.indexOf("=") + 1), required: true }];
42
- return [];
43
- });
44
- }
45
-
46
- // The .env cascade always populates these from .env.example, so absence is
47
- // a broken config, not a runtime branch — fail hard rather than `?? ""`.
48
- static #requireEnv(name: string): string {
49
- const value = process.env[name];
50
- if (value === undefined || value.length === 0) Cli.#die(78, `missing required env ${name} (declare it in .env.example)`);
51
- return value;
52
- }
53
-
54
- // Optional integer sqlite tuning knob — undefined when unset (so it never clobbers
55
- // sqlrite's default by spreading an explicit `undefined`); fail-hard on a non-integer.
56
- static #sqliteKnob(name: string): number | undefined {
57
- const raw = process.env[name];
58
- if (raw === undefined || raw.trim() === "") return undefined;
59
- const n = Number(raw);
60
- if (!Number.isInteger(n)) Cli.#die(78, `${name} must be an integer, got ${JSON.stringify(raw)}`);
61
- return n;
62
- }
63
-
64
- static async #openDb(dbPath: string): Promise<Db> {
65
- // Curated sqlite tuning (sqlrite 5.2.0, #7) — pass through ONLY the knobs the
66
- // operator set, so an unset one keeps sqlrite's default (e.g. busy_timeout=5000).
67
- const tuning: Record<string, number> = {};
68
- for (const [env, opt] of [
69
- ["PLURNK_SQLITE_TIMEOUT", "timeout"],
70
- ["PLURNK_SQLITE_CACHE_SIZE", "cacheSize"],
71
- ["PLURNK_SQLITE_MMAP_SIZE", "mmapSize"],
72
- ["PLURNK_SQLITE_MAX_PAGE_COUNT", "maxPageCount"],
73
- ] as const) {
74
- const v = Cli.#sqliteKnob(env);
75
- if (v !== undefined) tuning[opt] = v;
76
- }
77
- const db = await SqlRite.open({
78
- path: dbPath,
79
- dir: [resolve(Cli.#projectRoot, "migrations"), resolve(Cli.#projectRoot, "src")],
80
- functions: [resolve(Cli.#projectRoot, "src/schemes/cosine.ts")],
81
- ...tuning,
82
- });
83
- return db as unknown as Db;
84
- }
85
-
86
- static async #migrate(): Promise<void> {
87
- const dbPath = Cli.#requireEnv("PLURNK_DB_PATH");
88
- const db = await Cli.#openDb(dbPath);
89
- try { process.stdout.write(`migrated: ${dbPath}\n`); }
90
- finally { await db.close(); }
91
- }
92
-
93
- static async #start(): Promise<void> {
94
- const dbPath = Cli.#requireEnv("PLURNK_DB_PATH");
95
- const host = Cli.#requireEnv("PLURNK_HOST");
96
- const port = Number(Cli.#requireEnv("PLURNK_PORT"));
97
-
98
- const db = await Cli.#openDb(dbPath);
99
- const alias = resolveActiveAlias();
100
- const provider = alias === null ? null : await ProviderInstantiate.loadActiveProvider();
101
- const daemon = new Daemon({ db, provider });
102
- const addr = await daemon.start({ host, port });
103
- const aliasStr = alias === null ? "no model" : `${alias.alias}=${alias.provider}/${alias.model}`;
104
- process.stdout.write(`plurnk-service ws://${addr.host}:${addr.port} db=${dbPath} ${aliasStr}\n`);
105
-
106
- const shutdown = async (): Promise<void> => { await daemon.stop(); await db.close(); process.exit(0); };
107
- process.on("SIGINT", shutdown);
108
- process.on("SIGTERM", shutdown);
109
- }
110
-
111
- static async main(): Promise<void> {
112
- // Env cascade, highest precedence loads FIRST (loadEnvFile is set-if-unset,
113
- // first write wins): --env-file(s) < --config < .env < .env.example, all of them
114
- // OUTRANKED by pre-set shell env, then by the --<knob> CLI flags (assigned last,
115
- // below). So --env-file overrides the .env files but never a shell var or a CLI
116
- // arg — node-idiomatic layering.
117
- for (const { path: envFile, required } of Cli.#envFileArgs()) Cli.#loadEnv(envFile, required);
118
-
119
- const configFlagIndex = process.argv.findIndex((a) => a === "--config" || a.startsWith("--config="));
120
- const configFile = ((): string | null => {
121
- if (configFlagIndex === -1) return null;
122
- const arg = process.argv[configFlagIndex];
123
- if (arg.includes("=")) return arg.slice(arg.indexOf("=") + 1);
124
- return process.argv[configFlagIndex + 1] ?? null;
125
- })();
126
-
127
- if (configFile !== null) Cli.#loadEnv(configFile, true);
128
- Cli.#loadEnv(".env", false);
129
- Cli.#loadEnv(resolve(Cli.#projectRoot, ".env.example"), false);
130
-
131
- const flagDescriptors = await EnvFlags.parseEnvExample(resolve(Cli.#projectRoot, ".env.example"));
132
- const flagOptions: Record<string, { type: "string" }> = {};
133
- for (const f of flagDescriptors) {
134
- flagOptions[f.flagName.replace(/^--/, "")] = { type: "string" };
135
- }
136
-
137
- const usage = `usage: plurnk-service [options] [migrate]
138
-
139
- ${EnvFlags.formatFlagsHelp(flagDescriptors)}
140
-
141
- --env-file=<path> layer env from <path> (repeatable; errors if missing)
142
- --env-file-if-exists=<path> layer env from <path> if present (repeatable)
143
- --config=<path> layer additional env from <path>
144
- -h, --help show this help
145
- `;
146
-
147
- const { positionals, values } = parseArgs({
148
- allowPositionals: true,
149
- strict: false,
150
- options: { help: { type: "boolean", short: "h" }, config: { type: "string" }, ...flagOptions },
151
- });
152
-
153
- for (const f of flagDescriptors) {
154
- const key = f.flagName.replace(/^--/, "");
155
- const v = values[key];
156
- if (typeof v === "string") process.env[f.envName] = v;
157
- }
158
-
159
- if (values.help) { process.stdout.write(usage); process.exit(0); }
160
-
161
- const dispatch: Record<string, () => Promise<void>> = { migrate: Cli.#migrate, start: Cli.#start };
162
- const subcommand = typeof positionals[0] === "string" ? positionals[0] : "start";
163
- const handler = dispatch[subcommand];
164
- if (handler === undefined) Cli.#die(64, `unknown subcommand: ${subcommand}\n\n${usage}`);
165
- if (positionals.length > 1) Cli.#die(64, `unexpected arguments: ${positionals.slice(1).join(" ")}`);
166
-
167
- try { await handler(); }
168
- catch (cause) {
169
- process.stderr.write(`${subcommand}: ${cause instanceof Error ? cause.message : String(cause)}\n`);
170
- if (cause instanceof Error && cause.cause) process.stderr.write(` cause: ${cause.cause instanceof Error ? cause.cause.message : String(cause.cause)}\n`);
171
- process.exit(1);
172
- }
173
- }
174
- }
175
-
176
- await Cli.main();
@@ -1,42 +0,0 @@
1
- interface ChatMessage {
2
- role: "system" | "user" | "assistant";
3
- content: string;
4
- }
5
- export interface ProviderUsage {
6
- readonly prompt: number;
7
- readonly completion: number;
8
- readonly cached: number;
9
- readonly total: number;
10
- }
11
- export interface ProviderAssistant {
12
- readonly content: string;
13
- readonly reasoning: string | null;
14
- readonly usage: ProviderUsage;
15
- readonly finishReason: string | null;
16
- readonly model: string;
17
- }
18
- export interface ProviderResponse {
19
- readonly assistant: ProviderAssistant;
20
- readonly assistantRaw: unknown;
21
- }
22
- export interface Provider {
23
- generate(args: {
24
- messages: ChatMessage[];
25
- signal?: AbortSignal;
26
- }): Promise<ProviderResponse>;
27
- readonly contextSize: number | null;
28
- readonly model: string;
29
- countTokens(text: string): number;
30
- costFor(usage: ProviderUsage): number;
31
- }
32
- export interface ProviderAlias {
33
- readonly alias: string;
34
- readonly provider: string;
35
- readonly model: string;
36
- }
37
- export declare const parseAliasesFromEnv: (env?: NodeJS.ProcessEnv) => ProviderAlias[];
38
- export declare const resolveActiveAlias: (env?: NodeJS.ProcessEnv) => ProviderAlias | null;
39
- export declare const instantiateProvider: (alias: ProviderAlias, env?: NodeJS.ProcessEnv) => Promise<Provider>;
40
- export declare const loadActiveProvider: (env?: NodeJS.ProcessEnv) => Promise<Provider | null>;
41
- export {};
42
- //# sourceMappingURL=ProviderRegistry.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ProviderRegistry.d.ts","sourceRoot":"","sources":["../../src/core/ProviderRegistry.ts"],"names":[],"mappings":"AAWA,UAAU,WAAW;IAAG,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE;AAYhF,MAAM,WAAW,aAAa;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CAC1B;AACD,MAAM,WAAW,iBAAiB;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CAC1B;AACD,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAC;IACtC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;CAClC;AACD,MAAM,WAAW,QAAQ;IACrB,QAAQ,CAAC,IAAI,EAAE;QAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;QAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAK7F,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAMvB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAKlC,OAAO,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAAC;CACzC;AAED,MAAM,WAAW,aAAa;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CAC1B;AAED,eAAO,MAAM,mBAAmB,GAAI,MAAK,MAAM,CAAC,UAAwB,KAAG,aAAa,EAgBvF,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,MAAK,MAAM,CAAC,UAAwB,KAAG,aAAa,GAAG,IAKzF,CAAC;AAcF,eAAO,MAAM,mBAAmB,GAAU,OAAO,aAAa,EAAE,MAAK,MAAM,CAAC,UAAwB,KAAG,OAAO,CAAC,QAAQ,CAmBtH,CAAC;AAIF,eAAO,MAAM,kBAAkB,GAAU,MAAK,MAAM,CAAC,UAAwB,KAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAItG,CAAC"}
@@ -1,72 +0,0 @@
1
- // Model alias resolution. Reads PLURNK_MODEL_<alias>=<provider>/<model> env
2
- // vars; PLURNK_MODEL=<alias> selects which to use at boot. Each alias maps
3
- // to a provider plugin (`@plurnk/plurnk-providers-<provider>`); the registry
4
- // imports the matching package and constructs it with provider-specific
5
- // env conventions.
6
- //
7
- // Rummy parallel: RUMMY_MODEL_<alias>="<provider>/<model>" cascade. The
8
- // first path segment selects the provider plugin; the rest is the
9
- // provider's own identifier (may contain "/" for tri-level providers like
10
- // openrouter's publisher/model).
11
- var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
12
- if (typeof path === "string" && /^\.\.?\//.test(path)) {
13
- return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
14
- return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
15
- });
16
- }
17
- return path;
18
- };
19
- export const parseAliasesFromEnv = (env = process.env) => {
20
- const out = [];
21
- for (const [key, value] of Object.entries(env)) {
22
- if (value === undefined || value.length === 0)
23
- continue;
24
- if (!key.startsWith("PLURNK_MODEL_"))
25
- continue;
26
- const aliasRaw = key.slice("PLURNK_MODEL_".length);
27
- if (aliasRaw.length === 0)
28
- continue;
29
- const slash = value.indexOf("/");
30
- if (slash <= 0)
31
- continue;
32
- out.push({
33
- alias: aliasRaw.toLowerCase(),
34
- provider: value.slice(0, slash),
35
- model: value.slice(slash + 1),
36
- });
37
- }
38
- return out;
39
- };
40
- export const resolveActiveAlias = (env = process.env) => {
41
- const selected = env.PLURNK_MODEL;
42
- if (selected === undefined || selected.length === 0)
43
- return null;
44
- const aliases = parseAliasesFromEnv(env);
45
- return aliases.find((a) => a.alias === selected.toLowerCase()) ?? null;
46
- };
47
- export const instantiateProvider = async (alias, env = process.env) => {
48
- const packageName = `@plurnk/plurnk-providers-${alias.provider}`;
49
- let mod;
50
- try {
51
- mod = await import(__rewriteRelativeImportExtension(packageName));
52
- }
53
- catch (cause) {
54
- throw new Error(`provider package ${packageName} not installed (alias '${alias.alias}' requires it): ` +
55
- (cause instanceof Error ? cause.message : String(cause)));
56
- }
57
- const factory = mod.default;
58
- if (typeof factory?.fromEnv !== "function") {
59
- throw new Error(`${packageName}: default export must have a static \`fromEnv(env, model)\` factory ` +
60
- `(plurnk-providers#1)`);
61
- }
62
- return await factory.fromEnv(env, alias.model);
63
- };
64
- // Convenience: resolve + instantiate in one call. Returns null when no
65
- // PLURNK_MODEL is set (caller decides what 'no provider' means).
66
- export const loadActiveProvider = async (env = process.env) => {
67
- const alias = resolveActiveAlias(env);
68
- if (alias === null)
69
- return null;
70
- return instantiateProvider(alias, env);
71
- };
72
- //# sourceMappingURL=ProviderRegistry.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ProviderRegistry.js","sourceRoot":"","sources":["../../src/core/ProviderRegistry.ts"],"names":[],"mappings":"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"}