@bevel-software/platform-core-backend 0.28.1 → 0.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agent-guide/access-control.md +15 -0
- package/agent-guide/skills.md +8 -0
- package/dist/__tests__/test-repositories.d.ts +3 -0
- package/dist/__tests__/test-repositories.d.ts.map +1 -0
- package/dist/__tests__/test-repositories.js +18 -0
- package/dist/__tests__/test-repositories.js.map +1 -0
- package/dist/core/catalog-revision.d.ts.map +1 -1
- package/dist/core/catalog-revision.js +4 -2
- package/dist/core/catalog-revision.js.map +1 -1
- package/dist/core/compose-embed.d.ts +35 -0
- package/dist/core/compose-embed.d.ts.map +1 -0
- package/dist/core/compose-embed.js +14 -0
- package/dist/core/compose-embed.js.map +1 -0
- package/dist/core/core-ports.d.ts +10 -0
- package/dist/core/core-ports.d.ts.map +1 -1
- package/dist/core/core-ports.js.map +1 -1
- package/dist/core/create-core-server.d.ts.map +1 -1
- package/dist/core/create-core-server.js +8 -2
- package/dist/core/create-core-server.js.map +1 -1
- package/dist/core/create-core-services.d.ts +4 -1
- package/dist/core/create-core-services.d.ts.map +1 -1
- package/dist/core/create-core-services.js +57 -18
- package/dist/core/create-core-services.js.map +1 -1
- package/dist/core/lifecycle.d.ts +19 -6
- package/dist/core/lifecycle.d.ts.map +1 -1
- package/dist/core/lifecycle.js +17 -6
- package/dist/core/lifecycle.js.map +1 -1
- package/dist/modules/access/access-control.interface.d.ts +20 -0
- package/dist/modules/access/access-control.interface.d.ts.map +1 -1
- package/dist/modules/access/access-control.service.d.ts +68 -15
- package/dist/modules/access/access-control.service.d.ts.map +1 -1
- package/dist/modules/access/access-control.service.js +282 -58
- package/dist/modules/access/access-control.service.js.map +1 -1
- package/dist/modules/access/access.routes.d.ts.map +1 -1
- package/dist/modules/access/access.routes.js +20 -6
- package/dist/modules/access/access.routes.js.map +1 -1
- package/dist/modules/agent-instructions/shared-file-rules.d.ts +1 -1
- package/dist/modules/agent-instructions/shared-file-rules.js +1 -1
- package/dist/modules/auth/index.d.ts +15 -0
- package/dist/modules/auth/index.d.ts.map +1 -0
- package/dist/modules/auth/index.js +20 -0
- package/dist/modules/auth/index.js.map +1 -0
- package/dist/modules/diff/diff.service.d.ts.map +1 -1
- package/dist/modules/diff/diff.service.js +7 -1
- package/dist/modules/diff/diff.service.js.map +1 -1
- package/dist/modules/embed/embed.interface.d.ts +22 -0
- package/dist/modules/embed/embed.interface.d.ts.map +1 -1
- package/dist/modules/embed/embed.service.d.ts +28 -14
- package/dist/modules/embed/embed.service.d.ts.map +1 -1
- package/dist/modules/embed/embed.service.js +38 -17
- package/dist/modules/embed/embed.service.js.map +1 -1
- package/dist/modules/embed/embed.tools.d.ts.map +1 -1
- package/dist/modules/embed/embed.tools.js +10 -2
- package/dist/modules/embed/embed.tools.js.map +1 -1
- package/dist/modules/kb-fs/git-dir.d.ts +21 -0
- package/dist/modules/kb-fs/git-dir.d.ts.map +1 -0
- package/dist/modules/kb-fs/git-dir.js +58 -0
- package/dist/modules/kb-fs/git-dir.js.map +1 -0
- package/dist/modules/kb-fs/index.d.ts +9 -0
- package/dist/modules/kb-fs/index.d.ts.map +1 -0
- package/dist/modules/kb-fs/index.js +3 -0
- package/dist/modules/kb-fs/index.js.map +1 -0
- package/dist/modules/kb-fs/ref-files.d.ts +63 -0
- package/dist/modules/kb-fs/ref-files.d.ts.map +1 -0
- package/dist/modules/kb-fs/ref-files.js +249 -0
- package/dist/modules/kb-fs/ref-files.js.map +1 -0
- package/dist/modules/plugins/join-request-jobs.service.d.ts.map +1 -1
- package/dist/modules/plugins/join-request-jobs.service.js +43 -8
- package/dist/modules/plugins/join-request-jobs.service.js.map +1 -1
- package/dist/modules/plugins/teams.routes.d.ts +4 -0
- package/dist/modules/plugins/teams.routes.d.ts.map +1 -1
- package/dist/modules/plugins/teams.routes.js +9 -1
- package/dist/modules/plugins/teams.routes.js.map +1 -1
- package/dist/modules/skills/skills.contract.d.ts.map +1 -1
- package/dist/modules/skills/skills.tools.d.ts +8 -1
- package/dist/modules/skills/skills.tools.d.ts.map +1 -1
- package/dist/modules/skills/skills.tools.js +115 -11
- package/dist/modules/skills/skills.tools.js.map +1 -1
- package/dist/modules/tool-auth/internal-token.service.d.ts +1 -1
- package/dist/modules/tool-auth/tool-auth.middleware.d.ts +1 -2
- package/dist/modules/tool-auth/tool-auth.middleware.d.ts.map +1 -1
- package/dist/modules/tool-auth/tool-auth.middleware.js +1 -2
- package/dist/modules/tool-auth/tool-auth.middleware.js.map +1 -1
- package/dist/modules/tool-helpers/default-branch-write.d.ts +69 -0
- package/dist/modules/tool-helpers/default-branch-write.d.ts.map +1 -0
- package/dist/modules/tool-helpers/default-branch-write.js +63 -0
- package/dist/modules/tool-helpers/default-branch-write.js.map +1 -0
- package/dist/modules/tool-helpers/index.d.ts +1 -0
- package/dist/modules/tool-helpers/index.d.ts.map +1 -1
- package/dist/modules/tool-helpers/index.js +1 -0
- package/dist/modules/tool-helpers/index.js.map +1 -1
- package/dist/modules/tool-helpers/tool-handler.d.ts +2 -2
- package/dist/modules/tool-helpers/tool.contract.d.ts +2 -2
- package/dist/modules/workflow/file-lock.service.d.ts +27 -5
- package/dist/modules/workflow/file-lock.service.d.ts.map +1 -1
- package/dist/modules/workflow/file-lock.service.js +70 -18
- package/dist/modules/workflow/file-lock.service.js.map +1 -1
- package/dist/modules/workflow/git/git.service.d.ts +42 -0
- package/dist/modules/workflow/git/git.service.d.ts.map +1 -1
- package/dist/modules/workflow/git/git.service.js +201 -24
- package/dist/modules/workflow/git/git.service.js.map +1 -1
- package/dist/modules/workflow/index.d.ts +8 -0
- package/dist/modules/workflow/index.d.ts.map +1 -0
- package/dist/modules/workflow/index.js +8 -0
- package/dist/modules/workflow/index.js.map +1 -0
- package/dist/modules/workflow/pending-commits.service.d.ts +2 -17
- package/dist/modules/workflow/pending-commits.service.d.ts.map +1 -1
- package/dist/modules/workflow/pending-commits.service.js +4 -24
- package/dist/modules/workflow/pending-commits.service.js.map +1 -1
- package/dist/modules/workflow/workflow-hooks.d.ts +1 -1
- package/dist/modules/workflow/workflow.routes.d.ts.map +1 -1
- package/dist/modules/workflow/workflow.routes.js +20 -1
- package/dist/modules/workflow/workflow.routes.js.map +1 -1
- package/dist/modules/workflow/workflow.service.d.ts.map +1 -1
- package/dist/modules/workflow/workflow.service.js +5 -3
- package/dist/modules/workflow/workflow.service.js.map +1 -1
- package/dist/modules/workspace/agent-access.gate.d.ts +2 -2
- package/dist/modules/workspace/agent-access.gate.js +2 -2
- package/dist/modules/workspace/bounded-matcher.d.ts +79 -0
- package/dist/modules/workspace/bounded-matcher.d.ts.map +1 -0
- package/dist/modules/workspace/bounded-matcher.js +261 -0
- package/dist/modules/workspace/bounded-matcher.js.map +1 -0
- package/dist/modules/workspace/fetch-instant.d.ts +9 -0
- package/dist/modules/workspace/fetch-instant.d.ts.map +1 -0
- package/dist/modules/workspace/fetch-instant.js +13 -0
- package/dist/modules/workspace/fetch-instant.js.map +1 -0
- package/dist/modules/workspace/index.d.ts +17 -0
- package/dist/modules/workspace/index.d.ts.map +1 -0
- package/dist/modules/workspace/index.js +16 -0
- package/dist/modules/workspace/index.js.map +1 -0
- package/dist/modules/workspace/kb-repository.contract.d.ts +124 -0
- package/dist/modules/workspace/kb-repository.contract.d.ts.map +1 -0
- package/dist/modules/workspace/kb-repository.contract.js +19 -0
- package/dist/modules/workspace/kb-repository.contract.js.map +1 -0
- package/dist/modules/workspace/kb-repository.d.ts +236 -0
- package/dist/modules/workspace/kb-repository.d.ts.map +1 -0
- package/dist/modules/workspace/kb-repository.js +811 -0
- package/dist/modules/workspace/kb-repository.js.map +1 -0
- package/dist/modules/workspace/pattern-matcher.contract.d.ts +50 -0
- package/dist/modules/workspace/pattern-matcher.contract.d.ts.map +1 -0
- package/dist/modules/workspace/pattern-matcher.contract.js +27 -0
- package/dist/modules/workspace/pattern-matcher.contract.js.map +1 -0
- package/dist/modules/workspace/routine-write-policy.d.ts +0 -7
- package/dist/modules/workspace/routine-write-policy.d.ts.map +1 -1
- package/dist/modules/workspace/routine-write-policy.js +0 -5
- package/dist/modules/workspace/routine-write-policy.js.map +1 -1
- package/dist/modules/workspace/set-aside-clone.d.ts +40 -0
- package/dist/modules/workspace/set-aside-clone.d.ts.map +1 -1
- package/dist/modules/workspace/set-aside-clone.js +139 -0
- package/dist/modules/workspace/set-aside-clone.js.map +1 -1
- package/dist/modules/workspace/startup/kb-startup-runner.d.ts +99 -0
- package/dist/modules/workspace/startup/kb-startup-runner.d.ts.map +1 -1
- package/dist/modules/workspace/startup/kb-startup-runner.js +407 -29
- package/dist/modules/workspace/startup/kb-startup-runner.js.map +1 -1
- package/dist/modules/workspace/workspace.service.d.ts +68 -32
- package/dist/modules/workspace/workspace.service.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.service.js +240 -161
- package/dist/modules/workspace/workspace.service.js.map +1 -1
- package/dist/modules/workspace/workspace.tools.d.ts +13 -4
- package/dist/modules/workspace/workspace.tools.d.ts.map +1 -1
- package/dist/modules/workspace/workspace.tools.js +268 -356
- package/dist/modules/workspace/workspace.tools.js.map +1 -1
- package/dist/shared/workspace-id.d.ts +17 -0
- package/dist/shared/workspace-id.d.ts.map +1 -1
- package/dist/shared/workspace-id.js +24 -0
- package/dist/shared/workspace-id.js.map +1 -1
- package/dist/test-setup.js +4 -0
- package/dist/test-setup.js.map +1 -1
- package/mcp-app/page.html +142 -8
- package/package.json +3 -3
- package/src/__tests__/test-repositories.ts +22 -0
- package/src/__tests__/workspace-service.ts +69 -0
- package/src/core/__tests__/compose-embed.test.ts +65 -0
- package/src/core/__tests__/lifecycle.test.ts +45 -26
- package/src/core/catalog-revision.ts +4 -2
- package/src/core/compose-embed.ts +50 -0
- package/src/core/core-ports.ts +10 -0
- package/src/core/create-core-server.ts +8 -2
- package/src/core/create-core-services.ts +63 -24
- package/src/core/lifecycle.ts +34 -12
- package/src/modules/access/__tests__/access-control.atref-cache.test.ts +443 -25
- package/src/modules/access/__tests__/access-control.group-read.test.ts +73 -0
- package/src/modules/access/__tests__/access.routes.group-grant.test.ts +66 -0
- package/src/modules/access/__tests__/access.routes.unknown-email.test.ts +2 -0
- package/src/modules/access/access-control.interface.ts +22 -0
- package/src/modules/access/access-control.service.ts +302 -58
- package/src/modules/access/access.routes.ts +22 -6
- package/src/modules/agent-instructions/shared-file-rules.ts +1 -1
- package/src/modules/auth/index.ts +29 -0
- package/src/modules/diff/__tests__/diff.service.seed-atomicity.test.ts +2 -1
- package/src/modules/diff/__tests__/diff.service.test.ts +2 -1
- package/src/modules/diff/__tests__/diff.service.worktree.test.ts +76 -0
- package/src/modules/diff/diff.service.ts +6 -4
- package/src/modules/embed/__tests__/embed.service.test.ts +76 -3
- package/src/modules/embed/__tests__/embed.tools.test.ts +29 -0
- package/src/modules/embed/embed.interface.ts +24 -0
- package/src/modules/embed/embed.service.ts +44 -19
- package/src/modules/embed/embed.tools.ts +10 -2
- package/src/modules/kb-fs/__tests__/git-dir.test.ts +77 -0
- package/src/modules/kb-fs/__tests__/ref-files.test.ts +338 -0
- package/src/modules/kb-fs/git-dir.ts +53 -0
- package/src/modules/kb-fs/index.ts +8 -0
- package/src/modules/kb-fs/ref-files.ts +279 -0
- package/src/modules/plugins/__tests__/join-request-jobs.service.test.ts +73 -6
- package/src/modules/plugins/__tests__/teams.routes.test.ts +55 -0
- package/src/modules/plugins/join-request-jobs.service.ts +45 -8
- package/src/modules/plugins/teams.routes.ts +14 -1
- package/src/modules/settings/__tests__/setup.routes.layout-phase.test.ts +2 -2
- package/src/modules/settings/__tests__/setup.routes.managed-phase.test.ts +2 -2
- package/src/modules/skills/__tests__/branch-skills.tools.test.ts +1 -1
- package/src/modules/skills/skills.contract.ts +4 -0
- package/src/modules/skills/skills.tools.ts +120 -10
- package/src/modules/tool-auth/internal-token.service.ts +1 -1
- package/src/modules/tool-auth/tool-auth.middleware.ts +1 -2
- package/src/modules/tool-helpers/__tests__/branch-declaration.test.ts +2 -2
- package/src/modules/tool-helpers/__tests__/can-write.tools.test.ts +581 -0
- package/src/modules/tool-helpers/default-branch-write.ts +90 -0
- package/src/modules/tool-helpers/index.ts +5 -0
- package/src/modules/tool-helpers/tool-handler.ts +2 -2
- package/src/modules/tool-helpers/tool.contract.ts +2 -2
- package/src/modules/tool-registry/__tests__/tool-description-length.test.ts +42 -3
- package/src/modules/workflow/__tests__/fake-file-lock-db.ts +13 -2
- package/src/modules/workflow/__tests__/workflow.routes.lock-path.test.ts +168 -1
- package/src/modules/workflow/__tests__/workflow.service.delete-branch.test.ts +102 -6
- package/src/modules/workflow/file-lock.service.ts +79 -18
- package/src/modules/workflow/git/__tests__/git.service.changedPathsMemo.test.ts +175 -0
- package/src/modules/workflow/git/__tests__/git.service.readFileAtRef.test.ts +42 -0
- package/src/modules/workflow/git/__tests__/git.service.worktrees.test.ts +284 -0
- package/src/modules/workflow/git/git.service.ts +207 -22
- package/src/modules/workflow/index.ts +7 -0
- package/src/modules/workflow/pending-commits.service.ts +4 -23
- package/src/modules/workflow/workflow-hooks.ts +1 -1
- package/src/modules/workflow/workflow.routes.ts +24 -1
- package/src/modules/workflow/workflow.service.ts +3 -2
- package/src/modules/workspace/__tests__/agent-downloads.test.ts +2 -2
- package/src/modules/workspace/__tests__/bounded-matcher.test.ts +213 -0
- package/src/modules/workspace/__tests__/git-internals.security.test.ts +22 -7
- package/src/modules/workspace/__tests__/kb-repository.test.ts +481 -0
- package/src/modules/workspace/__tests__/rest-tool-arguments.test.ts +14 -0
- package/src/modules/workspace/__tests__/routine-write-policy.test.ts +0 -11
- package/src/modules/workspace/__tests__/workspace-paths-inside-the-repo.test.ts +2 -2
- package/src/modules/workspace/__tests__/workspace.routes.folder-zip-access.test.ts +2 -2
- package/src/modules/workspace/__tests__/workspace.routes.folders.test.ts +4 -3
- package/src/modules/workspace/__tests__/workspace.service.any-workspace-credentials.test.ts +2 -2
- package/src/modules/workspace/__tests__/workspace.service.ensure-remotes-fetched.test.ts +2 -2
- package/src/modules/workspace/__tests__/workspace.service.forget-clone-races.test.ts +12 -5
- package/src/modules/workspace/__tests__/workspace.service.list-cloned.test.ts +6 -6
- package/src/modules/workspace/__tests__/workspace.service.move-never-overwrites.test.ts +2 -1
- package/src/modules/workspace/__tests__/workspace.service.read-filter.test.ts +2 -1
- package/src/modules/workspace/__tests__/workspace.service.replaced-repository.test.ts +2 -1
- package/src/modules/workspace/__tests__/workspace.service.test.ts +24 -23
- package/src/modules/workspace/__tests__/workspace.service.unknown-branch.test.ts +2 -1
- package/src/modules/workspace/__tests__/workspace.service.worktrees.test.ts +620 -0
- package/src/modules/workspace/__tests__/workspace.tools.agents-file.test.ts +15 -1
- package/src/modules/workspace/__tests__/workspace.tools.branch-errors.test.ts +71 -5
- package/src/modules/workspace/__tests__/workspace.tools.test.ts +174 -309
- package/src/modules/workspace/agent-access.gate.ts +2 -2
- package/src/modules/workspace/bounded-matcher.ts +328 -0
- package/src/modules/workspace/fetch-instant.ts +13 -0
- package/src/modules/workspace/index.ts +26 -0
- package/src/modules/workspace/kb-repository.contract.ts +124 -0
- package/src/modules/workspace/kb-repository.ts +844 -0
- package/src/modules/workspace/pattern-matcher.contract.ts +69 -0
- package/src/modules/workspace/routine-write-policy.ts +0 -15
- package/src/modules/workspace/set-aside-clone.ts +140 -0
- package/src/modules/workspace/startup/__tests__/kb-startup-runner.degraded.test.ts +3 -2
- package/src/modules/workspace/startup/__tests__/kb-startup-runner.test.ts +12 -10
- package/src/modules/workspace/startup/__tests__/kb-startup-runner.worktrees.test.ts +613 -0
- package/src/modules/workspace/startup/kb-startup-runner.ts +422 -29
- package/src/modules/workspace/startup/steps/__tests__/steps.test.ts +4 -3
- package/src/modules/workspace/workspace.service.ts +247 -169
- package/src/modules/workspace/workspace.tools.ts +299 -385
- package/src/shared/workspace-id.ts +24 -0
- package/src/test-setup.ts +5 -0
|
@@ -475,7 +475,7 @@ export async function createCoreServer(
|
|
|
475
475
|
// because they are the only ones that gate their whole payload on the
|
|
476
476
|
// caller's read access, so they take the access service and nothing else.
|
|
477
477
|
registerChangeRequestReadTools(core.toolRegistry, toolsRouter, ta, th, core.accessControl, core.kb);
|
|
478
|
-
const workspaceTools = registerWorkspaceTools(core.toolRegistry, toolsRouter, ta, th, core.spillStore, core.docExtractService, core.accessControl, core.kb, agentAccessGate, core.routineWritePolicy, core.sessionSink, allowedToolsChecker, core.changeGate, core.agentUploadStore, core.agentGuide, core.agentDownloadStore, core.starterPackService, core.disk);
|
|
478
|
+
const workspaceTools = registerWorkspaceTools(core.toolRegistry, toolsRouter, ta, th, core.spillStore, core.docExtractService, core.accessControl, core.kb, agentAccessGate, core.routineWritePolicy, core.sessionSink, allowedToolsChecker, core.changeGate, core.agentUploadStore, core.agentGuide, core.agentDownloadStore, core.starterPackService, core.disk, core.patternMatcher);
|
|
479
479
|
// `open_page` — the knowledge-base page shown inside a chat. Registered
|
|
480
480
|
// here, on the same router as the file tools, because it answers with
|
|
481
481
|
// `read_file`'s own read: the read hook, the access gate and the
|
|
@@ -509,7 +509,13 @@ export async function createCoreServer(
|
|
|
509
509
|
// one-time link is the whole credential an agent's `curl` carries. Every
|
|
510
510
|
// file behind it was judged when `request_file_download` issued it.
|
|
511
511
|
toolsRouter.use(createAgentDownloadRoutes({ downloads: core.agentDownloadStore, identify: core.agentDownloadFetcher }));
|
|
512
|
-
registerSkillsTools(core.toolRegistry, toolsRouter, ta, th, core.skillService, allowedToolsChecker
|
|
512
|
+
registerSkillsTools(core.toolRegistry, toolsRouter, ta, th, core.skillService, allowedToolsChecker, {
|
|
513
|
+
accessControl: core.accessControl,
|
|
514
|
+
defaultWorkspaceId: () => core.kb.defaultWorkspaceId(),
|
|
515
|
+
// A skill's files as committed on the default branch, for the whole-skill
|
|
516
|
+
// verdict: the same clone and the same git the skill's history is read from.
|
|
517
|
+
committedFiles: core.gitService,
|
|
518
|
+
});
|
|
513
519
|
// Definitions only: the endpoints they describe are the app's own plugin
|
|
514
520
|
// creation routes, mounted below behind the key-or-session gate.
|
|
515
521
|
registerPluginsTools(core.toolRegistry, core.kb);
|
|
@@ -17,8 +17,11 @@ import { getDb, type Database } from '../modules/database/connection.js';
|
|
|
17
17
|
import { runCoreMigrations } from '../modules/database/migrate.js';
|
|
18
18
|
import { coreMigrationsDir } from '../assets.js';
|
|
19
19
|
import { WorkspaceService } from '../modules/workspace/workspace.service.js';
|
|
20
|
+
import { KbRepository, repositoryDirFor } from '../modules/workspace/kb-repository.js';
|
|
21
|
+
import type { IKbRepository } from '../modules/workspace/kb-repository.contract.js';
|
|
20
22
|
import { AccountLinkService } from '../modules/embed/account-link.service.js';
|
|
21
|
-
import { EmbedService } from '../modules/embed/embed.service.js';
|
|
23
|
+
import type { EmbedService } from '../modules/embed/embed.service.js';
|
|
24
|
+
import { composeEmbedService } from './compose-embed.js';
|
|
22
25
|
import { McpAppService, type IMcpAppService } from '../modules/embed/mcp-app.js';
|
|
23
26
|
import { createFileReaderRegistry } from '../modules/workspace/file-readers/file-reader.registry.js';
|
|
24
27
|
import { RoutineWritePolicyService } from '../modules/workspace/routine-write-policy.js';
|
|
@@ -61,6 +64,8 @@ import { SpillStore } from '../modules/workspace/spill-store.js';
|
|
|
61
64
|
import { AgentUploadStore, assertUploadsRootOutsideWorkspaces } from '../modules/workspace/agent-upload.store.js';
|
|
62
65
|
import { AgentDownloadStore, type IAgentDownloadStore } from '../modules/workspace/agent-download.store.js';
|
|
63
66
|
import { createDownloadFetcherIdentifier } from '../modules/workspace/agent-download.routes.js';
|
|
67
|
+
import { WorkerPatternMatcher } from '../modules/workspace/bounded-matcher.js';
|
|
68
|
+
import type { IPatternMatcher } from '../modules/workspace/pattern-matcher.contract.js';
|
|
64
69
|
import type { Request } from 'express';
|
|
65
70
|
import { DocExtractService } from '../modules/workspace/file-readers/doc-extract.service.js';
|
|
66
71
|
import { UuidSessionSink, type ISessionSink } from '../modules/workspace/session-sink.js';
|
|
@@ -242,6 +247,8 @@ export interface CoreServices {
|
|
|
242
247
|
agentUploadStore: AgentUploadStore;
|
|
243
248
|
/** The bytes `request_file_download` captured, held until their one-time link is fetched or expires. */
|
|
244
249
|
agentDownloadStore: IAgentDownloadStore;
|
|
250
|
+
/** Runs a caller's `grep` pattern off the request thread under a budget; its workers end when the graph stops. */
|
|
251
|
+
patternMatcher: IPatternMatcher;
|
|
245
252
|
/**
|
|
246
253
|
* Every user a download fetch identifies itself as, by its bearer and its
|
|
247
254
|
* session cookie — none when it carries none that verifies — so the
|
|
@@ -569,6 +576,30 @@ export async function createCoreServices(
|
|
|
569
576
|
* Under the backups root: a persistent volume of its own, and one nothing
|
|
570
577
|
* sweeps (see the runner's `reconcileClonesWithConfiguredRepository`).
|
|
571
578
|
*/
|
|
579
|
+
// Shared mutex so git and diff operations on the same workspace serialize
|
|
580
|
+
// against each other — a backup-reseed races a concurrent commit otherwise.
|
|
581
|
+
const workspaceMutex = new WorkspaceMutex();
|
|
582
|
+
/**
|
|
583
|
+
* The knowledge base's ONE repository: every branch workspace is a worktree
|
|
584
|
+
* of it (see `kb-repository.ts`). One instance, handed to the workspace
|
|
585
|
+
* service, the startup phase and (through the workspace service) the git
|
|
586
|
+
* layer, so one fetch serves every workspace and the writes to its one
|
|
587
|
+
* config file are serialized in one place. Git operations in the worktrees
|
|
588
|
+
* are not serialized against each other beyond the workspace mutex: git's
|
|
589
|
+
* own locks cover a repository shared by worktrees.
|
|
590
|
+
*
|
|
591
|
+
* Under the backups root, like the set-aside copies: a persistent volume in
|
|
592
|
+
* every shipped compose file, so no new mount is needed, and outside the
|
|
593
|
+
* workspaces root, where the orphan sweep never sees it. The folder name
|
|
594
|
+
* starts with a dot, which no branch — and so no backup ledger's workspace
|
|
595
|
+
* id — can. On hexis-cloud every tenant has its own backups root: one
|
|
596
|
+
* repository per tenant.
|
|
597
|
+
*/
|
|
598
|
+
const kbRepository: IKbRepository = new KbRepository({
|
|
599
|
+
dir: repositoryDirFor(config.workspacesRoot, kbDirName, path.join(config.backupsRoot, '.kb-repository')),
|
|
600
|
+
kbRepoUrl: () => repositorySource.url(),
|
|
601
|
+
gitRunner,
|
|
602
|
+
});
|
|
572
603
|
const replacedWorkingCopiesRoot = path.join(config.backupsRoot, 'replaced-working-copies');
|
|
573
604
|
/**
|
|
574
605
|
* What must leave with a working copy that is set aside, whoever sets it
|
|
@@ -634,6 +665,7 @@ export async function createCoreServices(
|
|
|
634
665
|
);
|
|
635
666
|
});
|
|
636
667
|
}),
|
|
668
|
+
kbRepository,
|
|
637
669
|
);
|
|
638
670
|
// The KB startup phase: every seeding, scaffolding and migration concern,
|
|
639
671
|
// run through one runner at the deployment's quiet moments (boot + setup
|
|
@@ -671,6 +703,9 @@ export async function createCoreServices(
|
|
|
671
703
|
// The same folder the workspace service sets aside into — see
|
|
672
704
|
// `replacedWorkingCopiesRoot` above for why the two must agree.
|
|
673
705
|
setAsideRoot: replacedWorkingCopiesRoot,
|
|
706
|
+
// The one repository every branch workspace is a worktree of — the same
|
|
707
|
+
// instance the workspace service holds (see `kbRepository` above).
|
|
708
|
+
repository: kbRepository,
|
|
674
709
|
kbDirName,
|
|
675
710
|
templateDir: config.kbTemplateDir,
|
|
676
711
|
defaultBranch: () => kb.defaultBranch,
|
|
@@ -740,6 +775,7 @@ export async function createCoreServices(
|
|
|
740
775
|
'captured download bytes wait there for their one-time links, so a root inside a workspace would let the ' +
|
|
741
776
|
'file tools read them. Point AGENT_UPLOADS_ROOT at a directory whose parent is outside WORKSPACES_ROOT.',
|
|
742
777
|
});
|
|
778
|
+
const patternMatcher = new WorkerPatternMatcher();
|
|
743
779
|
const agentDownloadStore = new AgentDownloadStore({
|
|
744
780
|
root: agentDownloadsRoot,
|
|
745
781
|
publicBaseUrl: config.publicBackendUrl,
|
|
@@ -826,9 +862,6 @@ export async function createCoreServices(
|
|
|
826
862
|
// registers its listener here, after this returns (see `AccountHooks`).
|
|
827
863
|
const accountHooks = new AccountHooks();
|
|
828
864
|
|
|
829
|
-
// Shared mutex so git and diff operations on the same workspace serialize
|
|
830
|
-
// against each other — a backup-reseed races a concurrent commit otherwise.
|
|
831
|
-
const workspaceMutex = new WorkspaceMutex();
|
|
832
865
|
// Workflow lifecycle hooks — the ONE registry this composition shares
|
|
833
866
|
// between GitService (advisory commit validation), the agent-access gate
|
|
834
867
|
// (the blocking agentRead / preWrite hooks), and the composition root,
|
|
@@ -1288,26 +1321,31 @@ export async function createCoreServices(
|
|
|
1288
1321
|
// judges them with the same access resolver the app file page uses, so what
|
|
1289
1322
|
// a reader may see and change inside a chat is what they may see and change
|
|
1290
1323
|
// in the app — never a second answer to the same question.
|
|
1291
|
-
const embedService =
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1324
|
+
const embedService = composeEmbedService(
|
|
1325
|
+
{
|
|
1326
|
+
// The RESOLVED checkout folder, not the env's: `config.kbDirName` is only
|
|
1327
|
+
// the environment value, empty on a deployment that took the default or
|
|
1328
|
+
// named it in setup, and every path the embed builds starts with it.
|
|
1329
|
+
config: { ...config, kbDirName },
|
|
1330
|
+
kb,
|
|
1331
|
+
workspaceService,
|
|
1332
|
+
accessControl,
|
|
1333
|
+
authService,
|
|
1334
|
+
workflowService,
|
|
1335
|
+
gitService,
|
|
1336
|
+
accountLinks: new AccountLinkService(db),
|
|
1337
|
+
// The SAME extension-to-reader registry `read_file` dispatches on, so the
|
|
1338
|
+
// embed answer to "is this text, or bytes a renderer fetches?" cannot
|
|
1339
|
+
// disagree with what a read of the file returns.
|
|
1340
|
+
readers: createFileReaderRegistry(docExtractService),
|
|
1341
|
+
// The SAME pre-disk gate the file editor and the agent tools run: a
|
|
1342
|
+
// `roles.yaml` that would not parse is refused before it is written, from
|
|
1343
|
+
// a chat exactly as from the app.
|
|
1344
|
+
validateWrite: makeRolesYamlWriteValidator(kbDirName),
|
|
1345
|
+
},
|
|
1346
|
+
// A node-id reference resolves only where a node graph is: the
|
|
1347
|
+
// distribution's, when it registers one (`ports.embedNodeIdResolver`).
|
|
1348
|
+
ports,
|
|
1311
1349
|
);
|
|
1312
1350
|
// The `ui://` view `open_page` carries, with the one origin it may frame:
|
|
1313
1351
|
// this deployment own public origin.
|
|
@@ -1592,6 +1630,7 @@ export async function createCoreServices(
|
|
|
1592
1630
|
spillStore,
|
|
1593
1631
|
agentUploadStore,
|
|
1594
1632
|
agentDownloadStore,
|
|
1633
|
+
patternMatcher,
|
|
1595
1634
|
agentDownloadFetcher,
|
|
1596
1635
|
docExtractService,
|
|
1597
1636
|
accessControl,
|
package/src/core/lifecycle.ts
CHANGED
|
@@ -425,13 +425,18 @@ export interface CoreStopDeps {
|
|
|
425
425
|
/** The lease loop from {@link holdCommitWorkerLease}: its stop finishes the in-flight commit and releases the lease. */
|
|
426
426
|
commitWorker: Pick<LeaseLoopHandle, 'stop'>;
|
|
427
427
|
/**
|
|
428
|
-
*
|
|
429
|
-
*
|
|
430
|
-
*
|
|
431
|
-
*
|
|
432
|
-
*
|
|
428
|
+
* The plugin join-request jobs, whose sweep must be wound down before the
|
|
429
|
+
* pool goes. The timer is stopped first so nothing new is scheduled, then
|
|
430
|
+
* the jobs already running are awaited (within the budget) so the pool is
|
|
431
|
+
* not ended under a clone or a push that is still writing to it. Optional:
|
|
432
|
+
* a caller that has not built them yet passes nothing.
|
|
433
|
+
*
|
|
434
|
+
* Named as `CoreServices` names it, because the graph IS what is passed
|
|
435
|
+
* here (`stopCore(graph.core)`): under another name the slot stayed empty,
|
|
436
|
+
* the sweep outlived every stopped graph, and a multi-tenant host gained
|
|
437
|
+
* one more sweeper querying an ended pool, every minute, per eviction.
|
|
433
438
|
*/
|
|
434
|
-
|
|
439
|
+
pluginJoinRequestJobs?: { stopSweeping(): void; drain(): Promise<void> };
|
|
435
440
|
/**
|
|
436
441
|
* The agent upload store, whose own sweep deletes staged bytes nobody
|
|
437
442
|
* applied. Stopped with this graph because the next graph for the same
|
|
@@ -443,6 +448,12 @@ export interface CoreStopDeps {
|
|
|
443
448
|
agentUploadStore?: { stopSweeping(): void; drainSweep(): Promise<void> };
|
|
444
449
|
/** The agent download store, whose sweep deletes captured bytes nobody fetched — stopped for the same reason. */
|
|
445
450
|
agentDownloadStore?: { stopSweeping(): void; drainSweep(): Promise<void> };
|
|
451
|
+
/**
|
|
452
|
+
* The grep pattern matcher, whose worker threads are this graph's own: ended
|
|
453
|
+
* here so a graph a tenant host evicts leaves no worker behind. Optional: a
|
|
454
|
+
* caller that has not built one passes nothing.
|
|
455
|
+
*/
|
|
456
|
+
patternMatcher?: { close(): Promise<void> };
|
|
446
457
|
/**
|
|
447
458
|
* The workflow service, for the tidy-up it runs after each sweep (closing
|
|
448
459
|
* empty requests, removing leftover branches): detached from whatever
|
|
@@ -532,7 +543,7 @@ async function releaseCore(deps: CoreStopDeps, remaining: () => number, log: (m:
|
|
|
532
543
|
// server is closed (or the tenant is no longer routed to), so this is the
|
|
533
544
|
// earliest point the interval is dead weight. Synchronous and unfailing
|
|
534
545
|
// — it just clears an interval — so it needs no budget of its own.
|
|
535
|
-
deps.
|
|
546
|
+
deps.pluginJoinRequestJobs?.stopSweeping();
|
|
536
547
|
// And the upload store's sweep, for the same reason and in the same breath:
|
|
537
548
|
// synchronous, and it only clears an interval and tells a sweep already
|
|
538
549
|
// running to stop deleting.
|
|
@@ -548,11 +559,18 @@ async function releaseCore(deps: CoreStopDeps, remaining: () => number, log: (m:
|
|
|
548
559
|
// Clearing the interval stops future ticks; it does nothing to a job a
|
|
549
560
|
// tick already started, which holds a claim it heartbeats through the
|
|
550
561
|
// pool and is mid-clone or mid-push. Awaited here, in the budget: a job
|
|
551
|
-
// that finishes releases or marks its row
|
|
552
|
-
//
|
|
553
|
-
//
|
|
554
|
-
|
|
555
|
-
|
|
562
|
+
// that finishes releases or marks its row. One that cannot in time is
|
|
563
|
+
// NOT cancelled — the bounded wait only stops waiting — and what becomes
|
|
564
|
+
// of it depends on who is stopping: a process shutting down takes it
|
|
565
|
+
// along; a tenant host evicting one graph ends the pool under it, which
|
|
566
|
+
// cancels nothing already running — a clone or push in flight finishes
|
|
567
|
+
// on its own — but its next heartbeat or database write fails, so from
|
|
568
|
+
// there the job records nothing and stops. Either way its claim goes
|
|
569
|
+
// stale and the next sweep — the next boot's, or a live graph's — picks
|
|
570
|
+
// the row up and does the whole thing again, which is the recovery every
|
|
571
|
+
// crash already gets (and why each step is written to be redone).
|
|
572
|
+
if (deps.pluginJoinRequestJobs) {
|
|
573
|
+
await bounded(deps.pluginJoinRequestJobs.drain(), remaining(), 'finishing the join-request jobs', log);
|
|
556
574
|
}
|
|
557
575
|
// The sweep in flight when the interval was cleared: awaited so the next
|
|
558
576
|
// graph for this tenant cannot start staging bytes while a store it has
|
|
@@ -569,6 +587,10 @@ async function releaseCore(deps: CoreStopDeps, remaining: () => number, log: (m:
|
|
|
569
587
|
if (deps.workflowService) {
|
|
570
588
|
await bounded(deps.workflowService.drainTidy(), remaining(), 'finishing the branch tidy-up', log);
|
|
571
589
|
}
|
|
590
|
+
// Its workers end with the graph; a search still running is answered busy.
|
|
591
|
+
if (deps.patternMatcher) {
|
|
592
|
+
await bounded(deps.patternMatcher.close(), remaining(), 'ending the search workers', log);
|
|
593
|
+
}
|
|
572
594
|
await bounded(deps.commitWorker.stop(), remaining(), 'stopping the commit worker', log);
|
|
573
595
|
if (deps.secretsScope !== undefined) unregisterBevelSecretsVariableLoader(deps.secretsScope);
|
|
574
596
|
await bounded(closeDb(deps.db), remaining(), 'ending the database pool', log);
|