@musnows/scriverse 0.6.0 → 0.6.2

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 (44) hide show
  1. package/README.en.md +3 -2
  2. package/README.md +3 -2
  3. package/dist/ai-tool-results.js +177 -0
  4. package/dist/ai-tool-results.js.map +1 -0
  5. package/dist/ai.js +516 -138
  6. package/dist/ai.js.map +1 -1
  7. package/dist/app.js +186 -55
  8. package/dist/app.js.map +1 -1
  9. package/dist/attachment-storage.js +9 -1
  10. package/dist/attachment-storage.js.map +1 -1
  11. package/dist/cli-contract.js +9 -5
  12. package/dist/cli-contract.js.map +1 -1
  13. package/dist/cli-core.js +14 -2
  14. package/dist/cli-core.js.map +1 -1
  15. package/dist/collaboration-presence.js +1 -0
  16. package/dist/collaboration-presence.js.map +1 -1
  17. package/dist/credential-vault.js +7 -5
  18. package/dist/credential-vault.js.map +1 -1
  19. package/dist/database.js +121 -2
  20. package/dist/database.js.map +1 -1
  21. package/dist/domain.js +9 -0
  22. package/dist/domain.js.map +1 -1
  23. package/dist/public/ai-context-meter.js +7 -0
  24. package/dist/public/app.js +556 -223
  25. package/dist/public/entity-version.js +2 -2
  26. package/dist/public/index.html +19 -11
  27. package/dist/public/markdown.js +1 -2
  28. package/dist/public/model-config.d.ts +3 -0
  29. package/dist/public/model-config.js +14 -0
  30. package/dist/public/page-route.js +1 -0
  31. package/dist/public/styles.css +40 -20
  32. package/dist/public/work-permissions.d.ts +1 -1
  33. package/dist/public/work-permissions.js +1 -1
  34. package/dist/security.js +45 -10
  35. package/dist/security.js.map +1 -1
  36. package/dist/server-runtime.js +56 -1
  37. package/dist/server-runtime.js.map +1 -1
  38. package/dist/store.js +236 -25
  39. package/dist/store.js.map +1 -1
  40. package/dist/user-auth.js +19 -71
  41. package/dist/user-auth.js.map +1 -1
  42. package/dist/version.js +1 -1
  43. package/dist/work-permissions.js +1 -1
  44. package/package.json +1 -1
package/README.en.md CHANGED
@@ -105,12 +105,13 @@ Run `scriverse --help` for all local server, default server, authentication, wor
105
105
  | `HOST` | `127.0.0.1` | Listen address; use `0.0.0.0` for a server deployment |
106
106
  | `DATA_DIR` | `<project>/.data` | Default data directory |
107
107
  | `DATABASE_PATH` | `<DATA_DIR>/novel.db` | SQLite database path |
108
- | `AI_NOVEL_MASTER_KEY` | Generated and stored at `<DATA_DIR>/master.key` | Master key used to encrypt AI provider credentials |
108
+ | `AI_NOVEL_MASTER_KEY` | Generated and stored at `<DATA_DIR>/master.key` | Master key used to encrypt AI provider credentials; at least 32 characters when configured manually |
109
109
  | `APP_AUTH_USERNAME` | Empty | Optional deployment gateway username; the in-app user system is always enabled |
110
110
  | `APP_AUTH_PASSWORD` | Empty | Optional deployment gateway password, at least 12 characters; must be transported over HTTPS |
111
111
  | `APP_TRUST_PROXY` | `false` | Set to the trusted proxy hop count (usually `1`) or `true` behind a trusted reverse proxy |
112
112
  | `APP_ALLOW_PRIVATE_AI_ENDPOINTS` | `true` in development, `false` in production | Allow AI providers on loopback/private networks; link-local and cloud metadata addresses are always blocked |
113
113
  | `APP_ALLOW_REGISTRATION` | `false` | Registration is enabled only when explicitly set to `true`; unset and all other values stay closed, including first-admin setup |
114
+ | `APP_SETUP_TOKEN` | Empty | Required when registration is enabled and must contain at least 32 characters; only the first administrator must enter it |
114
115
 
115
116
  Custom configuration example:
116
117
 
