fuli-context 0.5.0 → 0.7.3
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.
- package/README.md +370 -202
- package/README.zh-CN.md +448 -0
- package/compose.graphiti.yml +6 -6
- package/dist/web/assets/AboutPage-DXh7Fwxt.css +1 -0
- package/dist/web/assets/AboutPage-qeO_vm0T.js +1 -0
- package/dist/web/assets/ConnectionsPage-CBHAdZXT.css +1 -0
- package/dist/web/assets/ConnectionsPage-DO0GR9Xg.js +1 -0
- package/dist/web/assets/KnowledgeInspector-Bjhdu2mf.css +1 -0
- package/dist/web/assets/KnowledgeInspector-DEW5lA1m.js +1 -0
- package/dist/web/assets/KnowledgeOrganizerPage-BkM568Ld.js +1 -0
- package/dist/web/assets/KnowledgeOrganizerPage-Cx1w1jb2.css +1 -0
- package/dist/web/assets/KnowledgePage-BAT4aZIm.js +1 -0
- package/dist/web/assets/KnowledgeWorkspace-DyGtBz--.js +4 -0
- package/dist/web/assets/OverviewPage-CmCcDCAs.js +1 -0
- package/dist/web/assets/PersonalProfilePage-C42mwKN8.js +1 -0
- package/dist/web/assets/{PersonalProfilePage-S8ZcG2LU.css → PersonalProfilePage-CdmEzyvZ.css} +1 -1
- package/dist/web/assets/PersonalProjectsPage-BwaXR62K.js +1 -0
- package/dist/web/assets/PublicProjectsPage-egKBulOq.js +1 -0
- package/dist/web/assets/ReviewPage-B3vnZ6gn.js +1 -0
- package/dist/web/assets/SearchableSelect-ih69qbcS.js +1 -0
- package/dist/web/assets/SettingsPage-C6ouU0sR.css +1 -0
- package/dist/web/assets/SettingsPage-oLE8mNs5.js +1 -0
- package/dist/web/assets/_plugin-vue_export-helper-BDNMzG2s.js +1 -0
- package/dist/web/assets/console-DE40hXGC.js +1 -0
- package/dist/web/assets/fuli-logo-Bu9WBuQe.js +1 -0
- package/dist/web/assets/fuli-logo-ER1wQ8Kk.png +0 -0
- package/dist/web/assets/i18n-CDxBs1sz.js +5 -0
- package/dist/web/assets/identity-BCxb1mcy.js +1 -0
- package/dist/web/assets/index-BzhNfzU_.js +2 -0
- package/dist/web/assets/index-CCOGfZzE.css +1 -0
- package/dist/web/assets/model-CCMdt10Q.js +1 -0
- package/dist/web/assets/paths-DwHeiGMT.js +1 -0
- package/dist/web/assets/useMinimumLoadingDisplay-BpCyBeko.css +1 -0
- package/dist/web/assets/useMinimumLoadingDisplay-HdI7XAmu.js +1 -0
- package/dist/web/assets/vue-router-Drfl1F8i.js +1 -0
- package/dist/web/index.html +9 -6
- package/docs/external-knowledge-architecture.md +279 -0
- package/examples/external-knowledge/markdown-folder.mjs +235 -0
- package/graph-provider/fuli_graph/app.py +57 -1
- package/graph-provider/fuli_graph/graph_models.py +3 -0
- package/graph-provider/fuli_graph/graph_query.py +62 -16
- package/graph-provider/fuli_graph/knowledge_review.py +657 -0
- package/graph-provider/fuli_graph/knowledge_review_models.py +133 -0
- package/graph-provider/fuli_graph/knowledge_search.py +51 -4
- package/graph-provider/fuli_graph/models.py +19 -0
- package/graph-provider/fuli_graph/runtime.py +15 -0
- package/graph-provider/fuli_graph/store_knowledge.py +2 -1
- package/graph-provider/pyproject.toml +1 -1
- package/npm-shrinkwrap.json +5 -407
- package/package.json +7 -5
- package/skills/capturing-session-knowledge/SKILL.md +24 -4
- package/skills/flreview/SKILL.md +100 -0
- package/skills/flreview/agents/openai.yaml +6 -0
- package/src/agent-tools/graph-definitions.js +81 -6
- package/src/agent-tools/graph-handlers.js +12 -0
- package/src/cli/command-registry.js +3 -3
- package/src/cli/local-runtime-command.js +51 -28
- package/src/cli/local-runtime-options.js +14 -8
- package/src/cli/setup-agent-selection.js +12 -12
- package/src/cli/setup-command.js +41 -18
- package/src/cli/shell-argument.js +10 -0
- package/src/cli/uninstall-command.js +17 -15
- package/src/cli/update-command.js +38 -30
- package/src/external-knowledge/catalog.js +61 -0
- package/src/external-knowledge/conflict-policy.js +58 -0
- package/src/external-knowledge/connected-search.js +166 -0
- package/src/external-knowledge/connectors/custom.js +133 -0
- package/src/external-knowledge/connectors/feishu.js +461 -0
- package/src/external-knowledge/connectors/mcp.js +438 -0
- package/src/external-knowledge/connectors/notion.js +307 -0
- package/src/external-knowledge/connectors/retrieval-api.js +222 -0
- package/src/external-knowledge/document-mapping.js +151 -0
- package/src/external-knowledge/graph-projection.js +17 -0
- package/src/external-knowledge/index.js +8 -0
- package/src/external-knowledge/registry.js +91 -0
- package/src/external-knowledge/runtime.js +68 -0
- package/src/external-knowledge/safe-diagnostic.js +14 -0
- package/src/external-knowledge/service.js +811 -0
- package/src/graphiti/agent-knowledge-workflows.js +7 -2
- package/src/graphiti/federated-application.js +68 -42
- package/src/graphiti/knowledge-item-role.js +21 -0
- package/src/graphiti/knowledge-review.js +43 -0
- package/src/graphiti/project-profile-mapping.js +32 -0
- package/src/graphiti/provider-client.js +22 -1
- package/src/graphiti/source-marker.js +54 -3
- package/src/graphiti/task-knowledge-recall.js +250 -0
- package/src/http/api-router.js +23 -108
- package/src/http/external-knowledge-api-router.js +104 -0
- package/src/http/graph-api-router.js +12 -1
- package/src/http/request-policy.js +1 -1
- package/src/local-runtime/lifecycle.js +26 -15
- package/src/mcp/create-mcp-server.js +4 -1
- package/src/mcp/instructions.js +7 -7
- package/src/mcp/tool-annotations.js +6 -0
- package/src/mcp/tool-result.js +1 -0
- package/src/server/application-lifecycle.js +2 -11
- package/src/server/blocked-ports.js +11 -0
- package/src/server.js +36 -17
- package/src/setup/agent-installation-status.js +2 -1
- package/src/setup/agents.js +2 -1
- package/src/setup/claude-code-config.js +2 -1
- package/src/setup/codex-bootstrap.js +12 -7
- package/src/setup/container-runtime.js +25 -21
- package/src/setup/graph-runtime.js +148 -56
- package/src/setup/node-runtime.js +3 -3
- package/src/setup/options.js +2 -4
- package/src/setup/paths.js +18 -3
- package/src/setup/review-skill-adapters.js +49 -0
- package/src/setup/setup.js +26 -2
- package/src/setup/uninstall.js +4 -2
- package/src/system/resource-monitor.js +317 -0
- package/src/system/runtime-settings.js +131 -0
- package/src/system/system-service.js +119 -0
- package/README.en.md +0 -336
- package/dist/web/assets/ConnectionsPage-CCKWm-6p.js +0 -1
- package/dist/web/assets/KnowledgeInspector-BZkB2wJn.js +0 -1
- package/dist/web/assets/KnowledgeInspector-CrGYxEob.css +0 -1
- package/dist/web/assets/KnowledgeOrganizerPage-CZAF_OlN.css +0 -1
- package/dist/web/assets/KnowledgeOrganizerPage-DlvcLwlL.js +0 -1
- package/dist/web/assets/KnowledgePage-CNQXd15y.js +0 -1
- package/dist/web/assets/KnowledgeWorkspace-CXPE4GCD.js +0 -4
- package/dist/web/assets/OverviewPage-ul7g7HXh.js +0 -1
- package/dist/web/assets/PersonalProfilePage-CC40Pw2L.js +0 -1
- package/dist/web/assets/PersonalProjectsPage-CPIEcShD.js +0 -1
- package/dist/web/assets/PublicProjectsPage-C700sR7z.js +0 -1
- package/dist/web/assets/ReviewPage-7MDDUDgA.js +0 -1
- package/dist/web/assets/console-B_Ena2DS.js +0 -5
- package/dist/web/assets/fuli-logo-DGuyqchQ.png +0 -0
- package/dist/web/assets/identity-CjBwYSMX.js +0 -1
- package/dist/web/assets/index-CpLDx3of.css +0 -1
- package/dist/web/assets/index-DAzeFJSc.js +0 -2
- package/dist/web/assets/model-C-5RVIJ2.js +0 -1
- package/dist/web/assets/paths-BkULqmGI.js +0 -1
- package/dist/web/assets/vue-router-DnD3hUm7.js +0 -1
- package/src/agent/candidate-read-service.js +0 -53
- package/src/agent/context-pack-service.js +0 -83
- package/src/agent/public-read-policy.js +0 -39
- package/src/agent/public-read-service.js +0 -69
- package/src/agent/read-projection.js +0 -107
- package/src/agent/search-service.js +0 -61
- package/src/agent/space-boundary.js +0 -33
- package/src/app/bootstrap.js +0 -8
- package/src/app/create-application.js +0 -143
- package/src/app/state-service.js +0 -38
- package/src/candidates.js +0 -78
- package/src/classifier.js +0 -63
- package/src/cli/command-arguments.js +0 -14
- package/src/context-pack.js +0 -206
- package/src/extractor.js +0 -77
- package/src/fact-history.js +0 -39
- package/src/facts/fact-service.js +0 -89
- package/src/http/bounded-json-array.js +0 -19
- package/src/http/lens-route.js +0 -50
- package/src/ingestion.js +0 -161
- package/src/lens/lens-correction-service.js +0 -81
- package/src/lens/lens-fact-writer.js +0 -85
- package/src/lens/lens-input.js +0 -62
- package/src/lens/lens-query-projection.js +0 -87
- package/src/lens/lens-query-ranking.js +0 -62
- package/src/lens/lens-query.js +0 -143
- package/src/lens/lens-resource-projection.js +0 -93
- package/src/lens/lens-resource-selection.js +0 -45
- package/src/lens/lens-resource-service.js +0 -103
- package/src/lens/lens-search-query.js +0 -122
- package/src/lens/lens-service.js +0 -183
- package/src/models.js +0 -44
- package/src/observer.js +0 -83
- package/src/project-rules.js +0 -33
- package/src/publication/outbox-service.js +0 -46
- package/src/publication/publication-envelope-schema.js +0 -75
- package/src/publication/publication-envelope.js +0 -37
- package/src/publication/publication-policy.js +0 -82
- package/src/publication/publication-service.js +0 -48
- package/src/router.js +0 -58
- package/src/runtime-options.js +0 -138
- package/src/security/episode-visibility.js +0 -14
- package/src/security/fact-visibility.js +0 -15
- package/src/security/source-metadata-policy.js +0 -8
- package/src/storage/episode-evidence-preview.js +0 -100
- package/src/storage/fact-search-order.js +0 -18
- package/src/storage/file/episode-evidence.js +0 -37
- package/src/storage/file/episode-index.js +0 -59
- package/src/storage/file/fact-search.js +0 -60
- package/src/storage/file-store.js +0 -437
- package/src/storage/migrate.js +0 -128
- package/src/storage/migrations/001-initial.sql +0 -83
- package/src/storage/migrations/002-storage-integrity.sql +0 -113
- package/src/storage/record-validation.js +0 -46
- package/src/storage/snapshot-defaults.js +0 -54
- package/src/storage/sqlite/candidates-repository.js +0 -84
- package/src/storage/sqlite/episode-evidence-repository.js +0 -154
- package/src/storage/sqlite/episode-privacy-sql.js +0 -33
- package/src/storage/sqlite/episodes-repository.js +0 -52
- package/src/storage/sqlite/fact-search-repository.js +0 -162
- package/src/storage/sqlite/facts-repository.js +0 -146
- package/src/storage/sqlite/imports-repository.js +0 -39
- package/src/storage/sqlite/mapper.js +0 -84
- package/src/storage/sqlite/open-database.js +0 -15
- package/src/storage/sqlite/outbox-repository.js +0 -103
- package/src/storage/sqlite/snapshot-repository.js +0 -69
- package/src/storage/sqlite/spaces-repository.js +0 -52
- package/src/storage/sqlite/subscriptions-repository.js +0 -54
- package/src/storage/sqlite-store.js +0 -159
- package/src/storage/stable-json.js +0 -24
- package/src/storage/store-port.js +0 -20
- package/src/store.js +0 -2
package/src/mcp/instructions.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export const MCP_INSTRUCTIONS = [
|
|
2
|
-
"Each user task:
|
|
3
|
-
'
|
|
4
|
-
'Before claiming facts unknown, use search_knowledge_graph. Use exact IDs for extra projects
|
|
5
|
-
'Use record_decision_trace for confirmed choices
|
|
6
|
-
'Batch durable confirmed knowledge via capture_session_knowledge in exact scope
|
|
7
|
-
'
|
|
8
|
-
'Terminal-safe Markdown. Final MUST begin with sourceMarker.leadMarkdown; append sourceMarker.markdown unchanged
|
|
2
|
+
"Each user task: apply hook-provided task context from begin_task_context. Otherwise, before other tools/answer, call exactly get_collaboration_preferences with projectPath=cwd and taskPrompt=current user request as fallback; never substitute a project action/Fuli tool. Apply all effective_preferences: personal-global everywhere plus only Fuli's matched project. Resolve relevant deferred_conflict first. Never guess personalProjectId. Writes enforce preferences in the actual payload; final text is not compliance.",
|
|
3
|
+
'Before asking the user to repeat a stable project fact or method, inspect task_knowledge_recall. On miss use search_current_project_knowledge with 1-4 focused action, artifact, target-system, or identifier queries; never use the whole conversational request as the only query. Search the exact active child first, then inheritable parent PART_OF/USES_KNOWLEDGE_FROM knowledge within two hops; child stable keys override. Never inherit project preferences or traverse RELATED_TO.',
|
|
4
|
+
'Before claiming facts unknown, use search_knowledge_graph. Use exact IDs for extra projects. Widen a miss to all_local_confirmed only after consent, then rg only in the safe current repo/workspace. Never scan outside it. Live state needs deployment/monitoring/Git MCP evidence. External/public evidence: search_connected_knowledge; agent_decide is response-only.',
|
|
5
|
+
'Use record_decision_trace for confirmed choices and record_knowledge_feedback when knowledge is rejected, contradicted, outdated, or fails validation.',
|
|
6
|
+
'Batch durable confirmed knowledge via capture_session_knowledge in exact scope; never secrets, transcripts, or guesses. Finish once with checkpoint_task_knowledge: capture_candidates or retain_nothing.',
|
|
7
|
+
'After material personal-knowledge use call record_knowledge_usage; retrieval alone never counts or permits public use.',
|
|
8
|
+
'Terminal-safe Markdown. Final MUST begin with sourceMarker.leadMarkdown; append sourceMarker.markdown unchanged on match. On miss use noMatchSourceMarker leadMarkdown only (empty markdown). Never wrap markers in HTML.'
|
|
9
9
|
].join(' ');
|
|
@@ -5,6 +5,7 @@ const READ_TOOLS = new Set([
|
|
|
5
5
|
'preview_common_knowledge_promotion',
|
|
6
6
|
'list_knowledge_spaces',
|
|
7
7
|
'list_personal_projects',
|
|
8
|
+
'list_knowledge_review_candidates',
|
|
8
9
|
'preview_personal_project_action',
|
|
9
10
|
'list_project_releases',
|
|
10
11
|
'list_project_relations',
|
|
@@ -21,6 +22,7 @@ const WRITE_TOOLS = new Set([
|
|
|
21
22
|
'capture_session_knowledge',
|
|
22
23
|
'record_decision_trace',
|
|
23
24
|
'search_knowledge_graph',
|
|
25
|
+
'search_connected_knowledge',
|
|
24
26
|
'record_knowledge_usage',
|
|
25
27
|
'record_knowledge_feedback',
|
|
26
28
|
'apply_common_knowledge_promotion',
|
|
@@ -28,6 +30,9 @@ const WRITE_TOOLS = new Set([
|
|
|
28
30
|
'search_human_knowledge_changes',
|
|
29
31
|
'review_human_knowledge_change',
|
|
30
32
|
'upsert_personal_project',
|
|
33
|
+
'start_knowledge_review',
|
|
34
|
+
'record_knowledge_review_progress',
|
|
35
|
+
'finish_knowledge_review',
|
|
31
36
|
'revise_personal_knowledge',
|
|
32
37
|
'reassign_personal_knowledge',
|
|
33
38
|
'set_personal_preference_scope',
|
|
@@ -64,6 +69,7 @@ export function annotationsFor(name) {
|
|
|
64
69
|
name === 'record_knowledge_feedback' ||
|
|
65
70
|
name === 'checkpoint_task_knowledge',
|
|
66
71
|
openWorldHint: name === 'capture_session_knowledge' ||
|
|
72
|
+
name === 'search_connected_knowledge' ||
|
|
67
73
|
name === 'record_decision_trace' ||
|
|
68
74
|
name === 'record_knowledge_feedback' ||
|
|
69
75
|
name === 'checkpoint_task_knowledge' ||
|
package/src/mcp/tool-result.js
CHANGED
|
@@ -1,21 +1,12 @@
|
|
|
1
|
-
import { createApplication } from '../app/create-application.js';
|
|
2
1
|
import { openFederatedGraphApplication } from '../graphiti/federated-application.js';
|
|
3
|
-
import { openLocalApplication } from '../runtime-options.js';
|
|
4
2
|
|
|
5
3
|
export function createServerApplication({
|
|
6
4
|
app,
|
|
7
|
-
store,
|
|
8
|
-
dbPath,
|
|
9
5
|
runtimeConfigPath,
|
|
10
|
-
personalSpaceName,
|
|
11
6
|
closeApplicationOnShutdown
|
|
12
7
|
}) {
|
|
13
|
-
const application = app ?? (
|
|
14
|
-
|
|
15
|
-
: dbPath
|
|
16
|
-
? openLocalApplication({ dbPath, personalSpaceName })
|
|
17
|
-
: openFederatedGraphApplication({ runtimeConfigPath }));
|
|
18
|
-
const owned = closeApplicationOnShutdown ?? (!app && !store);
|
|
8
|
+
const application = app ?? openFederatedGraphApplication({ runtimeConfigPath });
|
|
9
|
+
const owned = closeApplicationOnShutdown ?? !app;
|
|
19
10
|
return {
|
|
20
11
|
application,
|
|
21
12
|
close: closeOnce(() => {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const FETCH_BLOCKED_PORTS = new Set([
|
|
2
|
+
1, 7, 9, 11, 13, 15, 17, 19, 20, 21, 22, 23, 25, 37, 42, 43, 53, 69, 77, 79, 87, 95,
|
|
3
|
+
101, 102, 103, 104, 109, 110, 111, 113, 115, 117, 119, 123, 135, 137, 139, 143, 161, 179, 389,
|
|
4
|
+
427, 465, 512, 513, 514, 515, 526, 530, 531, 532, 540, 548, 554, 556, 563, 587, 601, 636,
|
|
5
|
+
989, 990, 993, 995, 1719, 1720, 1723, 2049, 3659, 4045, 4190, 5060, 5061, 6000, 6566,
|
|
6
|
+
6665, 6666, 6667, 6668, 6669, 6697, 10080
|
|
7
|
+
]);
|
|
8
|
+
|
|
9
|
+
export function isFetchBlockedPort(port) {
|
|
10
|
+
return FETCH_BLOCKED_PORTS.has(Number(port));
|
|
11
|
+
}
|
package/src/server.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createServer as createHttpServer } from 'node:http';
|
|
3
|
+
import { dirname } from 'node:path';
|
|
3
4
|
import { fileURLToPath } from 'node:url';
|
|
4
5
|
|
|
5
6
|
import { handleApiRequest } from './http/api-router.js';
|
|
@@ -9,6 +10,7 @@ import { sendJson } from './http/response.js';
|
|
|
9
10
|
import { serveStatic } from './http/static-handler.js';
|
|
10
11
|
import { DEFAULT_FULI_PORT } from './defaults.js';
|
|
11
12
|
import { resolveGraphRuntimeOptions } from './graphiti/runtime-config.js';
|
|
13
|
+
import { isFetchBlockedPort } from './server/blocked-ports.js';
|
|
12
14
|
import {
|
|
13
15
|
discoverLanAddresses,
|
|
14
16
|
lanConsoleUrls,
|
|
@@ -16,19 +18,14 @@ import {
|
|
|
16
18
|
} from './server/lan-access.js';
|
|
17
19
|
import { createServerApplication } from './server/application-lifecycle.js';
|
|
18
20
|
import { listenServer } from './server/listen.js';
|
|
21
|
+
import { resolveSetupPaths } from './setup/paths.js';
|
|
22
|
+
import { createSystemService } from './system/system-service.js';
|
|
19
23
|
|
|
20
|
-
const
|
|
21
|
-
1, 7, 9, 11, 13, 15, 17, 19, 20, 21, 22, 23, 25, 37, 42, 43, 53, 69, 77, 79, 87, 95, 101, 102,
|
|
22
|
-
103, 104, 109, 110, 111, 113, 115, 117, 119, 123, 135, 137, 139, 143, 161, 179, 389, 427, 465,
|
|
23
|
-
512, 513, 514, 515, 526, 530, 531, 532, 540, 548, 554, 556, 563, 587, 601, 636, 989, 990, 993,
|
|
24
|
-
995, 1719, 1720, 1723, 2049, 3659, 4045, 4190, 5060, 5061, 6000, 6566, 6665, 6666, 6667, 6668,
|
|
25
|
-
6669, 6697, 10080
|
|
26
|
-
]);
|
|
24
|
+
const PACKAGE_ROOT = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
27
25
|
|
|
28
26
|
export async function createServer(options = {}) {
|
|
29
27
|
const {
|
|
30
28
|
port = DEFAULT_FULI_PORT,
|
|
31
|
-
store,
|
|
32
29
|
app,
|
|
33
30
|
closeApplicationOnShutdown,
|
|
34
31
|
isBlockedPort = isFetchBlockedPort,
|
|
@@ -47,17 +44,28 @@ export async function createServer(options = {}) {
|
|
|
47
44
|
if (Number(port) !== 0 && isBlockedPort(port)) {
|
|
48
45
|
throw new Error(`Port ${port} is blocked for local fetch`);
|
|
49
46
|
}
|
|
50
|
-
const
|
|
51
|
-
const localOptions = legacyRuntime
|
|
52
|
-
? { dbPath: options.dbPath, personalSpaceName: options.personalSpaceName ?? '我' }
|
|
53
|
-
: resolveServerGraphOptions(options);
|
|
47
|
+
const localOptions = app ? {} : resolveServerGraphOptions(options);
|
|
54
48
|
const runtime = createServerApplication({
|
|
55
49
|
app,
|
|
56
|
-
store,
|
|
57
50
|
...localOptions,
|
|
58
51
|
closeApplicationOnShutdown
|
|
59
52
|
});
|
|
60
53
|
const application = runtime.application;
|
|
54
|
+
const externalKnowledge = options.externalKnowledge ??
|
|
55
|
+
application.externalKnowledge ?? null;
|
|
56
|
+
const connectedKnowledge = options.connectedKnowledge ??
|
|
57
|
+
application.connectedKnowledge ?? null;
|
|
58
|
+
const system = options.system ?? (!app
|
|
59
|
+
? createSystemService({
|
|
60
|
+
paths: resolveSetupPaths({
|
|
61
|
+
dataDir: dirname(localOptions.runtimeConfigPath),
|
|
62
|
+
packageRoot: PACKAGE_ROOT
|
|
63
|
+
}),
|
|
64
|
+
packageRoot: PACKAGE_ROOT,
|
|
65
|
+
activePort: port,
|
|
66
|
+
activeLan: lanEnabled
|
|
67
|
+
})
|
|
68
|
+
: null);
|
|
61
69
|
|
|
62
70
|
for (let attempt = 0; attempt < 20; attempt += 1) {
|
|
63
71
|
let authority = null;
|
|
@@ -67,6 +75,9 @@ export async function createServer(options = {}) {
|
|
|
67
75
|
request,
|
|
68
76
|
response,
|
|
69
77
|
app: application,
|
|
78
|
+
system,
|
|
79
|
+
externalKnowledge,
|
|
80
|
+
connectedKnowledge,
|
|
70
81
|
authority,
|
|
71
82
|
lanAuthorities: allowedLanAuthorities,
|
|
72
83
|
lanAccessToken: lanToken
|
|
@@ -122,14 +133,15 @@ function resolveServerGraphOptions(options) {
|
|
|
122
133
|
});
|
|
123
134
|
}
|
|
124
135
|
|
|
125
|
-
export
|
|
126
|
-
return FETCH_BLOCKED_PORTS.has(Number(port));
|
|
127
|
-
}
|
|
136
|
+
export { isFetchBlockedPort } from './server/blocked-ports.js';
|
|
128
137
|
|
|
129
138
|
async function handleRequest({
|
|
130
139
|
request,
|
|
131
140
|
response,
|
|
132
141
|
app,
|
|
142
|
+
system,
|
|
143
|
+
externalKnowledge,
|
|
144
|
+
connectedKnowledge,
|
|
133
145
|
authority,
|
|
134
146
|
lanAuthorities,
|
|
135
147
|
lanAccessToken
|
|
@@ -141,7 +153,14 @@ async function handleRequest({
|
|
|
141
153
|
lanAuthorities,
|
|
142
154
|
lanAccessToken
|
|
143
155
|
})) return;
|
|
144
|
-
if (await handleApiRequest({
|
|
156
|
+
if (await handleApiRequest({
|
|
157
|
+
request,
|
|
158
|
+
response,
|
|
159
|
+
app,
|
|
160
|
+
system,
|
|
161
|
+
externalKnowledge,
|
|
162
|
+
connectedKnowledge
|
|
163
|
+
})) return;
|
|
145
164
|
serveStatic(new URL(request.url, 'http://127.0.0.1').pathname, response);
|
|
146
165
|
}
|
|
147
166
|
|
|
@@ -17,7 +17,8 @@ export function inspectAgentInstallations(agents, context, {
|
|
|
17
17
|
const registration = inspectRegistration(agent, context, { readText, readJson });
|
|
18
18
|
const skillPairs = [
|
|
19
19
|
[context.sessionSkillPath, agent.skillPath],
|
|
20
|
-
[context.projectSkillPath, agent.projectSkillPath]
|
|
20
|
+
[context.projectSkillPath, agent.projectSkillPath],
|
|
21
|
+
[context.reviewSkillPath, agent.reviewSkillPath]
|
|
21
22
|
];
|
|
22
23
|
const skillsPresent = skillPairs.some(([, targetPath]) => fileExists(targetPath));
|
|
23
24
|
const skillsCurrent = skillPairs.every(
|
package/src/setup/agents.js
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
} from './claude-code-config.js';
|
|
10
10
|
import { connectCursor, disconnectCursor } from './cursor-config.js';
|
|
11
11
|
import { connectCodex, disconnectCodex } from './codex-config.js';
|
|
12
|
+
import { adaptAgentForReviewSkill } from './review-skill-adapters.js';
|
|
12
13
|
|
|
13
14
|
export function discoverAgents({
|
|
14
15
|
platform = process.platform,
|
|
@@ -52,7 +53,7 @@ export function discoverAgents({
|
|
|
52
53
|
projectSkillPath: pathApi.join(homeDir, '.cursor', 'skills', projectSkillName),
|
|
53
54
|
available: Boolean(commandExists('cursor'))
|
|
54
55
|
}
|
|
55
|
-
];
|
|
56
|
+
].map((agent) => adaptAgentForReviewSkill(agent, { homeDir, pathApi }));
|
|
56
57
|
}
|
|
57
58
|
|
|
58
59
|
export function buildAgentCommands(agent, context) {
|
|
@@ -115,7 +115,8 @@ function withManagedHooks(settings) {
|
|
|
115
115
|
...(hooks.UserPromptSubmit ?? []),
|
|
116
116
|
managedHookGroup('begin_task_context', {
|
|
117
117
|
sessionId: '${session_id}',
|
|
118
|
-
projectPath: '${cwd}'
|
|
118
|
+
projectPath: '${cwd}',
|
|
119
|
+
taskPrompt: '${prompt}'
|
|
119
120
|
}, 'Loading Fuli task context')
|
|
120
121
|
];
|
|
121
122
|
hooks.Stop = [
|
|
@@ -9,18 +9,23 @@ import {
|
|
|
9
9
|
} from 'node:fs';
|
|
10
10
|
import { basename, dirname, join } from 'node:path';
|
|
11
11
|
|
|
12
|
+
import { codexReviewCommandBridge } from './review-skill-adapters.js';
|
|
13
|
+
|
|
12
14
|
const BLOCK_START = '<!-- BEGIN FULI MANAGED INSTRUCTIONS -->';
|
|
13
15
|
const BLOCK_END = '<!-- END FULI MANAGED INSTRUCTIONS -->';
|
|
14
16
|
|
|
15
17
|
const GLOBAL_INSTRUCTIONS = `${BLOCK_START}
|
|
16
18
|
At the start of every user task, before any other tool or answer, call exactly
|
|
17
|
-
\`get_collaboration_preferences\` with \`projectPath\`=current working directory
|
|
18
|
-
project action
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
\`get_collaboration_preferences\` with \`projectPath\`=current working directory and
|
|
20
|
+
\`taskPrompt\`=current user request; never substitute a project action/Fuli tool. Fuli uses both
|
|
21
|
+
transiently and never stores or returns them. Apply all returned \`effective_preferences\`.
|
|
22
|
+
Before asking the user to repeat a stable project fact or method, inspect
|
|
23
|
+
\`task_knowledge_recall\`. On miss call \`search_current_project_knowledge\` with 1-4 focused
|
|
24
|
+
action/artifact/target/identifier queries; never use the full request as the only query.
|
|
25
|
+
For write tools enforce them in the actual payload; mentioning them later is not compliance.
|
|
26
|
+
Relevant \`deferred_conflict\`: call \`resolve_deferred_preference_conflict\` first; ignore others.
|
|
27
|
+
Current request wins.
|
|
28
|
+
${codexReviewCommandBridge()}
|
|
24
29
|
${BLOCK_END}`;
|
|
25
30
|
|
|
26
31
|
export function installCodexBootstrap(agent, _context, {
|
|
@@ -86,7 +86,7 @@ export async function ensureContainerRuntime(options = {}, dependencies = {}) {
|
|
|
86
86
|
throw containerRuntimeError(runtime, options.platform ?? process.platform);
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
onProgress(
|
|
89
|
+
onProgress(`Starting ${runtime.desktop.label}; the first launch may take a few minutes...`);
|
|
90
90
|
await launch(runtime.desktop, dependencies);
|
|
91
91
|
|
|
92
92
|
const attempts = Math.max(1, Math.ceil(maxWaitMs / pollIntervalMs));
|
|
@@ -100,9 +100,9 @@ export async function ensureContainerRuntime(options = {}, dependencies = {}) {
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
throw new Error(
|
|
103
|
-
`${runtime.desktop?.label ?? runtime.label}
|
|
104
|
-
|
|
105
|
-
|
|
103
|
+
`${runtime.desktop?.label ?? runtime.label} started, but the container engine was not ready ` +
|
|
104
|
+
`within ${Math.ceil(maxWaitMs / 1000)} seconds. Open the application to inspect errors, ` +
|
|
105
|
+
`confirm that docker info succeeds, then run fl setup again.${detailSuffix(runtime.detail)}`
|
|
106
106
|
);
|
|
107
107
|
}
|
|
108
108
|
|
|
@@ -124,12 +124,14 @@ export function runDockerCompose(args, runtime = null, {
|
|
|
124
124
|
|
|
125
125
|
const detail = safeProcessDetail(result, homeDir);
|
|
126
126
|
if (/port is already allocated|address already in use|bind.+failed/i.test(detail)) {
|
|
127
|
-
throw new Error(`Fuli
|
|
127
|
+
throw new Error(`A local port required by Fuli is already in use.${detailSuffix(detail)}`);
|
|
128
128
|
}
|
|
129
129
|
if (/cannot connect|connection refused|error during connect|docker daemon|\bEOF\b/i.test(detail)) {
|
|
130
|
-
throw new Error(
|
|
130
|
+
throw new Error(
|
|
131
|
+
`The container runtime disconnected while starting the Fuli Provider.${detailSuffix(detail)}`
|
|
132
|
+
);
|
|
131
133
|
}
|
|
132
|
-
throw new Error(`Docker Compose
|
|
134
|
+
throw new Error(`Docker Compose could not start the Fuli Provider.${detailSuffix(detail)}`);
|
|
133
135
|
}
|
|
134
136
|
|
|
135
137
|
export function selectDockerEnvironment({
|
|
@@ -161,19 +163,21 @@ export function containerRuntimeError(runtime, platform = process.platform) {
|
|
|
161
163
|
}
|
|
162
164
|
if (runtime.status === 'missing-compose') {
|
|
163
165
|
return new Error(
|
|
164
|
-
|
|
166
|
+
'Docker was found, but Docker Compose v2 is missing. Install Compose v2, then run ' +
|
|
167
|
+
'fl setup again.' +
|
|
165
168
|
detailSuffix(runtime.detail)
|
|
166
169
|
);
|
|
167
170
|
}
|
|
168
171
|
if (runtime.explicitTarget) {
|
|
169
172
|
return new Error(
|
|
170
|
-
|
|
171
|
-
`docker info
|
|
173
|
+
'The container engine selected by DOCKER_HOST or DOCKER_CONTEXT is unavailable. Fix the ' +
|
|
174
|
+
`configuration, confirm that docker info succeeds, then run fl setup again.${detailSuffix(runtime.detail)}`
|
|
172
175
|
);
|
|
173
176
|
}
|
|
174
177
|
return new Error(
|
|
175
|
-
|
|
176
|
-
|
|
178
|
+
'Docker and Compose were found, but the container engine is not running. Start Docker ' +
|
|
179
|
+
'Desktop, Rancher Desktop, or the current Docker service; confirm that docker info succeeds; ' +
|
|
180
|
+
'then run fl setup again.' +
|
|
177
181
|
detailSuffix(runtime.detail)
|
|
178
182
|
);
|
|
179
183
|
}
|
|
@@ -330,17 +334,17 @@ async function launchDesktopRuntime(desktop, { spawnProcess = spawn } = {}) {
|
|
|
330
334
|
|
|
331
335
|
function missingRuntimeMessage(platform) {
|
|
332
336
|
if (platform === 'darwin') {
|
|
333
|
-
return
|
|
334
|
-
`(${RANCHER_DOWNLOAD_URL})
|
|
335
|
-
|
|
337
|
+
return 'No usable Docker Compose container runtime was detected. Install and open Rancher ' +
|
|
338
|
+
`Desktop (${RANCHER_DOWNLOAD_URL}) or Docker Desktop (${DOCKER_DOWNLOAD_URL}), then run ` +
|
|
339
|
+
'fl setup again.';
|
|
336
340
|
}
|
|
337
341
|
if (platform === 'win32') {
|
|
338
|
-
return
|
|
339
|
-
`Rancher Desktop (${RANCHER_DOWNLOAD_URL})
|
|
340
|
-
`(${DOCKER_DOWNLOAD_URL})
|
|
342
|
+
return 'No usable Docker Compose container runtime was detected. Enable WSL 2, then install ' +
|
|
343
|
+
`and open Rancher Desktop (${RANCHER_DOWNLOAD_URL}) or Docker Desktop ` +
|
|
344
|
+
`(${DOCKER_DOWNLOAD_URL}), and run fl setup again.`;
|
|
341
345
|
}
|
|
342
|
-
return
|
|
343
|
-
|
|
346
|
+
return 'No usable Docker Compose container runtime was detected. Install Docker Engine with ' +
|
|
347
|
+
`Compose v2, or Rancher Desktop (${RANCHER_DOWNLOAD_URL}), then run fl setup again.`;
|
|
344
348
|
}
|
|
345
349
|
|
|
346
350
|
function defaultDockerAvailable(env) {
|
|
@@ -372,7 +376,7 @@ function safeProcessDetail(result, homeDir) {
|
|
|
372
376
|
}
|
|
373
377
|
|
|
374
378
|
function detailSuffix(detail) {
|
|
375
|
-
return nonEmpty(detail) ? ` Docker
|
|
379
|
+
return nonEmpty(detail) ? ` Docker returned: ${detail}` : '';
|
|
376
380
|
}
|
|
377
381
|
|
|
378
382
|
function processSucceeded(result) {
|