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 @@
|
|
|
1
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-content:""}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:"JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;--color-neutral-100:oklch(97% 0 0);--color-neutral-950:oklch(14.5% 0 0);--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--container-md:28rem;--container-3xl:48rem;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-wider:.05em;--leading-snug:1.375;--radius-md:.375rem;--radius-lg:.5rem;--shadow-sm:0 1px 3px 0 #0000001a, 0 1px 2px -1px #0000001a;--shadow-md:0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a;--ease-out:cubic-bezier(0, 0, .2, 1);--ease-in-out:cubic-bezier(.4, 0, .2, 1);--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:"JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;--color-success:var(--success)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.top-0\.5{top:calc(var(--spacing) * .5)}.top-1\.5{top:calc(var(--spacing) * 1.5)}.top-9{top:calc(var(--spacing) * 9)}.top-\[var\(--header-h\)\]{top:var(--header-h)}.right-0{right:calc(var(--spacing) * 0)}.right-0\.5{right:calc(var(--spacing) * .5)}.right-1\.5{right:calc(var(--spacing) * 1.5)}.right-4{right:calc(var(--spacing) * 4)}.bottom-12{bottom:calc(var(--spacing) * 12)}.bottom-\[var\(--footer-h\)\]{bottom:var(--footer-h)}.left-\[var\(--sidebar-w\)\]{left:var(--sidebar-w)}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.mx-1{margin-inline:calc(var(--spacing) * 1)}.mx-2{margin-inline:calc(var(--spacing) * 2)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mb-0\.5{margin-bottom:calc(var(--spacing) * .5)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.ml-1{margin-left:calc(var(--spacing) * 1)}.ml-4{margin-left:calc(var(--spacing) * 4)}.ml-auto{margin-left:auto}.line-clamp-1{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.table{display:table}.h-3{height:calc(var(--spacing) * 3)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-\[38px\]{height:38px}.h-\[280px\]{height:280px}.h-\[var\(--header-h\)\]{height:var(--header-h)}.h-full{height:100%}.h-screen{height:100vh}.max-h-\[360px\]{max-height:360px}.max-h-\[400px\]{max-height:400px}.min-h-0{min-height:calc(var(--spacing) * 0)}.min-h-\[60vh\]{min-height:60vh}.min-h-\[200px\]{min-height:200px}.w-3{width:calc(var(--spacing) * 3)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-8{width:calc(var(--spacing) * 8)}.w-\[340px\]{width:340px}.w-\[360px\]{width:360px}.w-full{width:100%}.w-px{width:1px}.w-screen{width:100vw}.max-w-3xl{max-width:var(--container-3xl)}.max-w-md{max-width:var(--container-md)}.max-w-sm{max-width:var(--container-sm)}.min-w-0{min-width:calc(var(--spacing) * 0)}.flex-1{flex:1}.flex-shrink{flex-shrink:1}.flex-shrink-0{flex-shrink:0}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-pointer{cursor:pointer}.resize{resize:both}.resize-none{resize:none}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1.5) * calc(1 - var(--tw-space-y-reverse)))}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-border-subtle>:not(:last-child)){border-color:var(--border-subtle)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-r-0{border-right-style:var(--tw-border-style);border-right-width:0}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-accent,.border-accent\/30{border-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.border-accent\/30{border-color:color-mix(in oklab,var(--accent) 30%,transparent)}}.border-border-accent{border-color:var(--border-accent)}.border-border-default{border-color:var(--border-default)}.border-border-subtle{border-color:var(--border-subtle)}.border-danger\/30{border-color:var(--danger)}@supports (color:color-mix(in lab,red,red)){.border-danger\/30{border-color:color-mix(in oklab,var(--danger) 30%,transparent)}}.border-danger\/40{border-color:var(--danger)}@supports (color:color-mix(in lab,red,red)){.border-danger\/40{border-color:color-mix(in oklab,var(--danger) 40%,transparent)}}.border-info\/30{border-color:var(--info)}@supports (color:color-mix(in lab,red,red)){.border-info\/30{border-color:color-mix(in oklab,var(--info) 30%,transparent)}}.border-signal\/30{border-color:var(--signal)}@supports (color:color-mix(in lab,red,red)){.border-signal\/30{border-color:color-mix(in oklab,var(--signal) 30%,transparent)}}.border-transparent{border-color:#0000}.border-warning\/30{border-color:var(--warning)}@supports (color:color-mix(in lab,red,red)){.border-warning\/30{border-color:color-mix(in oklab,var(--warning) 30%,transparent)}}.bg-accent,.bg-accent\/8{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.bg-accent\/8{background-color:color-mix(in oklab,var(--accent) 8%,transparent)}}.bg-bg-0{background-color:var(--bg-0)}.bg-bg-1{background-color:var(--bg-1)}.bg-bg-2{background-color:var(--bg-2)}.bg-bg-3{background-color:var(--bg-3)}.bg-danger{background-color:var(--danger)}.bg-neutral-950{background-color:var(--color-neutral-950)}.bg-transparent{background-color:#0000}.bg-white\/10{background-color:#ffffff1a}@supports (color:color-mix(in lab,red,red)){.bg-white\/10{background-color:color-mix(in oklab,var(--color-white) 10%,transparent)}}.p-2{padding:calc(var(--spacing) * 2)}.p-6{padding:calc(var(--spacing) * 6)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-3\.5{padding-block:calc(var(--spacing) * 3.5)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-5{padding-block:calc(var(--spacing) * 5)}.py-6{padding-block:calc(var(--spacing) * 6)}.pl-5{padding-left:calc(var(--spacing) * 5)}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:JetBrains Mono,ui-monospace,SF Mono,Menlo,Consolas,monospace}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-\[14px\]{font-size:14px}.text-\[20px\]{font-size:20px}.leading-\[1\.6\]{--tw-leading:1.6;line-height:1.6}.leading-\[1\.55\]{--tw-leading:1.55;line-height:1.55}.leading-\[1\.65\]{--tw-leading:1.65;line-height:1.65}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\[0\.10em\]{--tw-tracking:.1em;letter-spacing:.1em}.tracking-\[0\.12em\]{--tw-tracking:.12em;letter-spacing:.12em}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.whitespace-nowrap{white-space:nowrap}.text-accent{color:var(--accent)}.text-accent-soft{color:var(--accent-soft)}.text-bg-0{color:var(--bg-0)}.text-danger{color:var(--danger)}.text-info{color:var(--info)}.text-neutral-100{color:var(--color-neutral-100)}.text-prime{color:var(--prime)}.text-signal{color:var(--signal)}.text-signal-soft{color:var(--signal-soft)}.text-success{color:var(--success)}.text-tx-1{color:var(--tx-1)}.text-tx-2{color:var(--tx-2)}.text-tx-3{color:var(--tx-3)}.text-tx-disabled{color:var(--tx-disabled)}.text-warning{color:var(--warning)}.text-white{color:var(--color-white)}.capitalize{text-transform:capitalize}.uppercase{text-transform:uppercase}.underline{text-decoration-line:underline}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-filter{-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.outline-none{--tw-outline-style:none;outline-style:none}.before\:absolute:before{content:var(--tw-content);position:absolute}.before\:top-2:before{content:var(--tw-content);top:calc(var(--spacing) * 2)}.before\:bottom-2:before{content:var(--tw-content);bottom:calc(var(--spacing) * 2)}.before\:left-0:before{content:var(--tw-content);left:calc(var(--spacing) * 0)}.before\:w-\[2px\]:before{content:var(--tw-content);width:2px}.before\:rounded-r:before{content:var(--tw-content);border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.before\:bg-accent:before{content:var(--tw-content);background-color:var(--accent)}@media(hover:hover){.hover\:border-accent\/40:hover{border-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.hover\:border-accent\/40:hover{border-color:color-mix(in oklab,var(--accent) 40%,transparent)}}.hover\:border-border-default:hover{border-color:var(--border-default)}.hover\:bg-accent-soft:hover{background-color:var(--accent-soft)}.hover\:bg-bg-2:hover{background-color:var(--bg-2)}.hover\:text-tx-1:hover{color:var(--tx-1)}}.focus\:bg-bg-0:focus{background-color:var(--bg-0)}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-40:disabled{opacity:.4}}:root{--bg-0:#0a0814;--bg-1:#14101f;--bg-2:#1e1830;--bg-3:#2a2240;--bg-overlay:#0a0814bf;--tx-1:#fafafc;--tx-2:#b5b0c2;--tx-3:#6b6577;--tx-disabled:#3f3b4f;--accent:#a855f7;--accent-soft:#c084fc;--accent-deep:#7c3aed;--accent-glow:#a855f740;--signal:#ec4899;--signal-soft:#f472b6;--signal-glow:#ec489933;--success:#10b981;--warning:#f59e0b;--danger:#ef4444;--info:#3b82f6;--border-subtle:#ffffff0d;--border-default:#ffffff1a;--border-accent:#a855f74d;--border-strong:#ffffff2e;--prime:#f59e0b;--sidebar-w:220px;--header-h:48px;--footer-h:32px}html,body,#root{height:100%}body{background:var(--bg-0);color:var(--tx-1);-webkit-font-smoothing:antialiased;margin:0;font-family:-apple-system,BlinkMacSystemFont,Inter,Segoe UI,Roboto,sans-serif;font-size:13px;line-height:1.5}.mono{font-family:var(--font-mono)}.dot{border-radius:50%;flex-shrink:0;width:6px;height:6px;display:inline-block}.dot-success{background:var(--success)}.dot-warning{background:var(--warning)}.dot-danger{background:var(--danger)}.dot-info{background:var(--info)}.dot-accent{background:var(--accent)}.dot-signal{background:var(--signal)}.dot-muted{background:var(--tx-3)}@keyframes signal-pulse{0%,to{opacity:1}50%{opacity:.5}}.dot-pulse{animation:1.6s ease-in-out infinite signal-pulse}@keyframes toast-in{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.animate-toast-in{animation:.22s ease-out toast-in}.prose-markdown h1{color:var(--tx-1);letter-spacing:-.01em;margin:.6em 0 .4em;font-size:22px;font-weight:600}.prose-markdown h2{color:var(--tx-1);margin:1.4em 0 .4em;font-size:17px;font-weight:600}.prose-markdown h3{color:var(--tx-2);text-transform:uppercase;letter-spacing:.06em;margin:1.2em 0 .4em;font-size:14px;font-weight:600}.prose-markdown h4{color:var(--tx-2);margin:1em 0 .3em;font-size:13px;font-weight:600}.prose-markdown p{color:var(--tx-2);margin:.6em 0}.prose-markdown ul,.prose-markdown ol{color:var(--tx-2);margin:.6em 0 .6em 1.4em}.prose-markdown li{margin:.25em 0}.prose-markdown a{color:var(--accent-soft);text-underline-offset:2px;text-decoration:underline}.prose-markdown a:hover{color:var(--accent)}.prose-markdown code{font-family:var(--font-mono);background:var(--bg-2);border:1px solid var(--border-subtle);color:var(--tx-1);border-radius:4px;padding:.08em .35em;font-size:.92em}.prose-markdown pre{background:var(--bg-2);border:1px solid var(--border-subtle);border-radius:6px;margin:.8em 0;padding:12px 14px;overflow-x:auto}.prose-markdown pre code{background:0 0;border:none;padding:0;font-size:12px;line-height:1.55}.prose-markdown blockquote{border-left:2px solid var(--accent);color:var(--tx-3);margin:.8em 0;padding-left:12px}.prose-markdown hr{border:0;border-top:1px solid var(--border-subtle);margin:1.4em 0}.prose-markdown table{border-collapse:collapse;width:100%;margin:.8em 0;font-size:12px}.prose-markdown th,.prose-markdown td{border:1px solid var(--border-subtle);text-align:left;padding:6px 10px}.prose-markdown th{background:var(--bg-2);color:var(--tx-1)}.prose-markdown img{border-radius:6px;max-width:100%}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="tr" class="dark">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>Kortext</title>
|
|
7
|
+
<script type="module" crossorigin src="/assets/index-B80d5ZPZ.js"></script>
|
|
8
|
+
<link rel="stylesheet" crossorigin href="/assets/index-Bge5Gzqv.css">
|
|
9
|
+
</head>
|
|
10
|
+
<body class="bg-neutral-950 text-neutral-100 antialiased">
|
|
11
|
+
<div id="root"></div>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
# Kortext v3 — Architecture
|
|
2
|
+
|
|
3
|
+
This document describes the runtime architecture of Kortext v3. It is meant
|
|
4
|
+
for developers contributing to Kortext or integrating against it. For an
|
|
5
|
+
end-user walkthrough, see [USER-GUIDE.md](../USER-GUIDE.md).
|
|
6
|
+
|
|
7
|
+
## Layers at a glance
|
|
8
|
+
|
|
9
|
+
```mermaid
|
|
10
|
+
flowchart TB
|
|
11
|
+
subgraph Clients["Clients"]
|
|
12
|
+
Dashboard["React Dashboard<br/>Vite + TanStack Router"]
|
|
13
|
+
ClaudeCode["Claude Code / Cursor<br/>(MCP stdio)"]
|
|
14
|
+
SSE["Remote MCP client<br/>(SSE)"]
|
|
15
|
+
CLI["kortext CLI"]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
subgraph Backend["Express 5 backend (one process)"]
|
|
19
|
+
REST["REST API<br/>/api/*"]
|
|
20
|
+
MCPSSE["MCP /mcp/sse + /mcp/messages"]
|
|
21
|
+
MCPStdio["MCP stdio entry"]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
subgraph Core["Core runtime"]
|
|
25
|
+
Orchestrator["Orchestrator<br/>watcher · chainer · queue · dispatcher"]
|
|
26
|
+
Engine["Pipeline engine<br/>parser · DAG · worker pool · gate · safety"]
|
|
27
|
+
Executors["CLI executors<br/>Claude · Codex · Gemini · Mock"]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
subgraph State["State"]
|
|
31
|
+
SQLite[("SQLite<br/>.kortext/kortext.db")]
|
|
32
|
+
Worktrees[(".kortext/worktrees/<br/>per-run git worktrees")]
|
|
33
|
+
Markdown[("agents/ workflows/ rules/<br/>workspace/references/")]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
Dashboard --> REST
|
|
37
|
+
CLI --> Backend
|
|
38
|
+
SSE --> MCPSSE
|
|
39
|
+
ClaudeCode --> MCPStdio
|
|
40
|
+
|
|
41
|
+
REST --> Orchestrator
|
|
42
|
+
MCPSSE --> Orchestrator
|
|
43
|
+
MCPStdio --> Orchestrator
|
|
44
|
+
|
|
45
|
+
Orchestrator --> Engine
|
|
46
|
+
Engine --> Executors
|
|
47
|
+
Engine --> SQLite
|
|
48
|
+
Engine --> Worktrees
|
|
49
|
+
Orchestrator --> SQLite
|
|
50
|
+
Orchestrator --> Markdown
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Single Node process. The MCP stdio entry is a separate process (one per
|
|
54
|
+
host CLI) that shares the factory and dependencies but mounts its own
|
|
55
|
+
transport.
|
|
56
|
+
|
|
57
|
+
## Data layer
|
|
58
|
+
|
|
59
|
+
### Hybrid: markdown + SQLite
|
|
60
|
+
|
|
61
|
+
| What | Where | Why |
|
|
62
|
+
|---|---|---|
|
|
63
|
+
| Blueprint, ADRs, references | `workspace/references/*.md` | Human authoring; long-form |
|
|
64
|
+
| Personas | `agents/*.md` | Human-editable; hot-reloaded |
|
|
65
|
+
| Workflows | `workflows/*.md` | Human-readable DAGs |
|
|
66
|
+
| Rules | `rules/*.md` | Human-readable; loaded into prompts |
|
|
67
|
+
| Backlog | SQLite `backlog_items` | Frequent state changes; relational |
|
|
68
|
+
| Runs / steps | SQLite `runs`, `run_steps` | Time-series; queried by status |
|
|
69
|
+
| Approvals | SQLite `pending_questions` | First-class lifecycle |
|
|
70
|
+
| Audit | SQLite `audit_log` | Append-only; queried by actor/action |
|
|
71
|
+
| Generated artifacts | Disk + SQLite index | Disk for history, index for search |
|
|
72
|
+
|
|
73
|
+
Two principles:
|
|
74
|
+
|
|
75
|
+
- **Human sources are read-only to the engine.** Personas and workflows
|
|
76
|
+
are parsed in memory; the engine never writes them back.
|
|
77
|
+
- **Generated markdown gets an index row** in `runtime_artifacts` so the
|
|
78
|
+
dashboard can find it without scanning the filesystem.
|
|
79
|
+
|
|
80
|
+
### SQLite schema (13 tables)
|
|
81
|
+
|
|
82
|
+
```mermaid
|
|
83
|
+
erDiagram
|
|
84
|
+
backlog_items ||--o{ runs : "item_id"
|
|
85
|
+
backlog_items ||--o{ contexts : "item_id"
|
|
86
|
+
backlog_items }o--|| backlog_items : "parent_id"
|
|
87
|
+
sessions ||--o{ contexts : "session_id"
|
|
88
|
+
runs ||--o{ run_steps : "run_id"
|
|
89
|
+
runs ||--o{ runtime_artifacts : "run_id"
|
|
90
|
+
runs ||--o{ pending_questions : "run_id"
|
|
91
|
+
runs ||--o{ secrets_scan_results : "run_id"
|
|
92
|
+
handovers ||--o| backlog_items : "item_id"
|
|
93
|
+
decisions_index ||--o| backlog_items : "item_id"
|
|
94
|
+
notifications_sent }o--|| pending_questions : "question_id"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Specifics worth knowing:
|
|
98
|
+
|
|
99
|
+
- **All timestamps are `INTEGER` Unix milliseconds.** Read with
|
|
100
|
+
`new Date(ms)` on the dashboard side.
|
|
101
|
+
- **All JSON columns are `TEXT`** plus json1 access. Helpers in
|
|
102
|
+
`server/db/json.ts` parse on read and serialize on write.
|
|
103
|
+
- **WAL mode is on.** Required because the dashboard polls every 3 seconds
|
|
104
|
+
while the engine writes step status concurrently.
|
|
105
|
+
- **Foreign keys are enforced.** `PRAGMA foreign_keys = ON` is set in
|
|
106
|
+
`server/db/client.ts`.
|
|
107
|
+
- **Migrations** live in `server/db/migrations/*.sql` and run on first DB
|
|
108
|
+
open. `npm run build:server` copies them into `dist/server/db/migrations/`
|
|
109
|
+
so installed packages can boot from scratch.
|
|
110
|
+
|
|
111
|
+
## Engine
|
|
112
|
+
|
|
113
|
+
```mermaid
|
|
114
|
+
flowchart LR
|
|
115
|
+
md["workflows/*.md"] --> parser["workflow-parser.ts"]
|
|
116
|
+
parser --> dag["dag.ts<br/>(Kahn-style)"]
|
|
117
|
+
dag --> pool["worker-pool.ts<br/>concurrency 3 (configurable)"]
|
|
118
|
+
pool --> exec["executor.ts<br/>(interface)"]
|
|
119
|
+
exec --> claude["claude-cli-executor"]
|
|
120
|
+
exec --> codex["codex-cli-executor"]
|
|
121
|
+
exec --> gemini["gemini-cli-executor"]
|
|
122
|
+
exec --> mock["mock-executor"]
|
|
123
|
+
|
|
124
|
+
pool --> wt["worktree.ts<br/>(per-run isolation)"]
|
|
125
|
+
pool --> gate["gate-enforcer.ts<br/>(pre + barrier)"]
|
|
126
|
+
pool --> safety["secret-scanner.ts<br/>harmful-output-filter.ts"]
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Workflow parsing
|
|
130
|
+
|
|
131
|
+
`workflow-parser.ts` reads YAML frontmatter (`id`, `nextWorkflowId`, `gates`)
|
|
132
|
+
and the `## Steps` section. Each `### step_name` block becomes a typed
|
|
133
|
+
step with `persona`, `inputs`, `outputs`, optional `gate`. The parser is
|
|
134
|
+
intentionally minimal — full YAML is not required.
|
|
135
|
+
|
|
136
|
+
### DAG construction
|
|
137
|
+
|
|
138
|
+
`dag.ts` walks every step and matches each `inputs[]` entry against
|
|
139
|
+
**`outputs[]`** from earlier steps. A step depends on the step that
|
|
140
|
+
produces its inputs. Inputs that no step produces are flagged as
|
|
141
|
+
`externalInputs` — these get checked by the gate enforcer.
|
|
142
|
+
|
|
143
|
+
Kahn-style topological sort detects cycles. Cycle = workflow rejected at
|
|
144
|
+
load time, never reaches the runtime.
|
|
145
|
+
|
|
146
|
+
### Worker pool
|
|
147
|
+
|
|
148
|
+
`worker-pool.ts` is a **pull-ready scheduler**, not a topological queue:
|
|
149
|
+
|
|
150
|
+
1. Initial ready set = nodes with zero dependencies.
|
|
151
|
+
2. Up to `concurrency` workers are spawned (default 3, configurable per run).
|
|
152
|
+
3. Each worker pulls one ready step, executes it, marks it `succeeded` /
|
|
153
|
+
`failed`, and re-evaluates the ready set.
|
|
154
|
+
4. On first `failed`, an `AbortController` cancels in-flight steps and the
|
|
155
|
+
remaining graph is marked `skipped`.
|
|
156
|
+
5. Gates pause the pool via a `gateController.pauseAtGate` barrier; resume
|
|
157
|
+
re-enters the same pool with the gate decision in hand.
|
|
158
|
+
|
|
159
|
+
### Gate enforcement
|
|
160
|
+
|
|
161
|
+
Two kinds of gate:
|
|
162
|
+
|
|
163
|
+
- **Pre-gate (`externalInputs`):** the workflow declares external inputs
|
|
164
|
+
(e.g. `blueprint.md`); the enforcer checks each one's frontmatter has
|
|
165
|
+
`status: approved` before the run starts.
|
|
166
|
+
- **Mid-run barrier (`gate: true`):** the worker pool halts after the step
|
|
167
|
+
completes, writes a row to `pending_questions`, and waits for an
|
|
168
|
+
`approval-queue` decision.
|
|
169
|
+
|
|
170
|
+
A rejected gate flips the run to `cancelled` with
|
|
171
|
+
`error_message: rejected: <reason>` and quarantines the worktree.
|
|
172
|
+
|
|
173
|
+
### Per-run worktrees
|
|
174
|
+
|
|
175
|
+
`worktree.ts` calls `git worktree add .kortext/worktrees/run-<id>` on a
|
|
176
|
+
branch named `kortext/run-<id>`. The namespace prevents collisions with
|
|
177
|
+
your own branches.
|
|
178
|
+
|
|
179
|
+
On success the engine can merge into the source branch and remove the
|
|
180
|
+
worktree (off by default). On failure the worktree is moved to
|
|
181
|
+
`.kortext/worktrees/quarantine/run-<id>-<timestamp>/` and the branch is
|
|
182
|
+
preserved.
|
|
183
|
+
|
|
184
|
+
`kortext cleanup --quarantine-older-than=Nd --branches` removes quarantined
|
|
185
|
+
worktrees and the matching branches after they age out.
|
|
186
|
+
|
|
187
|
+
### Output safety
|
|
188
|
+
|
|
189
|
+
After each successful step the engine runs:
|
|
190
|
+
|
|
191
|
+
- **Secret scanner** — four pattern groups (quoted assignment, env
|
|
192
|
+
assignment, service token, auth header) with allow-listed exceptions
|
|
193
|
+
(`process.env`, `YOUR_…`, `PLACEHOLDER`, `.env*`). Findings flip the step
|
|
194
|
+
to `failed` with a masked snippet recorded in `secrets_scan_results`.
|
|
195
|
+
- **Harmful-output filter** — configurable banned-phrase list. The v3.0
|
|
196
|
+
implementation is a placeholder; a content-policy pass lands in v3.1+.
|
|
197
|
+
|
|
198
|
+
## Orchestrator
|
|
199
|
+
|
|
200
|
+
```mermaid
|
|
201
|
+
sequenceDiagram
|
|
202
|
+
participant File as blueprint.md
|
|
203
|
+
participant W as BlueprintWatcher
|
|
204
|
+
participant O as Orchestrator
|
|
205
|
+
participant C as PipelineChainer
|
|
206
|
+
participant E as Engine
|
|
207
|
+
participant Q as ApprovalQueue
|
|
208
|
+
participant D as Dispatcher
|
|
209
|
+
participant N as Slack/Telegram
|
|
210
|
+
|
|
211
|
+
File->>W: status: draft → approved
|
|
212
|
+
W->>O: triggerWorkflow(analysis, blueprint)
|
|
213
|
+
O->>E: runWorkflow(graph, executor)
|
|
214
|
+
E-->>Q: gate barrier (step k)
|
|
215
|
+
Q-->>D: notify(question)
|
|
216
|
+
D->>N: post
|
|
217
|
+
Note over Q: waits...
|
|
218
|
+
Q->>E: decision: approve
|
|
219
|
+
E-->>O: workflow complete
|
|
220
|
+
O->>C: chain(nextWorkflowId)
|
|
221
|
+
C->>O: triggerWorkflow(planning)
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### Pipeline chainer
|
|
225
|
+
|
|
226
|
+
`pipeline-chainer.ts` reads the completed workflow's `nextWorkflowId` and
|
|
227
|
+
triggers the next run with the same item context. Chain breaks if
|
|
228
|
+
`nextWorkflowId` is missing or the previous run is in a terminal-failed
|
|
229
|
+
state.
|
|
230
|
+
|
|
231
|
+
### Approval queue
|
|
232
|
+
|
|
233
|
+
`approval-queue.ts` writes a `pending_questions` row, notifies, and exposes
|
|
234
|
+
three REST endpoints:
|
|
235
|
+
|
|
236
|
+
- `GET /api/questions` — list open
|
|
237
|
+
- `POST /api/questions/:id/answer` — resolve with `{ decision, reason? }`
|
|
238
|
+
- `POST /api/runs/:runId/approve` — sugar for resolving the most recent
|
|
239
|
+
open question on a run
|
|
240
|
+
|
|
241
|
+
The same surface is exposed via MCP (`list_pending_questions`,
|
|
242
|
+
`respond_to_question`).
|
|
243
|
+
|
|
244
|
+
### Notification dispatcher
|
|
245
|
+
|
|
246
|
+
`notifications/dispatcher.ts` fans out to `slack.ts` and `telegram.ts`,
|
|
247
|
+
deduplicated by `(channel, kind, resource_id)` and recorded in
|
|
248
|
+
`notifications_sent`. Restarting the runtime never replays old events.
|
|
249
|
+
|
|
250
|
+
### Resume semantics
|
|
251
|
+
|
|
252
|
+
`resume.ts` runs on server boot. Any row in `runs` with `status: running`
|
|
253
|
+
is reclassified to `cancelled` with `error_message: orphaned: server
|
|
254
|
+
restarted`. `orchestrator.retryRun(runId)` can pick orphaned runs up from
|
|
255
|
+
their last persisted gate (pre-completed gates are replayed in order).
|
|
256
|
+
|
|
257
|
+
## MCP server
|
|
258
|
+
|
|
259
|
+
```mermaid
|
|
260
|
+
flowchart LR
|
|
261
|
+
factory["createKortextMcpServer(deps)"] --> tools["15 tools<br/>(zod schemas)"]
|
|
262
|
+
factory --> stdio["mcp/stdio.ts<br/>(CLI entry)"]
|
|
263
|
+
factory --> sse["mcp/sse.ts<br/>(Express hook)"]
|
|
264
|
+
sse --> session1["new McpServer<br/>per GET /mcp/sse"]
|
|
265
|
+
sse --> session2["..."]
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Key decisions:
|
|
269
|
+
|
|
270
|
+
- **Factory + injectable deps.** Tests, stdio, and SSE all call the same
|
|
271
|
+
factory with mocked or real dependencies (db, orchestrator,
|
|
272
|
+
registries).
|
|
273
|
+
- **SSE per-session McpServer instance.** The MCP SDK ties handler state
|
|
274
|
+
to the transport; multiplexing one server across two transports leaks
|
|
275
|
+
state. `mcp/sse.ts` creates a fresh `McpServer` per `GET /mcp/sse`,
|
|
276
|
+
keys a `transports` map by `sessionId`, and cleans up on `onclose`.
|
|
277
|
+
- **Stdio console patch.** Stdout is the JSONRPC channel. `bin/kortext.ts
|
|
278
|
+
mcp` re-routes `console.log` → `console.error` at startup. New modules
|
|
279
|
+
must default to `console.error` for any logging.
|
|
280
|
+
- **Tool envelope = JSON text + structuredContent.** Every tool returns
|
|
281
|
+
`{ content: [{type:'text', text: JSON.stringify(...)}], structuredContent }`
|
|
282
|
+
so old clients see text frames and new clients get structured payloads.
|
|
283
|
+
|
|
284
|
+
The 15 tools:
|
|
285
|
+
|
|
286
|
+
| Group | Tools |
|
|
287
|
+
|---|---|
|
|
288
|
+
| Workflow | `list_workflows`, `list_personas`, `list_pipelines`, `get_pipeline`, `start_pipeline` |
|
|
289
|
+
| Backlog | `list_backlog`, `add_backlog_item`, `transition_item` |
|
|
290
|
+
| Approval | `list_pending_questions`, `respond_to_question` |
|
|
291
|
+
| Context | `get_context`, `handover`, `get_logs` |
|
|
292
|
+
| Blueprint | `read_blueprint`, `approve_blueprint` |
|
|
293
|
+
| Health | `get_runtime_status` |
|
|
294
|
+
|
|
295
|
+
## Dashboard
|
|
296
|
+
|
|
297
|
+
```mermaid
|
|
298
|
+
flowchart LR
|
|
299
|
+
subgraph Routes["TanStack Router (hash history)"]
|
|
300
|
+
D["/"]
|
|
301
|
+
B["/board"]
|
|
302
|
+
M["/memory"]
|
|
303
|
+
Rp["/reports"]
|
|
304
|
+
Rf["/references"]
|
|
305
|
+
S["/settings/*"]
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
subgraph Overlays["Global overlays"]
|
|
309
|
+
Bell["BellMenu"]
|
|
310
|
+
Toast["Toasts"]
|
|
311
|
+
Term["TerminalPanel"]
|
|
312
|
+
Time["TimelinePanel"]
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
subgraph Stores["Context fan-out"]
|
|
316
|
+
PQ["PendingQuestionsProvider<br/>poll 3s"]
|
|
317
|
+
Shell["shell-store"]
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
PQ --> Bell
|
|
321
|
+
PQ --> Toast
|
|
322
|
+
Shell --> Term
|
|
323
|
+
Shell --> Time
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
Implementation notes:
|
|
327
|
+
|
|
328
|
+
- **Hash history** so the Express side never needs an SPA fallback. Static
|
|
329
|
+
`dist/web` serves the bundle from any subpath.
|
|
330
|
+
- **Tailwind v4 `@theme inline` + CSS variables.** Palette tokens are a
|
|
331
|
+
single source — both `var(--accent)` and `bg-accent` work.
|
|
332
|
+
- **API type mirror.** `src/lib/api-types.ts` hand-mirrors server response
|
|
333
|
+
shapes so the frontend bundle never picks up transitive
|
|
334
|
+
`better-sqlite3`.
|
|
335
|
+
- **Allow-listed `/api/docs/:scope`.** Five scopes
|
|
336
|
+
(`references | reports | memory | rules | workflows`). `path.resolve` +
|
|
337
|
+
prefix check blocks traversal.
|
|
338
|
+
- **Marked + DOMPurify.** Every markdown render is sanitized.
|
|
339
|
+
- **Single polling source.** `PendingQuestionsProvider` is the only thing
|
|
340
|
+
hitting `/api/questions`; the bell, toast emitter, and dashboard card
|
|
341
|
+
all subscribe.
|
|
342
|
+
|
|
343
|
+
## CLI
|
|
344
|
+
|
|
345
|
+
```
|
|
346
|
+
bin/kortext.js (dual-mode shim)
|
|
347
|
+
├── dist/bin/kortext.js exists? → in-process import (fast)
|
|
348
|
+
└── otherwise → spawn `tsx bin/kortext.ts` (dev)
|
|
349
|
+
|
|
350
|
+
bin/kortext.ts
|
|
351
|
+
├── --version / --help (top-level)
|
|
352
|
+
├── init → server/cli/init.ts (pure: scaffold plan)
|
|
353
|
+
├── serve → server/cli/serve.ts (pure: buildServeCommands)
|
|
354
|
+
├── start → server/cli/commands.ts (orchestrator)
|
|
355
|
+
├── approve → server/cli/commands.ts
|
|
356
|
+
├── status → server/cli/commands.ts
|
|
357
|
+
├── logs → server/cli/logs.ts (pure: query plan)
|
|
358
|
+
├── cleanup → server/cli/cleanup.ts
|
|
359
|
+
├── doctor → server/engine/consistency.ts
|
|
360
|
+
└── mcp → mcp/stdio.ts
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
Command modules under `server/cli/` are **pure** — they never call
|
|
364
|
+
`console.*`. The bin layer formats data and owns stdout/stderr. This is
|
|
365
|
+
what makes the CLI unit-testable without spawning processes.
|
|
366
|
+
|
|
367
|
+
## CI
|
|
368
|
+
|
|
369
|
+
```mermaid
|
|
370
|
+
flowchart LR
|
|
371
|
+
push["push / PR to main"] --> co["checkout@v4"]
|
|
372
|
+
co --> sn["setup-node@v4<br/>Node 22 · npm cache"]
|
|
373
|
+
sn --> ci["npm ci"]
|
|
374
|
+
ci --> lint["npm run lint"]
|
|
375
|
+
lint --> tc["npm run typecheck"]
|
|
376
|
+
tc --> test["npm test (263)"]
|
|
377
|
+
test --> build["npm run build"]
|
|
378
|
+
build --> smoke["node dist/bin/kortext.js --version"]
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
`cancel-in-progress: true` on the workflow concurrency group supersedes
|
|
382
|
+
older runs for the same ref. The compiled-CLI smoke is the gate that
|
|
383
|
+
caught the `packageRoot()` walk-up bug — installed users always see the
|
|
384
|
+
fast `dist/` path, so the version-reporting bug would have shipped
|
|
385
|
+
otherwise.
|
|
386
|
+
|
|
387
|
+
## Where to look in the codebase
|
|
388
|
+
|
|
389
|
+
| Concern | File |
|
|
390
|
+
|---|---|
|
|
391
|
+
| Schema | `server/db/migrations/001_init.sql` |
|
|
392
|
+
| DB client | `server/db/client.ts` |
|
|
393
|
+
| Repositories | `server/db/repositories/*.ts` |
|
|
394
|
+
| Workflow parsing | `server/engine/workflow-parser.ts` |
|
|
395
|
+
| DAG construction | `server/engine/dag.ts` |
|
|
396
|
+
| Worker pool | `server/engine/worker-pool.ts` |
|
|
397
|
+
| Worktree manager | `server/engine/worktree.ts` |
|
|
398
|
+
| Gate enforcer | `server/engine/gate-enforcer.ts` |
|
|
399
|
+
| Output safety | `server/safety/secret-scanner.ts`, `server/safety/harmful-output-filter.ts` |
|
|
400
|
+
| Orchestrator | `server/orchestrator/orchestrator.ts` |
|
|
401
|
+
| Blueprint watcher | `server/orchestrator/blueprint-watcher.ts` |
|
|
402
|
+
| Pipeline chainer | `server/orchestrator/pipeline-chainer.ts` |
|
|
403
|
+
| Approval queue | `server/orchestrator/approval-queue.ts` |
|
|
404
|
+
| Notifications | `server/notifications/{dispatcher,slack,telegram}.ts` |
|
|
405
|
+
| MCP factory | `mcp/server.ts` |
|
|
406
|
+
| MCP stdio | `mcp/stdio.ts` |
|
|
407
|
+
| MCP SSE | `mcp/sse.ts` |
|
|
408
|
+
| CLI bin | `bin/kortext.ts`, `bin/kortext.js` |
|
|
409
|
+
| Dashboard | `src/router.tsx`, `src/routes/*`, `src/components/*` |
|
|
410
|
+
|
|
411
|
+
For day-to-day operations see [USER-GUIDE.md](../USER-GUIDE.md). Internal
|
|
412
|
+
project history (phase-by-phase roadmap, handover bootstrap, contributor
|
|
413
|
+
guidelines) lives under [docs/internal/](./internal/).
|
package/package.json
CHANGED
|
@@ -1,29 +1,101 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kortext",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "AI
|
|
5
|
-
"
|
|
3
|
+
"version": "3.0.0",
|
|
4
|
+
"description": "Autonomous AI agent runtime — TypeScript + SQLite + React",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"private": false,
|
|
6
7
|
"bin": {
|
|
7
|
-
"kortext": "
|
|
8
|
+
"kortext": "./bin/kortext.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"bin/",
|
|
12
|
+
"dist/",
|
|
13
|
+
"agents/",
|
|
14
|
+
"workflows/",
|
|
15
|
+
"rules/",
|
|
16
|
+
"workspace/",
|
|
17
|
+
"scripts/",
|
|
18
|
+
"AGENTS.md",
|
|
19
|
+
"CHANGELOG.md",
|
|
20
|
+
"USER-GUIDE.md",
|
|
21
|
+
"docs/architecture.md",
|
|
22
|
+
"LICENSE"
|
|
23
|
+
],
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "git+https://github.com/erayendes/kortext.git"
|
|
27
|
+
},
|
|
28
|
+
"homepage": "https://github.com/erayendes/kortext#readme",
|
|
29
|
+
"bugs": {
|
|
30
|
+
"url": "https://github.com/erayendes/kortext/issues"
|
|
8
31
|
},
|
|
9
32
|
"scripts": {
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
33
|
+
"dev": "concurrently -n server,web -c blue,magenta \"npm:dev:server\" \"npm:dev:web\"",
|
|
34
|
+
"dev:server": "tsx watch --clear-screen=false server/index.ts",
|
|
35
|
+
"dev:web": "vite",
|
|
36
|
+
"build": "npm run build:server && npm run build:web",
|
|
37
|
+
"build:server": "tsc -p tsconfig.build.json && node scripts/copy-migrations.mjs",
|
|
38
|
+
"build:web": "vite build",
|
|
39
|
+
"preview": "vite preview",
|
|
40
|
+
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.server.json --noEmit",
|
|
41
|
+
"lint": "eslint .",
|
|
42
|
+
"format": "prettier --write .",
|
|
43
|
+
"format:check": "prettier --check .",
|
|
44
|
+
"test": "vitest run",
|
|
45
|
+
"test:watch": "vitest"
|
|
13
46
|
},
|
|
14
47
|
"keywords": [
|
|
15
48
|
"ai",
|
|
16
49
|
"agent",
|
|
17
50
|
"framework",
|
|
18
51
|
"automation",
|
|
19
|
-
"
|
|
52
|
+
"claude",
|
|
53
|
+
"codex",
|
|
20
54
|
"gemini",
|
|
21
|
-
"
|
|
55
|
+
"mcp",
|
|
56
|
+
"orchestration"
|
|
22
57
|
],
|
|
23
58
|
"author": "Eray Endes",
|
|
24
59
|
"license": "MIT",
|
|
25
60
|
"engines": {
|
|
26
|
-
"node": ">=
|
|
27
|
-
|
|
61
|
+
"node": ">=22.0.0"
|
|
62
|
+
},
|
|
63
|
+
"dependencies": {
|
|
64
|
+
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
65
|
+
"@tanstack/react-router": "^1.170.7",
|
|
66
|
+
"better-sqlite3": "^12.10.0",
|
|
67
|
+
"dompurify": "^3.4.5",
|
|
68
|
+
"express": "^5.0.1",
|
|
69
|
+
"lucide-react": "^1.16.0",
|
|
70
|
+
"marked": "^18.0.4",
|
|
71
|
+
"zod": "^3.24.1"
|
|
72
|
+
},
|
|
73
|
+
"devDependencies": {
|
|
74
|
+
"@eslint/js": "^9.18.0",
|
|
75
|
+
"@tailwindcss/vite": "^4.0.0",
|
|
76
|
+
"@tanstack/router-devtools": "^1.167.0",
|
|
77
|
+
"@types/better-sqlite3": "^7.6.12",
|
|
78
|
+
"@types/express": "^5.0.0",
|
|
79
|
+
"@types/marked": "^5.0.2",
|
|
80
|
+
"@types/node": "^22.10.5",
|
|
81
|
+
"@types/react": "^19.0.2",
|
|
82
|
+
"@types/react-dom": "^19.0.2",
|
|
83
|
+
"@typescript-eslint/eslint-plugin": "^8.20.0",
|
|
84
|
+
"@typescript-eslint/parser": "^8.20.0",
|
|
85
|
+
"@vitejs/plugin-react": "^4.3.4",
|
|
86
|
+
"concurrently": "^9.1.2",
|
|
87
|
+
"eslint": "^9.18.0",
|
|
88
|
+
"eslint-config-prettier": "^10.0.1",
|
|
89
|
+
"eslint-plugin-react": "^7.37.4",
|
|
90
|
+
"eslint-plugin-react-hooks": "^5.1.0",
|
|
91
|
+
"globals": "^15.14.0",
|
|
92
|
+
"prettier": "^3.4.2",
|
|
93
|
+
"react": "^19.0.0",
|
|
94
|
+
"react-dom": "^19.0.0",
|
|
95
|
+
"tailwindcss": "^4.0.0",
|
|
96
|
+
"tsx": "^4.19.2",
|
|
97
|
+
"typescript": "^5.7.2",
|
|
98
|
+
"vite": "^7.0.0",
|
|
99
|
+
"vitest": "^3.0.0"
|
|
28
100
|
}
|
|
29
101
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Post-build step: tsc doesn't copy non-TS assets. The migration runner
|
|
3
|
+
// expects `server/db/migrations/*.sql` next to the compiled `migrate.js`,
|
|
4
|
+
// so we mirror them into `dist/server/db/migrations/` after tsc emits.
|
|
5
|
+
|
|
6
|
+
import { cpSync, mkdirSync, readdirSync, existsSync } from 'node:fs';
|
|
7
|
+
import { dirname, join, resolve } from 'node:path';
|
|
8
|
+
import { fileURLToPath } from 'node:url';
|
|
9
|
+
|
|
10
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
const root = resolve(here, '..');
|
|
12
|
+
const src = join(root, 'server', 'db', 'migrations');
|
|
13
|
+
const dst = join(root, 'dist', 'server', 'db', 'migrations');
|
|
14
|
+
|
|
15
|
+
if (!existsSync(src)) {
|
|
16
|
+
console.error(`[copy-migrations] source missing: ${src}`);
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
if (!existsSync(join(root, 'dist'))) {
|
|
20
|
+
console.error('[copy-migrations] dist/ not found — did `tsc` run?');
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
mkdirSync(dst, { recursive: true });
|
|
25
|
+
const files = readdirSync(src).filter((f) => f.endsWith('.sql'));
|
|
26
|
+
for (const f of files) {
|
|
27
|
+
cpSync(join(src, f), join(dst, f));
|
|
28
|
+
}
|
|
29
|
+
console.error(`[copy-migrations] copied ${files.length} migration file(s) → ${dst}`);
|
package/hooks/audit-logger.sh
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# KORTEXT MANAGED HOOK — generated/edited by kortext framework
|
|
3
|
-
# [KORTEXT] İşlem Günlüğü (Audit Logger)
|
|
4
|
-
|
|
5
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
-
# shellcheck source=kortext-lib.sh
|
|
7
|
-
source "$SCRIPT_DIR/kortext-lib.sh"
|
|
8
|
-
|
|
9
|
-
LOG_FILE="$KORTEXT_WORKSPACE_DIR/reports/audit.log"
|
|
10
|
-
TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S")
|
|
11
|
-
|
|
12
|
-
# Çevresel değişkenlerden bilgileri çek (Casing ve isim kullandığın AI arayüzüne göre değişebilir)
|
|
13
|
-
ACTION_FILE="${KORTEXT_FILE_PATH:-${CLAUDE_FILE_PATH:-${GEMINI_FILE_PATH:-${OPENAI_FILE_PATH:-N/A}}}}"
|
|
14
|
-
LAST_CMD="${KORTEXT_LAST_CMD:-${CLAUDE_LAST_COMMAND:-${GEMINI_LAST_ACTION:-${OPENAI_LAST_COMMAND:-N/A}}}}"
|
|
15
|
-
AGENT_NAME="${KORTEXT_AGENT_NAME:-${CLAUDE_AGENT_NAME:-${GEMINI_AGENT_NAME:-${OPENAI_AGENT_NAME:-Agent}}}}"
|
|
16
|
-
|
|
17
|
-
mkdir -p "$KORTEXT_WORKSPACE_DIR/reports"
|
|
18
|
-
|
|
19
|
-
# Kayıt Satırı Oluştur
|
|
20
|
-
LOG_ENTRY="[$TIMESTAMP] | AGENT: $AGENT_NAME | FILE: $ACTION_FILE | CMD: $LAST_CMD"
|
|
21
|
-
|
|
22
|
-
# Dosyaya ekle
|
|
23
|
-
echo "$LOG_ENTRY" >> "$LOG_FILE"
|
|
24
|
-
|
|
25
|
-
exit 0
|