kortext 2.2.3 → 3.0.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/AGENTS.md +0 -4
- package/CHANGELOG.md +81 -0
- package/LICENSE +21 -0
- package/README.md +145 -55
- package/USER-GUIDE.md +505 -0
- package/bin/kortext.js +23 -0
- package/bin/kortext.ts +377 -0
- package/dist/bin/kortext.js +346 -0
- package/dist/bin/kortext.js.map +1 -0
- package/dist/mcp/index.js +4 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/server.js +553 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/sse.js +38 -0
- package/dist/mcp/sse.js.map +1 -0
- package/dist/mcp/stdio.js +44 -0
- package/dist/mcp/stdio.js.map +1 -0
- package/dist/server/cli/cleanup.js +73 -0
- package/dist/server/cli/cleanup.js.map +1 -0
- package/dist/server/cli/commands.js +73 -0
- package/dist/server/cli/commands.js.map +1 -0
- package/dist/server/cli/doctor.js +118 -0
- package/dist/server/cli/doctor.js.map +1 -0
- package/dist/server/cli/executor-factory.js +39 -0
- package/dist/server/cli/executor-factory.js.map +1 -0
- package/dist/server/cli/init.js +121 -0
- package/dist/server/cli/init.js.map +1 -0
- package/dist/server/cli/logs.js +28 -0
- package/dist/server/cli/logs.js.map +1 -0
- package/dist/server/cli/serve.js +72 -0
- package/dist/server/cli/serve.js.map +1 -0
- package/dist/server/config/env.js +12 -0
- package/dist/server/config/env.js.map +1 -0
- package/dist/server/db/client.js +32 -0
- package/dist/server/db/client.js.map +1 -0
- package/dist/server/db/json.js +21 -0
- package/dist/server/db/json.js.map +1 -0
- package/dist/server/db/migrate.js +70 -0
- package/dist/server/db/migrate.js.map +1 -0
- package/dist/server/db/migrations/001_init.sql +243 -0
- package/dist/server/db/repositories/audit-log.js +58 -0
- package/dist/server/db/repositories/audit-log.js.map +1 -0
- package/dist/server/db/repositories/backlog.js +96 -0
- package/dist/server/db/repositories/backlog.js.map +1 -0
- package/dist/server/db/repositories/contexts.js +54 -0
- package/dist/server/db/repositories/contexts.js.map +1 -0
- package/dist/server/db/repositories/decisions.js +71 -0
- package/dist/server/db/repositories/decisions.js.map +1 -0
- package/dist/server/db/repositories/handovers.js +53 -0
- package/dist/server/db/repositories/handovers.js.map +1 -0
- package/dist/server/db/repositories/index.js +30 -0
- package/dist/server/db/repositories/index.js.map +1 -0
- package/dist/server/db/repositories/locks.js +59 -0
- package/dist/server/db/repositories/locks.js.map +1 -0
- package/dist/server/db/repositories/notifications.js +63 -0
- package/dist/server/db/repositories/notifications.js.map +1 -0
- package/dist/server/db/repositories/pending-questions.js +63 -0
- package/dist/server/db/repositories/pending-questions.js.map +1 -0
- package/dist/server/db/repositories/runs.js +138 -0
- package/dist/server/db/repositories/runs.js.map +1 -0
- package/dist/server/db/repositories/runtime-artifacts.js +39 -0
- package/dist/server/db/repositories/runtime-artifacts.js.map +1 -0
- package/dist/server/db/repositories/secrets.js +65 -0
- package/dist/server/db/repositories/secrets.js.map +1 -0
- package/dist/server/db/repositories/sessions.js +48 -0
- package/dist/server/db/repositories/sessions.js.map +1 -0
- package/dist/server/db/schemas.js +308 -0
- package/dist/server/db/schemas.js.map +1 -0
- package/dist/server/engine/consistency.js +25 -0
- package/dist/server/engine/consistency.js.map +1 -0
- package/dist/server/engine/dag.js +86 -0
- package/dist/server/engine/dag.js.map +1 -0
- package/dist/server/engine/executor.js +2 -0
- package/dist/server/engine/executor.js.map +1 -0
- package/dist/server/engine/executors/claude-cli-executor.js +83 -0
- package/dist/server/engine/executors/claude-cli-executor.js.map +1 -0
- package/dist/server/engine/executors/cli-spawn.js +127 -0
- package/dist/server/engine/executors/cli-spawn.js.map +1 -0
- package/dist/server/engine/executors/codex-cli-executor.js +69 -0
- package/dist/server/engine/executors/codex-cli-executor.js.map +1 -0
- package/dist/server/engine/executors/gemini-cli-executor.js +69 -0
- package/dist/server/engine/executors/gemini-cli-executor.js.map +1 -0
- package/dist/server/engine/executors/mock-executor.js +52 -0
- package/dist/server/engine/executors/mock-executor.js.map +1 -0
- package/dist/server/engine/executors/persona-routed-executor.js +17 -0
- package/dist/server/engine/executors/persona-routed-executor.js.map +1 -0
- package/dist/server/engine/gate-enforcer.js +75 -0
- package/dist/server/engine/gate-enforcer.js.map +1 -0
- package/dist/server/engine/git-commit.js +42 -0
- package/dist/server/engine/git-commit.js.map +1 -0
- package/dist/server/engine/handover.js +120 -0
- package/dist/server/engine/handover.js.map +1 -0
- package/dist/server/engine/item-lifecycle.js +74 -0
- package/dist/server/engine/item-lifecycle.js.map +1 -0
- package/dist/server/engine/persona-registry.js +108 -0
- package/dist/server/engine/persona-registry.js.map +1 -0
- package/dist/server/engine/worker-pool.js +324 -0
- package/dist/server/engine/worker-pool.js.map +1 -0
- package/dist/server/engine/workflow-loader.js +55 -0
- package/dist/server/engine/workflow-loader.js.map +1 -0
- package/dist/server/engine/workflow-parser.js +158 -0
- package/dist/server/engine/workflow-parser.js.map +1 -0
- package/dist/server/engine/worktree.js +176 -0
- package/dist/server/engine/worktree.js.map +1 -0
- package/dist/server/index.js +99 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/notifications/dispatcher.js +60 -0
- package/dist/server/notifications/dispatcher.js.map +1 -0
- package/dist/server/notifications/slack.js +37 -0
- package/dist/server/notifications/slack.js.map +1 -0
- package/dist/server/notifications/telegram.js +33 -0
- package/dist/server/notifications/telegram.js.map +1 -0
- package/dist/server/orchestrator/approval-queue.js +83 -0
- package/dist/server/orchestrator/approval-queue.js.map +1 -0
- package/dist/server/orchestrator/blueprint-watcher.js +94 -0
- package/dist/server/orchestrator/blueprint-watcher.js.map +1 -0
- package/dist/server/orchestrator/orchestrator.js +283 -0
- package/dist/server/orchestrator/orchestrator.js.map +1 -0
- package/dist/server/orchestrator/pipeline-chainer.js +96 -0
- package/dist/server/orchestrator/pipeline-chainer.js.map +1 -0
- package/dist/server/orchestrator/resume.js +36 -0
- package/dist/server/orchestrator/resume.js.map +1 -0
- package/dist/server/routes/approvals.js +52 -0
- package/dist/server/routes/approvals.js.map +1 -0
- package/dist/server/routes/backlog.js +44 -0
- package/dist/server/routes/backlog.js.map +1 -0
- package/dist/server/routes/db-info.js +21 -0
- package/dist/server/routes/db-info.js.map +1 -0
- package/dist/server/routes/docs.js +70 -0
- package/dist/server/routes/docs.js.map +1 -0
- package/dist/server/routes/doctor.js +19 -0
- package/dist/server/routes/doctor.js.map +1 -0
- package/dist/server/routes/handovers.js +25 -0
- package/dist/server/routes/handovers.js.map +1 -0
- package/dist/server/routes/health.js +11 -0
- package/dist/server/routes/health.js.map +1 -0
- package/dist/server/routes/personas.js +96 -0
- package/dist/server/routes/personas.js.map +1 -0
- package/dist/server/routes/runs.js +41 -0
- package/dist/server/routes/runs.js.map +1 -0
- package/dist/server/routes/workflows.js +38 -0
- package/dist/server/routes/workflows.js.map +1 -0
- package/dist/server/safety/harmful-output-filter.js +40 -0
- package/dist/server/safety/harmful-output-filter.js.map +1 -0
- package/dist/server/safety/secret-scanner.js +169 -0
- package/dist/server/safety/secret-scanner.js.map +1 -0
- package/dist/server/services/markdown-sync.js +101 -0
- package/dist/server/services/markdown-sync.js.map +1 -0
- package/dist/web/assets/index-B80d5ZPZ.js +75 -0
- package/dist/web/assets/index-B80d5ZPZ.js.map +1 -0
- package/dist/web/assets/index-Bge5Gzqv.css +1 -0
- package/dist/web/index.html +13 -0
- package/docs/architecture.md +413 -0
- package/package.json +83 -11
- package/scripts/copy-migrations.mjs +29 -0
- package/workspace/.locks/workspace_handover.md.lock +3 -0
- package/hooks/audit-logger.sh +0 -25
- package/hooks/auto-locker.sh +0 -74
- package/hooks/auto-unlocker.sh +0 -17
- package/hooks/backlog-sync-guard.sh +0 -12
- package/hooks/branch-guard.sh +0 -32
- package/hooks/commit-msg-guard.sh +0 -43
- package/hooks/git-pre-commit.sh +0 -76
- package/hooks/git-pre-push.sh +0 -17
- package/hooks/handover-guard.sh +0 -33
- package/hooks/kortext-init.sh +0 -194
- package/hooks/kortext-lib.sh +0 -151
- package/hooks/lint-guard.sh +0 -50
- package/hooks/secret-scanner.sh +0 -89
- package/hooks/size-guard.sh +0 -48
- package/hooks/snapshot-guard.sh +0 -39
- package/hooks/write-guard.sh +0 -77
- package/scripts/kortext-backlog-add.py +0 -123
- package/scripts/kortext-backlog-health.py +0 -112
- package/scripts/kortext-backlog-sync.py +0 -117
- package/scripts/kortext-bulk-plan.py +0 -63
- package/scripts/kortext-cli.py +0 -376
- package/scripts/kortext-consistency-check.py +0 -74
- package/scripts/kortext-context-check.py +0 -146
- package/scripts/kortext-handover.py +0 -107
- package/scripts/kortext-item-check.py +0 -61
- package/scripts/kortext-item-start.py +0 -70
- package/scripts/kortext-item-transition.py +0 -78
- package/scripts/kortext-lock.py +0 -174
- package/scripts/kortext-session-start.py +0 -127
- package/scripts/lock_kortext.sh +0 -34
- package/settings/.claude-settings.template.json +0 -48
- package/settings/CHANGELOG.md +0 -176
- package/settings/INTEGRATION-MAP.md +0 -276
- package/settings/README.md +0 -255
- package/settings/USER-GUIDE.md +0 -502
- package/settings/VERSION +0 -1
- package/settings/config.md +0 -8
- package/settings/runtime-adapters.md +0 -104
- package/skills/backend-developer/.gitkeep +0 -0
- package/skills/compliance-expert/.gitkeep +0 -0
- package/skills/copywriter/.gitkeep +0 -0
- package/skills/db-admin/.gitkeep +0 -0
- package/skills/delivery-manager/.gitkeep +0 -0
- package/skills/designer/.gitkeep +0 -0
- package/skills/devops-engineer/.gitkeep +0 -0
- package/skills/engineering-manager/.gitkeep +0 -0
- package/skills/frontend-developer/.gitkeep +0 -0
- package/skills/growth-expert/.gitkeep +0 -0
- package/skills/operation-manager/.gitkeep +0 -0
- package/skills/product-manager/.gitkeep +0 -0
- package/skills/qa-engineer/.gitkeep +0 -0
- package/skills/security-engineer/.gitkeep +0 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stdio entry — what `kortext mcp` spawns.
|
|
3
|
+
*
|
|
4
|
+
* Reads from stdin / writes JSON-RPC frames to stdout. CRITICAL: nothing
|
|
5
|
+
* besides MCP frames may go to stdout — every log line is routed to stderr.
|
|
6
|
+
* The CLI sets `console.log = console.error` defensively before this loads.
|
|
7
|
+
*/
|
|
8
|
+
import { resolve } from 'node:path';
|
|
9
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
10
|
+
import { getDb } from "../server/db/client.js";
|
|
11
|
+
import { loadWorkflowsFromDir } from "../server/engine/workflow-loader.js";
|
|
12
|
+
import { loadPersonasFromDir } from "../server/engine/persona-registry.js";
|
|
13
|
+
import { ApprovalQueue } from "../server/orchestrator/approval-queue.js";
|
|
14
|
+
import { createKortextMcpServer } from "./server.js";
|
|
15
|
+
export async function runStdioServer(opts = {}) {
|
|
16
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
17
|
+
const log = (msg) => process.stderr.write(`[kortext-mcp] ${msg}\n`);
|
|
18
|
+
const { schemaVersion, repositories: repos } = getDb();
|
|
19
|
+
log(`db ready (schema v${schemaVersion})`);
|
|
20
|
+
const workflowsDir = resolve(cwd, 'workflows');
|
|
21
|
+
const agentsDir = resolve(cwd, 'agents');
|
|
22
|
+
const workflows = loadWorkflowsFromDir(workflowsDir);
|
|
23
|
+
const personas = loadPersonasFromDir(agentsDir);
|
|
24
|
+
log(`loaded ${workflows.list().length} workflow(s), ${personas.list().length} persona(s)`);
|
|
25
|
+
const queue = new ApprovalQueue({ repos });
|
|
26
|
+
const server = createKortextMcpServer({
|
|
27
|
+
repos,
|
|
28
|
+
workflows,
|
|
29
|
+
personas,
|
|
30
|
+
queue,
|
|
31
|
+
workspaceRoot: cwd,
|
|
32
|
+
workflowsDir,
|
|
33
|
+
});
|
|
34
|
+
const transport = new StdioServerTransport();
|
|
35
|
+
await server.connect(transport);
|
|
36
|
+
log('mcp server connected on stdio');
|
|
37
|
+
const shutdown = (signal) => {
|
|
38
|
+
log(`received ${signal}, closing`);
|
|
39
|
+
void server.close().finally(() => process.exit(0));
|
|
40
|
+
};
|
|
41
|
+
process.on('SIGINT', () => shutdown('SIGINT'));
|
|
42
|
+
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=stdio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdio.js","sourceRoot":"","sources":["../../mcp/stdio.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,0CAA0C,CAAC;AACzE,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAErD,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAyB,EAAE;IAC9D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACtC,MAAM,GAAG,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;IAE5E,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,CAAC;IACvD,GAAG,CAAC,qBAAqB,aAAa,GAAG,CAAC,CAAC;IAE3C,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IAC/C,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACzC,MAAM,SAAS,GAAG,oBAAoB,CAAC,YAAY,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAChD,GAAG,CACD,UAAU,SAAS,CAAC,IAAI,EAAE,CAAC,MAAM,iBAAiB,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,aAAa,CACtF,CAAC;IAEF,MAAM,KAAK,GAAG,IAAI,aAAa,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,sBAAsB,CAAC;QACpC,KAAK;QACL,SAAS;QACT,QAAQ;QACR,KAAK;QACL,aAAa,EAAE,GAAG;QAClB,YAAY;KACb,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,GAAG,CAAC,+BAA+B,CAAC,CAAC;IAErC,MAAM,QAAQ,GAAG,CAAC,MAAc,EAAE,EAAE;QAClC,GAAG,CAAC,YAAY,MAAM,WAAW,CAAC,CAAC;QACnC,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,CAAC,CAAC;IACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC/C,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import * as cp from 'node:child_process';
|
|
2
|
+
import { existsSync, readdirSync, rmSync, statSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
const runFile = cp.execFileSync;
|
|
5
|
+
const TERMINAL_RUN_STATUSES = new Set([
|
|
6
|
+
'succeeded',
|
|
7
|
+
'failed',
|
|
8
|
+
'cancelled',
|
|
9
|
+
]);
|
|
10
|
+
export async function cleanupQuarantine(opts) {
|
|
11
|
+
if (!existsSync(opts.quarantineRoot)) {
|
|
12
|
+
return { deleted: [], kept: [], dryRun: opts.dryRun };
|
|
13
|
+
}
|
|
14
|
+
const cutoffMs = Date.now() - opts.olderThanDays * 86400 * 1000;
|
|
15
|
+
const deleted = [];
|
|
16
|
+
const kept = [];
|
|
17
|
+
for (const entry of readdirSync(opts.quarantineRoot)) {
|
|
18
|
+
const full = join(opts.quarantineRoot, entry);
|
|
19
|
+
let mtimeMs;
|
|
20
|
+
try {
|
|
21
|
+
mtimeMs = statSync(full).mtimeMs;
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
if (mtimeMs < cutoffMs) {
|
|
27
|
+
deleted.push(full);
|
|
28
|
+
if (!opts.dryRun)
|
|
29
|
+
rmSync(full, { recursive: true, force: true });
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
kept.push(full);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return { deleted, kept, dryRun: opts.dryRun };
|
|
36
|
+
}
|
|
37
|
+
const BRANCH_NAME_RE = /^kortext\/run-(\d+)$/;
|
|
38
|
+
export async function cleanupBranches(opts) {
|
|
39
|
+
const listed = runFile('git', ['branch', '--list', 'kortext/run-*', '--format=%(refname:short)'], { cwd: opts.repoRoot, encoding: 'utf8' });
|
|
40
|
+
const branches = listed
|
|
41
|
+
.split('\n')
|
|
42
|
+
.map((s) => s.trim())
|
|
43
|
+
.filter((s) => s.length > 0);
|
|
44
|
+
const deleted = [];
|
|
45
|
+
const kept = [];
|
|
46
|
+
for (const branch of branches) {
|
|
47
|
+
const match = BRANCH_NAME_RE.exec(branch);
|
|
48
|
+
if (!match || !match[1]) {
|
|
49
|
+
kept.push(branch);
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
const runId = Number(match[1]);
|
|
53
|
+
const run = opts.repos.runs.getRun(runId);
|
|
54
|
+
if (!run || !TERMINAL_RUN_STATUSES.has(run.status)) {
|
|
55
|
+
kept.push(branch);
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
deleted.push(branch);
|
|
59
|
+
if (!opts.dryRun) {
|
|
60
|
+
try {
|
|
61
|
+
runFile('git', ['branch', '-D', branch], {
|
|
62
|
+
cwd: opts.repoRoot,
|
|
63
|
+
stdio: ['ignore', 'ignore', 'pipe'],
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
// Branch may have been deleted between listing and now — non-fatal.
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return { deleted, kept, dryRun: opts.dryRun };
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=cleanup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleanup.js","sourceRoot":"","sources":["../../../server/cli/cleanup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { isAbsolute, resolve } from 'node:path';
|
|
2
|
+
import { loadWorkflowsFromDir } from "../engine/workflow-loader.js";
|
|
3
|
+
import { loadPersonasFromDir } from "../engine/persona-registry.js";
|
|
4
|
+
import { buildGraph } from "../engine/dag.js";
|
|
5
|
+
import { runWorkflow } from "../engine/worker-pool.js";
|
|
6
|
+
import { createExecutor } from "./executor-factory.js";
|
|
7
|
+
export async function startCommand(input) {
|
|
8
|
+
const workflowsDir = isAbsolute(input.workflowsDir)
|
|
9
|
+
? input.workflowsDir
|
|
10
|
+
: resolve(process.cwd(), input.workflowsDir);
|
|
11
|
+
const registry = loadWorkflowsFromDir(workflowsDir);
|
|
12
|
+
const def = registry.get(input.workflowId);
|
|
13
|
+
if (!def) {
|
|
14
|
+
const loadError = registry.errors().find((e) => e.file === `${input.workflowId}.md`);
|
|
15
|
+
if (loadError) {
|
|
16
|
+
return {
|
|
17
|
+
ok: false,
|
|
18
|
+
errorMessage: `workflow '${input.workflowId}' not loadable: ${loadError.reason}`,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
ok: false,
|
|
23
|
+
errorMessage: `workflow not found: ${input.workflowId} (in ${workflowsDir})`,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
if (input.executor !== 'mock' && !input.executorBinary) {
|
|
27
|
+
return {
|
|
28
|
+
ok: false,
|
|
29
|
+
errorMessage: `executor '${input.executor}' requires --binary (or KORTEXT_${input.executor.toUpperCase()}_BIN env var)`,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
const graph = buildGraph(def);
|
|
33
|
+
const agentsDir = input.agentsDir ?? resolve(process.cwd(), 'agents');
|
|
34
|
+
// Mock executor doesn't read personas — skip the disk scan when possible.
|
|
35
|
+
const personaRegistry = input.executor === 'mock' ? undefined : loadPersonasFromDir(agentsDir);
|
|
36
|
+
const executor = createExecutor(input.executor, {
|
|
37
|
+
binary: input.executorBinary ?? '',
|
|
38
|
+
agentsDir,
|
|
39
|
+
logsDir: input.logsDir ?? resolve(process.cwd(), '.kortext', 'logs'),
|
|
40
|
+
personaRegistry,
|
|
41
|
+
});
|
|
42
|
+
const result = await runWorkflow(graph, executor, input.repos, {
|
|
43
|
+
concurrency: input.concurrency ?? 3,
|
|
44
|
+
triggeredBy: 'cli',
|
|
45
|
+
});
|
|
46
|
+
return {
|
|
47
|
+
ok: true,
|
|
48
|
+
runId: result.run.id,
|
|
49
|
+
status: result.run.status,
|
|
50
|
+
failedStepKey: result.failedStepKey,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
export async function approveCommand(input) {
|
|
54
|
+
const open = input.queue.findOpenForRun(input.runId);
|
|
55
|
+
if (!open) {
|
|
56
|
+
return { ok: false, errorMessage: `no open question for run ${input.runId}` };
|
|
57
|
+
}
|
|
58
|
+
try {
|
|
59
|
+
const answered = input.queue.answer(open.id, input.answer, input.answeredBy);
|
|
60
|
+
return { ok: true, questionId: open.id, answer: answered.answer ?? input.answer };
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
return { ok: false, errorMessage: err instanceof Error ? err.message : String(err) };
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export function statusCommand(input) {
|
|
67
|
+
const limit = input.limit ?? 10;
|
|
68
|
+
return {
|
|
69
|
+
recentRuns: input.repos.runs.listRuns({ limit }),
|
|
70
|
+
openQuestions: input.repos.pendingQuestions.listOpen(),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../../server/cli/commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGhD,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,cAAc,EAAqB,MAAM,uBAAuB,CAAC;AAwB1E,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,KAAwB;IACzD,MAAM,YAAY,GAAG,UAAU,CAAC,KAAK,CAAC,YAAY,CAAC;QACjD,CAAC,CAAC,KAAK,CAAC,YAAY;QACpB,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;IAE/C,MAAM,QAAQ,GAAG,oBAAoB,CAAC,YAAY,CAAC,CAAC;IACpD,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC3C,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,KAAK,CAAC,UAAU,KAAK,CAAC,CAAC;QACrF,IAAI,SAAS,EAAE,CAAC;YACd,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,YAAY,EAAE,aAAa,KAAK,CAAC,UAAU,mBAAmB,SAAS,CAAC,MAAM,EAAE;aACjF,CAAC;QACJ,CAAC;QACD,OAAO;YACL,EAAE,EAAE,KAAK;YACT,YAAY,EAAE,uBAAuB,KAAK,CAAC,UAAU,QAAQ,YAAY,GAAG;SAC7E,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,CAAC,QAAQ,KAAK,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC;QACvD,OAAO;YACL,EAAE,EAAE,KAAK;YACT,YAAY,EAAE,aAAa,KAAK,CAAC,QAAQ,mCAAmC,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE,eAAe;SACxH,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;IAC9B,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC;IACtE,0EAA0E;IAC1E,MAAM,eAAe,GACnB,KAAK,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC;IACzE,MAAM,QAAQ,GAAG,cAAc,CAAC,KAAK,CAAC,QAAQ,EAAE;QAC9C,MAAM,EAAE,KAAK,CAAC,cAAc,IAAI,EAAE;QAClC,SAAS;QACT,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,EAAE,MAAM,CAAC;QACpE,eAAe;KAChB,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,KAAK,EAAE;QAC7D,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,CAAC;QACnC,WAAW,EAAE,KAAK;KACnB,CAAC,CAAC;IAEH,OAAO;QACL,EAAE,EAAE,IAAI;QACR,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE;QACpB,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM;QACzB,aAAa,EAAE,MAAM,CAAC,aAAa;KACpC,CAAC;AACJ,CAAC;AAcD,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,KAA0B;IAC7D,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACrD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,4BAA4B,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;IAChF,CAAC;IACD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;QAC7E,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;IACpF,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;IACvF,CAAC;AACH,CAAC;AAYD,MAAM,UAAU,aAAa,CAAC,KAAyB;IACrD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;IAChC,OAAO;QACL,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,CAAC;QAChD,aAAa,EAAE,KAAK,CAAC,KAAK,CAAC,gBAAgB,CAAC,QAAQ,EAAE;KACvD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { findUnknownPersonas } from "../engine/consistency.js";
|
|
2
|
+
const DEFAULT_ALLOWED_MISSING = ['+prime'];
|
|
3
|
+
export function runDoctor(opts) {
|
|
4
|
+
const allowedMissing = new Set(opts.allowedMissingPersonas ?? DEFAULT_ALLOWED_MISSING);
|
|
5
|
+
const now = (opts.now ?? (() => new Date()))().getTime();
|
|
6
|
+
const findings = [];
|
|
7
|
+
// ---- workflows ----
|
|
8
|
+
const wfErrors = opts.workflows.errors();
|
|
9
|
+
const wfList = opts.workflows.list();
|
|
10
|
+
if (wfErrors.length === 0) {
|
|
11
|
+
findings.push({
|
|
12
|
+
category: 'workflow',
|
|
13
|
+
severity: 'ok',
|
|
14
|
+
message: `${wfList.length} workflow(s) loaded`,
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
for (const e of wfErrors) {
|
|
19
|
+
findings.push({
|
|
20
|
+
category: 'workflow',
|
|
21
|
+
severity: 'error',
|
|
22
|
+
message: `${e.file}: ${e.reason}`,
|
|
23
|
+
details: e,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
// ---- personas ----
|
|
28
|
+
const personaErrors = opts.personas.errors();
|
|
29
|
+
const personaList = opts.personas.list();
|
|
30
|
+
if (personaErrors.length === 0) {
|
|
31
|
+
findings.push({
|
|
32
|
+
category: 'persona',
|
|
33
|
+
severity: 'ok',
|
|
34
|
+
message: `${personaList.length} persona(s) loaded`,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
for (const e of personaErrors) {
|
|
39
|
+
findings.push({
|
|
40
|
+
category: 'persona',
|
|
41
|
+
severity: 'error',
|
|
42
|
+
message: `${e.file}: ${e.reason}`,
|
|
43
|
+
details: e,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// ---- cross-references ----
|
|
48
|
+
const unknownRefs = findUnknownPersonas(opts.workflows, opts.personas).filter((f) => !allowedMissing.has(f.persona));
|
|
49
|
+
if (unknownRefs.length === 0) {
|
|
50
|
+
findings.push({
|
|
51
|
+
category: 'cross-ref',
|
|
52
|
+
severity: 'ok',
|
|
53
|
+
message: 'all persona handles resolve',
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
for (const ref of unknownRefs) {
|
|
58
|
+
findings.push({
|
|
59
|
+
category: 'cross-ref',
|
|
60
|
+
severity: 'error',
|
|
61
|
+
message: `workflow '${ref.workflowId}' step ${ref.stepKey} references unknown persona ${ref.persona}`,
|
|
62
|
+
details: ref,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// ---- stale locks ----
|
|
67
|
+
const allLocks = opts.repos.locks.list();
|
|
68
|
+
const staleLocks = allLocks.filter((l) => l.expires_at !== null && l.expires_at < now);
|
|
69
|
+
if (staleLocks.length === 0) {
|
|
70
|
+
findings.push({ category: 'lock', severity: 'ok', message: 'no stale locks' });
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
findings.push({
|
|
74
|
+
category: 'lock',
|
|
75
|
+
severity: 'warn',
|
|
76
|
+
message: `${staleLocks.length} stale lock(s): ${staleLocks.map((l) => l.resource).join(', ')}`,
|
|
77
|
+
details: staleLocks,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
// ---- blocked items ----
|
|
81
|
+
const blockedCount = opts.repos.backlog.countByStatus('blocked');
|
|
82
|
+
if (blockedCount === 0) {
|
|
83
|
+
findings.push({ category: 'item', severity: 'ok', message: 'no blocked items' });
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
findings.push({
|
|
87
|
+
category: 'item',
|
|
88
|
+
severity: 'warn',
|
|
89
|
+
message: `${blockedCount} blocked item(s)`,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
const summary = {
|
|
93
|
+
workflowsLoaded: wfList.length,
|
|
94
|
+
workflowErrors: wfErrors.length,
|
|
95
|
+
personasLoaded: personaList.length,
|
|
96
|
+
personaErrors: personaErrors.length,
|
|
97
|
+
unknownPersonaRefs: unknownRefs.length,
|
|
98
|
+
staleLocks: staleLocks.length,
|
|
99
|
+
blockedItems: blockedCount,
|
|
100
|
+
};
|
|
101
|
+
return {
|
|
102
|
+
findings,
|
|
103
|
+
summary,
|
|
104
|
+
hasErrors: findings.some((f) => f.severity === 'error'),
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Human-readable text format. Used by `bin/kortext.ts` doctor command.
|
|
109
|
+
*/
|
|
110
|
+
export function formatDoctorReport(report) {
|
|
111
|
+
const lines = [];
|
|
112
|
+
const icon = (s) => (s === 'ok' ? '✔' : s === 'warn' ? '⚠' : '✖');
|
|
113
|
+
for (const f of report.findings) {
|
|
114
|
+
lines.push(`${icon(f.severity)} [${f.category}] ${f.message}`);
|
|
115
|
+
}
|
|
116
|
+
return lines.join('\n');
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../server/cli/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { MockExecutor } from "../engine/executors/mock-executor.js";
|
|
2
|
+
import { ClaudeCliExecutor } from "../engine/executors/claude-cli-executor.js";
|
|
3
|
+
import { CodexCliExecutor } from "../engine/executors/codex-cli-executor.js";
|
|
4
|
+
import { GeminiCliExecutor } from "../engine/executors/gemini-cli-executor.js";
|
|
5
|
+
export function createExecutor(kind, opts) {
|
|
6
|
+
switch (kind) {
|
|
7
|
+
case 'mock':
|
|
8
|
+
return new MockExecutor();
|
|
9
|
+
case 'claude':
|
|
10
|
+
return new ClaudeCliExecutor({
|
|
11
|
+
binary: opts.binary,
|
|
12
|
+
agentsDir: opts.agentsDir,
|
|
13
|
+
logsDir: opts.logsDir,
|
|
14
|
+
extraArgs: opts.extraArgs,
|
|
15
|
+
personaRegistry: opts.personaRegistry,
|
|
16
|
+
});
|
|
17
|
+
case 'codex':
|
|
18
|
+
return new CodexCliExecutor({
|
|
19
|
+
binary: opts.binary,
|
|
20
|
+
agentsDir: opts.agentsDir,
|
|
21
|
+
logsDir: opts.logsDir,
|
|
22
|
+
extraArgs: opts.extraArgs,
|
|
23
|
+
personaRegistry: opts.personaRegistry,
|
|
24
|
+
});
|
|
25
|
+
case 'gemini':
|
|
26
|
+
return new GeminiCliExecutor({
|
|
27
|
+
binary: opts.binary,
|
|
28
|
+
agentsDir: opts.agentsDir,
|
|
29
|
+
logsDir: opts.logsDir,
|
|
30
|
+
extraArgs: opts.extraArgs,
|
|
31
|
+
personaRegistry: opts.personaRegistry,
|
|
32
|
+
});
|
|
33
|
+
default: {
|
|
34
|
+
const exhaustive = kind;
|
|
35
|
+
throw new Error(`unknown executor kind: ${String(exhaustive)}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=executor-factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor-factory.js","sourceRoot":"","sources":["../../../server/cli/executor-factory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,4CAA4C,CAAC;AAC/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,4CAA4C,CAAC;AA2B/E,MAAM,UAAU,cAAc,CAC5B,IAAkB,EAClB,IAA4B;IAE5B,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,MAAM;YACT,OAAO,IAAI,YAAY,EAAE,CAAC;QAC5B,KAAK,QAAQ;YACX,OAAO,IAAI,iBAAiB,CAAC;gBAC3B,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,eAAe,EAAE,IAAI,CAAC,eAAe;aACtC,CAAC,CAAC;QACL,KAAK,OAAO;YACV,OAAO,IAAI,gBAAgB,CAAC;gBAC1B,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,eAAe,EAAE,IAAI,CAAC,eAAe;aACtC,CAAC,CAAC;QACL,KAAK,QAAQ;YACX,OAAO,IAAI,iBAAiB,CAAC;gBAC3B,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,eAAe,EAAE,IAAI,CAAC,eAAe;aACtC,CAAC,CAAC;QACL,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,UAAU,GAAU,IAAI,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,0BAA0B,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { cpSync, existsSync, mkdirSync, readFileSync, writeFileSync, } from 'node:fs';
|
|
2
|
+
import { dirname, join, relative, resolve } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { openDb } from "../db/client.js";
|
|
5
|
+
const SCAFFOLD_DIRS = ['agents', 'workflows', 'rules', 'workspace'];
|
|
6
|
+
const DEFAULT_AGENTS_MD = `# AGENTS.md
|
|
7
|
+
|
|
8
|
+
> Kortext v3 — autonomous AI agent runtime. Run \`kortext serve\` to launch
|
|
9
|
+
> the dashboard + backend, or \`kortext mcp\` to expose tools over MCP.
|
|
10
|
+
|
|
11
|
+
## Quick start
|
|
12
|
+
|
|
13
|
+
\`\`\`bash
|
|
14
|
+
kortext serve # backend + dashboard (default port 3200)
|
|
15
|
+
kortext status # recent runs + open approval questions
|
|
16
|
+
kortext logs # tail of the audit log
|
|
17
|
+
kortext doctor # workflow / persona / lock consistency scan
|
|
18
|
+
\`\`\`
|
|
19
|
+
|
|
20
|
+
## Where things live
|
|
21
|
+
|
|
22
|
+
- \`agents/\` — persona definitions (one markdown file per role)
|
|
23
|
+
- \`workflows/\` — pipeline definitions, executed via the worker pool
|
|
24
|
+
- \`rules/\` — project-wide behavior, branching, commands, models, emergency
|
|
25
|
+
- \`workspace/references/blueprint.md\` — product blueprint; approving it
|
|
26
|
+
triggers the analysis → planning → development pipeline chain
|
|
27
|
+
- \`.kortext/runtime/kortext.db\` — SQLite state (runs, items, audit log)
|
|
28
|
+
`;
|
|
29
|
+
function packageRootFromHere() {
|
|
30
|
+
// Source path is `server/cli/init.ts` (root two levels up). Compiled path is
|
|
31
|
+
// `dist/server/cli/init.js` (root three levels up). Walking up until we find
|
|
32
|
+
// a package.json keeps both layouts working without special-casing — the same
|
|
33
|
+
// pattern bin/kortext.ts uses for version reporting.
|
|
34
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
35
|
+
let cursor = here;
|
|
36
|
+
for (let i = 0; i < 6; i++) {
|
|
37
|
+
if (existsSync(join(cursor, 'package.json')))
|
|
38
|
+
return cursor;
|
|
39
|
+
const parent = resolve(cursor, '..');
|
|
40
|
+
if (parent === cursor)
|
|
41
|
+
break;
|
|
42
|
+
cursor = parent;
|
|
43
|
+
}
|
|
44
|
+
return resolve(here, '..', '..');
|
|
45
|
+
}
|
|
46
|
+
function copyTemplateDir(sourceRoot, targetRoot, relPath, force, created, skipped) {
|
|
47
|
+
const source = join(sourceRoot, relPath);
|
|
48
|
+
const target = join(targetRoot, relPath);
|
|
49
|
+
if (!existsSync(source)) {
|
|
50
|
+
// Templates dir lacks this entry — nothing to scaffold.
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (existsSync(target) && !force) {
|
|
54
|
+
skipped.push(relPath);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
cpSync(source, target, { recursive: true, force });
|
|
58
|
+
created.push(relPath);
|
|
59
|
+
}
|
|
60
|
+
export function initCommand(input) {
|
|
61
|
+
const targetDir = resolve(input.targetDir);
|
|
62
|
+
const templatesDir = resolve(input.templatesDir ?? packageRootFromHere());
|
|
63
|
+
if (resolve(templatesDir) === targetDir && !input.force) {
|
|
64
|
+
return {
|
|
65
|
+
ok: false,
|
|
66
|
+
errorMessage: 'refusing to init into the templates directory itself (use --force to override)',
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
mkdirSync(targetDir, { recursive: true });
|
|
70
|
+
const created = [];
|
|
71
|
+
const skipped = [];
|
|
72
|
+
const force = input.force === true;
|
|
73
|
+
for (const rel of SCAFFOLD_DIRS) {
|
|
74
|
+
copyTemplateDir(templatesDir, targetDir, rel, force, created, skipped);
|
|
75
|
+
}
|
|
76
|
+
// AGENTS.md: prefer the template's copy when present, otherwise write a
|
|
77
|
+
// minimal default so `claude` / `codex` agents can discover the project.
|
|
78
|
+
const agentsMdPath = join(targetDir, 'AGENTS.md');
|
|
79
|
+
if (existsSync(agentsMdPath) && !force) {
|
|
80
|
+
skipped.push('AGENTS.md');
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
const templateAgentsMd = join(templatesDir, 'AGENTS.md');
|
|
84
|
+
const content = existsSync(templateAgentsMd)
|
|
85
|
+
? readFileSync(templateAgentsMd, 'utf8')
|
|
86
|
+
: DEFAULT_AGENTS_MD;
|
|
87
|
+
writeFileSync(agentsMdPath, content, 'utf8');
|
|
88
|
+
created.push('AGENTS.md');
|
|
89
|
+
}
|
|
90
|
+
// Runtime dir + DB (migrations run inside openDb).
|
|
91
|
+
const runtimeDir = join(targetDir, '.kortext', 'runtime');
|
|
92
|
+
mkdirSync(runtimeDir, { recursive: true });
|
|
93
|
+
const dbPath = join(runtimeDir, 'kortext.db');
|
|
94
|
+
const dbExisted = existsSync(dbPath);
|
|
95
|
+
let schemaVersion = 0;
|
|
96
|
+
try {
|
|
97
|
+
const bundle = openDb({ path: dbPath });
|
|
98
|
+
schemaVersion = bundle.schemaVersion;
|
|
99
|
+
bundle.db.close();
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
return {
|
|
103
|
+
ok: false,
|
|
104
|
+
errorMessage: `db init failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
if (dbExisted) {
|
|
108
|
+
skipped.push(relative(targetDir, dbPath));
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
created.push(relative(targetDir, dbPath));
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
ok: true,
|
|
115
|
+
created,
|
|
116
|
+
skipped,
|
|
117
|
+
dbPath,
|
|
118
|
+
schemaVersion,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../server/cli/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export function logsCommand(input) {
|
|
2
|
+
const limit = input.limit ?? 50;
|
|
3
|
+
const rows = input.repos.auditLog.list({
|
|
4
|
+
actor: input.actor ?? null,
|
|
5
|
+
action: input.action ?? null,
|
|
6
|
+
resource_type: input.resourceType ?? null,
|
|
7
|
+
resource_id: input.resourceId ?? null,
|
|
8
|
+
since: input.sinceMs ?? null,
|
|
9
|
+
limit,
|
|
10
|
+
});
|
|
11
|
+
return { rows };
|
|
12
|
+
}
|
|
13
|
+
export function formatLogsForCli(rows) {
|
|
14
|
+
if (rows.length === 0)
|
|
15
|
+
return '(no audit log entries)';
|
|
16
|
+
return rows
|
|
17
|
+
.map((row) => {
|
|
18
|
+
const ts = new Date(row.created_at).toISOString();
|
|
19
|
+
const resource = row.resource_type
|
|
20
|
+
? ` ${row.resource_type}:${row.resource_id ?? '-'}`
|
|
21
|
+
: '';
|
|
22
|
+
const payloadKeys = Object.keys(row.payload ?? {});
|
|
23
|
+
const payload = payloadKeys.length > 0 ? ` {${payloadKeys.join(',')}}` : '';
|
|
24
|
+
return `[${row.id}] ${ts} ${row.actor.padEnd(18)} ${row.action}${resource}${payload}`;
|
|
25
|
+
})
|
|
26
|
+
.join('\n');
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=logs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs.js","sourceRoot":"","sources":["../../../server/cli/logs.ts"],"names":[],"mappings":"AAuBA,MAAM,UAAU,WAAW,CAAC,KAAuB;IACjD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;IAChC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;QACrC,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,IAAI;QAC1B,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,IAAI;QAC5B,aAAa,EAAE,KAAK,CAAC,YAAY,IAAI,IAAI;QACzC,WAAW,EAAE,KAAK,CAAC,UAAU,IAAI,IAAI;QACrC,KAAK,EAAE,KAAK,CAAC,OAAO,IAAI,IAAI;QAC5B,KAAK;KACN,CAAC,CAAC;IACH,OAAO,EAAE,IAAI,EAAE,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAmB;IAClD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,wBAAwB,CAAC;IACvD,OAAO,IAAI;SACR,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACX,MAAM,EAAE,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC;QAClD,MAAM,QAAQ,GAAG,GAAG,CAAC,aAAa;YAChC,CAAC,CAAC,IAAI,GAAG,CAAC,aAAa,IAAI,GAAG,CAAC,WAAW,IAAI,GAAG,EAAE;YACnD,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;QACnD,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5E,OAAO,IAAI,GAAG,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,QAAQ,GAAG,OAAO,EAAE,CAAC;IACzF,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Resolve dev vs prod from package state when caller passes 'auto':
|
|
5
|
+
* - prod when both compiled server (`dist/server/index.js`) and built web
|
|
6
|
+
* (`dist/web/index.html`) are present
|
|
7
|
+
* - dev otherwise (uses tsx + vite from devDependencies)
|
|
8
|
+
*/
|
|
9
|
+
export function buildServeCommands(input) {
|
|
10
|
+
const exists = input.existsImpl ?? existsSync;
|
|
11
|
+
const mode = resolveMode(input.packageRoot, input.mode ?? 'auto', exists);
|
|
12
|
+
const baseEnv = {};
|
|
13
|
+
if (input.port !== undefined) {
|
|
14
|
+
baseEnv.KORTEXT_PORT = String(input.port);
|
|
15
|
+
}
|
|
16
|
+
if (mode === 'prod') {
|
|
17
|
+
return {
|
|
18
|
+
mode,
|
|
19
|
+
commands: [
|
|
20
|
+
{
|
|
21
|
+
name: 'server',
|
|
22
|
+
command: process.execPath,
|
|
23
|
+
args: [join(input.packageRoot, 'dist', 'server', 'index.js')],
|
|
24
|
+
cwd: input.projectDir,
|
|
25
|
+
env: baseEnv,
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: 'web',
|
|
29
|
+
command: 'npx',
|
|
30
|
+
args: [
|
|
31
|
+
'vite',
|
|
32
|
+
'preview',
|
|
33
|
+
'--host',
|
|
34
|
+
'--port',
|
|
35
|
+
String(input.port ? input.port + 1 : 5173),
|
|
36
|
+
],
|
|
37
|
+
cwd: input.packageRoot,
|
|
38
|
+
env: baseEnv,
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
mode,
|
|
45
|
+
commands: [
|
|
46
|
+
{
|
|
47
|
+
name: 'server',
|
|
48
|
+
command: 'npx',
|
|
49
|
+
args: ['tsx', join(input.packageRoot, 'server', 'index.ts')],
|
|
50
|
+
cwd: input.projectDir,
|
|
51
|
+
env: baseEnv,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: 'web',
|
|
55
|
+
command: 'npx',
|
|
56
|
+
args: ['vite', '--host'],
|
|
57
|
+
cwd: input.packageRoot,
|
|
58
|
+
env: baseEnv,
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function resolveMode(packageRoot, requested, exists) {
|
|
64
|
+
if (requested === 'dev')
|
|
65
|
+
return 'dev';
|
|
66
|
+
if (requested === 'prod')
|
|
67
|
+
return 'prod';
|
|
68
|
+
const compiledServer = join(packageRoot, 'dist', 'server', 'index.js');
|
|
69
|
+
const builtWeb = join(packageRoot, 'dist', 'web', 'index.html');
|
|
70
|
+
return exists(compiledServer) && exists(builtWeb) ? 'prod' : 'dev';
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=serve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../../../server/cli/serve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAqCjC;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAA8B;IAC/D,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,IAAI,UAAU,CAAC;IAC9C,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,IAAI,MAAM,EAAE,MAAM,CAAC,CAAC;IAE1E,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,CAAC,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5C,CAAC;IAED,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACpB,OAAO;YACL,IAAI;YACJ,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,OAAO,CAAC,QAAQ;oBACzB,IAAI,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;oBAC7D,GAAG,EAAE,KAAK,CAAC,UAAU;oBACrB,GAAG,EAAE,OAAO;iBACb;gBACD;oBACE,IAAI,EAAE,KAAK;oBACX,OAAO,EAAE,KAAK;oBACd,IAAI,EAAE;wBACJ,MAAM;wBACN,SAAS;wBACT,QAAQ;wBACR,QAAQ;wBACR,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;qBAC3C;oBACD,GAAG,EAAE,KAAK,CAAC,WAAW;oBACtB,GAAG,EAAE,OAAO;iBACb;aACF;SACF,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI;QACJ,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,KAAK;gBACd,IAAI,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;gBAC5D,GAAG,EAAE,KAAK,CAAC,UAAU;gBACrB,GAAG,EAAE,OAAO;aACb;YACD;gBACE,IAAI,EAAE,KAAK;gBACX,OAAO,EAAE,KAAK;gBACd,IAAI,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC;gBACxB,GAAG,EAAE,KAAK,CAAC,WAAW;gBACtB,GAAG,EAAE,OAAO;aACb;SACF;KACF,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAClB,WAAmB,EACnB,SAAoB,EACpB,MAAiC;IAEjC,IAAI,SAAS,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IACtC,IAAI,SAAS,KAAK,MAAM;QAAE,OAAO,MAAM,CAAC;IACxC,MAAM,cAAc,GAAG,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;IACvE,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;IAChE,OAAO,MAAM,CAAC,cAAc,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;AACrE,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
const EnvSchema = z.object({
|
|
3
|
+
NODE_ENV: z.enum(['development', 'test', 'production']).default('development'),
|
|
4
|
+
KORTEXT_PORT: z.coerce.number().int().positive().default(3200),
|
|
5
|
+
KORTEXT_DB_PATH: z.string().default('.kortext/runtime/kortext.db'),
|
|
6
|
+
SLACK_WEBHOOK_URL: z.string().url().optional(),
|
|
7
|
+
SLACK_CHANNEL: z.string().optional(),
|
|
8
|
+
TELEGRAM_BOT_TOKEN: z.string().optional(),
|
|
9
|
+
TELEGRAM_CHAT_ID: z.string().optional(),
|
|
10
|
+
});
|
|
11
|
+
export const env = EnvSchema.parse(process.env);
|
|
12
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../../server/config/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IACzB,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;IAC9E,YAAY,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAC9D,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,6BAA6B,CAAC;IAClE,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAC9C,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACpC,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACzC,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACxC,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,GAAG,GAAQ,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC"}
|