@cleocode/mcp-server 0.86.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/LICENSE +21 -0
- package/README.md +306 -0
- package/dist/domains/index.d.ts +16 -0
- package/dist/domains/index.d.ts.map +1 -0
- package/dist/domains/index.js +16 -0
- package/dist/domains/index.js.map +1 -0
- package/dist/domains/lifecycle.d.ts +147 -0
- package/dist/domains/lifecycle.d.ts.map +1 -0
- package/dist/domains/lifecycle.js +452 -0
- package/dist/domains/lifecycle.js.map +1 -0
- package/dist/domains/orchestrate.d.ts +133 -0
- package/dist/domains/orchestrate.d.ts.map +1 -0
- package/dist/domains/orchestrate.js +465 -0
- package/dist/domains/orchestrate.js.map +1 -0
- package/dist/domains/release.d.ts +109 -0
- package/dist/domains/release.d.ts.map +1 -0
- package/dist/domains/release.js +400 -0
- package/dist/domains/release.js.map +1 -0
- package/dist/domains/research.d.ts +139 -0
- package/dist/domains/research.d.ts.map +1 -0
- package/dist/domains/research.js +606 -0
- package/dist/domains/research.js.map +1 -0
- package/dist/domains/session.d.ts +129 -0
- package/dist/domains/session.d.ts.map +1 -0
- package/dist/domains/session.js +433 -0
- package/dist/domains/session.js.map +1 -0
- package/dist/domains/system.d.ts +92 -0
- package/dist/domains/system.d.ts.map +1 -0
- package/dist/domains/system.js +473 -0
- package/dist/domains/system.js.map +1 -0
- package/dist/domains/tasks.d.ts +180 -0
- package/dist/domains/tasks.d.ts.map +1 -0
- package/dist/domains/tasks.js +704 -0
- package/dist/domains/tasks.js.map +1 -0
- package/dist/domains/validate.d.ts +150 -0
- package/dist/domains/validate.d.ts.map +1 -0
- package/dist/domains/validate.js +568 -0
- package/dist/domains/validate.js.map +1 -0
- package/dist/gateways/mutate.d.ts +100 -0
- package/dist/gateways/mutate.d.ts.map +1 -0
- package/dist/gateways/mutate.js +937 -0
- package/dist/gateways/mutate.js.map +1 -0
- package/dist/gateways/query.d.ts +91 -0
- package/dist/gateways/query.d.ts.map +1 -0
- package/dist/gateways/query.js +245 -0
- package/dist/gateways/query.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +299 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/audit.d.ts +118 -0
- package/dist/lib/audit.d.ts.map +1 -0
- package/dist/lib/audit.js +311 -0
- package/dist/lib/audit.js.map +1 -0
- package/dist/lib/background-jobs.d.ts +86 -0
- package/dist/lib/background-jobs.d.ts.map +1 -0
- package/dist/lib/background-jobs.js +183 -0
- package/dist/lib/background-jobs.js.map +1 -0
- package/dist/lib/cache.d.ts +78 -0
- package/dist/lib/cache.d.ts.map +1 -0
- package/dist/lib/cache.js +204 -0
- package/dist/lib/cache.js.map +1 -0
- package/dist/lib/command-builder.d.ts +52 -0
- package/dist/lib/command-builder.d.ts.map +1 -0
- package/dist/lib/command-builder.js +280 -0
- package/dist/lib/command-builder.js.map +1 -0
- package/dist/lib/config.d.ts +42 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +248 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/defaults.d.ts +115 -0
- package/dist/lib/defaults.d.ts.map +1 -0
- package/dist/lib/defaults.js +61 -0
- package/dist/lib/defaults.js.map +1 -0
- package/dist/lib/error-handler.d.ts +101 -0
- package/dist/lib/error-handler.d.ts.map +1 -0
- package/dist/lib/error-handler.js +277 -0
- package/dist/lib/error-handler.js.map +1 -0
- package/dist/lib/executor.d.ts +110 -0
- package/dist/lib/executor.d.ts.map +1 -0
- package/dist/lib/executor.js +362 -0
- package/dist/lib/executor.js.map +1 -0
- package/dist/lib/exit-codes.d.ts +190 -0
- package/dist/lib/exit-codes.d.ts.map +1 -0
- package/dist/lib/exit-codes.js +1027 -0
- package/dist/lib/exit-codes.js.map +1 -0
- package/dist/lib/formatter.d.ts +196 -0
- package/dist/lib/formatter.d.ts.map +1 -0
- package/dist/lib/formatter.js +260 -0
- package/dist/lib/formatter.js.map +1 -0
- package/dist/lib/gate-validators.d.ts +103 -0
- package/dist/lib/gate-validators.d.ts.map +1 -0
- package/dist/lib/gate-validators.js +689 -0
- package/dist/lib/gate-validators.js.map +1 -0
- package/dist/lib/manifest-parser.d.ts +61 -0
- package/dist/lib/manifest-parser.d.ts.map +1 -0
- package/dist/lib/manifest-parser.js +338 -0
- package/dist/lib/manifest-parser.js.map +1 -0
- package/dist/lib/manifest.d.ts +177 -0
- package/dist/lib/manifest.d.ts.map +1 -0
- package/dist/lib/manifest.js +301 -0
- package/dist/lib/manifest.js.map +1 -0
- package/dist/lib/protocol-enforcement.d.ts +105 -0
- package/dist/lib/protocol-enforcement.d.ts.map +1 -0
- package/dist/lib/protocol-enforcement.js +331 -0
- package/dist/lib/protocol-enforcement.js.map +1 -0
- package/dist/lib/protocol-rules.d.ts +55 -0
- package/dist/lib/protocol-rules.d.ts.map +1 -0
- package/dist/lib/protocol-rules.js +760 -0
- package/dist/lib/protocol-rules.js.map +1 -0
- package/dist/lib/rate-limiter.d.ts +110 -0
- package/dist/lib/rate-limiter.d.ts.map +1 -0
- package/dist/lib/rate-limiter.js +208 -0
- package/dist/lib/rate-limiter.js.map +1 -0
- package/dist/lib/router.d.ts +126 -0
- package/dist/lib/router.d.ts.map +1 -0
- package/dist/lib/router.js +276 -0
- package/dist/lib/router.js.map +1 -0
- package/dist/lib/schema.d.ts +55 -0
- package/dist/lib/schema.d.ts.map +1 -0
- package/dist/lib/schema.js +70 -0
- package/dist/lib/schema.js.map +1 -0
- package/dist/lib/security.d.ts +156 -0
- package/dist/lib/security.d.ts.map +1 -0
- package/dist/lib/security.js +347 -0
- package/dist/lib/security.js.map +1 -0
- package/dist/lib/verification-gates.d.ts +287 -0
- package/dist/lib/verification-gates.d.ts.map +1 -0
- package/dist/lib/verification-gates.js +548 -0
- package/dist/lib/verification-gates.js.map +1 -0
- package/dist/types/domain.d.ts +29 -0
- package/dist/types/domain.d.ts.map +1 -0
- package/dist/types/domain.js +7 -0
- package/dist/types/domain.js.map +1 -0
- package/dist/types/error.d.ts +101 -0
- package/dist/types/error.d.ts.map +1 -0
- package/dist/types/error.js +61 -0
- package/dist/types/error.js.map +1 -0
- package/dist/types/gateway.d.ts +78 -0
- package/dist/types/gateway.d.ts.map +1 -0
- package/dist/types/gateway.js +7 -0
- package/dist/types/gateway.js.map +1 -0
- package/dist/types/index.d.ts +21 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +11 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/operations/lifecycle.d.ts +140 -0
- package/dist/types/operations/lifecycle.d.ts.map +1 -0
- package/dist/types/operations/lifecycle.js +8 -0
- package/dist/types/operations/lifecycle.js.map +1 -0
- package/dist/types/operations/orchestrate.d.ts +140 -0
- package/dist/types/operations/orchestrate.d.ts.map +1 -0
- package/dist/types/operations/orchestrate.js +8 -0
- package/dist/types/operations/orchestrate.js.map +1 -0
- package/dist/types/operations/release.d.ts +97 -0
- package/dist/types/operations/release.d.ts.map +1 -0
- package/dist/types/operations/release.js +7 -0
- package/dist/types/operations/release.js.map +1 -0
- package/dist/types/operations/research.d.ts +122 -0
- package/dist/types/operations/research.d.ts.map +1 -0
- package/dist/types/operations/research.js +8 -0
- package/dist/types/operations/research.js.map +1 -0
- package/dist/types/operations/session.d.ts +108 -0
- package/dist/types/operations/session.d.ts.map +1 -0
- package/dist/types/operations/session.js +8 -0
- package/dist/types/operations/session.js.map +1 -0
- package/dist/types/operations/system.d.ts +147 -0
- package/dist/types/operations/system.d.ts.map +1 -0
- package/dist/types/operations/system.js +8 -0
- package/dist/types/operations/system.js.map +1 -0
- package/dist/types/operations/tasks.d.ts +186 -0
- package/dist/types/operations/tasks.d.ts.map +1 -0
- package/dist/types/operations/tasks.js +8 -0
- package/dist/types/operations/tasks.js.map +1 -0
- package/dist/types/operations/validate.d.ts +170 -0
- package/dist/types/operations/validate.d.ts.map +1 -0
- package/dist/types/operations/validate.js +8 -0
- package/dist/types/operations/validate.js.map +1 -0
- package/package.json +67 -0
- package/schemas/IMPLEMENTATION-SUMMARY.md +250 -0
- package/schemas/README.md +284 -0
- package/schemas/common/error.schema.json +54 -0
- package/schemas/common/meta.schema.json +39 -0
- package/schemas/common/pagination.schema.json +32 -0
- package/schemas/index.json +159 -0
- package/schemas/requests/lifecycle/check.schema.json +20 -0
- package/schemas/requests/lifecycle/gate.fail.schema.json +25 -0
- package/schemas/requests/lifecycle/gate.pass.schema.json +28 -0
- package/schemas/requests/lifecycle/gates.schema.json +15 -0
- package/schemas/requests/lifecycle/history.schema.json +15 -0
- package/schemas/requests/lifecycle/prerequisites.schema.json +15 -0
- package/schemas/requests/lifecycle/progress.schema.json +29 -0
- package/schemas/requests/lifecycle/reset.schema.json +25 -0
- package/schemas/requests/lifecycle/skip.schema.json +25 -0
- package/schemas/requests/lifecycle/status.schema.json +23 -0
- package/schemas/requests/orchestrate/analyze.schema.json +15 -0
- package/schemas/requests/orchestrate/context.schema.json +13 -0
- package/schemas/requests/orchestrate/next.schema.json +15 -0
- package/schemas/requests/orchestrate/parallel.end.schema.json +20 -0
- package/schemas/requests/orchestrate/parallel.start.schema.json +20 -0
- package/schemas/requests/orchestrate/ready.schema.json +15 -0
- package/schemas/requests/orchestrate/skill.list.schema.json +13 -0
- package/schemas/requests/orchestrate/spawn.schema.json +25 -0
- package/schemas/requests/orchestrate/startup.schema.json +15 -0
- package/schemas/requests/orchestrate/status.schema.json +15 -0
- package/schemas/requests/orchestrate/validate.schema.json +15 -0
- package/schemas/requests/orchestrate/waves.schema.json +15 -0
- package/schemas/requests/release/changelog.schema.json +23 -0
- package/schemas/requests/release/commit.schema.json +22 -0
- package/schemas/requests/release/gates.run.schema.json +17 -0
- package/schemas/requests/release/prepare.schema.json +20 -0
- package/schemas/requests/release/push.schema.json +20 -0
- package/schemas/requests/release/rollback.schema.json +20 -0
- package/schemas/requests/release/tag.schema.json +19 -0
- package/schemas/requests/research/inject.schema.json +24 -0
- package/schemas/requests/research/link.schema.json +25 -0
- package/schemas/requests/research/list.schema.json +19 -0
- package/schemas/requests/research/manifest.append.schema.json +20 -0
- package/schemas/requests/research/manifest.archive.schema.json +19 -0
- package/schemas/requests/research/manifest.read.schema.json +21 -0
- package/schemas/requests/research/pending.schema.json +14 -0
- package/schemas/requests/research/query.schema.json +21 -0
- package/schemas/requests/research/show.schema.json +14 -0
- package/schemas/requests/research/stats.schema.json +14 -0
- package/schemas/requests/session/end.schema.json +13 -0
- package/schemas/requests/session/focus.clear.schema.json +7 -0
- package/schemas/requests/session/focus.get.schema.json +7 -0
- package/schemas/requests/session/focus.set.schema.json +15 -0
- package/schemas/requests/session/gc.schema.json +14 -0
- package/schemas/requests/session/history.schema.json +16 -0
- package/schemas/requests/session/list.schema.json +13 -0
- package/schemas/requests/session/resume.schema.json +14 -0
- package/schemas/requests/session/show.schema.json +14 -0
- package/schemas/requests/session/start.schema.json +23 -0
- package/schemas/requests/session/status.schema.json +7 -0
- package/schemas/requests/session/suspend.schema.json +13 -0
- package/schemas/requests/system/backup.schema.json +19 -0
- package/schemas/requests/system/cleanup.schema.json +20 -0
- package/schemas/requests/system/config.get.schema.json +14 -0
- package/schemas/requests/system/config.set.schema.json +24 -0
- package/schemas/requests/system/context.schema.json +7 -0
- package/schemas/requests/system/doctor.schema.json +7 -0
- package/schemas/requests/system/init.schema.json +18 -0
- package/schemas/requests/system/migrate.schema.json +19 -0
- package/schemas/requests/system/restore.schema.json +14 -0
- package/schemas/requests/system/stats.schema.json +7 -0
- package/schemas/requests/system/sync.schema.json +15 -0
- package/schemas/requests/system/version.schema.json +7 -0
- package/schemas/requests/tasks/analyze.schema.json +14 -0
- package/schemas/requests/tasks/archive.schema.json +19 -0
- package/schemas/requests/tasks/blockers.schema.json +15 -0
- package/schemas/requests/tasks/complete.schema.json +24 -0
- package/schemas/requests/tasks/create.schema.json +48 -0
- package/schemas/requests/tasks/delete.schema.json +20 -0
- package/schemas/requests/tasks/deps.schema.json +21 -0
- package/schemas/requests/tasks/exists.schema.json +15 -0
- package/schemas/requests/tasks/find.schema.json +22 -0
- package/schemas/requests/tasks/get.schema.json +15 -0
- package/schemas/requests/tasks/list.schema.json +26 -0
- package/schemas/requests/tasks/next.schema.json +21 -0
- package/schemas/requests/tasks/promote.schema.json +15 -0
- package/schemas/requests/tasks/reopen.schema.json +15 -0
- package/schemas/requests/tasks/reorder.schema.json +20 -0
- package/schemas/requests/tasks/reparent.schema.json +20 -0
- package/schemas/requests/tasks/tree.schema.json +21 -0
- package/schemas/requests/tasks/unarchive.schema.json +15 -0
- package/schemas/requests/tasks/update.schema.json +41 -0
- package/schemas/requests/validate/compliance.record.schema.json +20 -0
- package/schemas/requests/validate/compliance.summary.schema.json +18 -0
- package/schemas/requests/validate/compliance.violations.schema.json +19 -0
- package/schemas/requests/validate/manifest.schema.json +23 -0
- package/schemas/requests/validate/output.schema.json +19 -0
- package/schemas/requests/validate/protocol.schema.json +20 -0
- package/schemas/requests/validate/schema.schema.json +19 -0
- package/schemas/requests/validate/task.schema.json +21 -0
- package/schemas/requests/validate/test.coverage.schema.json +14 -0
- package/schemas/requests/validate/test.run.schema.json +22 -0
- package/schemas/requests/validate/test.status.schema.json +14 -0
- package/schemas/responses/common-error.schema.json +20 -0
- package/schemas/responses/common-success.schema.json +21 -0
- package/schemas/responses/lifecycle/check.schema.json +18 -0
- package/schemas/responses/lifecycle/gate.fail.schema.json +18 -0
- package/schemas/responses/lifecycle/gate.pass.schema.json +18 -0
- package/schemas/responses/lifecycle/gates.schema.json +18 -0
- package/schemas/responses/lifecycle/history.schema.json +18 -0
- package/schemas/responses/lifecycle/prerequisites.schema.json +18 -0
- package/schemas/responses/lifecycle/progress.schema.json +18 -0
- package/schemas/responses/lifecycle/reset.schema.json +18 -0
- package/schemas/responses/lifecycle/skip.schema.json +18 -0
- package/schemas/responses/lifecycle/status.schema.json +18 -0
- package/schemas/responses/orchestrate/analyze.schema.json +18 -0
- package/schemas/responses/orchestrate/context.schema.json +18 -0
- package/schemas/responses/orchestrate/next.schema.json +18 -0
- package/schemas/responses/orchestrate/parallel.end.schema.json +18 -0
- package/schemas/responses/orchestrate/parallel.start.schema.json +18 -0
- package/schemas/responses/orchestrate/ready.schema.json +18 -0
- package/schemas/responses/orchestrate/skill.list.schema.json +18 -0
- package/schemas/responses/orchestrate/spawn.schema.json +18 -0
- package/schemas/responses/orchestrate/startup.schema.json +18 -0
- package/schemas/responses/orchestrate/status.schema.json +18 -0
- package/schemas/responses/orchestrate/validate.schema.json +18 -0
- package/schemas/responses/orchestrate/waves.schema.json +18 -0
- package/schemas/responses/release/changelog.schema.json +18 -0
- package/schemas/responses/release/commit.schema.json +18 -0
- package/schemas/responses/release/gates.run.schema.json +18 -0
- package/schemas/responses/release/prepare.schema.json +18 -0
- package/schemas/responses/release/push.schema.json +18 -0
- package/schemas/responses/release/rollback.schema.json +18 -0
- package/schemas/responses/release/tag.schema.json +18 -0
- package/schemas/responses/research/inject.schema.json +18 -0
- package/schemas/responses/research/link.schema.json +18 -0
- package/schemas/responses/research/list.schema.json +18 -0
- package/schemas/responses/research/manifest.append.schema.json +18 -0
- package/schemas/responses/research/manifest.archive.schema.json +18 -0
- package/schemas/responses/research/manifest.read.schema.json +18 -0
- package/schemas/responses/research/pending.schema.json +18 -0
- package/schemas/responses/research/query.schema.json +18 -0
- package/schemas/responses/research/show.schema.json +18 -0
- package/schemas/responses/research/stats.schema.json +18 -0
- package/schemas/responses/session/end.schema.json +18 -0
- package/schemas/responses/session/focus.clear.schema.json +18 -0
- package/schemas/responses/session/focus.get.schema.json +18 -0
- package/schemas/responses/session/focus.set.schema.json +18 -0
- package/schemas/responses/session/gc.schema.json +18 -0
- package/schemas/responses/session/history.schema.json +18 -0
- package/schemas/responses/session/list.schema.json +18 -0
- package/schemas/responses/session/resume.schema.json +18 -0
- package/schemas/responses/session/show.schema.json +18 -0
- package/schemas/responses/session/start.schema.json +18 -0
- package/schemas/responses/session/status.schema.json +18 -0
- package/schemas/responses/session/suspend.schema.json +18 -0
- package/schemas/responses/system/backup.schema.json +18 -0
- package/schemas/responses/system/cleanup.schema.json +18 -0
- package/schemas/responses/system/config.get.schema.json +18 -0
- package/schemas/responses/system/config.set.schema.json +18 -0
- package/schemas/responses/system/context.schema.json +18 -0
- package/schemas/responses/system/doctor.schema.json +18 -0
- package/schemas/responses/system/init.schema.json +18 -0
- package/schemas/responses/system/migrate.schema.json +18 -0
- package/schemas/responses/system/restore.schema.json +18 -0
- package/schemas/responses/system/stats.schema.json +18 -0
- package/schemas/responses/system/sync.schema.json +18 -0
- package/schemas/responses/system/version.schema.json +18 -0
- package/schemas/responses/tasks/analyze.schema.json +18 -0
- package/schemas/responses/tasks/archive.schema.json +18 -0
- package/schemas/responses/tasks/blockers.schema.json +18 -0
- package/schemas/responses/tasks/complete.schema.json +18 -0
- package/schemas/responses/tasks/create.schema.json +18 -0
- package/schemas/responses/tasks/delete.schema.json +18 -0
- package/schemas/responses/tasks/deps.schema.json +18 -0
- package/schemas/responses/tasks/exists.schema.json +18 -0
- package/schemas/responses/tasks/find.schema.json +18 -0
- package/schemas/responses/tasks/get.schema.json +87 -0
- package/schemas/responses/tasks/list.schema.json +18 -0
- package/schemas/responses/tasks/next.schema.json +18 -0
- package/schemas/responses/tasks/promote.schema.json +18 -0
- package/schemas/responses/tasks/reopen.schema.json +18 -0
- package/schemas/responses/tasks/reorder.schema.json +18 -0
- package/schemas/responses/tasks/reparent.schema.json +18 -0
- package/schemas/responses/tasks/tree.schema.json +18 -0
- package/schemas/responses/tasks/unarchive.schema.json +18 -0
- package/schemas/responses/tasks/update.schema.json +18 -0
- package/schemas/responses/validate/compliance.record.schema.json +18 -0
- package/schemas/responses/validate/compliance.summary.schema.json +18 -0
- package/schemas/responses/validate/compliance.violations.schema.json +18 -0
- package/schemas/responses/validate/manifest.schema.json +18 -0
- package/schemas/responses/validate/output.schema.json +18 -0
- package/schemas/responses/validate/protocol.schema.json +18 -0
- package/schemas/responses/validate/schema.schema.json +18 -0
- package/schemas/responses/validate/task.schema.json +18 -0
- package/schemas/responses/validate/test.coverage.schema.json +18 -0
- package/schemas/responses/validate/test.run.schema.json +18 -0
- package/schemas/responses/validate/test.status.schema.json +18 -0
- package/server.json +53 -0
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit Trail for MCP Server Mutations
|
|
3
|
+
*
|
|
4
|
+
* Logs all write operations to .cleo/audit-log.json for compliance
|
|
5
|
+
* and debugging purposes.
|
|
6
|
+
*
|
|
7
|
+
* @task T2920
|
|
8
|
+
* @task T2929
|
|
9
|
+
*/
|
|
10
|
+
import { promises as fs } from 'fs';
|
|
11
|
+
import { join } from 'path';
|
|
12
|
+
import { getConfig } from './config.js';
|
|
13
|
+
/**
|
|
14
|
+
* Maximum audit log size in bytes before rotation (default: 10MB)
|
|
15
|
+
*/
|
|
16
|
+
const MAX_AUDIT_LOG_SIZE = 10 * 1024 * 1024;
|
|
17
|
+
/**
|
|
18
|
+
* Get audit log file path
|
|
19
|
+
*/
|
|
20
|
+
function getAuditLogPath() {
|
|
21
|
+
const config = getConfig();
|
|
22
|
+
// Default to .cleo/audit-log.json in project root
|
|
23
|
+
return join(process.cwd(), '.cleo', 'audit-log.json');
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Get current session ID from environment or config
|
|
27
|
+
*/
|
|
28
|
+
function getCurrentSessionId() {
|
|
29
|
+
// TODO: Integrate with session system when available
|
|
30
|
+
return process.env.CLEO_SESSION_ID || null;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Ensure .cleo directory exists
|
|
34
|
+
*/
|
|
35
|
+
async function ensureCleoDir() {
|
|
36
|
+
const cleoDir = join(process.cwd(), '.cleo');
|
|
37
|
+
try {
|
|
38
|
+
await fs.mkdir(cleoDir, { recursive: true });
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
// Ignore if already exists
|
|
42
|
+
if (error.code !== 'EEXIST') {
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Log mutation to audit trail
|
|
49
|
+
*
|
|
50
|
+
* Appends a single-line JSON entry to .cleo/audit-log.json
|
|
51
|
+
* Non-blocking - errors are logged but not thrown
|
|
52
|
+
* Automatically rotates log if size exceeds limit
|
|
53
|
+
*
|
|
54
|
+
* @param entry Audit entry to log
|
|
55
|
+
*/
|
|
56
|
+
export async function logMutation(entry) {
|
|
57
|
+
try {
|
|
58
|
+
// Check if audit logging is enabled
|
|
59
|
+
const config = getConfig();
|
|
60
|
+
if (!config.auditLog) {
|
|
61
|
+
return; // Audit logging disabled
|
|
62
|
+
}
|
|
63
|
+
// Ensure .cleo directory exists
|
|
64
|
+
await ensureCleoDir();
|
|
65
|
+
// Get audit log path
|
|
66
|
+
const logPath = getAuditLogPath();
|
|
67
|
+
// Check if rotation is needed
|
|
68
|
+
await checkAndRotateLog(logPath);
|
|
69
|
+
// Serialize entry as single-line JSON
|
|
70
|
+
const line = JSON.stringify(entry) + '\n';
|
|
71
|
+
// Append to log file
|
|
72
|
+
await fs.appendFile(logPath, line, 'utf8');
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
// Log error but don't throw - audit logging should not block operations
|
|
76
|
+
console.error('Failed to write audit log entry:', error);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Log error to audit trail
|
|
81
|
+
*
|
|
82
|
+
* Convenience function for logging errors with full context
|
|
83
|
+
*
|
|
84
|
+
* @param domain Domain where error occurred
|
|
85
|
+
* @param operation Operation that failed
|
|
86
|
+
* @param error Error object or message
|
|
87
|
+
* @param params Operation parameters
|
|
88
|
+
* @param exitCode Exit code (default: 1)
|
|
89
|
+
*/
|
|
90
|
+
export async function logError(domain, operation, error, params = {}, exitCode = 1) {
|
|
91
|
+
// Check if audit logging is enabled
|
|
92
|
+
const config = getConfig();
|
|
93
|
+
if (!config.auditLog) {
|
|
94
|
+
return; // Audit logging disabled
|
|
95
|
+
}
|
|
96
|
+
const errorMessage = error instanceof Error ? error.message : error;
|
|
97
|
+
const taskId = typeof params.taskId === 'string' ? params.taskId : undefined;
|
|
98
|
+
const entry = {
|
|
99
|
+
timestamp: new Date().toISOString(),
|
|
100
|
+
sessionId: getCurrentSessionId(),
|
|
101
|
+
domain,
|
|
102
|
+
operation,
|
|
103
|
+
params,
|
|
104
|
+
result: {
|
|
105
|
+
success: false,
|
|
106
|
+
exitCode,
|
|
107
|
+
duration: 0,
|
|
108
|
+
},
|
|
109
|
+
metadata: {
|
|
110
|
+
taskId,
|
|
111
|
+
source: 'mcp',
|
|
112
|
+
},
|
|
113
|
+
error: errorMessage,
|
|
114
|
+
};
|
|
115
|
+
await logMutation(entry);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Read audit log entries
|
|
119
|
+
*
|
|
120
|
+
* @param options Filter options
|
|
121
|
+
* @returns Array of audit entries
|
|
122
|
+
*/
|
|
123
|
+
export async function readAuditLog(options) {
|
|
124
|
+
try {
|
|
125
|
+
const logPath = getAuditLogPath();
|
|
126
|
+
// Read log file
|
|
127
|
+
const content = await fs.readFile(logPath, 'utf8');
|
|
128
|
+
// Parse JSONL
|
|
129
|
+
const entries = content
|
|
130
|
+
.split('\n')
|
|
131
|
+
.filter((line) => line.trim())
|
|
132
|
+
.map((line) => JSON.parse(line));
|
|
133
|
+
// Apply filters
|
|
134
|
+
let filtered = entries;
|
|
135
|
+
if (options?.since) {
|
|
136
|
+
filtered = filtered.filter((e) => e.timestamp >= options.since);
|
|
137
|
+
}
|
|
138
|
+
if (options?.domain) {
|
|
139
|
+
filtered = filtered.filter((e) => e.domain === options.domain);
|
|
140
|
+
}
|
|
141
|
+
if (options?.operation) {
|
|
142
|
+
filtered = filtered.filter((e) => e.operation === options.operation);
|
|
143
|
+
}
|
|
144
|
+
if (options?.success !== undefined) {
|
|
145
|
+
filtered = filtered.filter((e) => e.result.success === options.success);
|
|
146
|
+
}
|
|
147
|
+
// Apply limit
|
|
148
|
+
if (options?.limit) {
|
|
149
|
+
filtered = filtered.slice(-options.limit);
|
|
150
|
+
}
|
|
151
|
+
return filtered;
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
// If file doesn't exist, return empty array
|
|
155
|
+
if (error.code === 'ENOENT') {
|
|
156
|
+
return [];
|
|
157
|
+
}
|
|
158
|
+
throw error;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Get audit statistics
|
|
163
|
+
*
|
|
164
|
+
* @returns Audit statistics
|
|
165
|
+
*/
|
|
166
|
+
export async function getAuditStats() {
|
|
167
|
+
const entries = await readAuditLog();
|
|
168
|
+
const stats = {
|
|
169
|
+
totalEntries: entries.length,
|
|
170
|
+
successCount: entries.filter((e) => e.result.success).length,
|
|
171
|
+
failureCount: entries.filter((e) => !e.result.success).length,
|
|
172
|
+
byDomain: {},
|
|
173
|
+
byOperation: {},
|
|
174
|
+
avgDuration: 0,
|
|
175
|
+
};
|
|
176
|
+
// Count by domain
|
|
177
|
+
for (const entry of entries) {
|
|
178
|
+
stats.byDomain[entry.domain] = (stats.byDomain[entry.domain] || 0) + 1;
|
|
179
|
+
const opKey = `${entry.domain}.${entry.operation}`;
|
|
180
|
+
stats.byOperation[opKey] = (stats.byOperation[opKey] || 0) + 1;
|
|
181
|
+
}
|
|
182
|
+
// Calculate average duration
|
|
183
|
+
const durations = entries.filter((e) => e.result.duration).map((e) => e.result.duration);
|
|
184
|
+
if (durations.length > 0) {
|
|
185
|
+
stats.avgDuration = durations.reduce((a, b) => a + b, 0) / durations.length;
|
|
186
|
+
}
|
|
187
|
+
return stats;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Clear audit log (use with caution)
|
|
191
|
+
*
|
|
192
|
+
* @returns Number of entries cleared
|
|
193
|
+
*/
|
|
194
|
+
export async function clearAuditLog() {
|
|
195
|
+
try {
|
|
196
|
+
const entries = await readAuditLog();
|
|
197
|
+
const count = entries.length;
|
|
198
|
+
const logPath = getAuditLogPath();
|
|
199
|
+
await fs.unlink(logPath);
|
|
200
|
+
return count;
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
if (error.code === 'ENOENT') {
|
|
204
|
+
return 0;
|
|
205
|
+
}
|
|
206
|
+
throw error;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Check and rotate audit log if size exceeds limit
|
|
211
|
+
*
|
|
212
|
+
* Rotates log to timestamped archive file when size exceeds MAX_AUDIT_LOG_SIZE
|
|
213
|
+
*
|
|
214
|
+
* @param logPath Path to audit log file
|
|
215
|
+
*/
|
|
216
|
+
async function checkAndRotateLog(logPath) {
|
|
217
|
+
try {
|
|
218
|
+
const stats = await fs.stat(logPath);
|
|
219
|
+
if (stats.size >= MAX_AUDIT_LOG_SIZE) {
|
|
220
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
221
|
+
const archivePath = join(process.cwd(), '.cleo', `audit-log-${timestamp}.json`);
|
|
222
|
+
// Move current log to archive
|
|
223
|
+
await fs.rename(logPath, archivePath);
|
|
224
|
+
console.log(`Rotated audit log: ${archivePath} (${stats.size} bytes)`);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
catch (error) {
|
|
228
|
+
// If file doesn't exist, no rotation needed
|
|
229
|
+
if (error.code !== 'ENOENT') {
|
|
230
|
+
console.error('Failed to check/rotate audit log:', error);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Manually rotate audit log
|
|
236
|
+
*
|
|
237
|
+
* Forces rotation regardless of size
|
|
238
|
+
*
|
|
239
|
+
* @returns Path to rotated log file
|
|
240
|
+
*/
|
|
241
|
+
export async function rotateLog() {
|
|
242
|
+
try {
|
|
243
|
+
const logPath = getAuditLogPath();
|
|
244
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
245
|
+
const archivePath = join(process.cwd(), '.cleo', `audit-log-${timestamp}.json`);
|
|
246
|
+
// Check if log exists
|
|
247
|
+
try {
|
|
248
|
+
await fs.access(logPath);
|
|
249
|
+
}
|
|
250
|
+
catch {
|
|
251
|
+
return null; // No log to rotate
|
|
252
|
+
}
|
|
253
|
+
// Move current log to archive
|
|
254
|
+
await fs.rename(logPath, archivePath);
|
|
255
|
+
return archivePath;
|
|
256
|
+
}
|
|
257
|
+
catch (error) {
|
|
258
|
+
console.error('Failed to rotate audit log:', error);
|
|
259
|
+
return null;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Archive old audit entries
|
|
264
|
+
*
|
|
265
|
+
* Moves entries older than specified date to archive file
|
|
266
|
+
*
|
|
267
|
+
* @param beforeDate ISO date string
|
|
268
|
+
* @returns Number of entries archived
|
|
269
|
+
*/
|
|
270
|
+
export async function archiveAuditLog(beforeDate) {
|
|
271
|
+
try {
|
|
272
|
+
const entries = await readAuditLog();
|
|
273
|
+
const toArchive = entries.filter((e) => e.timestamp < beforeDate);
|
|
274
|
+
const toKeep = entries.filter((e) => e.timestamp >= beforeDate);
|
|
275
|
+
if (toArchive.length === 0) {
|
|
276
|
+
return 0;
|
|
277
|
+
}
|
|
278
|
+
// Write archive file
|
|
279
|
+
const archivePath = join(process.cwd(), '.cleo', `audit-log-archive-${beforeDate}.json`);
|
|
280
|
+
const archiveContent = toArchive.map((e) => JSON.stringify(e)).join('\n') + '\n';
|
|
281
|
+
await fs.writeFile(archivePath, archiveContent, 'utf8');
|
|
282
|
+
// Write remaining entries back to log
|
|
283
|
+
const logPath = getAuditLogPath();
|
|
284
|
+
const logContent = toKeep.map((e) => JSON.stringify(e)).join('\n') + '\n';
|
|
285
|
+
await fs.writeFile(logPath, logContent, 'utf8');
|
|
286
|
+
return toArchive.length;
|
|
287
|
+
}
|
|
288
|
+
catch (error) {
|
|
289
|
+
console.error('Failed to archive audit log:', error);
|
|
290
|
+
return 0;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Query audit log entries with filters
|
|
295
|
+
*
|
|
296
|
+
* @param options Query options
|
|
297
|
+
* @returns Filtered audit entries
|
|
298
|
+
*/
|
|
299
|
+
export async function queryAudit(options) {
|
|
300
|
+
const entries = await readAuditLog(options);
|
|
301
|
+
// Additional filters for new fields
|
|
302
|
+
let filtered = entries;
|
|
303
|
+
if (options?.taskId) {
|
|
304
|
+
filtered = filtered.filter((e) => e.metadata?.taskId === options.taskId);
|
|
305
|
+
}
|
|
306
|
+
if (options?.sessionId) {
|
|
307
|
+
filtered = filtered.filter((e) => e.sessionId === options.sessionId);
|
|
308
|
+
}
|
|
309
|
+
return filtered;
|
|
310
|
+
}
|
|
311
|
+
//# sourceMappingURL=audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/lib/audit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Background Job Manager for Long-Running Operations
|
|
3
|
+
*
|
|
4
|
+
* Per MCP-SERVER-SPECIFICATION.md Section 10, operations that may take >30s
|
|
5
|
+
* should support async execution. This module provides a job manager that
|
|
6
|
+
* tracks background operations with status, progress, and auto-cleanup.
|
|
7
|
+
*
|
|
8
|
+
* @task T3080
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Background job status
|
|
12
|
+
*/
|
|
13
|
+
export type JobStatus = 'running' | 'completed' | 'failed' | 'cancelled';
|
|
14
|
+
/**
|
|
15
|
+
* Background job representation
|
|
16
|
+
*/
|
|
17
|
+
export interface BackgroundJob {
|
|
18
|
+
id: string;
|
|
19
|
+
operation: string;
|
|
20
|
+
status: JobStatus;
|
|
21
|
+
startedAt: string;
|
|
22
|
+
completedAt?: string;
|
|
23
|
+
result?: unknown;
|
|
24
|
+
error?: string;
|
|
25
|
+
progress?: number;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Configuration for BackgroundJobManager
|
|
29
|
+
*/
|
|
30
|
+
export interface BackgroundJobManagerConfig {
|
|
31
|
+
maxJobs?: number;
|
|
32
|
+
retentionMs?: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Manages background jobs for long-running operations
|
|
36
|
+
*/
|
|
37
|
+
export declare class BackgroundJobManager {
|
|
38
|
+
private jobs;
|
|
39
|
+
private abortControllers;
|
|
40
|
+
private maxJobs;
|
|
41
|
+
private retentionMs;
|
|
42
|
+
private cleanupTimer;
|
|
43
|
+
constructor(config?: BackgroundJobManagerConfig);
|
|
44
|
+
/**
|
|
45
|
+
* Start a new background job
|
|
46
|
+
*
|
|
47
|
+
* @param operation - The operation identifier (e.g. "validate.test.run")
|
|
48
|
+
* @param executor - Async function to execute in the background
|
|
49
|
+
* @returns The job ID
|
|
50
|
+
* @throws Error if max concurrent jobs reached
|
|
51
|
+
*/
|
|
52
|
+
startJob(operation: string, executor: () => Promise<unknown>): Promise<string>;
|
|
53
|
+
/**
|
|
54
|
+
* Get a specific job by ID
|
|
55
|
+
*/
|
|
56
|
+
getJob(jobId: string): BackgroundJob | undefined;
|
|
57
|
+
/**
|
|
58
|
+
* List all jobs, optionally filtered by status
|
|
59
|
+
*/
|
|
60
|
+
listJobs(status?: string): BackgroundJob[];
|
|
61
|
+
/**
|
|
62
|
+
* Cancel a running job
|
|
63
|
+
*
|
|
64
|
+
* @returns true if the job was cancelled, false if not found or not running
|
|
65
|
+
*/
|
|
66
|
+
cancelJob(jobId: string): boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Update job progress (0-100)
|
|
69
|
+
*/
|
|
70
|
+
updateProgress(jobId: string, progress: number): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Cleanup old completed/failed/cancelled jobs past retention period
|
|
73
|
+
*
|
|
74
|
+
* @returns Number of jobs cleaned up
|
|
75
|
+
*/
|
|
76
|
+
cleanup(): number;
|
|
77
|
+
/**
|
|
78
|
+
* Destroy the manager: cancel all running jobs and clear state
|
|
79
|
+
*/
|
|
80
|
+
destroy(): void;
|
|
81
|
+
/**
|
|
82
|
+
* Execute a job's executor function and update status on completion/failure
|
|
83
|
+
*/
|
|
84
|
+
private executeJob;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=background-jobs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"background-jobs.d.ts","sourceRoot":"","sources":["../../src/lib/background-jobs.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEzE;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,SAAS,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,IAAI,CAA6B;IACzC,OAAO,CAAC,gBAAgB,CAA+B;IACvD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,YAAY,CAAwC;gBAEhD,MAAM,CAAC,EAAE,0BAA0B;IAe/C;;;;;;;OAOG;IACG,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IA4BpF;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAIhD;;OAEG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,EAAE;IAQ1C;;;;OAIG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAkBjC;;OAEG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;IASxD;;;;OAIG;IACH,OAAO,IAAI,MAAM;IAqBjB;;OAEG;IACH,OAAO,IAAI,IAAI;IAoBf;;OAEG;YACW,UAAU;CAmCzB"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Background Job Manager for Long-Running Operations
|
|
3
|
+
*
|
|
4
|
+
* Per MCP-SERVER-SPECIFICATION.md Section 10, operations that may take >30s
|
|
5
|
+
* should support async execution. This module provides a job manager that
|
|
6
|
+
* tracks background operations with status, progress, and auto-cleanup.
|
|
7
|
+
*
|
|
8
|
+
* @task T3080
|
|
9
|
+
*/
|
|
10
|
+
import { randomUUID } from 'crypto';
|
|
11
|
+
/**
|
|
12
|
+
* Manages background jobs for long-running operations
|
|
13
|
+
*/
|
|
14
|
+
export class BackgroundJobManager {
|
|
15
|
+
jobs;
|
|
16
|
+
abortControllers;
|
|
17
|
+
maxJobs;
|
|
18
|
+
retentionMs;
|
|
19
|
+
cleanupTimer;
|
|
20
|
+
constructor(config) {
|
|
21
|
+
this.jobs = new Map();
|
|
22
|
+
this.abortControllers = new Map();
|
|
23
|
+
this.maxJobs = config?.maxJobs ?? 10;
|
|
24
|
+
this.retentionMs = config?.retentionMs ?? 3600000; // 1 hour default
|
|
25
|
+
this.cleanupTimer = null;
|
|
26
|
+
// Start periodic cleanup every 5 minutes
|
|
27
|
+
this.cleanupTimer = setInterval(() => this.cleanup(), 300000);
|
|
28
|
+
// Don't prevent process exit
|
|
29
|
+
if (this.cleanupTimer.unref) {
|
|
30
|
+
this.cleanupTimer.unref();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Start a new background job
|
|
35
|
+
*
|
|
36
|
+
* @param operation - The operation identifier (e.g. "validate.test.run")
|
|
37
|
+
* @param executor - Async function to execute in the background
|
|
38
|
+
* @returns The job ID
|
|
39
|
+
* @throws Error if max concurrent jobs reached
|
|
40
|
+
*/
|
|
41
|
+
async startJob(operation, executor) {
|
|
42
|
+
// Check concurrent job limit (only count running jobs)
|
|
43
|
+
const runningCount = this.listJobs('running').length;
|
|
44
|
+
if (runningCount >= this.maxJobs) {
|
|
45
|
+
throw new Error(`Maximum concurrent jobs reached (${this.maxJobs}). Cancel or wait for existing jobs to complete.`);
|
|
46
|
+
}
|
|
47
|
+
const jobId = randomUUID();
|
|
48
|
+
const abortController = new AbortController();
|
|
49
|
+
const job = {
|
|
50
|
+
id: jobId,
|
|
51
|
+
operation,
|
|
52
|
+
status: 'running',
|
|
53
|
+
startedAt: new Date().toISOString(),
|
|
54
|
+
};
|
|
55
|
+
this.jobs.set(jobId, job);
|
|
56
|
+
this.abortControllers.set(jobId, abortController);
|
|
57
|
+
// Execute async - don't await
|
|
58
|
+
this.executeJob(jobId, executor, abortController.signal);
|
|
59
|
+
return jobId;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Get a specific job by ID
|
|
63
|
+
*/
|
|
64
|
+
getJob(jobId) {
|
|
65
|
+
return this.jobs.get(jobId);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* List all jobs, optionally filtered by status
|
|
69
|
+
*/
|
|
70
|
+
listJobs(status) {
|
|
71
|
+
const all = Array.from(this.jobs.values());
|
|
72
|
+
if (!status) {
|
|
73
|
+
return all;
|
|
74
|
+
}
|
|
75
|
+
return all.filter((job) => job.status === status);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Cancel a running job
|
|
79
|
+
*
|
|
80
|
+
* @returns true if the job was cancelled, false if not found or not running
|
|
81
|
+
*/
|
|
82
|
+
cancelJob(jobId) {
|
|
83
|
+
const job = this.jobs.get(jobId);
|
|
84
|
+
if (!job || job.status !== 'running') {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
const controller = this.abortControllers.get(jobId);
|
|
88
|
+
if (controller) {
|
|
89
|
+
controller.abort();
|
|
90
|
+
this.abortControllers.delete(jobId);
|
|
91
|
+
}
|
|
92
|
+
job.status = 'cancelled';
|
|
93
|
+
job.completedAt = new Date().toISOString();
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Update job progress (0-100)
|
|
98
|
+
*/
|
|
99
|
+
updateProgress(jobId, progress) {
|
|
100
|
+
const job = this.jobs.get(jobId);
|
|
101
|
+
if (!job || job.status !== 'running') {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
job.progress = Math.max(0, Math.min(100, progress));
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Cleanup old completed/failed/cancelled jobs past retention period
|
|
109
|
+
*
|
|
110
|
+
* @returns Number of jobs cleaned up
|
|
111
|
+
*/
|
|
112
|
+
cleanup() {
|
|
113
|
+
const now = Date.now();
|
|
114
|
+
let cleaned = 0;
|
|
115
|
+
for (const [id, job] of this.jobs.entries()) {
|
|
116
|
+
if (job.status === 'running') {
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
if (job.completedAt) {
|
|
120
|
+
const completedTime = new Date(job.completedAt).getTime();
|
|
121
|
+
if (now - completedTime > this.retentionMs) {
|
|
122
|
+
this.jobs.delete(id);
|
|
123
|
+
this.abortControllers.delete(id);
|
|
124
|
+
cleaned++;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return cleaned;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Destroy the manager: cancel all running jobs and clear state
|
|
132
|
+
*/
|
|
133
|
+
destroy() {
|
|
134
|
+
// Cancel all running jobs
|
|
135
|
+
for (const [id, job] of this.jobs.entries()) {
|
|
136
|
+
if (job.status === 'running') {
|
|
137
|
+
const controller = this.abortControllers.get(id);
|
|
138
|
+
if (controller) {
|
|
139
|
+
controller.abort();
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
this.jobs.clear();
|
|
144
|
+
this.abortControllers.clear();
|
|
145
|
+
if (this.cleanupTimer) {
|
|
146
|
+
clearInterval(this.cleanupTimer);
|
|
147
|
+
this.cleanupTimer = null;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Execute a job's executor function and update status on completion/failure
|
|
152
|
+
*/
|
|
153
|
+
async executeJob(jobId, executor, signal) {
|
|
154
|
+
const job = this.jobs.get(jobId);
|
|
155
|
+
if (!job) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
try {
|
|
159
|
+
const result = await executor();
|
|
160
|
+
// Check if cancelled during execution
|
|
161
|
+
if (signal.aborted) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
job.status = 'completed';
|
|
165
|
+
job.completedAt = new Date().toISOString();
|
|
166
|
+
job.result = result;
|
|
167
|
+
job.progress = 100;
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
// Check if this was a cancellation
|
|
171
|
+
if (signal.aborted) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
job.status = 'failed';
|
|
175
|
+
job.completedAt = new Date().toISOString();
|
|
176
|
+
job.error = error instanceof Error ? error.message : String(error);
|
|
177
|
+
}
|
|
178
|
+
finally {
|
|
179
|
+
this.abortControllers.delete(jobId);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=background-jobs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"background-jobs.js","sourceRoot":"","sources":["../../src/lib/background-jobs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory query cache for CLEO MCP Server
|
|
3
|
+
*
|
|
4
|
+
* Caches cleo_query responses with configurable TTL.
|
|
5
|
+
* Cache key = domain + operation + hash(params).
|
|
6
|
+
* Invalidated on any cleo_mutate operation for the relevant domain.
|
|
7
|
+
*
|
|
8
|
+
* @task T3145
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Cache statistics
|
|
12
|
+
*/
|
|
13
|
+
export interface CacheStats {
|
|
14
|
+
hits: number;
|
|
15
|
+
misses: number;
|
|
16
|
+
evictions: number;
|
|
17
|
+
size: number;
|
|
18
|
+
domains: Record<string, number>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Query cache with per-domain invalidation
|
|
22
|
+
*/
|
|
23
|
+
export declare class QueryCache {
|
|
24
|
+
private store;
|
|
25
|
+
private domainKeys;
|
|
26
|
+
private stats;
|
|
27
|
+
private ttl;
|
|
28
|
+
private enabled;
|
|
29
|
+
private cleanupTimer;
|
|
30
|
+
constructor(ttlMs?: number, enabled?: boolean);
|
|
31
|
+
/**
|
|
32
|
+
* Build cache key from domain, operation, and params
|
|
33
|
+
*/
|
|
34
|
+
buildKey(domain: string, operation: string, params?: Record<string, unknown>): string;
|
|
35
|
+
/**
|
|
36
|
+
* Get cached value, or undefined if not found/expired
|
|
37
|
+
*/
|
|
38
|
+
get<T = unknown>(domain: string, operation: string, params?: Record<string, unknown>): T | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* Store a value in the cache
|
|
41
|
+
*/
|
|
42
|
+
set<T = unknown>(domain: string, operation: string, params: Record<string, unknown> | undefined, value: T): void;
|
|
43
|
+
/**
|
|
44
|
+
* Invalidate all cached entries for a domain
|
|
45
|
+
*
|
|
46
|
+
* Called on any cleo_mutate operation to ensure consistency.
|
|
47
|
+
*/
|
|
48
|
+
invalidateDomain(domain: string): number;
|
|
49
|
+
/**
|
|
50
|
+
* Clear entire cache
|
|
51
|
+
*/
|
|
52
|
+
clear(): void;
|
|
53
|
+
/**
|
|
54
|
+
* Get cache statistics
|
|
55
|
+
*/
|
|
56
|
+
getStats(): CacheStats;
|
|
57
|
+
/**
|
|
58
|
+
* Reset statistics counters
|
|
59
|
+
*/
|
|
60
|
+
resetStats(): void;
|
|
61
|
+
/**
|
|
62
|
+
* Evict all expired entries
|
|
63
|
+
*/
|
|
64
|
+
evictExpired(): number;
|
|
65
|
+
/**
|
|
66
|
+
* Stop the cleanup timer (call on shutdown)
|
|
67
|
+
*/
|
|
68
|
+
destroy(): void;
|
|
69
|
+
/**
|
|
70
|
+
* Check if cache is enabled
|
|
71
|
+
*/
|
|
72
|
+
isEnabled(): boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Delete a single key and update domain tracking
|
|
75
|
+
*/
|
|
76
|
+
private delete;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=cache.d.ts.map
|