fuli-context 0.5.0 → 0.7.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 (206) hide show
  1. package/README.en.md +2 -333
  2. package/README.md +370 -202
  3. package/README.zh-CN.md +448 -0
  4. package/compose.graphiti.yml +6 -6
  5. package/dist/web/assets/AboutPage-DXh7Fwxt.css +1 -0
  6. package/dist/web/assets/AboutPage-DfnZo7Lo.js +1 -0
  7. package/dist/web/assets/ConnectionsPage-BloaSKmt.js +1 -0
  8. package/dist/web/assets/ConnectionsPage-CBHAdZXT.css +1 -0
  9. package/dist/web/assets/KnowledgeInspector-Bjhdu2mf.css +1 -0
  10. package/dist/web/assets/KnowledgeInspector-QvNpv0_k.js +1 -0
  11. package/dist/web/assets/KnowledgeOrganizerPage-Cx1w1jb2.css +1 -0
  12. package/dist/web/assets/KnowledgeOrganizerPage-DKq1jVD5.js +1 -0
  13. package/dist/web/assets/KnowledgePage-BWL0jT01.js +1 -0
  14. package/dist/web/assets/KnowledgeWorkspace-Czq6aZ7b.js +4 -0
  15. package/dist/web/assets/OverviewPage-5sJoO1Gh.js +1 -0
  16. package/dist/web/assets/{PersonalProfilePage-S8ZcG2LU.css → PersonalProfilePage-CdmEzyvZ.css} +1 -1
  17. package/dist/web/assets/PersonalProfilePage-tVChM9ik.js +1 -0
  18. package/dist/web/assets/PersonalProjectsPage-BPFrup4V.js +1 -0
  19. package/dist/web/assets/PublicProjectsPage-BPJSeREN.js +1 -0
  20. package/dist/web/assets/ReviewPage-B7EN817i.js +1 -0
  21. package/dist/web/assets/SearchableSelect-ClLN0rIb.js +1 -0
  22. package/dist/web/assets/SettingsPage-C6ouU0sR.css +1 -0
  23. package/dist/web/assets/SettingsPage-Chd_B3eH.js +1 -0
  24. package/dist/web/assets/_plugin-vue_export-helper-BDNMzG2s.js +1 -0
  25. package/dist/web/assets/console-CbDsKrsO.js +1 -0
  26. package/dist/web/assets/fuli-logo-Bu9WBuQe.js +1 -0
  27. package/dist/web/assets/fuli-logo-ER1wQ8Kk.png +0 -0
  28. package/dist/web/assets/i18n-BQcns1PH.js +5 -0
  29. package/dist/web/assets/identity-B8K4VYg6.js +1 -0
  30. package/dist/web/assets/index-CB8Xmsc2.js +2 -0
  31. package/dist/web/assets/index-CZeuPh-U.css +1 -0
  32. package/dist/web/assets/model-eF52GgPF.js +1 -0
  33. package/dist/web/assets/paths-hwz-Ac1g.js +1 -0
  34. package/dist/web/assets/useMinimumLoadingDisplay-BpCyBeko.css +1 -0
  35. package/dist/web/assets/useMinimumLoadingDisplay-wCgGDmHg.js +1 -0
  36. package/dist/web/assets/vue-router-BsEp_XwI.js +1 -0
  37. package/dist/web/index.html +9 -6
  38. package/docs/external-knowledge-architecture.md +279 -0
  39. package/examples/external-knowledge/markdown-folder.mjs +235 -0
  40. package/graph-provider/fuli_graph/app.py +57 -1
  41. package/graph-provider/fuli_graph/graph_models.py +3 -0
  42. package/graph-provider/fuli_graph/graph_query.py +62 -16
  43. package/graph-provider/fuli_graph/knowledge_review.py +612 -0
  44. package/graph-provider/fuli_graph/knowledge_review_models.py +127 -0
  45. package/graph-provider/fuli_graph/knowledge_search.py +51 -4
  46. package/graph-provider/fuli_graph/models.py +19 -0
  47. package/graph-provider/fuli_graph/runtime.py +15 -0
  48. package/graph-provider/fuli_graph/store_knowledge.py +2 -1
  49. package/graph-provider/pyproject.toml +1 -1
  50. package/npm-shrinkwrap.json +5 -407
  51. package/package.json +7 -5
  52. package/skills/capturing-session-knowledge/SKILL.md +24 -4
  53. package/skills/flreview/SKILL.md +73 -0
  54. package/skills/flreview/agents/openai.yaml +6 -0
  55. package/src/agent-tools/graph-definitions.js +79 -4
  56. package/src/agent-tools/graph-handlers.js +12 -0
  57. package/src/cli/command-registry.js +3 -3
  58. package/src/cli/local-runtime-command.js +51 -28
  59. package/src/cli/local-runtime-options.js +14 -8
  60. package/src/cli/setup-agent-selection.js +12 -12
  61. package/src/cli/setup-command.js +41 -18
  62. package/src/cli/shell-argument.js +10 -0
  63. package/src/cli/uninstall-command.js +17 -15
  64. package/src/cli/update-command.js +38 -30
  65. package/src/external-knowledge/catalog.js +61 -0
  66. package/src/external-knowledge/conflict-policy.js +58 -0
  67. package/src/external-knowledge/connected-search.js +166 -0
  68. package/src/external-knowledge/connectors/custom.js +133 -0
  69. package/src/external-knowledge/connectors/feishu.js +461 -0
  70. package/src/external-knowledge/connectors/mcp.js +438 -0
  71. package/src/external-knowledge/connectors/notion.js +307 -0
  72. package/src/external-knowledge/connectors/retrieval-api.js +222 -0
  73. package/src/external-knowledge/document-mapping.js +151 -0
  74. package/src/external-knowledge/graph-projection.js +17 -0
  75. package/src/external-knowledge/index.js +8 -0
  76. package/src/external-knowledge/registry.js +91 -0
  77. package/src/external-knowledge/runtime.js +68 -0
  78. package/src/external-knowledge/safe-diagnostic.js +14 -0
  79. package/src/external-knowledge/service.js +811 -0
  80. package/src/graphiti/agent-knowledge-workflows.js +7 -2
  81. package/src/graphiti/federated-application.js +66 -41
  82. package/src/graphiti/knowledge-item-role.js +21 -0
  83. package/src/graphiti/knowledge-review.js +43 -0
  84. package/src/graphiti/project-profile-mapping.js +32 -0
  85. package/src/graphiti/provider-client.js +22 -1
  86. package/src/graphiti/source-marker.js +54 -3
  87. package/src/graphiti/task-knowledge-recall.js +250 -0
  88. package/src/http/api-router.js +23 -108
  89. package/src/http/external-knowledge-api-router.js +104 -0
  90. package/src/http/graph-api-router.js +12 -1
  91. package/src/http/request-policy.js +1 -1
  92. package/src/local-runtime/lifecycle.js +26 -15
  93. package/src/mcp/create-mcp-server.js +1 -0
  94. package/src/mcp/instructions.js +7 -7
  95. package/src/mcp/tool-annotations.js +6 -0
  96. package/src/mcp/tool-result.js +1 -0
  97. package/src/server/application-lifecycle.js +2 -11
  98. package/src/server/blocked-ports.js +11 -0
  99. package/src/server.js +36 -17
  100. package/src/setup/agent-installation-status.js +2 -1
  101. package/src/setup/agents.js +2 -1
  102. package/src/setup/claude-code-config.js +2 -1
  103. package/src/setup/codex-bootstrap.js +12 -7
  104. package/src/setup/container-runtime.js +25 -21
  105. package/src/setup/graph-runtime.js +148 -56
  106. package/src/setup/node-runtime.js +3 -3
  107. package/src/setup/options.js +2 -4
  108. package/src/setup/paths.js +18 -3
  109. package/src/setup/review-skill-adapters.js +49 -0
  110. package/src/setup/setup.js +26 -2
  111. package/src/setup/uninstall.js +4 -2
  112. package/src/system/resource-monitor.js +317 -0
  113. package/src/system/runtime-settings.js +131 -0
  114. package/src/system/system-service.js +119 -0
  115. package/dist/web/assets/ConnectionsPage-CCKWm-6p.js +0 -1
  116. package/dist/web/assets/KnowledgeInspector-BZkB2wJn.js +0 -1
  117. package/dist/web/assets/KnowledgeInspector-CrGYxEob.css +0 -1
  118. package/dist/web/assets/KnowledgeOrganizerPage-CZAF_OlN.css +0 -1
  119. package/dist/web/assets/KnowledgeOrganizerPage-DlvcLwlL.js +0 -1
  120. package/dist/web/assets/KnowledgePage-CNQXd15y.js +0 -1
  121. package/dist/web/assets/KnowledgeWorkspace-CXPE4GCD.js +0 -4
  122. package/dist/web/assets/OverviewPage-ul7g7HXh.js +0 -1
  123. package/dist/web/assets/PersonalProfilePage-CC40Pw2L.js +0 -1
  124. package/dist/web/assets/PersonalProjectsPage-CPIEcShD.js +0 -1
  125. package/dist/web/assets/PublicProjectsPage-C700sR7z.js +0 -1
  126. package/dist/web/assets/ReviewPage-7MDDUDgA.js +0 -1
  127. package/dist/web/assets/console-B_Ena2DS.js +0 -5
  128. package/dist/web/assets/fuli-logo-DGuyqchQ.png +0 -0
  129. package/dist/web/assets/identity-CjBwYSMX.js +0 -1
  130. package/dist/web/assets/index-CpLDx3of.css +0 -1
  131. package/dist/web/assets/index-DAzeFJSc.js +0 -2
  132. package/dist/web/assets/model-C-5RVIJ2.js +0 -1
  133. package/dist/web/assets/paths-BkULqmGI.js +0 -1
  134. package/dist/web/assets/vue-router-DnD3hUm7.js +0 -1
  135. package/src/agent/candidate-read-service.js +0 -53
  136. package/src/agent/context-pack-service.js +0 -83
  137. package/src/agent/public-read-policy.js +0 -39
  138. package/src/agent/public-read-service.js +0 -69
  139. package/src/agent/read-projection.js +0 -107
  140. package/src/agent/search-service.js +0 -61
  141. package/src/agent/space-boundary.js +0 -33
  142. package/src/app/bootstrap.js +0 -8
  143. package/src/app/create-application.js +0 -143
  144. package/src/app/state-service.js +0 -38
  145. package/src/candidates.js +0 -78
  146. package/src/classifier.js +0 -63
  147. package/src/cli/command-arguments.js +0 -14
  148. package/src/context-pack.js +0 -206
  149. package/src/extractor.js +0 -77
  150. package/src/fact-history.js +0 -39
  151. package/src/facts/fact-service.js +0 -89
  152. package/src/http/bounded-json-array.js +0 -19
  153. package/src/http/lens-route.js +0 -50
  154. package/src/ingestion.js +0 -161
  155. package/src/lens/lens-correction-service.js +0 -81
  156. package/src/lens/lens-fact-writer.js +0 -85
  157. package/src/lens/lens-input.js +0 -62
  158. package/src/lens/lens-query-projection.js +0 -87
  159. package/src/lens/lens-query-ranking.js +0 -62
  160. package/src/lens/lens-query.js +0 -143
  161. package/src/lens/lens-resource-projection.js +0 -93
  162. package/src/lens/lens-resource-selection.js +0 -45
  163. package/src/lens/lens-resource-service.js +0 -103
  164. package/src/lens/lens-search-query.js +0 -122
  165. package/src/lens/lens-service.js +0 -183
  166. package/src/models.js +0 -44
  167. package/src/observer.js +0 -83
  168. package/src/project-rules.js +0 -33
  169. package/src/publication/outbox-service.js +0 -46
  170. package/src/publication/publication-envelope-schema.js +0 -75
  171. package/src/publication/publication-envelope.js +0 -37
  172. package/src/publication/publication-policy.js +0 -82
  173. package/src/publication/publication-service.js +0 -48
  174. package/src/router.js +0 -58
  175. package/src/runtime-options.js +0 -138
  176. package/src/security/episode-visibility.js +0 -14
  177. package/src/security/fact-visibility.js +0 -15
  178. package/src/security/source-metadata-policy.js +0 -8
  179. package/src/storage/episode-evidence-preview.js +0 -100
  180. package/src/storage/fact-search-order.js +0 -18
  181. package/src/storage/file/episode-evidence.js +0 -37
  182. package/src/storage/file/episode-index.js +0 -59
  183. package/src/storage/file/fact-search.js +0 -60
  184. package/src/storage/file-store.js +0 -437
  185. package/src/storage/migrate.js +0 -128
  186. package/src/storage/migrations/001-initial.sql +0 -83
  187. package/src/storage/migrations/002-storage-integrity.sql +0 -113
  188. package/src/storage/record-validation.js +0 -46
  189. package/src/storage/snapshot-defaults.js +0 -54
  190. package/src/storage/sqlite/candidates-repository.js +0 -84
  191. package/src/storage/sqlite/episode-evidence-repository.js +0 -154
  192. package/src/storage/sqlite/episode-privacy-sql.js +0 -33
  193. package/src/storage/sqlite/episodes-repository.js +0 -52
  194. package/src/storage/sqlite/fact-search-repository.js +0 -162
  195. package/src/storage/sqlite/facts-repository.js +0 -146
  196. package/src/storage/sqlite/imports-repository.js +0 -39
  197. package/src/storage/sqlite/mapper.js +0 -84
  198. package/src/storage/sqlite/open-database.js +0 -15
  199. package/src/storage/sqlite/outbox-repository.js +0 -103
  200. package/src/storage/sqlite/snapshot-repository.js +0 -69
  201. package/src/storage/sqlite/spaces-repository.js +0 -52
  202. package/src/storage/sqlite/subscriptions-repository.js +0 -54
  203. package/src/storage/sqlite-store.js +0 -159
  204. package/src/storage/stable-json.js +0 -24
  205. package/src/storage/store-port.js +0 -20
  206. package/src/store.js +0 -2