@@ -128,7 +129,7 @@ APP_AUTH_PASSWORD='replace-with-a-long-random-password' \
128
129
  npm start
129
130
  ```
130
131
 
131
- Production deployments must use HTTPS at a trusted reverse proxy. For first-time setup, set `APP_ALLOW_REGISTRATION=true`; the first registered user becomes the system administrator. Afterwards, remove the variable or set it to `false` and restart the service. Explicitly enable it again only when more users need to register. Optional HTTP Basic Auth is only an additional deployment gateway, and its credentials are merely Base64 encoded. `/api/health` remains public for health checks, while business APIs require an in-app login.
132
+ Production deployments must use HTTPS at a trusted reverse proxy. For first-time setup, set `APP_ALLOW_REGISTRATION=true` and configure `APP_SETUP_TOKEN` with at least 32 random characters. The first registered user must enter that token and becomes the system administrator. Afterwards, remove both variables or disable registration and restart the service. Later ordinary registrations do not require the setup token. Optional HTTP Basic Auth is only an additional deployment gateway, and its credentials are merely Base64 encoded. `/api/health` remains public for health checks, while business APIs require an in-app login.
132
133
 
133
134
  ## AI Provider Setup
134
135
 
package/README.md CHANGED
@@ -111,12 +111,13 @@ CLI 会按服务器保存登录凭据。所有连接服务的数据命令都可
111
111
  | `HOST` | `127.0.0.1` | 监听地址;服务器部署时可设为 `0.0.0.0` |
112
112
  | `DATA_DIR` | `<项目目录>/.data` | 默认数据目录 |
113
113
  | `DATABASE_PATH` | `<DATA_DIR>/novel.db` | SQLite 数据库路径 |
114
- | `AI_NOVEL_MASTER_KEY` | 自动生成并保存在 `<DATA_DIR>/master.key` | 加密 AI 供应商密钥的主密钥 |
114
+ | `AI_NOVEL_MASTER_KEY` | 自动生成并保存在 `<DATA_DIR>/master.key` | 加密 AI 供应商密钥的主密钥;手动配置时至少 32 个字符 |
115
115
  | `APP_AUTH_USERNAME` | 空 | 可选的部署网关账号;应用内用户系统始终启用 |
116
116
  | `APP_AUTH_PASSWORD` | 空 | 可选的部署网关密码,至少 12 个字符;必须通过 HTTPS 传输 |
117
117
  | `APP_TRUST_PROXY` | `false` | 位于可信反向代理后时设为代理跳数(通常为 `1`)或 `true` |
118
118
  | `APP_ALLOW_PRIVATE_AI_ENDPOINTS` | 开发环境 `true`,生产环境 `false` | 是否允许 AI 供应商连接本机或内网地址;链路本地与云元数据地址始终禁止 |
119
119
  | `APP_ALLOW_REGISTRATION` | `false` | 仅明确设为 `true` 时开放注册;未设置或其他值均关闭,首次初始化创建管理员也必须显式开启 |
120
+ | `APP_SETUP_TOKEN` | 空 | 开放注册时必填且至少 32 个字符;仅首位管理员注册需要在页面输入 |
120
121
 
121
122
  自定义示例:
122
123
 
@@ -134,7 +135,7 @@ APP_AUTH_PASSWORD='请替换为足够长的随机密码' \
134
135
  npm start
135
136
  ```
136
137
 
137
- 生产环境必须在可信反向代理后启用 HTTPS。首次初始化时,将 `APP_ALLOW_REGISTRATION` 设为 `true`,创建的第一个用户会自动成为系统管理员;完成后应删除该环境变量或设为 `false` 并重启服务。后续如需添加用户,再临时显式开启注册。可选的 HTTP Basic Auth 仅作为额外部署网关,其凭据只是 Base64 编码,未使用 HTTPS 时不能防止链路窃听。`/api/health` 保持免认证以供探活,业务 API 需要应用内登录。
138
+ 生产环境必须在可信反向代理后启用 HTTPS。首次初始化时,将 `APP_ALLOW_REGISTRATION` 设为 `true`,并为 `APP_SETUP_TOKEN` 配置至少 32 个字符的随机值;创建的第一个用户会自动成为系统管理员,且必须在页面输入该令牌。完成后应删除这两个环境变量或关闭注册并重启服务。后续添加普通用户只需临时开放注册,不再要求初始化令牌。可选的 HTTP Basic Auth 仅作为额外部署网关,其凭据只是 Base64 编码,未使用 HTTPS 时不能防止链路窃听。`/api/health` 保持免认证以供探活,业务 API 需要应用内登录。
138
139
 
