@seele00/seele 0.1.63 → 0.1.64

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/README.md +5 -3
  2. package/bin/seele-codex +1 -1
  3. package/libexec/seele-server +0 -0
  4. package/libexec/seele-worker +0 -0
  5. package/package.json +1 -4
  6. package/scripts/deploy/bootstrap.sh +14 -3
  7. package/scripts/deploy/start.sh +14 -9
  8. package/web/dist/assets/{abnfDiagram-VRR7QNED-DXJQwnn-.js → abnfDiagram-VRR7QNED-BB7DT0BN.js} +1 -1
  9. package/web/dist/assets/{arc-D_47-IET.js → arc-BlEU_mit.js} +1 -1
  10. package/web/dist/assets/{architectureDiagram-ZJ3FMSHR-CKUldIzR.js → architectureDiagram-ZJ3FMSHR-Dy9cu2Mg.js} +1 -1
  11. package/web/dist/assets/{blockDiagram-677ZJIJ3-BD4Ym8Xi.js → blockDiagram-677ZJIJ3-DP4jMSfo.js} +1 -1
  12. package/web/dist/assets/{c4Diagram-LMCZKHZV-Cn268vLB.js → c4Diagram-LMCZKHZV-BtqFzX1w.js} +1 -1
  13. package/web/dist/assets/channel-mhSuRKJT.js +1 -0
  14. package/web/dist/assets/{chunk-2Q5K7J3B-D00lQ7mJ.js → chunk-2Q5K7J3B-BK9F5a0L.js} +1 -1
  15. package/web/dist/assets/{chunk-32BRIVSS-z7gv8Mry.js → chunk-32BRIVSS-nuQI6gtU.js} +1 -1
  16. package/web/dist/assets/{chunk-5VM5RSS4-BZJeO_rz.js → chunk-5VM5RSS4-D4IT05bt.js} +1 -1
  17. package/web/dist/assets/{chunk-EX3LRPZG-DoIg9UGx.js → chunk-EX3LRPZG-CrOtgxcr.js} +1 -1
  18. package/web/dist/assets/{chunk-JWPE2WC7-C1LcQus2.js → chunk-JWPE2WC7-Dn9JHm4W.js} +1 -1
  19. package/web/dist/assets/{chunk-MOJQB5TN--JPbFu4n.js → chunk-MOJQB5TN-VtD0_fGF.js} +1 -1
  20. package/web/dist/assets/{chunk-RYQCIY6F-BVv30W60.js → chunk-RYQCIY6F-TqRYsCot.js} +1 -1
  21. package/web/dist/assets/{chunk-V7JOEXUC-DYoSFgRT.js → chunk-V7JOEXUC-U9b5a7vL.js} +1 -1
  22. package/web/dist/assets/{chunk-VR4S4FIN-C8BRkTOa.js → chunk-VR4S4FIN-B3qLfeNJ.js} +1 -1
  23. package/web/dist/assets/{chunk-XXDRQBXY-CDfofIob.js → chunk-XXDRQBXY-DazVAZe-.js} +1 -1
  24. package/web/dist/assets/classDiagram-OUVF2IWQ-DYQSxD4g.js +1 -0
  25. package/web/dist/assets/classDiagram-v2-EOCWNBFH-DYQSxD4g.js +1 -0
  26. package/web/dist/assets/{core-C10OFTno.js → core-2RdBW0rZ.js} +1 -1
  27. package/web/dist/assets/{cose-bilkent-JH36ORCC-g9E8J4Fz.js → cose-bilkent-JH36ORCC-vvKttQXU.js} +1 -1
  28. package/web/dist/assets/{cynefin-VYW2F7L2-Dc689veM.js → cynefin-VYW2F7L2-BKMZmA-n.js} +1 -1
  29. package/web/dist/assets/{cynefinDiagram-TSTJHNR4-BAAq_jvr.js → cynefinDiagram-TSTJHNR4-ckdzxzlr.js} +1 -1
  30. package/web/dist/assets/{dagre-VKFMJZFB-CPtiniZQ.js → dagre-VKFMJZFB-CZw8DTb1.js} +1 -1
  31. package/web/dist/assets/{diagram-FQU43EPY-CvbIL3lu.js → diagram-FQU43EPY-C06X0Kru.js} +1 -1
  32. package/web/dist/assets/{diagram-G47NLZAW-u5m78Utg.js → diagram-G47NLZAW-HX9CdauD.js} +1 -1
  33. package/web/dist/assets/{diagram-NH7WQ7WH-4f-Ipubv.js → diagram-NH7WQ7WH-Dlo1tIod.js} +1 -1
  34. package/web/dist/assets/{diagram-OA4YK3LP-SUl1EQ56.js → diagram-OA4YK3LP-C9GXFhgw.js} +1 -1
  35. package/web/dist/assets/{diagram-WEI45ONY-C_Upd46l.js → diagram-WEI45ONY-Ch1Xx234.js} +1 -1
  36. package/web/dist/assets/{ebnfDiagram-CCIWWBDH-CHp2D7Q9.js → ebnfDiagram-CCIWWBDH-Q0_rEUgk.js} +1 -1
  37. package/web/dist/assets/{erDiagram-Q63AITRT-DQliHxOw.js → erDiagram-Q63AITRT-BsDRdpx6.js} +1 -1
  38. package/web/dist/assets/{flowDiagram-23GEKE2U-BcOYSJFM.js → flowDiagram-23GEKE2U-DDFuMRJN.js} +1 -1
  39. package/web/dist/assets/{ganttDiagram-NO4QXBWP-CDLHtJq0.js → ganttDiagram-NO4QXBWP-Cjpm08-d.js} +1 -1
  40. package/web/dist/assets/{gitGraphDiagram-IHSO6WYX-2j8C3mlk.js → gitGraphDiagram-IHSO6WYX-CnIosh2K.js} +1 -1
  41. package/web/dist/assets/index-eN6ddNRA.js +111 -0
  42. package/web/dist/assets/{infoDiagram-FWYZ7A6U-ClxdyQnM.js → infoDiagram-FWYZ7A6U-CH163HyC.js} +1 -1
  43. package/web/dist/assets/{ishikawaDiagram-FXEZZL3T-Bc2nIRgb.js → ishikawaDiagram-FXEZZL3T-DkT-3n3D.js} +1 -1
  44. package/web/dist/assets/{journeyDiagram-5HDEW3XC-R-vJ00LW.js → journeyDiagram-5HDEW3XC-34TnH3wG.js} +1 -1
  45. package/web/dist/assets/{kanban-definition-HUTT4EX6-CR0s_Mo8.js → kanban-definition-HUTT4EX6-CJbOm0lN.js} +1 -1
  46. package/web/dist/assets/{linear-BQgrawZS.js → linear-CTKXTLwe.js} +1 -1
  47. package/web/dist/assets/{mermaid.core-faLMbjSU.js → mermaid.core-CAVP16_-.js} +4 -4
  48. package/web/dist/assets/{mindmap-definition-LN4V7U3C-BZULnQui.js → mindmap-definition-LN4V7U3C-rlppHZj_.js} +1 -1
  49. package/web/dist/assets/{pegDiagram-2B236MQR-DUm1p_1o.js → pegDiagram-2B236MQR-MbcWBNJi.js} +1 -1
  50. package/web/dist/assets/{pieDiagram-ENE6RG2P-r3LCASRK.js → pieDiagram-ENE6RG2P-DKU7a4tv.js} +1 -1
  51. package/web/dist/assets/{quadrantDiagram-ABIIQ3AL-CGaCp0Px.js → quadrantDiagram-ABIIQ3AL-DpDsJVLi.js} +1 -1
  52. package/web/dist/assets/{railroadDiagram-RFXS5EU6-DmEKGO1A.js → railroadDiagram-RFXS5EU6-DrPM3aKC.js} +1 -1
  53. package/web/dist/assets/{requirementDiagram-TGXJPOKE-Byc4ivmp.js → requirementDiagram-TGXJPOKE-ZzS_iVag.js} +1 -1
  54. package/web/dist/assets/{sankeyDiagram-HTMAVEWB-BtJiL4zX.js → sankeyDiagram-HTMAVEWB-DrRrN0Lc.js} +1 -1
  55. package/web/dist/assets/{sequenceDiagram-DBY2YBRQ-Bg3vdDGW.js → sequenceDiagram-DBY2YBRQ-CP8GBGZM.js} +1 -1
  56. package/web/dist/assets/{sizeCapture-X5ZJPWSS-CCRwjaWU.js → sizeCapture-X5ZJPWSS-BYVg_dQd.js} +1 -1
  57. package/web/dist/assets/{stateDiagram-2N3HPSRC-CQU-udox.js → stateDiagram-2N3HPSRC-CsJ3M80-.js} +1 -1
  58. package/web/dist/assets/stateDiagram-v2-6OUMAXLB-CaFOY1Xb.js +1 -0
  59. package/web/dist/assets/{swimlanes-5IMT3BWC-r3tJnQLJ.js → swimlanes-5IMT3BWC-XgRKQ20Q.js} +2 -2
  60. package/web/dist/assets/swimlanesDiagram-G3AALYLV-DaKP_iDy.js +8 -0
  61. package/web/dist/assets/{timeline-definition-FHXFAJF6-DryYrdts.js → timeline-definition-FHXFAJF6-CU_Cq10d.js} +1 -1
  62. package/web/dist/assets/{vennDiagram-L72KCM5P-ZLPc0qvQ.js → vennDiagram-L72KCM5P-CLSDbg6o.js} +1 -1
  63. package/web/dist/assets/{wardleyDiagram-EHGQE667-RmgA6vQ9.js → wardleyDiagram-EHGQE667-DnAOuvzv.js} +1 -1
  64. package/web/dist/assets/{xychartDiagram-FW5EYKEG-BGIzispI.js → xychartDiagram-FW5EYKEG-CyC6V11l.js} +1 -1
  65. package/web/dist/index.html +1 -1
  66. package/codex/dist/app-server.js +0 -63
  67. package/codex/dist/errors.js +0 -16
  68. package/codex/dist/index.js +0 -4
  69. package/codex/dist/rpc-client.js +0 -96
  70. package/codex/dist/transports/stdio.js +0 -81
  71. package/codex/dist/types.js +0 -1
  72. package/codex/package.json +0 -12
  73. package/scripts/deploy/npm/postinstall.mjs +0 -10
  74. package/server/dist/auth/session.js +0 -71
  75. package/server/dist/auth/users.js +0 -276
  76. package/server/dist/codex-runtime/run-streamed-turn.js +0 -587
  77. package/server/dist/config/config.js +0 -71
  78. package/server/dist/contracts/artifact-rendering.js +0 -14
  79. package/server/dist/contracts/global-environment.js +0 -23
  80. package/server/dist/contracts/index.js +0 -114
  81. package/server/dist/contracts/managed-assets.js +0 -13
  82. package/server/dist/contracts/response-style.js +0 -23
  83. package/server/dist/contracts/task-clarification.js +0 -13
  84. package/server/dist/contracts/types.js +0 -1
  85. package/server/dist/contracts/wakeup.js +0 -13
  86. package/server/dist/contracts/workspace-boundary.js +0 -20
  87. package/server/dist/contracts/workspace-knowledge.js +0 -48
  88. package/server/dist/contracts/workspace-memory.js +0 -32
  89. package/server/dist/contracts/workspace-responsibility.js +0 -23
  90. package/server/dist/contracts/workspace-transcript.js +0 -26
  91. package/server/dist/conversations/knowledge.js +0 -380
  92. package/server/dist/conversations/store.js +0 -2466
  93. package/server/dist/doctor.js +0 -105
  94. package/server/dist/realtime/sse.js +0 -12
  95. package/server/dist/runtime-worker/client.js +0 -405
  96. package/server/dist/runtime-worker/process.js +0 -216
  97. package/server/dist/runtime-worker/protocol.js +0 -1
  98. package/server/dist/server.js +0 -4605
  99. package/server/dist/storage/sqlite.js +0 -39
  100. package/web/dist/assets/channel-Uz6zF6Xw.js +0 -1
  101. package/web/dist/assets/classDiagram-OUVF2IWQ-D6mpE1t2.js +0 -1
  102. package/web/dist/assets/classDiagram-v2-EOCWNBFH-D6mpE1t2.js +0 -1
  103. package/web/dist/assets/index-BqSosI7W.js +0 -111
  104. package/web/dist/assets/stateDiagram-v2-6OUMAXLB-YNSWW4ip.js +0 -1
  105. package/web/dist/assets/swimlanesDiagram-G3AALYLV-BGZAc11_.js +0 -8