@@ -0,0 +1,317 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { readdir, lstat, statfs } from 'node:fs/promises';
3
+ import { freemem, totalmem } from 'node:os';
4
+ import { join } from 'node:path';
5
+
6
+ import { inspectContainerRuntime } from '../setup/container-runtime.js';
7
+
8
+ const COMPOSE_PROJECT = 'fuli-graphiti';
9
+ const DISK_CACHE_MS = 60_000;
10
+ const PROCESS_TIMEOUT_MS = 8_000;
11
+ const CONTAINER_LABELS = Object.freeze({
12
+ 'personal-provider': 'Personal Provider',
13
+ 'personal-neo4j': 'Personal Neo4j',
14
+ 'workspace-provider': 'Workspace Provider',
15
+ 'workspace-neo4j': 'Workspace Neo4j'
16
+ });
17
+
18
+ export function createResourceMonitor({
19
+ dataDir,
20
+ packageRoot,
21
+ now = () => new Date(),
22
+ processMemory = () => process.memoryUsage(),
23
+ hostMemory = () => ({ totalBytes: totalmem(), freeBytes: freemem() }),
24
+ containerRuntime = null,
25
+ inspectRuntime = inspectContainerRuntime,
26
+ run = runCommand,
27
+ directorySize = allocatedDirectorySize,
28
+ filesystemStats = hostFilesystemStats
29
+ }) {
30
+ let resolvedRuntime = containerRuntime;
31
+ let diskCache = null;
32
+
33
+ async function sample() {
34
+ const sampledAt = now().toISOString();
35
+ const runtime = resolvedRuntime ??= inspectRuntime();
36
+ const containers = await containerMemory(runtime, run);
37
+ const localMemory = processMemory();
38
+ const host = hostMemory();
39
+ const disk = await diskSample({
40
+ runtime,
41
+ run,
42
+ dataDir,
43
+ packageRoot,
44
+ directorySize,
45
+ filesystemStats,
46
+ now,
47
+ cache: diskCache
48
+ });
49
+ diskCache = disk.cache;
50
+
51
+ const memoryComponents = [{
52
+ id: 'console',
53
+ label: 'Management service',
54
+ kind: 'process',
55
+ status: 'ready',
56
+ bytes: localMemory.rss
57
+ }, ...containers.components];
58
+ return {
59
+ sampledAt,
60
+ status: containers.complete && disk.value.complete ? 'ready' : 'partial',
61
+ memory: {
62
+ usedBytes: sumBytes(memoryComponents),
63
+ hostTotalBytes: host.totalBytes,
64
+ hostFreeBytes: host.freeBytes,
65
+ complete: containers.complete,
66
+ components: memoryComponents
67
+ },
68
+ disk: disk.value,
69
+ exclusions: ['browser-tab-memory', 'shared-container-vm-overhead']
70
+ };
71
+ }
72
+
73
+ return { sample };
74
+ }
75
+
76
+ async function containerMemory(runtime, run) {
77
+ if (runtime?.status !== 'ready') return { complete: false, components: [] };
78
+ try {
79
+ const containers = await listManagedContainers(runtime, run);
80
+ if (containers.length === 0) return { complete: false, components: [] };
81
+ const output = await runDocker(runtime, [
82
+ 'stats', '--no-stream', '--format', '{{.ID}}\t{{.MemUsage}}',
83
+ ...containers.map(({ id }) => id)
84
+ ], run);
85
+ const usage = new Map(parseLines(output).map((line) => {
86
+ const [id, value] = line.split('\t');
87
+ return [id, parseDockerBytes(value.split('/', 1)[0].trim())];
88
+ }));
89
+ return {
90
+ complete: containers.every(({ id }) => usage.has(id)),
91
+ components: containers.flatMap(({ id, service }) => usage.has(id) ? [{
92
+ id: service,
93
+ label: CONTAINER_LABELS[service] ?? service,
94
+ kind: 'container',
95
+ status: 'ready',
96
+ bytes: usage.get(id)
97
+ }] : [])
98
+ };
99
+ } catch {
100
+ return { complete: false, components: [] };
101
+ }
102
+ }
103
+
104
+ async function diskSample(input) {
105
+ const timestamp = input.now().getTime();
106
+ if (input.cache && timestamp - input.cache.timestamp < DISK_CACHE_MS) {
107
+ return { value: input.cache.value, cache: input.cache };
108
+ }
109
+ const [applicationBytes, localDataBytes, filesystem, docker] = await Promise.all([
110
+ input.directorySize(input.packageRoot),
111
+ input.directorySize(input.dataDir),
112
+ input.filesystemStats(input.dataDir),
113
+ dockerDisk(input.runtime, input.run)
114
+ ]);
115
+ const components = [
116
+ diskComponent('application', 'Application files', applicationBytes),
117
+ diskComponent('localData', 'Local runtime data', localDataBytes),
118
+ ...docker.components
119
+ ].filter(Boolean);
120
+ const value = {
121
+ usedBytes: sumBytes(components),
122
+ hostTotalBytes: filesystem.totalBytes,
123
+ hostFreeBytes: filesystem.freeBytes,
124
+ complete: docker.complete && Number.isFinite(filesystem.totalBytes) &&
125
+ Number.isFinite(filesystem.freeBytes),
126
+ measuredAt: input.now().toISOString(),
127
+ temporaryBytes: docker.temporaryBytes,
128
+ components
129
+ };
130
+ return { value, cache: { timestamp, value } };
131
+ }
132
+
133
+ async function dockerDisk(runtime, run) {
134
+ if (runtime?.status !== 'ready') {
135
+ return { complete: false, components: [], temporaryBytes: null };
136
+ }
137
+ try {
138
+ const containers = await listManagedContainers(runtime, run);
139
+ if (containers.length === 0) {
140
+ return { complete: false, components: [], temporaryBytes: null };
141
+ }
142
+ const inspectOutput = await runDocker(runtime, [
143
+ 'inspect', '--size', '--format', '{{.Id}}\t{{.SizeRw}}\t{{.Image}}',
144
+ ...containers.map(({ id }) => id)
145
+ ], run);
146
+ const inspected = parseLines(inspectOutput).map((line) => {
147
+ const [id, writable, imageId] = line.split('\t');
148
+ return { id, writableBytes: nonNegativeNumber(writable), imageId };
149
+ });
150
+ if (
151
+ inspected.length !== containers.length ||
152
+ inspected.some(({ id, imageId }) => !id || !imageId)
153
+ ) {
154
+ throw new TypeError('Docker container disk metrics are incomplete');
155
+ }
156
+ const imageIds = [...new Set(inspected.map(({ imageId }) => imageId).filter(Boolean))];
157
+ const imageOutput = imageIds.length === 0 ? '' : await runDocker(runtime, [
158
+ 'image', 'inspect', '--format', '{{.Id}}\t{{.Size}}', ...imageIds
159
+ ], run);
160
+ const imageSizes = new Map(parseLines(imageOutput).map((line) => {
161
+ const [id, value] = line.split('\t');
162
+ return [id, nonNegativeNumber(value)];
163
+ }));
164
+ if (imageIds.some((id) => !imageSizes.has(id))) {
165
+ throw new TypeError('Docker image disk metrics are incomplete');
166
+ }
167
+ const imageBytes = imageIds.reduce((total, id) => total + imageSizes.get(id), 0);
168
+ const writableBytes = inspected.reduce(
169
+ (total, item) => total + item.writableBytes,
170
+ 0
171
+ );
172
+ const volumeUsage = await managedVolumeUsage(runtime, containers, run);
173
+ return {
174
+ complete: true,
175
+ temporaryBytes: volumeUsage.temporaryBytes,
176
+ components: [
177
+ diskComponent('containerImages', 'Container images', imageBytes),
178
+ diskComponent('containerWritable', 'Container writable data', writableBytes),
179
+ diskComponent('neo4jData', 'Neo4j data', volumeUsage.dataBytes),
180
+ diskComponent('neo4jLogs', 'Neo4j logs', volumeUsage.logBytes)
181
+ ].filter(Boolean)
182
+ };
183
+ } catch {
184
+ return { complete: false, components: [], temporaryBytes: null };
185
+ }
186
+ }
187
+
188
+ async function managedVolumeUsage(runtime, containers, run) {
189
+ let dataBytes = 0;
190
+ let logBytes = 0;
191
+ let temporaryBytes = 0;
192
+ const neo4jContainers = containers.filter(({ service }) => service.endsWith('-neo4j'));
193
+ if (neo4jContainers.length === 0) {
194
+ throw new TypeError('No managed Neo4j container was available');
195
+ }
196
+ for (const container of neo4jContainers) {
197
+ const output = await runDocker(runtime, [
198
+ 'exec', container.id, 'du', '-sk', '/data', '/logs', '/tmp'
199
+ ], run);
200
+ const usage = new Map();
201
+ for (const line of parseLines(output)) {
202
+ const [kib, path] = line.trim().split(/\s+/, 2);
203
+ if (['/data', '/logs', '/tmp'].includes(path)) {
204
+ usage.set(path, nonNegativeNumber(kib) * 1024);
205
+ }
206
+ }
207
+ if (['/data', '/logs', '/tmp'].some((path) => !usage.has(path))) {
208
+ throw new TypeError('Neo4j volume disk metrics are incomplete');
209
+ }
210
+ dataBytes += usage.get('/data');
211
+ logBytes += usage.get('/logs');
212
+ temporaryBytes += usage.get('/tmp');
213
+ }
214
+ return { dataBytes, logBytes, temporaryBytes };
215
+ }
216
+
217
+ async function listManagedContainers(runtime, run) {
218
+ const output = await runDocker(runtime, [
219
+ 'ps', '--filter', `label=com.docker.compose.project=${COMPOSE_PROJECT}`,
220
+ '--format', '{{.ID}}\t{{.Label "com.docker.compose.service"}}'
221
+ ], run);
222
+ return parseLines(output).flatMap((line) => {
223
+ const [id, service] = line.split('\t');
224
+ return id && service && Object.hasOwn(CONTAINER_LABELS, service)
225
+ ? [{ id, service }]
226
+ : [];
227
+ });
228
+ }
229
+
230
+ function runDocker(runtime, args, run) {
231
+ return run(runtime.dockerCommand, args, { env: runtime.dockerEnvironment });
232
+ }
233
+
234
+ export async function allocatedDirectorySize(root) {
235
+ if (typeof root !== 'string' || !root) return 0;
236
+ let total = 0;
237
+ let entries;
238
+ try {
239
+ entries = await readdir(root, { withFileTypes: true });
240
+ } catch {
241
+ return 0;
242
+ }
243
+ for (const entry of entries) {
244
+ const path = join(root, entry.name);
245
+ if (entry.isSymbolicLink()) continue;
246
+ if (entry.isDirectory()) {
247
+ total += await allocatedDirectorySize(path);
248
+ continue;
249
+ }
250
+ try {
251
+ const stats = await lstat(path);
252
+ total += Number.isFinite(stats.blocks) ? stats.blocks * 512 : stats.size;
253
+ } catch {
254
+ // Files may be replaced while the snapshot is being collected.
255
+ }
256
+ }
257
+ return total;
258
+ }
259
+
260
+ async function hostFilesystemStats(path) {
261
+ try {
262
+ const stats = await statfs(path, { bigint: true });
263
+ return {
264
+ totalBytes: Number(stats.blocks * stats.bsize),
265
+ freeBytes: Number(stats.bavail * stats.bsize)
266
+ };
267
+ } catch {
268
+ return { totalBytes: null, freeBytes: null };
269
+ }
270
+ }
271
+
272
+ function runCommand(command, args, { env } = {}) {
273
+ return new Promise((resolve, reject) => {
274
+ execFile(command, args, {
275
+ encoding: 'utf8',
276
+ env,
277
+ timeout: PROCESS_TIMEOUT_MS,
278
+ windowsHide: true,
279
+ maxBuffer: 2 * 1024 * 1024
280
+ }, (error, stdout) => {
281
+ if (error) reject(error);
282
+ else resolve(stdout);
283
+ });
284
+ });
285
+ }
286
+
287
+ export function parseDockerBytes(value) {
288
+ const match = /^([0-9]+(?:\.[0-9]+)?)\s*([kmgtp]?i?b)$/i.exec(String(value).trim());
289
+ if (!match) throw new TypeError(`Unsupported Docker byte value: ${value}`);
290
+ const unit = match[2].toLowerCase();
291
+ const powers = { b: 0, kb: 1, kib: 1, mb: 2, mib: 2, gb: 3, gib: 3, tb: 4, tib: 4,
292
+ pb: 5, pib: 5 };
293
+ const base = unit.includes('i') ? 1024 : 1000;
294
+ return Math.round(Number(match[1]) * (base ** powers[unit]));
295
+ }
296
+
297
+ function diskComponent(id, label, bytes) {
298
+ return Number.isFinite(bytes) && bytes >= 0
299
+ ? { id, label, status: 'ready', bytes }
300
+ : null;
301
+ }
302
+
303
+ function sumBytes(components) {
304
+ return components.reduce((total, component) => total + component.bytes, 0);
305
+ }
306
+
307
+ function nonNegativeNumber(value) {
308
+ const number = Number(value);
309
+ if (!Number.isFinite(number) || number < 0) {
310
+ throw new TypeError(`Expected a non-negative number, received: ${value}`);
311
+ }
312
+ return number;
313
+ }
314
+
315
+ function parseLines(value) {
316
+ return String(value).split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
317
+ }
@@ -0,0 +1,131 @@
1
+ import { chmodSync } from 'node:fs';
2
+
3
+ import { isFetchBlockedPort } from '../server/blocked-ports.js';
4
+ import { readJsonFile, writeJsonFileAtomic } from '../storage/json-file.js';
5
+
6
+ export const RUNTIME_SETTINGS_VERSION = 1;
7
+ export const RESOURCE_REFRESH_OPTIONS = Object.freeze([5, 10, 30, 60]);
8
+ export const PORT_KEYS = Object.freeze([
9
+ 'console',
10
+ 'personalProvider',
11
+ 'personalNeo4jHttp',
12
+ 'personalNeo4jBolt',
13
+ 'workspaceProvider',
14
+ 'workspaceNeo4jHttp',
15
+ 'workspaceNeo4jBolt'
16
+ ]);
17
+
18
+ export const DEFAULT_RUNTIME_SETTINGS = deepFreeze({
19
+ version: RUNTIME_SETTINGS_VERSION,
20
+ ports: {
21
+ console: 2727,
22
+ personalProvider: 8787,
23
+ personalNeo4jHttp: 8060,
24
+ personalNeo4jBolt: 7687,
25
+ workspaceProvider: 8788,
26
+ workspaceNeo4jHttp: 7475,
27
+ workspaceNeo4jBolt: 7688
28
+ },
29
+ lanAccess: false,
30
+ resourceRefreshSeconds: 5
31
+ });
32
+
33
+ export function readRuntimeSettings(path, {
34
+ fallback = DEFAULT_RUNTIME_SETTINGS,
35
+ read = readJsonFile
36
+ } = {}) {
37
+ const stored = read(path, null);
38
+ return normalizeRuntimeSettings(stored ?? fallback, { base: fallback });
39
+ }
40
+
41
+ export function writeRuntimeSettings(path, input, {
42
+ write = writeJsonFileAtomic,
43
+ secure = (filePath) => chmodSync(filePath, 0o600)
44
+ } = {}) {
45
+ const settings = normalizeRuntimeSettings(input, { strict: true });
46
+ write(path, settings);
47
+ secure(path);
48
+ return settings;
49
+ }
50
+
51
+ export function normalizeRuntimeSettings(input, {
52
+ base = DEFAULT_RUNTIME_SETTINGS,
53
+ strict = false
54
+ } = {}) {
55
+ if (!input || typeof input !== 'object' || Array.isArray(input)) {
56
+ throw new TypeError('Runtime settings must be an object');
57
+ }
58
+ if (input.version !== undefined && input.version !== RUNTIME_SETTINGS_VERSION) {
59
+ throw new TypeError('Unsupported runtime settings version');
60
+ }
61
+ const portsInput = input.ports;
62
+ if (strict && (!portsInput || typeof portsInput !== 'object' || Array.isArray(portsInput))) {
63
+ throw new TypeError('ports is required');
64
+ }
65
+ const ports = {};
66
+ for (const key of PORT_KEYS) {
67
+ const value = portsInput?.[key] ?? base.ports[key];
68
+ ports[key] = validPort(value, key);
69
+ }
70
+ const uniquePorts = new Set(Object.values(ports));
71
+ if (uniquePorts.size !== PORT_KEYS.length) {
72
+ throw new TypeError('Every FULI service must use a different port');
73
+ }
74
+ if (isFetchBlockedPort(ports.console)) {
75
+ throw new TypeError('The management UI port is blocked by web browsers');
76
+ }
77
+
78
+ const lanAccess = input.lanAccess ?? base.lanAccess;
79
+ if (typeof lanAccess !== 'boolean') throw new TypeError('lanAccess must be a boolean');
80
+ const resourceRefreshSeconds = input.resourceRefreshSeconds ?? base.resourceRefreshSeconds;
81
+ if (!RESOURCE_REFRESH_OPTIONS.includes(resourceRefreshSeconds)) {
82
+ throw new TypeError('resourceRefreshSeconds must be 5, 10, 30, or 60');
83
+ }
84
+ return {
85
+ version: RUNTIME_SETTINGS_VERSION,
86
+ ports,
87
+ lanAccess,
88
+ resourceRefreshSeconds
89
+ };
90
+ }
91
+
92
+ export function runtimeSettingsWithOverrides(settings, {
93
+ consolePort = null,
94
+ lanAccess = null
95
+ } = {}) {
96
+ return normalizeRuntimeSettings({
97
+ ...settings,
98
+ ports: {
99
+ ...settings.ports,
100
+ ...(consolePort === null ? {} : { console: consolePort })
101
+ },
102
+ ...(lanAccess === null ? {} : { lanAccess })
103
+ });
104
+ }
105
+
106
+ export function managedProviderUrls(settings) {
107
+ return {
108
+ personal: `http://127.0.0.1:${settings.ports.personalProvider}`,
109
+ workspace: `http://127.0.0.1:${settings.ports.workspaceProvider}`
110
+ };
111
+ }
112
+
113
+ export function runtimeSettingsEqual(left, right) {
114
+ return JSON.stringify(normalizeRuntimeSettings(left)) ===
115
+ JSON.stringify(normalizeRuntimeSettings(right));
116
+ }
117
+
118
+ function validPort(value, key) {
119
+ if (typeof value !== 'number' || !Number.isInteger(value) || value < 1 || value > 65535) {
120
+ throw new TypeError(`${key} must be an integer between 1 and 65535`);
121
+ }
122
+ return value;
123
+ }
124
+
125
+ function deepFreeze(value) {
126
+ Object.freeze(value);
127
+ for (const child of Object.values(value)) {
128
+ if (child && typeof child === 'object' && !Object.isFrozen(child)) deepFreeze(child);
129
+ }
130
+ return value;
131
+ }
@@ -0,0 +1,119 @@
1
+ import { readJsonFile } from '../storage/json-file.js';
2
+ import {
3
+ DEFAULT_RUNTIME_SETTINGS,
4
+ normalizeRuntimeSettings,
5
+ readRuntimeSettings,
6
+ runtimeSettingsEqual,
7
+ writeRuntimeSettings
8
+ } from './runtime-settings.js';
9
+ import { createResourceMonitor } from './resource-monitor.js';
10
+
11
+ export function createSystemService({
12
+ paths,
13
+ packageRoot,
14
+ activePort,
15
+ activeLan,
16
+ readJson = readJsonFile,
17
+ readSettings = readRuntimeSettings,
18
+ writeSettings = writeRuntimeSettings,
19
+ resourceMonitor = createResourceMonitor({
20
+ dataDir: paths.dataDir,
21
+ packageRoot
22
+ })
23
+ }) {
24
+ function activeSettings() {
25
+ const state = readJson(paths.graphRuntimeStatePath, null);
26
+ const graphConfig = readJson(paths.graphRuntimeConfigPath, null);
27
+ return settingsFromActiveRuntime({
28
+ state,
29
+ graphConfig,
30
+ activePort,
31
+ activeLan
32
+ });
33
+ }
34
+
35
+ function getSettings() {
36
+ const active = activeSettings();
37
+ const configured = readSettings(paths.runtimeSettingsPath, { fallback: active });
38
+ return settingsResult(configured, active);
39
+ }
40
+
41
+ function updateSettings(input) {
42
+ const configured = writeSettings(paths.runtimeSettingsPath, input);
43
+ return settingsResult(configured, activeSettings());
44
+ }
45
+
46
+ return {
47
+ getSettings,
48
+ updateSettings,
49
+ resources: () => resourceMonitor.sample()
50
+ };
51
+ }
52
+
53
+ export function settingsFromActiveRuntime({
54
+ state,
55
+ graphConfig,
56
+ activePort,
57
+ activeLan
58
+ }) {
59
+ let settings = DEFAULT_RUNTIME_SETTINGS;
60
+ if (state?.runtimeSettings) {
61
+ try {
62
+ settings = normalizeRuntimeSettings(state.runtimeSettings);
63
+ } catch {
64
+ settings = DEFAULT_RUNTIME_SETTINGS;
65
+ }
66
+ }
67
+ const ports = { ...settings.ports };
68
+ const consolePort = integerPort(state?.port) ?? integerPort(activePort);
69
+ if (consolePort !== null) ports.console = consolePort;
70
+ const personalProvider = urlPort(graphConfig?.personal?.providerUrl);
71
+ if (personalProvider !== null) ports.personalProvider = personalProvider;
72
+ const managedWorkspace = (graphConfig?.workspaces ?? []).find((workspace) =>
73
+ workspace?.managedDevelopment === true || isLoopbackProvider(workspace?.providerUrl)
74
+ );
75
+ const workspaceProvider = urlPort(managedWorkspace?.providerUrl);
76
+ if (workspaceProvider !== null) ports.workspaceProvider = workspaceProvider;
77
+ return normalizeRuntimeSettings({
78
+ ...settings,
79
+ ports,
80
+ lanAccess: state?.lan === true || (state == null && activeLan === true)
81
+ });
82
+ }
83
+
84
+ function settingsResult(configured, active) {
85
+ return {
86
+ configured,
87
+ active,
88
+ restartRequired: !runtimeSettingsEqual(
89
+ { ...configured, resourceRefreshSeconds: active.resourceRefreshSeconds },
90
+ active
91
+ )
92
+ };
93
+ }
94
+
95
+ function integerPort(value) {
96
+ const port = Number(value);
97
+ return Number.isInteger(port) && port >= 1 && port <= 65535 ? port : null;
98
+ }
99
+
100
+ function urlPort(value) {
101
+ if (typeof value !== 'string') return null;
102
+ try {
103
+ const url = new URL(value);
104
+ return integerPort(url.port || (url.protocol === 'https:' ? 443 : 80));
105
+ } catch {
106
+ return null;
107
+ }
108
+ }
109
+
110
+ function isLoopbackProvider(value) {
111
+ if (typeof value !== 'string') return false;
112
+ try {
113
+ const url = new URL(value);
114
+ return url.protocol === 'http:' &&
115
+ ['127.0.0.1', 'localhost', '::1', '[::1]'].includes(url.hostname);
116
+ } catch {
117
+ return false;
118
+ }
119
+ }
@@ -1 +0,0 @@
1
- import{C as e,D as t,E as n,F as r,J as i,K as a,N as o,U as s,a as c,b as l,d as u,n as d,t as f,v as p,w as m,x as h,y as g}from"./console-B_Ena2DS.js";import{i as _,r as v,t as y}from"./identity-CjBwYSMX.js";var b={class:`view connections-view`},x={class:`connection-intro`},S=[`aria-label`],C=[`data-status`],w={class:`service-state`},T=[`data-status`],E={class:`service-state`},D={key:0,class:`connection-subscriptions`},O={class:`section-title`},k={class:`subscription-list`},A=[`onClick`],j={key:0,class:`empty-state`},M={type:`submit`},N=t({__name:`ConnectionsPage`,setup(t){let N=f(),P=s(``),F=l(()=>N.state?.providers?.personal?.status===`ready`),I=l(()=>N.state?.providers?.workspaces??[]),L=l(()=>I.value.filter(({status:e})=>e===`ready`).length),R=l(()=>N.state?.subscriptions??[]),z=l(()=>new Set(R.value.map(({provider_url:e,project_id:t})=>`${e}::${t}`))),B=l(()=>(N.state?.projects??[]).filter(e=>!z.value.has(H(e)))),V=l(()=>B.value.map(e=>({value:H(e),label:e.name,meta:`#${y(e.id,26)}`,search:v(e.id)})));function H(e){return`${e.providerUrl}::${e.id}`}async function U(){let e=B.value.find(e=>H(e)===P.value);if(e)try{await c(`/api/subscriptions`,{personalSpaceId:N.activePersonalSpace?.id,projectId:e.id,providerUrl:e.providerUrl,projectName:e.name}),P.value=``,N.notify(u(`pages.connections.subscribed`,{name:e.name})),await N.refresh()}catch(e){N.reportError(e)}}async function W(e){try{let t=new URLSearchParams({personalSpaceId:N.activePersonalSpace?.id??``,providerUrl:e.provider_url});await d(`/api/subscriptions/${encodeURIComponent(e.project_id)}?${t}`),N.notify(u(`pages.connections.unsubscribed`,{name:e.project_name??e.project_id})),await N.refresh()}catch(e){N.reportError(e)}}return(t,s)=>(o(),m(`section`,b,[h(`div`,x,[h(`h3`,null,i(a(u)(`pages.connections.title`)),1),h(`p`,null,i(a(u)(`pages.connections.intro`)),1)]),h(`div`,{class:`service-connection-grid`,"aria-label":a(u)(`pages.connections.statusAria`)},[h(`article`,{class:`service-connection-card`,"data-status":F.value?`ready`:`error`},[h(`header`,null,[s[2]||=h(`span`,{class:`service-connection-icon local`,"aria-hidden":`true`},[h(`span`,{class:`nav-icon nav-icon-personal-project`})],-1),h(`div`,null,[s[1]||=h(`p`,null,`LOCAL KNOWLEDGE`,-1),h(`h3`,null,i(a(u)(`pages.connections.localGraphiti`)),1)]),h(`span`,w,i(F.value?a(u)(`common.status.connected`):a(u)(`common.status.connectionError`)),1)]),h(`p`,null,i(F.value?a(u)(`pages.connections.localReadyCopy`):a(u)(`pages.connections.localErrorCopy`)),1),h(`dl`,null,[h(`div`,null,[h(`dt`,null,i(a(u)(`pages.connections.storage`)),1),s[3]||=h(`dd`,null,`Neo4j`,-1)]),h(`div`,null,[h(`dt`,null,i(a(u)(`pages.connections.purpose`)),1),h(`dd`,null,i(a(u)(`pages.connections.localPurpose`)),1)])])],8,C),h(`article`,{class:`service-connection-card`,"data-status":a(N).publicRuntimeStatus},[h(`header`,null,[s[5]||=h(`span`,{class:`service-connection-icon public`,"aria-hidden":`true`},[h(`span`,{class:`nav-icon nav-icon-public-project`})],-1),h(`div`,null,[s[4]||=h(`p`,null,`PUBLIC PROVIDER`,-1),h(`h3`,null,i(a(u)(`pages.connections.publicService`)),1)]),h(`span`,E,i(a(N).publicRuntimeStatus===`ready`?a(u)(`common.status.connected`):a(N).publicRuntimeStatus===`error`?a(u)(`common.status.connectionError`):a(u)(`common.status.notConnected`)),1)]),h(`p`,null,i(a(N).publicRuntimeStatus===`ready`?a(u)(`pages.connections.publicReadyCopy`):a(N).publicRuntimeStatus===`error`?a(u)(`pages.connections.publicErrorCopy`):a(u)(`pages.connections.publicOfflineCopy`)),1),h(`dl`,null,[h(`div`,null,[h(`dt`,null,i(a(u)(`pages.connections.currentStatus`)),1),h(`dd`,null,i(a(N).publicRuntimeStatus===`ready`?a(u)(`pages.connections.sharedServicesReady`,{count:L.value||I.value.length}):a(u)(`pages.connections.notAvailable`)),1)]),h(`div`,null,[h(`dt`,null,i(a(u)(`pages.connections.purpose`)),1),h(`dd`,null,i(a(u)(`pages.connections.publicPurpose`)),1)])])],8,T)],8,S),a(N).state?.capabilities?.subscribeProject?(o(),m(`section`,D,[h(`div`,O,[h(`h3`,null,i(a(u)(`pages.connections.subscriptionsTitle`)),1),h(`p`,null,i(a(u)(`pages.connections.subscriptionsCopy`)),1)]),h(`div`,k,[(o(!0),m(g,null,r(R.value,e=>(o(),m(`div`,{key:`${e.provider_url}:${e.project_id}`,class:`subscription-row`},[s[6]||=h(`span`,null,`↗`,-1),h(`div`,null,[h(`strong`,null,i(e.project_name??e.project_id),1),h(`span`,null,i(a(u)(`pages.connections.sharedProject`)),1)]),h(`button`,{class:`secondary-action subscription-action`,type:`button`,onClick:t=>W(e)},i(a(u)(`pages.connections.unsubscribe`)),9,A)]))),128)),R.value.length?e(``,!0):(o(),m(`div`,j,i(a(u)(`pages.connections.noSubscriptions`)),1))]),h(`form`,{class:`subscription-form`,onSubmit:p(U,[`prevent`])},[n(_,{modelValue:P.value,"onUpdate:modelValue":s[0]||=e=>P.value=e,options:V.value,label:a(u)(`pages.connections.sharedProjectLabel`),placeholder:a(u)(`pages.connections.choosePublicProject`),searchable:``,required:``},null,8,[`modelValue`,`options`,`label`,`placeholder`]),h(`button`,M,i(a(u)(`pages.connections.subscribe`)),1)],32)])):e(``,!0)]))}});export{N as default};
@@ -1 +0,0 @@
1
- import{C as e,D as t,E as n,F as r,H as i,J as a,K as o,N as s,R as c,T as l,U as u,V as d,_ as f,a as p,b as m,d as h,i as g,m as _,q as v,t as y,v as b,w as x,x as S,y as C}from"./console-B_Ena2DS.js";import{i as w,r as T,t as E}from"./identity-CjBwYSMX.js";import{C as D,D as O,E as k,S as A,T as j,d as M,f as N,g as P,h as F,i as I,l as L,r as R,s as z,u as B,w as V,x as H}from"./model-C-5RVIJ2.js";var U=(e,t)=>{let n=e.__vccOpts||e;for(let[e,r]of t)n[e]=r;return n},ee={key:0,open:``,class:`knowledge-confirm-dialog vue-dialog`},W={class:`project-dialog-header`},te=[`disabled`],G={class:`knowledge-confirm-summary`},K={class:`knowledge-confirm-fields`},q={class:`knowledge-confirm-acknowledgement`},ne={key:0,class:`publish-dialog-error`,role:`alert`},J={class:`project-profile-dialog-actions`},Y=[`disabled`],re=[`disabled`],X=U(t({__name:`KnowledgeConfirmDialog`,props:{item:{},personalSpaceId:{},personalProjectId:{}},emits:[`close`,`saved`],setup(t,{emit:n}){let r=t,i=n,l=y(),p=u(``),v=u(``),C=u(``),w=u(!1),T=u(!1),E=u(``),D=u({kind:`import`,label:h(`knowledge.domain.actors.historicalRecord`)}),O=m(()=>r.item?.profileAspect?h(`knowledge.dialogs.confirm.preferenceSubject`):h(`knowledge.dialogs.confirm.knowledgeSubject`));c(()=>r.item,e=>{if(!e)return;let t=e.evidence.at(0),n=e.confirmationBasis;p.value=n?.existence_reason||t?.source_description||t?.summary||h(`knowledge.dialogs.confirm.sourceSupport`),v.value=n?.quadrant_reason||e.reasoningSummary||h(`knowledge.dialogs.confirm.quadrantReason`,{quadrant:j(e.originQuadrant),description:V(e.originQuadrant)}),D.value=n?.proposed_by??A(t),C.value=h(`knowledge.dialogs.confirm.confirmationReason`),w.value=!1,E.value=``},{immediate:!0});async function k(){let e=r.item;if(!(!e||T.value)){if(!e.classificationExplicit)return M(h(`knowledge.dialogs.confirm.errors.quadrantRequired`));if(!p.value.trim())return M(h(`knowledge.dialogs.confirm.errors.existenceRequired`));if(!v.value.trim())return M(h(`knowledge.dialogs.confirm.errors.quadrantReasonRequired`));if(!C.value.trim())return M(h(`knowledge.dialogs.confirm.errors.confirmationReasonRequired`));if(!w.value)return M(h(`knowledge.dialogs.confirm.errors.acknowledgmentRequired`));T.value=!0,E.value=``;try{await g(`/api/knowledge/${e.itemKind}/${encodeURIComponent(e.id)}`,{personalSpaceId:r.personalSpaceId,personalProjectId:r.personalProjectId,action:`confirm`,reason:C.value.trim(),confirmationStatus:`confirmed`,confirmationBasis:{existenceReason:p.value.trim(),quadrantReason:v.value.trim(),proposedBy:D.value,confirmedBy:{kind:`user`,label:h(`knowledge.domain.actors.currentUser`)},confirmedAt:new Date().toISOString()}}),l.notify(h(`knowledge.dialogs.confirm.confirmed`,{subject:O.value})),i(`saved`),i(`close`)}catch(e){E.value=e instanceof Error?e.message:h(`knowledge.dialogs.confirm.errors.failed`),l.reportError(e)}finally{T.value=!1}}}function A(e){let t={codex:`Codex`,claude_code:`Claude Code`,cursor:`Cursor`,kiro:`Kiro`,other:h(`knowledge.domain.actors.otherAgent`)}[e?.source_application??``];return t?{kind:`agent`,label:t}:{kind:`import`,label:h(`knowledge.domain.actors.historicalRecord`)}}function M(e){E.value=e}return(n,r)=>t.item?(s(),x(`dialog`,ee,[S(`form`,{class:`knowledge-confirm-dialog-shell`,onSubmit:b(k,[`prevent`])},[S(`header`,W,[S(`div`,null,[r[6]||=S(`p`,{class:`eyebrow`},`KNOWLEDGE CONFIRMATION`,-1),S(`h3`,null,a(o(h)(`knowledge.dialogs.confirm.title`,{subject:O.value})),1),S(`p`,null,a(o(h)(`knowledge.dialogs.confirm.intro`)),1)]),S(`button`,{class:`secondary-action`,type:`button`,disabled:T.value,onClick:r[0]||=e=>i(`close`)},a(o(h)(`common.actions.close`)),9,te)]),S(`section`,G,[S(`span`,null,a(t.item.profileAspect?o(h)(`knowledge.dialogs.confirm.preference`):o(h)(`knowledge.dialogs.confirm.knowledge`)),1),S(`strong`,null,a(t.item.title),1),S(`p`,null,a(t.item.body),1),S(`small`,null,a(o(h)(`knowledge.dialogs.confirm.quadrant`,{quadrant:o(j)(t.item.originQuadrant)})),1)]),S(`div`,K,[S(`label`,null,[S(`span`,null,a(o(h)(`knowledge.dialogs.confirm.whyExists`)),1),d(S(`textarea`,{"onUpdate:modelValue":r[1]||=e=>p.value=e,name:`confirmation-existence-reason`,maxlength:`4096`,rows:`3`,required:``},null,512),[[f,p.value]])]),S(`label`,null,[S(`span`,null,a(o(h)(`knowledge.dialogs.confirm.whyQuadrant`)),1),d(S(`textarea`,{"onUpdate:modelValue":r[2]||=e=>v.value=e,name:`confirmation-quadrant-reason`,maxlength:`4096`,rows:`3`,required:``},null,512),[[f,v.value]])]),S(`label`,null,[S(`span`,null,a(o(h)(`knowledge.dialogs.confirm.confirmationCopy`)),1),d(S(`textarea`,{"onUpdate:modelValue":r[3]||=e=>C.value=e,name:`confirmation-reason`,maxlength:`2000`,rows:`2`,required:``},null,512),[[f,C.value]])])]),S(`label`,q,[d(S(`input`,{"onUpdate:modelValue":r[4]||=e=>w.value=e,name:`confirmation-acknowledged`,type:`checkbox`},null,512),[[_,w.value]]),S(`span`,null,a(o(h)(`knowledge.dialogs.confirm.acknowledgment`)),1)]),E.value?(s(),x(`p`,ne,a(E.value),1)):e(``,!0),S(`footer`,J,[S(`button`,{class:`secondary-action`,type:`button`,disabled:T.value,onClick:r[5]||=e=>i(`close`)},a(o(h)(`common.actions.cancel`)),9,Y),S(`button`,{class:`primary-action`,type:`submit`,disabled:T.value||!w.value},a(T.value?o(h)(`knowledge.dialogs.confirm.confirming`):o(h)(`knowledge.dialogs.confirm.confirmSubject`,{subject:O.value})),9,re)])],32)])):e(``,!0)}}),[[`__scopeId`,`data-v-26170b1a`]]),ie={key:0,open:``,class:`project-dialog knowledge-edit-dialog vue-dialog`},ae={class:`project-dialog-shell`},oe={class:`project-dialog-header`},se={class:`knowledge-edit-columns`},ce={key:0},le={key:1},ue={key:2},de={class:`knowledge-taxonomy-fields`},fe={class:`knowledge-classification-warning`},pe={key:3,class:`knowledge-classification-warning`},me={class:`knowledge-confirmation-fields`},he={class:`knowledge-taxonomy-fields`},ge=[`placeholder`],_e=[`placeholder`],ve={key:4,class:`knowledge-replacement-fields`},ye={key:0},be={class:`knowledge-replacement-fields`},xe={key:5,class:`publish-dialog-error`,role:`alert`},Se={class:`knowledge-editor-actions`},Ce=[`disabled`],we=[`disabled`],Te=[`disabled`],Ee=[`disabled`],De={key:0},Oe=[`disabled`],ke={key:1},Ae={key:0},je=[`disabled`],Me=t({__name:`KnowledgeEditDialog`,props:{item:{},personalSpaceId:{},personalProjectId:{},projects:{},replacementItems:{default:()=>[]}},emits:[`close`,`saved`],setup(t,{emit:r}){let _=t,v=r,D=y(),O=u(!1),k=u(``),A=u(``),M=u(``),N=u(`global`),P=u(``),F=u(``),I=u(``),L=u(``),R=i({name:``,summary:``,fact:``,currentQuadrant:``,confirmationStatus:`pending`,existenceReason:``,quadrantReason:``,proposedByKind:`agent`,proposedByLabel:``,confirmedByKind:`user`,confirmedByLabel:``,profileAspect:`none`,inheritanceMode:`local_only`,reason:``}),z=m(()=>_.item?.itemKind===`relationship`),B=m(()=>!!_.item?.invalidAt),V=m(()=>!!_.item?.raw.profile_aspect),H=m(()=>_.projects.map(e=>({value:e.project_id,label:e.profile.name,meta:`#${E(e.project_id,26)}`,search:T(e.project_id)}))),U=m(()=>[`known_known`,`known_unknown`,`unknown_known`,`unknown_unknown`].map(e=>({value:e,label:h(`knowledge.dialogs.edit.quadrants.${e}`)}))),ee=m(()=>[{value:`pending`,label:h(`knowledge.dialogs.edit.confirmationStates.pending`)},{value:`confirmed`,label:h(`knowledge.dialogs.edit.confirmationStates.confirmed`)}]),W=m(()=>[{value:`local_only`,label:h(`knowledge.dialogs.edit.inheritance.local`)},{value:`descendants`,label:h(`knowledge.dialogs.edit.inheritance.descendants`)},{value:`selected_projects`,label:h(`knowledge.dialogs.edit.inheritance.selected`)}]),te=m(()=>[`user`,`agent`,`authoritative_source`,`import`].map(e=>({value:e,label:h(`knowledge.domain.actors.${e}`)}))),G=m(()=>[`user`,`authoritative_source`].map(e=>({value:e,label:h(`knowledge.domain.actors.${e}`)}))),K=m(()=>[{value:`none`,label:h(`knowledge.dialogs.edit.profiles.none`)},...[`taste`,`personality`,`judgment_preference`].map(e=>({value:e,label:h(`knowledge.domain.profiles.${e}`)}))]),q=m(()=>[{value:`global`,label:h(`knowledge.dialogs.edit.scopes.global`)},{value:`project`,label:h(`knowledge.dialogs.edit.scopes.project`),disabled:_.projects.length===0}]),ne=m(()=>[{value:``,label:h(`knowledge.dialogs.edit.replacementNone`)},..._.replacementItems.filter(e=>!e.invalidAt&&(e.itemKind!==_.item?.itemKind||e.id!==_.item?.id)).map(e=>({value:Fe(e.itemKind,e.id),label:e.title,meta:e.type,search:`${e.body} ${e.id}`}))]),J=m(()=>{if(!L.value)return null;try{let[e,t]=JSON.parse(L.value);return e!==`entity`&&e!==`relationship`||typeof t!=`string`?null:{itemKind:e,id:t}}catch{return null}}),Y=m(()=>_.item?.assignments.at(0)?.project_id??_.item?.evidence.find(({personal_project_id:e})=>e)?.personal_project_id??_.personalProjectId??null);c(()=>_.item,e=>{if(!e)return;let t=e.raw;R.name=e.itemKind===`entity`?t.name:``,R.summary=e.itemKind===`entity`?t.summary??``:``,R.fact=e.itemKind===`relationship`?t.fact??``:``;let n=e.confirmationBasis,r=e.evidence.at(0);R.currentQuadrant=e.classificationExplicit?t.current_quadrant??t.origin_quadrant??`known_known`:``,R.confirmationStatus=e.confirmationStatus===`confirmed`?`confirmed`:`pending`,R.existenceReason=n?.existence_reason??r?.source_description??r?.summary??``,R.quadrantReason=n?.quadrant_reason??t.reasoning_summary??``,R.proposedByKind=n?.proposed_by.kind??`agent`,R.proposedByLabel=n?.proposed_by.label??``,R.confirmedByKind=n?.confirmed_by?.kind??`user`,R.confirmedByLabel=n?.confirmed_by?.label??``,R.profileAspect=t.profile_aspect??`none`,R.inheritanceMode=t.profile_aspect?`local_only`:t.inheritance_mode??`local_only`,I.value=t.inherited_project_ids?.at(0)??_.projects[0]?.project_id??``,R.reason=``,A.value=``,M.value=Y.value??_.projects[0]?.project_id??``,N.value=t.preference_scope??`global`,P.value=t.preference_project_id??_.projects[0]?.project_id??``,F.value=``,L.value=e.replacedByItemId&&e.replacedByItemKind?Fe(e.replacedByItemKind,e.replacedByItemId):``,k.value=``},{immediate:!0});async function re(){let e=_.item;if(!e)return;if(!R.reason.trim())return $(h(`knowledge.dialogs.edit.errors.reasonRequired`));if(!z.value&&!R.name.trim())return $(h(`knowledge.dialogs.edit.errors.nameRequired`));if(z.value&&!R.fact.trim())return $(h(`knowledge.dialogs.edit.errors.factRequired`));if(!R.currentQuadrant||!R.confirmationStatus)return $(h(`knowledge.dialogs.edit.errors.classificationRequired`));if(!R.existenceReason.trim())return $(h(`knowledge.dialogs.edit.errors.existenceRequired`));if(!R.quadrantReason.trim())return $(h(`knowledge.dialogs.edit.errors.quadrantRequired`));if(!R.proposedByKind)return $(h(`knowledge.dialogs.edit.errors.proposerRequired`));if(R.confirmationStatus===`confirmed`&&!R.confirmedByKind)return $(h(`knowledge.dialogs.edit.errors.confirmerRequired`));if(R.inheritanceMode===`selected_projects`&&!I.value)return $(h(`knowledge.dialogs.edit.errors.inheritedProjectsRequired`));let t={...Z(`update`),confirmationStatus:R.confirmationStatus,confirmationBasis:{existenceReason:R.existenceReason.trim(),quadrantReason:R.quadrantReason.trim(),proposedBy:{kind:R.proposedByKind,label:R.proposedByLabel.trim()||null},confirmedBy:R.confirmationStatus===`confirmed`?{kind:R.confirmedByKind,label:R.confirmedByLabel.trim()||null}:null,confirmedAt:R.confirmationStatus===`confirmed`?new Date().toISOString():null},profileAspect:R.profileAspect,inheritanceMode:R.profileAspect===`none`?R.inheritanceMode:`local_only`,inheritedProjectIds:R.profileAspect===`none`&&R.inheritanceMode===`selected_projects`?[I.value]:[],reasoningSummary:R.quadrantReason.trim()};_.item.classificationExplicit?t.currentQuadrant=R.currentQuadrant:t.originQuadrant=R.currentQuadrant,z.value?t.fact=R.fact.trim():(t.name=R.name.trim(),t.summary=R.summary.trim()),await Q(async()=>{await g(`/api/knowledge/${e.itemKind}/${encodeURIComponent(e.id)}`,t),D.notify(h(`knowledge.dialogs.edit.notices.corrected`))})}async function X(e){let t=_.item;if(t){if(!R.reason.trim())return $(h(e===`invalidate`?`knowledge.dialogs.edit.errors.statusReasonRequired`:`knowledge.dialogs.edit.errors.restoreReasonRequired`));await Q(async()=>{let n=Z(e);e===`invalidate`&&J.value&&(n.replacementItemId=J.value.id,n.replacementItemKind=J.value.itemKind),await g(`/api/knowledge/${t.itemKind}/${encodeURIComponent(t.id)}`,n),D.notify(e===`invalidate`?J.value?h(`knowledge.dialogs.edit.notices.invalidatedWithReplacement`):h(`knowledge.dialogs.edit.notices.invalidated`):h(`knowledge.dialogs.edit.notices.restored`))})}}async function Me(){let e=_.item,t=J.value;if(!(!e||!B.value)){if(!t)return $(h(`knowledge.dialogs.edit.errors.replacementRequired`));if(!R.reason.trim())return $(h(`knowledge.dialogs.edit.errors.replacementReasonRequired`));await Q(async()=>{await g(`/api/knowledge/${e.itemKind}/${encodeURIComponent(e.id)}`,{...Z(`link_replacement`),replacementItemId:t.id,replacementItemKind:t.itemKind}),D.notify(h(`knowledge.dialogs.edit.notices.replacementSaved`))})}}async function Ne(){let e=_.item;if(e){if(!M.value)return $(h(`knowledge.dialogs.edit.errors.projectRequired`));if(!A.value.trim())return $(h(`knowledge.dialogs.edit.errors.assignmentReasonRequired`));if(M.value===Y.value)return $(h(`knowledge.dialogs.edit.errors.alreadyAssigned`));await Q(async()=>{await p(`/api/knowledge/${e.itemKind}/${encodeURIComponent(e.id)}/assignment`,{personalSpaceId:_.personalSpaceId,targetProjectId:M.value,reason:A.value.trim()}),D.notify(h(`knowledge.dialogs.edit.notices.assignmentChanged`))})}}async function Pe(){let e=_.item;if(!e)return;let t=N.value===`project`?P.value:null;if(N.value===`project`&&!t)return $(h(`knowledge.dialogs.edit.errors.preferenceProjectRequired`));if(!F.value.trim())return $(h(`knowledge.dialogs.edit.errors.preferenceReasonRequired`));await Q(async()=>{await p(`/api/knowledge/${e.itemKind}/${encodeURIComponent(e.id)}/preference-scope`,{personalSpaceId:_.personalSpaceId,scope:N.value,projectId:t,reason:F.value.trim()}),D.notify(N.value===`global`?h(`knowledge.dialogs.edit.notices.preferenceGlobal`):h(`knowledge.dialogs.edit.notices.preferenceProject`))})}function Z(e){return{personalSpaceId:_.personalSpaceId,personalProjectId:_.personalProjectId,action:e,reason:R.reason.trim()}}function Fe(e,t){return JSON.stringify([e,t])}async function Q(e){O.value=!0,k.value=``;try{await e(),v(`close`),v(`saved`)}catch(e){k.value=e instanceof Error?e.message:h(`knowledge.dialogs.edit.errors.saveFailed`),D.reportError(e)}finally{O.value=!1}}function $(e){k.value=e}return(r,i)=>t.item?(s(),x(`dialog`,ie,[S(`div`,ae,[S(`header`,oe,[S(`div`,null,[i[24]||=S(`p`,{class:`eyebrow`},`PERSONAL KNOWLEDGE`,-1),S(`h3`,null,a(B.value?o(h)(`knowledge.dialogs.edit.titleRestore`):o(h)(`knowledge.dialogs.edit.titleCorrect`)),1),S(`p`,null,a(o(h)(`knowledge.dialogs.edit.intro`)),1)]),S(`button`,{class:`secondary-action`,type:`button`,onClick:i[0]||=e=>v(`close`)},a(o(h)(`common.actions.close`)),1)]),S(`div`,se,[S(`section`,null,[S(`h4`,null,a(o(h)(`knowledge.dialogs.edit.currentContent`)),1),S(`form`,{class:`knowledge-editor-form`,onSubmit:b(re,[`prevent`])},[z.value?e(``,!0):(s(),x(`label`,ce,[l(a(o(h)(`knowledge.dialogs.edit.name`)),1),d(S(`input`,{"onUpdate:modelValue":i[1]||=e=>R.name=e,maxlength:`512`},null,512),[[f,R.name]])])),z.value?(s(),x(`label`,ue,[l(a(o(h)(`knowledge.dialogs.edit.fact`)),1),d(S(`textarea`,{"onUpdate:modelValue":i[3]||=e=>R.fact=e,maxlength:`8192`,rows:`5`},null,512),[[f,R.fact]])])):(s(),x(`label`,le,[l(a(o(h)(`knowledge.dialogs.edit.description`)),1),d(S(`textarea`,{"onUpdate:modelValue":i[2]||=e=>R.summary=e,maxlength:`4096`,rows:`5`},null,512),[[f,R.summary]])])),S(`div`,de,[S(`label`,null,[l(a(o(h)(`knowledge.dialogs.edit.classification`))+` `,1),n(w,{modelValue:R.currentQuadrant,"onUpdate:modelValue":i[4]||=e=>R.currentQuadrant=e,options:U.value,label:o(h)(`knowledge.dialogs.edit.classification`)},null,8,[`modelValue`,`options`,`label`])]),S(`label`,null,[l(a(o(h)(`knowledge.dialogs.edit.confirmationStatus`))+` `,1),n(w,{modelValue:R.confirmationStatus,"onUpdate:modelValue":i[5]||=e=>R.confirmationStatus=e,options:ee.value,label:o(h)(`knowledge.dialogs.edit.confirmationStatus`)},null,8,[`modelValue`,`options`,`label`])]),S(`label`,null,[l(a(o(h)(`knowledge.dialogs.edit.preferenceDimension`))+` `,1),n(w,{modelValue:R.profileAspect,"onUpdate:modelValue":i[6]||=e=>R.profileAspect=e,options:K.value,label:o(h)(`knowledge.dialogs.edit.preferenceDimension`)},null,8,[`modelValue`,`options`,`label`])])]),S(`p`,fe,a(o(h)(`knowledge.dialogs.edit.originQuadrant`,{quadrant:o(j)(t.item.originQuadrant)})),1),t.item.classificationExplicit?e(``,!0):(s(),x(`p`,pe,a(o(h)(`knowledge.dialogs.edit.missingQuadrant`)),1)),S(`fieldset`,me,[S(`legend`,null,a(o(h)(`knowledge.dialogs.edit.basis`)),1),S(`label`,null,[l(a(o(h)(`knowledge.dialogs.edit.whyExists`))+` `,1),d(S(`textarea`,{"onUpdate:modelValue":i[7]||=e=>R.existenceReason=e,maxlength:`4096`,rows:`3`,required:``},null,512),[[f,R.existenceReason]])]),S(`label`,null,[l(a(o(h)(`knowledge.dialogs.edit.whyQuadrant`))+` `,1),d(S(`textarea`,{"onUpdate:modelValue":i[8]||=e=>R.quadrantReason=e,maxlength:`4096`,rows:`3`,required:``},null,512),[[f,R.quadrantReason]])]),S(`div`,he,[S(`label`,null,[l(a(o(h)(`knowledge.dialogs.edit.proposer`))+` `,1),n(w,{modelValue:R.proposedByKind,"onUpdate:modelValue":i[9]||=e=>R.proposedByKind=e,options:te.value,label:o(h)(`knowledge.dialogs.edit.proposer`)},null,8,[`modelValue`,`options`,`label`])]),S(`label`,null,[l(a(o(h)(`knowledge.dialogs.edit.proposerDescription`))+` `,1),d(S(`input`,{"onUpdate:modelValue":i[10]||=e=>R.proposedByLabel=e,maxlength:`160`,placeholder:o(h)(`knowledge.dialogs.edit.proposerPlaceholder`)},null,8,ge),[[f,R.proposedByLabel]])]),R.confirmationStatus===`confirmed`?(s(),x(C,{key:0},[S(`label`,null,[l(a(o(h)(`knowledge.dialogs.edit.confirmer`))+` `,1),n(w,{modelValue:R.confirmedByKind,"onUpdate:modelValue":i[11]||=e=>R.confirmedByKind=e,options:G.value,label:o(h)(`knowledge.dialogs.edit.confirmer`)},null,8,[`modelValue`,`options`,`label`])]),S(`label`,null,[l(a(o(h)(`knowledge.dialogs.edit.confirmerDescription`))+` `,1),d(S(`input`,{"onUpdate:modelValue":i[12]||=e=>R.confirmedByLabel=e,maxlength:`160`,placeholder:o(h)(`knowledge.dialogs.edit.confirmerPlaceholder`)},null,8,_e),[[f,R.confirmedByLabel]])])],64)):e(``,!0)]),S(`p`,null,a(o(h)(`knowledge.dialogs.edit.agentConfirmedBoundary`)),1)]),V.value?e(``,!0):(s(),x(`fieldset`,ve,[S(`legend`,null,a(o(h)(`knowledge.dialogs.edit.crossProjectInheritance`)),1),S(`label`,null,[l(a(o(h)(`knowledge.dialogs.edit.inheritanceScope`))+` `,1),n(w,{modelValue:R.inheritanceMode,"onUpdate:modelValue":i[13]||=e=>R.inheritanceMode=e,options:W.value,label:o(h)(`knowledge.dialogs.edit.inheritanceScope`)},null,8,[`modelValue`,`options`,`label`])]),R.inheritanceMode===`selected_projects`?(s(),x(`label`,ye,[l(a(o(h)(`knowledge.dialogs.edit.inheritedProjects`))+` `,1),n(w,{modelValue:I.value,"onUpdate:modelValue":i[14]||=e=>I.value=e,options:H.value,label:o(h)(`knowledge.dialogs.edit.inheritedProjects`),searchable:``},null,8,[`modelValue`,`options`,`label`])])):e(``,!0),S(`p`,null,a(o(h)(`knowledge.dialogs.edit.inheritanceBoundary`)),1)])),S(`fieldset`,be,[S(`legend`,null,a(B.value?o(h)(`knowledge.dialogs.edit.replacement`):o(h)(`knowledge.dialogs.edit.optionalReplacement`)),1),S(`label`,null,[l(a(B.value?o(h)(`knowledge.dialogs.edit.historicalReplacement`):o(h)(`knowledge.dialogs.edit.activeReplacement`))+` `,1),n(w,{modelValue:L.value,"onUpdate:modelValue":i[15]||=e=>L.value=e,options:ne.value,label:o(h)(`knowledge.dialogs.edit.replacement`),searchable:``},null,8,[`modelValue`,`options`,`label`])]),S(`p`,null,a(o(h)(`knowledge.dialogs.edit.replacementBoundary`)),1)]),S(`label`,null,[l(a(o(h)(`knowledge.dialogs.edit.correctionReason`)),1),d(S(`textarea`,{"onUpdate:modelValue":i[16]||=e=>R.reason=e,maxlength:`2000`,rows:`3`,required:``},null,512),[[f,R.reason]])]),k.value?(s(),x(`p`,xe,a(k.value),1)):e(``,!0),S(`div`,Se,[B.value?(s(),x(C,{key:1},[S(`button`,{class:`secondary-action`,type:`button`,disabled:O.value,onClick:i[18]||=e=>X(`restore`)},a(o(h)(`knowledge.dialogs.edit.restore`)),9,we),S(`button`,{class:`secondary-action`,type:`button`,disabled:O.value,onClick:Me},a(o(h)(`knowledge.dialogs.edit.saveReplacement`)),9,Te)],64)):(s(),x(`button`,{key:0,class:`secondary-action`,type:`button`,disabled:O.value,onClick:i[17]||=e=>X(`invalidate`)},a(o(h)(`knowledge.dialogs.edit.invalidate`)),9,Ce)),S(`button`,{class:`primary-action`,type:`submit`,disabled:O.value},a(O.value?o(h)(`knowledge.dialogs.edit.saving`):R.confirmationStatus===`confirmed`?o(h)(`knowledge.dialogs.edit.saveConfirmed`):o(h)(`knowledge.dialogs.edit.savePending`)),9,Ee)])],32)]),V.value?(s(),x(`section`,ke,[S(`h4`,null,a(o(h)(`knowledge.dialogs.edit.preferenceScope`)),1),S(`p`,null,a(o(h)(`knowledge.dialogs.edit.preferenceScopeCopy`)),1),S(`form`,{class:`knowledge-editor-form`,onSubmit:b(Pe,[`prevent`])},[S(`label`,null,[l(a(o(h)(`knowledge.dialogs.edit.effectiveScope`))+` `,1),n(w,{modelValue:N.value,"onUpdate:modelValue":i[21]||=e=>N.value=e,options:q.value,label:o(h)(`knowledge.dialogs.edit.preferenceScope`)},null,8,[`modelValue`,`options`,`label`])]),N.value===`project`?(s(),x(`label`,Ae,[l(a(o(h)(`knowledge.dialogs.edit.personalProject`))+` `,1),n(w,{modelValue:P.value,"onUpdate:modelValue":i[22]||=e=>P.value=e,options:H.value,label:o(h)(`knowledge.dialogs.edit.personalProject`),searchable:``},null,8,[`modelValue`,`options`,`label`])])):e(``,!0),S(`label`,null,[l(a(o(h)(`knowledge.dialogs.edit.assignmentReason`)),1),d(S(`textarea`,{"onUpdate:modelValue":i[23]||=e=>F.value=e,maxlength:`2000`,rows:`3`,required:``},null,512),[[f,F.value]])]),S(`button`,{class:`primary-action`,type:`submit`,disabled:O.value},a(o(h)(`knowledge.dialogs.edit.saveScope`)),9,je)],32)])):(s(),x(`section`,De,[S(`h4`,null,a(o(h)(`knowledge.dialogs.edit.projectOwnership`)),1),S(`p`,null,a(o(h)(`knowledge.dialogs.edit.ownershipCopy`)),1),S(`form`,{class:`knowledge-editor-form`,onSubmit:b(Ne,[`prevent`])},[S(`label`,null,[l(a(o(h)(`knowledge.dialogs.edit.targetProject`))+` `,1),n(w,{modelValue:M.value,"onUpdate:modelValue":i[19]||=e=>M.value=e,options:H.value,label:o(h)(`knowledge.dialogs.edit.targetProject`),searchable:``,required:``},null,8,[`modelValue`,`options`,`label`])]),S(`label`,null,[l(a(o(h)(`knowledge.dialogs.edit.assignmentReason`)),1),d(S(`textarea`,{"onUpdate:modelValue":i[20]||=e=>A.value=e,maxlength:`2000`,rows:`3`,required:``},null,512),[[f,A.value]])]),S(`button`,{class:`primary-action`,type:`submit`,disabled:O.value||t.projects.length===0},a(o(h)(`knowledge.dialogs.edit.adjustOwnership`)),9,Oe)],32)]))])])])):e(``,!0)}}),Ne={codex:`Codex`,claude_code:`Claude Code`,cursor:`Cursor`,kiro:`Kiro`,other:`Other Agent`},Pe=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Z(e={}){let t=e.source_application;if(t&&Ne[t])return t;let n=`${e.source_kind??``} ${e.source_description??``}`.toLocaleLowerCase();return n.includes(`claude`)?`claude_code`:n.includes(`cursor`)?`cursor`:n.includes(`kiro`)?`kiro`:n.includes(`codex`)?`codex`:`other`}function Fe(e){let t=Z(e);return t===`other`?h(`knowledge.domain.actors.otherAgent`):Ne[t]}function Q(e={}){return Z(e)!==`codex`||!Pe.test(e.session_id??``)?null:`codex://threads/${e.session_id}`}async function $(e={},t=globalThis.navigator?.clipboard){return!e.session_id||!t?.writeText?!1:(await t.writeText(e.session_id),!0)}var Ie={class:`graph-inspector`},Le={class:`eyebrow`},Re={class:`inspector-identity`},ze={class:`muted`},Be={key:0,class:`inspector-project-material`},Ve={key:3,class:`inspector-replacement`},He={class:`inspector-replacement-heading`},Ue={key:1},We={key:2},Ge={class:`inspector-meta`},Ke={key:0},qe={key:1},Je={key:2},Ye={key:3},Xe={key:4},Ze={key:5},Qe={key:6},$e={key:7},et={key:8},tt={key:9},nt={key:10},rt={key:12},it={class:`inspector-subtitle`},at={key:0,class:`inspector-meta inspector-confirmation-basis`},ot={key:0},st={key:1,class:`inspector-reasoning`},ct={class:`inspector-subtitle`},lt={class:`inspector-meta inspector-attributes`},ut={class:`inspector-subtitle`},dt={class:`inspector-reasoning`},ft={key:7,class:`inspector-actions`},pt={class:`inspector-subtitle`},mt={class:`inspector-relations`},ht={class:`relation-type`},gt={class:`relation-target`},_t={class:`inspector-subtitle`},vt={class:`inspector-evidence`},yt={key:0,class:`evidence-excerpt`},bt=[`href`],xt=[`onClick`],St={class:`inspector-subtitle`},Ct={class:`inspector-history`},wt={class:`inspector-subtitle`},Tt={class:`inspector-history inspector-audit-history`},Et={key:0},Dt={class:`eyebrow`},Ot={class:`inspector-placeholder`},kt=t({__name:`KnowledgeInspector`,props:{item:{},graph:{},editable:{type:Boolean},currentProjectId:{},canPublishProject:{type:Boolean},canManageProject:{type:Boolean},mode:{}},emits:[`confirm`,`edit`,`createProject`,`openProject`,`publishProject`,`openDirectory`,`openGraph`,`openReplacement`,`manageProject`],setup(t,{emit:n}){let i=t,c=n,l=m(()=>i.item?.itemKind===`entity`?i.item.raw:null),d=m(()=>i.item?.itemKind===`relationship`?i.item.raw:null),f=m(()=>new Map(i.graph?.nodes.map(e=>[e.id,e.name])??[])),p=m(()=>!l.value||!i.graph?[]:i.graph.edges.filter(e=>z(e.source)===l.value?.id||z(e.target)===l.value?.id).slice(0,12)),g=m(()=>Object.entries(i.item?.raw.attributes??{}).filter(([,e])=>e!=null&&e!==``)),_=m(()=>M(i.item)),y=m(()=>H(i.item)),b=m(()=>i.item?.itemKind===`entity`&&[`PersonalProject`,`RelatedPersonalProject`].includes(i.item.type)),w=m(()=>i.editable&&i.item?.itemKind===`entity`&&!i.item.invalidAt&&!i.item.profileAspect&&!_.value),T=m(()=>i.editable&&!_.value),E=m(()=>i.editable&&!_.value&&!i.item?.invalidAt&&!!i.item?.classificationExplicit&&W.value===`pending`),U=m(()=>_.value&&i.canManageProject),ee=m(()=>w.value||T.value||E.value||U.value||!!i.mode||b.value&&!!y.value&&y.value!==i.currentProjectId||b.value&&!!y.value&&i.canPublishProject),W=m(()=>i.item?P(i.item):`unclassified`),te=m(()=>i.item?R(i.item):``),G=m(()=>i.item?.confirmationBasis??null),K=u(``),q=m(()=>{let e=i.item?.replacedByItemId,t=i.item?.replacedByItemKind;return!e||!t?null:F(i.graph).find(n=>n.id===e&&n.itemKind===t)??null}),ne=m(()=>{let e=i.item;return e?.humanEdited?e.humanChangeStatus===`unseen`?h(`knowledge.workspace.inspector.humanReview.unseen`):e.humanChangeStatus===`viewed`?h(`knowledge.workspace.inspector.humanReview.viewed`):h(`knowledge.workspace.inspector.humanReview.reviewed`):``});function J(e){return typeof e==`string`?e:JSON.stringify(e)}function Y(e){return`${Math.round(e*100)}%`}function re(e){return e.inheritanceMode===`descendants`?h(`knowledge.workspace.inspector.inheritance.descendants`):e.inheritanceMode===`selected_projects`?h(`knowledge.workspace.inspector.inheritance.selected`,{count:e.inheritedProjectIds.length}):h(`knowledge.workspace.inspector.inheritance.local`)}function X(e,t){return String(e.id??e.session_id??t)}async function ie(e,t){await $(e)&&(K.value=X(e,t))}return(n,i)=>(s(),x(`aside`,Ie,[t.item?(s(),x(C,{key:0},[S(`p`,Le,a(_.value?`PROJECT MATERIAL`:t.item.itemKind===`entity`?`ENTITY`:`RELATIONSHIP`),1),S(`h3`,null,a(t.item.itemKind===`entity`?t.item.title:d.value?.type),1),S(`div`,Re,[S(`span`,null,a(_.value?o(h)(`knowledge.workspace.inspector.ids.projection`):t.item.itemKind===`entity`?o(h)(`knowledge.workspace.inspector.ids.node`):o(h)(`knowledge.workspace.inspector.ids.relationship`)),1),S(`code`,null,a(t.item.id),1)]),S(`p`,ze,a(t.item.body),1),_.value?(s(),x(`section`,Be,[S(`div`,null,[S(`span`,null,a(o(h)(`knowledge.workspace.inspector.ownership`)),1),S(`strong`,null,a(o(D)(t.item)),1)]),S(`p`,null,a(o(h)(`knowledge.workspace.inspector.projectionCopy`)),1)])):(s(),x(`section`,{key:1,class:v([`inspector-classification`,`state-${W.value}`])},[S(`div`,null,[S(`span`,null,a(o(h)(`knowledge.workspace.inspector.currentJudgment`)),1),S(`strong`,null,a(o(k)(t.item)),1)]),S(`p`,null,a(te.value),1)],2)),!_.value&&t.item.humanEdited?(s(),x(`section`,{key:2,class:v([`inspector-human-change`,`state-${t.item.humanChangeStatus}`])},[S(`div`,null,[S(`span`,null,a(o(h)(`knowledge.workspace.inspector.humanReviewTitle`)),1),S(`strong`,null,a(o(B)(t.item.humanChangeStatus)),1)]),S(`p`,null,a(ne.value),1),S(`small`,null,a(o(h)(`knowledge.workspace.inspector.humanVersion`,{version:t.item.humanChangeVersion})),1)],2)):e(``,!0),!_.value&&t.item.invalidAt?(s(),x(`section`,Ve,[S(`div`,He,[S(`span`,null,a(o(h)(`knowledge.workspace.inspector.replacement`)),1),S(`strong`,null,a(q.value?o(h)(`knowledge.workspace.inspector.replacedBy`):o(h)(`knowledge.workspace.inspector.noReplacement`)),1)]),q.value?(s(),x(`button`,{key:0,class:`inspector-replacement-link`,type:`button`,onClick:i[0]||=e=>c(`openReplacement`,q.value)},[S(`span`,null,[S(`strong`,null,a(q.value.title),1),S(`small`,null,a(q.value.body),1)]),S(`b`,null,a(o(h)(`knowledge.workspace.inspector.viewReplacement`)),1)])):t.item.replacedByItemId?(s(),x(`p`,Ue,a(o(h)(`knowledge.workspace.inspector.replacementOutOfScope`)),1)):(s(),x(`p`,We,a(o(h)(`knowledge.workspace.inspector.missingReplacement`)),1))])):e(``,!0),S(`dl`,Ge,[S(`div`,null,[S(`dt`,null,a(o(h)(`knowledge.workspace.inspector.fields.type`)),1),S(`dd`,null,a(t.item.type),1)]),_.value?e(``,!0):(s(),x(`div`,Ke,[S(`dt`,null,a(o(h)(`knowledge.workspace.inspector.fields.originQuadrant`)),1),S(`dd`,null,a(o(j)(t.item.originQuadrant)),1)])),_.value?e(``,!0):(s(),x(`div`,qe,[S(`dt`,null,a(o(h)(`knowledge.workspace.inspector.fields.currentQuadrant`)),1),S(`dd`,null,a(o(j)(t.item.currentQuadrant)),1)])),_.value?e(``,!0):(s(),x(`div`,Je,[S(`dt`,null,a(o(h)(`knowledge.workspace.inspector.fields.quadrantExplanation`)),1),S(`dd`,null,a(o(V)(t.item.originQuadrant)),1)])),_.value?e(``,!0):(s(),x(`div`,Ye,[S(`dt`,null,a(o(h)(`knowledge.workspace.inspector.fields.confirmationStatus`)),1),S(`dd`,null,a(o(k)(t.item)),1)])),_.value?e(``,!0):(s(),x(`div`,Xe,[S(`dt`,null,a(o(h)(`knowledge.workspace.inspector.fields.confidence`)),1),S(`dd`,null,a(Y(t.item.confidenceScore)),1)])),_.value?e(``,!0):(s(),x(`div`,Ze,[S(`dt`,null,a(o(h)(`knowledge.workspace.inspector.fields.utility`)),1),S(`dd`,null,a(Y(t.item.utilityScore)),1)])),_.value?e(``,!0):(s(),x(`div`,Qe,[S(`dt`,null,a(o(h)(`knowledge.workspace.inspector.fields.materialUse`)),1),S(`dd`,null,a(o(h)(`knowledge.workspace.inspector.useCount`,{uses:t.item.qualifiedUseCount,tasks:t.item.distinctTaskCount})),1)])),_.value?e(``,!0):(s(),x(`div`,$e,[S(`dt`,null,a(o(h)(`knowledge.workspace.inspector.fields.recentUse`)),1),S(`dd`,null,a(o(L)(t.item.lastUsedAt)),1)])),!_.value&&!t.item.profileAspect?(s(),x(`div`,et,[S(`dt`,null,a(o(h)(`knowledge.workspace.inspector.fields.inheritance`)),1),S(`dd`,null,a(re(t.item)),1)])):e(``,!0),!_.value&&t.item.profileAspect?(s(),x(`div`,tt,[S(`dt`,null,a(o(h)(`knowledge.workspace.inspector.fields.preference`)),1),S(`dd`,null,a(o(A)(t.item.profileAspect)),1)])):e(``,!0),!_.value&&t.item.profileAspect?(s(),x(`div`,nt,[S(`dt`,null,a(o(h)(`knowledge.workspace.inspector.fields.effectiveScope`)),1),S(`dd`,null,a(t.item.preferenceScope===`project`?o(h)(`knowledge.workspace.inspector.selectedProject`):o(h)(`knowledge.workspace.inspector.personalGlobal`)),1)])):e(``,!0),d.value?(s(),x(C,{key:11},[S(`div`,null,[S(`dt`,null,a(o(h)(`knowledge.workspace.inspector.fields.source`)),1),S(`dd`,null,a(f.value.get(o(z)(d.value.source))??o(z)(d.value.source)),1)]),S(`div`,null,[S(`dt`,null,a(o(h)(`knowledge.workspace.inspector.fields.target`)),1),S(`dd`,null,a(f.value.get(o(z)(d.value.target))??o(z)(d.value.target)),1)])],64)):e(``,!0),_.value?e(``,!0):(s(),x(`div`,rt,[S(`dt`,null,a(o(h)(`knowledge.workspace.inspector.fields.status`)),1),S(`dd`,null,a(t.item.invalidAt?o(h)(`knowledge.workspace.inspector.historical`):o(h)(`common.status.current`)),1)]))]),_.value?e(``,!0):(s(),x(C,{key:4},[S(`h4`,it,a(o(h)(`knowledge.workspace.inspector.basisTitle`)),1),G.value?(s(),x(`dl`,at,[S(`div`,null,[S(`dt`,null,a(o(h)(`knowledge.workspace.inspector.basis.existence`)),1),S(`dd`,null,a(G.value.existence_reason),1)]),S(`div`,null,[S(`dt`,null,a(o(h)(`knowledge.workspace.inspector.basis.quadrant`)),1),S(`dd`,null,a(G.value.quadrant_reason),1)]),S(`div`,null,[S(`dt`,null,a(o(h)(`knowledge.workspace.inspector.basis.proposer`)),1),S(`dd`,null,a(o(I)(G.value.proposed_by)),1)]),S(`div`,null,[S(`dt`,null,a(o(h)(`knowledge.workspace.inspector.basis.confirmer`)),1),S(`dd`,null,a(o(I)(G.value.confirmed_by)),1)]),S(`div`,null,[S(`dt`,null,a(o(h)(`knowledge.workspace.inspector.basis.time`)),1),S(`dd`,null,a(o(L)(G.value.confirmed_at)),1)]),G.value.agent_policy_version?(s(),x(`div`,ot,[S(`dt`,null,a(o(h)(`knowledge.workspace.inspector.basis.agentPolicy`)),1),S(`dd`,null,a(G.value.agent_policy_version),1)])):e(``,!0)])):(s(),x(`p`,st,a(o(h)(`knowledge.workspace.inspector.legacyBasis`)),1))],64)),g.value.length?(s(),x(C,{key:5},[S(`h4`,ct,a(o(h)(`knowledge.workspace.inspector.contentDetails`)),1),S(`dl`,lt,[(s(!0),x(C,null,r(g.value,([e,t])=>(s(),x(`div`,{key:e},[S(`dt`,null,a(e),1),S(`dd`,null,a(J(t)),1)]))),128))])],64)):e(``,!0),t.item.reasoningSummary?(s(),x(C,{key:6},[S(`h4`,ut,a(o(h)(`knowledge.workspace.inspector.formation`)),1),S(`p`,dt,a(t.item.reasoningSummary),1)],64)):e(``,!0),ee.value?(s(),x(`div`,ft,[E.value?(s(),x(`button`,{key:0,class:`primary-action inspector-confirm-action`,type:`button`,onClick:i[1]||=e=>c(`confirm`,t.item)},a(t.item.profileAspect?o(h)(`knowledge.workspace.inspector.confirmPreference`):o(h)(`knowledge.workspace.inspector.confirmKnowledge`)),1)):e(``,!0),U.value?(s(),x(`button`,{key:1,class:`primary-action`,type:`button`,onClick:i[2]||=e=>c(`manageProject`,t.item)},a(o(h)(`knowledge.workspace.inspector.editMaterials`)),1)):e(``,!0),t.mode===`graph`?(s(),x(`button`,{key:2,class:`secondary-action`,type:`button`,onClick:i[3]||=e=>c(`openDirectory`,t.item)},a(o(h)(`knowledge.workspace.inspector.locateDirectory`)),1)):e(``,!0),t.mode===`directory`?(s(),x(`button`,{key:3,class:`secondary-action`,type:`button`,onClick:i[4]||=e=>c(`openGraph`,t.item)},a(o(h)(`knowledge.workspace.inspector.locateGraph`)),1)):e(``,!0),b.value&&y.value&&y.value!==t.currentProjectId?(s(),x(`button`,{key:4,class:`primary-action`,type:`button`,onClick:i[5]||=e=>c(`openProject`,y.value)},a(o(h)(`knowledge.workspace.inspector.enterProject`)),1)):e(``,!0),b.value&&y.value&&t.canPublishProject?(s(),x(`button`,{key:5,class:`secondary-action`,type:`button`,onClick:i[6]||=e=>c(`publishProject`,y.value)},a(o(h)(`knowledge.workspace.inspector.publish`)),1)):e(``,!0),w.value?(s(),x(`button`,{key:6,class:`primary-action`,type:`button`,onClick:i[7]||=e=>c(`createProject`,t.item)},a(o(h)(`knowledge.workspace.inspector.createProject`)),1)):e(``,!0),T.value?(s(),x(`button`,{key:7,class:`secondary-action inspector-edit-action`,type:`button`,onClick:i[8]||=e=>c(`edit`,t.item)},a(t.item.profileAspect?o(h)(`knowledge.workspace.inspector.correctPreference`):o(h)(`knowledge.workspace.inspector.correctOrAssign`)),1)):e(``,!0)])):e(``,!0),p.value.length?(s(),x(C,{key:8},[S(`h4`,pt,a(o(h)(`knowledge.workspace.inspector.relations`)),1),S(`div`,mt,[(s(!0),x(C,null,r(p.value,e=>(s(),x(`div`,{key:e.id,class:`inspector-relation`},[S(`strong`,ht,a(e.type),1),S(`p`,gt,a(e.fact||o(h)(`knowledge.workspace.inspector.relationshipFallback`)),1)]))),128))])],64)):e(``,!0),t.item.evidence.length?(s(),x(C,{key:9},[S(`h4`,_t,a(o(h)(`knowledge.workspace.inspector.evidence`)),1),S(`div`,vt,[(s(!0),x(C,null,r(t.item.evidence,(t,n)=>(s(),x(`article`,{key:X(t,n),class:`evidence-card`},[S(`strong`,null,a(t.name||t.source_description||o(h)(`knowledge.workspace.inspector.sourceRecord`)),1),S(`p`,null,a(t.summary||t.source_description),1),S(`span`,null,a(o(Fe)(t))+` · `+a(t.source_kind||o(h)(`knowledge.workspace.inspector.source`))+` · `+a(o(L)(t.reference_time||t.created_at)),1),t.source_excerpt?(s(),x(`p`,yt,a(t.source_excerpt),1)):e(``,!0),o(Q)(t)?(s(),x(`a`,{key:1,class:`evidence-source-action`,href:o(Q)(t)??void 0},a(o(h)(`knowledge.workspace.inspector.openConversation`)),9,bt)):t.session_id?(s(),x(`button`,{key:2,class:`evidence-source-action`,type:`button`,onClick:e=>ie(t,n)},a(K.value===X(t,n)?o(h)(`knowledge.workspace.inspector.copiedSessionId`):o(h)(`knowledge.workspace.inspector.copySessionId`)),9,xt)):e(``,!0)]))),128))])],64)):e(``,!0),t.item.revisions.length?(s(),x(C,{key:10},[S(`h4`,St,a(o(h)(`knowledge.workspace.inspector.revisions`)),1),S(`div`,Ct,[(s(!0),x(C,null,r(t.item.revisions,(e,t)=>(s(),x(`article`,{key:String(e.id??t),class:`history-row`},[S(`strong`,null,a(o(O)(e.action)),1),S(`p`,null,a(e.reason??e.summary??o(h)(`knowledge.workspace.inspector.noRevisionCopy`)),1),S(`span`,null,a(o(L)(e.created_at)),1)]))),128))])],64)):e(``,!0),t.item.auditEvents.length?(s(),x(C,{key:11},[S(`h4`,wt,a(o(h)(`knowledge.workspace.inspector.audit`)),1),S(`div`,Tt,[(s(!0),x(C,null,r(t.item.auditEvents,t=>(s(),x(`article`,{key:t.id,class:`history-row`},[S(`strong`,null,a(o(N)(t.action)),1),S(`p`,null,a(t.reason),1),S(`span`,null,a(o(h)(`knowledge.workspace.inspector.version`,{version:t.human_change_version}))+` · `+a(o(L)(t.created_at)),1),t.action===`agent_review`?(s(),x(`small`,Et,a(o(h)(`knowledge.workspace.inspector.conflictClassification`,{conflict:t.conflict_check===`no_conflict`?o(h)(`knowledge.workspace.inspector.conflictNone`):o(h)(`knowledge.workspace.inspector.conflictFound`),classification:t.classification_check===`reasonable`?o(h)(`knowledge.workspace.inspector.classificationReasonable`):o(h)(`knowledge.workspace.inspector.classificationAdjust`)})),1)):e(``,!0)]))),128))])],64)):e(``,!0)],64)):(s(),x(C,{key:1},[S(`p`,Dt,a(o(h)(`knowledge.workspace.inspector.contentDetails`)),1),S(`h3`,null,a(o(h)(`knowledge.workspace.inspector.placeholderTitle`)),1),S(`p`,Ot,a(o(h)(`knowledge.workspace.inspector.placeholderCopy`)),1)],64))]))}});export{U as i,Me as n,X as r,kt as t};
@@ -1 +0,0 @@
1
- .knowledge-confirm-dialog[data-v-26170b1a]{width:min(680px,100vw - 48px)}.knowledge-confirm-dialog-shell[data-v-26170b1a]{gap:18px;padding:24px;display:grid}.knowledge-confirm-summary[data-v-26170b1a]{border-top:1px solid #e1e5e2;border-bottom:1px solid #e1e5e2;gap:6px;padding:14px 0;display:grid}.knowledge-confirm-summary span[data-v-26170b1a],.knowledge-confirm-summary small[data-v-26170b1a]{color:#7d8780;font-size:10px}.knowledge-confirm-summary strong[data-v-26170b1a]{color:#29382f;font-size:16px}.knowledge-confirm-summary p[data-v-26170b1a]{color:#606b63;font-size:12px;line-height:1.65}.knowledge-confirm-fields[data-v-26170b1a]{gap:14px;display:grid}.knowledge-confirm-fields label[data-v-26170b1a]{color:#59645c;gap:6px;font-size:11px;font-weight:600;display:grid}.knowledge-confirm-acknowledgement[data-v-26170b1a]{color:#4e5c53;grid-template-columns:auto minmax(0,1fr);align-items:start;gap:9px;font-size:11px;line-height:1.5;display:grid}