karajan-code 4.70.3 → 5.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/README.md +2 -2
- package/package.json +6 -14
- package/packages/hu-board/package.json +1 -1
- package/packages/hu-board/public/app.js +4 -18
- package/packages/hu-board/public/index.html +5 -2
- package/packages/hu-board/public/styles.css +26 -0
- package/packages/hu-board/public/utils/api.js +0 -74
- package/packages/hu-board/public/utils/board-tour.js +62 -0
- package/packages/hu-board/public/utils/board-view.js +49 -144
- package/packages/hu-board/public/utils/command-launcher.js +8 -70
- package/packages/hu-board/public/utils/formatters.js +10 -0
- package/packages/hu-board/public/utils/governance-view.js +13 -1
- package/packages/hu-board/public/utils/hu-actions.js +17 -68
- package/packages/hu-board/public/utils/init-listeners.js +7 -8
- package/packages/hu-board/public/utils/log-panel.js +3 -16
- package/packages/hu-board/public/utils/maggle-mode.js +2 -12
- package/packages/hu-board/public/utils/modals.js +7 -0
- package/packages/hu-board/public/utils/project-picker-view.js +1 -1
- package/packages/hu-board/public/utils/server-push.js +3 -22
- package/packages/hu-board/public/utils/shared-board-notice.js +33 -0
- package/packages/hu-board/public/utils/story-detail-view.js +5 -19
- package/packages/hu-board/src/cleanup-zombies.js +0 -1
- package/packages/hu-board/src/command-runner.js +36 -25
- package/packages/hu-board/src/db-connection.js +282 -0
- package/packages/hu-board/src/db-paths.js +113 -0
- package/packages/hu-board/src/db-queries.js +188 -0
- package/packages/hu-board/src/db-tombstones.js +51 -0
- package/packages/hu-board/src/db.js +28 -619
- package/packages/hu-board/src/ephemeral-cleaner.js +2 -3
- package/packages/hu-board/src/hu-zombie-reaper.js +5 -1
- package/packages/hu-board/src/plan-mutations.js +3 -153
- package/packages/hu-board/src/plans-service.js +55 -0
- package/packages/hu-board/src/routes/api/commands.js +122 -0
- package/packages/hu-board/src/routes/api/plans.js +55 -0
- package/packages/hu-board/src/routes/api/projects.js +267 -0
- package/packages/hu-board/src/routes/api/prompts.js +135 -0
- package/packages/hu-board/src/routes/api/sessions.js +95 -0
- package/packages/hu-board/src/routes/api/stories.js +183 -0
- package/packages/hu-board/src/routes/api/system.js +241 -0
- package/packages/hu-board/src/routes/api/tombstones.js +38 -0
- package/packages/hu-board/src/routes/api.js +24 -1371
- package/packages/hu-board/src/routes/governance.js +23 -1
- package/packages/hu-board/src/routes/lanes.js +40 -0
- package/packages/hu-board/src/routes/rag.js +4 -3
- package/packages/hu-board/src/server.js +20 -34
- package/packages/hu-board/src/sync-files.js +318 -0
- package/packages/hu-board/src/sync-project.js +99 -0
- package/packages/hu-board/src/sync.js +22 -566
- package/packages/hu-board/src/zombie-reaper.js +1 -1
- package/scripts/dual-publish.mjs +19 -3
- package/scripts/postinstall.js +15 -2
- package/scripts/verify-pack-mcp.mjs +11 -7
- package/scripts/verify-pack.mjs +4 -4
- package/src/audit/audit-history.js +3 -2
- package/src/audit/dead-exports.js +68 -59
- package/src/audit/deterministic-summary.js +33 -13
- package/src/audit/npm-signatures.js +41 -0
- package/src/audit/sbom.js +35 -0
- package/src/checks/agent-token.js +112 -0
- package/src/checks/ai-surface.js +9 -7
- package/src/checks/config-files.js +8 -7
- package/src/checks/dir-setup.js +34 -1
- package/src/checks/native-build.js +21 -39
- package/src/checks/runner.js +128 -142
- package/src/cli/advanced-commands.js +6 -6
- package/src/cli/register-meta.js +42 -82
- package/src/cli/register-pipeline.js +8 -140
- package/src/cli/register-plan.js +9 -100
- package/src/cli/retired-commands.js +49 -0
- package/src/cli.js +18 -5
- package/src/commands/agent-run.js +40 -26
- package/src/commands/audit.js +127 -124
- package/src/commands/board.js +5 -9
- package/src/commands/check.js +29 -16
- package/src/commands/doctor.js +2 -0
- package/src/commands/env.js +176 -148
- package/src/commands/go.js +76 -55
- package/src/commands/harden.js +105 -86
- package/src/commands/hu-start.js +52 -0
- package/src/commands/hu.js +288 -221
- package/src/commands/identity.js +111 -78
- package/src/commands/init-atril.js +47 -0
- package/src/commands/init.js +11 -40
- package/src/commands/install-tools.js +70 -85
- package/src/commands/main-guard.js +78 -0
- package/src/commands/policy.js +226 -184
- package/src/commands/qmd.js +27 -21
- package/src/commands/rag.js +75 -48
- package/src/commands/review-gate.js +422 -339
- package/src/commands/start.js +4 -5
- package/src/commands/steward.js +96 -47
- package/src/commands/tournament.js +46 -37
- package/src/commands/worktree.js +94 -25
- package/src/config/loader.js +34 -17
- package/src/config/overrides.js +2 -1
- package/src/config/secrets.js +36 -0
- package/src/config.js +1 -0
- package/src/environment/adr.js +16 -2
- package/src/environment/board-access.js +11 -9
- package/src/git/karajan-label.js +20 -8
- package/src/guards/main-guard.js +54 -0
- package/src/harden/branch-protection.js +36 -3
- package/src/harden/hook-templates.js +16 -1
- package/src/harden/sentinel/posttooluse.mjs +18 -6
- package/src/harden/sentinel/pretooluse-sentinel.mjs +81 -35
- package/src/harden/sentinel/sentinel-lib.mjs +149 -23
- package/src/harden/sentinel/sentinel-shell.mjs +64 -0
- package/src/harden/sentinel/sessionstart.mjs +3 -2
- package/src/harden/sentinel/stop.mjs +5 -4
- package/src/harden/workflow-engine.js +12 -1
- package/src/harden/workflow-templates.js +1 -1
- package/src/hu/board-lookup.js +29 -0
- package/src/hu/gh-identity.js +23 -0
- package/src/hu/github-board.js +4 -2
- package/src/hu/lane-prune.js +15 -7
- package/src/hu/lane-setup.js +65 -0
- package/src/hu/lanes.js +66 -0
- package/src/hu/team-board-mirror.js +3 -2
- package/src/infrastructure/command-runner.js +1 -1
- package/src/infrastructure/file-system-service.js +1 -1
- package/src/mcp/handlers/direct-handlers.js +2 -292
- package/src/mcp/handlers/hu-handlers.js +44 -55
- package/src/mcp/handlers/management-handlers.js +2 -42
- package/src/mcp/server-handlers.js +16 -22
- package/src/mcp/tools.js +5 -200
- package/src/plan/lane-plans.js +54 -0
- package/src/plan/plan-store.js +7 -4
- package/src/policy/add.js +26 -12
- package/src/policy/adr-number-check.js +31 -0
- package/src/prompts/audit.js +299 -339
- package/src/prompts/card-context.js +10 -5
- package/src/prompts/reviewer.js +5 -2
- package/src/rag/auto-update.js +56 -43
- package/src/rag/bootstrap-index.js +28 -54
- package/src/rag/migrate.js +1 -1
- package/src/rag/onnx-fallback.js +2 -2
- package/src/rag/pid-lease.js +70 -0
- package/src/rag/project-store.js +2 -12
- package/src/review/card-first.js +57 -46
- package/src/review/dual-review.js +5 -4
- package/src/review/gate-gitignore.js +23 -4
- package/src/review/gate-hook.js +47 -0
- package/src/review/one-shot-review.js +51 -37
- package/src/review/publish-pr.js +18 -3
- package/src/review/repo-docs.js +73 -0
- package/src/review/repo-stack.js +59 -0
- package/src/review/reviewer-fallback.js +34 -3
- package/src/review/seal-commit.js +29 -0
- package/src/review/sonar-pregate.js +59 -44
- package/src/review/third-party-review.js +90 -16
- package/src/review/third-party-size.js +43 -0
- package/src/review/third-party-skills.js +54 -0
- package/src/review/verify-pr.js +2 -26
- package/src/roles/audit-role.js +106 -125
- package/src/skills/atril-skills.js +5 -4
- package/src/sonar/scanner.js +116 -101
- package/src/steward/invariants.js +5 -4
- package/src/steward/phantom-sweep.js +66 -0
- package/src/tournament/judge.js +60 -53
- package/src/utils/agent-home.js +33 -0
- package/src/utils/gh-account.js +37 -0
- package/src/utils/git.js +0 -13
- package/src/utils/home-migration.js +7 -1
- package/src/utils/main-checkout.js +53 -0
- package/src/utils/qmd-collection.js +3 -1
- package/src/utils/welcome.js +3 -3
- package/templates/{skills → atril/commands}/kj-architect.md +5 -0
- package/templates/{skills → atril/commands}/kj-audit.md +5 -0
- package/templates/{skills → atril/commands}/kj-board.md +5 -0
- package/templates/{skills → atril/commands}/kj-code.md +5 -0
- package/templates/{skills → atril/commands}/kj-csv-transform.md +5 -0
- package/templates/{skills → atril/commands}/kj-data-report.md +5 -0
- package/templates/{skills → atril/commands}/kj-discover.md +5 -0
- package/templates/{skills → atril/commands}/kj-rag-query.md +5 -0
- package/templates/{skills → atril/commands}/kj-review.md +5 -0
- package/templates/{skills → atril/commands}/kj-security.md +5 -0
- package/templates/{skills → atril/commands}/kj-sonar.md +5 -0
- package/templates/{skills → atril/commands}/kj-sql-analysis.md +5 -0
- package/templates/{skills → atril/commands}/kj-test.md +5 -0
- package/packages/hu-board/public/utils/run-launcher.js +0 -169
- package/packages/hu-board/src/run-tracker.js +0 -121
- package/src/activity-log.js +0 -59
- package/src/agents/host-agent.js +0 -38
- package/src/agents/model-registry.js +0 -142
- package/src/audit/plan-adherence.js +0 -224
- package/src/autonomy/arbiter-role.js +0 -71
- package/src/autonomy/arbiter.js +0 -22
- package/src/autonomy/decider.js +0 -18
- package/src/autonomy/decision-resolver.js +0 -58
- package/src/autonomy/outcome-report.js +0 -55
- package/src/autonomy/stage-ask.js +0 -30
- package/src/brain/decision-tracker.js +0 -125
- package/src/brain/decisor.js +0 -243
- package/src/brain/solomon-consult.js +0 -171
- package/src/brain/standby-scheduler.js +0 -8
- package/src/budget/comparison.js +0 -96
- package/src/canvas/parse-md.js +0 -238
- package/src/canvas/schema.js +0 -101
- package/src/canvas/to-flat.js +0 -85
- package/src/canvas/validate.js +0 -163
- package/src/ci/dispatch.js +0 -99
- package/src/ci/index.js +0 -3
- package/src/ci/pr-diff.js +0 -26
- package/src/cli/register-standby.js +0 -26
- package/src/commands/architect.js +0 -111
- package/src/commands/autorun.js +0 -49
- package/src/commands/researcher.js +0 -54
- package/src/commands/resume.js +0 -72
- package/src/commands/review.js +0 -89
- package/src/commands/run.js +0 -185
- package/src/commands/standby.js +0 -117
- package/src/commands/status.js +0 -36
- package/src/commands/triage.js +0 -78
- package/src/commands/undo.js +0 -62
- package/src/domains/domain-loader.js +0 -245
- package/src/domains/domain-registry.js +0 -140
- package/src/domains/domain-synthesizer.js +0 -129
- package/src/git/automation.js +0 -433
- package/src/git/coder-commit-guard.js +0 -40
- package/src/git/hu-automation.js +0 -243
- package/src/git/hu-snapshot.js +0 -10
- package/src/git/symlink-targets.js +0 -57
- package/src/golden/asserter.js +0 -92
- package/src/golden/loader.js +0 -52
- package/src/golden/runner.js +0 -92
- package/src/golden/schema.js +0 -41
- package/src/guards/duplicate-members.js +0 -86
- package/src/guards/intent-guard.js +0 -161
- package/src/guards/perf-guard.js +0 -126
- package/src/guards/policy-guard.js +0 -90
- package/src/guards/policy-resolver.js +0 -85
- package/src/guards/secret-redactor.js +0 -71
- package/src/hu/acceptance-runner.js +0 -138
- package/src/hu/lazy-planner.js +0 -109
- package/src/hu/parallel-executor.js +0 -94
- package/src/hu/routing-metrics.js +0 -17
- package/src/hu/split-validator.js +0 -143
- package/src/hu/splitting-detector.js +0 -158
- package/src/hu/splitting-generator.js +0 -175
- package/src/hu/store.js +0 -394
- package/src/infrastructure/mocks.js +0 -182
- package/src/mcp/handlers/run-handler.js +0 -318
- package/src/mcp/sovereignty-guard.js +0 -113
- package/src/mcp/tool-arg-normalizers.js +0 -16
- package/src/mutate/reviewer-signal.js +0 -76
- package/src/orchestrator/agent-fallback.js +0 -81
- package/src/orchestrator/brain-coordinator.js +0 -186
- package/src/orchestrator/ci-integration.js +0 -139
- package/src/orchestrator/config-init.js +0 -426
- package/src/orchestrator/direct-actions.js +0 -217
- package/src/orchestrator/drivers/error-recovery.js +0 -287
- package/src/orchestrator/drivers/init-context.js +0 -238
- package/src/orchestrator/drivers/iteration-loop.js +0 -382
- package/src/orchestrator/drivers/iteration-phases/coder-and-refactorer.js +0 -69
- package/src/orchestrator/drivers/iteration-phases/guards.js +0 -91
- package/src/orchestrator/drivers/iteration-phases/handle-approved.js +0 -29
- package/src/orchestrator/drivers/iteration-phases/quality-gates.js +0 -125
- package/src/orchestrator/drivers/iteration-phases/reviewer-gate.js +0 -62
- package/src/orchestrator/drivers/post-loop.js +0 -404
- package/src/orchestrator/drivers/pre-loop-phases/auto-hu-batch.js +0 -137
- package/src/orchestrator/drivers/pre-loop-phases/config-deprecations.js +0 -47
- package/src/orchestrator/drivers/pre-loop-phases/ensure-addyosmani-skills.js +0 -84
- package/src/orchestrator/drivers/pre-loop-phases/inject-loaded-plan.js +0 -393
- package/src/orchestrator/drivers/pre-loop.js +0 -524
- package/src/orchestrator/drivers/run-hu-batch.js +0 -468
- package/src/orchestrator/feedback-enrichment.js +0 -140
- package/src/orchestrator/feedback-queue.js +0 -151
- package/src/orchestrator/flow-control.js +0 -170
- package/src/orchestrator/flow-runner.js +0 -365
- package/src/orchestrator/fs-leak-detector.js +0 -228
- package/src/orchestrator/hu-scheduler.js +0 -114
- package/src/orchestrator/hu-sub-pipeline.js +0 -642
- package/src/orchestrator/iteration-gate.js +0 -73
- package/src/orchestrator/iteration-stages.js +0 -9
- package/src/orchestrator/parallel-limiter.js +0 -74
- package/src/orchestrator/pipeline-context.js +0 -72
- package/src/orchestrator/post-loop-stages.js +0 -468
- package/src/orchestrator/pre-loop-stages.js +0 -11
- package/src/orchestrator/preflight-checks.js +0 -487
- package/src/orchestrator/repair/repair-detector.js +0 -117
- package/src/orchestrator/repair/repair-runner.js +0 -142
- package/src/orchestrator/reviewer-fallback.js +0 -45
- package/src/orchestrator/role-output-compressor.js +0 -189
- package/src/orchestrator/session-journal.js +0 -308
- package/src/orchestrator/solomon-escalation.js +0 -331
- package/src/orchestrator/solomon-rules.js +0 -212
- package/src/orchestrator/stages/acceptance-coverage-stage.js +0 -47
- package/src/orchestrator/stages/architect-stage.js +0 -172
- package/src/orchestrator/stages/coder-stage.js +0 -506
- package/src/orchestrator/stages/domain-curator-stage.js +0 -82
- package/src/orchestrator/stages/format-stage.js +0 -61
- package/src/orchestrator/stages/hu-reviewer-phases/detect-and-apply-splits.js +0 -127
- package/src/orchestrator/stages/hu-reviewer-stage.js +0 -419
- package/src/orchestrator/stages/perf-stage.js +0 -140
- package/src/orchestrator/stages/planner-stage.js +0 -85
- package/src/orchestrator/stages/rag-context-stage.js +0 -80
- package/src/orchestrator/stages/rag-preload-decisor.js +0 -58
- package/src/orchestrator/stages/research-stage.js +0 -69
- package/src/orchestrator/stages/reviewer-stage.js +0 -431
- package/src/orchestrator/stages/sonar-stage.js +0 -439
- package/src/orchestrator/stages/stage-classes.js +0 -84
- package/src/orchestrator/stages/stage-executor.js +0 -155
- package/src/orchestrator/stages/suite-green-stage.js +0 -62
- package/src/orchestrator/stages/tdd-discipline-stage.js +0 -56
- package/src/orchestrator/stages/tool-judge-stage.js +0 -53
- package/src/orchestrator/stages/triage-stage.js +0 -172
- package/src/orchestrator/standby.js +0 -71
- package/src/orchestrator/verification-gate.js +0 -183
- package/src/orchestrator.js +0 -22
- package/src/plan/adr-generator.js +0 -170
- package/src/plan/adr-loader.js +0 -60
- package/src/plan/plan-executor.js +0 -100
- package/src/plan/plan-validation.js +0 -4
- package/src/prompts/acceptance-coverage.js +0 -32
- package/src/prompts/arbiter.js +0 -38
- package/src/prompts/architect.js +0 -103
- package/src/prompts/hu-reviewer.js +0 -244
- package/src/prompts/tool-correctness-judge.js +0 -31
- package/src/prompts/triage.js +0 -57
- package/src/rag/embedder.js +0 -2
- package/src/rag/embedders/_cloud-base.js +0 -2
- package/src/rag/embedders/cohere.js +0 -2
- package/src/rag/embedders/mistral.js +0 -2
- package/src/rag/embedders/onnx.js +0 -2
- package/src/rag/embedders/openai.js +0 -2
- package/src/rag/embedders/voyage.js +0 -2
- package/src/rag/rerank.js +0 -4
- package/src/rag/where-parser.js +0 -4
- package/src/repeat-detector.js +0 -88
- package/src/review/diff-generator.js +0 -112
- package/src/review/git-stash-helper.js +0 -104
- package/src/review/schema.js +0 -31
- package/src/review/scope-filter.js +0 -152
- package/src/review/snapshot-diff.js +0 -122
- package/src/review/tdd-discipline.js +0 -90
- package/src/review/tdd-policy.js +0 -69
- package/src/roles/acceptance-coverage-role.js +0 -78
- package/src/roles/architect-role.js +0 -77
- package/src/roles/coder-role.js +0 -113
- package/src/roles/commiter-role.js +0 -113
- package/src/roles/domain-curator-role.js +0 -134
- package/src/roles/hu-reviewer-role.js +0 -64
- package/src/roles/impeccable-role.js +0 -85
- package/src/roles/index.js +0 -18
- package/src/roles/karajan-brain-role.js +0 -134
- package/src/roles/perf-role.js +0 -122
- package/src/roles/planner-role.js +0 -151
- package/src/roles/refactorer-role.js +0 -30
- package/src/roles/repairer-role.js +0 -181
- package/src/roles/researcher-role.js +0 -70
- package/src/roles/reviewer-role.js +0 -115
- package/src/roles/security-role.js +0 -73
- package/src/roles/solomon-role.js +0 -271
- package/src/roles/sonar-role.js +0 -72
- package/src/roles/tester-role.js +0 -235
- package/src/roles/tool-correctness-judge-role.js +0 -78
- package/src/roles/triage-role.js +0 -99
- package/src/session/journal/decisions-writer.js +0 -200
- package/src/session/journal/iteration-logger.js +0 -194
- package/src/session/journal/summary-writer.js +0 -320
- package/src/session/journal/tree-writer.js +0 -164
- package/src/session/journal/write-all.js +0 -89
- package/src/session-cleanup.js +0 -116
- package/src/skills/semantic-detector.js +0 -167
- package/src/skills/skill-detector.js +0 -385
- package/src/sonar/cloud-scanner.js +0 -78
- package/src/tracker-bootstrap.js +0 -44
- package/src/types/index.js +0 -38
- package/src/types/policy.js +0 -43
- package/src/types/solomon.js +0 -87
- package/src/utils/async-lock.js +0 -31
- package/src/utils/budget.js +0 -229
- package/src/utils/cwd-confirm.js +0 -39
- package/src/utils/display/event-handlers.js +0 -403
- package/src/utils/display/formatters.js +0 -132
- package/src/utils/display/header.js +0 -47
- package/src/utils/display/session-summary.js +0 -118
- package/src/utils/display/solomon.js +0 -42
- package/src/utils/pricing.js +0 -29
- package/src/utils/quota-simulator.js +0 -56
- package/src/utils/role-assigner.js +0 -137
- package/src/utils/rtk-wrapper.js +0 -87
- package/src/utils/run-registry.js +0 -9
- package/src/utils/status-dashboard.js +0 -254
- package/src/utils/tool-call-extractor.js +0 -56
- package/src/webperf/devtools-detect.js +0 -112
- package/src/webperf/webperf-role-integration.js +0 -66
- package/templates/skills/kj-run.md +0 -73
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The main checkout of the repo a dir belongs to: lanes and plans hang from it, never from a
|
|
3
|
+
* lane (#2566). Not the Sentinel's lane identity (ADR 0002). Outside git, the dir unchanged.
|
|
4
|
+
*/
|
|
5
|
+
import fs from "node:fs";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import { execFileSync } from "node:child_process";
|
|
8
|
+
|
|
9
|
+
// null only for "not a git repository"; any other git failure is loud, never a silent nested lane.
|
|
10
|
+
const gitOrNull = (args, cwd) => {
|
|
11
|
+
// A git hook exports GIT_DIR & co: left in, they would override `cwd` and answer for the wrong repo.
|
|
12
|
+
const env = { ...process.env };
|
|
13
|
+
for (const name of ["GIT_DIR", "GIT_WORK_TREE", "GIT_COMMON_DIR", "LANGUAGE"]) delete env[name];
|
|
14
|
+
env.LC_ALL = "C"; // the stderr check below reads git's English message (KJC-BUG-0409)
|
|
15
|
+
try {
|
|
16
|
+
return execFileSync("git", args, { cwd, env, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }).trim();
|
|
17
|
+
} catch (err) {
|
|
18
|
+
if (/not a git repository/i.test(String(err.stderr))) return null;
|
|
19
|
+
throw new Error(`cannot resolve the main checkout of ${cwd}: ${String(err.stderr || err.message).trim()}`, { cause: err });
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const mains = new Map(); // two git spawns per lookup, and plan list/load loops ask once per plan
|
|
24
|
+
export const mainCheckout = (dir) => mains.get(dir) ?? mains.set(dir, resolveMain(dir)).get(dir);
|
|
25
|
+
|
|
26
|
+
function resolveMain(dir) {
|
|
27
|
+
const out = gitOrNull(["rev-parse", "--path-format=absolute", "--git-common-dir", "--is-bare-repository"], dir);
|
|
28
|
+
if (out === null) return dir;
|
|
29
|
+
const [common, bare] = out.split("\n");
|
|
30
|
+
if (bare === "true") throw new Error(`${dir} belongs to a bare repository: kj lanes need a main checkout`);
|
|
31
|
+
// The main checkout is the dir whose `.git` IS the common dir or a file pointing at it. Git
|
|
32
|
+
// records no path back to it, so the candidates are the ancestors of the toplevel (lanes live
|
|
33
|
+
// under it; --separate-git-dir, submodules) and the common dir's parent (a lane beside it).
|
|
34
|
+
const top = gitOrNull(["rev-parse", "--show-toplevel"], dir);
|
|
35
|
+
const candidates = [];
|
|
36
|
+
for (let up = top; path.dirname(up) !== up; up = path.dirname(up)) candidates.push(up);
|
|
37
|
+
const found = [...candidates, path.dirname(common)].find((c) => dotGitIs(path.join(c, ".git"), common));
|
|
38
|
+
if (!found) {
|
|
39
|
+
throw new Error(`cannot find the main checkout of ${dir}: its git dir is separate and the worktree sits outside the checkout`);
|
|
40
|
+
}
|
|
41
|
+
return found;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const GITDIR_PREFIX = "gitdir:";
|
|
45
|
+
const dotGitIs = (dotGit, common) => {
|
|
46
|
+
try {
|
|
47
|
+
if (fs.statSync(dotGit).isDirectory()) return fs.realpathSync(dotGit) === common;
|
|
48
|
+
const line = fs.readFileSync(dotGit, "utf8").split("\n").find((l) => l.startsWith(GITDIR_PREFIX));
|
|
49
|
+
return line !== undefined && fs.realpathSync(path.resolve(path.dirname(dotGit), line.slice(GITDIR_PREFIX.length).trim())) === common;
|
|
50
|
+
} catch {
|
|
51
|
+
return false; // no ".git" here: keep climbing
|
|
52
|
+
}
|
|
53
|
+
};
|
|
@@ -2,7 +2,9 @@ import path from "node:path";
|
|
|
2
2
|
import { existsSync, statSync } from "node:fs";
|
|
3
3
|
import { runCommand } from "./process.js";
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
// ADR 0032: the wiki indexes what travels with the project, so a whole team gets the same one:
|
|
6
|
+
// the docs and the plans shared with `kj plan share` (private plans stay out of it).
|
|
7
|
+
export const QMD_DEFAULT_PATHS = ["docs", ".karajan-shared/plans"];
|
|
6
8
|
|
|
7
9
|
export function projectSlug(projectDir) {
|
|
8
10
|
const base = path.basename(path.resolve(projectDir));
|
package/src/utils/welcome.js
CHANGED
|
@@ -10,11 +10,11 @@ const A = {
|
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
const QUICK_START = [
|
|
13
|
-
["kj run <task>", "Run the full coder+reviewer pipeline"],
|
|
14
13
|
["kj init", "Initialize config and setup"],
|
|
14
|
+
["kj hu add", "Put a piece of work on the board before it starts"],
|
|
15
|
+
["kj review --staged", "Have another AI review the diff you are about to commit"],
|
|
16
|
+
["kj board start", "Open the HU board and its governance view"],
|
|
15
17
|
["kj doctor", "Check environment and agent availability"],
|
|
16
|
-
["kj status", "Show pipeline dashboard"],
|
|
17
|
-
["kj report", "Show latest session report"],
|
|
18
18
|
];
|
|
19
19
|
|
|
20
20
|
/**
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: kj-audit
|
|
3
|
+
description: "Codebase Health Audit"
|
|
4
|
+
kind: command
|
|
5
|
+
---
|
|
1
6
|
# kj-audit — Codebase Health Audit
|
|
2
7
|
|
|
3
8
|
Analyze the current codebase for security, code quality, performance, architecture, and testing issues. This is a READ-ONLY analysis — do not modify any files.
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: kj-rag-query
|
|
3
|
+
description: "Query Project RAG index"
|
|
4
|
+
kind: command
|
|
5
|
+
---
|
|
1
6
|
# kj-rag-query — Query Project RAG index
|
|
2
7
|
|
|
3
8
|
Query the Project RAG (vector store + embedder) and return the top-K most relevant chunks of the indexed project: plans, onboarding briefs, and (optionally) source code.
|
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
// KJC-TSK-0501 step 8f/8 — Preflight gate + run launcher.
|
|
2
|
-
//
|
|
3
|
-
// Classic script (no exports). Loaded by index.html before app.js so the
|
|
4
|
-
// top-level `function`/`let` declarations are hoisted into the shared
|
|
5
|
-
// realm and the inline handlers in app.js (and elsewhere) resolve
|
|
6
|
-
// `runProject` / `confirmRunWithPreflight` via that hoisting.
|
|
7
|
-
//
|
|
8
|
-
// Globals consumed from earlier scripts / app.js:
|
|
9
|
-
// - esc() (utils/formatters.js)
|
|
10
|
-
// - ensureDialog() (app.js)
|
|
11
|
-
// - showError() (utils/modals.js)
|
|
12
|
-
// - renderBoard() (app.js)
|
|
13
|
-
// - openLogViewer() (utils/log-panel.js)
|
|
14
|
-
// - lastLaunchedPlanId (mutable in app.js — assignment crosses
|
|
15
|
-
// scripts transparently)
|
|
16
|
-
// - lastOpenedLog (mutable in app.js — same)
|
|
17
|
-
|
|
18
|
-
// ---- Preflight panel + safety modal ----
|
|
19
|
-
//
|
|
20
|
-
// Goal: when a non-technical user opens a project, they should see at
|
|
21
|
-
// a glance whether the environment is ready (git initialised, remote
|
|
22
|
-
// configured, agents installed, Node version, etc.). Each missing
|
|
23
|
-
// item is rendered with a plain-Spanish "consequence" so the user
|
|
24
|
-
// understands what's at stake.
|
|
25
|
-
//
|
|
26
|
-
// The panel doubles as the gate for ▶ Run plan / ▶ Run HU: if any
|
|
27
|
-
// blocker (status:fail with blocking:true) is present, we refuse to
|
|
28
|
-
// launch. If only warnings are present, we open a confirm modal
|
|
29
|
-
// listing them and require an explicit "Lanzar de todos modos".
|
|
30
|
-
|
|
31
|
-
let preflightCache = null; // memoise per-render so the modal can re-use what the panel already fetched
|
|
32
|
-
|
|
33
|
-
async function fetchPreflight(projectId) {
|
|
34
|
-
try {
|
|
35
|
-
const r = await fetch(`/api/projects/${encodeURIComponent(projectId)}/preflight`);
|
|
36
|
-
if (!r.ok) return null;
|
|
37
|
-
return await r.json();
|
|
38
|
-
} catch { return null; }
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function preflightStatusIcon(status) {
|
|
42
|
-
if (status === 'ok') return '✓';
|
|
43
|
-
if (status === 'warn') return '⚠';
|
|
44
|
-
if (status === 'fail') return '✗';
|
|
45
|
-
return 'ℹ';
|
|
46
|
-
}
|
|
47
|
-
function preflightStatusColor(status) {
|
|
48
|
-
if (status === 'ok') return 'var(--color-green)';
|
|
49
|
-
if (status === 'warn') return 'var(--color-yellow,#eab308)';
|
|
50
|
-
if (status === 'fail') return 'var(--color-red,#ef4444)';
|
|
51
|
-
return 'var(--text-muted)';
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Pre-run safety modal. Returns true if the user wants to proceed,
|
|
56
|
-
* false to cancel. Call BEFORE invoking the run endpoint.
|
|
57
|
-
*
|
|
58
|
-
* Behaviour:
|
|
59
|
-
* - All green → returns true immediately (no modal).
|
|
60
|
-
* - Blockers present → modal explains them in plain Spanish; only
|
|
61
|
-
* "Cancelar" button (no proceed-anyway) because blockers are
|
|
62
|
-
* known to break the run.
|
|
63
|
-
* - Only warnings → modal lists them with their consequences and
|
|
64
|
-
* offers "Cancelar" or "Lanzar de todos modos" (red button so
|
|
65
|
-
* the user notices they're accepting risk).
|
|
66
|
-
*/
|
|
67
|
-
async function confirmRunWithPreflight(projectId) {
|
|
68
|
-
const data = preflightCache || await fetchPreflight(projectId);
|
|
69
|
-
if (!data) return true; // can't fetch → don't block the user
|
|
70
|
-
const blockers = data.blockers || [];
|
|
71
|
-
const warnings = data.warnings || [];
|
|
72
|
-
if (blockers.length === 0 && warnings.length === 0) return true;
|
|
73
|
-
|
|
74
|
-
return await new Promise((resolve) => {
|
|
75
|
-
const dlg = document.getElementById('app-dialog') || ensureDialog();
|
|
76
|
-
const isBlocked = blockers.length > 0;
|
|
77
|
-
const headerColor = isBlocked ? 'var(--color-red,#ef4444)' : 'var(--color-yellow,#eab308)';
|
|
78
|
-
const allItems = [...blockers, ...warnings];
|
|
79
|
-
dlg.innerHTML = `
|
|
80
|
-
<div style="padding:14px 18px;border-bottom:1px solid var(--border);font-weight:700;display:flex;align-items:center;gap:10px;background:${headerColor};color:#000;">
|
|
81
|
-
<span style="font-size:1.2rem;">${isBlocked ? '✗' : '⚠'}</span>
|
|
82
|
-
<span>${isBlocked ? 'No se puede lanzar — falta algo crítico' : 'Atención antes de lanzar'}</span>
|
|
83
|
-
</div>
|
|
84
|
-
<div style="padding:14px 18px;max-height:60vh;overflow:auto;">
|
|
85
|
-
<p style="margin:0 0 10px;font-size:0.9rem;color:var(--text);">
|
|
86
|
-
${isBlocked
|
|
87
|
-
? 'Se detectaron problemas bloqueantes que impedirán que Karajan funcione correctamente:'
|
|
88
|
-
: 'Se detectaron avisos. Karajan puede ejecutarse, pero con limitaciones:'}
|
|
89
|
-
</p>
|
|
90
|
-
<ul style="list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:8px;">
|
|
91
|
-
${allItems.map((c) => `
|
|
92
|
-
<li style="padding:8px 10px;background:var(--bg-primary);border-left:3px solid ${preflightStatusColor(c.status)};border-radius:var(--radius-sm);">
|
|
93
|
-
<div style="font-weight:600;color:var(--text);font-size:0.85rem;">
|
|
94
|
-
${preflightStatusIcon(c.status)} ${esc(c.label)} — <span style="color:var(--text-muted);font-weight:400;">${esc(c.detail || '')}</span>
|
|
95
|
-
</div>
|
|
96
|
-
${c.consequence ? `<div style="font-size:0.8rem;color:var(--text);margin-top:4px;">${esc(c.consequence)}</div>` : ''}
|
|
97
|
-
</li>
|
|
98
|
-
`).join('')}
|
|
99
|
-
</ul>
|
|
100
|
-
</div>
|
|
101
|
-
<div style="padding:12px 18px;border-top:1px solid var(--border);display:flex;gap:8px;justify-content:flex-end;">
|
|
102
|
-
<button id="preflight-cancel" style="padding:8px 16px;background:var(--bg-primary);border:1px solid var(--border);color:var(--text);border-radius:var(--radius-sm);cursor:pointer;">Cancelar</button>
|
|
103
|
-
${isBlocked ? '' : `<button id="preflight-proceed" style="padding:8px 16px;background:var(--color-red,#ef4444);border:none;color:#fff;border-radius:var(--radius-sm);cursor:pointer;font-weight:600;">Lanzar de todos modos</button>`}
|
|
104
|
-
</div>
|
|
105
|
-
`;
|
|
106
|
-
if (typeof dlg.showModal === 'function' && !dlg.open) dlg.showModal();
|
|
107
|
-
const cancel = dlg.querySelector('#preflight-cancel');
|
|
108
|
-
const proceed = dlg.querySelector('#preflight-proceed');
|
|
109
|
-
const close = (val) => { try { dlg.close(); } catch { /* ignore */ } resolve(val); };
|
|
110
|
-
cancel?.addEventListener('click', () => close(false), { once: true });
|
|
111
|
-
proceed?.addEventListener('click', () => close(true), { once: true });
|
|
112
|
-
dlg.addEventListener('close', () => resolve(false), { once: true });
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
async function runProject(projectId) {
|
|
117
|
-
try {
|
|
118
|
-
const res = await fetch(`/api/projects/${encodeURIComponent(projectId)}/run`, {
|
|
119
|
-
method: 'POST',
|
|
120
|
-
headers: { 'Content-Type': 'application/json' },
|
|
121
|
-
body: JSON.stringify({}),
|
|
122
|
-
});
|
|
123
|
-
if (!res.ok) {
|
|
124
|
-
if (res.status === 404) {
|
|
125
|
-
await showError(
|
|
126
|
-
'The board server does not recognise the "run" endpoint.\n\n'
|
|
127
|
-
+ 'Most likely cause: the board process is running a pre-v2.7.5 build. '
|
|
128
|
-
+ 'Restart it with:\n\n'
|
|
129
|
-
+ ' kj board stop && kj board start',
|
|
130
|
-
{ title: 'Board out of date' }
|
|
131
|
-
);
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
const msg = (await res.json().catch(() => ({}))).error || `HTTP ${res.status}`;
|
|
135
|
-
await showError(msg, { title: 'Could not launch run' });
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
const body = await res.json();
|
|
139
|
-
// Best-effort: a chokidar tick may still be in flight, so fetch
|
|
140
|
-
// once explicitly to surface the "running" state without waiting
|
|
141
|
-
// for the watcher debounce.
|
|
142
|
-
await fetch('/api/sync', { method: 'POST' }).catch(() => {});
|
|
143
|
-
await renderBoard();
|
|
144
|
-
|
|
145
|
-
// Remember the first successful planId so the section header can
|
|
146
|
-
// offer a "View log" button without the user having to re-launch.
|
|
147
|
-
const firstOk = (body.results || []).find((r) => r.ok);
|
|
148
|
-
if (firstOk && firstOk.planId) {
|
|
149
|
-
lastLaunchedPlanId = firstOk.planId;
|
|
150
|
-
lastOpenedLog = {
|
|
151
|
-
id: firstOk.planId,
|
|
152
|
-
label: 'Run log',
|
|
153
|
-
tailUrl: (offset) => `/api/plans/${encodeURIComponent(firstOk.planId)}/log?offset=${offset}`,
|
|
154
|
-
};
|
|
155
|
-
// Open the log viewer straight away — the user's mental model is
|
|
156
|
-
// "I clicked Run, I want to see what's happening", not "I clicked
|
|
157
|
-
// Run, now where do I look".
|
|
158
|
-
openLogViewer(firstOk.planId);
|
|
159
|
-
} else {
|
|
160
|
-
await showError(
|
|
161
|
-
`Pipeline launched for ${body.launched}/${body.total} plan(s) but `
|
|
162
|
-
+ 'no planId came back, so there\'s no log to show.',
|
|
163
|
-
{ title: 'Run started' }
|
|
164
|
-
);
|
|
165
|
-
}
|
|
166
|
-
} catch (err) {
|
|
167
|
-
await showError(err.message, { title: 'Could not launch run' });
|
|
168
|
-
}
|
|
169
|
-
}
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Run tracker — registro híbrido (memoria + disco) de procesos kj run.
|
|
3
|
-
*
|
|
4
|
-
* KJC-TSK-0396: el botón ⏹ Stop del board combina dos fuentes:
|
|
5
|
-
*
|
|
6
|
-
* 1. **Memoria** (`runs` Map) — runs lanzados desde el board vía
|
|
7
|
-
* `runPlan` en plan-mutations.js. Bajo coste, sin I/O.
|
|
8
|
-
*
|
|
9
|
-
* 2. **Disco** (`~/.karajan/runs/<runId>.json` vía run-registry.js) —
|
|
10
|
-
* runs lanzados desde la terminal externa (cualquier `kj run`). El
|
|
11
|
-
* CLI escribe el registro al arranque y lo borra al final. Esto da
|
|
12
|
-
* bidireccionalidad terminal ↔ board.
|
|
13
|
-
*
|
|
14
|
-
* `getActiveRuns(planId)` une las dos fuentes y dedupe por PID. Los
|
|
15
|
-
* registros con PID muerto se filtran automáticamente y los del disco
|
|
16
|
-
* se borran como cleanup (responsabilidad de run-registry).
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
import { listActiveRuns as fsList } from "karajan-core/run-registry";
|
|
20
|
-
|
|
21
|
-
const runs = new Map();
|
|
22
|
-
let reaperTimer = null;
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Registra un run lanzado desde el board (memoria).
|
|
26
|
-
*
|
|
27
|
-
* @param {string} planId
|
|
28
|
-
* @param {{ pid: number, huIds?: string[]|null }} info
|
|
29
|
-
*/
|
|
30
|
-
export function trackRun(planId, info) {
|
|
31
|
-
if (!planId || !info?.pid) return;
|
|
32
|
-
const set = runs.get(planId) || new Set();
|
|
33
|
-
set.add({ pid: info.pid, huIds: info.huIds || null, startedAt: Date.now() });
|
|
34
|
-
runs.set(planId, set);
|
|
35
|
-
ensureReaper();
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Devuelve los runs activos para un planId. Une memoria + FS y dedupe
|
|
40
|
-
* por PID. Filtra PIDs muertos.
|
|
41
|
-
*/
|
|
42
|
-
export function getActiveRuns(planId) {
|
|
43
|
-
const seen = new Set();
|
|
44
|
-
const out = [];
|
|
45
|
-
// Memoria
|
|
46
|
-
const set = runs.get(planId);
|
|
47
|
-
if (set) {
|
|
48
|
-
for (const r of set) {
|
|
49
|
-
if (isAlive(r.pid)) {
|
|
50
|
-
seen.add(r.pid);
|
|
51
|
-
out.push({ pid: r.pid, huIds: r.huIds, startedAt: r.startedAt, source: "board" });
|
|
52
|
-
} else set.delete(r);
|
|
53
|
-
}
|
|
54
|
-
if (set.size === 0) runs.delete(planId);
|
|
55
|
-
}
|
|
56
|
-
// Disco
|
|
57
|
-
for (const entry of fsList({ planId })) {
|
|
58
|
-
if (seen.has(entry.pid)) continue;
|
|
59
|
-
seen.add(entry.pid);
|
|
60
|
-
out.push({
|
|
61
|
-
pid: entry.pid,
|
|
62
|
-
huIds: entry.huIds,
|
|
63
|
-
startedAt: entry.startedAt,
|
|
64
|
-
source: entry.source || "cli",
|
|
65
|
-
projectDir: entry.projectDir,
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
return out;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Igual que getActiveRuns pero para todos los planes (memoria + FS).
|
|
73
|
-
*/
|
|
74
|
-
export function getAllActiveRuns() {
|
|
75
|
-
const out = {};
|
|
76
|
-
// Memoria
|
|
77
|
-
for (const planId of runs.keys()) {
|
|
78
|
-
const alive = getActiveRuns(planId);
|
|
79
|
-
if (alive.length > 0) out[planId] = alive;
|
|
80
|
-
}
|
|
81
|
-
// FS — añadir planes que solo viven en disco (no se vieron arriba).
|
|
82
|
-
for (const entry of fsList()) {
|
|
83
|
-
if (!entry.planId) continue;
|
|
84
|
-
if (out[entry.planId]) continue;
|
|
85
|
-
out[entry.planId] = getActiveRuns(entry.planId);
|
|
86
|
-
}
|
|
87
|
-
return out;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Quita el registro de un PID de memoria. Los registros FS los limpia
|
|
92
|
-
* el propio CLI (vía registry.unregisterRun en su finally).
|
|
93
|
-
*/
|
|
94
|
-
export function untrack(planId, pid) {
|
|
95
|
-
const set = runs.get(planId);
|
|
96
|
-
if (!set) return;
|
|
97
|
-
for (const r of set) {
|
|
98
|
-
if (r.pid === pid) set.delete(r);
|
|
99
|
-
}
|
|
100
|
-
if (set.size === 0) runs.delete(planId);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function isAlive(pid) {
|
|
104
|
-
if (!pid) return false;
|
|
105
|
-
try { process.kill(pid, 0); return true; }
|
|
106
|
-
catch (err) { return err.code === "EPERM"; }
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/** Test-only reset. */
|
|
110
|
-
export function _resetForTests() {
|
|
111
|
-
runs.clear();
|
|
112
|
-
if (reaperTimer) { clearInterval(reaperTimer); reaperTimer = null; }
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
function ensureReaper() {
|
|
116
|
-
if (reaperTimer || process.env.VITEST) return;
|
|
117
|
-
reaperTimer = setInterval(() => {
|
|
118
|
-
for (const planId of [...runs.keys()]) getActiveRuns(planId);
|
|
119
|
-
}, 30_000);
|
|
120
|
-
reaperTimer.unref?.();
|
|
121
|
-
}
|
package/src/activity-log.js
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs/promises";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { getSessionRoot } from "./utils/paths.js";
|
|
4
|
-
import { ensureDir } from "./utils/fs.js";
|
|
5
|
-
|
|
6
|
-
function formatLine(entry) {
|
|
7
|
-
const ts = entry.timestamp || new Date().toISOString();
|
|
8
|
-
const lvl = (entry.level || "info").toUpperCase().padEnd(5);
|
|
9
|
-
const ctx = entry.context
|
|
10
|
-
? Object.entries(entry.context)
|
|
11
|
-
.filter(([, v]) => v !== undefined)
|
|
12
|
-
.map(([k, v]) => `${k}=${v}`)
|
|
13
|
-
.join(" ")
|
|
14
|
-
: "";
|
|
15
|
-
const ctxStr = ctx ? ` ${ctx}` : "";
|
|
16
|
-
return `${ts} [${lvl}]${ctxStr} ${entry.message || ""}`;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function createActivityLog(sessionId) {
|
|
20
|
-
const logPath = path.join(getSessionRoot(), sessionId, "activity.log");
|
|
21
|
-
let buffer = [];
|
|
22
|
-
let flushing = false;
|
|
23
|
-
|
|
24
|
-
async function flush() {
|
|
25
|
-
if (flushing || buffer.length === 0) return;
|
|
26
|
-
flushing = true;
|
|
27
|
-
const lines = buffer.splice(0);
|
|
28
|
-
try {
|
|
29
|
-
await ensureDir(path.dirname(logPath));
|
|
30
|
-
await fs.appendFile(logPath, lines.join("\n") + "\n", "utf8");
|
|
31
|
-
} catch {
|
|
32
|
-
// best-effort: I/O errors do not crash the flow
|
|
33
|
-
}
|
|
34
|
-
flushing = false;
|
|
35
|
-
if (buffer.length > 0) flush();
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return {
|
|
39
|
-
write(logEntry) {
|
|
40
|
-
buffer.push(formatLine(logEntry));
|
|
41
|
-
flush();
|
|
42
|
-
},
|
|
43
|
-
writeEvent(progressEvent) {
|
|
44
|
-
const entry = {
|
|
45
|
-
timestamp: progressEvent.timestamp,
|
|
46
|
-
level: progressEvent.status === "fail" ? "error" : "info",
|
|
47
|
-
context: {
|
|
48
|
-
iteration: progressEvent.iteration,
|
|
49
|
-
stage: progressEvent.stage
|
|
50
|
-
},
|
|
51
|
-
message: progressEvent.message || progressEvent.type
|
|
52
|
-
};
|
|
53
|
-
this.write(entry);
|
|
54
|
-
},
|
|
55
|
-
get path() {
|
|
56
|
-
return logPath;
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
}
|
package/src/agents/host-agent.js
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Host Agent — delegates task execution to the MCP host AI via elicitation.
|
|
3
|
-
*
|
|
4
|
-
* Instead of spawning a subprocess, returns the prompt to the host AI
|
|
5
|
-
* (Claude, Codex, etc.) for direct execution. The host has full access
|
|
6
|
-
* to the codebase and tools — no subprocess overhead.
|
|
7
|
-
*
|
|
8
|
-
* Used when: the MCP host IS the same agent configured for a role.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import { BaseAgent } from "./base-agent.js";
|
|
12
|
-
|
|
13
|
-
export class HostAgent extends BaseAgent {
|
|
14
|
-
constructor(config, logger, { askHost }) {
|
|
15
|
-
super("host", config, logger);
|
|
16
|
-
this._askHost = askHost;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
async runTask(task) {
|
|
20
|
-
const { prompt, onOutput } = task;
|
|
21
|
-
|
|
22
|
-
if (!this._askHost) {
|
|
23
|
-
return { ok: false, output: "", error: "Host agent has no askHost callback" };
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if (onOutput) onOutput({ stream: "info", line: "[host-agent] Delegating to host AI..." });
|
|
27
|
-
|
|
28
|
-
const answer = await this._askHost(prompt);
|
|
29
|
-
|
|
30
|
-
if (!answer) {
|
|
31
|
-
return { ok: false, output: "", error: "Host AI declined or returned no response" };
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (onOutput) onOutput({ stream: "info", line: "[host-agent] Host AI completed task" });
|
|
35
|
-
|
|
36
|
-
return { ok: true, output: answer, exitCode: 0 };
|
|
37
|
-
}
|
|
38
|
-
}
|