forge-workflow 0.0.9 → 0.1.0-beta.2
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/.claude/rules/{greptile-review-process.md → review-process.md} +56 -41
- package/.claude/scripts/{greptile-resolve.sh → review-resolve.sh} +13 -3
- package/.cursor/rules/permissions-guidance.mdc +2 -2
- package/.forge/hooks/check-tdd.js +3 -0
- package/.forge/hooks/forge-native-hook.js +245 -0
- package/.forge/protected-paths.yaml +157 -0
- package/AGENTS.md +151 -61
- package/CHANGELOG.md +681 -0
- package/CLAUDE.md +9 -106
- package/QUICKSTART.md +171 -0
- package/README.md +271 -363
- package/bin/forge-cmd.js +120 -9
- package/bin/forge-preflight.js +26 -5
- package/bin/forge.js +466 -489
- package/docs/INDEX.md +93 -0
- package/docs/PROJECT_DESIGN.md +685 -0
- package/docs/architecture/index.md +66 -0
- package/docs/architecture/notes/README.md +35 -0
- package/docs/architecture/subsystems/README.md +46 -0
- package/docs/{TOOLCHAIN.md → forge/TOOLCHAIN.md} +56 -47
- package/docs/forge/VALIDATION.md +82 -0
- package/docs/{AGENT_INSTALL_PROMPT.md → guides/AGENT_INSTALL_PROMPT.md} +3 -3
- package/docs/guides/BEADS_GITHUB_SYNC.md +32 -0
- package/docs/{ENHANCED_ONBOARDING.md → guides/ENHANCED_ONBOARDING.md} +16 -12
- package/docs/guides/GREPTILE_SETUP.md +46 -0
- package/docs/guides/MANUAL_REVIEW_GUIDE.md +58 -0
- package/docs/guides/MIGRATION.md +56 -0
- package/docs/guides/SETUP.md +118 -0
- package/docs/guides/SUPPORT.md +185 -0
- package/docs/guides/WORKFLOW_TEMPLATES.md +74 -0
- package/docs/guides/memory-backends.md +183 -0
- package/docs/reference/ADAPTERS.md +128 -0
- package/docs/reference/AGENT_SKILL_PARITY.md +175 -0
- package/docs/reference/COMMANDS.md +205 -0
- package/docs/reference/DECISION_DRIFT_GUARDS.md +97 -0
- package/docs/{EXAMPLES.md → reference/EXAMPLES.md} +7 -5
- package/docs/reference/FORGE_KERNEL_STORAGE_MODEL.md +135 -0
- package/docs/reference/HERMES_INTEGRATION.md +118 -0
- package/docs/reference/INSIGHTS_RECAP.md +63 -0
- package/docs/reference/INSTALL.md +164 -0
- package/docs/reference/KERNEL_TAXONOMY_VALIDATION.md +161 -0
- package/docs/reference/PROTECTED_PATH_MANIFEST.md +25 -0
- package/docs/reference/RELEASE.md +68 -0
- package/docs/reference/RESEARCH_TEMPLATE.md +292 -0
- package/docs/{ROADMAP.md → reference/ROADMAP.md} +12 -9
- package/docs/reference/SKILLS.md +35 -0
- package/docs/reference/STATUS_BOARD.md +80 -0
- package/docs/reference/TEMPLATES.md +106 -0
- package/docs/reference/TOOLCHAIN.md +658 -0
- package/docs/reference/VALIDATION.md +82 -0
- package/docs/reference/agent-permissions.md +169 -0
- package/docs/reference/beads-to-kernel-migration-ux.md +61 -0
- package/docs/reference/control-plane-guarantees.md +125 -0
- package/docs/reference/dependency-chain.md +331 -0
- package/docs/reference/forge-kernel-issue-command-contract.md +161 -0
- package/docs/reference/forge-kernel-schema.md +72 -0
- package/docs/reference/kernel-conflict-evaluators.md +27 -0
- package/docs/reference/patch-md-format.md +77 -0
- package/docs/reference/protected-state-surfaces.md +59 -0
- package/docs/reference/shepherd.md +115 -0
- package/docs/reference/superpowers-analysis.md +320 -0
- package/docs/reference/superpowers-integration-options.md +404 -0
- package/docs/reference/test-environment.md +519 -0
- package/docs/reference/upgrade-safety.md +59 -0
- package/lefthook.yml +18 -0
- package/lib/adapter-cli.js +307 -0
- package/lib/adapters/beads-issue-adapter.js +127 -0
- package/lib/adapters/beads-kernel-compat.js +1042 -0
- package/lib/adapters/greptile-review-adapter.js +141 -0
- package/lib/adapters/kernel-issue-adapter.js +101 -0
- package/lib/adapters/pr-state-adapter.js +484 -0
- package/lib/adoption-profiles.js +126 -0
- package/lib/agents/README.md +2 -6
- package/lib/agents/claude.plugin.json +3 -8
- package/lib/agents/codex.plugin.json +9 -1
- package/lib/agents/cursor.plugin.json +2 -6
- package/lib/agents/hermes.plugin.json +22 -0
- package/lib/agents-config.js +39 -1236
- package/lib/audit-evidence.js +282 -0
- package/lib/beads-setup.js +225 -28
- package/lib/beads-sync-scaffold.js +36 -107
- package/lib/codex-skills.js +51 -1
- package/lib/commands/_issue.js +744 -70
- package/lib/commands/_manifest.js +91 -0
- package/lib/commands/_registry.js +85 -34
- package/lib/commands/_resolve-command-opts.js +261 -0
- package/lib/commands/_serve-security.js +270 -0
- package/lib/commands/adapter.js +12 -0
- package/lib/commands/add.js +118 -0
- package/lib/commands/audit.js +70 -0
- package/lib/commands/blocked.js +5 -0
- package/lib/commands/board.js +64 -0
- package/lib/commands/claim.js +21 -2
- package/lib/commands/claims.js +7 -0
- package/lib/commands/clean.js +485 -75
- package/lib/commands/close.js +2 -2
- package/lib/commands/comment.js +5 -0
- package/lib/commands/control.js +148 -0
- package/lib/commands/create.js +2 -2
- package/lib/commands/dev.js +185 -7
- package/lib/commands/doc-gate.js +336 -0
- package/lib/commands/doctor.js +156 -0
- package/lib/commands/explain.js +15 -0
- package/lib/commands/export.js +237 -0
- package/lib/commands/gate.js +192 -0
- package/lib/commands/hooks.js +242 -0
- package/lib/commands/inbox.js +118 -0
- package/lib/commands/init.js +598 -0
- package/lib/commands/insights.js +79 -0
- package/lib/commands/issue.js +12 -1
- package/lib/commands/issues.js +66 -0
- package/lib/commands/lint.js +5 -0
- package/lib/commands/list.js +2 -2
- package/lib/commands/merge.js +312 -0
- package/lib/commands/migrate.js +523 -0
- package/lib/commands/new.js +12 -0
- package/lib/commands/options.js +241 -0
- package/lib/commands/orient.js +13 -0
- package/lib/commands/orphans.js +5 -0
- package/lib/commands/patch.js +67 -0
- package/lib/commands/plan.js +436 -24
- package/lib/commands/preflight.js +211 -0
- package/lib/commands/prime.js +13 -0
- package/lib/commands/push.js +69 -2
- package/lib/commands/ready.js +2 -2
- package/lib/commands/recall.js +116 -0
- package/lib/commands/recap.js +61 -0
- package/lib/commands/recommend.js +22 -2
- package/lib/commands/release.js +91 -0
- package/lib/commands/remember.js +74 -0
- package/lib/commands/role.js +99 -0
- package/lib/commands/serve.js +581 -0
- package/lib/commands/setup.js +851 -979
- package/lib/commands/shepherd.js +436 -0
- package/lib/commands/ship.js +23 -1
- package/lib/commands/show.js +2 -2
- package/lib/commands/stage.js +192 -0
- package/lib/commands/stale.js +5 -0
- package/lib/commands/status.js +329 -11
- package/lib/commands/sync.js +34 -46
- package/lib/commands/team.js +15 -2
- package/lib/commands/test.js +58 -7
- package/lib/commands/update.js +2 -2
- package/lib/commands/upgrade.js +47 -0
- package/lib/commands/validate.js +56 -25
- package/lib/commands/worktree.js +308 -128
- package/lib/config-writer.js +202 -0
- package/lib/control-plane.js +236 -0
- package/lib/core/runtime-graph.js +946 -0
- package/lib/dep-guard/keyword-ripple.js +184 -0
- package/lib/deprecated-sync-cleanup.js +362 -0
- package/lib/detect-agent.js +2 -28
- package/lib/detect-worktree.js +42 -17
- package/lib/doc-gate/declaration.js +177 -0
- package/lib/doc-gate/detect.js +289 -0
- package/lib/doc-gate/gate.js +375 -0
- package/lib/doc-gate/okf-config.js +128 -0
- package/lib/doc-gate/okf.js +429 -0
- package/lib/docs-command.js +1161 -6
- package/lib/forge-issues.js +697 -0
- package/lib/forge-lock.js +262 -0
- package/lib/gate-events.js +193 -0
- package/lib/global-flags.js +74 -0
- package/lib/greptile-match.js +7 -63
- package/lib/harness-capability-matrix.js +380 -0
- package/lib/hook-global-installer.js +347 -0
- package/lib/hook-renderer.js +451 -0
- package/lib/inbox.js +391 -0
- package/lib/insights.js +397 -0
- package/lib/issue-adapter.js +156 -0
- package/lib/issue-backend.js +145 -0
- package/lib/issue-render.js +220 -0
- package/lib/issue-sync/authority.js +100 -0
- package/lib/issue-sync/github-pull.js +184 -0
- package/lib/issue-sync/import-primitives.js +98 -0
- package/lib/issue-sync/legacy-link-bridge.js +436 -0
- package/lib/issue-sync/link-store.js +292 -0
- package/lib/issue-sync/project-github.js +123 -0
- package/lib/issue-sync/reconcile.js +195 -0
- package/lib/issue-sync/schema.js +126 -0
- package/lib/kernel/backing-issue.js +305 -0
- package/lib/kernel/broker.js +1218 -0
- package/lib/kernel/cli-broker-factory.js +130 -0
- package/lib/kernel/conflict-signal.js +82 -0
- package/lib/kernel/evaluators.js +195 -0
- package/lib/kernel/fs-class.js +495 -0
- package/lib/kernel/issue-command-contract.js +559 -0
- package/lib/kernel/issue-id-resolver.js +186 -0
- package/lib/kernel/lease-enforcer.js +158 -0
- package/lib/kernel/migrations.js +333 -0
- package/lib/kernel/planning-buckets-schema.js +109 -0
- package/lib/kernel/projection-jsonl-writer.js +450 -0
- package/lib/kernel/readiness-model.js +329 -0
- package/lib/kernel/schema.js +356 -0
- package/lib/kernel/sqlite-driver.js +2504 -0
- package/lib/kernel/taxonomy-validator.js +394 -0
- package/lib/lefthook-check.js +8 -4
- package/lib/lefthook-wiring.js +413 -0
- package/lib/mcp-config-renderer.js +288 -0
- package/lib/memory/graphiti-mcp.js +106 -0
- package/lib/memory/router.js +387 -0
- package/lib/memory/typed-api.js +102 -0
- package/lib/memory-digest.js +195 -0
- package/lib/merge-rules.js +395 -0
- package/lib/migrate-dry-run.js +466 -0
- package/lib/orientation.js +863 -0
- package/lib/package-manager-remediation.js +103 -0
- package/lib/package-root.js +381 -0
- package/lib/patch-intent.js +890 -0
- package/lib/plugin-catalog.js +3 -4
- package/lib/plugin-manager.js +0 -5
- package/lib/pr-bundle.js +186 -0
- package/lib/pr-monitor/differ.js +195 -0
- package/lib/pr-monitor/events.js +0 -0
- package/lib/pr-monitor/gather.js +124 -0
- package/lib/pr-monitor/journal.js +299 -0
- package/lib/pr-monitor/monitor.js +146 -0
- package/lib/pr-monitor/render-sticky.js +157 -0
- package/lib/pr-monitor/watch-lifecycle.js +95 -0
- package/lib/pr-monitor/watch.js +247 -0
- package/lib/pr-pull.js +1273 -0
- package/lib/pr-shepherd.js +494 -0
- package/lib/pr-state-validator.js +59 -0
- package/lib/preflight/gates.js +237 -0
- package/lib/preflight/runner.js +116 -0
- package/lib/project-discovery.js +0 -53
- package/lib/project-memory.js +166 -0
- package/lib/protected-path-manifest.js +281 -0
- package/lib/protected-state-surfaces.js +387 -0
- package/lib/release-readiness.js +2089 -0
- package/lib/reset.js +59 -45
- package/lib/review-adapter.js +68 -0
- package/lib/rules-sync.js +260 -0
- package/lib/runtime-health.js +332 -23
- package/lib/safety-config-renderer.js +268 -0
- package/lib/setup-action-log.js +1 -7
- package/lib/setup.js +27 -65
- package/lib/shell-utils.js +76 -6
- package/lib/skills-sync.js +330 -0
- package/lib/smart-status/conflicts.js +205 -0
- package/lib/smart-status/scoring.js +191 -0
- package/lib/status/beads-snapshot.js +145 -0
- package/lib/status/presenter.js +216 -0
- package/lib/status/snapshot.js +186 -0
- package/lib/sync-backend.js +202 -0
- package/lib/untrusted-content.js +52 -0
- package/lib/upgrade-safety.js +199 -0
- package/lib/workflow/enforce-stage.js +298 -47
- package/lib/workflow/stage-transition.js +115 -0
- package/lib/workflow/stages.js +30 -6
- package/lib/workflow/state-manager.js +159 -14
- package/lib/workflow/state.js +23 -1
- package/lib/workflow-profiles.js +17 -5
- package/package.json +46 -36
- package/rules/documentation.md +19 -0
- package/rules/kernel-tracking.md +26 -0
- package/rules/security.md +22 -0
- package/rules/tdd.md +20 -0
- package/rules/workflow.md +27 -0
- package/scripts/auto-backing-issue.js +47 -0
- package/scripts/beads-context.sh +165 -22
- package/scripts/beads-migrate-to-dolt.sh +7 -0
- package/scripts/beads-upgrade-smoke.sh +284 -0
- package/scripts/behavioral-judge.sh +115 -11
- package/scripts/benchmark.js +349 -63
- package/scripts/bootstrap-windows-tools.sh +78 -0
- package/scripts/branch-protection.js +2 -3
- package/scripts/check-agents.js +34 -137
- package/scripts/commitlint.js +3 -1
- package/scripts/conflict-detect.sh +3 -0
- package/scripts/dep-guard-analyze.js +52 -17
- package/scripts/dep-guard-keyword-ripple.js +29 -0
- package/scripts/dep-guard-render-review.js +86 -0
- package/scripts/dep-guard.sh +64 -232
- package/scripts/file-index.sh +3 -0
- package/scripts/forge-team/lib/claim.sh +34 -18
- package/scripts/forge-team/lib/dashboard.sh +61 -86
- package/scripts/forge-team/lib/epic.sh +99 -263
- package/scripts/forge-team/lib/hooks.sh +26 -28
- package/scripts/forge-team/lib/identity.sh +4 -4
- package/scripts/forge-team/lib/sync-github.sh +144 -47
- package/scripts/forge-team/lib/verify.sh +93 -83
- package/scripts/forge-team/lib/workload.sh +41 -65
- package/scripts/forge-team/tests/claim.test.sh +25 -19
- package/scripts/forge-team/tests/dashboard.test.sh +31 -46
- package/scripts/forge-team/tests/epic.test.sh +52 -71
- package/scripts/forge-team/tests/hooks.test.sh +38 -50
- package/scripts/forge-team/tests/identity.test.sh +3 -3
- package/scripts/forge-team/tests/integration.test.sh +44 -66
- package/scripts/forge-team/tests/sync-github.test.sh +183 -79
- package/scripts/forge-team/tests/verify.test.sh +37 -46
- package/scripts/forge-team/tests/workflow-integration.test.sh +4 -4
- package/scripts/forge-team/tests/workload.test.sh +32 -66
- package/scripts/gen-command-manifest.js +153 -0
- package/scripts/gen-embedded-assets.mjs +129 -0
- package/scripts/install.ps1 +139 -0
- package/scripts/install.sh +268 -0
- package/scripts/lib/beads-migrate-to-dolt.mjs +503 -0
- package/scripts/lib/release-asset.mjs +84 -0
- package/scripts/parity-check.mjs +145 -0
- package/scripts/parity-check.test.mjs +58 -0
- package/scripts/pin-agentic-workflow-images.js +112 -0
- package/scripts/pr-coordinator.sh +3 -0
- package/scripts/preflight-sonar.eslint.config.mjs +44 -0
- package/scripts/preflight.sh +108 -0
- package/scripts/protected-state-check.js +104 -0
- package/scripts/smart-status-score.js +31 -0
- package/scripts/smart-status-sessions.js +51 -0
- package/scripts/smart-status.sh +117 -369
- package/scripts/spikes/config-race-bench.js +111 -0
- package/scripts/spikes/harness-capability-matrix.js +13 -0
- package/scripts/spikes/patch-anchor-stability-bench.js +125 -0
- package/scripts/spikes/protected-path-manifest.js +20 -0
- package/scripts/spikes/skill-auto-invoke-parity.js +292 -0
- package/scripts/sync-agent-skills.js +62 -0
- package/scripts/sync-agentic-workflow.js +48 -0
- package/scripts/sync-utils.sh +3 -0
- package/scripts/test-ci-shard.js +251 -0
- package/scripts/test-dashboard.js +188 -52
- package/scripts/test-full-suite.js +186 -0
- package/scripts/test-profile.js +278 -0
- package/scripts/test.js +302 -28
- package/scripts/validate.js +143 -0
- package/scripts/validate.sh +18 -1
- package/skills/claim-safety/SKILL.md +102 -0
- package/skills/claim-safety/evals/evals.json +46 -0
- package/{.github/prompts/dev.prompt.md → skills/dev/SKILL.md} +46 -52
- package/skills/dev/evals/evals.json +50 -0
- package/skills/hermes-forge/SKILL.md +185 -0
- package/skills/hermes-forge/evals/evals.json +46 -0
- package/skills/issue-basics/SKILL.md +111 -0
- package/skills/issue-basics/evals/evals.json +46 -0
- package/skills/kernel/SKILL.md +166 -0
- package/skills/kernel/evals/evals.json +50 -0
- package/skills/memory/SKILL.md +102 -0
- package/skills/parallel-deep-research/SKILL.md +14 -11
- package/skills/parallel-deep-research/evals/evals.json +11 -27
- package/{.github/prompts/plan.prompt.md → skills/plan/SKILL.md} +134 -159
- package/skills/plan/evals/evals.json +42 -0
- package/skills/research/SKILL.md +195 -0
- package/skills/research/evals/evals.json +42 -0
- package/{.github/prompts/review.prompt.md → skills/review/SKILL.md} +98 -62
- package/skills/review/evals/evals.json +42 -0
- package/skills/rollback/SKILL.md +110 -0
- package/skills/rollback/evals/evals.json +46 -0
- package/skills/rollback/references/methods.md +204 -0
- package/{.cursor/commands/rollback.md → skills/rollback/references/workflow-integration.md} +10 -284
- package/skills/shepherd/SKILL.md +66 -0
- package/skills/shepherd/evals/evals.json +42 -0
- package/skills/ship/SKILL.md +251 -0
- package/skills/ship/evals/evals.json +42 -0
- package/skills/smith/SKILL.md +142 -0
- package/skills/smith/evals/evals.json +46 -0
- package/skills/smith/references/autonomy-and-gates.md +94 -0
- package/{.github/prompts/sonarcloud.prompt.md → skills/sonarcloud/SKILL.md} +14 -3
- package/skills/sonarcloud/evals/evals.json +46 -0
- package/skills/sonarcloud-analysis/SKILL.md +18 -13
- package/skills/sonarcloud-analysis/evals/evals.json +11 -15
- package/skills/status/SKILL.md +102 -0
- package/skills/status/evals/evals.json +50 -0
- package/skills/triage-ready/SKILL.md +121 -0
- package/skills/triage-ready/evals/evals.json +42 -0
- package/{.github/prompts/validate.prompt.md → skills/validate/SKILL.md} +52 -29
- package/skills/validate/evals/evals.json +42 -0
- package/skills/verify/SKILL.md +299 -0
- package/skills/verify/evals/evals.json +50 -0
- package/.claude/commands/dev.md +0 -345
- package/.claude/commands/plan.md +0 -566
- package/.claude/commands/premerge.md +0 -186
- package/.claude/commands/research.md +0 -42
- package/.claude/commands/review.md +0 -451
- package/.claude/commands/rollback.md +0 -721
- package/.claude/commands/ship.md +0 -213
- package/.claude/commands/sonarcloud.md +0 -152
- package/.claude/commands/status.md +0 -90
- package/.claude/commands/validate.md +0 -288
- package/.claude/commands/verify.md +0 -269
- package/.claude/rules/workflow.md +0 -121
- package/.cline/workflows/dev.md +0 -342
- package/.cline/workflows/plan.md +0 -563
- package/.cline/workflows/premerge.md +0 -183
- package/.cline/workflows/research.md +0 -39
- package/.cline/workflows/review.md +0 -448
- package/.cline/workflows/rollback.md +0 -718
- package/.cline/workflows/ship.md +0 -210
- package/.cline/workflows/sonarcloud.md +0 -146
- package/.cline/workflows/status.md +0 -87
- package/.cline/workflows/validate.md +0 -285
- package/.cline/workflows/verify.md +0 -266
- package/.codex/config.toml +0 -11
- package/.codex/skills/dev/SKILL.md +0 -345
- package/.codex/skills/plan/SKILL.md +0 -566
- package/.codex/skills/premerge/SKILL.md +0 -186
- package/.codex/skills/research/SKILL.md +0 -42
- package/.codex/skills/review/SKILL.md +0 -451
- package/.codex/skills/rollback/SKILL.md +0 -721
- package/.codex/skills/ship/SKILL.md +0 -213
- package/.codex/skills/sonarcloud/SKILL.md +0 -149
- package/.codex/skills/status/SKILL.md +0 -90
- package/.codex/skills/validate/SKILL.md +0 -288
- package/.codex/skills/verify/SKILL.md +0 -269
- package/.cursor/commands/dev.md +0 -342
- package/.cursor/commands/plan.md +0 -563
- package/.cursor/commands/premerge.md +0 -183
- package/.cursor/commands/research.md +0 -39
- package/.cursor/commands/review.md +0 -448
- package/.cursor/commands/ship.md +0 -210
- package/.cursor/commands/sonarcloud.md +0 -146
- package/.cursor/commands/status.md +0 -87
- package/.cursor/commands/validate.md +0 -285
- package/.cursor/commands/verify.md +0 -266
- package/.cursorrules +0 -149
- package/.github/prompts/premerge.prompt.md +0 -188
- package/.github/prompts/research.prompt.md +0 -44
- package/.github/prompts/rollback.prompt.md +0 -723
- package/.github/prompts/ship.prompt.md +0 -215
- package/.github/prompts/status.prompt.md +0 -92
- package/.github/prompts/verify.prompt.md +0 -271
- package/.github/workflows/beads-to-github.yml +0 -56
- package/.github/workflows/github-to-beads.yml +0 -97
- package/.kilocode/workflows/dev.md +0 -346
- package/.kilocode/workflows/plan.md +0 -567
- package/.kilocode/workflows/premerge.md +0 -187
- package/.kilocode/workflows/research.md +0 -43
- package/.kilocode/workflows/review.md +0 -452
- package/.kilocode/workflows/rollback.md +0 -722
- package/.kilocode/workflows/ship.md +0 -214
- package/.kilocode/workflows/sonarcloud.md +0 -150
- package/.kilocode/workflows/status.md +0 -91
- package/.kilocode/workflows/validate.md +0 -289
- package/.kilocode/workflows/verify.md +0 -270
- package/.opencode/commands/dev.md +0 -345
- package/.opencode/commands/plan.md +0 -566
- package/.opencode/commands/premerge.md +0 -186
- package/.opencode/commands/research.md +0 -42
- package/.opencode/commands/review.md +0 -451
- package/.opencode/commands/rollback.md +0 -721
- package/.opencode/commands/ship.md +0 -213
- package/.opencode/commands/sonarcloud.md +0 -149
- package/.opencode/commands/status.md +0 -90
- package/.opencode/commands/validate.md +0 -288
- package/.opencode/commands/verify.md +0 -269
- package/.roo/commands/dev.md +0 -346
- package/.roo/commands/plan.md +0 -567
- package/.roo/commands/premerge.md +0 -187
- package/.roo/commands/research.md +0 -43
- package/.roo/commands/review.md +0 -452
- package/.roo/commands/rollback.md +0 -722
- package/.roo/commands/ship.md +0 -214
- package/.roo/commands/sonarcloud.md +0 -150
- package/.roo/commands/status.md +0 -91
- package/.roo/commands/validate.md +0 -289
- package/.roo/commands/verify.md +0 -270
- package/docs/BEADS_GITHUB_SYNC.md +0 -255
- package/docs/GREPTILE_SETUP.md +0 -400
- package/docs/MANUAL_REVIEW_GUIDE.md +0 -106
- package/docs/SETUP.md +0 -663
- package/docs/VALIDATION.md +0 -363
- package/lib/agents/cline.plugin.json +0 -29
- package/lib/agents/copilot.plugin.json +0 -24
- package/lib/agents/kilocode.plugin.json +0 -22
- package/lib/agents/opencode.plugin.json +0 -23
- package/lib/agents/roo.plugin.json +0 -30
- package/lib/beads-health-check.js +0 -143
- package/lib/commands/commands-reset.js +0 -147
- package/opencode.json +0 -67
- package/scripts/beads-context.test.js +0 -567
- package/scripts/github-beads-sync/comment.mjs +0 -64
- package/scripts/github-beads-sync/config.mjs +0 -148
- package/scripts/github-beads-sync/github-api.mjs +0 -131
- package/scripts/github-beads-sync/index.mjs +0 -332
- package/scripts/github-beads-sync/label-mapper.mjs +0 -54
- package/scripts/github-beads-sync/mapping.mjs +0 -78
- package/scripts/github-beads-sync/reverse-sync-cli.mjs +0 -31
- package/scripts/github-beads-sync/reverse-sync.mjs +0 -138
- package/scripts/github-beads-sync/run-bd.mjs +0 -161
- package/scripts/github-beads-sync/sanitize.mjs +0 -121
- package/scripts/github-beads-sync.config.json +0 -26
- package/scripts/sync-commands.js +0 -600
package/scripts/smart-status.sh
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# smart-status.sh
|
|
2
|
+
# smart-status.sh  Workflow intelligence scoring engine
|
|
3
3
|
#
|
|
4
|
-
# Reads issues via `
|
|
5
|
-
# for each issue, and outputs them sorted by score descending.
|
|
4
|
+
# Reads issues via `forge issue list --json` (Forge Kernel), computes a composite
|
|
5
|
+
# score for each issue, and outputs them sorted by score descending.
|
|
6
6
|
#
|
|
7
7
|
# Composite score:
|
|
8
8
|
# priority_weight * unblock_chain * type_weight * status_boost * epic_proximity * staleness_boost
|
|
@@ -11,20 +11,42 @@
|
|
|
11
11
|
# smart-status.sh [--json]
|
|
12
12
|
#
|
|
13
13
|
# Environment:
|
|
14
|
-
#
|
|
15
|
-
# GIT_CMD
|
|
16
|
-
# DEFAULT_BRANCH
|
|
14
|
+
# FORGE_CMD override the forge command (for testing with mocks)
|
|
15
|
+
# GIT_CMD  override the git command (for testing with mocks)
|
|
16
|
+
# DEFAULT_BRANCH  override the default branch name (default: auto-detect)
|
|
17
17
|
#
|
|
18
18
|
# Cross-platform: bash 3.2 compatible (no associative arrays, no mapfile).
|
|
19
19
|
# OWASP A03: All variables quoted, sanitize() strips injection patterns.
|
|
20
20
|
|
|
21
21
|
set -euo pipefail
|
|
22
22
|
|
|
23
|
-
#
|
|
23
|
+
# ââ€â‚¬Ã¢â€â‚¬ Source cross-dev awareness scripts ââ€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬
|
|
24
24
|
# file-index.sh: file_index_read for reading file index entries
|
|
25
25
|
# sync-utils.sh: get_session_identity for current developer identity
|
|
26
26
|
|
|
27
27
|
_SMART_STATUS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
28
|
+
if [ -f "$_SMART_STATUS_DIR/bootstrap-windows-tools.sh" ]; then
|
|
29
|
+
source "$_SMART_STATUS_DIR/bootstrap-windows-tools.sh"
|
|
30
|
+
fi
|
|
31
|
+
NODE_CMD="${NODE_CMD:-node}"
|
|
32
|
+
JQ_CMD="${JQ_CMD:-jq}"
|
|
33
|
+
|
|
34
|
+
node_script_path() {
|
|
35
|
+
case "$1" in
|
|
36
|
+
/[A-Za-z]/*)
|
|
37
|
+
_drive="$(printf '%s' "${1:1:1}" | tr '[:lower:]' '[:upper:]')"
|
|
38
|
+
printf '%s:/%s\n' "$_drive" "${1:3}"
|
|
39
|
+
;;
|
|
40
|
+
*)
|
|
41
|
+
if command -v cygpath >/dev/null 2>&1; then
|
|
42
|
+
cygpath -m "$1"
|
|
43
|
+
else
|
|
44
|
+
printf '%s\n' "$1"
|
|
45
|
+
fi
|
|
46
|
+
;;
|
|
47
|
+
esac
|
|
48
|
+
}
|
|
49
|
+
|
|
28
50
|
if [ -f "$_SMART_STATUS_DIR/lib/sanitize.sh" ]; then
|
|
29
51
|
source "$_SMART_STATUS_DIR/lib/sanitize.sh"
|
|
30
52
|
fi
|
|
@@ -35,7 +57,7 @@ if [ -f "$_SMART_STATUS_DIR/sync-utils.sh" ]; then
|
|
|
35
57
|
source "$_SMART_STATUS_DIR/sync-utils.sh"
|
|
36
58
|
fi
|
|
37
59
|
|
|
38
|
-
#
|
|
60
|
+
# ââ€â‚¬Ã¢â€â‚¬ Helpers ââ€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬
|
|
39
61
|
|
|
40
62
|
if ! declare -F sanitize >/dev/null; then
|
|
41
63
|
# Sanitize a string: strip shell-injection patterns (OWASP A03)
|
|
@@ -56,9 +78,9 @@ sanitize() {
|
|
|
56
78
|
}
|
|
57
79
|
fi
|
|
58
80
|
|
|
59
|
-
#
|
|
81
|
+
# ââ€â‚¬Ã¢â€â‚¬ Dependency check ââ€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬
|
|
60
82
|
|
|
61
|
-
if ! command -v
|
|
83
|
+
if ! command -v "$JQ_CMD" &>/dev/null; then
|
|
62
84
|
echo "Error: jq is required but not found." >&2
|
|
63
85
|
echo "Install jq:" >&2
|
|
64
86
|
echo " macOS: brew install jq" >&2
|
|
@@ -70,12 +92,12 @@ fi
|
|
|
70
92
|
# Warn if jq < 1.6 (fromdateiso8601 and sub/2 require 1.6+)
|
|
71
93
|
# Strip CR here as well because Windows jq.exe (or a CRLF-emitting wrapper in
|
|
72
94
|
# tests) can affect the version probe before the jq() shim is defined below.
|
|
73
|
-
_jq_version="$(command
|
|
95
|
+
_jq_version="$(command "$JQ_CMD" --version 2>/dev/null | tr -d '\r' | sed 's/jq-//')" || true
|
|
74
96
|
if [ -n "$_jq_version" ]; then
|
|
75
97
|
_jq_major="${_jq_version%%.*}"
|
|
76
98
|
_jq_minor="${_jq_version#*.}"; _jq_minor="${_jq_minor%%.*}"
|
|
77
99
|
if [ "${_jq_major:-0}" -lt 1 ] || { [ "${_jq_major:-0}" -eq 1 ] && [ "${_jq_minor:-0}" -lt 6 ]; }; then
|
|
78
|
-
echo "Warning: jq $_jq_version detected
|
|
100
|
+
echo "Warning: jq $_jq_version detected - staleness features require jq 1.6+. Team Activity may not display." >&2
|
|
79
101
|
fi
|
|
80
102
|
fi
|
|
81
103
|
|
|
@@ -83,12 +105,12 @@ fi
|
|
|
83
105
|
# numeric comparisons like `[ "$count" -gt 0 ]`. Strip trailing CRs from
|
|
84
106
|
# all jq output after the dependency/version checks above.
|
|
85
107
|
jq() {
|
|
86
|
-
command
|
|
108
|
+
command "$JQ_CMD" "$@" | tr -d '\r'
|
|
87
109
|
}
|
|
88
110
|
|
|
89
|
-
#
|
|
111
|
+
# ââ€â‚¬Ã¢â€â‚¬ Configuration ââ€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬
|
|
90
112
|
|
|
91
|
-
|
|
113
|
+
FORGE="${FORGE_CMD:-forge}"
|
|
92
114
|
GIT="${GIT_CMD:-git}"
|
|
93
115
|
JSON_MODE=0
|
|
94
116
|
|
|
@@ -103,7 +125,7 @@ else
|
|
|
103
125
|
BASE_BRANCH="master"
|
|
104
126
|
fi
|
|
105
127
|
|
|
106
|
-
# Parse arguments (bash 3.2 compatible
|
|
128
|
+
# Parse arguments (bash 3.2 compatible  no associative arrays)
|
|
107
129
|
for arg in "$@"; do
|
|
108
130
|
case "$arg" in
|
|
109
131
|
--json) JSON_MODE=1 ;;
|
|
@@ -124,36 +146,18 @@ for arg in "$@"; do
|
|
|
124
146
|
esac
|
|
125
147
|
done
|
|
126
148
|
|
|
127
|
-
#
|
|
149
|
+
# ââ€â‚¬Ã¢â€â‚¬ Fetch issues ââ€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬
|
|
128
150
|
|
|
129
|
-
#
|
|
130
|
-
#
|
|
131
|
-
#
|
|
132
|
-
#
|
|
133
|
-
#
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
_bd_list_err="$("$BD" list --json --limit 0 2>&1 >/dev/null || true)"
|
|
140
|
-
if printf '%s' "$_bd_list_err" | grep -qi "database.*not found"; then
|
|
141
|
-
# Derive prefix from repo root directory name (not pwd, which could be a subdirectory)
|
|
142
|
-
_repo_root="$("$GIT" rev-parse --show-toplevel 2>/dev/null || pwd)"
|
|
143
|
-
_bd_prefix="$(basename "$_repo_root" | tr '[:upper:]' '[:lower:]' | tr -cs '[:alnum:]-' '-' | sed 's/^-//;s/-$//')"
|
|
144
|
-
echo "Beads database not found — attempting auto-recovery..." >&2
|
|
145
|
-
if "$BD" init --force --prefix "$_bd_prefix" >/dev/null 2>&1; then
|
|
146
|
-
if [ -d "$_repo_root/.beads/backup" ] && ls "$_repo_root/.beads/backup"/*.jsonl >/dev/null 2>&1; then
|
|
147
|
-
"$BD" backup restore >/dev/null 2>&1 && echo "Beads: restored from backup." >&2 || echo "Beads: backup restore failed." >&2
|
|
148
|
-
else
|
|
149
|
-
echo "Beads: initialized fresh (no backup found)." >&2
|
|
150
|
-
fi
|
|
151
|
-
else
|
|
152
|
-
echo "Beads: auto-recovery failed — run 'bd doctor' manually." >&2
|
|
153
|
-
fi
|
|
154
|
-
fi
|
|
155
|
-
|
|
156
|
-
ISSUES_JSON="$("$BD" list --json --limit 0 2>/dev/null || echo '[]')"
|
|
151
|
+
# Fetch issues from the Forge Kernel and normalize the envelope into the bare
|
|
152
|
+
# array the scorer + grouping expect: extract .data.issues and drop terminal
|
|
153
|
+
# (done/cancelled) issues so completed work never pollutes the work queue. The
|
|
154
|
+
# kernel already supplies each issue's `dependents` (reverse-graph) and
|
|
155
|
+
# `dependencies` arrays, so no per-issue reshaping is needed. The kernel
|
|
156
|
+
# auto-migrates its single-machine SQLite store on read — nothing to recover.
|
|
157
|
+
ISSUES_JSON="$("$FORGE" issue list --json 2>/dev/null | jq '[
|
|
158
|
+
.data.issues[]
|
|
159
|
+
| select(.status != "done" and .status != "cancelled")
|
|
160
|
+
]' 2>/dev/null || echo '[]')"
|
|
157
161
|
|
|
158
162
|
# Bail early on empty
|
|
159
163
|
if [ "$(printf '%s' "$ISSUES_JSON" | jq 'length')" = "0" ]; then
|
|
@@ -165,7 +169,7 @@ if [ "$(printf '%s' "$ISSUES_JSON" | jq 'length')" = "0" ]; then
|
|
|
165
169
|
exit 0
|
|
166
170
|
fi
|
|
167
171
|
|
|
168
|
-
#
|
|
172
|
+
# ââ€â‚¬Ã¢â€â‚¬ Identify epics and fetch their children ââ€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬
|
|
169
173
|
|
|
170
174
|
# Extract epic IDs (type == "epic")
|
|
171
175
|
EPIC_IDS="$(printf '%s' "$ISSUES_JSON" | jq -r '.[] | select(.type == "epic") | .id')"
|
|
@@ -173,104 +177,33 @@ EPIC_IDS="$(printf '%s' "$ISSUES_JSON" | jq -r '.[] | select(.type == "epic") |
|
|
|
173
177
|
# Build a JSON object mapping epic_id -> { closed, total }
|
|
174
178
|
EPIC_STATS="{}"
|
|
175
179
|
if [ -n "$EPIC_IDS" ]; then
|
|
176
|
-
# Process each epic (bash 3.2 compatible
|
|
180
|
+
# Process each epic (bash 3.2 compatible  read line by line)
|
|
177
181
|
while IFS= read -r epic_id; do
|
|
178
182
|
[ -z "$epic_id" ] && continue
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
183
|
+
# Kernel `forge issue children` returns the rollup envelope; read total + the done
|
|
184
|
+
# count straight from the kernel-computed rollup (the kernel `done` status replaces
|
|
185
|
+
# the beads `closed` this math used to count). EPIC_STATS keeps its { total, closed }
|
|
186
|
+
# shape, so smart-status-score.js / scoring.js:getEpicProximity stay untouched.
|
|
187
|
+
CHILDREN_JSON="$("$FORGE" issue children "$epic_id" --json 2>/dev/null || echo '{}')"
|
|
188
|
+
[ -z "$CHILDREN_JSON" ] && CHILDREN_JSON='{}'
|
|
189
|
+
TOTAL="$(printf '%s' "$CHILDREN_JSON" | jq -r '(.data.rollup.total // 0)')"
|
|
190
|
+
CLOSED="$(printf '%s' "$CHILDREN_JSON" | jq -r '(.data.rollup.done // 0)')"
|
|
182
191
|
EPIC_STATS="$(printf '%s' "$EPIC_STATS" | jq --arg id "$epic_id" --argjson total "$TOTAL" --argjson closed "$CLOSED" '. + {($id): {total: $total, closed: $closed}}')"
|
|
183
192
|
done <<EOF
|
|
184
193
|
$EPIC_IDS
|
|
185
194
|
EOF
|
|
186
195
|
fi
|
|
187
196
|
|
|
188
|
-
#
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
[.[] | . as $issue |
|
|
200
|
-
|
|
201
|
-
# Priority weight: P0=5, P1=4, P2=3, P3=2, P4=1, default=1
|
|
202
|
-
# Normalize priority to number (beads 0.62+ sends numbers, older sends strings)
|
|
203
|
-
((.priority // 2) | if type == "string" then
|
|
204
|
-
(if . == "P0" then 0 elif . == "P1" then 1 elif . == "P2" then 2 elif . == "P3" then 3 elif . == "P4" then 4 else 5 end)
|
|
205
|
-
else . end) as $pri_num |
|
|
206
|
-
(if $pri_num == 0 then 5
|
|
207
|
-
elif $pri_num == 1 then 4
|
|
208
|
-
elif $pri_num == 2 then 3
|
|
209
|
-
elif $pri_num == 3 then 2
|
|
210
|
-
elif $pri_num == 4 then 1
|
|
211
|
-
else 1 end) as $priority_weight |
|
|
212
|
-
|
|
213
|
-
# Unblock chain: dependent_count + 1 (min 1).
|
|
214
|
-
# NOTE: dependent_count is the authoritative server-side count. The "Unblocks:"
|
|
215
|
-
# annotation (computed below from local response) may show fewer items when
|
|
216
|
-
# bd list omits closed or filtered-out issues. This is an intentional trade-off.
|
|
217
|
-
(((.dependent_count // 0) + 1) | if . < 1 then 1 else . end) as $unblock_chain |
|
|
218
|
-
|
|
219
|
-
# Type weight: bug=1.2, feature=1.0, task=0.8, default=1.0
|
|
220
|
-
# Handle null type from beads 0.62+
|
|
221
|
-
(if (.type // "task") == "bug" then 1.2
|
|
222
|
-
elif (.type // "task") == "feature" then 1.0
|
|
223
|
-
elif (.type // "task") == "task" then 0.8
|
|
224
|
-
else 1.0 end) as $type_weight |
|
|
225
|
-
|
|
226
|
-
# Status boost: in_progress=1.5, open=1.0, default=1.0
|
|
227
|
-
(if .status == "in_progress" then 1.5
|
|
228
|
-
elif .status == "open" then 1.0
|
|
229
|
-
else 1.0 end) as $status_boost |
|
|
230
|
-
|
|
231
|
-
# Epic proximity: if issue has parent_id that is an epic, compute
|
|
232
|
-
# 1.0 + (closed_siblings / total_siblings) * 0.5
|
|
233
|
-
(if (.parent_id // "") != "" and ($epic_stats[.parent_id] // null) != null then
|
|
234
|
-
$epic_stats[.parent_id] as $es |
|
|
235
|
-
if $es.total > 0 then
|
|
236
|
-
1.0 + (($es.closed / $es.total) * 0.5)
|
|
237
|
-
else 1.0 end
|
|
238
|
-
else 1.0 end) as $epic_proximity |
|
|
239
|
-
|
|
240
|
-
# Staleness boost based on updated_at
|
|
241
|
-
# 0-7d=1.0, 7-14d=1.1, 14-30d=1.2, 30+d=1.5
|
|
242
|
-
# Truncate to first 19 chars (YYYY-MM-DDTHH:MM:SS) + "Z" for fromdateiso8601.
|
|
243
|
-
# Handles fractional seconds (.NNN), timezone offsets (+05:30), or both.
|
|
244
|
-
(if .updated_at then
|
|
245
|
-
((.updated_at[:19] + "Z") | fromdateiso8601) as $ts |
|
|
246
|
-
((now - $ts) / 86400) as $days |
|
|
247
|
-
if $days >= 30 then 1.5
|
|
248
|
-
elif $days >= 14 then 1.2
|
|
249
|
-
elif $days >= 7 then 1.1
|
|
250
|
-
else 1.0 end
|
|
251
|
-
else 1.0 end) as $staleness_boost |
|
|
252
|
-
|
|
253
|
-
# Composite score
|
|
254
|
-
($priority_weight * $unblock_chain * $type_weight * $status_boost * $epic_proximity * $staleness_boost) as $score |
|
|
255
|
-
|
|
256
|
-
# Compute dependents list (which issues does this one unblock?)
|
|
257
|
-
($dependents_map[$issue.id] // []) as $dependents_list |
|
|
258
|
-
|
|
259
|
-
# Output scored issue
|
|
260
|
-
$issue + {
|
|
261
|
-
score: ($score * 100 | round / 100),
|
|
262
|
-
priority_weight: $priority_weight,
|
|
263
|
-
unblock_chain: $unblock_chain,
|
|
264
|
-
type_weight: $type_weight,
|
|
265
|
-
status_boost: $status_boost,
|
|
266
|
-
epic_proximity: (($epic_proximity * 100 | round) / 100),
|
|
267
|
-
staleness_boost: $staleness_boost,
|
|
268
|
-
dependents: $dependents_list
|
|
269
|
-
}
|
|
270
|
-
] | sort_by(-.score)
|
|
271
|
-
')"
|
|
272
|
-
|
|
273
|
-
# ── Session detection ─────────────────────────────────────────────────
|
|
197
|
+
# ââ€â‚¬Ã¢â€â‚¬ Score issues via shared JS helper ââ€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬
|
|
198
|
+
|
|
199
|
+
if ! command -v "$NODE_CMD" >/dev/null 2>&1; then
|
|
200
|
+
echo "Error: node is required but not found." >&2
|
|
201
|
+
exit 1
|
|
202
|
+
fi
|
|
203
|
+
|
|
204
|
+
SCORED_JSON="$(printf '{"issues":%s,"epicStats":%s}' "$ISSUES_JSON" "$EPIC_STATS" | "$NODE_CMD" "$(node_script_path "$_SMART_STATUS_DIR/smart-status-score.js")")"
|
|
205
|
+
|
|
206
|
+
# ââ€â‚¬Ã¢â€â‚¬ Session detection ââ€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬
|
|
274
207
|
|
|
275
208
|
# Parse git worktree list --porcelain to find active sessions
|
|
276
209
|
# Format: blocks separated by blank lines, each block has:
|
|
@@ -280,198 +213,50 @@ SCORED_JSON="$(printf '%s' "$ISSUES_JSON" | jq --argjson epic_stats "$EPIC_STATS
|
|
|
280
213
|
|
|
281
214
|
WORKTREE_PORCELAIN="$("$GIT" worktree list --porcelain 2>/dev/null || echo '')"
|
|
282
215
|
|
|
283
|
-
# Collect non-default-branch worktree branches and paths
|
|
284
|
-
# Stored as newline-delimited "branch<TAB>path" entries — safe for paths with |, spaces, etc.
|
|
285
|
-
SESSION_ENTRIES=""
|
|
286
|
-
SESSION_COUNT=0
|
|
287
|
-
|
|
288
|
-
_wt_path=""
|
|
289
|
-
_wt_branch=""
|
|
290
|
-
while IFS= read -r line; do
|
|
291
|
-
case "$line" in
|
|
292
|
-
worktree\ *)
|
|
293
|
-
_wt_path="${line#worktree }"
|
|
294
|
-
;;
|
|
295
|
-
branch\ *)
|
|
296
|
-
_wt_branch="${line#branch refs/heads/}"
|
|
297
|
-
;;
|
|
298
|
-
"")
|
|
299
|
-
# End of block — process if we have a branch that is not the default branch
|
|
300
|
-
if [ -n "$_wt_branch" ] && [ "$_wt_branch" != "$BASE_BRANCH" ]; then
|
|
301
|
-
SESSION_COUNT=$((SESSION_COUNT + 1))
|
|
302
|
-
if [ -n "$SESSION_ENTRIES" ]; then
|
|
303
|
-
SESSION_ENTRIES="${SESSION_ENTRIES}
|
|
304
|
-
${_wt_branch} ${_wt_path}"
|
|
305
|
-
else
|
|
306
|
-
SESSION_ENTRIES="${_wt_branch} ${_wt_path}"
|
|
307
|
-
fi
|
|
308
|
-
fi
|
|
309
|
-
_wt_path=""
|
|
310
|
-
_wt_branch=""
|
|
311
|
-
;;
|
|
312
|
-
esac
|
|
313
|
-
done <<EOF
|
|
314
|
-
${WORKTREE_PORCELAIN}
|
|
315
|
-
|
|
316
|
-
EOF
|
|
317
216
|
|
|
318
|
-
#
|
|
217
|
+
# Build session/conflict data with the shared JS helper so the shell layer
|
|
218
|
+
# only performs command execution and rendering.
|
|
319
219
|
IN_PROGRESS_JSON="[]"
|
|
320
|
-
if [ "$
|
|
321
|
-
|
|
322
|
-
#
|
|
323
|
-
|
|
324
|
-
IN_PROGRESS_JSON="$(printf '%s' "$ISSUES_JSON" | jq '[.[] | select(.status == "in_progress")]')"
|
|
325
|
-
fi
|
|
326
|
-
fi
|
|
327
|
-
|
|
328
|
-
# Build sessions data: for each branch, find matching in-progress issues
|
|
329
|
-
# Match by: branch slug (after feat/, fix/, docs/) appears in issue title (case-insensitive, hyphen-to-space)
|
|
330
|
-
SESSIONS_JSON="[]"
|
|
331
|
-
if [ "$SESSION_COUNT" -gt 0 ]; then
|
|
332
|
-
# Process each session (newline-delimited "branch<TAB>path" entries)
|
|
333
|
-
while IFS=' ' read -r _branch _path; do
|
|
334
|
-
[ -z "$_branch" ] && continue
|
|
335
|
-
|
|
336
|
-
# Extract slug from branch name (strip any <prefix>/ convention)
|
|
337
|
-
_slug="$_branch"
|
|
338
|
-
case "$_slug" in
|
|
339
|
-
*/*) _slug="${_slug##*/}" ;;
|
|
340
|
-
esac
|
|
341
|
-
|
|
342
|
-
# Convert slug hyphens to spaces for title matching
|
|
343
|
-
_slug_spaces="$(printf '%s' "$_slug" | tr '-' ' ')"
|
|
344
|
-
|
|
345
|
-
# Find matching in-progress issues: title contains slug words (case-insensitive)
|
|
346
|
-
_matched_ids="$(printf '%s' "$IN_PROGRESS_JSON" | jq -r --arg slug "$_slug_spaces" '
|
|
347
|
-
[.[] | select(
|
|
348
|
-
(.title | ascii_downcase | contains($slug | ascii_downcase))
|
|
349
|
-
) | .id] | join(",")
|
|
350
|
-
')"
|
|
351
|
-
|
|
352
|
-
_issue_count=0
|
|
353
|
-
if [ -n "$_matched_ids" ]; then
|
|
354
|
-
# Count commas + 1
|
|
355
|
-
_issue_count="$(printf '%s' "$_matched_ids" | tr -cd ',' | wc -c)"
|
|
356
|
-
_issue_count=$((_issue_count + 1))
|
|
357
|
-
fi
|
|
358
|
-
|
|
359
|
-
# Build session JSON entry
|
|
360
|
-
if [ -n "$_matched_ids" ]; then
|
|
361
|
-
_ids_json="$(printf '%s' "$_matched_ids" | jq -R 'split(",")')"
|
|
362
|
-
else
|
|
363
|
-
_ids_json="[]"
|
|
364
|
-
fi
|
|
365
|
-
|
|
366
|
-
SESSIONS_JSON="$(printf '%s' "$SESSIONS_JSON" | jq \
|
|
367
|
-
--arg branch "$_branch" \
|
|
368
|
-
--arg path "$_path" \
|
|
369
|
-
--argjson ids "$_ids_json" \
|
|
370
|
-
--argjson count "$_issue_count" \
|
|
371
|
-
'. + [{branch: $branch, path: $path, issue_ids: $ids, issue_count: $count}]'
|
|
372
|
-
)"
|
|
373
|
-
|
|
374
|
-
done <<SESSIONS_EOF
|
|
375
|
-
$SESSION_ENTRIES
|
|
376
|
-
SESSIONS_EOF
|
|
220
|
+
if [ -n "$WORKTREE_PORCELAIN" ]; then
|
|
221
|
+
# In-progress issues come straight from the already-fetched kernel list (it
|
|
222
|
+
# includes in_progress; only done/cancelled were dropped during the fetch).
|
|
223
|
+
IN_PROGRESS_JSON="$(printf '%s' "$ISSUES_JSON" | jq '[.[] | select(.status == "in_progress")]')"
|
|
377
224
|
fi
|
|
378
225
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
226
|
+
SESSIONS_JSON="$(printf '{"baseBranch":%s,"worktreePorcelain":%s,"inProgressIssues":%s}' \
|
|
227
|
+
"$(printf '%s' "$BASE_BRANCH" | jq -R '.')" \
|
|
228
|
+
"$(printf '%s' "$WORKTREE_PORCELAIN" | jq -Rs '.')" \
|
|
229
|
+
"$IN_PROGRESS_JSON" | "$NODE_CMD" "$(node_script_path "$_SMART_STATUS_DIR/smart-status-sessions.js")")"
|
|
230
|
+
SESSION_COUNT="$(printf '%s' "$SESSIONS_JSON" | jq 'length')"
|
|
383
231
|
|
|
384
|
-
# ALL_BRANCH_FILES: newline-delimited list of "branch<TAB>file1<TAB>file2..."
|
|
385
|
-
ALL_BRANCH_FILES=""
|
|
386
232
|
if [ "$SESSION_COUNT" -ge 2 ]; then
|
|
387
|
-
|
|
388
|
-
|
|
233
|
+
BRANCH_FILES_JSON="[]"
|
|
234
|
+
_session_branches="$(printf '%s' "$SESSIONS_JSON" | jq -r '.[].branch')"
|
|
235
|
+
while IFS= read -r _branch; do
|
|
389
236
|
[ -z "$_branch" ] && continue
|
|
390
|
-
|
|
391
|
-
# Get changed files for this branch vs BASE_BRANCH (-- prevents injection)
|
|
392
237
|
_files="$("$GIT" diff "${BASE_BRANCH}...${_branch}" --name-only -- 2>/dev/null || echo '')"
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
if [ -n "$ALL_BRANCH_FILES" ]; then
|
|
397
|
-
ALL_BRANCH_FILES="${ALL_BRANCH_FILES}
|
|
398
|
-
${_branch}:${_files_csv}"
|
|
399
|
-
else
|
|
400
|
-
ALL_BRANCH_FILES="${_branch}:${_files_csv}"
|
|
401
|
-
fi
|
|
402
|
-
done <<CONFLICT_EOF
|
|
403
|
-
$SESSION_ENTRIES
|
|
404
|
-
CONFLICT_EOF
|
|
405
|
-
|
|
406
|
-
# Build conflict map: find files that appear in multiple branches
|
|
407
|
-
# and add changed_files + conflicts to SESSIONS_JSON
|
|
408
|
-
while IFS= read -r _entry; do
|
|
409
|
-
[ -z "$_entry" ] && continue
|
|
410
|
-
_branch="${_entry%%:*}"
|
|
411
|
-
_files_csv="${_entry#*:}"
|
|
412
|
-
|
|
413
|
-
# Convert tab-delimited files to JSON array
|
|
414
|
-
if [ -n "$_files_csv" ]; then
|
|
415
|
-
_files_json="$(printf '%s' "$_files_csv" | jq -R 'split("\t")')"
|
|
416
|
-
else
|
|
417
|
-
_files_json="[]"
|
|
418
|
-
fi
|
|
419
|
-
|
|
420
|
-
# Find conflicts: files in this branch that also appear in other branches
|
|
421
|
-
_conflicts_json="[]"
|
|
422
|
-
while IFS= read -r _other_entry; do
|
|
423
|
-
[ -z "$_other_entry" ] && continue
|
|
424
|
-
_other_branch="${_other_entry%%:*}"
|
|
425
|
-
_other_files="${_other_entry#*:}"
|
|
426
|
-
|
|
427
|
-
# Skip self
|
|
428
|
-
[ "$_other_branch" = "$_branch" ] && continue
|
|
429
|
-
[ -z "$_other_files" ] && continue
|
|
430
|
-
|
|
431
|
-
# Find intersection
|
|
432
|
-
_other_json="$(printf '%s' "$_other_files" | jq -R 'split("\t")')"
|
|
433
|
-
_overlap="$(jq -n --argjson a "$_files_json" --argjson b "$_other_json" \
|
|
434
|
-
'[$a[] as $f | select($b | index($f))] | unique')"
|
|
435
|
-
_overlap_len="$(printf '%s' "$_overlap" | jq 'length')"
|
|
436
|
-
if [ "$_overlap_len" -gt 0 ]; then
|
|
437
|
-
_conflicts_json="$(jq -n \
|
|
438
|
-
--argjson existing "$_conflicts_json" \
|
|
439
|
-
--arg other_branch "$_other_branch" \
|
|
440
|
-
--argjson files "$_overlap" \
|
|
441
|
-
'$existing + [{branch: $other_branch, files: $files}]')"
|
|
442
|
-
fi
|
|
443
|
-
done <<INNER_EOF
|
|
444
|
-
$ALL_BRANCH_FILES
|
|
445
|
-
INNER_EOF
|
|
446
|
-
|
|
447
|
-
# Update SESSIONS_JSON: add changed_files and conflicts to matching branch entry
|
|
448
|
-
SESSIONS_JSON="$(printf '%s' "$SESSIONS_JSON" | jq \
|
|
238
|
+
_files_json="$(printf '%s' "$_files" | jq -R -s 'split("\n") | map(select(length > 0))')"
|
|
239
|
+
BRANCH_FILES_JSON="$(printf '%s' "$BRANCH_FILES_JSON" | jq \
|
|
449
240
|
--arg branch "$_branch" \
|
|
450
241
|
--argjson files "$_files_json" \
|
|
451
|
-
|
|
452
|
-
'[.[] | if .branch == $branch then . + {changed_files: $files, conflicts: $conflicts} else . end]'
|
|
242
|
+
'. + [{branch: $branch, files: $files}]'
|
|
453
243
|
)"
|
|
454
|
-
done <<
|
|
455
|
-
$
|
|
456
|
-
|
|
457
|
-
fi
|
|
244
|
+
done <<BRANCHEOF
|
|
245
|
+
$_session_branches
|
|
246
|
+
BRANCHEOF
|
|
458
247
|
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
# to detect actual merge conflicts vs mere file overlap.
|
|
248
|
+
SESSIONS_JSON="$(printf '{"sessions":%s,"branchFiles":%s}' "$SESSIONS_JSON" "$BRANCH_FILES_JSON" | "$NODE_CMD" "$(node_script_path "$_SMART_STATUS_DIR/smart-status-sessions.js")")"
|
|
249
|
+
fi
|
|
462
250
|
|
|
463
251
|
TIER2_ENABLED=0
|
|
464
252
|
if [ "$SESSION_COUNT" -ge 2 ]; then
|
|
465
|
-
# Check git version >= 2.38 (merge-tree --write-tree requires it)
|
|
466
253
|
_git_ver="$("$GIT" --version 2>/dev/null || echo '')"
|
|
467
254
|
_git_major=0
|
|
468
255
|
_git_minor=0
|
|
469
|
-
# Parse "git version X.Y.Z..." -> extract major and minor
|
|
470
256
|
_ver_nums="${_git_ver#git version }"
|
|
471
257
|
_git_major="${_ver_nums%%.*}"
|
|
472
258
|
_ver_rest="${_ver_nums#*.}"
|
|
473
259
|
_git_minor="${_ver_rest%%.*}"
|
|
474
|
-
# Validate they are numbers
|
|
475
260
|
case "$_git_major" in ''|*[!0-9]*) _git_major=0 ;; esac
|
|
476
261
|
case "$_git_minor" in ''|*[!0-9]*) _git_minor=0 ;; esac
|
|
477
262
|
|
|
@@ -480,79 +265,38 @@ if [ "$SESSION_COUNT" -ge 2 ]; then
|
|
|
480
265
|
fi
|
|
481
266
|
fi
|
|
482
267
|
|
|
483
|
-
# For each pair of branches with file overlaps, run merge-tree
|
|
484
268
|
if [ "$TIER2_ENABLED" = "1" ]; then
|
|
485
|
-
# Collect all branch pairs that have conflicts in SESSIONS_JSON
|
|
486
269
|
_conflict_pairs="$(printf '%s' "$SESSIONS_JSON" | jq -r '
|
|
487
270
|
[.[] | select((.conflicts // []) | length > 0) |
|
|
488
271
|
.branch as $b |
|
|
489
272
|
.conflicts[] |
|
|
490
|
-
[$b, .branch] | sort | join("
|
|
273
|
+
[$b, .branch] | sort | join("\t")
|
|
491
274
|
] | unique | .[]
|
|
492
275
|
')"
|
|
493
276
|
|
|
494
277
|
if [ -n "$_conflict_pairs" ]; then
|
|
495
|
-
|
|
496
|
-
while IFS= read -r
|
|
497
|
-
[ -z "$
|
|
498
|
-
|
|
499
|
-
_b2="${_pair#* }"
|
|
500
|
-
|
|
501
|
-
# Run merge-tree; exit 1 = actual conflict, exit 0 = clean merge
|
|
278
|
+
MERGE_TREE_RESULTS_JSON="[]"
|
|
279
|
+
while IFS=' ' read -r _b1 _b2; do
|
|
280
|
+
[ -z "$_b1" ] && continue
|
|
281
|
+
[ -z "$_b2" ] && continue
|
|
502
282
|
_mt_output=""
|
|
503
283
|
_mt_exit=0
|
|
504
284
|
_mt_output="$("$GIT" merge-tree --write-tree --name-only --no-messages -- "$_b1" "$_b2" 2>/dev/null)" || _mt_exit=$?
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
while IFS= read -r _cf_line; do
|
|
513
|
-
_line_num=$((_line_num + 1))
|
|
514
|
-
# Skip the first line (tree SHA output from merge-tree)
|
|
515
|
-
if [ "$_line_num" -eq 1 ]; then continue; fi
|
|
516
|
-
# Skip empty lines
|
|
517
|
-
if [ -z "$_cf_line" ]; then continue; fi
|
|
518
|
-
if [ -n "$_conflict_files" ]; then
|
|
519
|
-
_conflict_files="${_conflict_files} ${_cf_line}"
|
|
520
|
-
else
|
|
521
|
-
_conflict_files="${_cf_line}"
|
|
522
|
-
fi
|
|
523
|
-
done <<MTEOF
|
|
524
|
-
$_mt_output
|
|
525
|
-
MTEOF
|
|
526
|
-
|
|
527
|
-
if [ -n "$_conflict_files" ]; then
|
|
528
|
-
_cf_json="$(printf '%s' "$_conflict_files" | jq -R 'split("\t")')"
|
|
529
|
-
|
|
530
|
-
# Add merge_conflicts to both branches in SESSIONS_JSON
|
|
531
|
-
for _target_branch in "$_b1" "$_b2"; do
|
|
532
|
-
_other_branch="$_b1"
|
|
533
|
-
[ "$_target_branch" = "$_b1" ] && _other_branch="$_b2"
|
|
534
|
-
|
|
535
|
-
SESSIONS_JSON="$(printf '%s' "$SESSIONS_JSON" | jq \
|
|
536
|
-
--arg branch "$_target_branch" \
|
|
537
|
-
--arg other "$_other_branch" \
|
|
538
|
-
--argjson files "$_cf_json" \
|
|
539
|
-
'[.[] | if .branch == $branch then
|
|
540
|
-
. + {merge_conflicts: ((.merge_conflicts // []) + [{branch: $other, files: $files}])}
|
|
541
|
-
else . end]'
|
|
542
|
-
)"
|
|
543
|
-
done
|
|
544
|
-
fi
|
|
545
|
-
fi
|
|
285
|
+
MERGE_TREE_RESULTS_JSON="$(printf '%s' "$MERGE_TREE_RESULTS_JSON" | jq \
|
|
286
|
+
--arg left "$_b1" \
|
|
287
|
+
--arg right "$_b2" \
|
|
288
|
+
--arg output "$_mt_output" \
|
|
289
|
+
--argjson exitCode "$_mt_exit" \
|
|
290
|
+
'. + [{left: $left, right: $right, exitCode: $exitCode, output: $output}]'
|
|
291
|
+
)"
|
|
546
292
|
done <<PAIRSEOF
|
|
547
293
|
$_conflict_pairs
|
|
548
294
|
PAIRSEOF
|
|
295
|
+
|
|
296
|
+
SESSIONS_JSON="$(printf '{"sessions":%s,"mergeTreeResults":%s}' "$SESSIONS_JSON" "$MERGE_TREE_RESULTS_JSON" | "$NODE_CMD" "$(node_script_path "$_SMART_STATUS_DIR/smart-status-sessions.js")")"
|
|
549
297
|
fi
|
|
550
298
|
fi
|
|
551
299
|
|
|
552
|
-
# ── Cross-developer team activity ────────────────────────────────────────
|
|
553
|
-
# Read file index entries from all developers, identify OTHER developers'
|
|
554
|
-
# in-progress work, compute module overlaps, and flag stale claims.
|
|
555
|
-
|
|
556
300
|
TEAM_ACTIVITY_JSON="[]"
|
|
557
301
|
|
|
558
302
|
# Only proceed if file_index_read and get_session_identity are available
|
|
@@ -620,7 +364,7 @@ if command -v file_index_read &>/dev/null && command -v get_session_identity &>/
|
|
|
620
364
|
fi
|
|
621
365
|
fi
|
|
622
366
|
|
|
623
|
-
#
|
|
367
|
+
# ââ€â‚¬Ã¢â€â‚¬ Output ââ€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬Ã¢â€â‚¬
|
|
624
368
|
|
|
625
369
|
if [ "$JSON_MODE" = "1" ]; then
|
|
626
370
|
# Always output consistent shape: {sessions: [...], issues: [...], team_activity: [...]}
|
|
@@ -637,7 +381,7 @@ else
|
|
|
637
381
|
C_RED=$'\033[31m' C_DIM=$'\033[2m' C_BOLD=$'\033[1m' C_CYAN=$'\033[36m'
|
|
638
382
|
fi
|
|
639
383
|
|
|
640
|
-
#
|
|
384
|
+
# ââ€â‚¬Ã¢â€â‚¬ Active Sessions (before grouped output) ââ€â‚¬Ã¢â€â‚¬
|
|
641
385
|
if [ "$SESSION_COUNT" -gt 0 ]; then
|
|
642
386
|
printf '%s%s=== ACTIVE SESSIONS ===%s\n' "$C_BOLD" "$C_CYAN" "$C_RESET"
|
|
643
387
|
printf '%s' "$SESSIONS_JSON" | jq -r '.[] |
|
|
@@ -687,10 +431,10 @@ else
|
|
|
687
431
|
printf '\n'
|
|
688
432
|
fi
|
|
689
433
|
|
|
690
|
-
#
|
|
434
|
+
# ââ€â‚¬Ã¢â€â‚¬ Team Activity (cross-developer visibility) ââ€â‚¬Ã¢â€â‚¬
|
|
691
435
|
_ta_len="$(printf '%s' "$TEAM_ACTIVITY_JSON" | jq 'length')"
|
|
692
436
|
if [ "$_ta_len" -gt 0 ]; then
|
|
693
|
-
printf '%s%s
|
|
437
|
+
printf '%s%s--- Team Activity ----------------------------------------%s\n' "$C_BOLD" "$C_CYAN" "$C_RESET"
|
|
694
438
|
printf '%s' "$TEAM_ACTIVITY_JSON" | jq -r '
|
|
695
439
|
.[] |
|
|
696
440
|
.developer as $dev |
|
|
@@ -707,7 +451,7 @@ else
|
|
|
707
451
|
else
|
|
708
452
|
" " + $iid + " (in_progress)" +
|
|
709
453
|
(if ($mods | length) > 0 then
|
|
710
|
-
"
|
|
454
|
+
" - touching " + ($mods | join(", "))
|
|
711
455
|
else "" end)
|
|
712
456
|
end),
|
|
713
457
|
# Overlap or no-overlap line
|
|
@@ -733,14 +477,18 @@ else
|
|
|
733
477
|
# Group assignment (priority order: RESUME > UNBLOCK_CHAINS > BLOCKED > BACKLOG > READY_WORK)
|
|
734
478
|
# Note: in_progress issues with active blockers still show in RESUME (you started
|
|
735
479
|
# the work, you need to see it) but get a "BLOCKED" annotation in the output.
|
|
480
|
+
# Counts come from the scorer output: dependents is the reverse-graph
|
|
481
|
+
# array it computes, dependencies is the normalized { depends_on_id }
|
|
482
|
+
# list. done/cancelled were dropped at fetch; the status guards below stay
|
|
483
|
+
# as defense-in-depth so a terminal issue can never land in BLOCKED.
|
|
736
484
|
(if .status == "in_progress" then "RESUME"
|
|
737
|
-
elif (.
|
|
738
|
-
elif (.
|
|
485
|
+
elif ((.dependents // []) | length) >= 2 then "UNBLOCK_CHAINS"
|
|
486
|
+
elif ((.dependencies // []) | length) > 0 and .status != "done" and .status != "cancelled" then "BLOCKED"
|
|
739
487
|
elif (.priority == "P4" or .priority == 4) then "BACKLOG"
|
|
740
488
|
else "READY_WORK"
|
|
741
489
|
end) as $group |
|
|
742
490
|
# Flag in_progress issues that have active blockers
|
|
743
|
-
(if .status == "in_progress" and (.
|
|
491
|
+
(if .status == "in_progress" and ((.dependencies // []) | length) > 0 then true else false end) as $blocked_resume |
|
|
744
492
|
$item + { group: $group, days_ago: $days_ago, blocked_resume: $blocked_resume }
|
|
745
493
|
] |
|
|
746
494
|
|