kortext 2.2.0 → 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.
Files changed (209) hide show
  1. package/AGENTS.md +7 -11
  2. package/CHANGELOG.md +81 -0
  3. package/LICENSE +21 -0
  4. package/README.md +144 -47
  5. package/USER-GUIDE.md +505 -0
  6. package/bin/kortext.js +23 -0
  7. package/bin/kortext.ts +377 -0
  8. package/dist/bin/kortext.js +346 -0
  9. package/dist/bin/kortext.js.map +1 -0
  10. package/dist/mcp/index.js +4 -0
  11. package/dist/mcp/index.js.map +1 -0
  12. package/dist/mcp/server.js +553 -0
  13. package/dist/mcp/server.js.map +1 -0
  14. package/dist/mcp/sse.js +38 -0
  15. package/dist/mcp/sse.js.map +1 -0
  16. package/dist/mcp/stdio.js +44 -0
  17. package/dist/mcp/stdio.js.map +1 -0
  18. package/dist/server/cli/cleanup.js +73 -0
  19. package/dist/server/cli/cleanup.js.map +1 -0
  20. package/dist/server/cli/commands.js +73 -0
  21. package/dist/server/cli/commands.js.map +1 -0
  22. package/dist/server/cli/doctor.js +118 -0
  23. package/dist/server/cli/doctor.js.map +1 -0
  24. package/dist/server/cli/executor-factory.js +39 -0
  25. package/dist/server/cli/executor-factory.js.map +1 -0
  26. package/dist/server/cli/init.js +121 -0
  27. package/dist/server/cli/init.js.map +1 -0
  28. package/dist/server/cli/logs.js +28 -0
  29. package/dist/server/cli/logs.js.map +1 -0
  30. package/dist/server/cli/serve.js +72 -0
  31. package/dist/server/cli/serve.js.map +1 -0
  32. package/dist/server/config/env.js +12 -0
  33. package/dist/server/config/env.js.map +1 -0
  34. package/dist/server/db/client.js +32 -0
  35. package/dist/server/db/client.js.map +1 -0
  36. package/dist/server/db/json.js +21 -0
  37. package/dist/server/db/json.js.map +1 -0
  38. package/dist/server/db/migrate.js +70 -0
  39. package/dist/server/db/migrate.js.map +1 -0
  40. package/dist/server/db/migrations/001_init.sql +243 -0
  41. package/dist/server/db/repositories/audit-log.js +58 -0
  42. package/dist/server/db/repositories/audit-log.js.map +1 -0
  43. package/dist/server/db/repositories/backlog.js +96 -0
  44. package/dist/server/db/repositories/backlog.js.map +1 -0
  45. package/dist/server/db/repositories/contexts.js +54 -0
  46. package/dist/server/db/repositories/contexts.js.map +1 -0
  47. package/dist/server/db/repositories/decisions.js +71 -0
  48. package/dist/server/db/repositories/decisions.js.map +1 -0
  49. package/dist/server/db/repositories/handovers.js +53 -0
  50. package/dist/server/db/repositories/handovers.js.map +1 -0
  51. package/dist/server/db/repositories/index.js +30 -0
  52. package/dist/server/db/repositories/index.js.map +1 -0
  53. package/dist/server/db/repositories/locks.js +59 -0
  54. package/dist/server/db/repositories/locks.js.map +1 -0
  55. package/dist/server/db/repositories/notifications.js +63 -0
  56. package/dist/server/db/repositories/notifications.js.map +1 -0
  57. package/dist/server/db/repositories/pending-questions.js +63 -0
  58. package/dist/server/db/repositories/pending-questions.js.map +1 -0
  59. package/dist/server/db/repositories/runs.js +138 -0
  60. package/dist/server/db/repositories/runs.js.map +1 -0
  61. package/dist/server/db/repositories/runtime-artifacts.js +39 -0
  62. package/dist/server/db/repositories/runtime-artifacts.js.map +1 -0
  63. package/dist/server/db/repositories/secrets.js +65 -0
  64. package/dist/server/db/repositories/secrets.js.map +1 -0
  65. package/dist/server/db/repositories/sessions.js +48 -0
  66. package/dist/server/db/repositories/sessions.js.map +1 -0
  67. package/dist/server/db/schemas.js +308 -0
  68. package/dist/server/db/schemas.js.map +1 -0
  69. package/dist/server/engine/consistency.js +25 -0
  70. package/dist/server/engine/consistency.js.map +1 -0
  71. package/dist/server/engine/dag.js +86 -0
  72. package/dist/server/engine/dag.js.map +1 -0
  73. package/dist/server/engine/executor.js +2 -0
  74. package/dist/server/engine/executor.js.map +1 -0
  75. package/dist/server/engine/executors/claude-cli-executor.js +83 -0
  76. package/dist/server/engine/executors/claude-cli-executor.js.map +1 -0
  77. package/dist/server/engine/executors/cli-spawn.js +127 -0
  78. package/dist/server/engine/executors/cli-spawn.js.map +1 -0
  79. package/dist/server/engine/executors/codex-cli-executor.js +69 -0
  80. package/dist/server/engine/executors/codex-cli-executor.js.map +1 -0
  81. package/dist/server/engine/executors/gemini-cli-executor.js +69 -0
  82. package/dist/server/engine/executors/gemini-cli-executor.js.map +1 -0
  83. package/dist/server/engine/executors/mock-executor.js +52 -0
  84. package/dist/server/engine/executors/mock-executor.js.map +1 -0
  85. package/dist/server/engine/executors/persona-routed-executor.js +17 -0
  86. package/dist/server/engine/executors/persona-routed-executor.js.map +1 -0
  87. package/dist/server/engine/gate-enforcer.js +75 -0
  88. package/dist/server/engine/gate-enforcer.js.map +1 -0
  89. package/dist/server/engine/git-commit.js +42 -0
  90. package/dist/server/engine/git-commit.js.map +1 -0
  91. package/dist/server/engine/handover.js +120 -0
  92. package/dist/server/engine/handover.js.map +1 -0
  93. package/dist/server/engine/item-lifecycle.js +74 -0
  94. package/dist/server/engine/item-lifecycle.js.map +1 -0
  95. package/dist/server/engine/persona-registry.js +108 -0
  96. package/dist/server/engine/persona-registry.js.map +1 -0
  97. package/dist/server/engine/worker-pool.js +324 -0
  98. package/dist/server/engine/worker-pool.js.map +1 -0
  99. package/dist/server/engine/workflow-loader.js +55 -0
  100. package/dist/server/engine/workflow-loader.js.map +1 -0
  101. package/dist/server/engine/workflow-parser.js +158 -0
  102. package/dist/server/engine/workflow-parser.js.map +1 -0
  103. package/dist/server/engine/worktree.js +176 -0
  104. package/dist/server/engine/worktree.js.map +1 -0
  105. package/dist/server/index.js +99 -0
  106. package/dist/server/index.js.map +1 -0
  107. package/dist/server/notifications/dispatcher.js +60 -0
  108. package/dist/server/notifications/dispatcher.js.map +1 -0
  109. package/dist/server/notifications/slack.js +37 -0
  110. package/dist/server/notifications/slack.js.map +1 -0
  111. package/dist/server/notifications/telegram.js +33 -0
  112. package/dist/server/notifications/telegram.js.map +1 -0
  113. package/dist/server/orchestrator/approval-queue.js +83 -0
  114. package/dist/server/orchestrator/approval-queue.js.map +1 -0
  115. package/dist/server/orchestrator/blueprint-watcher.js +94 -0
  116. package/dist/server/orchestrator/blueprint-watcher.js.map +1 -0
  117. package/dist/server/orchestrator/orchestrator.js +283 -0
  118. package/dist/server/orchestrator/orchestrator.js.map +1 -0
  119. package/dist/server/orchestrator/pipeline-chainer.js +96 -0
  120. package/dist/server/orchestrator/pipeline-chainer.js.map +1 -0
  121. package/dist/server/orchestrator/resume.js +36 -0
  122. package/dist/server/orchestrator/resume.js.map +1 -0
  123. package/dist/server/routes/approvals.js +52 -0
  124. package/dist/server/routes/approvals.js.map +1 -0
  125. package/dist/server/routes/backlog.js +44 -0
  126. package/dist/server/routes/backlog.js.map +1 -0
  127. package/dist/server/routes/db-info.js +21 -0
  128. package/dist/server/routes/db-info.js.map +1 -0
  129. package/dist/server/routes/docs.js +70 -0
  130. package/dist/server/routes/docs.js.map +1 -0
  131. package/dist/server/routes/doctor.js +19 -0
  132. package/dist/server/routes/doctor.js.map +1 -0
  133. package/dist/server/routes/handovers.js +25 -0
  134. package/dist/server/routes/handovers.js.map +1 -0
  135. package/dist/server/routes/health.js +11 -0
  136. package/dist/server/routes/health.js.map +1 -0
  137. package/dist/server/routes/personas.js +96 -0
  138. package/dist/server/routes/personas.js.map +1 -0
  139. package/dist/server/routes/runs.js +41 -0
  140. package/dist/server/routes/runs.js.map +1 -0
  141. package/dist/server/routes/workflows.js +38 -0
  142. package/dist/server/routes/workflows.js.map +1 -0
  143. package/dist/server/safety/harmful-output-filter.js +40 -0
  144. package/dist/server/safety/harmful-output-filter.js.map +1 -0
  145. package/dist/server/safety/secret-scanner.js +169 -0
  146. package/dist/server/safety/secret-scanner.js.map +1 -0
  147. package/dist/server/services/markdown-sync.js +101 -0
  148. package/dist/server/services/markdown-sync.js.map +1 -0
  149. package/dist/web/assets/index-B80d5ZPZ.js +75 -0
  150. package/dist/web/assets/index-B80d5ZPZ.js.map +1 -0
  151. package/dist/web/assets/index-Bge5Gzqv.css +1 -0
  152. package/dist/web/index.html +13 -0
  153. package/docs/architecture.md +413 -0
  154. package/package.json +83 -11
  155. package/rules/behavior.md +2 -2
  156. package/scripts/copy-migrations.mjs +29 -0
  157. package/workspace/.locks/workspace_handover.md.lock +3 -0
  158. package/hooks/audit-logger.sh +0 -25
  159. package/hooks/auto-locker.sh +0 -74
  160. package/hooks/auto-unlocker.sh +0 -17
  161. package/hooks/backlog-sync-guard.sh +0 -12
  162. package/hooks/branch-guard.sh +0 -32
  163. package/hooks/commit-msg-guard.sh +0 -43
  164. package/hooks/git-pre-commit.sh +0 -76
  165. package/hooks/git-pre-push.sh +0 -17
  166. package/hooks/handover-guard.sh +0 -33
  167. package/hooks/kortext-init.sh +0 -194
  168. package/hooks/kortext-lib.sh +0 -141
  169. package/hooks/lint-guard.sh +0 -50
  170. package/hooks/secret-scanner.sh +0 -89
  171. package/hooks/size-guard.sh +0 -48
  172. package/hooks/snapshot-guard.sh +0 -39
  173. package/hooks/write-guard.sh +0 -77
  174. package/scripts/kortext-backlog-add.py +0 -123
  175. package/scripts/kortext-backlog-health.py +0 -112
  176. package/scripts/kortext-backlog-sync.py +0 -117
  177. package/scripts/kortext-bulk-plan.py +0 -63
  178. package/scripts/kortext-cli.py +0 -295
  179. package/scripts/kortext-consistency-check.py +0 -74
  180. package/scripts/kortext-context-check.py +0 -146
  181. package/scripts/kortext-handover.py +0 -107
  182. package/scripts/kortext-item-check.py +0 -61
  183. package/scripts/kortext-item-start.py +0 -70
  184. package/scripts/kortext-item-transition.py +0 -78
  185. package/scripts/kortext-lock.py +0 -174
  186. package/scripts/kortext-session-start.py +0 -127
  187. package/scripts/lock_kortext.sh +0 -34
  188. package/settings/.claude-settings.template.json +0 -48
  189. package/settings/CHANGELOG.md +0 -176
  190. package/settings/INTEGRATION-MAP.md +0 -276
  191. package/settings/README.md +0 -255
  192. package/settings/USER-GUIDE.md +0 -502
  193. package/settings/VERSION +0 -1
  194. package/settings/config.md +0 -8
  195. package/settings/runtime-adapters.md +0 -104
  196. package/skills/backend-developer/.gitkeep +0 -0
  197. package/skills/compliance-expert/.gitkeep +0 -0
  198. package/skills/copywriter/.gitkeep +0 -0
  199. package/skills/db-admin/.gitkeep +0 -0
  200. package/skills/delivery-manager/.gitkeep +0 -0
  201. package/skills/designer/.gitkeep +0 -0
  202. package/skills/devops-engineer/.gitkeep +0 -0
  203. package/skills/engineering-manager/.gitkeep +0 -0
  204. package/skills/frontend-developer/.gitkeep +0 -0
  205. package/skills/growth-expert/.gitkeep +0 -0
  206. package/skills/operation-manager/.gitkeep +0 -0
  207. package/skills/product-manager/.gitkeep +0 -0
  208. package/skills/qa-engineer/.gitkeep +0 -0
  209. 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":"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"}
@@ -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"}