139
140
  ## AI 供应商配置
140
141
 
@@ -0,0 +1,177 @@
1
+ export const AGENT_TOOL_RESULT_MAX_CHARS = 10_000;
2
+ const TOOL_RESULT_RECORD_MAX_CHARS = 6_000;
3
+ const TOOL_RESULT_IDENTITY_FIELDS = new Set([
4
+ "id",
5
+ "chapterId",
6
+ "sectionId",
7
+ "characterId",
8
+ "characterName",
9
+ "draftType",
10
+ "draftTypeLabel",
11
+ "name",
12
+ "title",
13
+ "type",
14
+ "sourceType",
15
+ "versionNo"
16
+ ]);
17
+ export function serializedToolResultChars(value) {
18
+ return JSON.stringify(value).length;
19
+ }
20
+ function largestStringChunk(value, offset, maximumChars) {
21
+ let low = 1;
22
+ let high = value.length - offset;
23
+ let accepted = "";
24
+ while (low <= high) {
25
+ const middle = Math.floor((low + high) / 2);
26
+ const candidate = value.slice(offset, offset + middle);
27
+ if (serializedToolResultChars(candidate) <= maximumChars) {
28
+ accepted = candidate;
29
+ low = middle + 1;
30
+ }
31
+ else {
32
+ high = middle - 1;
33
+ }
34
+ }
35
+ const end = offset + accepted.length;
36
+ const lastCodeUnit = accepted.charCodeAt(accepted.length - 1);
37
+ const nextCodeUnit = value.charCodeAt(end);
38
+ if (lastCodeUnit >= 0xD800 && lastCodeUnit <= 0xDBFF && nextCodeUnit >= 0xDC00 && nextCodeUnit <= 0xDFFF) {
39
+ return accepted.slice(0, -1);
40
+ }
41
+ return accepted;
42
+ }
43
+ function structuralValueFragments(value, maximumChars, path) {
44
+ if (serializedToolResultChars(value) <= maximumChars)
45
+ return [{ value, path }];
46
+ if (typeof value === "string") {
47
+ const fragments = [];
48
+ let offset = 0;
49
+ while (offset < value.length) {
50
+ const chunk = largestStringChunk(value, offset, maximumChars);
51
+ if (!chunk)
52
+ throw new Error("Tool result string cannot fit within the structural page budget.");
53
+ const nextOffset = offset + chunk.length;
54
+ fragments.push({ value: chunk, path: `${path}[${offset}:${nextOffset}]` });
55
+ offset = nextOffset;
56
+ }
57
+ return fragments;
58
+ }
59
+ if (Array.isArray(value)) {
60
+ const fragments = [];
61
+ let current = [];
62
+ let currentStart = 0;
63
+ const flush = (end) => {
64
+ if (current.length === 0)
65
+ return;
66
+ fragments.push({ value: current, path: `${path}[${currentStart}:${end}]` });
67
+ current = [];
68
+ };
69
+ for (let index = 0; index < value.length; index += 1) {
70
+ const item = value[index];
71
+ const candidate = [...current, item];
72
+ if (serializedToolResultChars(candidate) <= maximumChars) {
73
+ if (current.length === 0)
74
+ currentStart = index;
75
+ current = candidate;
76
+ continue;
77
+ }
78
+ flush(index);
79
+ if (serializedToolResultChars([item]) <= maximumChars) {
80
+ currentStart = index;
81
+ current = [item];
82
+ continue;
83
+ }
84
+ const nested = structuralValueFragments(item, Math.max(64, maximumChars - 2), `${path}[${index}]`);
85
+ for (const fragment of nested)
86
+ fragments.push({ value: [fragment.value], path: fragment.path });
87
+ }
88
+ flush(value.length);
89
+ return fragments;
90
+ }
91
+ if (value && typeof value === "object") {
92
+ const fragments = [];
93
+ let current = {};
94
+ const flush = () => {
95
+ if (Object.keys(current).length === 0)
96
+ return;
97
+ fragments.push({ value: current, path });
98
+ current = {};
99
+ };
100
+ for (const [key, item] of Object.entries(value)) {
101
+ const candidate = { ...current, [key]: item };
102
+ if (serializedToolResultChars(candidate) <= maximumChars) {
103
+ current = candidate;
104
+ continue;
105
+ }
106
+ flush();
107
+ if (serializedToolResultChars({ [key]: item }) <= maximumChars) {
108
+ current = { [key]: item };
109
+ continue;
110
+ }
111
+ const keyOverhead = serializedToolResultChars({ [key]: null }) - serializedToolResultChars(null);
112
+ const nested = structuralValueFragments(item, Math.max(64, maximumChars - keyOverhead), path ? `${path}.${key}` : key);
113
+ for (const fragment of nested)
114
+ fragments.push({ value: { [key]: fragment.value }, path: fragment.path });
115
+ }
116
+ flush();
117
+ return fragments;
118
+ }
119
+ return [{ value: null, path }];
120
+ }
121
+ export function structuralToolResultRecords(records, maximumChars = TOOL_RESULT_RECORD_MAX_CHARS) {
122
+ return records.flatMap((record) => {
123
+ if (serializedToolResultChars(record) <= maximumChars)
124
+ return [record];
125
+ const identity = Object.fromEntries(Object.entries(record).filter(([key]) => TOOL_RESULT_IDENTITY_FIELDS.has(key)));
126
+ const payload = Object.fromEntries(Object.entries(record).filter(([key]) => !TOOL_RESULT_IDENTITY_FIELDS.has(key)));
127
+ const identityChars = serializedToolResultChars(identity);
128
+ const payloadBudget = Math.max(64, maximumChars - identityChars - 320);
129
+ const fragments = structuralValueFragments(payload, payloadBudget, "");
130
+ return fragments.map((fragment, index) => {
131
+ const partial = fragment.value && typeof fragment.value === "object" && !Array.isArray(fragment.value)
132
+ ? fragment.value
133
+ : { value: fragment.value };
134
+ const result = {
135
+ ...identity,
136
+ ...partial,
137
+ _fragment: {
138
+ index,
139
+ total: fragments.length,
140
+ path: fragment.path || null
141
+ }
142
+ };
143
+ if (serializedToolResultChars(result) > maximumChars) {
144
+ throw new Error("Tool result record cannot fit within the structural page budget.");
145
+ }
146
+ return result;
147
+ });
148
+ });
149
+ }
150
+ export function paginateToolResultRecords(records, cursor, buildResult, maximumChars = AGENT_TOOL_RESULT_MAX_CHARS) {
151
+ const safeCursor = Math.min(Math.max(0, Math.trunc(cursor)), records.length);
152
+ const page = [];
153
+ let nextIndex = safeCursor;
154
+ while (nextIndex < records.length) {
155
+ const candidatePage = [...page, records[nextIndex]];
156
+ const candidateNextCursor = nextIndex + 1 < records.length ? nextIndex + 1 : null;
157
+ const candidate = buildResult(candidatePage, {
158
+ cursor: safeCursor,
159
+ nextCursor: candidateNextCursor,
160
+ maxChars: maximumChars
161
+ });
162
+ if (serializedToolResultChars(candidate) > maximumChars)
163
+ break;
164
+ page.push(records[nextIndex]);
165
+ nextIndex += 1;
166
+ }
167
+ const nextCursor = nextIndex < records.length ? nextIndex : null;
168
+ const result = buildResult(page, { cursor: safeCursor, nextCursor, maxChars: maximumChars });
169
+ if (serializedToolResultChars(result) > maximumChars) {
170
+ throw new Error("Tool result metadata exceeds the configured result budget.");
171
+ }
172
+ if (page.length === 0 && safeCursor < records.length) {
173
+ throw new Error("Tool result item exceeds the configured result budget.");
174
+ }
175
+ return result;
176
+ }
177
+ //# sourceMappingURL=ai-tool-results.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-tool-results.js","sourceRoot":"","sources":["../src/ai-tool-results.ts"],"names":[],"mappings":"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"}