@indigoai-us/hq-cli 5.314.0 → 5.315.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/CHANGELOG.md +4311 -1
- package/README.md +113 -0
- package/assets/bot-workers/setup/context/USER-GUIDE.md +404 -0
- package/assets/bot-workers/setup/context/quick-reference.md +199 -0
- package/assets/bot-workers/setup/skills/agents-and-team.md +167 -0
- package/assets/bot-workers/setup/skills/explain-hq.md +35 -0
- package/assets/bot-workers/setup/skills/first-company.md +74 -0
- package/assets/bot-workers/setup/skills/joining-a-team.md +125 -0
- package/assets/bot-workers/setup/skills/pricing.md +92 -0
- package/assets/bot-workers/setup/skills/standing-help.md +81 -0
- package/assets/bot-workers/setup/skills/your-business.md +281 -0
- package/assets/bot-workers/setup/worker.yaml +791 -0
- package/assets/lanes-hooks/hq-lanes-drain.json +15 -0
- package/assets/lanes-hooks/hq-lanes-drain.mjs +275 -0
- package/assets/lanes-hooks/hq-lanes-drain.sh +21 -0
- package/assets/lanes-reconcile/hq-lanes-reconcile.service +11 -0
- package/assets/lanes-reconcile/hq-lanes-reconcile.timer +12 -0
- package/assets/scaffold/.claude/hooks/validate-policy-frontmatter.sh +485 -0
- package/assets/scaffold/core/scripts/audit-log.sh +384 -0
- package/assets/scaffold/core/scripts/checkpoint-stop-gate.sh +281 -43
- package/assets/scaffold/core/scripts/clean-worktree-reconcile-handoff.sh +171 -0
- package/assets/scaffold/core/scripts/eval-trigger.sh +193 -0
- package/assets/scaffold/core/scripts/git-pack-extension-check.sh +164 -0
- package/assets/scaffold/core/scripts/handoff-finalize.sh +688 -0
- package/assets/scaffold/core/scripts/handoff-open-steps.sh +81 -0
- package/assets/scaffold/core/scripts/handoff-post.sh +252 -0
- package/assets/scaffold/core/scripts/hook-lib.sh +345 -50
- package/assets/scaffold/core/scripts/hq-delegate-bundle.sh +307 -0
- package/assets/scaffold/core/scripts/hq-delegate-grant.sh +252 -0
- package/assets/scaffold/core/scripts/hq-delegate-pickup.sh +99 -0
- package/assets/scaffold/core/scripts/hq-delegate-publish.sh +91 -0
- package/assets/scaffold/core/scripts/hq-delegate-repo.sh +158 -0
- package/assets/scaffold/core/scripts/hq-delegate-resolve.sh +145 -0
- package/assets/scaffold/core/scripts/hq-delegate-secrets.sh +129 -0
- package/assets/scaffold/core/scripts/hq-delegate-send.sh +259 -0
- package/assets/scaffold/core/scripts/hq-delegate-transfer.sh +175 -0
- package/assets/scaffold/core/scripts/hq-delegate-verify.sh +238 -0
- package/assets/scaffold/core/scripts/hq-dm-bind.sh +585 -0
- package/assets/scaffold/core/scripts/hq-job-notify.sh +389 -0
- package/assets/scaffold/core/scripts/hq-job-probe.sh +835 -0
- package/assets/scaffold/core/scripts/hq-job-remediate.sh +359 -0
- package/assets/scaffold/core/scripts/hq-job-run.sh +1025 -0
- package/assets/scaffold/core/scripts/hq-pin.sh +118 -0
- package/assets/scaffold/core/scripts/hq-session.sh +184 -23
- package/assets/scaffold/core/scripts/jobs-schedule-parse.sh +310 -0
- package/assets/scaffold/core/scripts/jobs-validate.sh +451 -0
- package/assets/scaffold/core/scripts/knowledge-prefs.sh +55 -0
- package/assets/scaffold/core/scripts/lib/portable.sh +211 -0
- package/assets/scaffold/core/scripts/lib/secret-patterns.sh +58 -0
- package/assets/scaffold/core/scripts/lib/session-id.sh +3 -2
- package/assets/scaffold/core/scripts/lib/session-scope-capability.sh +1 -1
- package/assets/scaffold/core/scripts/lib/work-mesh-enqueue.sh +2 -1
- package/assets/scaffold/core/scripts/lib/work-mesh-live-hook.sh +378 -0
- package/assets/scaffold/core/scripts/lib/work-mesh-live-rebind.sh +141 -0
- package/assets/scaffold/core/scripts/migrate-policy-triggers.sh +378 -0
- package/assets/scaffold/core/scripts/ontology-audience-grant.sh +81 -0
- package/assets/scaffold/core/scripts/ontology-brief.mjs +93 -0
- package/assets/scaffold/core/scripts/ontology-candidate.sh +100 -0
- package/assets/scaffold/core/scripts/ontology-garden.mjs +238 -0
- package/assets/scaffold/core/scripts/ontology-source-worklist.sh +79 -0
- package/assets/scaffold/core/scripts/outpost-jobs-reconcile.sh +834 -0
- package/assets/scaffold/core/scripts/policy-age-report.sh +156 -0
- package/assets/scaffold/core/scripts/policy-retire.sh +199 -0
- package/assets/scaffold/core/scripts/qmd-reindex-after-sync.sh +10 -87
- package/assets/scaffold/core/scripts/qmd-reindex-bg.sh +40 -0
- package/assets/scaffold/core/scripts/read-policy-frontmatter.sh +32 -0
- package/assets/scaffold/core/scripts/rebuild-company-knowledge-index.sh +36 -3
- package/assets/scaffold/core/scripts/rebuild-projects-index.sh +99 -12
- package/assets/scaffold/core/scripts/refresh-vault-access.sh +188 -0
- package/assets/scaffold/core/scripts/register-project.sh +262 -0
- package/assets/scaffold/core/scripts/resolve-company.sh +199 -0
- package/assets/scaffold/core/scripts/resume-thread-lock.sh +285 -0
- package/assets/scaffold/core/scripts/source-yaml-validate.sh +36 -0
- package/assets/scaffold/core/scripts/token-usage-report.sh +81 -20
- package/assets/scaffold/core/scripts/verify-story-deliverables.sh +148 -0
- package/assets/scaffold/core/scripts/work-mesh-live-bind-trusted.sh +152 -0
- package/assets/scaffold/core/scripts/work-mesh-live-rebind.sh +59 -0
- package/assets/scaffold/core/scripts/worktree-gc.sh +362 -0
- package/contracts/preflight/v1/fixtures.json +87 -0
- package/contracts/preflight/v1/schema.json +58 -0
- package/dist/bin/hq-auth-refresh.d.ts +2 -0
- package/dist/bin/hq-auth-refresh.js +12 -6
- package/dist/command-catalog.generated.d.ts +10753 -0
- package/dist/command-catalog.generated.js +13859 -0
- package/dist/command-registration-plan.d.ts +474 -0
- package/dist/command-registration-plan.js +136 -0
- package/dist/commands/__fixtures__/access-vault.d.ts +2 -0
- package/dist/commands/__fixtures__/access-vault.js +1 -1
- package/dist/commands/_patterns.d.ts +16 -0
- package/dist/commands/_patterns.js +20 -3
- package/dist/commands/access.d.ts +2 -1
- package/dist/commands/access.js +58 -49
- package/dist/commands/agent-enroll.d.ts +146 -0
- package/dist/commands/agent-enroll.js +401 -0
- package/dist/commands/agent-inbox.d.ts +9 -0
- package/dist/commands/agent-inbox.js +102 -0
- package/dist/commands/agent-kit.d.ts +87 -0
- package/dist/commands/agent-kit.js +480 -0
- package/dist/commands/agent-mcp.d.ts +24 -0
- package/dist/commands/agent-mcp.js +127 -0
- package/dist/commands/agent-probe.d.ts +77 -0
- package/dist/commands/agent-probe.js +335 -0
- package/dist/commands/agent.d.ts +13 -0
- package/dist/commands/agent.js +40 -0
- package/dist/commands/agents.d.ts +106 -4
- package/dist/commands/agents.js +924 -45
- package/dist/commands/auth.d.ts +1 -0
- package/dist/commands/auth.js +189 -19
- package/dist/commands/billing-sponsor.d.ts +83 -0
- package/dist/commands/billing-sponsor.js +344 -0
- package/dist/commands/billing.d.ts +3 -0
- package/dist/commands/billing.js +6 -1
- package/dist/commands/bot-companies.d.ts +40 -0
- package/dist/commands/bot-companies.js +64 -0
- package/dist/commands/bot-continuity.d.ts +28 -0
- package/dist/commands/bot-continuity.js +68 -0
- package/dist/commands/bot-jobs.d.ts +127 -0
- package/dist/commands/bot-jobs.js +454 -0
- package/dist/commands/bot.d.ts +278 -0
- package/dist/commands/bot.js +1982 -0
- package/dist/commands/channels.js +56 -1
- package/dist/commands/cloud-demote.js +3 -2
- package/dist/commands/cloud-provision.d.ts +14 -0
- package/dist/commands/cloud-provision.js +232 -58
- package/dist/commands/cloud-retire.d.ts +51 -0
- package/dist/commands/cloud-retire.js +154 -0
- package/dist/commands/cloud.d.ts +49 -15
- package/dist/commands/cloud.js +357 -122
- package/dist/commands/company-rename-flag.d.ts +4 -0
- package/dist/commands/company-rename-flag.js +7 -0
- package/dist/commands/company-rename.d.ts +4 -0
- package/dist/commands/company-rename.js +90 -0
- package/dist/commands/company-transfer.d.ts +4 -28
- package/dist/commands/company-transfer.js +5 -49
- package/dist/commands/company.js +68 -3
- package/dist/commands/core-audit-log-native.d.ts +9 -0
- package/dist/commands/core-audit-log-native.js +257 -0
- package/dist/commands/core-checkpoint-gate-setting.d.ts +59 -0
- package/dist/commands/core-checkpoint-gate-setting.js +163 -0
- package/dist/commands/core-checkpoint-stop-gate-native.d.ts +34 -0
- package/dist/commands/core-checkpoint-stop-gate-native.js +725 -0
- package/dist/commands/core-checkpoint.d.ts +19 -9
- package/dist/commands/core-checkpoint.js +301 -37
- package/dist/commands/core-command-catalog.d.ts +34 -0
- package/dist/commands/core-command-catalog.js +62 -0
- package/dist/commands/core-company-index-scope-flag.d.ts +3 -0
- package/dist/commands/core-company-index-scope-flag.js +6 -0
- package/dist/commands/core-delegate-w1b.d.ts +10 -0
- package/dist/commands/core-delegate-w1b.js +1219 -0
- package/dist/commands/core-delegate.d.ts +46 -0
- package/dist/commands/core-delegate.js +1040 -0
- package/dist/commands/core-dm-bind-native.d.ts +32 -0
- package/dist/commands/core-dm-bind-native.js +668 -0
- package/dist/commands/core-eval-trigger-native.d.ts +4 -0
- package/dist/commands/core-eval-trigger-native.js +12 -0
- package/dist/commands/core-git-pack-extension-check-native.d.ts +22 -0
- package/dist/commands/core-git-pack-extension-check-native.js +190 -0
- package/dist/commands/core-handoff-fast.d.ts +18 -0
- package/dist/commands/core-handoff-fast.js +104 -0
- package/dist/commands/core-handoff-open-steps.d.ts +21 -0
- package/dist/commands/core-handoff-open-steps.js +264 -0
- package/dist/commands/core-handoff.d.ts +24 -0
- package/dist/commands/core-handoff.js +1144 -0
- package/dist/commands/core-hq-session-native.d.ts +39 -0
- package/dist/commands/core-hq-session-native.js +579 -0
- package/dist/commands/core-job-native-utils.d.ts +6 -0
- package/dist/commands/core-job-native-utils.js +80 -0
- package/dist/commands/core-job-native.d.ts +5 -0
- package/dist/commands/core-job-native.js +16 -0
- package/dist/commands/core-job-notify-native.d.ts +36 -0
- package/dist/commands/core-job-notify-native.js +359 -0
- package/dist/commands/core-job-probe-native.d.ts +45 -0
- package/dist/commands/core-job-probe-native.js +564 -0
- package/dist/commands/core-job-remediate-native.d.ts +26 -0
- package/dist/commands/core-job-remediate-native.js +374 -0
- package/dist/commands/core-job-remote-launcher.d.ts +7 -0
- package/dist/commands/core-job-remote-launcher.js +51 -0
- package/dist/commands/core-job-run-native.d.ts +47 -0
- package/dist/commands/core-job-run-native.js +1215 -0
- package/dist/commands/core-jobs-native.d.ts +25 -0
- package/dist/commands/core-jobs-native.js +1339 -0
- package/dist/commands/core-knowledge-prefs.d.ts +11 -0
- package/dist/commands/core-knowledge-prefs.js +137 -0
- package/dist/commands/core-migrate-policy-triggers-native.d.ts +21 -0
- package/dist/commands/core-migrate-policy-triggers-native.js +374 -0
- package/dist/commands/core-native-handoff-flag.d.ts +4 -0
- package/dist/commands/core-native-handoff-flag.js +7 -0
- package/dist/commands/core-native-hook-helper-commands.d.ts +4 -0
- package/dist/commands/core-native-hook-helper-commands.js +56 -0
- package/dist/commands/core-native-hook-helpers-flag.d.ts +4 -0
- package/dist/commands/core-native-hook-helpers-flag.js +7 -0
- package/dist/commands/core-native-jobs-flag.d.ts +4 -0
- package/dist/commands/core-native-jobs-flag.js +7 -0
- package/dist/commands/core-native-policy-flag.d.ts +9 -0
- package/dist/commands/core-native-policy-flag.js +12 -0
- package/dist/commands/core-native-session-flag.d.ts +4 -0
- package/dist/commands/core-native-session-flag.js +7 -0
- package/dist/commands/core-native-utilities-flag.d.ts +4 -0
- package/dist/commands/core-native-utilities-flag.js +7 -0
- package/dist/commands/core-native-utilities.d.ts +29 -0
- package/dist/commands/core-native-utilities.js +54 -0
- package/dist/commands/core-native-worker-skills-flag.d.ts +4 -0
- package/dist/commands/core-native-worker-skills-flag.js +7 -0
- package/dist/commands/core-ontology-native.d.ts +17 -0
- package/dist/commands/core-ontology-native.js +916 -0
- package/dist/commands/core-ontology.d.ts +66 -0
- package/dist/commands/core-ontology.js +430 -0
- package/dist/commands/core-pin-native.d.ts +14 -0
- package/dist/commands/core-pin-native.js +236 -0
- package/dist/commands/core-policy-frontmatter.d.ts +8 -0
- package/dist/commands/core-policy-frontmatter.js +52 -0
- package/dist/commands/core-policy.d.ts +14 -0
- package/dist/commands/core-policy.js +1018 -0
- package/dist/commands/core-refresh-vault-access-native.d.ts +20 -0
- package/dist/commands/core-refresh-vault-access-native.js +229 -0
- package/dist/commands/core-register-project-native.d.ts +30 -0
- package/dist/commands/core-register-project-native.js +347 -0
- package/dist/commands/core-resolve-company-command.d.ts +4 -0
- package/dist/commands/core-resolve-company-command.js +42 -0
- package/dist/commands/core-resolve-company-native.d.ts +28 -0
- package/dist/commands/core-resolve-company-native.js +408 -0
- package/dist/commands/core-work-mesh-bind-trusted-native.d.ts +32 -0
- package/dist/commands/core-work-mesh-bind-trusted-native.js +190 -0
- package/dist/commands/core-work-mesh-live-rebind-native.d.ts +18 -0
- package/dist/commands/core-work-mesh-live-rebind-native.js +262 -0
- package/dist/commands/core-worker-lint-native.d.ts +4 -0
- package/dist/commands/core-worker-lint-native.js +160 -0
- package/dist/commands/core-worker-share-native.d.ts +4 -0
- package/dist/commands/core-worker-share-native.js +260 -0
- package/dist/commands/core-worker-skills-command.d.ts +8 -0
- package/dist/commands/core-worker-skills-command.js +33 -0
- package/dist/commands/core-worker-skills-runtime.d.ts +33 -0
- package/dist/commands/core-worker-skills-runtime.js +86 -0
- package/dist/commands/core.d.ts +4 -0
- package/dist/commands/core.js +277 -80
- package/dist/commands/crm.js +52 -3
- package/dist/commands/daemon.d.ts +63 -0
- package/dist/commands/daemon.js +877 -0
- package/dist/commands/db-provision.js +4 -4
- package/dist/commands/db-sql.js +7 -21
- package/dist/commands/deploy-comments.d.ts +3 -0
- package/dist/commands/deploy-comments.js +162 -0
- package/dist/commands/dm.d.ts +119 -12
- package/dist/commands/dm.js +388 -38
- package/dist/commands/doctor.d.ts +12 -0
- package/dist/commands/doctor.js +158 -12
- package/dist/commands/feedback.d.ts +6 -0
- package/dist/commands/feedback.js +86 -37
- package/dist/commands/files-browse.d.ts +32 -12
- package/dist/commands/files-browse.js +176 -60
- package/dist/commands/files.d.ts +17 -0
- package/dist/commands/files.js +300 -47
- package/dist/commands/group-grants.js +3 -2
- package/dist/commands/groups.js +6 -5
- package/dist/commands/index-cmd.d.ts +19 -1
- package/dist/commands/index-cmd.js +74 -7
- package/dist/commands/integrations-api.d.ts +15 -10
- package/dist/commands/integrations-api.js +27 -22
- package/dist/commands/integrations-connect.d.ts +51 -13
- package/dist/commands/integrations-connect.js +86 -71
- package/dist/commands/integrations-core.d.ts +6 -6
- package/dist/commands/integrations-core.js +25 -11
- package/dist/commands/integrations-import.d.ts +1 -1
- package/dist/commands/integrations-import.js +43 -24
- package/dist/commands/integrations-manage.js +20 -13
- package/dist/commands/integrations.d.ts +8 -0
- package/dist/commands/integrations.js +94 -7
- package/dist/commands/lanes-accounts.d.ts +28 -0
- package/dist/commands/lanes-accounts.js +595 -0
- package/dist/commands/lanes-autopilot.d.ts +11 -0
- package/dist/commands/lanes-autopilot.js +336 -0
- package/dist/commands/lanes-checks.d.ts +51 -0
- package/dist/commands/lanes-checks.js +941 -0
- package/dist/commands/lanes-hold.d.ts +43 -0
- package/dist/commands/lanes-hold.js +655 -0
- package/dist/commands/lanes-keep-alive-audit.d.ts +10 -0
- package/dist/commands/lanes-keep-alive-audit.js +19 -0
- package/dist/commands/lanes-kpis.d.ts +11 -0
- package/dist/commands/lanes-kpis.js +34 -0
- package/dist/commands/lanes-message.d.ts +9 -0
- package/dist/commands/lanes-message.js +946 -0
- package/dist/commands/lanes-move.d.ts +12 -0
- package/dist/commands/lanes-move.js +397 -0
- package/dist/commands/lanes-questions.d.ts +36 -0
- package/dist/commands/lanes-questions.js +1005 -0
- package/dist/commands/lanes-report.d.ts +11 -0
- package/dist/commands/lanes-report.js +333 -0
- package/dist/commands/lanes-resume.d.ts +6 -0
- package/dist/commands/lanes-resume.js +564 -0
- package/dist/commands/lanes-review.d.ts +10 -0
- package/dist/commands/lanes-review.js +56 -0
- package/dist/commands/lanes-shared.d.ts +449 -0
- package/dist/commands/lanes-shared.js +170 -0
- package/dist/commands/lanes-stories.d.ts +15 -0
- package/dist/commands/lanes-stories.js +347 -0
- package/dist/commands/lanes-watch.d.ts +7 -0
- package/dist/commands/lanes-watch.js +216 -0
- package/dist/commands/lanes.d.ts +149 -0
- package/dist/commands/lanes.js +8983 -0
- package/dist/commands/login.js +49 -6
- package/dist/commands/mcp-registration.d.ts +32 -25
- package/dist/commands/mcp-registration.js +256 -23
- package/dist/commands/mcp-status.js +1 -0
- package/dist/commands/meetings.js +55 -34
- package/dist/commands/members.js +5 -1
- package/dist/commands/mesh.d.ts +11 -0
- package/dist/commands/mesh.js +1086 -76
- package/dist/commands/monitor.d.ts +58 -0
- package/dist/commands/monitor.js +980 -0
- package/dist/commands/onboard-bot-membership.d.ts +32 -0
- package/dist/commands/onboard-bot-membership.js +40 -0
- package/dist/commands/onboard-create-identity.d.ts +26 -0
- package/dist/commands/onboard-create-identity.js +23 -0
- package/dist/commands/onboard-identity-guard.d.ts +1 -1
- package/dist/commands/onboard.js +24 -5
- package/dist/commands/outpost-pruner.d.ts +3 -0
- package/dist/commands/outpost-pruner.js +125 -0
- package/dist/commands/pack-install.js +3 -1
- package/dist/commands/packs.js +11 -1
- package/dist/commands/people.d.ts +4 -0
- package/dist/commands/people.js +37 -3
- package/dist/commands/personal-connector-settings-flag.d.ts +4 -0
- package/dist/commands/personal-connector-settings-flag.js +7 -0
- package/dist/commands/personal-targeted-push-flag.d.ts +4 -0
- package/dist/commands/personal-targeted-push-flag.js +7 -0
- package/dist/commands/personal-targeted-push-paths.d.ts +3 -0
- package/dist/commands/personal-targeted-push-paths.js +67 -0
- package/dist/commands/publish.d.ts +8 -1
- package/dist/commands/publish.js +17 -4
- package/dist/commands/reindex.js +56 -6
- package/dist/commands/report.d.ts +19 -0
- package/dist/commands/report.js +537 -0
- package/dist/commands/rescue.d.ts +4 -0
- package/dist/commands/rescue.js +27 -17
- package/dist/commands/run-feature-telemetry.d.ts +3 -0
- package/dist/commands/run-feature-telemetry.js +6 -0
- package/dist/commands/run.js +18 -4
- package/dist/commands/safe-extract.d.ts +11 -2
- package/dist/commands/safe-extract.js +36 -8
- package/dist/commands/secrets.d.ts +20 -2
- package/dist/commands/secrets.js +175 -71
- package/dist/commands/skill.d.ts +35 -4
- package/dist/commands/skill.js +357 -18
- package/dist/commands/staff/reset-test-account.d.ts +110 -0
- package/dist/commands/staff/reset-test-account.js +268 -0
- package/dist/commands/staff/test-account.d.ts +51 -0
- package/dist/commands/staff/test-account.js +196 -0
- package/dist/commands/sync-mode.d.ts +11 -0
- package/dist/commands/sync-mode.js +30 -0
- package/dist/commands/sync-narrow.js +36 -5
- package/dist/commands/team-sync.js +71 -10
- package/dist/commands/update.js +6 -0
- package/dist/commands/vault-retention-flag.d.ts +3 -0
- package/dist/commands/vault-retention-flag.js +9 -0
- package/dist/commands/vault-retention.d.ts +11 -0
- package/dist/commands/vault-retention.js +69 -0
- package/dist/commands/version.d.ts +10 -0
- package/dist/commands/version.js +11 -0
- package/dist/commands/whoami.d.ts +22 -0
- package/dist/commands/whoami.js +137 -4
- package/dist/commands/workers.d.ts +2 -14
- package/dist/commands/workers.js +7 -10
- package/dist/fast-core.d.ts +6 -7
- package/dist/fast-core.js +87 -24
- package/dist/fast-scaffold.d.ts +86 -0
- package/dist/fast-scaffold.js +364 -0
- package/dist/index.d.ts +3 -4
- package/dist/index.js +59 -9
- package/dist/lanes-drain-hook.d.ts +14 -0
- package/dist/lanes-drain-hook.js +203 -0
- package/dist/lazy-commands.d.ts +20 -44
- package/dist/lazy-commands.js +60 -58
- package/dist/lib/agent-kit/adopt-identity.d.ts +27 -0
- package/dist/lib/agent-kit/adopt-identity.js +60 -0
- package/dist/lib/agent-kit/attachment-download.d.ts +24 -0
- package/dist/lib/agent-kit/attachment-download.js +47 -0
- package/dist/lib/agent-kit/creds.d.ts +106 -0
- package/dist/lib/agent-kit/creds.js +163 -0
- package/dist/lib/agent-kit/fallback.d.ts +78 -0
- package/dist/lib/agent-kit/fallback.js +210 -0
- package/dist/lib/agent-kit/inbox-state.d.ts +83 -0
- package/dist/lib/agent-kit/inbox-state.js +159 -0
- package/dist/lib/agent-kit/kit-config.d.ts +56 -0
- package/dist/lib/agent-kit/kit-config.js +65 -0
- package/dist/lib/agent-kit/log.d.ts +16 -0
- package/dist/lib/agent-kit/log.js +46 -0
- package/dist/lib/agent-kit/mcp/attachments.d.ts +126 -0
- package/dist/lib/agent-kit/mcp/attachments.js +222 -0
- package/dist/lib/agent-kit/mcp/jsonrpc.d.ts +75 -0
- package/dist/lib/agent-kit/mcp/jsonrpc.js +164 -0
- package/dist/lib/agent-kit/mcp/tools.d.ts +64 -0
- package/dist/lib/agent-kit/mcp/tools.js +397 -0
- package/dist/lib/agent-kit/paths.d.ts +65 -0
- package/dist/lib/agent-kit/paths.js +118 -0
- package/dist/lib/agent-kit/private-file.d.ts +29 -0
- package/dist/lib/agent-kit/private-file.js +91 -0
- package/dist/lib/agent-kit/run/heartbeat.d.ts +72 -0
- package/dist/lib/agent-kit/run/heartbeat.js +128 -0
- package/dist/lib/agent-kit/run/inbox.d.ts +76 -0
- package/dist/lib/agent-kit/run/inbox.js +205 -0
- package/dist/lib/agent-kit/run/supervisor.d.ts +35 -0
- package/dist/lib/agent-kit/run/supervisor.js +85 -0
- package/dist/lib/agent-kit/run/sync.d.ts +33 -0
- package/dist/lib/agent-kit/run/sync.js +58 -0
- package/dist/lib/agent-kit/services.d.ts +31 -0
- package/dist/lib/agent-kit/services.js +55 -0
- package/dist/lib/agent-kit/skills.d.ts +18 -0
- package/dist/lib/agent-kit/skills.js +151 -0
- package/dist/lib/agent-kit/wake.d.ts +83 -0
- package/dist/lib/agent-kit/wake.js +243 -0
- package/dist/lib/agents/model-catalog.d.ts +62 -0
- package/dist/lib/agents/model-catalog.js +275 -0
- package/dist/lib/auth-login-provider-state.d.ts +8 -0
- package/dist/lib/auth-login-provider-state.js +63 -0
- package/dist/lib/aws-sdk-node-warning-output.d.ts +12 -0
- package/dist/lib/aws-sdk-node-warning-output.js +22 -0
- package/dist/lib/billing/free-month.d.ts +18 -0
- package/dist/lib/billing/free-month.js +31 -0
- package/dist/lib/billing/plan-limit-refusals.d.ts +69 -0
- package/dist/lib/billing/plan-limit-refusals.js +187 -0
- package/dist/lib/billing/plan-limit-upgrade-url.d.ts +11 -0
- package/dist/lib/billing/plan-limit-upgrade-url.js +66 -0
- package/dist/lib/billing/plan-lock.d.ts +143 -0
- package/dist/lib/billing/plan-lock.js +439 -0
- package/dist/lib/bot/api.d.ts +349 -0
- package/dist/lib/bot/api.js +316 -0
- package/dist/lib/bot/attachments.d.ts +45 -0
- package/dist/lib/bot/attachments.js +89 -0
- package/dist/lib/bot/cli-update.d.ts +138 -0
- package/dist/lib/bot/cli-update.js +278 -0
- package/dist/lib/bot/company-bind.d.ts +27 -0
- package/dist/lib/bot/company-bind.js +62 -0
- package/dist/lib/bot/config.d.ts +153 -0
- package/dist/lib/bot/config.js +233 -0
- package/dist/lib/bot/continuity-download.d.ts +28 -0
- package/dist/lib/bot/continuity-download.js +75 -0
- package/dist/lib/bot/continuity-install.d.ts +14 -0
- package/dist/lib/bot/continuity-install.js +101 -0
- package/dist/lib/bot/continuity.d.ts +67 -0
- package/dist/lib/bot/continuity.js +301 -0
- package/dist/lib/bot/creds.d.ts +24 -0
- package/dist/lib/bot/creds.js +51 -0
- package/dist/lib/bot/daemon.d.ts +173 -0
- package/dist/lib/bot/daemon.js +552 -0
- package/dist/lib/bot/inbox-poll-backoff-flag.d.ts +24 -0
- package/dist/lib/bot/inbox-poll-backoff-flag.js +135 -0
- package/dist/lib/bot/inbox-state.d.ts +18 -0
- package/dist/lib/bot/inbox-state.js +51 -0
- package/dist/lib/bot/index.d.ts +23 -0
- package/dist/lib/bot/index.js +23 -0
- package/dist/lib/bot/inflight.d.ts +119 -0
- package/dist/lib/bot/inflight.js +83 -0
- package/dist/lib/bot/job-completions.d.ts +89 -0
- package/dist/lib/bot/job-completions.js +132 -0
- package/dist/lib/bot/job-run.d.ts +109 -0
- package/dist/lib/bot/job-run.js +246 -0
- package/dist/lib/bot/local-config.d.ts +61 -0
- package/dist/lib/bot/local-config.js +145 -0
- package/dist/lib/bot/local-jobs.d.ts +89 -0
- package/dist/lib/bot/local-jobs.js +459 -0
- package/dist/lib/bot/local-name.d.ts +54 -0
- package/dist/lib/bot/local-name.js +114 -0
- package/dist/lib/bot/log.d.ts +13 -0
- package/dist/lib/bot/log.js +59 -0
- package/dist/lib/bot/owner-context.d.ts +79 -0
- package/dist/lib/bot/owner-context.js +175 -0
- package/dist/lib/bot/paths.d.ts +76 -0
- package/dist/lib/bot/paths.js +131 -0
- package/dist/lib/bot/progress.d.ts +132 -0
- package/dist/lib/bot/progress.js +289 -0
- package/dist/lib/bot/promote.d.ts +16 -0
- package/dist/lib/bot/promote.js +106 -0
- package/dist/lib/bot/promotion-hold.d.ts +24 -0
- package/dist/lib/bot/promotion-hold.js +103 -0
- package/dist/lib/bot/promotion-receipt.d.ts +9 -0
- package/dist/lib/bot/promotion-receipt.js +56 -0
- package/dist/lib/bot/promotion-upload.d.ts +16 -0
- package/dist/lib/bot/promotion-upload.js +80 -0
- package/dist/lib/bot/prompt.d.ts +136 -0
- package/dist/lib/bot/prompt.js +433 -0
- package/dist/lib/bot/room-policy.d.ts +63 -0
- package/dist/lib/bot/room-policy.js +91 -0
- package/dist/lib/bot/run.d.ts +217 -0
- package/dist/lib/bot/run.js +1869 -0
- package/dist/lib/bot/runnable.d.ts +51 -0
- package/dist/lib/bot/runnable.js +65 -0
- package/dist/lib/bot/runtime/claude.d.ts +50 -0
- package/dist/lib/bot/runtime/claude.js +170 -0
- package/dist/lib/bot/runtime/codex.d.ts +28 -0
- package/dist/lib/bot/runtime/codex.js +153 -0
- package/dist/lib/bot/runtime/grok-acp.d.ts +40 -0
- package/dist/lib/bot/runtime/grok-acp.js +265 -0
- package/dist/lib/bot/runtime/grok.d.ts +41 -0
- package/dist/lib/bot/runtime/grok.js +169 -0
- package/dist/lib/bot/runtime/index.d.ts +36 -0
- package/dist/lib/bot/runtime/index.js +417 -0
- package/dist/lib/bot/runtime/messages-stream.d.ts +56 -0
- package/dist/lib/bot/runtime/messages-stream.js +194 -0
- package/dist/lib/bot/runtime/sanitize.d.ts +18 -0
- package/dist/lib/bot/runtime/sanitize.js +28 -0
- package/dist/lib/bot/runtime/types.d.ts +159 -0
- package/dist/lib/bot/runtime/types.js +51 -0
- package/dist/lib/bot/runtime/windows.d.ts +10 -0
- package/dist/lib/bot/runtime/windows.js +53 -0
- package/dist/lib/bot/runtime-sign-in.d.ts +24 -0
- package/dist/lib/bot/runtime-sign-in.js +31 -0
- package/dist/lib/bot/scaffold.d.ts +38 -0
- package/dist/lib/bot/scaffold.js +94 -0
- package/dist/lib/bot/self-heal.d.ts +52 -0
- package/dist/lib/bot/self-heal.js +79 -0
- package/dist/lib/bot/self-process.d.ts +19 -0
- package/dist/lib/bot/self-process.js +35 -0
- package/dist/lib/bot/session.d.ts +19 -0
- package/dist/lib/bot/session.js +39 -0
- package/dist/lib/bot/setup-explain.d.ts +64 -0
- package/dist/lib/bot/setup-explain.js +141 -0
- package/dist/lib/bot/split.d.ts +32 -0
- package/dist/lib/bot/split.js +241 -0
- package/dist/lib/bot/status.d.ts +57 -0
- package/dist/lib/bot/status.js +66 -0
- package/dist/lib/bot/worker-source.d.ts +66 -0
- package/dist/lib/bot/worker-source.js +283 -0
- package/dist/lib/checkpoint-ontology/aliases.d.ts +17 -0
- package/dist/lib/checkpoint-ontology/aliases.js +44 -0
- package/dist/lib/checkpoint-ontology/apply.d.ts +110 -0
- package/dist/lib/checkpoint-ontology/apply.js +777 -0
- package/dist/lib/checkpoint-ontology/company-brief.d.ts +18 -0
- package/dist/lib/checkpoint-ontology/company-brief.js +337 -0
- package/dist/lib/checkpoint-ontology/company.d.ts +44 -0
- package/dist/lib/checkpoint-ontology/company.js +118 -0
- package/dist/lib/checkpoint-ontology/drop-aliases.d.ts +41 -0
- package/dist/lib/checkpoint-ontology/drop-aliases.js +76 -0
- package/dist/lib/checkpoint-ontology/entity-file.d.ts +109 -0
- package/dist/lib/checkpoint-ontology/entity-file.js +371 -0
- package/dist/lib/checkpoint-ontology/identity.d.ts +38 -0
- package/dist/lib/checkpoint-ontology/identity.js +95 -0
- package/dist/lib/checkpoint-ontology/merge-copies.d.ts +199 -0
- package/dist/lib/checkpoint-ontology/merge-copies.js +1086 -0
- package/dist/lib/checkpoint-ontology/multi-writer.d.ts +101 -0
- package/dist/lib/checkpoint-ontology/multi-writer.js +394 -0
- package/dist/lib/checkpoint-ontology/plan.d.ts +193 -0
- package/dist/lib/checkpoint-ontology/plan.js +504 -0
- package/dist/lib/checkpoint-ontology/queued-touches.d.ts +29 -0
- package/dist/lib/checkpoint-ontology/queued-touches.js +193 -0
- package/dist/lib/checkpoint-ontology/sync-client.d.ts +38 -0
- package/dist/lib/checkpoint-ontology/sync-client.js +84 -0
- package/dist/lib/checkpoint-ontology/tree.d.ts +55 -0
- package/dist/lib/checkpoint-ontology/tree.js +198 -0
- package/dist/lib/company-errors-sdk-warning-flag.d.ts +5 -0
- package/dist/lib/company-errors-sdk-warning-flag.js +8 -0
- package/dist/lib/company-skill-wrapper.d.ts +1 -0
- package/dist/lib/company-skill-wrapper.js +121 -29
- package/dist/lib/core-utils/codex-skill-bridge.d.ts +2 -1
- package/dist/lib/core-utils/hook-timeout-debug-context-flag.d.ts +20 -0
- package/dist/lib/core-utils/hook-timeout-debug-context-flag.js +81 -0
- package/dist/lib/core-utils/jq-json-serializer.d.ts +5 -0
- package/dist/lib/core-utils/jq-json-serializer.js +10 -0
- package/dist/lib/core-utils/qmd-reindex-after-sync.d.ts +14 -1
- package/dist/lib/core-utils/qmd-reindex-after-sync.js +101 -17
- package/dist/lib/core-utils/secret-patterns.d.ts +43 -0
- package/dist/lib/core-utils/secret-patterns.js +34 -0
- package/dist/lib/core-utils/sentry-report.d.ts +114 -0
- package/dist/lib/core-utils/sentry-report.js +1055 -0
- package/dist/lib/core-utils/soft-timeout.js +1 -1
- package/dist/lib/core-utils/timeout-guard-native.d.ts +7 -0
- package/dist/lib/core-utils/timeout-guard-native.js +40 -0
- package/dist/lib/core-utils/timeout-guard.d.ts +3 -3
- package/dist/lib/core-utils/timeout-guard.js +28 -13
- package/dist/lib/core-utils/token-usage-report.js +17 -3
- package/dist/lib/core-utils/worktree-resume.d.ts +20 -0
- package/dist/lib/core-utils/worktree-resume.js +1198 -0
- package/dist/lib/daemon/catalog.d.ts +134 -0
- package/dist/lib/daemon/catalog.js +358 -0
- package/dist/lib/daemon/config.d.ts +35 -0
- package/dist/lib/daemon/config.js +108 -0
- package/dist/lib/daemon/flag.d.ts +25 -0
- package/dist/lib/daemon/flag.js +59 -0
- package/dist/lib/daemon/handoff.d.ts +56 -0
- package/dist/lib/daemon/handoff.js +161 -0
- package/dist/lib/daemon/hq-cloud.d.ts +79 -0
- package/dist/lib/daemon/hq-cloud.js +183 -0
- package/dist/lib/daemon/install.d.ts +85 -0
- package/dist/lib/daemon/install.js +320 -0
- package/dist/lib/daemon/legacy-sync-env.d.ts +10 -0
- package/dist/lib/daemon/legacy-sync-env.js +58 -0
- package/dist/lib/daemon/legacy.d.ts +45 -0
- package/dist/lib/daemon/legacy.js +133 -0
- package/dist/lib/daemon/lock.d.ts +47 -0
- package/dist/lib/daemon/lock.js +138 -0
- package/dist/lib/daemon/machine-type.d.ts +50 -0
- package/dist/lib/daemon/machine-type.js +159 -0
- package/dist/lib/daemon/migrate.d.ts +77 -0
- package/dist/lib/daemon/migrate.js +265 -0
- package/dist/lib/daemon/paths.d.ts +24 -0
- package/dist/lib/daemon/paths.js +43 -0
- package/dist/lib/daemon/protocol-tail.d.ts +33 -0
- package/dist/lib/daemon/protocol-tail.js +131 -0
- package/dist/lib/daemon/remote-control.d.ts +74 -0
- package/dist/lib/daemon/remote-control.js +153 -0
- package/dist/lib/daemon/requests.d.ts +28 -0
- package/dist/lib/daemon/requests.js +65 -0
- package/dist/lib/daemon/run.d.ts +79 -0
- package/dist/lib/daemon/run.js +755 -0
- package/dist/lib/daemon/succession.d.ts +118 -0
- package/dist/lib/daemon/succession.js +263 -0
- package/dist/lib/daemon/supervisor.d.ts +132 -0
- package/dist/lib/daemon/supervisor.js +836 -0
- package/dist/lib/daemon/sync-runner.d.ts +58 -0
- package/dist/lib/daemon/sync-runner.js +277 -0
- package/dist/lib/daemon/tools.d.ts +52 -0
- package/dist/lib/daemon/tools.js +95 -0
- package/dist/lib/daemon/updater.d.ts +57 -0
- package/dist/lib/daemon/updater.js +163 -0
- package/dist/lib/db/control-plane.js +6 -0
- package/dist/lib/db/local.d.ts +0 -5
- package/dist/lib/db/local.js +1 -1
- package/dist/lib/db/migrate.d.ts +0 -12
- package/dist/lib/db/migrate.js +5 -5
- package/dist/lib/db/remote-sql.d.ts +2 -2
- package/dist/lib/db/remote-sql.js +3 -3
- package/dist/lib/db/sql.d.ts +0 -10
- package/dist/lib/db/sql.js +4 -8
- package/dist/lib/deploy-api.d.ts +5 -0
- package/dist/lib/deploy-api.js +21 -0
- package/dist/lib/deploy-apps.d.ts +13 -0
- package/dist/lib/deploy-apps.js +29 -0
- package/dist/lib/doctor/__testing__/fake-hq-tree.d.ts +1 -1
- package/dist/lib/doctor/__testing__/fake-hq-tree.js +1 -1
- package/dist/lib/doctor/__testing__/run-doctor.d.ts +8 -0
- package/dist/lib/doctor/__testing__/run-doctor.js +52 -0
- package/dist/lib/doctor/checks/bots.d.ts +13 -0
- package/dist/lib/doctor/checks/bots.js +189 -0
- package/dist/lib/doctor/checks/claude-wiring.js +70 -1
- package/dist/lib/doctor/checks/codex-wiring.d.ts +0 -4
- package/dist/lib/doctor/checks/codex-wiring.js +3 -35
- package/dist/lib/doctor/checks/grok-wiring.js +1 -34
- package/dist/lib/doctor/checks/integrations.js +11 -0
- package/dist/lib/doctor/checks/runtime-health.d.ts +4 -17
- package/dist/lib/doctor/checks/runtime-health.js +20 -7
- package/dist/lib/doctor/checks/scaffold-cli-floor.d.ts +6 -0
- package/dist/lib/doctor/checks/scaffold-cli-floor.js +73 -0
- package/dist/lib/doctor/checks/sync-health.d.ts +21 -0
- package/dist/lib/doctor/checks/sync-health.js +72 -2
- package/dist/lib/doctor/checks/sync-runtime.d.ts +11 -0
- package/dist/lib/doctor/checks/sync-runtime.js +216 -0
- package/dist/lib/doctor/checks/work-context.js +20 -6
- package/dist/lib/doctor/client-health-flag-token.d.ts +15 -0
- package/dist/lib/doctor/client-health-flag-token.js +66 -0
- package/dist/lib/doctor/client-health-reason-codes-flag.d.ts +27 -0
- package/dist/lib/doctor/client-health-reason-codes-flag.js +106 -0
- package/dist/lib/doctor/compat.d.ts +0 -16
- package/dist/lib/doctor/compat.js +4 -3
- package/dist/lib/doctor/deep/effects.js +1 -3
- package/dist/lib/doctor/deep/executor.d.ts +4 -10
- package/dist/lib/doctor/deep/executor.js +1 -1
- package/dist/lib/doctor/deep/parity.d.ts +2 -29
- package/dist/lib/doctor/deep/parity.js +7 -7
- package/dist/lib/doctor/deep/sandbox.d.ts +7 -25
- package/dist/lib/doctor/deep/sandbox.js +5 -7
- package/dist/lib/doctor/fix/apply.d.ts +79 -8
- package/dist/lib/doctor/fix/apply.js +292 -80
- package/dist/lib/doctor/fix/json-output.d.ts +28 -0
- package/dist/lib/doctor/fix/json-output.js +33 -0
- package/dist/lib/doctor/fix/refresh-sync-outcome.d.ts +12 -0
- package/dist/lib/doctor/fix/refresh-sync-outcome.js +25 -0
- package/dist/lib/doctor/fix/remediation.d.ts +14 -6
- package/dist/lib/doctor/fix/remediation.js +49 -9
- package/dist/lib/doctor/fixtures/schema.js +1 -3
- package/dist/lib/doctor/json-output.d.ts +17 -1
- package/dist/lib/doctor/json-output.js +7 -2
- package/dist/lib/doctor/platform.d.ts +0 -26
- package/dist/lib/doctor/platform.js +5 -5
- package/dist/lib/doctor/registry.d.ts +14 -0
- package/dist/lib/doctor/registry.js +71 -0
- package/dist/lib/doctor/report.js +1 -1
- package/dist/lib/doctor/shared.d.ts +8 -0
- package/dist/lib/doctor/shared.js +38 -0
- package/dist/lib/doctor/stray-gate-entries.d.ts +35 -0
- package/dist/lib/doctor/stray-gate-entries.js +83 -0
- package/dist/lib/doctor/types.d.ts +5 -0
- package/dist/lib/doctor/types.js +20 -0
- package/dist/lib/first-sync-next-step.d.ts +34 -0
- package/dist/lib/first-sync-next-step.js +179 -0
- package/dist/lib/flag-registry-endpoint.d.ts +5 -0
- package/dist/lib/flag-registry-endpoint.js +9 -0
- package/dist/lib/flag-registry-worker-source.generated.d.ts +2 -0
- package/dist/lib/flag-registry-worker-source.generated.js +3 -0
- package/dist/lib/flag-registry-worker.js +12 -1
- package/dist/lib/flag-registry.d.ts +26 -6
- package/dist/lib/flag-registry.js +133 -16
- package/dist/lib/flag-snapshot-file.d.ts +20 -0
- package/dist/lib/flag-snapshot-file.js +91 -0
- package/dist/lib/heartbeat-identity.d.ts +30 -0
- package/dist/lib/heartbeat-identity.js +76 -0
- package/dist/lib/index-render/companies.d.ts +4 -1
- package/dist/lib/index-render/companies.js +66 -3
- package/dist/lib/index-render/company-knowledge.js +80 -17
- package/dist/lib/index-render/index.d.ts +1 -0
- package/dist/lib/index-render/index.js +2 -1
- package/dist/lib/index-render/projects.js +82 -5
- package/dist/lib/index-render/shared.d.ts +13 -1
- package/dist/lib/index-render/shared.js +41 -2
- package/dist/lib/lanes/account-home.d.ts +8 -0
- package/dist/lib/lanes/account-home.js +10 -0
- package/dist/lib/lanes/accounts.d.ts +117 -0
- package/dist/lib/lanes/accounts.js +366 -0
- package/dist/lib/lanes/admission-host.d.ts +22 -0
- package/dist/lib/lanes/admission-host.js +37 -0
- package/dist/lib/lanes/admission.d.ts +26 -0
- package/dist/lib/lanes/admission.js +210 -0
- package/dist/lib/lanes/approval-gate.d.ts +8 -0
- package/dist/lib/lanes/approval-gate.js +90 -0
- package/dist/lib/lanes/autopilot-metrics.d.ts +99 -0
- package/dist/lib/lanes/autopilot-metrics.js +301 -0
- package/dist/lib/lanes/autopilot-registry.d.ts +62 -0
- package/dist/lib/lanes/autopilot-registry.js +192 -0
- package/dist/lib/lanes/autopilot.d.ts +133 -0
- package/dist/lib/lanes/autopilot.js +1222 -0
- package/dist/lib/lanes/blocker-freshness.d.ts +31 -0
- package/dist/lib/lanes/blocker-freshness.js +168 -0
- package/dist/lib/lanes/checked-company-path.d.ts +3 -0
- package/dist/lib/lanes/checked-company-path.js +39 -0
- package/dist/lib/lanes/claude-balance.d.ts +97 -0
- package/dist/lib/lanes/claude-balance.js +319 -0
- package/dist/lib/lanes/compaction.d.ts +110 -0
- package/dist/lib/lanes/compaction.js +293 -0
- package/dist/lib/lanes/config.d.ts +94 -0
- package/dist/lib/lanes/config.js +606 -0
- package/dist/lib/lanes/constants.d.ts +3 -0
- package/dist/lib/lanes/constants.js +3 -0
- package/dist/lib/lanes/delivery-core.d.ts +15 -0
- package/dist/lib/lanes/delivery-core.js +21 -0
- package/dist/lib/lanes/delivery.d.ts +180 -0
- package/dist/lib/lanes/delivery.js +443 -0
- package/dist/lib/lanes/disk-guard.d.ts +66 -0
- package/dist/lib/lanes/disk-guard.js +172 -0
- package/dist/lib/lanes/dropbox.d.ts +129 -0
- package/dist/lib/lanes/dropbox.js +601 -0
- package/dist/lib/lanes/effort.d.ts +51 -0
- package/dist/lib/lanes/effort.js +113 -0
- package/dist/lib/lanes/envelope-repair-dispatch.d.ts +26 -0
- package/dist/lib/lanes/envelope-repair-dispatch.js +74 -0
- package/dist/lib/lanes/errors.d.ts +39 -0
- package/dist/lib/lanes/errors.js +72 -0
- package/dist/lib/lanes/flag-keys.d.ts +22 -0
- package/dist/lib/lanes/flag-keys.js +22 -0
- package/dist/lib/lanes/grants.d.ts +30 -0
- package/dist/lib/lanes/grants.js +171 -0
- package/dist/lib/lanes/hire-grant-dispatch.d.ts +29 -0
- package/dist/lib/lanes/hire-grant-dispatch.js +315 -0
- package/dist/lib/lanes/hooks-install.d.ts +82 -0
- package/dist/lib/lanes/hooks-install.js +479 -0
- package/dist/lib/lanes/host-capacity.d.ts +69 -0
- package/dist/lib/lanes/host-capacity.js +254 -0
- package/dist/lib/lanes/hq-root.d.ts +19 -0
- package/dist/lib/lanes/hq-root.js +28 -0
- package/dist/lib/lanes/index.d.ts +76 -0
- package/dist/lib/lanes/index.js +42 -0
- package/dist/lib/lanes/keep-alive-audit.d.ts +46 -0
- package/dist/lib/lanes/keep-alive-audit.js +370 -0
- package/dist/lib/lanes/keep-alive.d.ts +68 -0
- package/dist/lib/lanes/keep-alive.js +343 -0
- package/dist/lib/lanes/kr-freshness.d.ts +76 -0
- package/dist/lib/lanes/kr-freshness.js +413 -0
- package/dist/lib/lanes/lane-company.d.ts +10 -0
- package/dist/lib/lanes/lane-company.js +41 -0
- package/dist/lib/lanes/liveness.d.ts +108 -0
- package/dist/lib/lanes/liveness.js +396 -0
- package/dist/lib/lanes/machine-identity.d.ts +34 -0
- package/dist/lib/lanes/machine-identity.js +92 -0
- package/dist/lib/lanes/manager-status-gate.d.ts +17 -0
- package/dist/lib/lanes/manager-status-gate.js +133 -0
- package/dist/lib/lanes/merge-command.d.ts +15 -0
- package/dist/lib/lanes/merge-command.js +629 -0
- package/dist/lib/lanes/mesh-events.d.ts +127 -0
- package/dist/lib/lanes/mesh-events.js +564 -0
- package/dist/lib/lanes/message-replay.d.ts +21 -0
- package/dist/lib/lanes/message-replay.js +122 -0
- package/dist/lib/lanes/models.d.ts +86 -0
- package/dist/lib/lanes/models.js +234 -0
- package/dist/lib/lanes/monitor.d.ts +48 -0
- package/dist/lib/lanes/monitor.js +428 -0
- package/dist/lib/lanes/move-account.d.ts +56 -0
- package/dist/lib/lanes/move-account.js +193 -0
- package/dist/lib/lanes/orphans.d.ts +25 -0
- package/dist/lib/lanes/orphans.js +102 -0
- package/dist/lib/lanes/outpost-dispatch.d.ts +147 -0
- package/dist/lib/lanes/outpost-dispatch.js +271 -0
- package/dist/lib/lanes/outpost-hire-cache.d.ts +22 -0
- package/dist/lib/lanes/outpost-hire-cache.js +153 -0
- package/dist/lib/lanes/outpost-identity.d.ts +33 -0
- package/dist/lib/lanes/outpost-identity.js +59 -0
- package/dist/lib/lanes/outpost-profile-repin.d.ts +17 -0
- package/dist/lib/lanes/outpost-profile-repin.js +84 -0
- package/dist/lib/lanes/outpost-pruner-install.d.ts +37 -0
- package/dist/lib/lanes/outpost-pruner-install.js +238 -0
- package/dist/lib/lanes/outpost-registry-worker-approval.d.ts +18 -0
- package/dist/lib/lanes/outpost-registry-worker-approval.js +109 -0
- package/dist/lib/lanes/outpost-snapshot-memo.d.ts +6 -0
- package/dist/lib/lanes/outpost-snapshot-memo.js +14 -0
- package/dist/lib/lanes/outpost-worktree-pruner-flag.d.ts +19 -0
- package/dist/lib/lanes/outpost-worktree-pruner-flag.js +86 -0
- package/dist/lib/lanes/outpost-worktree-pruner.d.ts +62 -0
- package/dist/lib/lanes/outpost-worktree-pruner.js +1201 -0
- package/dist/lib/lanes/profile.d.ts +69 -0
- package/dist/lib/lanes/profile.js +552 -0
- package/dist/lib/lanes/provider-rejection.d.ts +86 -0
- package/dist/lib/lanes/provider-rejection.js +286 -0
- package/dist/lib/lanes/questions.d.ts +90 -0
- package/dist/lib/lanes/questions.js +384 -0
- package/dist/lib/lanes/quota.d.ts +134 -0
- package/dist/lib/lanes/quota.js +471 -0
- package/dist/lib/lanes/reconcile-install.d.ts +90 -0
- package/dist/lib/lanes/reconcile-install.js +257 -0
- package/dist/lib/lanes/reconcile.d.ts +161 -0
- package/dist/lib/lanes/reconcile.js +3343 -0
- package/dist/lib/lanes/registry-flag.d.ts +35 -0
- package/dist/lib/lanes/registry-flag.js +164 -0
- package/dist/lib/lanes/registry-persona.d.ts +20 -0
- package/dist/lib/lanes/registry-persona.js +329 -0
- package/dist/lib/lanes/registry.d.ts +122 -0
- package/dist/lib/lanes/registry.js +570 -0
- package/dist/lib/lanes/reviews.d.ts +38 -0
- package/dist/lib/lanes/reviews.js +395 -0
- package/dist/lib/lanes/runaway-tool-guard.d.ts +38 -0
- package/dist/lib/lanes/runaway-tool-guard.js +284 -0
- package/dist/lib/lanes/session-relink.d.ts +25 -0
- package/dist/lib/lanes/session-relink.js +216 -0
- package/dist/lib/lanes/spawn.d.ts +355 -0
- package/dist/lib/lanes/spawn.js +2668 -0
- package/dist/lib/lanes/ssm-command-context.d.ts +12 -0
- package/dist/lib/lanes/ssm-command-context.js +52 -0
- package/dist/lib/lanes/store.d.ts +91 -0
- package/dist/lib/lanes/store.js +1822 -0
- package/dist/lib/lanes/stories.d.ts +23 -0
- package/dist/lib/lanes/stories.js +92 -0
- package/dist/lib/lanes/story-ledger.d.ts +80 -0
- package/dist/lib/lanes/story-ledger.js +815 -0
- package/dist/lib/lanes/story-switch.d.ts +21 -0
- package/dist/lib/lanes/story-switch.js +75 -0
- package/dist/lib/lanes/text-scan.d.ts +11 -0
- package/dist/lib/lanes/text-scan.js +103 -0
- package/dist/lib/lanes/throttle.d.ts +116 -0
- package/dist/lib/lanes/throttle.js +437 -0
- package/dist/lib/lanes/timestamp.d.ts +3 -0
- package/dist/lib/lanes/timestamp.js +26 -0
- package/dist/lib/lanes/tracker-checks.d.ts +77 -0
- package/dist/lib/lanes/tracker-checks.js +134 -0
- package/dist/lib/lanes/tracker-report-state.d.ts +10 -0
- package/dist/lib/lanes/tracker-report-state.js +124 -0
- package/dist/lib/lanes/tracker-report.d.ts +203 -0
- package/dist/lib/lanes/tracker-report.js +522 -0
- package/dist/lib/lanes/tracker-store.d.ts +18 -0
- package/dist/lib/lanes/tracker-store.js +106 -0
- package/dist/lib/lanes/types.d.ts +1030 -0
- package/dist/lib/lanes/types.js +418 -0
- package/dist/lib/lanes/wait.d.ts +39 -0
- package/dist/lib/lanes/wait.js +159 -0
- package/dist/lib/lanes/watch.d.ts +39 -0
- package/dist/lib/lanes/watch.js +249 -0
- package/dist/lib/lanes/watcher-main.d.ts +11 -0
- package/dist/lib/lanes/watcher-main.js +108 -0
- package/dist/lib/lanes/watcher.d.ts +287 -0
- package/dist/lib/lanes/watcher.js +1972 -0
- package/dist/lib/mesh/api.d.ts +103 -10
- package/dist/lib/mesh/api.js +334 -64
- package/dist/lib/mesh/client.d.ts +3 -2
- package/dist/lib/mesh/client.js +26 -7
- package/dist/lib/mesh/denial-codes.d.ts +5 -0
- package/dist/lib/mesh/denial-codes.js +14 -0
- package/dist/lib/mesh/live/backfill-held.d.ts +67 -16
- package/dist/lib/mesh/live/backfill-held.js +415 -61
- package/dist/lib/mesh/live/backoff.d.ts +2 -2
- package/dist/lib/mesh/live/backoff.js +16 -3
- package/dist/lib/mesh/live/daemon/board-refresh.d.ts +7 -1
- package/dist/lib/mesh/live/daemon/board-refresh.js +78 -30
- package/dist/lib/mesh/live/daemon/config.d.ts +36 -0
- package/dist/lib/mesh/live/daemon/config.js +120 -0
- package/dist/lib/mesh/live/daemon/credentials.d.ts +64 -10
- package/dist/lib/mesh/live/daemon/credentials.js +270 -20
- package/dist/lib/mesh/live/daemon/doctor.d.ts +53 -0
- package/dist/lib/mesh/live/daemon/doctor.js +190 -6
- package/dist/lib/mesh/live/daemon/index.d.ts +13 -10
- package/dist/lib/mesh/live/daemon/index.js +7 -6
- package/dist/lib/mesh/live/daemon/install.d.ts +255 -1
- package/dist/lib/mesh/live/daemon/install.js +811 -13
- package/dist/lib/mesh/live/daemon/legacy-listen.d.ts +43 -0
- package/dist/lib/mesh/live/daemon/legacy-listen.js +89 -0
- package/dist/lib/mesh/live/daemon/live-cache.d.ts +26 -0
- package/dist/lib/mesh/live/daemon/live-cache.js +116 -0
- package/dist/lib/mesh/live/daemon/mqtt-events.d.ts +7 -0
- package/dist/lib/mesh/live/daemon/mqtt-events.js +2 -0
- package/dist/lib/mesh/live/daemon/mqtt-events.test-d.d.ts +2 -0
- package/dist/lib/mesh/live/daemon/mqtt-events.test-d.js +10 -0
- package/dist/lib/mesh/live/daemon/paths.d.ts +2 -0
- package/dist/lib/mesh/live/daemon/paths.js +2 -0
- package/dist/lib/mesh/live/daemon/presence.d.ts +24 -5
- package/dist/lib/mesh/live/daemon/presence.js +79 -10
- package/dist/lib/mesh/live/daemon/run.d.ts +48 -2
- package/dist/lib/mesh/live/daemon/run.js +485 -33
- package/dist/lib/mesh/live/daemon/state.d.ts +19 -2
- package/dist/lib/mesh/live/daemon/state.js +34 -2
- package/dist/lib/mesh/live/daemon/transcript-watch.d.ts +45 -9
- package/dist/lib/mesh/live/daemon/transcript-watch.js +227 -31
- package/dist/lib/mesh/live/daemon/version-drift.d.ts +5 -0
- package/dist/lib/mesh/live/daemon/version-drift.js +47 -0
- package/dist/lib/mesh/live/daemon/work-subscribe.d.ts +32 -0
- package/dist/lib/mesh/live/daemon/work-subscribe.js +262 -0
- package/dist/lib/mesh/live/emit-client.d.ts +8 -0
- package/dist/lib/mesh/live/emit-client.js +23 -8
- package/dist/lib/mesh/live/emit-evidence.d.ts +19 -0
- package/dist/lib/mesh/live/emit-evidence.js +20 -2
- package/dist/lib/mesh/live/emit.d.ts +9 -0
- package/dist/lib/mesh/live/emit.js +28 -2
- package/dist/lib/mesh/live/enqueue.d.ts +5 -0
- package/dist/lib/mesh/live/enqueue.js +19 -0
- package/dist/lib/mesh/live/flush.d.ts +17 -5
- package/dist/lib/mesh/live/flush.js +391 -38
- package/dist/lib/mesh/live/format-spool-line.d.ts +5 -2
- package/dist/lib/mesh/live/format-spool-line.js +10 -0
- package/dist/lib/mesh/live/paths.d.ts +2 -0
- package/dist/lib/mesh/live/paths.js +4 -0
- package/dist/lib/mesh/live/report-summary.d.ts +45 -0
- package/dist/lib/mesh/live/report-summary.js +234 -0
- package/dist/lib/mesh/live/session-event.schema.json +24 -1
- package/dist/lib/mesh/live/session-events-client.d.ts +2 -0
- package/dist/lib/mesh/live/session-events-client.js +26 -0
- package/dist/lib/mesh/live/session-seq.d.ts +4 -0
- package/dist/lib/mesh/live/session-seq.js +33 -0
- package/dist/lib/mesh/live/spool.d.ts +19 -0
- package/dist/lib/mesh/live/spool.js +269 -3
- package/dist/lib/mesh/live/validate-session-event.d.ts +1 -1
- package/dist/lib/mesh/live/validate-session-event.js +1 -1
- package/dist/lib/mesh/project-board.d.ts +65 -0
- package/dist/lib/mesh/project-board.js +181 -0
- package/dist/lib/mesh/story-status.d.ts +22 -0
- package/dist/lib/mesh/story-status.js +49 -0
- package/dist/lib/monitor.d.ts +149 -0
- package/dist/lib/monitor.js +519 -0
- package/dist/lib/node-binary.d.ts +50 -0
- package/dist/lib/node-binary.js +133 -0
- package/dist/lib/notify-recipient.d.ts +7 -0
- package/dist/lib/notify-recipient.js +11 -0
- package/dist/lib/onboarding/checkpoint.d.ts +13 -0
- package/dist/lib/onboarding/checkpoint.js +44 -0
- package/dist/lib/onboarding/cli/onboard.d.ts +53 -0
- package/dist/lib/onboarding/cli/onboard.js +135 -0
- package/dist/lib/onboarding/cli/prompts.d.ts +28 -0
- package/dist/lib/onboarding/cli/prompts.js +83 -0
- package/dist/lib/onboarding/errors.d.ts +34 -0
- package/dist/lib/onboarding/errors.js +59 -0
- package/dist/lib/onboarding/index.d.ts +13 -0
- package/dist/lib/onboarding/index.js +13 -0
- package/dist/lib/onboarding/orchestrator.d.ts +47 -0
- package/dist/lib/onboarding/orchestrator.js +569 -0
- package/dist/lib/onboarding/types.d.ts +79 -0
- package/dist/lib/onboarding/types.js +8 -0
- package/dist/lib/plan-limit-nag.d.ts +102 -6
- package/dist/lib/plan-limit-nag.js +348 -43
- package/dist/lib/policy-validator.d.ts +7 -0
- package/dist/lib/policy-validator.js +187 -0
- package/dist/lib/process-flag-company-context.d.ts +8 -0
- package/dist/lib/process-flag-company-context.js +67 -0
- package/dist/lib/report-publish.d.ts +175 -0
- package/dist/lib/report-publish.js +421 -0
- package/dist/lib/report-run.d.ts +62 -0
- package/dist/lib/report-run.js +123 -0
- package/dist/lib/report-snapshot.d.ts +12 -0
- package/dist/lib/report-snapshot.js +135 -0
- package/dist/lib/report-templates.d.ts +9 -0
- package/dist/lib/report-templates.js +21 -0
- package/dist/lib/scaffold-cli-floor.d.ts +8 -0
- package/dist/lib/scaffold-cli-floor.js +50 -0
- package/dist/lib/scan-packages/index.d.ts +2 -0
- package/dist/lib/scan-packages/index.js +168 -6
- package/dist/lib/search-index/background.d.ts +8 -1
- package/dist/lib/search-index/background.js +55 -200
- package/dist/lib/search-index/collection-path-repair-flag.d.ts +4 -0
- package/dist/lib/search-index/collection-path-repair-flag.js +7 -0
- package/dist/lib/search-index/embed-lock.d.ts +34 -0
- package/dist/lib/search-index/embed-lock.js +295 -0
- package/dist/lib/search-index/index.d.ts +12 -0
- package/dist/lib/search-index/index.js +153 -7
- package/dist/lib/search-index/load-gate.d.ts +57 -0
- package/dist/lib/search-index/load-gate.js +270 -0
- package/dist/lib/search-index/max-doc-bytes.d.ts +219 -0
- package/dist/lib/search-index/max-doc-bytes.js +463 -0
- package/dist/lib/search-index/qmd-exit-diagnostics.d.ts +5 -0
- package/dist/lib/search-index/qmd-exit-diagnostics.js +40 -0
- package/dist/lib/search-index/reindex-single-flight-flag.d.ts +5 -0
- package/dist/lib/search-index/reindex-single-flight-flag.js +8 -0
- package/dist/lib/service-manager/index.d.ts +42 -0
- package/dist/lib/service-manager/index.js +105 -0
- package/dist/lib/service-manager/launchd.d.ts +81 -0
- package/dist/lib/service-manager/launchd.js +212 -0
- package/dist/lib/service-manager/systemd.d.ts +19 -0
- package/dist/lib/service-manager/systemd.js +72 -0
- package/dist/lib/service-manager/types.d.ts +34 -0
- package/dist/lib/service-manager/types.js +26 -0
- package/dist/lib/test-utils/isolated-flag-company-context.d.ts +3 -0
- package/dist/lib/test-utils/isolated-flag-company-context.js +18 -0
- package/dist/lib/work-context/bind-best.d.ts +66 -0
- package/dist/lib/work-context/bind-best.js +344 -0
- package/dist/lib/work-context/bind-calling-session.d.ts +26 -0
- package/dist/lib/work-context/bind-calling-session.js +63 -0
- package/dist/lib/work-context/company-rebind.d.ts +23 -0
- package/dist/lib/work-context/company-rebind.js +59 -0
- package/dist/lib/work-context/company.d.ts +22 -20
- package/dist/lib/work-context/company.js +124 -40
- package/dist/lib/work-context/config.d.ts +58 -11
- package/dist/lib/work-context/config.js +334 -83
- package/dist/lib/work-context/contract.d.ts +13 -0
- package/dist/lib/work-context/contract.schema.json +3 -1
- package/dist/lib/work-context/default-company.d.ts +43 -0
- package/dist/lib/work-context/default-company.js +83 -0
- package/dist/lib/work-context/outbox-quarantine-status-flag.d.ts +4 -0
- package/dist/lib/work-context/outbox-quarantine-status-flag.js +7 -0
- package/dist/lib/work-context/outbox.d.ts +27 -5
- package/dist/lib/work-context/outbox.js +135 -6
- package/dist/lib/work-context/prd-sync.d.ts +56 -0
- package/dist/lib/work-context/prd-sync.js +197 -0
- package/dist/lib/work-context/preflight-contract.d.ts +28 -0
- package/dist/lib/work-context/preflight-contract.js +85 -0
- package/dist/lib/work-context/prompt-rebind.d.ts +25 -0
- package/dist/lib/work-context/prompt-rebind.js +85 -0
- package/dist/lib/work-context/reconcile.d.ts +15 -0
- package/dist/lib/work-context/reconcile.js +405 -29
- package/dist/lib/work-context/state.d.ts +93 -10
- package/dist/lib/work-context/state.js +342 -29
- package/dist/lib/work-context/windows-acl.d.ts +123 -0
- package/dist/lib/work-context/windows-acl.js +425 -0
- package/dist/lib/workers-registry/index.js +62 -8
- package/dist/lib/workers-registry/read.d.ts +15 -0
- package/dist/lib/workers-registry/read.js +17 -0
- package/dist/main.d.ts +32 -0
- package/dist/main.js +273 -73
- package/dist/native-fast-route.d.ts +7 -0
- package/dist/native-fast-route.js +45 -0
- package/dist/node-network-compat-core.d.ts +12 -0
- package/dist/node-network-compat-core.js +41 -0
- package/dist/node-network-compat-fast.d.ts +7 -0
- package/dist/node-network-compat-fast.js +23 -0
- package/dist/node-network-compat.d.ts +2 -30
- package/dist/node-network-compat.js +4 -51
- package/dist/node-preflight.d.ts +7 -1
- package/dist/node-preflight.js +5 -5
- package/dist/register-all.d.ts +4 -29
- package/dist/register-all.js +4 -233
- package/dist/run/discover-schemas.d.ts +2 -1
- package/dist/run/env-graph-guard.d.ts +2 -2
- package/dist/run/env-graph-guard.js +5 -2
- package/dist/run/hq-plugin.d.ts +4 -0
- package/dist/run/hq-plugin.js +36 -8
- package/dist/secrets-env-fast-path.d.ts +5 -0
- package/dist/secrets-env-fast-path.js +16 -0
- package/dist/secrets-env-fast-route.d.ts +18 -0
- package/dist/secrets-env-fast-route.js +54 -0
- package/dist/sentry-before-send.js +80 -0
- package/dist/sentry.d.ts +16 -4
- package/dist/sentry.js +179 -18
- package/dist/startup-registration.d.ts +26 -2
- package/dist/startup-registration.js +116 -15
- package/dist/utils/checkpoint-stamp-write-error.d.ts +28 -0
- package/dist/utils/checkpoint-stamp-write-error.js +99 -0
- package/dist/utils/cli-network-lifecycle.d.ts +4 -0
- package/dist/utils/cli-network-lifecycle.js +11 -0
- package/dist/utils/cli-telemetry.d.ts +75 -1
- package/dist/utils/cli-telemetry.js +433 -7
- package/dist/utils/client-health.d.ts +0 -4
- package/dist/utils/client-health.js +2 -2
- package/dist/utils/cognito-refresh-sentry.d.ts +3 -0
- package/dist/utils/cognito-refresh-sentry.js +49 -0
- package/dist/utils/cognito-session.d.ts +71 -0
- package/dist/utils/cognito-session.js +481 -27
- package/dist/utils/console-origin.d.ts +9 -0
- package/dist/utils/console-origin.js +28 -0
- package/dist/utils/contribution-table.d.ts +1 -1
- package/dist/utils/core-eval-trigger.d.ts +4 -0
- package/dist/utils/core-eval-trigger.js +88 -0
- package/dist/utils/environmental-error.d.ts +18 -0
- package/dist/utils/environmental-error.js +240 -7
- package/dist/utils/exclusive-lock.d.ts +32 -0
- package/dist/utils/exclusive-lock.js +75 -0
- package/dist/utils/expected-cli-error.d.ts +2 -0
- package/dist/utils/expected-cli-error.js +4 -0
- package/dist/utils/fast-stream-errors.d.ts +12 -0
- package/dist/utils/fast-stream-errors.js +18 -0
- package/dist/utils/feedback-diagnostics.d.ts +2 -1
- package/dist/utils/feedback-log-bundle.d.ts +51 -26
- package/dist/utils/feedback-log-bundle.js +211 -31
- package/dist/utils/feedback-logs.d.ts +18 -47
- package/dist/utils/feedback-logs.js +50 -21
- package/dist/utils/feedback-screenshots.d.ts +0 -1
- package/dist/utils/feedback-screenshots.js +1 -1
- package/dist/utils/files-browse-acl.d.ts +5 -0
- package/dist/utils/files-browse-acl.js +11 -0
- package/dist/utils/hq-core-yaml.d.ts +10 -0
- package/dist/utils/hq-core-yaml.js +40 -0
- package/dist/utils/hq-root-resolver.d.ts +13 -0
- package/dist/utils/hq-root-resolver.js +103 -0
- package/dist/utils/hq-roots.d.ts +25 -2
- package/dist/utils/hq-roots.js +67 -7
- package/dist/utils/incomplete-install-error.d.ts +87 -19
- package/dist/utils/incomplete-install-error.js +319 -68
- package/dist/utils/install-tree-torn.d.ts +260 -24
- package/dist/utils/install-tree-torn.js +998 -51
- package/dist/utils/large-file-guard.d.ts +0 -10
- package/dist/utils/large-file-guard.js +1 -1
- package/dist/utils/local-files-overview.d.ts +4 -8
- package/dist/utils/local-files-overview.js +48 -7
- package/dist/utils/login-provider.d.ts +7 -0
- package/dist/utils/login-provider.js +34 -0
- package/dist/utils/pack-contributions.d.ts +2 -14
- package/dist/utils/pack-contributions.js +7 -44
- package/dist/utils/package-root-diagnostics.d.ts +1 -1
- package/dist/utils/people.d.ts +7 -11
- package/dist/utils/people.js +5 -20
- package/dist/utils/plan-gate-error.d.ts +52 -10
- package/dist/utils/plan-gate-error.js +364 -41
- package/dist/utils/qmd-model-download-error.d.ts +0 -8
- package/dist/utils/qmd-model-download-error.js +1 -1
- package/dist/utils/qmd-query-document-error.d.ts +0 -6
- package/dist/utils/qmd-query-document-error.js +1 -1
- package/dist/utils/redact-error-text.d.ts +0 -2
- package/dist/utils/redact-error-text.js +3 -2
- package/dist/utils/redact-url.d.ts +14 -0
- package/dist/utils/redact-url.js +218 -0
- package/dist/utils/run-bundled-script.d.ts +6 -0
- package/dist/utils/run-bundled-script.js +117 -4
- package/dist/utils/sandbox-runner-client.d.ts +2 -1
- package/dist/utils/scaffold-fast-import-guard.d.ts +2 -0
- package/dist/utils/scaffold-fast-import-guard.js +40 -0
- package/dist/utils/scaffold-packlist-guard.d.ts +7 -0
- package/dist/utils/scaffold-packlist-guard.js +23 -0
- package/dist/utils/scaffold-sibling-references.d.ts +22 -0
- package/dist/utils/scaffold-sibling-references.js +156 -0
- package/dist/utils/secret-load-availability.d.ts +8 -0
- package/dist/utils/secret-load-availability.js +54 -0
- package/dist/utils/secrets-cache.d.ts +7 -3
- package/dist/utils/secrets-cache.js +162 -14
- package/dist/utils/self-update.d.ts +34 -1
- package/dist/utils/self-update.js +660 -42
- package/dist/utils/sentry-fingerprint.d.ts +23 -1
- package/dist/utils/sentry-fingerprint.js +223 -31
- package/dist/utils/staged-install.d.ts +34 -0
- package/dist/utils/staged-install.js +346 -0
- package/dist/utils/staged-npm-install.d.ts +16 -0
- package/dist/utils/staged-npm-install.js +264 -0
- package/dist/utils/sync-log-sources.d.ts +15 -0
- package/dist/utils/sync-log-sources.js +36 -0
- package/dist/utils/table-width.d.ts +7 -0
- package/dist/utils/table-width.js +15 -0
- package/dist/utils/team-upgrade.d.ts +1 -1
- package/dist/utils/team-upgrade.js +4 -3
- package/dist/utils/update-command-supervisor.cjs +247 -0
- package/dist/utils/upload-author.d.ts +15 -0
- package/dist/utils/upload-author.js +39 -0
- package/dist/utils/vault-api.d.ts +21 -1
- package/dist/utils/vault-api.js +251 -84
- package/dist/utils/version-check.d.ts +11 -1
- package/dist/utils/version-check.js +32 -3
- package/dist/utils/version-gate.d.ts +101 -17
- package/dist/utils/version-gate.js +645 -70
- package/dist/utils/version-report.d.ts +27 -0
- package/dist/utils/version-report.js +105 -0
- package/dist/utils/windows-spawn.d.ts +6 -0
- package/dist/utils/windows-spawn.js +37 -0
- package/dist/version-request.d.ts +14 -0
- package/dist/version-request.js +36 -0
- package/package.json +20 -8
- package/scripts/mesh-daemon-if-stale.mjs +20 -0
- package/templates/reports/blank.md +3 -0
- package/templates/reports/daily-digest.md +11 -0
- package/templates/runbooks/update-report.md +21 -0
- package/dist/commands/scaffold-fast.d.ts +0 -41
- package/dist/commands/scaffold-fast.js +0 -57
- package/dist/lib/work-context/index.d.ts +0 -25
- package/dist/lib/work-context/index.js +0 -21
package/dist/commands/mesh.js
CHANGED
|
@@ -5,37 +5,57 @@
|
|
|
5
5
|
* require hq-pack-work-mesh on disk and does not start MQTT listen.
|
|
6
6
|
* Distinct from `hq doctor` (hook guardrails).
|
|
7
7
|
*/
|
|
8
|
+
import { resolve as resolvePath } from "node:path";
|
|
8
9
|
import * as os from "node:os";
|
|
10
|
+
import { readFileSync } from "node:fs";
|
|
11
|
+
import { findHqRoot } from "../utils/manifest.js";
|
|
12
|
+
import { CLI_VERSION } from "../cli-version.js";
|
|
9
13
|
import chalk from "chalk";
|
|
10
|
-
import {
|
|
14
|
+
import { ensureCognitoToken, isExpiring, isMachineIdentity, loadCachedTokens, } from "../utils/cognito-session.js";
|
|
11
15
|
import * as readline from "node:readline/promises";
|
|
12
|
-
import { STORY_STATUSES, appendThreadEvent,
|
|
16
|
+
import { STORY_STATUSES, appendThreadEvent, ensureProjectThread, eventPayload, getProjectView, listActiveMembershipCompanies, listActiveThreads, patchStory, putProjectView, registerMeshProject, resolveActiveMembershipCompany, resolveMeshPrincipalUid, warmMeshConversationCache, } from "../lib/mesh/api.js";
|
|
17
|
+
import { closeSupersededProjectThread, ensureMissingBoardStories, ensureProjectBoard, boardStoryStatus, formatStoryStatusChanges, mergeProjectStories, prdSyncEventsThatChangeBoard, } from "../lib/mesh/project-board.js";
|
|
18
|
+
import { mapSourceStoryStatus } from "../lib/mesh/story-status.js";
|
|
19
|
+
import { buildPreflightFixtures } from "../lib/work-context/preflight-contract.js";
|
|
13
20
|
import { createCandidatesFetcher, createMigratePoster, createOrganizePoster, createWorkSessionDeliverer, fetchCompanyLive, formatCompanyLiveTable, openMeshTransport, probeMigrationCapabilityForMemberships, requireToken, } from "../lib/mesh/client.js";
|
|
14
|
-
import { clearDefaultCompany,
|
|
15
|
-
import {
|
|
21
|
+
import { clearDefaultCompany, isDefaultCompanyDisabled, readDeviceConfig, recordMigrationCapabilitySnapshot, setRepairHeldWithDefault, setDefaultCompany, } from "../lib/work-context/config.js";
|
|
22
|
+
import { ensureDefaultCompany } from "../lib/work-context/default-company.js";
|
|
23
|
+
import { DefaultCompanyUnavailableError, } from "../lib/work-context/errors.js";
|
|
16
24
|
import { isValidSessionId } from "../lib/mesh/live/session-identity.js";
|
|
17
25
|
import { CLI_KIND_TO_SCHEMA, resolveEnqueueSessionId, } from "../lib/mesh/live/index.js";
|
|
18
26
|
import { flushSessionEvents } from "../lib/mesh/live/flush.js";
|
|
19
27
|
import { backfillHeldSessions } from "../lib/mesh/live/backfill-held.js";
|
|
20
28
|
import { createSessionEventsPoster, resolveVaultApiBase, } from "../lib/mesh/live/session-events-client.js";
|
|
21
|
-
|
|
29
|
+
const ONLINE_MEMBERSHIP_VALIDATION_TIMEOUT_MS = 5_000;
|
|
30
|
+
// Leave 500 ms of headroom inside SessionStart's 2 s process-group limit.
|
|
31
|
+
const OFFLINE_MEMBERSHIP_VALIDATION_TIMEOUT_MS = 1_500;
|
|
32
|
+
import { buildEmitEvidence, machineEmitDisposition } from "../lib/mesh/live/emit-evidence.js";
|
|
33
|
+
import { appendHeldLine } from "../lib/mesh/live/spool.js";
|
|
22
34
|
import { createEmitPoster, buildMeshEmitEvent } from "../lib/mesh/live/emit-client.js";
|
|
23
|
-
import {
|
|
35
|
+
import { enrichSessionEndEvent } from "../lib/mesh/live/report-summary.js";
|
|
36
|
+
import { emitEvents, formatEmitRejectionLines } from "../lib/mesh/live/emit.js";
|
|
24
37
|
import { readEmitRetry, writeEmitRetry } from "../lib/mesh/live/emit-retry.js";
|
|
25
38
|
import { generateUlid } from "../lib/mesh/live/ulid.js";
|
|
26
39
|
import { readLegacyBacklog } from "../lib/mesh/live/emit-replay.js";
|
|
27
40
|
import { resolveMeshEmitMode, writeMeshConfigMode, } from "../lib/mesh/live/daemon/mode.js";
|
|
28
41
|
import { workMeshRoot } from "../lib/mesh/live/paths.js";
|
|
29
|
-
import { buildInstallPaths, collectDaemonDoctor, daemonServiceStatus, detectPlatform, formatDaemonDoctor, installDaemonService, readDaemonState, runMeshDaemon, uninstallDaemonService,
|
|
42
|
+
import { buildInstallPaths, collectDaemonDoctor, daemonServiceIsLoaded, daemonServiceStatus, findAncestorHqRoot, resolveInstallHqRoot, detectPlatform, formatCliIdentityLines, formatDaemonDoctor, installDaemonIfStale, installDaemonService, readDaemonState, resolveAbsoluteNodeBinary, resolveRunningCliEntry, runMeshDaemon, uninstallDaemonService, } from "../lib/mesh/live/daemon/index.js";
|
|
43
|
+
import { defaultRunCommand } from "../lib/service-manager/launchd.js";
|
|
30
44
|
import { workContextRoot } from "../lib/work-context/paths.js";
|
|
31
45
|
import { formatMigrateConfirmation, submitSessionMigration, } from "../lib/work-context/migrate.js";
|
|
32
46
|
import { formatOrganizeList, prepareOrganizeDecision, settleOrganizeAskWithoutBind, submitOrganizeDecision, } from "../lib/work-context/organize.js";
|
|
33
|
-
import { readSessionState } from "../lib/work-context/state.js";
|
|
47
|
+
import { applyOperatorProjectBinding, readSessionState, updateSessionState, } from "../lib/work-context/state.js";
|
|
48
|
+
import { findLocalPrd, listNeedsProjectSessions } from "../lib/work-context/bind-best.js";
|
|
49
|
+
import { bindCallingSession, formatSessionBoundLine } from "../lib/work-context/bind-calling-session.js";
|
|
50
|
+
import { rebindNeedsProjectOnPrompt } from "../lib/work-context/prompt-rebind.js";
|
|
51
|
+
import { planPrdSync, rebindSessionToProject } from "../lib/work-context/prd-sync.js";
|
|
52
|
+
import { reserveSessionSeq } from "../lib/mesh/live/session-seq.js";
|
|
34
53
|
import { loadObservationFromFile, markUntracked, parseObservationJson, reconcileObservation, } from "../lib/work-context/reconcile.js";
|
|
35
54
|
import { resolveCompany } from "../lib/work-context/company.js";
|
|
36
55
|
import { deriveRemoteOwnerSlug, deriveRepoIdentityKey, } from "../lib/work-context/repo-remote.js";
|
|
37
56
|
import { promptRepoCompany, } from "../lib/work-context/repo-prompt.js";
|
|
38
57
|
import { requeueQuarantinedOutbox } from "../lib/work-context/outbox.js";
|
|
58
|
+
import { handOffInstallHere } from "../lib/daemon/handoff.js";
|
|
39
59
|
export function formatCheckLines(threads, company, projectId) {
|
|
40
60
|
if (threads.length === 0) {
|
|
41
61
|
return ["Work mesh: no active project threads found."];
|
|
@@ -43,14 +63,22 @@ export function formatCheckLines(threads, company, projectId) {
|
|
|
43
63
|
const scope = projectId
|
|
44
64
|
? `${company.companySlug || company.companyUid}/${projectId}`
|
|
45
65
|
: company.companySlug || company.companyUid;
|
|
46
|
-
const lines = [`Work mesh: ${threads.length}
|
|
66
|
+
const lines = [`Work mesh: ${threads.length} thread(s) for ${scope}`];
|
|
47
67
|
for (const thread of threads.slice(0, 8)) {
|
|
48
68
|
const owner = thread.ownerUid ? ` owner=${thread.ownerUid}` : "";
|
|
49
69
|
const summary = thread.progressSummary ||
|
|
50
70
|
thread.sourceSignalSummary ||
|
|
51
71
|
thread.blockedReason ||
|
|
52
72
|
"";
|
|
53
|
-
|
|
73
|
+
const lane = thread.kind === "lane" ? thread.lane : undefined;
|
|
74
|
+
const laneDetails = lane
|
|
75
|
+
? ` lane=${lane.laneId} laneStatus=${thread.laneStatus ?? "unknown"}` +
|
|
76
|
+
` story=${lane.storyId ?? "unknown"} profile=${lane.workerProfile ?? "unknown"}` +
|
|
77
|
+
` model=${lane.model ?? "unknown"} account=${lane.account ?? "unknown"}` +
|
|
78
|
+
`${lane.parentLaneId ? ` parent=${lane.parentLaneId}` : ""}`
|
|
79
|
+
: "";
|
|
80
|
+
const machine = thread.senderMachineUid ? ` machine=${thread.senderMachineUid}` : "";
|
|
81
|
+
lines.push(`- ${thread.threadStatus ?? "unknown"} ${thread.threadId ?? "?"}${owner}${machine}${laneDetails}${summary ? `: ${summary}` : ""}`);
|
|
54
82
|
}
|
|
55
83
|
return lines;
|
|
56
84
|
}
|
|
@@ -85,12 +113,20 @@ async function runCheck(opts) {
|
|
|
85
113
|
async function runEvent(verb, opts) {
|
|
86
114
|
const { token, company } = await withCompany(opts);
|
|
87
115
|
const projectId = requireProject(opts);
|
|
116
|
+
const eventKind = verb === "start" ? "claim" : verb;
|
|
117
|
+
let claimant = "";
|
|
118
|
+
if (eventKind === "claim") {
|
|
119
|
+
const resolvedClaimant = await resolveMeshPrincipalUid(token, loadCachedTokens());
|
|
120
|
+
if (!resolvedClaimant) {
|
|
121
|
+
fail("Could not resolve the authenticated claimant. Sign in again and retry `hq mesh start`.");
|
|
122
|
+
}
|
|
123
|
+
claimant = resolvedClaimant;
|
|
124
|
+
}
|
|
88
125
|
const ensured = await ensureProjectThread(token, company, projectId, {
|
|
89
126
|
threadId: opts.threadId,
|
|
90
127
|
summary: opts.summary,
|
|
91
128
|
});
|
|
92
|
-
const
|
|
93
|
-
const event = await appendThreadEvent(token, company.companyUid, ensured.threadId, eventKind, eventPayload(eventKind, opts, callerLabelFromToken(token)));
|
|
129
|
+
const event = await appendThreadEvent(token, company.companyUid, ensured.threadId, eventKind, eventPayload(eventKind, opts, claimant));
|
|
94
130
|
if (opts.json) {
|
|
95
131
|
console.log(JSON.stringify({
|
|
96
132
|
ok: true,
|
|
@@ -109,33 +145,705 @@ async function runEvent(verb, opts) {
|
|
|
109
145
|
async function runStory(opts) {
|
|
110
146
|
const storyId = opts.story?.trim();
|
|
111
147
|
const status = opts.status?.trim();
|
|
112
|
-
|
|
113
|
-
|
|
148
|
+
const assignee = opts.assignee?.trim();
|
|
149
|
+
if (!storyId) {
|
|
150
|
+
fail("story requires --story <id>");
|
|
151
|
+
}
|
|
152
|
+
if (!status && !assignee) {
|
|
153
|
+
fail("story requires --status queued|in_progress|review|done or --assignee <uid|me|none>");
|
|
154
|
+
}
|
|
155
|
+
if (status && !STORY_STATUSES.has(status)) {
|
|
156
|
+
fail("story --status must be queued|in_progress|review|done");
|
|
114
157
|
}
|
|
115
158
|
const { token, company } = await withCompany(opts);
|
|
116
159
|
const projectId = requireProject(opts);
|
|
117
|
-
|
|
160
|
+
let assigneeUid;
|
|
161
|
+
let clearAssignee = false;
|
|
162
|
+
if (assignee === "none") {
|
|
163
|
+
clearAssignee = true;
|
|
164
|
+
}
|
|
165
|
+
else if (assignee === "me") {
|
|
166
|
+
const resolved = await resolveMeshPrincipalUid(token, loadCachedTokens());
|
|
167
|
+
if (!resolved || resolved === "session") {
|
|
168
|
+
fail("`--assignee me` needs the signed-in person or agent. The synthetic session identity cannot be assigned. Sign in again and retry `hq mesh story`.");
|
|
169
|
+
}
|
|
170
|
+
assigneeUid = resolved;
|
|
171
|
+
}
|
|
172
|
+
else if (assignee) {
|
|
173
|
+
if (!/^(prs|agt)_/.test(assignee)) {
|
|
174
|
+
fail("`--assignee` must be a person or agent uid, `me`, or `none`.");
|
|
175
|
+
}
|
|
176
|
+
assigneeUid = assignee;
|
|
177
|
+
}
|
|
178
|
+
const patched = await patchStory(token, company.companyUid, projectId, storyId, {
|
|
179
|
+
...(status ? { status } : {}),
|
|
180
|
+
...(assigneeUid ? { assigneeUid } : {}),
|
|
181
|
+
...(clearAssignee ? { clearAssignee: true } : {}),
|
|
182
|
+
});
|
|
118
183
|
if (opts.json) {
|
|
119
184
|
console.log(JSON.stringify({ ok: true, action: "story", company, ...patched, storyId }, null, 2));
|
|
120
185
|
return;
|
|
121
186
|
}
|
|
122
|
-
|
|
187
|
+
const assignment = assignee === "none"
|
|
188
|
+
? "assignee cleared"
|
|
189
|
+
: assignee
|
|
190
|
+
? `assignee ${patched.assigneeUid ?? assigneeUid}`
|
|
191
|
+
: "";
|
|
192
|
+
const statusPart = status ? `${storyId} → ${patched.status}` : storyId;
|
|
193
|
+
console.log(`Work mesh: story ${statusPart}${assignment ? ` ${assignment}` : ""} (v${patched.version ?? "?"})`);
|
|
194
|
+
}
|
|
195
|
+
function record(value) {
|
|
196
|
+
return value && typeof value === "object" && !Array.isArray(value)
|
|
197
|
+
? value
|
|
198
|
+
: null;
|
|
199
|
+
}
|
|
200
|
+
function parseProjectRepoSpec(value, source) {
|
|
201
|
+
const raw = value.trim();
|
|
202
|
+
const separator = raw.lastIndexOf("@");
|
|
203
|
+
const path = (separator > 0 ? raw.slice(0, separator) : raw).trim();
|
|
204
|
+
const branch = (separator > 0 ? raw.slice(separator + 1) : "").trim();
|
|
205
|
+
if (!path)
|
|
206
|
+
fail(`${source} requires a non-empty repository path.`);
|
|
207
|
+
if (separator > 0 && !branch)
|
|
208
|
+
fail(`${source} has an empty branch after @.`);
|
|
209
|
+
return { path, branch };
|
|
210
|
+
}
|
|
211
|
+
function parseProjectRepos(value, source) {
|
|
212
|
+
if (!Array.isArray(value))
|
|
213
|
+
fail(`${source} must be a JSON repository array.`);
|
|
214
|
+
return value.map((raw, index) => {
|
|
215
|
+
if (typeof raw === "string")
|
|
216
|
+
return parseProjectRepoSpec(raw, `${source}[${index}]`);
|
|
217
|
+
const repo = record(raw);
|
|
218
|
+
const path = typeof repo?.path === "string"
|
|
219
|
+
? repo.path.trim()
|
|
220
|
+
: typeof repo?.repoPath === "string"
|
|
221
|
+
? repo.repoPath.trim()
|
|
222
|
+
: typeof repo?.repo === "string"
|
|
223
|
+
? repo.repo.trim()
|
|
224
|
+
: "";
|
|
225
|
+
const branchValue = repo?.branch ?? repo?.branchName;
|
|
226
|
+
const branch = branchValue === undefined ? "" : typeof branchValue === "string" ? branchValue.trim() : null;
|
|
227
|
+
if (!repo || !path)
|
|
228
|
+
fail(`${source}[${index}].path requires a string.`);
|
|
229
|
+
if (branch === null)
|
|
230
|
+
fail(`${source}[${index}].branch requires a string.`);
|
|
231
|
+
return { path, branch };
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
function parseProjectReposJson(raw, source) {
|
|
235
|
+
try {
|
|
236
|
+
return parseProjectRepos(JSON.parse(raw), source);
|
|
237
|
+
}
|
|
238
|
+
catch (err) {
|
|
239
|
+
if (err instanceof SyntaxError)
|
|
240
|
+
fail(`${source} must contain valid JSON.`);
|
|
241
|
+
throw err;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
function projectStoriesFromJson(value, source) {
|
|
245
|
+
const plan = Array.isArray(value) ? null : record(value);
|
|
246
|
+
const rawStories = Array.isArray(value)
|
|
247
|
+
? value
|
|
248
|
+
: Array.isArray(plan?.userStories)
|
|
249
|
+
? plan.userStories
|
|
250
|
+
: Array.isArray(plan?.stories)
|
|
251
|
+
? plan.stories
|
|
252
|
+
: null;
|
|
253
|
+
if (!rawStories) {
|
|
254
|
+
fail(`${source} must be a JSON story array or an object with userStories.`);
|
|
255
|
+
}
|
|
256
|
+
const stories = rawStories.map((raw, index) => {
|
|
257
|
+
const story = record(raw);
|
|
258
|
+
const id = typeof story?.id === "string" ? story.id.trim() : "";
|
|
259
|
+
const title = typeof story?.title === "string" ? story.title.trim() : "";
|
|
260
|
+
if (!story || !id || !title) {
|
|
261
|
+
fail(`${source} userStories[${index}] requires string id and title.`);
|
|
262
|
+
}
|
|
263
|
+
const status = mapSourceStoryStatus(story, `${source} userStories[${index}]`);
|
|
264
|
+
const resolvedStatus = status || (story.passes === true ? "done" : undefined);
|
|
265
|
+
return {
|
|
266
|
+
id,
|
|
267
|
+
title,
|
|
268
|
+
...(typeof story.description === "string" ? { description: story.description } : {}),
|
|
269
|
+
...(Array.isArray(story.acceptanceCriteria)
|
|
270
|
+
? {
|
|
271
|
+
acceptanceCriteria: story.acceptanceCriteria.filter((item) => typeof item === "string"),
|
|
272
|
+
}
|
|
273
|
+
: {}),
|
|
274
|
+
...(resolvedStatus ? { status: resolvedStatus } : {}),
|
|
275
|
+
// hq-pro makes passes mirror the Board status. A completed PRD story
|
|
276
|
+
// without an explicit status must therefore become done.
|
|
277
|
+
passes: resolvedStatus === "done",
|
|
278
|
+
...(typeof story.priority === "number" && Number.isFinite(story.priority)
|
|
279
|
+
? { priority: story.priority }
|
|
280
|
+
: {}),
|
|
281
|
+
};
|
|
282
|
+
});
|
|
283
|
+
const metadata = record(plan?.metadata);
|
|
284
|
+
const repos = metadata && Object.hasOwn(metadata, "repos")
|
|
285
|
+
? parseProjectRepos(metadata.repos, `${source} metadata.repos`)
|
|
286
|
+
: undefined;
|
|
287
|
+
return {
|
|
288
|
+
...(typeof plan?.name === "string" ? { name: plan.name } : {}),
|
|
289
|
+
...(typeof plan?.description === "string" ? { description: plan.description } : {}),
|
|
290
|
+
stories,
|
|
291
|
+
...(repos ? { repos } : {}),
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
function parseProjectPlan(raw, source) {
|
|
295
|
+
try {
|
|
296
|
+
return projectStoriesFromJson(JSON.parse(raw), source);
|
|
297
|
+
}
|
|
298
|
+
catch (err) {
|
|
299
|
+
if (err instanceof SyntaxError)
|
|
300
|
+
fail(`${source} must contain valid JSON.`);
|
|
301
|
+
throw err;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
function httpStatus(err) {
|
|
305
|
+
if (err && typeof err === "object" && "status" in err && typeof err.status === "number") {
|
|
306
|
+
return err.status;
|
|
307
|
+
}
|
|
308
|
+
return undefined;
|
|
309
|
+
}
|
|
310
|
+
function mergeProjectRepos(current, planned) {
|
|
311
|
+
const plannedPaths = new Set(planned.map((repo) => repo.path));
|
|
312
|
+
return [...planned, ...current.filter((repo) => !plannedPaths.has(repo.path))];
|
|
313
|
+
}
|
|
314
|
+
async function runProjectSet(projectId, opts) {
|
|
315
|
+
if (opts.channel !== undefined && !opts.channel.trim()) {
|
|
316
|
+
fail("PROJECT_CHANNEL_INVALID: --channel must be a non-empty channel id.");
|
|
317
|
+
}
|
|
318
|
+
if (opts.storiesFile && opts.storiesJson) {
|
|
319
|
+
fail("Pass only one of --stories-file or --stories-json.");
|
|
320
|
+
}
|
|
321
|
+
if (opts.reposJson && opts.repo?.length) {
|
|
322
|
+
fail("Pass only one of --repos-json or --repo.");
|
|
323
|
+
}
|
|
324
|
+
const source = opts.storiesFile
|
|
325
|
+
? parseProjectPlan(readFileSync(opts.storiesFile, "utf8"), opts.storiesFile)
|
|
326
|
+
: opts.storiesJson
|
|
327
|
+
? parseProjectPlan(opts.storiesJson, "--stories-json")
|
|
328
|
+
: undefined;
|
|
329
|
+
const explicitRepos = opts.reposJson
|
|
330
|
+
? parseProjectReposJson(opts.reposJson, "--repos-json")
|
|
331
|
+
: opts.repo?.length
|
|
332
|
+
? opts.repo.map((repo, index) => parseProjectRepoSpec(repo, `--repo[${index}]`))
|
|
333
|
+
: undefined;
|
|
334
|
+
const { token, company } = await withCompany(opts);
|
|
335
|
+
let current;
|
|
336
|
+
try {
|
|
337
|
+
current = await getProjectView(token, company.companyUid, projectId);
|
|
338
|
+
}
|
|
339
|
+
catch (err) {
|
|
340
|
+
if (httpStatus(err) === 404 && opts.create) {
|
|
341
|
+
if (!source && !opts.name?.trim()) {
|
|
342
|
+
fail("`--create` needs --name or a stories file when the Board view does not exist.");
|
|
343
|
+
}
|
|
344
|
+
current = undefined;
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
throw err;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
if (!current && !opts.create) {
|
|
351
|
+
fail(`Work mesh project ${projectId} has no Board view. Re-run with --create to add one.`);
|
|
352
|
+
}
|
|
353
|
+
const principalUid = await resolveMeshPrincipalUid(token, loadCachedTokens());
|
|
354
|
+
const PROJECT_CHANGED = "The Board changed while you were editing. Re-run to pick up the latest.";
|
|
355
|
+
let view;
|
|
356
|
+
let registration;
|
|
357
|
+
if (!current) {
|
|
358
|
+
const ensured = await ensureProjectBoard({
|
|
359
|
+
token,
|
|
360
|
+
company,
|
|
361
|
+
projectId,
|
|
362
|
+
name: opts.name?.trim() || source?.name || projectId,
|
|
363
|
+
description: opts.description !== undefined ? opts.description : source?.description ?? "",
|
|
364
|
+
stories: source?.stories ?? [],
|
|
365
|
+
repos: explicitRepos ?? source?.repos ?? [],
|
|
366
|
+
channelId: opts.channel,
|
|
367
|
+
});
|
|
368
|
+
view = ensured.view;
|
|
369
|
+
registration = ensured.registration;
|
|
370
|
+
}
|
|
371
|
+
else if (opts.name !== undefined || opts.description !== undefined || source !== undefined || explicitRepos !== undefined) {
|
|
372
|
+
const stories = source
|
|
373
|
+
? mergeProjectStories(current.stories, source.stories, { resetStatus: Boolean(opts.resetStatus) })
|
|
374
|
+
: current.stories;
|
|
375
|
+
const statusChangeLine = source ? formatStoryStatusChanges(current.stories, stories) : undefined;
|
|
376
|
+
try {
|
|
377
|
+
view = await putProjectView(token, company.companyUid, projectId, {
|
|
378
|
+
name: opts.name?.trim() || source?.name || current.name,
|
|
379
|
+
...(opts.description !== undefined
|
|
380
|
+
? { description: opts.description }
|
|
381
|
+
: source?.description !== undefined
|
|
382
|
+
? { description: source.description }
|
|
383
|
+
: { description: current.description }),
|
|
384
|
+
stories,
|
|
385
|
+
repos: explicitRepos ?? source?.repos ?? current.repos,
|
|
386
|
+
...(current.version !== undefined ? { expectedVersion: current.version } : {}),
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
catch (err) {
|
|
390
|
+
const conflict = err;
|
|
391
|
+
if (conflict.status === 409 && conflict.code === "VERSION_CONFLICT") {
|
|
392
|
+
if (opts.json) {
|
|
393
|
+
console.log(JSON.stringify({ ok: false, code: "VERSION_CONFLICT", error: PROJECT_CHANGED }));
|
|
394
|
+
}
|
|
395
|
+
fail(PROJECT_CHANGED);
|
|
396
|
+
}
|
|
397
|
+
throw err;
|
|
398
|
+
}
|
|
399
|
+
if (statusChangeLine) {
|
|
400
|
+
if (opts.json)
|
|
401
|
+
console.error(statusChangeLine);
|
|
402
|
+
else
|
|
403
|
+
console.log(statusChangeLine);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
else {
|
|
407
|
+
view = current;
|
|
408
|
+
}
|
|
409
|
+
if (current && opts.channel !== undefined) {
|
|
410
|
+
registration = await registerMeshProject(token, company.companyUid, projectId, opts.channel);
|
|
411
|
+
}
|
|
412
|
+
if (!current && opts.create) {
|
|
413
|
+
noteCallingSessionBound(view.projectId, company);
|
|
414
|
+
}
|
|
415
|
+
if (opts.json) {
|
|
416
|
+
console.log(JSON.stringify({
|
|
417
|
+
ok: true,
|
|
418
|
+
action: "project.set",
|
|
419
|
+
principalUid,
|
|
420
|
+
...view,
|
|
421
|
+
...(registration ? { registration } : {}),
|
|
422
|
+
}, null, 2));
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
console.log(`Work mesh: project ${view.projectId} set (${view.name}; ${view.stories.length} stories)`);
|
|
426
|
+
}
|
|
427
|
+
async function runProjectRegister(projectId, opts) {
|
|
428
|
+
if (opts.channel !== undefined && !opts.channel.trim()) {
|
|
429
|
+
fail("PROJECT_CHANNEL_INVALID: --channel must be a non-empty channel id.");
|
|
430
|
+
}
|
|
431
|
+
const { token, company } = await withCompany(opts);
|
|
432
|
+
const principalUid = await resolveMeshPrincipalUid(token, loadCachedTokens());
|
|
433
|
+
const companyRef = company.companySlug || company.companyUid;
|
|
434
|
+
try {
|
|
435
|
+
const board = await getProjectView(token, company.companyUid, projectId);
|
|
436
|
+
if (board.companyUid !== company.companyUid || board.projectId !== projectId) {
|
|
437
|
+
fail(`Work mesh project ${projectId} has no Board view in company ${companyRef}. Create the Board before registering it.`);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
catch (err) {
|
|
441
|
+
if (httpStatus(err) === 404) {
|
|
442
|
+
fail(`Work mesh project ${projectId} has no Board view in company ${companyRef}. Create the Board before registering it.`);
|
|
443
|
+
}
|
|
444
|
+
throw err;
|
|
445
|
+
}
|
|
446
|
+
let registration;
|
|
447
|
+
try {
|
|
448
|
+
registration = await registerMeshProject(token, company.companyUid, projectId, opts.channel);
|
|
449
|
+
}
|
|
450
|
+
catch (err) {
|
|
451
|
+
const failure = err;
|
|
452
|
+
if (failure.status === 403 && failure.code === "PROJECT_NOT_IN_COMPANY") {
|
|
453
|
+
fail(`Work mesh project ${projectId} could not be registered in company ${companyRef}: the Board or its genesis thread is missing. Run "hq mesh project ensure ${projectId} --company ${companyRef} --stories-file <prd.json>" to create or restore them.`);
|
|
454
|
+
}
|
|
455
|
+
throw err;
|
|
456
|
+
}
|
|
457
|
+
const boardState = "registered";
|
|
458
|
+
if (opts.json) {
|
|
459
|
+
console.log(JSON.stringify({ ok: true, action: "project.register", principalUid, boardState, ...registration }, null, 2));
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
console.log(`Work mesh: project ${registration.projectId} registered (${boardState}; channel ${registration.channelId} ${registration.channelCreated ? "created" : "bound"})`);
|
|
463
|
+
}
|
|
464
|
+
async function runProjectEnsure(projectId, opts) {
|
|
465
|
+
if (!opts.storiesFile?.trim())
|
|
466
|
+
fail("`--stories-file <prd.json>` is required.");
|
|
467
|
+
const source = parseProjectPlan(readFileSync(opts.storiesFile, "utf8"), opts.storiesFile);
|
|
468
|
+
const { token, company } = await withCompany(opts);
|
|
469
|
+
let current;
|
|
470
|
+
try {
|
|
471
|
+
current = await getProjectView(token, company.companyUid, projectId);
|
|
472
|
+
}
|
|
473
|
+
catch (err) {
|
|
474
|
+
if (httpStatus(err) !== 404)
|
|
475
|
+
throw err;
|
|
476
|
+
}
|
|
477
|
+
if (opts.dryRun) {
|
|
478
|
+
if (current && (current.companyUid !== company.companyUid || current.projectId !== projectId)) {
|
|
479
|
+
fail("Work mesh project ensure dry-run: Board company or project id did not match the request.");
|
|
480
|
+
}
|
|
481
|
+
const stories = current ? mergeProjectStories(current.stories, source.stories) : source.stories;
|
|
482
|
+
const sourceStatuses = source.stories.map((story) => ({
|
|
483
|
+
id: story.id,
|
|
484
|
+
title: story.title,
|
|
485
|
+
status: boardStoryStatus(story),
|
|
486
|
+
}));
|
|
487
|
+
const boardStatuses = stories.map((story) => ({
|
|
488
|
+
id: story.id,
|
|
489
|
+
title: story.title,
|
|
490
|
+
status: boardStoryStatus(story),
|
|
491
|
+
}));
|
|
492
|
+
if (opts.json) {
|
|
493
|
+
console.log(JSON.stringify({
|
|
494
|
+
ok: true,
|
|
495
|
+
action: "project.ensure.dry-run",
|
|
496
|
+
projectId,
|
|
497
|
+
companyUid: company.companyUid,
|
|
498
|
+
sourceStatuses,
|
|
499
|
+
stories: boardStatuses,
|
|
500
|
+
}, null, 2));
|
|
501
|
+
}
|
|
502
|
+
else {
|
|
503
|
+
console.log(`Work mesh: project ${projectId} dry run (${sourceStatuses.length} source stories)`);
|
|
504
|
+
console.log("Source statuses:");
|
|
505
|
+
for (const story of sourceStatuses)
|
|
506
|
+
console.log(`${story.id}\t${story.status}`);
|
|
507
|
+
console.log("Merged Board statuses:");
|
|
508
|
+
for (const story of boardStatuses)
|
|
509
|
+
console.log(`${story.id}\t${story.status}`);
|
|
510
|
+
}
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
// Genesis thread, then the view, then register. Register returns 403
|
|
514
|
+
// PROJECT_NOT_IN_COMPANY until both exist. A missing view uses that chain
|
|
515
|
+
// from ensureProjectBoard; an existing view is merged, then registered.
|
|
516
|
+
let registration;
|
|
517
|
+
let verified;
|
|
518
|
+
if (!current) {
|
|
519
|
+
const ensured = await ensureProjectBoard({
|
|
520
|
+
token,
|
|
521
|
+
company,
|
|
522
|
+
projectId,
|
|
523
|
+
name: source.name || projectId,
|
|
524
|
+
description: source.description ?? "",
|
|
525
|
+
stories: source.stories,
|
|
526
|
+
repos: source.repos ?? [],
|
|
527
|
+
});
|
|
528
|
+
registration = ensured.registration;
|
|
529
|
+
verified = ensured.view;
|
|
530
|
+
}
|
|
531
|
+
else {
|
|
532
|
+
const genesis = await ensureProjectThread(token, company, projectId, {
|
|
533
|
+
summary: source.name || projectId,
|
|
534
|
+
});
|
|
535
|
+
if (!genesis.threadId)
|
|
536
|
+
fail("Work mesh did not return a threadId.");
|
|
537
|
+
{
|
|
538
|
+
const stories = mergeProjectStories(current.stories, source.stories);
|
|
539
|
+
const repos = mergeProjectRepos(current.repos, source.repos ?? []);
|
|
540
|
+
const name = source.name || current.name;
|
|
541
|
+
const description = source.description !== undefined ? source.description : current.description;
|
|
542
|
+
const changed = name !== current.name ||
|
|
543
|
+
description !== current.description ||
|
|
544
|
+
JSON.stringify(stories) !== JSON.stringify(current.stories) ||
|
|
545
|
+
JSON.stringify(repos) !== JSON.stringify(current.repos);
|
|
546
|
+
if (changed) {
|
|
547
|
+
await putProjectView(token, company.companyUid, projectId, {
|
|
548
|
+
name,
|
|
549
|
+
description,
|
|
550
|
+
stories,
|
|
551
|
+
repos,
|
|
552
|
+
...(current.version !== undefined ? { expectedVersion: current.version } : {}),
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
registration = await registerMeshProject(token, company.companyUid, projectId);
|
|
557
|
+
await closeSupersededProjectThread({
|
|
558
|
+
token,
|
|
559
|
+
companyUid: company.companyUid,
|
|
560
|
+
openedThreadId: genesis.threadId,
|
|
561
|
+
canonicalThreadId: registration.threadId,
|
|
562
|
+
created: genesis.created,
|
|
563
|
+
});
|
|
564
|
+
if (!registration.threadId || !registration.channelId) {
|
|
565
|
+
fail("Work mesh registration did not return a threadId and channelId.");
|
|
566
|
+
}
|
|
567
|
+
verified = await getProjectView(token, company.companyUid, projectId);
|
|
568
|
+
}
|
|
569
|
+
if (verified.companyUid !== company.companyUid) {
|
|
570
|
+
fail(`Work mesh project ensure: company mismatch (expected ${company.companyUid}, got ${verified.companyUid}).`);
|
|
571
|
+
}
|
|
572
|
+
if (verified.projectId !== projectId) {
|
|
573
|
+
fail(`Work mesh project ensure: project id mismatch (expected ${projectId}, got ${verified.projectId}).`);
|
|
574
|
+
}
|
|
575
|
+
for (const story of source.stories) {
|
|
576
|
+
if (!verified.stories.some((row) => row.id === story.id)) {
|
|
577
|
+
fail(`Work mesh project ensure: missing story ${story.id}.`);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
for (const repo of source.repos ?? []) {
|
|
581
|
+
if (!verified.repos.some((row) => row.path === repo.path)) {
|
|
582
|
+
fail(`Work mesh project ensure: missing repo ${repo.path}.`);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
if (verified.version === undefined) {
|
|
586
|
+
fail("Work mesh project ensure: verified view has no version.");
|
|
587
|
+
}
|
|
588
|
+
const payload = {
|
|
589
|
+
projectId: verified.projectId,
|
|
590
|
+
threadId: registration.threadId,
|
|
591
|
+
channelId: registration.channelId,
|
|
592
|
+
version: verified.version,
|
|
593
|
+
stories: verified.stories,
|
|
594
|
+
};
|
|
595
|
+
noteCallingSessionBound(payload.projectId, company);
|
|
596
|
+
if (opts.json) {
|
|
597
|
+
console.log(JSON.stringify(payload));
|
|
598
|
+
return;
|
|
599
|
+
}
|
|
600
|
+
console.log(`Work mesh: project ${payload.projectId} ensured (thread ${payload.threadId}, channel ${payload.channelId}, ${payload.stories.length} stories)`);
|
|
601
|
+
}
|
|
602
|
+
async function runPrdSync(opts) {
|
|
603
|
+
const sessionId = opts.session.trim();
|
|
604
|
+
const file = opts.file.trim();
|
|
605
|
+
if (!sessionId || !file)
|
|
606
|
+
fail("Usage: hq mesh context prd-sync --session <sid> --file <prd.json>");
|
|
607
|
+
const root = workContextHomeRoot();
|
|
608
|
+
const plan = planPrdSync({ sessionId, file, root });
|
|
609
|
+
if (plan.rebindTo) {
|
|
610
|
+
rebindSessionToProject({ sessionId, root, projectId: plan.rebindTo });
|
|
611
|
+
}
|
|
612
|
+
if (!plan.changed) {
|
|
613
|
+
const payload = { ok: true, action: "context.prd-sync", changed: 0, ...(plan.skip ? { skip: plan.skip } : {}) };
|
|
614
|
+
if (opts.json)
|
|
615
|
+
console.log(JSON.stringify(payload));
|
|
616
|
+
else
|
|
617
|
+
console.log(plan.skip ? `Work mesh: prd-sync skipped (${plan.skip})` : "Work mesh: prd-sync unchanged");
|
|
618
|
+
return;
|
|
619
|
+
}
|
|
620
|
+
let token;
|
|
621
|
+
try {
|
|
622
|
+
token = await requireToken();
|
|
623
|
+
}
|
|
624
|
+
catch {
|
|
625
|
+
token = null;
|
|
626
|
+
}
|
|
627
|
+
if (!token) {
|
|
628
|
+
console.error("work-mesh: prd-sync has changes but no token; snapshot not advanced");
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
631
|
+
// Attribution evidence: without company and project the server files these
|
|
632
|
+
// as unassigned and the Board never moves. After a same-company switch,
|
|
633
|
+
// this is the new project's id so ingest writes SESSION_STATE.projectId
|
|
634
|
+
// and bound-forward posts the channel line there.
|
|
635
|
+
const bound = readSessionState(sessionId, root);
|
|
636
|
+
const evidenceBase = {
|
|
637
|
+
...(bound?.companySlug ? { companySlug: bound.companySlug } : {}),
|
|
638
|
+
...(bound?.projectId ? { project: bound.projectId } : {}),
|
|
639
|
+
touchedPaths: [resolvePath(file)],
|
|
640
|
+
};
|
|
641
|
+
let toEmit = plan.events;
|
|
642
|
+
if (bound?.companyUid && bound.projectId) {
|
|
643
|
+
try {
|
|
644
|
+
const live = await getProjectView(token, bound.companyUid, bound.projectId);
|
|
645
|
+
toEmit = prdSyncEventsThatChangeBoard(plan.events, live.stories);
|
|
646
|
+
}
|
|
647
|
+
catch {
|
|
648
|
+
// Board unread — emit the snapshot diff; the server drops same-status.
|
|
649
|
+
}
|
|
650
|
+
if (toEmit.length === 0) {
|
|
651
|
+
plan.commit();
|
|
652
|
+
if (opts.json) {
|
|
653
|
+
console.log(JSON.stringify({ ok: true, action: "context.prd-sync", changed: 0 }));
|
|
654
|
+
}
|
|
655
|
+
else {
|
|
656
|
+
console.log("Work mesh: prd-sync unchanged");
|
|
657
|
+
}
|
|
658
|
+
return;
|
|
659
|
+
}
|
|
660
|
+
try {
|
|
661
|
+
const source = parseProjectPlan(readFileSync(file, "utf8"), file);
|
|
662
|
+
await ensureMissingBoardStories({
|
|
663
|
+
token,
|
|
664
|
+
company: {
|
|
665
|
+
companyUid: bound.companyUid,
|
|
666
|
+
companySlug: bound.companySlug || bound.companyUid,
|
|
667
|
+
},
|
|
668
|
+
projectId: bound.projectId,
|
|
669
|
+
name: source.name || bound.projectId,
|
|
670
|
+
description: source.description ?? "",
|
|
671
|
+
stories: source.stories,
|
|
672
|
+
repos: source.repos ?? [],
|
|
673
|
+
requiredIds: toEmit.map((event) => event.taskId),
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
catch (err) {
|
|
677
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
678
|
+
console.error(`work-mesh: prd-sync ensure failed; emitting anyway (${reason.slice(0, 160)})`);
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
const alreadyOnBoard = plan.events
|
|
682
|
+
.filter((event) => !toEmit.some((row) => row.taskId === event.taskId))
|
|
683
|
+
.map((event) => event.taskId);
|
|
684
|
+
const meshRoot = workMeshHomeRoot();
|
|
685
|
+
const seqFirst = reserveSessionSeq(sessionId, toEmit.length);
|
|
686
|
+
const events = toEmit.map((event, index) => buildMeshEmitEvent({
|
|
687
|
+
eventId: generateUlid(Date.now() + index),
|
|
688
|
+
kind: "task_status",
|
|
689
|
+
sessionId,
|
|
690
|
+
harness: "hq-sessions",
|
|
691
|
+
adapterVersion: "1.0.0",
|
|
692
|
+
at: new Date().toISOString(),
|
|
693
|
+
seq: seqFirst + index,
|
|
694
|
+
source: "hooks",
|
|
695
|
+
taskId: event.taskId,
|
|
696
|
+
status: event.status,
|
|
697
|
+
summary: event.status === "done"
|
|
698
|
+
? `${event.taskId} passes`
|
|
699
|
+
: event.status === "in_progress"
|
|
700
|
+
? `${event.taskId} in progress`
|
|
701
|
+
: `${event.taskId} in review`,
|
|
702
|
+
evidence: { ...evidenceBase, task: event.taskId },
|
|
703
|
+
}));
|
|
704
|
+
const poster = createEmitPoster({ token, baseUrl: resolveVaultApiBase(process.env) });
|
|
705
|
+
const emitted = await emitEvents({
|
|
706
|
+
workMeshRoot: meshRoot,
|
|
707
|
+
poster,
|
|
708
|
+
newEvents: events,
|
|
709
|
+
});
|
|
710
|
+
if (emitted.unassigned > 0 || emitted.rejected > 0) {
|
|
711
|
+
console.error(`work-mesh: prd-sync sent ${events.length}; unassigned=${emitted.unassigned} rejected=${emitted.rejected}`);
|
|
712
|
+
for (const line of formatEmitRejectionLines(emitted.rejections))
|
|
713
|
+
console.error(line);
|
|
714
|
+
}
|
|
715
|
+
const blocked = new Set(emitted.rejections.map((row) => row.eventId));
|
|
716
|
+
for (const pending of readEmitRetry(meshRoot)) {
|
|
717
|
+
const id = typeof pending.eventId === "string" ? pending.eventId : "";
|
|
718
|
+
if (id)
|
|
719
|
+
blocked.add(id);
|
|
720
|
+
}
|
|
721
|
+
const advanced = events.flatMap((event) => (event.eventId && event.taskId && !blocked.has(event.eventId) ? [event.taskId] : []));
|
|
722
|
+
plan.commit([...alreadyOnBoard, ...advanced]);
|
|
723
|
+
if (plan.taskId && advanced.includes(plan.taskId)) {
|
|
724
|
+
updateSessionState(sessionId, root, (current) => {
|
|
725
|
+
if (!current)
|
|
726
|
+
return null;
|
|
727
|
+
return {
|
|
728
|
+
...current,
|
|
729
|
+
taskId: plan.taskId,
|
|
730
|
+
contextStatus: current.projectId ? "bound" : current.contextStatus,
|
|
731
|
+
updatedAt: new Date().toISOString(),
|
|
732
|
+
};
|
|
733
|
+
});
|
|
734
|
+
}
|
|
735
|
+
if (opts.json) {
|
|
736
|
+
console.log(JSON.stringify({ ok: true, action: "context.prd-sync", changed: toEmit.length, taskId: plan.taskId }));
|
|
737
|
+
return;
|
|
738
|
+
}
|
|
739
|
+
console.log(`Work mesh: prd-sync emitted ${toEmit.length} task_status`);
|
|
740
|
+
}
|
|
741
|
+
function noteCallingSessionBound(projectId, company) {
|
|
742
|
+
try {
|
|
743
|
+
const bound = bindCallingSession({
|
|
744
|
+
root: workContextHomeRoot(),
|
|
745
|
+
projectId,
|
|
746
|
+
company,
|
|
747
|
+
});
|
|
748
|
+
if (bound.bound)
|
|
749
|
+
console.error(formatSessionBoundLine(bound.sessionId, bound.projectId));
|
|
750
|
+
}
|
|
751
|
+
catch {
|
|
752
|
+
/* session bind is local and must not fail project ensure */
|
|
753
|
+
}
|
|
123
754
|
}
|
|
124
755
|
async function runDoctor(opts) {
|
|
125
756
|
if (opts.apply) {
|
|
126
757
|
fail("`hq mesh doctor --apply` (paced Board PUTs from local prd.json) is not in the CLI yet.\n" +
|
|
127
758
|
"Omit --apply to warm the conversation cache (directory, inbox, pair DMs).");
|
|
128
759
|
}
|
|
760
|
+
const identity = collectDaemonDoctor();
|
|
761
|
+
const identityLines = formatCliIdentityLines(identity);
|
|
762
|
+
if (!opts.json) {
|
|
763
|
+
for (const line of identityLines)
|
|
764
|
+
console.log(line);
|
|
765
|
+
}
|
|
129
766
|
const token = await requireToken();
|
|
130
767
|
const principalUid = await resolveMeshPrincipalUid(token, loadCachedTokens());
|
|
768
|
+
if (!principalUid) {
|
|
769
|
+
fail("Could not resolve the authenticated principal. Sign in again and retry `hq mesh doctor`.");
|
|
770
|
+
}
|
|
131
771
|
const warmed = await warmMeshConversationCache(token, principalUid);
|
|
772
|
+
const needsProject = listNeedsProjectSessions(workContextHomeRoot());
|
|
132
773
|
if (opts.json) {
|
|
133
|
-
console.log(JSON.stringify({
|
|
774
|
+
console.log(JSON.stringify({
|
|
775
|
+
ok: true,
|
|
776
|
+
action: "doctor",
|
|
777
|
+
...warmed,
|
|
778
|
+
needsProject,
|
|
779
|
+
cliMismatchLine: identity.cliMismatchLine ?? null,
|
|
780
|
+
hqOnPath: identity.hqOnPath,
|
|
781
|
+
multipleHqOnPath: identity.multipleHqOnPath,
|
|
782
|
+
}, null, 2));
|
|
134
783
|
return;
|
|
135
784
|
}
|
|
136
785
|
console.log(`Work mesh cache warmed at ${warmed.cacheRoot}` +
|
|
137
786
|
` (directory=${warmed.directory} inbox=${warmed.inbox}` +
|
|
138
787
|
` contacts=${warmed.contacts} pair-threads=${warmed.threads})`);
|
|
788
|
+
if (needsProject.length === 0) {
|
|
789
|
+
console.log("needs_project sessions: none");
|
|
790
|
+
return;
|
|
791
|
+
}
|
|
792
|
+
console.log(`needs_project sessions: ${needsProject.length}`);
|
|
793
|
+
for (const row of needsProject) {
|
|
794
|
+
const choices = row.candidates.map((candidate) => candidate.projectId).join(", ") || "(none)";
|
|
795
|
+
console.log(`- ${row.sessionId}: ${row.reason ?? "no reason recorded"}; candidates: ${choices}`);
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
async function runBindProject(target, opts) {
|
|
799
|
+
const sessionId = opts.session.trim();
|
|
800
|
+
const root = workContextHomeRoot();
|
|
801
|
+
const current = readSessionState(sessionId, root);
|
|
802
|
+
if (!current)
|
|
803
|
+
fail(`No work-context state for session ${sessionId}.`);
|
|
804
|
+
let projectId = target.trim();
|
|
805
|
+
if (projectId === "new") {
|
|
806
|
+
const slug = opts.slug?.trim();
|
|
807
|
+
if (!slug)
|
|
808
|
+
fail("Usage: hq mesh context bind-project new <slug> --session <sid>");
|
|
809
|
+
const hqRoot = process.env.HQ_ROOT?.trim() || findHqRoot();
|
|
810
|
+
const prdPath = findLocalPrd(hqRoot, current.companySlug, slug);
|
|
811
|
+
if (!prdPath) {
|
|
812
|
+
fail(`No PRD for ${slug}. Run /prd before binding a new project.`);
|
|
813
|
+
}
|
|
814
|
+
if (!current.companyUid)
|
|
815
|
+
fail(`Session ${sessionId} has no company. Bind a company first.`);
|
|
816
|
+
const { token, company } = await withCompany({ company: opts.company ?? current.companySlug });
|
|
817
|
+
const plan = parseProjectPlan(readFileSync(prdPath, "utf8"), prdPath);
|
|
818
|
+
await ensureProjectBoard({
|
|
819
|
+
token,
|
|
820
|
+
company: {
|
|
821
|
+
companyUid: current.companyUid,
|
|
822
|
+
companySlug: current.companySlug || company.companySlug,
|
|
823
|
+
},
|
|
824
|
+
projectId: slug,
|
|
825
|
+
name: plan.name || slug,
|
|
826
|
+
description: plan.description ?? "",
|
|
827
|
+
stories: plan.stories,
|
|
828
|
+
repos: plan.repos ?? [],
|
|
829
|
+
});
|
|
830
|
+
projectId = slug;
|
|
831
|
+
}
|
|
832
|
+
else if (/^[1-9][0-9]*$/.test(projectId)) {
|
|
833
|
+
const index = Number(projectId) - 1;
|
|
834
|
+
const chosen = current.projectCandidates?.[index];
|
|
835
|
+
if (!chosen)
|
|
836
|
+
fail(`No candidate ${projectId} on session ${sessionId}.`);
|
|
837
|
+
projectId = chosen.projectId;
|
|
838
|
+
}
|
|
839
|
+
const updated = updateSessionState(sessionId, root, (state) => state ? applyOperatorProjectBinding(state, projectId) : null);
|
|
840
|
+
if (!updated)
|
|
841
|
+
fail(`No work-context state for session ${sessionId}.`);
|
|
842
|
+
if (opts.json) {
|
|
843
|
+
console.log(JSON.stringify({ ok: true, action: "context.bind-project", sessionId, projectId, contextStatus: updated.contextStatus }));
|
|
844
|
+
return;
|
|
845
|
+
}
|
|
846
|
+
console.log(`Work mesh: session ${sessionId} bound to project ${projectId}`);
|
|
139
847
|
}
|
|
140
848
|
async function runContextReconcile(opts) {
|
|
141
849
|
if (!opts.observationFile && !opts.observationJson) {
|
|
@@ -152,25 +860,92 @@ async function runContextReconcile(opts) {
|
|
|
152
860
|
let fetchCandidates;
|
|
153
861
|
let validateMembership;
|
|
154
862
|
let offline = Boolean(opts.offline);
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
863
|
+
let token;
|
|
864
|
+
try {
|
|
865
|
+
if (offline) {
|
|
866
|
+
if (isMachineIdentity()) {
|
|
867
|
+
token = await ensureCognitoToken({ tokenSource: "machine", interactive: false });
|
|
868
|
+
}
|
|
869
|
+
else {
|
|
870
|
+
const cached = loadCachedTokens();
|
|
871
|
+
if (cached && !isExpiring(cached, 120)) {
|
|
872
|
+
token = cached.accessToken;
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
else {
|
|
877
|
+
token = await requireToken();
|
|
878
|
+
}
|
|
879
|
+
if (token) {
|
|
880
|
+
const sessionToken = token;
|
|
881
|
+
const membershipValidationTimeoutMs = offline
|
|
882
|
+
? OFFLINE_MEMBERSHIP_VALIDATION_TIMEOUT_MS
|
|
883
|
+
: ONLINE_MEMBERSHIP_VALIDATION_TIMEOUT_MS;
|
|
160
884
|
validateMembership = async (candidate) => {
|
|
161
|
-
const membership = await
|
|
162
|
-
|
|
885
|
+
const membership = await new Promise((resolve, reject) => {
|
|
886
|
+
const timer = setTimeout(() => reject(new Error("membership validation timed out")), membershipValidationTimeoutMs);
|
|
887
|
+
void resolveActiveMembershipCompany(sessionToken, candidate).then((value) => {
|
|
888
|
+
clearTimeout(timer);
|
|
889
|
+
resolve(value);
|
|
890
|
+
}, (error) => {
|
|
891
|
+
clearTimeout(timer);
|
|
892
|
+
reject(error);
|
|
893
|
+
});
|
|
894
|
+
});
|
|
895
|
+
if (!membership || typeof membership.companyUid !== "string" || !membership.companyUid) {
|
|
163
896
|
return false;
|
|
897
|
+
}
|
|
164
898
|
return { uid: membership.companyUid };
|
|
165
899
|
};
|
|
900
|
+
if (!offline) {
|
|
901
|
+
deliver = createWorkSessionDeliverer({ token: sessionToken });
|
|
902
|
+
fetchCandidates = createCandidatesFetcher({ token: sessionToken });
|
|
903
|
+
}
|
|
166
904
|
}
|
|
167
|
-
|
|
905
|
+
}
|
|
906
|
+
catch {
|
|
907
|
+
if (!offline) {
|
|
168
908
|
offline = true;
|
|
169
909
|
if (!opts.machine) {
|
|
170
910
|
console.error(chalk.yellow("No Cognito session; reconciling offline (outbox only)."));
|
|
171
911
|
}
|
|
172
912
|
}
|
|
173
913
|
}
|
|
914
|
+
if (token) {
|
|
915
|
+
const activation = await ensureDefaultCompany({
|
|
916
|
+
root,
|
|
917
|
+
listMemberships: () => listActiveMembershipCompanies(token),
|
|
918
|
+
log: (message) => console.error(chalk.dim(message)),
|
|
919
|
+
});
|
|
920
|
+
if (activation.status === "needs_choice") {
|
|
921
|
+
const interactive = !offline &&
|
|
922
|
+
!opts.machine &&
|
|
923
|
+
Boolean(process.stdin.isTTY && process.stdout.isTTY) &&
|
|
924
|
+
!isMachineIdentity();
|
|
925
|
+
if (interactive) {
|
|
926
|
+
const choices = activation.memberships
|
|
927
|
+
.map((membership, index) => `${index + 1}. ${membership.slug}`)
|
|
928
|
+
.join("\n");
|
|
929
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
|
|
930
|
+
try {
|
|
931
|
+
const answer = await rl.question(`Choose this device's default company:\n${choices}\nSelection: `);
|
|
932
|
+
const selected = activation.memberships[Number.parseInt(answer, 10) - 1];
|
|
933
|
+
if (selected) {
|
|
934
|
+
await setDefaultCompany(selected.slug, {
|
|
935
|
+
root,
|
|
936
|
+
validateMembership: (candidate) => candidate === selected.slug ? { uid: selected.uid } : false,
|
|
937
|
+
});
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
finally {
|
|
941
|
+
rl.close();
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
else if (!offline && !opts.machine) {
|
|
945
|
+
console.error(chalk.yellow("Multiple active memberships. Run `hq mesh context default set <slug>` to choose this device's default company."));
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
}
|
|
174
949
|
const outcome = await reconcileObservation(obs, {
|
|
175
950
|
root,
|
|
176
951
|
env: process.env,
|
|
@@ -178,6 +953,20 @@ async function runContextReconcile(opts) {
|
|
|
178
953
|
fetchCandidates,
|
|
179
954
|
offline,
|
|
180
955
|
validateMembership,
|
|
956
|
+
ensureProjectBoard: token
|
|
957
|
+
? async ({ companyUid, projectId, prdPath }) => {
|
|
958
|
+
const plan = parseProjectPlan(readFileSync(prdPath, "utf8"), prdPath);
|
|
959
|
+
await ensureProjectBoard({
|
|
960
|
+
token,
|
|
961
|
+
company: { companyUid, companySlug: companyUid },
|
|
962
|
+
projectId,
|
|
963
|
+
name: plan.name || projectId,
|
|
964
|
+
description: plan.description ?? "",
|
|
965
|
+
stories: plan.stories,
|
|
966
|
+
repos: plan.repos ?? [],
|
|
967
|
+
});
|
|
968
|
+
}
|
|
969
|
+
: undefined,
|
|
181
970
|
});
|
|
182
971
|
for (const line of outcome.diagnostics) {
|
|
183
972
|
console.error(line);
|
|
@@ -294,19 +1083,21 @@ async function runContextBackfillHeld(opts) {
|
|
|
294
1083
|
const parsedLimit = opts.limit ? Number.parseInt(opts.limit, 10) : 0;
|
|
295
1084
|
const limit = Number.isFinite(parsedLimit) && parsedLimit > 0 ? parsedLimit : 0;
|
|
296
1085
|
const companyHint = opts.company?.trim() || undefined;
|
|
297
|
-
|
|
298
|
-
//
|
|
299
|
-
//
|
|
300
|
-
//
|
|
1086
|
+
const useDeviceDefault = opts.useDeviceDefault === true || readDeviceConfig({ root }).repairHeldWithDefault === true;
|
|
1087
|
+
// Build the membership seam for both modes; dry-run is read-only but must
|
|
1088
|
+
// validate a locally resolved slug just as live reconciliation does.
|
|
1089
|
+
// The remaining seams are captured in the reconcile closure below.
|
|
301
1090
|
let deliver;
|
|
302
1091
|
let fetchCandidates;
|
|
303
1092
|
let validateMembership;
|
|
304
1093
|
let offline = Boolean(opts.offline);
|
|
305
|
-
if (!
|
|
1094
|
+
if (!offline) {
|
|
306
1095
|
try {
|
|
307
1096
|
const token = await requireToken();
|
|
308
|
-
|
|
309
|
-
|
|
1097
|
+
if (!dryRun) {
|
|
1098
|
+
deliver = createWorkSessionDeliverer({ token });
|
|
1099
|
+
fetchCandidates = createCandidatesFetcher({ token });
|
|
1100
|
+
}
|
|
310
1101
|
validateMembership = async (candidate) => {
|
|
311
1102
|
const membership = await resolveActiveMembershipCompany(token, candidate);
|
|
312
1103
|
if (!membership)
|
|
@@ -324,11 +1115,14 @@ async function runContextBackfillHeld(opts) {
|
|
|
324
1115
|
const result = await backfillHeldSessions({
|
|
325
1116
|
workMeshRoot: meshRoot,
|
|
326
1117
|
workContextRoot: root,
|
|
1118
|
+
hqRoot: process.env.HQ_ROOT?.trim() || findHqRoot(),
|
|
327
1119
|
dryRun,
|
|
328
1120
|
limit,
|
|
329
1121
|
// Mirror the reconcile closure's non-forcing hint in the dry-run predictor
|
|
330
1122
|
// so `--dry-run` and the real run report the same counts.
|
|
331
1123
|
remoteOwnerHint: companyHint || undefined,
|
|
1124
|
+
useDeviceDefault,
|
|
1125
|
+
validateMembership,
|
|
332
1126
|
reconcile: (obs) => reconcileObservation(
|
|
333
1127
|
// Pass --company as a non-forcing hint (remoteOwnerSlug feeds
|
|
334
1128
|
// deterministic resolution BELOW the identity-file / device default,
|
|
@@ -340,6 +1134,8 @@ async function runContextBackfillHeld(opts) {
|
|
|
340
1134
|
fetchCandidates,
|
|
341
1135
|
offline,
|
|
342
1136
|
validateMembership,
|
|
1137
|
+
allowDeviceDefault: useDeviceDefault,
|
|
1138
|
+
deviceDefaultConfidence: useDeviceDefault,
|
|
343
1139
|
}),
|
|
344
1140
|
});
|
|
345
1141
|
if (opts.json) {
|
|
@@ -354,6 +1150,9 @@ async function runContextBackfillHeld(opts) {
|
|
|
354
1150
|
`${result.unresolved} unresolved, ` +
|
|
355
1151
|
`${result.errors} error(s).` +
|
|
356
1152
|
(dryRun ? " (dry-run: nothing written)" : ""));
|
|
1153
|
+
for (const { sessionId, reason } of result.unresolvedReasons) {
|
|
1154
|
+
console.log(`Unresolved ${sessionId}: ${reason}`);
|
|
1155
|
+
}
|
|
357
1156
|
if (!dryRun && result.reconciled > 0) {
|
|
358
1157
|
console.log("Reconciled session state files were rewritten with a resolved company; " +
|
|
359
1158
|
"the mesh daemon's held retry will re-attribute and post those events.");
|
|
@@ -362,20 +1161,38 @@ async function runContextBackfillHeld(opts) {
|
|
|
362
1161
|
async function runContextDefaultGet(opts) {
|
|
363
1162
|
const root = workContextHomeRoot();
|
|
364
1163
|
const cfg = readDeviceConfig({ root });
|
|
365
|
-
const current =
|
|
1164
|
+
const current = cfg.defaultCompany?.enabled && cfg.defaultCompany.slug
|
|
1165
|
+
? cfg.defaultCompany
|
|
1166
|
+
: null;
|
|
1167
|
+
const memberships = cfg.defaultCompanyMemberships?.memberships ?? [];
|
|
1168
|
+
const disabled = isDefaultCompanyDisabled({ root });
|
|
1169
|
+
const source = disabled ? "disabled" : current?.source ?? (current ? "chosen" : "unset");
|
|
366
1170
|
if (opts.json) {
|
|
367
|
-
console.log(JSON.stringify({
|
|
1171
|
+
console.log(JSON.stringify({
|
|
1172
|
+
ok: true,
|
|
1173
|
+
slug: current?.slug ?? null,
|
|
1174
|
+
uid: current?.uid ?? null,
|
|
1175
|
+
enabled: current?.enabled ?? false,
|
|
1176
|
+
source,
|
|
1177
|
+
needsChoice: !current && !disabled && memberships.length > 1,
|
|
1178
|
+
memberships,
|
|
1179
|
+
repairHeldWithDefault: cfg.repairHeldWithDefault === true,
|
|
1180
|
+
}, null, 2));
|
|
1181
|
+
return;
|
|
1182
|
+
}
|
|
1183
|
+
if (disabled) {
|
|
1184
|
+
console.log("Default company disabled on this device.");
|
|
368
1185
|
return;
|
|
369
1186
|
}
|
|
370
1187
|
if (!current) {
|
|
371
1188
|
console.log("No device default company (default-company mode may be dark).");
|
|
372
1189
|
return;
|
|
373
1190
|
}
|
|
374
|
-
console.log(`Default company: ${current.slug}${current.uid ? ` (${current.uid})` : ""} enabled=${current.enabled}`);
|
|
1191
|
+
console.log(`Default company: ${current.slug}${current.uid ? ` (${current.uid})` : ""} enabled=${current.enabled} source=${source}`);
|
|
375
1192
|
}
|
|
376
1193
|
async function runContextDefaultSet(slug, opts) {
|
|
377
1194
|
const root = workContextHomeRoot();
|
|
378
|
-
void opts.company; // retained for CLI compatibility
|
|
1195
|
+
void opts.company; // retained for CLI compatibility
|
|
379
1196
|
let token;
|
|
380
1197
|
try {
|
|
381
1198
|
token = await requireToken();
|
|
@@ -383,42 +1200,38 @@ async function runContextDefaultSet(slug, opts) {
|
|
|
383
1200
|
catch {
|
|
384
1201
|
token = undefined;
|
|
385
1202
|
}
|
|
386
|
-
//
|
|
1203
|
+
// Migration remains useful diagnostic context, but it must never prevent a
|
|
1204
|
+
// verified member from choosing their own device-local preference.
|
|
387
1205
|
let migrationCapability = false;
|
|
1206
|
+
let migrationWarning;
|
|
388
1207
|
if (token) {
|
|
389
1208
|
const probe = await probeMigrationCapabilityForMemberships(token);
|
|
390
1209
|
recordMigrationCapabilitySnapshot(probe, { root });
|
|
391
1210
|
migrationCapability = probe.unlocked;
|
|
392
|
-
if (probe.offline
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
return;
|
|
1211
|
+
if (probe.offline) {
|
|
1212
|
+
migrationWarning =
|
|
1213
|
+
"Warning: migration capability could not be checked; membership for the selected company will still be verified.";
|
|
396
1214
|
}
|
|
397
|
-
if (!probe.unlocked
|
|
1215
|
+
else if (!probe.unlocked) {
|
|
398
1216
|
const detail = probe.companies.length === 0
|
|
399
1217
|
? "no active memberships"
|
|
400
1218
|
: probe.companies
|
|
401
1219
|
.filter((c) => !c.migration)
|
|
402
1220
|
.map((c) => c.companySlug || c.companyUid)
|
|
403
1221
|
.join(", ");
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
1222
|
+
migrationWarning =
|
|
1223
|
+
`Warning: migration capability is mixed or unavailable for ${detail || "some memberships"}; ` +
|
|
1224
|
+
"the selected company can still be set because membership is verified directly.";
|
|
407
1225
|
}
|
|
408
1226
|
}
|
|
409
|
-
else
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
return;
|
|
413
|
-
}
|
|
414
|
-
if (!migrationCapability && opts.allowWithoutMigration) {
|
|
415
|
-
console.error(chalk.yellow("Warning: --allow-without-migration bypasses DEFAULT_COMPANY_LOCKED; a wrong default is hard to correct until migration is available for every company you belong to."));
|
|
1227
|
+
else {
|
|
1228
|
+
migrationWarning =
|
|
1229
|
+
"Warning: migration capability could not be checked without a Cognito session; membership for the selected company must still be verified.";
|
|
416
1230
|
}
|
|
417
1231
|
try {
|
|
418
1232
|
const cfg = await setDefaultCompany(slug, {
|
|
419
1233
|
root,
|
|
420
1234
|
migrationCapability,
|
|
421
|
-
allowWithoutMigration: opts.allowWithoutMigration,
|
|
422
1235
|
validateMembership: async (candidate) => {
|
|
423
1236
|
if (!token) {
|
|
424
1237
|
throw new DefaultCompanyUnavailableError(`Cannot verify membership for company "${candidate}" (no Cognito session; offline or not logged in)`);
|
|
@@ -436,16 +1249,20 @@ async function runContextDefaultSet(slug, opts) {
|
|
|
436
1249
|
return { uid: membership.companyUid };
|
|
437
1250
|
},
|
|
438
1251
|
});
|
|
1252
|
+
const configured = opts.repairHeldWithDefault
|
|
1253
|
+
? setRepairHeldWithDefault(true, { root })
|
|
1254
|
+
: cfg;
|
|
439
1255
|
if (opts.json) {
|
|
440
|
-
console.log(JSON.stringify({ ok: true, config:
|
|
1256
|
+
console.log(JSON.stringify({ ok: true, config: configured, migrationWarning }, null, 2));
|
|
441
1257
|
return;
|
|
442
1258
|
}
|
|
443
|
-
const stored =
|
|
1259
|
+
const stored = configured.defaultCompany;
|
|
444
1260
|
console.log(`Default company set to ${stored?.slug ?? slug}${stored?.uid ? ` (${stored.uid})` : ""}`);
|
|
1261
|
+
if (migrationWarning)
|
|
1262
|
+
console.error(chalk.yellow(migrationWarning));
|
|
445
1263
|
}
|
|
446
1264
|
catch (err) {
|
|
447
|
-
if (err instanceof
|
|
448
|
-
err instanceof DefaultCompanyUnavailableError) {
|
|
1265
|
+
if (err instanceof DefaultCompanyUnavailableError) {
|
|
449
1266
|
console.error(chalk.red(`${err.code}: ${err.message}`));
|
|
450
1267
|
process.exitCode = 1;
|
|
451
1268
|
return;
|
|
@@ -715,13 +1532,16 @@ async function runSessionStatus(opts) {
|
|
|
715
1532
|
}
|
|
716
1533
|
const { token, company } = await withCompany({ company: opts.company });
|
|
717
1534
|
const live = await fetchCompanyLive(token, company.companyUid);
|
|
1535
|
+
const unattributedEvents = collectDaemonDoctor().unattributedEvents;
|
|
718
1536
|
if (opts.json) {
|
|
719
|
-
console.log(JSON.stringify({ ok: true, action: "session-status", company, live }, null, 2));
|
|
1537
|
+
console.log(JSON.stringify({ ok: true, action: "session-status", company, live, unattributedEvents }, null, 2));
|
|
720
1538
|
return;
|
|
721
1539
|
}
|
|
722
1540
|
for (const line of formatCompanyLiveTable(live, company.companySlug || company.companyUid)) {
|
|
723
1541
|
console.log(line);
|
|
724
1542
|
}
|
|
1543
|
+
console.log(`unattributed events: ${unattributedEvents.total} ` +
|
|
1544
|
+
`(spool=${unattributedEvents.spool} held=${unattributedEvents.held} dead-letter=${unattributedEvents.deadLetter})`);
|
|
725
1545
|
}
|
|
726
1546
|
const HARNESSES = new Set([
|
|
727
1547
|
"claude-code",
|
|
@@ -754,6 +1574,21 @@ async function runSessionEnqueue(cliKind, opts) {
|
|
|
754
1574
|
const sessionId = resolveEnqueueSessionId(opts.sessionId, process.env);
|
|
755
1575
|
if (!sessionId)
|
|
756
1576
|
fail("sessionId required (--session-id or HQ_SESSION_ID)");
|
|
1577
|
+
if (kind === "turn_start") {
|
|
1578
|
+
try {
|
|
1579
|
+
rebindNeedsProjectOnPrompt({
|
|
1580
|
+
sessionId,
|
|
1581
|
+
root: workContextHomeRoot(),
|
|
1582
|
+
hqRoot: opts.hqRoot?.trim() || process.env.HQ_ROOT,
|
|
1583
|
+
cwd: opts.cwd,
|
|
1584
|
+
companySlug: opts.companySlug,
|
|
1585
|
+
env: process.env,
|
|
1586
|
+
});
|
|
1587
|
+
}
|
|
1588
|
+
catch {
|
|
1589
|
+
/* prompt rebind is fail-soft */
|
|
1590
|
+
}
|
|
1591
|
+
}
|
|
757
1592
|
const evidence = buildEmitEvidence({
|
|
758
1593
|
sessionId: sessionId,
|
|
759
1594
|
hqRoot: opts.hqRoot,
|
|
@@ -763,7 +1598,16 @@ async function runSessionEnqueue(cliKind, opts) {
|
|
|
763
1598
|
companySlug: opts.companySlug,
|
|
764
1599
|
project: opts.project,
|
|
765
1600
|
task: opts.task,
|
|
1601
|
+
env: process.env,
|
|
766
1602
|
});
|
|
1603
|
+
const reportFields = kind === "session_end"
|
|
1604
|
+
? enrichSessionEndEvent({
|
|
1605
|
+
kind,
|
|
1606
|
+
sessionId: sessionId,
|
|
1607
|
+
cwd: opts.cwd,
|
|
1608
|
+
summary: opts.summary,
|
|
1609
|
+
})
|
|
1610
|
+
: {};
|
|
767
1611
|
const event = buildMeshEmitEvent({
|
|
768
1612
|
eventId: opts.eventId?.trim() || generateUlid(Date.now()),
|
|
769
1613
|
kind: kind,
|
|
@@ -777,10 +1621,35 @@ async function runSessionEnqueue(cliKind, opts) {
|
|
|
777
1621
|
taskId: opts.taskId,
|
|
778
1622
|
status: opts.status,
|
|
779
1623
|
reason: opts.reason,
|
|
780
|
-
summary: opts.summary
|
|
1624
|
+
summary: opts.summary ||
|
|
1625
|
+
(typeof reportFields.summary === "string" ? reportFields.summary : undefined),
|
|
1626
|
+
repo: typeof reportFields.repo === "string" ? reportFields.repo : undefined,
|
|
1627
|
+
gitBranch: typeof reportFields.gitBranch === "string"
|
|
1628
|
+
? reportFields.gitBranch
|
|
1629
|
+
: undefined,
|
|
1630
|
+
prUrls: Array.isArray(reportFields.prUrls)
|
|
1631
|
+
? reportFields.prUrls
|
|
1632
|
+
: undefined,
|
|
781
1633
|
evidence,
|
|
782
1634
|
});
|
|
783
1635
|
const meshRoot = workMeshHomeRoot();
|
|
1636
|
+
// A machine credential with no company must not be posted. The server files
|
|
1637
|
+
// that as company NONE. Hold it and say why.
|
|
1638
|
+
if (machineEmitDisposition({ machine: isMachineIdentity(), companySlug: evidence.companySlug }) === "hold") {
|
|
1639
|
+
appendHeldLine(JSON.stringify({
|
|
1640
|
+
event,
|
|
1641
|
+
heldReason: "NEEDS_COMPANY",
|
|
1642
|
+
heldAt: new Date().toISOString(),
|
|
1643
|
+
reason: "machine session has no company; event was not sent",
|
|
1644
|
+
}), meshRoot);
|
|
1645
|
+
const heldMessage = `work-mesh: held ${kind}; needs_company (machine session has no company; not sent)`;
|
|
1646
|
+
if (opts.json) {
|
|
1647
|
+
console.log(JSON.stringify({ ok: true, action: "emit", kind, held: true, reason: "needs_company" }, null, 2));
|
|
1648
|
+
return;
|
|
1649
|
+
}
|
|
1650
|
+
console.error(heldMessage);
|
|
1651
|
+
return;
|
|
1652
|
+
}
|
|
784
1653
|
// Resolve a token non-interactively (same path as every CLI call). If the box
|
|
785
1654
|
// is not logged in, retain the event locally for the next invocation to drain.
|
|
786
1655
|
let token;
|
|
@@ -816,6 +1685,9 @@ async function runSessionEnqueue(cliKind, opts) {
|
|
|
816
1685
|
console.error(`work-mesh: emit ${kind} accepted=${summary.accepted}` +
|
|
817
1686
|
` unassigned=${summary.unassigned} rejected=${summary.rejected}` +
|
|
818
1687
|
` retryDepth=${summary.retryDepth}`);
|
|
1688
|
+
for (const line of formatEmitRejectionLines(summary.rejections)) {
|
|
1689
|
+
console.error(line);
|
|
1690
|
+
}
|
|
819
1691
|
}
|
|
820
1692
|
async function runMeshMode(action, opts) {
|
|
821
1693
|
const meshRoot = workMeshHomeRoot();
|
|
@@ -900,6 +1772,9 @@ async function runMeshEmit(opts) {
|
|
|
900
1772
|
` unassigned=${summary.unassigned} rejected=${summary.rejected}` +
|
|
901
1773
|
` retryDepth=${summary.retryDepth}` +
|
|
902
1774
|
(opts.replayLegacy ? ` (legacy scanned=${scanned} skipped=${skipped})` : ""));
|
|
1775
|
+
for (const line of formatEmitRejectionLines(summary.rejections)) {
|
|
1776
|
+
console.log(line);
|
|
1777
|
+
}
|
|
903
1778
|
}
|
|
904
1779
|
async function runSessionFlush(opts) {
|
|
905
1780
|
const token = await requireToken();
|
|
@@ -998,9 +1873,43 @@ export function registerMeshCommand(program) {
|
|
|
998
1873
|
.option("--summary <text>", "Note text")).action((opts) => wrap(() => runEvent("note", opts))());
|
|
999
1874
|
addSharedFlags(mesh
|
|
1000
1875
|
.command("story")
|
|
1001
|
-
.description("PATCH one Board story status")
|
|
1876
|
+
.description("PATCH one Board story status and/or assignee")
|
|
1002
1877
|
.requiredOption("--story <id>", "Story id, e.g. US-001")
|
|
1003
|
-
.
|
|
1878
|
+
.option("--status <status>", "queued|in_progress|review|done")
|
|
1879
|
+
.option("--assignee <uid|me|none>", "Assign a person or agent uid, yourself, or clear")).action((opts) => wrap(() => runStory(opts))());
|
|
1880
|
+
const project = mesh
|
|
1881
|
+
.command("project")
|
|
1882
|
+
.description("Set a project Board view or register its project channel");
|
|
1883
|
+
project
|
|
1884
|
+
.command("set <projectId>")
|
|
1885
|
+
.description("PUT the project Board view from flags or a PRD JSON file")
|
|
1886
|
+
.requiredOption("--company <slug|uid>", "Company slug or cloud uid")
|
|
1887
|
+
.option("--name <name>", "Project name")
|
|
1888
|
+
.option("--description <text>", "Project description")
|
|
1889
|
+
.option("--stories-file <path>", "PRD JSON file with userStories")
|
|
1890
|
+
.option("--stories-json <json>", "Story array or JSON object with userStories")
|
|
1891
|
+
.option("--repos-json <json>", "Repository array, such as [{path,branch}]")
|
|
1892
|
+
.option("--repo <path[@branch]>", "Repository binding (repeatable)", collectRepeatable)
|
|
1893
|
+
.option("--channel <channelId>", "Bind the project to an existing company or project channel")
|
|
1894
|
+
.option("--create", "Create the Board view when the GET is a 404")
|
|
1895
|
+
.option("--reset-status", "Overwrite live story status from the PRD (prints a one-line summary of changes)")
|
|
1896
|
+
.option("--json", "Print machine-readable JSON")
|
|
1897
|
+
.action((projectId, opts) => wrap(() => runProjectSet(projectId, opts))());
|
|
1898
|
+
project
|
|
1899
|
+
.command("ensure <projectId>")
|
|
1900
|
+
.description("Idempotently register a PRD on the Board and verify the view")
|
|
1901
|
+
.requiredOption("--company <slug|uid>", "Company slug or cloud uid")
|
|
1902
|
+
.requiredOption("--stories-file <path>", "PRD JSON file with userStories and metadata.repos")
|
|
1903
|
+
.option("--dry-run", "Read the current Board and print computed story statuses without writing")
|
|
1904
|
+
.option("--json", "Print {projectId, threadId, channelId, version, stories}")
|
|
1905
|
+
.action((projectId, opts) => wrap(() => runProjectEnsure(projectId, opts))());
|
|
1906
|
+
project
|
|
1907
|
+
.command("register <projectId>")
|
|
1908
|
+
.description("Register an existing Board and bind its project channel; use project ensure to create or repair a Board")
|
|
1909
|
+
.requiredOption("--company <slug|uid>", "Company slug or cloud uid")
|
|
1910
|
+
.option("--channel <channelId>", "Bind the project to an existing company or project channel")
|
|
1911
|
+
.option("--json", "Print machine-readable JSON")
|
|
1912
|
+
.action((projectId, opts) => wrap(() => runProjectRegister(projectId, opts))());
|
|
1004
1913
|
mesh
|
|
1005
1914
|
.command("doctor")
|
|
1006
1915
|
.description("Warm ~/.hq/work-mesh/cache from hq-pro (directory, inbox, pair DMs). Not `hq doctor`.")
|
|
@@ -1030,12 +1939,29 @@ export function registerMeshCommand(program) {
|
|
|
1030
1939
|
context
|
|
1031
1940
|
.command("backfill-held")
|
|
1032
1941
|
.description("Reconcile ENDED sessions whose held events lack a company so the daemon re-attributes the backlog (explicit, opt-in; no fleet fan-out)")
|
|
1033
|
-
.option("--dry-run", "Report what would be reconciled; write nothing
|
|
1942
|
+
.option("--dry-run", "Report what would be reconciled; write nothing or deliver events")
|
|
1034
1943
|
.option("--offline", "Reconcile outbox-only (no candidates/register network)")
|
|
1035
1944
|
.option("--limit <n>", "Cap sessions processed (default 0 = no cap)")
|
|
1036
|
-
.option("--company <slug>", "Optional non-forcing company hint
|
|
1945
|
+
.option("--company <slug>", "Optional non-forcing company hint")
|
|
1946
|
+
.option("--use-device-default", "Opt in to historical repair using the device default (lower-confidence attribution)")
|
|
1037
1947
|
.option("--json", "Print machine-readable JSON")
|
|
1038
1948
|
.action((opts) => wrap(() => runContextBackfillHeld(opts))());
|
|
1949
|
+
context
|
|
1950
|
+
.command("bind-project")
|
|
1951
|
+
.description("Bind this session to a project id, a numbered candidate, or new <slug>")
|
|
1952
|
+
.argument("<target>", "Project id, candidate number, or new")
|
|
1953
|
+
.argument("[slug]", "Project slug when target is new")
|
|
1954
|
+
.requiredOption("--session <sid>", "Canonical session id")
|
|
1955
|
+
.option("--company <slug|uid>", "Company override when creating a Board")
|
|
1956
|
+
.option("--json", "Print machine-readable JSON")
|
|
1957
|
+
.action((target, slug, opts) => wrap(() => runBindProject(target, { ...opts, slug }))());
|
|
1958
|
+
context
|
|
1959
|
+
.command("prd-sync")
|
|
1960
|
+
.description("Emit task_status for PRD story passes/status changes on a bound session")
|
|
1961
|
+
.requiredOption("--session <sid>", "Canonical session id")
|
|
1962
|
+
.requiredOption("--file <path>", "prd.json written by the bound session")
|
|
1963
|
+
.option("--json", "Print machine-readable JSON")
|
|
1964
|
+
.action((opts) => wrap(() => runPrdSync(opts))());
|
|
1039
1965
|
context
|
|
1040
1966
|
.command("organize")
|
|
1041
1967
|
.description("List or submit one-time project/task decisions (US-007B / US-005B)")
|
|
@@ -1085,10 +2011,11 @@ export function registerMeshCommand(program) {
|
|
|
1085
2011
|
.action((opts) => wrap(() => runContextDefaultGet(opts))());
|
|
1086
2012
|
def
|
|
1087
2013
|
.command("set")
|
|
1088
|
-
.description("Set the device default company slug
|
|
2014
|
+
.description("Set the device default company slug after verifying membership")
|
|
1089
2015
|
.argument("<slug>", "Company slug")
|
|
1090
|
-
.option("--allow-without-migration", "
|
|
1091
|
-
.option("--
|
|
2016
|
+
.option("--allow-without-migration", "Deprecated compatibility no-op; selected-company membership is always verified")
|
|
2017
|
+
.option("--repair-held-with-default", "Persist opt-in for lower-confidence historical held-session repair")
|
|
2018
|
+
.option("--company <slug|uid>", "Deprecated no-op; the selected company is verified directly")
|
|
1092
2019
|
.option("--json", "Print machine-readable JSON")
|
|
1093
2020
|
.action((slug, opts) => wrap(() => runContextDefaultSet(slug, opts))());
|
|
1094
2021
|
def
|
|
@@ -1102,6 +2029,19 @@ export function registerMeshCommand(program) {
|
|
|
1102
2029
|
.argument("<sessionId>", "Canonical session id")
|
|
1103
2030
|
.option("--machine", "Write exactly one ContextResult JSON line to stdout")
|
|
1104
2031
|
.action((sessionId, opts) => wrap(() => runContextUntracked(sessionId, opts))());
|
|
2032
|
+
const contract = mesh
|
|
2033
|
+
.command("contract")
|
|
2034
|
+
.description("Print versioned work-mesh contracts for other repositories");
|
|
2035
|
+
contract
|
|
2036
|
+
.command("preflight")
|
|
2037
|
+
.description("Offline preflight ContextResult contract (contracts/preflight/v1)")
|
|
2038
|
+
.option("--print-fixtures", "Write the fixture file JSON to stdout")
|
|
2039
|
+
.action((opts) => wrap(async () => {
|
|
2040
|
+
if (!opts.printFixtures) {
|
|
2041
|
+
throw new Error("Pass --print-fixtures. The stable package path is contracts/preflight/v1/fixtures.json.");
|
|
2042
|
+
}
|
|
2043
|
+
process.stdout.write(`${JSON.stringify(buildPreflightFixtures(), null, 2)}\n`);
|
|
2044
|
+
})());
|
|
1105
2045
|
const session = mesh
|
|
1106
2046
|
.command("session")
|
|
1107
2047
|
.description("Local session-event spool: enqueue (printf-compatible), flush, and live status");
|
|
@@ -1148,11 +2088,14 @@ export function registerMeshCommand(program) {
|
|
|
1148
2088
|
daemon
|
|
1149
2089
|
.command("run")
|
|
1150
2090
|
.description("Start the single-instance daemon (pid lock, spool watch, presence)")
|
|
1151
|
-
.
|
|
2091
|
+
.option("--hq-root <path>", "HQ tree root (else HQ_ROOT / persisted trusted roots); the Windows task passes this explicitly")
|
|
2092
|
+
.action((opts) => wrap(() => runDaemonRun(opts))());
|
|
1152
2093
|
daemon
|
|
1153
2094
|
.command("install")
|
|
1154
|
-
.description("Install LaunchAgent (macOS)
|
|
2095
|
+
.description("Install LaunchAgent (macOS), systemd user unit (Linux), or Scheduled Task (Windows)")
|
|
1155
2096
|
.option("--system-user <user>", "Write a root-owned unit template for agent boxes (e.g. ec2-user)")
|
|
2097
|
+
.option("--hq-root <path>", "HQ root to record for the service (else HQ_ROOT, else the nearest HQ root above cwd)")
|
|
2098
|
+
.option("--if-stale", "Reinstall and restart only when this CLI is newer than the daemon's recorded version")
|
|
1156
2099
|
.option("--json", "Print machine-readable JSON")
|
|
1157
2100
|
.action((opts) => wrap(() => runDaemonInstall(opts))());
|
|
1158
2101
|
daemon
|
|
@@ -1171,18 +2114,65 @@ export function registerMeshCommand(program) {
|
|
|
1171
2114
|
.option("--json", "Print machine-readable JSON")
|
|
1172
2115
|
.action((opts) => wrap(() => runDaemonDoctorCmd(opts))());
|
|
1173
2116
|
}
|
|
1174
|
-
async function runDaemonRun() {
|
|
1175
|
-
const
|
|
2117
|
+
async function runDaemonRun(opts = {}) {
|
|
2118
|
+
const hqRoot = opts.hqRoot?.trim() || undefined;
|
|
2119
|
+
const handle = await runMeshDaemon({
|
|
2120
|
+
...(hqRoot ? { hqRoot } : {}),
|
|
2121
|
+
enableWorkCache: true,
|
|
2122
|
+
});
|
|
1176
2123
|
// Stay alive until signal handlers call stop + exit.
|
|
1177
2124
|
await new Promise(() => {
|
|
1178
2125
|
void handle;
|
|
1179
2126
|
});
|
|
1180
2127
|
}
|
|
1181
2128
|
async function runDaemonInstall(opts) {
|
|
2129
|
+
// `hq daemon` runs mesh on this machine: installing a second unit would run it twice.
|
|
2130
|
+
// An explicit --hq-root is verified the same way as below and saved for the daemon.
|
|
2131
|
+
const explicitRoot = opts.hqRoot ? resolveInstallHqRoot({ explicit: opts.hqRoot }).root : undefined;
|
|
2132
|
+
const handedOff = opts.systemUser
|
|
2133
|
+
? null
|
|
2134
|
+
: handOffInstallHere(["mesh"], process.env, { hqRoot: explicitRoot, ifStale: opts.ifStale });
|
|
2135
|
+
if (handedOff) {
|
|
2136
|
+
console.log(opts.json ? JSON.stringify({ ok: true, action: "hq-daemon", reinstalled: false, message: handedOff }) : handedOff);
|
|
2137
|
+
return;
|
|
2138
|
+
}
|
|
2139
|
+
// Verified root only: a repo's own .claude/ must never become the daemon's
|
|
2140
|
+
// HQ root (that path is persisted as trusted and used for attribution).
|
|
2141
|
+
const hqRoot = resolveInstallHqRoot({ explicit: opts.hqRoot });
|
|
2142
|
+
const paths = buildInstallPaths({
|
|
2143
|
+
systemUser: opts.systemUser,
|
|
2144
|
+
hqRoot: hqRoot.root,
|
|
2145
|
+
hqRootSource: hqRoot.source,
|
|
2146
|
+
hqBinary: resolveRunningCliEntry(),
|
|
2147
|
+
nodeBinary: resolveAbsoluteNodeBinary(),
|
|
2148
|
+
});
|
|
2149
|
+
if (opts.ifStale) {
|
|
2150
|
+
const stale = installDaemonIfStale({
|
|
2151
|
+
currentVersion: CLI_VERSION,
|
|
2152
|
+
platform: detectPlatform(),
|
|
2153
|
+
paths,
|
|
2154
|
+
systemUser: opts.systemUser,
|
|
2155
|
+
});
|
|
2156
|
+
if (opts.json) {
|
|
2157
|
+
console.log(JSON.stringify({
|
|
2158
|
+
ok: true,
|
|
2159
|
+
action: stale.reinstalled ? "install" : "unchanged",
|
|
2160
|
+
reinstalled: stale.reinstalled,
|
|
2161
|
+
message: stale.message,
|
|
2162
|
+
hqBinary: paths.hqBinary,
|
|
2163
|
+
nodeBinary: paths.nodeBinary,
|
|
2164
|
+
hqRoot: hqRoot.root,
|
|
2165
|
+
}, null, 2));
|
|
2166
|
+
return;
|
|
2167
|
+
}
|
|
2168
|
+
console.log(stale.message);
|
|
2169
|
+
return;
|
|
2170
|
+
}
|
|
1182
2171
|
const result = installDaemonService({
|
|
1183
2172
|
platform: detectPlatform(),
|
|
1184
|
-
paths
|
|
2173
|
+
paths,
|
|
1185
2174
|
systemUser: opts.systemUser,
|
|
2175
|
+
run: defaultRunCommand,
|
|
1186
2176
|
});
|
|
1187
2177
|
if (opts.json) {
|
|
1188
2178
|
console.log(JSON.stringify({
|
|
@@ -1191,10 +2181,15 @@ async function runDaemonInstall(opts) {
|
|
|
1191
2181
|
platform: result.platform,
|
|
1192
2182
|
dest: result.dest,
|
|
1193
2183
|
message: result.message,
|
|
2184
|
+
hqRoot: hqRoot.root,
|
|
2185
|
+
hqRootSource: hqRoot.source,
|
|
2186
|
+
...(result.notice ? { notice: result.notice } : {}),
|
|
1194
2187
|
}, null, 2));
|
|
1195
2188
|
return;
|
|
1196
2189
|
}
|
|
1197
2190
|
console.log(result.message);
|
|
2191
|
+
if (result.notice)
|
|
2192
|
+
console.log(result.notice);
|
|
1198
2193
|
}
|
|
1199
2194
|
async function runDaemonUninstall(opts) {
|
|
1200
2195
|
const result = uninstallDaemonService({
|
|
@@ -1213,12 +2208,14 @@ async function runDaemonUninstall(opts) {
|
|
|
1213
2208
|
}
|
|
1214
2209
|
console.log(result.message);
|
|
1215
2210
|
}
|
|
1216
|
-
async function runDaemonStatus(opts) {
|
|
2211
|
+
export async function runDaemonStatus(opts, deps = {}) {
|
|
2212
|
+
const paths = deps.paths ?? buildInstallPaths({});
|
|
1217
2213
|
const result = daemonServiceStatus({
|
|
1218
|
-
platform: detectPlatform(),
|
|
1219
|
-
paths
|
|
2214
|
+
platform: deps.platform ?? detectPlatform(),
|
|
2215
|
+
paths,
|
|
2216
|
+
isLoaded: daemonServiceIsLoaded(deps.run ?? defaultRunCommand, deps.uid),
|
|
1220
2217
|
});
|
|
1221
|
-
const state = readDaemonState(daemonDir
|
|
2218
|
+
const state = readDaemonState(paths.daemonDir);
|
|
1222
2219
|
const presenceRefusal = state?.presenceRefusal ?? null;
|
|
1223
2220
|
if (opts.json) {
|
|
1224
2221
|
console.log(JSON.stringify({
|
|
@@ -1228,12 +2225,21 @@ async function runDaemonStatus(opts) {
|
|
|
1228
2225
|
running: result.running ?? false,
|
|
1229
2226
|
dest: result.dest,
|
|
1230
2227
|
message: result.message,
|
|
2228
|
+
...(result.lastResult !== undefined ? { lastResult: result.lastResult } : {}),
|
|
2229
|
+
...(result.lastRunFailed !== undefined ? { lastRunFailed: result.lastRunFailed } : {}),
|
|
2230
|
+
...(result.recordedHqRoot !== undefined ? { hqRoot: result.recordedHqRoot } : {}),
|
|
2231
|
+
...(result.rootValid !== undefined ? { rootValid: result.rootValid } : {}),
|
|
2232
|
+
...(result.notice ? { notice: result.notice } : {}),
|
|
1231
2233
|
mqttState: state?.mqttState,
|
|
1232
2234
|
presenceRefusal,
|
|
1233
2235
|
}, null, 2));
|
|
1234
2236
|
return;
|
|
1235
2237
|
}
|
|
1236
2238
|
console.log(result.message);
|
|
2239
|
+
if (result.recordedHqRoot)
|
|
2240
|
+
console.log(`hq root: ${result.recordedHqRoot}`);
|
|
2241
|
+
if (result.notice)
|
|
2242
|
+
console.log(result.notice);
|
|
1237
2243
|
if (presenceRefusal) {
|
|
1238
2244
|
console.log(`presence refusal: ${presenceRefusal.code} (HTTP ${presenceRefusal.status}); next retry at ${presenceRefusal.nextRetryAt}`);
|
|
1239
2245
|
}
|
|
@@ -1242,7 +2248,11 @@ async function runDaemonStatus(opts) {
|
|
|
1242
2248
|
}
|
|
1243
2249
|
}
|
|
1244
2250
|
async function runDaemonDoctorCmd(opts) {
|
|
1245
|
-
|
|
2251
|
+
// Same predicate as install: a repo's .claude/ is not an HQ root. Doctor
|
|
2252
|
+
// only reads, so an unresolvable root is reported as absent, not fatal.
|
|
2253
|
+
const report = collectDaemonDoctor({
|
|
2254
|
+
hqRoot: process.env.HQ_ROOT?.trim() || findAncestorHqRoot(process.cwd()) || undefined,
|
|
2255
|
+
});
|
|
1246
2256
|
if (opts.json) {
|
|
1247
2257
|
console.log(JSON.stringify({ ok: !report.unhealthy, ...report }, null, 2));
|
|
1248
2258
|
return;
|