@@ -1,380 +0,0 @@
1
- import { existsSync, readdirSync, readFileSync, } from "node:fs";
2
- import path from "node:path";
3
- import { randomInt } from "node:crypto";
4
- import { getConversationWorkspaceDatabase, } from "./store.js";
5
- import { runInTransaction } from "../storage/sqlite.js";
6
- const KNOWLEDGE_ROOT = ".seele/knowledge";
7
- const KNOWLEDGE_URI_ROOT = "seele://knowledge";
8
- export function listWorkspaceKnowledge(conversation) {
9
- migrateLegacyFileKnowledge(conversation);
10
- const rows = getConversationWorkspaceDatabase(conversation)
11
- .prepare("select data_json from workspace_knowledge order by updated_at desc")
12
- .all();
13
- return rows
14
- .map((row) => parseStoredKnowledgeItem(conversation, row.data_json))
15
- .filter((item) => item !== null)
16
- .sort((left, right) => {
17
- const attentionOrder = attentionRank(right.attention) - attentionRank(left.attention);
18
- if (attentionOrder !== 0) {
19
- return attentionOrder;
20
- }
21
- return right.updatedAt.localeCompare(left.updatedAt);
22
- });
23
- }
24
- export function createWorkspaceKnowledge(conversation, input) {
25
- const now = new Date().toISOString();
26
- const id = createKnowledgeId(conversation);
27
- const item = normalizeKnowledgeItem(conversation, {
28
- id,
29
- kind: parseKnowledgeKind(input.kind, "source"),
30
- name: parseText(input.name, "Untitled knowledge"),
31
- description: parseText(input.description),
32
- purpose: parseText(input.purpose),
33
- attention: parseKnowledgeAttention(input.attention, "tracked"),
34
- refreshPolicy: parseKnowledgeRefreshPolicy(input.refreshPolicy, "manual"),
35
- status: parseKnowledgeStatus(input.status, "draft"),
36
- sourceClues: parseSourceClues(input.sourceClues, now),
37
- fetch: {
38
- type: "script",
39
- scriptPath: relativeKnowledgePath(id, "fetch.sh"),
40
- requiredEnv: parseRequiredEnv(input.requiredEnv),
41
- verified: input.fetchVerified === true,
42
- lastRunAt: parseNullableText(input.lastRunAt),
43
- lastExitCode: typeof input.lastExitCode === "number"
44
- ? Math.trunc(input.lastExitCode)
45
- : null,
46
- lastContentHash: parseNullableText(input.lastContentHash),
47
- },
48
- rawPath: relativeKnowledgePath(id, "raw"),
49
- digestPath: relativeKnowledgePath(id, "digest.md"),
50
- skillPath: relativeKnowledgePath(id, "skill.md"),
51
- createdAt: now,
52
- updatedAt: now,
53
- });
54
- writeKnowledgeItem(conversation, item);
55
- return item;
56
- }
57
- export function updateWorkspaceKnowledge(conversation, id, input) {
58
- const existing = readKnowledgeItem(conversation, id);
59
- if (!existing) {
60
- return null;
61
- }
62
- const item = normalizeKnowledgeItem(conversation, {
63
- ...existing,
64
- kind: parseKnowledgeKind(input.kind, existing.kind),
65
- name: Object.prototype.hasOwnProperty.call(input, "name")
66
- ? parseText(input.name, existing.name)
67
- : existing.name,
68
- description: Object.prototype.hasOwnProperty.call(input, "description")
69
- ? parseText(input.description)
70
- : existing.description,
71
- purpose: Object.prototype.hasOwnProperty.call(input, "purpose")
72
- ? parseText(input.purpose)
73
- : existing.purpose,
74
- attention: parseKnowledgeAttention(input.attention, existing.attention),
75
- refreshPolicy: parseKnowledgeRefreshPolicy(input.refreshPolicy, existing.refreshPolicy),
76
- status: parseKnowledgeStatus(input.status, existing.status),
77
- sourceClues: Object.prototype.hasOwnProperty.call(input, "sourceClues")
78
- ? parseSourceClues(input.sourceClues, new Date().toISOString())
79
- : existing.sourceClues,
80
- fetch: {
81
- ...existing.fetch,
82
- requiredEnv: Object.prototype.hasOwnProperty.call(input, "requiredEnv")
83
- ? parseRequiredEnv(input.requiredEnv)
84
- : existing.fetch.requiredEnv,
85
- verified: Object.prototype.hasOwnProperty.call(input, "fetchVerified")
86
- ? input.fetchVerified === true
87
- : existing.fetch.verified,
88
- lastRunAt: Object.prototype.hasOwnProperty.call(input, "lastRunAt")
89
- ? parseNullableText(input.lastRunAt)
90
- : existing.fetch.lastRunAt,
91
- lastExitCode: Object.prototype.hasOwnProperty.call(input, "lastExitCode")
92
- ? typeof input.lastExitCode === "number"
93
- ? Math.trunc(input.lastExitCode)
94
- : null
95
- : existing.fetch.lastExitCode,
96
- lastContentHash: Object.prototype.hasOwnProperty.call(input, "lastContentHash")
97
- ? parseNullableText(input.lastContentHash)
98
- : existing.fetch.lastContentHash,
99
- },
100
- updatedAt: new Date().toISOString(),
101
- });
102
- writeKnowledgeItem(conversation, item);
103
- return item;
104
- }
105
- export function deleteWorkspaceKnowledge(conversation, id) {
106
- migrateLegacyFileKnowledge(conversation);
107
- const result = getConversationWorkspaceDatabase(conversation)
108
- .prepare("delete from workspace_knowledge where id = ?")
109
- .run(sanitizeKnowledgeId(id));
110
- return result.changes > 0;
111
- }
112
- export function summarizeWorkspaceKnowledge(conversation) {
113
- return listWorkspaceKnowledge(conversation).map((item) => ({
114
- id: item.id,
115
- kind: item.kind,
116
- name: item.name,
117
- purpose: item.purpose || item.description,
118
- status: item.status,
119
- attention: item.attention,
120
- refreshPolicy: item.refreshPolicy,
121
- rawPath: item.rawPath,
122
- digestPath: item.digestPath,
123
- skillPath: item.skillPath,
124
- fetchScriptPath: item.fetch.scriptPath,
125
- requiredEnv: item.fetch.requiredEnv,
126
- }));
127
- }
128
- function readKnowledgeItem(conversation, id) {
129
- const safeId = sanitizeKnowledgeId(id);
130
- if (!safeId) {
131
- return null;
132
- }
133
- migrateLegacyFileKnowledge(conversation);
134
- const row = getConversationWorkspaceDatabase(conversation)
135
- .prepare("select data_json from workspace_knowledge where id = ?")
136
- .get(safeId);
137
- return row?.data_json
138
- ? parseStoredKnowledgeItem(conversation, row.data_json)
139
- : null;
140
- }
141
- function writeKnowledgeItem(conversation, item) {
142
- getConversationWorkspaceDatabase(conversation)
143
- .prepare(`
144
- insert into workspace_knowledge (id, data_json, created_at, updated_at)
145
- values (@id, @dataJson, @createdAt, @updatedAt)
146
- on conflict(id) do update set
147
- data_json = excluded.data_json,
148
- updated_at = excluded.updated_at
149
- `)
150
- .run({
151
- id: item.id,
152
- dataJson: JSON.stringify(item),
153
- createdAt: item.createdAt,
154
- updatedAt: item.updatedAt,
155
- });
156
- }
157
- function parseStoredKnowledgeItem(conversation, dataJson) {
158
- try {
159
- const value = JSON.parse(dataJson);
160
- return normalizeKnowledgeItem(conversation, value);
161
- }
162
- catch {
163
- return null;
164
- }
165
- }
166
- function migrateLegacyFileKnowledge(conversation) {
167
- const db = getConversationWorkspaceDatabase(conversation);
168
- const existing = db
169
- .prepare("select count(*) as count from workspace_knowledge")
170
- .get();
171
- if (existing.count > 0) {
172
- return;
173
- }
174
- const root = workspaceKnowledgeRoot(conversation);
175
- if (!existsSync(root)) {
176
- return;
177
- }
178
- const legacyItems = readdirSync(root, { withFileTypes: true })
179
- .filter((entry) => entry.isDirectory())
180
- .map((entry) => readLegacyKnowledgeItem(conversation, entry.name))
181
- .filter((item) => item !== null);
182
- const insert = db.prepare(`
183
- insert or ignore into workspace_knowledge (id, data_json, created_at, updated_at)
184
- values (@id, @dataJson, @createdAt, @updatedAt)
185
- `);
186
- runInTransaction(db, () => {
187
- for (const item of legacyItems) {
188
- insert.run({
189
- id: item.id,
190
- dataJson: JSON.stringify(item),
191
- createdAt: item.createdAt,
192
- updatedAt: item.updatedAt,
193
- });
194
- }
195
- });
196
- }
197
- function readLegacyKnowledgeItem(conversation, id) {
198
- const safeId = sanitizeKnowledgeId(id);
199
- if (!safeId) {
200
- return null;
201
- }
202
- const itemPath = path.join(workspaceKnowledgeItemRoot(conversation, safeId), "item.json");
203
- if (!existsSync(itemPath)) {
204
- return null;
205
- }
206
- try {
207
- const value = JSON.parse(readFileSync(itemPath, "utf8"));
208
- return normalizeKnowledgeItem(conversation, value);
209
- }
210
- catch {
211
- return null;
212
- }
213
- }
214
- function normalizeKnowledgeItem(conversation, item) {
215
- const now = new Date().toISOString();
216
- const id = sanitizeKnowledgeId(item.id) || createKnowledgeId(conversation);
217
- const createdAt = parseNullableText(item.createdAt) ?? now;
218
- return {
219
- id,
220
- kind: parseKnowledgeKind(item.kind, "source"),
221
- name: parseText(item.name, "Untitled knowledge"),
222
- description: parseText(item.description),
223
- purpose: parseText(item.purpose),
224
- attention: parseKnowledgeAttention(item.attention, "tracked"),
225
- refreshPolicy: parseKnowledgeRefreshPolicy(item.refreshPolicy, "manual"),
226
- status: parseKnowledgeStatus(item.status, "draft"),
227
- sourceClues: parseSourceClues(item.sourceClues, createdAt),
228
- fetch: {
229
- type: "script",
230
- scriptPath: parseRelativeKnowledgePath(item.fetch?.scriptPath, id) ??
231
- relativeKnowledgePath(id, "fetch.sh"),
232
- requiredEnv: parseRequiredEnv(item.fetch?.requiredEnv),
233
- verified: item.fetch?.verified === true,
234
- lastRunAt: parseNullableText(item.fetch?.lastRunAt),
235
- lastExitCode: typeof item.fetch?.lastExitCode === "number"
236
- ? Math.trunc(item.fetch.lastExitCode)
237
- : null,
238
- lastContentHash: parseNullableText(item.fetch?.lastContentHash),
239
- },
240
- rawPath: parseRelativeKnowledgePath(item.rawPath, id) ??
241
- relativeKnowledgePath(id, "raw"),
242
- digestPath: parseRelativeKnowledgePath(item.digestPath, id) ??
243
- relativeKnowledgePath(id, "digest.md"),
244
- skillPath: parseRelativeKnowledgePath(item.skillPath, id) ??
245
- relativeKnowledgePath(id, "skill.md"),
246
- createdAt,
247
- updatedAt: parseNullableText(item.updatedAt) ?? createdAt,
248
- };
249
- }
250
- function createKnowledgeId(conversation) {
251
- for (let index = 0; index < 50; index += 1) {
252
- const id = randomInt(36 ** 6).toString(36).padStart(6, "0");
253
- const row = getConversationWorkspaceDatabase(conversation)
254
- .prepare("select id from workspace_knowledge where id = ?")
255
- .get(id);
256
- if (!row) {
257
- return id;
258
- }
259
- }
260
- return randomInt(36 ** 8).toString(36).padStart(8, "0");
261
- }
262
- function workspaceKnowledgeRoot(conversation) {
263
- return path.join(conversation.workspacePath, KNOWLEDGE_ROOT);
264
- }
265
- function workspaceKnowledgeItemRoot(conversation, id) {
266
- return path.join(workspaceKnowledgeRoot(conversation), sanitizeKnowledgeId(id));
267
- }
268
- function relativeKnowledgePath(id, leaf) {
269
- return `${KNOWLEDGE_URI_ROOT}/${sanitizeKnowledgeId(id)}/${leaf}`;
270
- }
271
- function parseRelativeKnowledgePath(value, id) {
272
- const text = parseText(value);
273
- if (!text) {
274
- return null;
275
- }
276
- const normalized = text.replace(/\\/g, "/").replace(/^\/+/, "");
277
- if (normalized.startsWith(`${KNOWLEDGE_ROOT}/${sanitizeKnowledgeId(id)}/`)) {
278
- return normalized.replace(`${KNOWLEDGE_ROOT}/${sanitizeKnowledgeId(id)}`, `${KNOWLEDGE_URI_ROOT}/${sanitizeKnowledgeId(id)}`);
279
- }
280
- if (normalized.startsWith(`${KNOWLEDGE_URI_ROOT}/${sanitizeKnowledgeId(id)}/`)) {
281
- return normalized;
282
- }
283
- return null;
284
- }
285
- function sanitizeKnowledgeId(value) {
286
- return String(value ?? "")
287
- .trim()
288
- .toLowerCase()
289
- .replace(/[^a-z0-9_-]/g, "")
290
- .slice(0, 32);
291
- }
292
- function parseText(value, fallback = "") {
293
- return typeof value === "string" ? value.trim() : fallback;
294
- }
295
- function parseNullableText(value) {
296
- const text = parseText(value);
297
- return text ? text : null;
298
- }
299
- function parseKnowledgeKind(value, fallback) {
300
- return value === "source" || value === "skill" || value === "reference"
301
- ? value
302
- : fallback;
303
- }
304
- function parseKnowledgeAttention(value, fallback) {
305
- return value === "none" || value === "tracked" || value === "watch"
306
- ? value
307
- : fallback;
308
- }
309
- function parseKnowledgeRefreshPolicy(value, fallback) {
310
- return value === "manual" || value === "low-frequency-check"
311
- ? value
312
- : fallback;
313
- }
314
- function parseKnowledgeStatus(value, fallback) {
315
- return value === "draft" ||
316
- value === "needs_credentials" ||
317
- value === "invalid_credentials" ||
318
- value === "needs_fetch_method" ||
319
- value === "ready" ||
320
- value === "stale_signal"
321
- ? value
322
- : fallback;
323
- }
324
- function parseSourceClues(value, fallbackTime) {
325
- if (!Array.isArray(value)) {
326
- return [];
327
- }
328
- return value
329
- .map((item) => {
330
- if (!item || typeof item !== "object") {
331
- return null;
332
- }
333
- const record = item;
334
- const clueValue = parseText(record.value);
335
- if (!clueValue) {
336
- return null;
337
- }
338
- const providedBy = record.providedBy === "agent" || record.providedBy === "system"
339
- ? record.providedBy
340
- : "user";
341
- return {
342
- type: parseText(record.type, "text"),
343
- value: clueValue,
344
- providedBy,
345
- providedAt: parseNullableText(record.providedAt) ?? fallbackTime,
346
- };
347
- })
348
- .filter((item) => item !== null);
349
- }
350
- function parseRequiredEnv(value) {
351
- if (!Array.isArray(value)) {
352
- return [];
353
- }
354
- return value
355
- .map((item) => {
356
- if (!item || typeof item !== "object") {
357
- return null;
358
- }
359
- const record = item;
360
- const key = parseText(record.key).toUpperCase();
361
- if (!/^[A-Z_][A-Z0-9_]*$/.test(key)) {
362
- return null;
363
- }
364
- return {
365
- key,
366
- description: parseText(record.description),
367
- };
368
- })
369
- .filter((item) => item !== null)
370
- .sort((left, right) => left.key.localeCompare(right.key));
371
- }
372
- function attentionRank(value) {
373
- if (value === "watch") {
374
- return 2;
375
- }
376
- if (value === "tracked") {
377
- return 1;
378
- }
379
- return 0;
380
- }