@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
|
@@ -30,18 +30,193 @@
|
|
|
30
30
|
* are only READ (their exported symbols), never modified.
|
|
31
31
|
*/
|
|
32
32
|
import * as nodeFs from "node:fs";
|
|
33
|
+
import { homedir } from "node:os";
|
|
33
34
|
import * as path from "node:path";
|
|
34
35
|
import { fileURLToPath } from "node:url";
|
|
35
36
|
import { CLI_NAME } from "../cli-version.js";
|
|
36
37
|
import { boundedDiagnosticValue } from "./package-root-diagnostics.js";
|
|
37
|
-
import { isLockStale } from "./update-lock.js";
|
|
38
|
+
import { isLockStale, UPDATE_LOCK_STALE_MS } from "./update-lock.js";
|
|
38
39
|
/** Byte caps for the (hq-derived, path-shaped) diagnostic strings. */
|
|
39
40
|
const SPECIFIER_BYTES = 256;
|
|
40
41
|
const IMPORTER_BYTES = 256;
|
|
41
42
|
const PACKAGE_ROOT_BYTES = 256;
|
|
43
|
+
/** Byte cap for the lock holder's `tool` (the only foreign string this reads). */
|
|
44
|
+
const LOCK_TOOL_BYTES = 64;
|
|
45
|
+
/** The eval-throw error name is a short closed-set token; the cap is only a belt. */
|
|
46
|
+
const ERRORNAME_BYTES = 64;
|
|
42
47
|
const ESM_PACKAGE_RE = /^Cannot find package '([^']+)' imported from (.+)$/s;
|
|
43
48
|
const CJS_MODULE_RE = /^Cannot find module '([^']+)'/s;
|
|
44
49
|
const ESM_MODULE_IMPORTED_RE = /^Cannot find module '([^']+)' imported from (.+)$/s;
|
|
50
|
+
/**
|
|
51
|
+
* The Node ESM loader's SOURCE-READ helper in `node:internal/modules/esm/load`
|
|
52
|
+
* (Node 22) or `node:internal/modules/esm/loader` (Node 24's sync loader).
|
|
53
|
+
* `getSourceSync` must be the first non-`node:fs` caller after the source read;
|
|
54
|
+
* an ordinary fs ENOENT that escapes module evaluation therefore stays outside
|
|
55
|
+
* recovery even when an outer ModuleLoader frame exists.
|
|
56
|
+
*/
|
|
57
|
+
const ESM_SOURCE_READ_FRAME = /^at getSourceSync \(node:internal[\\/]modules[\\/]esm[\\/](?:load|loader)\b/;
|
|
58
|
+
const NODE_FS_FRAME = /^at .* \(node:fs\b/;
|
|
59
|
+
/** True only when Node's ESM source-read helper called the failing fs read. */
|
|
60
|
+
function hasEsmLoaderSourceReadFrame(stack) {
|
|
61
|
+
const frames = stack
|
|
62
|
+
.split("\n")
|
|
63
|
+
.map((line) => line.trim())
|
|
64
|
+
.filter((line) => line.startsWith("at "));
|
|
65
|
+
let sawFsRead = false;
|
|
66
|
+
for (const frame of frames) {
|
|
67
|
+
if (!sawFsRead) {
|
|
68
|
+
if (NODE_FS_READ_FRAME.test(frame))
|
|
69
|
+
sawFsRead = true;
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (NODE_FS_FRAME.test(frame))
|
|
73
|
+
continue;
|
|
74
|
+
return ESM_SOURCE_READ_FRAME.test(frame);
|
|
75
|
+
}
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* The Node module RESOLVER frame — `finalizeResolution` in
|
|
80
|
+
* `node:internal/modules/esm/resolve` (the observed HQ-CLI-1S route, where
|
|
81
|
+
* realpathSync lstat's a component that vanished after the earlier stat), or the
|
|
82
|
+
* CJS `Module._findPath → toRealPath` route in `node:internal/modules/cjs/loader`
|
|
83
|
+
* (the same stat-then-lstat TOCTOU, accepted for symmetry). Requiring a resolver
|
|
84
|
+
* frame — alongside `syscall === 'lstat'` — is what proves the ENOENT came from
|
|
85
|
+
* the resolver's realpath step, so an ordinary `fs.lstatSync` ENOENT written by
|
|
86
|
+
* hq's own code (no resolver frame) is NOT misclassified as a torn install.
|
|
87
|
+
*/
|
|
88
|
+
const RESOLVER_FRAME = /node:internal[\\/]modules[\\/](?:esm[\\/]resolve|cjs[\\/]loader)\b/;
|
|
89
|
+
/** The closed set of error `name`s the eval-throw dialect accepts (HQ-CLI-1T). */
|
|
90
|
+
const EVAL_THROW_NAMES = new Set(["TypeError", "ReferenceError", "SyntaxError"]);
|
|
91
|
+
/**
|
|
92
|
+
* A CJS module-EVALUATION frame — `Module._compile` / `wrapSafe` in
|
|
93
|
+
* `node:internal/modules/cjs/loader`, where a required module's top-level code
|
|
94
|
+
* runs (and where a SyntaxError is raised at compile). NOT the resolve frame
|
|
95
|
+
* `Module._resolveFilename`, so a resolution failure is never read as an eval.
|
|
96
|
+
*/
|
|
97
|
+
const CJS_EVAL_FRAME = /\bat (?:Module\._compile|wrapSafe) \(node:internal[\\/]modules[\\/]cjs[\\/]loader/;
|
|
98
|
+
/** An ESM module-EVALUATION frame — `ModuleJob` run/evaluate in esm/module_job. */
|
|
99
|
+
const ESM_EVAL_FRAME = /node:internal[\\/]modules[\\/]esm[\\/]module_job\b/;
|
|
100
|
+
/** Whether `stack` carries a CJS or ESM module-EVALUATION loader frame. */
|
|
101
|
+
function hasModuleEvalFrame(stack) {
|
|
102
|
+
return CJS_EVAL_FRAME.test(stack) || ESM_EVAL_FRAME.test(stack);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* The Node CJS loader's SOURCE-READ position (HQ-CLI-20) — the CJS twin of
|
|
106
|
+
* {@link hasEsmLoaderSourceReadFrame}. A CJS require whose target was present at RESOLVE (its
|
|
107
|
+
* filename cached in Module._pathCache) and gone at READ fails inside the loader's
|
|
108
|
+
* source read: `readFileSync (node:fs)` called by `defaultLoadImpl`/`loadSource`
|
|
109
|
+
* (Node ≥22) or, on older Node, the `Module._extensions..js` extension handler —
|
|
110
|
+
* all frames in `node:internal/modules/cjs/loader`, and (unlike HQ-CLI-1M) with NO
|
|
111
|
+
* ESM source-read frame.
|
|
112
|
+
*
|
|
113
|
+
* The discriminator is POSITIONAL: the innermost `node:fs` read frame's
|
|
114
|
+
* IMMEDIATELY-following (caller) frame must be a cjs/loader frame that is NOT a
|
|
115
|
+
* module-EVALUATION frame (Module._compile / wrapSafe). That is what proves the
|
|
116
|
+
* LOADER was reading the module's source. An ordinary `fs.readFileSync`/`openSync`
|
|
117
|
+
* ENOENT that merely ESCAPES a third-party module's own EVALUATION has the
|
|
118
|
+
* third-party FILE directly beneath `node:fs`, not a cjs/loader frame, so it stays
|
|
119
|
+
* captured (both shapes reproduced frame-for-frame on Node v22.23.1). The
|
|
120
|
+
* positional rule is the PRIMARY discriminator; the source-read helper NAMES are
|
|
121
|
+
* an accepted closed set, not the sole requirement, so a renamed helper still
|
|
122
|
+
* classifies.
|
|
123
|
+
*
|
|
124
|
+
* The whole-stack presence of Module._compile is deliberately NOT a rejection
|
|
125
|
+
* signal: under a raised Error.stackTraceLimit the torn shape ALSO carries the
|
|
126
|
+
* requiring module's own Module._compile frame — always at depth 11, past the
|
|
127
|
+
* default limit of 10 — so only the frame immediately beneath the node:fs read is
|
|
128
|
+
* consulted. Exported so incomplete-install-error.ts (which already imports from
|
|
129
|
+
* this module) shares the exact gate rather than duplicating the positional logic,
|
|
130
|
+
* mirroring how {@link evalThrowShape} and {@link packageNameOf} are shared.
|
|
131
|
+
*/
|
|
132
|
+
const NODE_FS_READ_FRAME = /^at (?:[\w$.]+\.)?(?:readFileSync|openSync) \(node:fs\b/;
|
|
133
|
+
const CJS_LOADER_FRAME = /node:internal[\\/]modules[\\/]cjs[\\/]loader\b/;
|
|
134
|
+
export function hasCjsLoaderSourceReadFrame(stack) {
|
|
135
|
+
const frames = stack
|
|
136
|
+
.split("\n")
|
|
137
|
+
.map((line) => line.trim())
|
|
138
|
+
.filter((line) => line.startsWith("at "));
|
|
139
|
+
for (let i = 0; i < frames.length; i++) {
|
|
140
|
+
if (!NODE_FS_READ_FRAME.test(frames[i]))
|
|
141
|
+
continue;
|
|
142
|
+
const caller = frames[i + 1];
|
|
143
|
+
if (caller === undefined)
|
|
144
|
+
return false;
|
|
145
|
+
return CJS_LOADER_FRAME.test(caller) && !CJS_EVAL_FRAME.test(caller);
|
|
146
|
+
}
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* A stack LOCATION token — the absolute filesystem path in either an
|
|
151
|
+
* `at <fn> (<abs>:L:C)` frame or a bare `<abs>:L` header line (the source
|
|
152
|
+
* location a SyntaxError prepends). Anchored at line-start or an opening paren so
|
|
153
|
+
* a `node:internal/…` internal frame (never an absolute FS path) is skipped, and
|
|
154
|
+
* a Windows drive/UNC path is matched by shape so it classifies on any host.
|
|
155
|
+
*/
|
|
156
|
+
const STACK_LOCATION = /(?:^|\()((?:\/|[A-Za-z]:[\\/]|\\\\)[^():\n]*?):\d+(?::\d+)?(?:\)|$)/;
|
|
157
|
+
/**
|
|
158
|
+
* A `file:` URL location in a stack frame — the form Node uses for an ESM module
|
|
159
|
+
* EVALUATION frame (`at file:///abs/mod.mjs:2:1`, or the same wrapped in parens).
|
|
160
|
+
* The whole non-space token is captured; the caller strips the trailing paren and
|
|
161
|
+
* `:line[:col]` and decodes it with fileURLToPath.
|
|
162
|
+
*/
|
|
163
|
+
function fileUrlFromFrame(line) {
|
|
164
|
+
const token = line.match(/file:\/\/\/\S+/);
|
|
165
|
+
if (!token)
|
|
166
|
+
return null;
|
|
167
|
+
const url = token[0].replace(/\)+$/, "").replace(/:\d+(?::\d+)?$/, "");
|
|
168
|
+
try {
|
|
169
|
+
return fileURLToPath(url);
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
return null; // not a decodable file URL
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* The eval-throw THROW SITE — the FIRST absolute filesystem path token in the
|
|
177
|
+
* stack, scanning top-down: for an ordinary error that is the throwing frame (a
|
|
178
|
+
* raw path for a CJS module, or a `file:` URL for an ESM one); for a SyntaxError
|
|
179
|
+
* it is the `<abs>:L` header line the stack carries before the `Error:` line.
|
|
180
|
+
* Returns null when no absolute path token is present.
|
|
181
|
+
*/
|
|
182
|
+
function evalThrowSite(stack) {
|
|
183
|
+
for (const rawLine of stack.split("\n")) {
|
|
184
|
+
const line = rawLine.trim();
|
|
185
|
+
const plain = STACK_LOCATION.exec(line);
|
|
186
|
+
if (plain)
|
|
187
|
+
return plain[1];
|
|
188
|
+
const fromUrl = fileUrlFromFrame(line);
|
|
189
|
+
if (fromUrl)
|
|
190
|
+
return fromUrl;
|
|
191
|
+
}
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Lexical `<root>/node_modules/` containment for the eval-throw throw-site gate.
|
|
196
|
+
* Separator- and (Windows-shape-only) case-folded and anchored at a true
|
|
197
|
+
* directory boundary, so a sibling such as `<root>-old/node_modules/…` never
|
|
198
|
+
* matches. Mirrors incomplete-install-error.ts's isUnderNodeModules discipline;
|
|
199
|
+
* kept local because that module imports THIS one (a shared import would cycle).
|
|
200
|
+
*/
|
|
201
|
+
function looksWin32(p) {
|
|
202
|
+
return /^[a-zA-Z]:[\\/]/.test(p) || /^\\\\/.test(p);
|
|
203
|
+
}
|
|
204
|
+
function foldForCompare(p) {
|
|
205
|
+
const folded = p.replace(/[\\/]+/g, "/").replace(/\/+$/, "");
|
|
206
|
+
return looksWin32(p) ? folded.toLowerCase() : folded;
|
|
207
|
+
}
|
|
208
|
+
function isUnderNodeModules(candidate, root) {
|
|
209
|
+
if (!candidate || !root)
|
|
210
|
+
return false;
|
|
211
|
+
return foldForCompare(candidate).startsWith(`${foldForCompare(root)}/node_modules/`);
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* A relative module specifier — `./x`, `../x`, `.\x`, `..\x`, or a bare `.`/`..`.
|
|
215
|
+
* Mirrors the shape src/utils/incomplete-install-error.ts uses, extended with the
|
|
216
|
+
* bare-`.`/`..` case so a token that packageNameOf would reduce to the
|
|
217
|
+
* un-probeable name `.` is caught here and re-resolved instead.
|
|
218
|
+
*/
|
|
219
|
+
const RELATIVE_CJS_SPECIFIER = /^\.\.?([\\/]|$)/;
|
|
45
220
|
/**
|
|
46
221
|
* Reduce a bare specifier to its PACKAGE name: `@scope/name/sub` → `@scope/name`,
|
|
47
222
|
* `name/sub` → `name`, `name` → `name`. This is the unit the readiness probe
|
|
@@ -54,19 +229,104 @@ export function packageNameOf(specifier) {
|
|
|
54
229
|
return parts.slice(0, 2).join("/");
|
|
55
230
|
return parts[0] ?? specifier;
|
|
56
231
|
}
|
|
232
|
+
/**
|
|
233
|
+
* Build a `package` target from an already-reduced name, UNLESS that name is not
|
|
234
|
+
* a plausible bare package: empty, a relative token reduced to `.`/`..`, or a
|
|
235
|
+
* subpath-imports token (`#internal`). Each of those reduces to a name whose
|
|
236
|
+
* `node_modules/<name>/package.json` ancestor probe can NEVER be true, so it
|
|
237
|
+
* falls back to `unknown` — readiness then turns on the lock / retired-dir /
|
|
238
|
+
* quiet signals rather than a probe that stays permanently false.
|
|
239
|
+
*/
|
|
240
|
+
function barePackageTarget(name, from) {
|
|
241
|
+
if (name.length === 0 || name.startsWith(".") || name.startsWith("#")) {
|
|
242
|
+
return { kind: "unknown" };
|
|
243
|
+
}
|
|
244
|
+
return { kind: "package", name, from };
|
|
245
|
+
}
|
|
57
246
|
/**
|
|
58
247
|
* Classify a thrown value as a module-resolution failure and extract the missing
|
|
59
248
|
* target, or return `null` for anything that is not one. The decision is
|
|
60
|
-
* STRUCTURAL: `err.code` must be exactly `ERR_MODULE_NOT_FOUND
|
|
61
|
-
* `MODULE_NOT_FOUND
|
|
62
|
-
*
|
|
63
|
-
*
|
|
249
|
+
* STRUCTURAL: `err.code` must be exactly `ERR_MODULE_NOT_FOUND`,
|
|
250
|
+
* `MODULE_NOT_FOUND`, or — for the esm-loader ENOENT dialect — `ENOENT` under
|
|
251
|
+
* the full conjunction below. No argv, env, or free text is ever consulted, and
|
|
252
|
+
* any other error (including an import-time throw of another class) returns
|
|
253
|
+
* `null` so it is rethrown to the existing boundary unchanged.
|
|
64
254
|
*/
|
|
65
255
|
export function classifyModuleNotFound(err) {
|
|
66
256
|
if (err === null || typeof err !== "object")
|
|
67
257
|
return null;
|
|
68
258
|
const record = err;
|
|
69
259
|
const code = record.code;
|
|
260
|
+
// (0) esm-loader ENOENT (HQ-CLI-1M): a module present at RESOLVE and gone at
|
|
261
|
+
// READ, so Node's ESM loader raises ENOENT from getSourceSync/openSync rather
|
|
262
|
+
// than ERR_MODULE_NOT_FOUND at resolve. Gated on the FULL conjunction — code
|
|
263
|
+
// ENOENT AND syscall 'open' AND an esm-loader stack frame AND a string path —
|
|
264
|
+
// so an ordinary fs.readFileSync/openSync ENOENT written by hq's own code (no
|
|
265
|
+
// loader frame) cannot enter it. The vanished file IS the re-resolvable target
|
|
266
|
+
// the settle wait polls; recovery then waits and re-execs exactly as for the
|
|
267
|
+
// other dialects.
|
|
268
|
+
if (code === "ENOENT") {
|
|
269
|
+
if (record.syscall === "open" &&
|
|
270
|
+
typeof record.path === "string" &&
|
|
271
|
+
typeof record.stack === "string" &&
|
|
272
|
+
hasEsmLoaderSourceReadFrame(record.stack)) {
|
|
273
|
+
return {
|
|
274
|
+
code,
|
|
275
|
+
dialect: "esm-enoent",
|
|
276
|
+
specifier: record.path,
|
|
277
|
+
importer: "",
|
|
278
|
+
target: { kind: "path", path: record.path },
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
// cjs-loader source-read ENOENT (HQ-CLI-20): the CJS twin of esm-enoent — a
|
|
282
|
+
// require() whose target was present at RESOLVE (its filename held in
|
|
283
|
+
// Module._pathCache) and gone at READ, so the CJS loader's source read raises
|
|
284
|
+
// ENOENT with syscall 'open' and a cjs/loader frame but NO ESM source-read frame
|
|
285
|
+
// (which is why arm (0) missed it and classifyModuleNotFound returned null,
|
|
286
|
+
// filing the bare HQ-CLI-20 capture). Gated on the FULL conjunction — code
|
|
287
|
+
// ENOENT AND syscall 'open' AND a string path AND the POSITIONAL CJS
|
|
288
|
+
// source-read gate — so a third-party module's own top-level fs.readFileSync
|
|
289
|
+
// ENOENT (module EVALUATION, its own frame directly beneath node:fs) stays null
|
|
290
|
+
// and keeps its capture. Ordered AFTER the esm-enoent arm so HQ-CLI-1M keeps
|
|
291
|
+
// its byte-for-byte classification. Target 'path': the vanished file is a
|
|
292
|
+
// regular .js/.json file Node's CJS LOAD_AS_FILE step re-resolves, so the probe
|
|
293
|
+
// and settle wait reuse the same machinery as esm-enoent, unchanged.
|
|
294
|
+
if (record.syscall === "open" &&
|
|
295
|
+
typeof record.path === "string" &&
|
|
296
|
+
typeof record.stack === "string" &&
|
|
297
|
+
hasCjsLoaderSourceReadFrame(record.stack)) {
|
|
298
|
+
return {
|
|
299
|
+
code,
|
|
300
|
+
dialect: "cjs-enoent",
|
|
301
|
+
specifier: record.path,
|
|
302
|
+
importer: "",
|
|
303
|
+
target: { kind: "path", path: record.path },
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
// resolve-time ENOENT (HQ-CLI-1S): Node's resolver stat'ed a path OK, then
|
|
307
|
+
// realpathSync lstat'ed a component that a concurrent reinstall renamed away
|
|
308
|
+
// between the two, throwing ENOENT with syscall `lstat` from a RESOLVER frame
|
|
309
|
+
// (finalizeResolution / Module._findPath→toRealPath). Gated on the FULL
|
|
310
|
+
// conjunction so an ordinary fs.lstatSync ENOENT from hq's own code (no
|
|
311
|
+
// resolver frame) and a rename/unlink ENOENT (syscall not `lstat`) both stay
|
|
312
|
+
// null. The vanished component may be a package/scope DIRECTORY whose bare
|
|
313
|
+
// existence precedes its `package.json`, so the target is `exists` (presence
|
|
314
|
+
// only); readiness still rides the lock / manifest-health / retired-sibling /
|
|
315
|
+
// quiet guards. Structurally a loader race like esm-enoent — no writer gate.
|
|
316
|
+
if (record.syscall === "lstat" &&
|
|
317
|
+
typeof record.path === "string" &&
|
|
318
|
+
typeof record.stack === "string" &&
|
|
319
|
+
RESOLVER_FRAME.test(record.stack)) {
|
|
320
|
+
return {
|
|
321
|
+
code,
|
|
322
|
+
dialect: "resolve-enoent",
|
|
323
|
+
specifier: record.path,
|
|
324
|
+
importer: "",
|
|
325
|
+
target: { kind: "exists", path: record.path },
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
return null;
|
|
329
|
+
}
|
|
70
330
|
if (code !== "ERR_MODULE_NOT_FOUND" && code !== "MODULE_NOT_FOUND")
|
|
71
331
|
return null;
|
|
72
332
|
const message = typeof record.message === "string" ? record.message : "";
|
|
@@ -94,7 +354,7 @@ export function classifyModuleNotFound(err) {
|
|
|
94
354
|
dialect: "esm-package",
|
|
95
355
|
specifier: spec,
|
|
96
356
|
importer,
|
|
97
|
-
target:
|
|
357
|
+
target: barePackageTarget(spec, path.dirname(importer)),
|
|
98
358
|
};
|
|
99
359
|
}
|
|
100
360
|
// (c) CJS `Cannot find module '<spec>'` (+ Require stack). Absolute → a path
|
|
@@ -108,12 +368,32 @@ export function classifyModuleNotFound(err) {
|
|
|
108
368
|
if (path.isAbsolute(spec)) {
|
|
109
369
|
return { code, dialect: "cjs-path", specifier: spec, importer, target: { kind: "path", path: spec } };
|
|
110
370
|
}
|
|
371
|
+
// Relative specifier (`./x`, `../x`): Node reports the RAW token, so
|
|
372
|
+
// packageNameOf would reduce it to `.`/`..` and build a package target
|
|
373
|
+
// whose ancestor probe can never be true. Re-resolve it from the importer's
|
|
374
|
+
// directory, and report the RESOLVED path as the diagnostic specifier
|
|
375
|
+
// (actionable — the missing sibling's real location), mirroring esm-path.
|
|
376
|
+
if (RELATIVE_CJS_SPECIFIER.test(spec)) {
|
|
377
|
+
if (importer && path.isAbsolute(importer)) {
|
|
378
|
+
const from = path.dirname(importer);
|
|
379
|
+
return {
|
|
380
|
+
code,
|
|
381
|
+
dialect: "cjs-relative",
|
|
382
|
+
specifier: path.resolve(from, spec),
|
|
383
|
+
importer,
|
|
384
|
+
target: { kind: "relative", specifier: spec, from },
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
// No usable (absolute) importer survived — fall back to the lock /
|
|
388
|
+
// retired-dir / quiet signals rather than a probe that cannot be true.
|
|
389
|
+
return { code, dialect: "cjs-relative", specifier: spec, importer, target: { kind: "unknown" } };
|
|
390
|
+
}
|
|
111
391
|
return {
|
|
112
392
|
code,
|
|
113
393
|
dialect: "cjs-package",
|
|
114
394
|
specifier: spec,
|
|
115
395
|
importer,
|
|
116
|
-
target:
|
|
396
|
+
target: barePackageTarget(packageNameOf(spec), path.dirname(importer)),
|
|
117
397
|
};
|
|
118
398
|
}
|
|
119
399
|
}
|
|
@@ -129,9 +409,65 @@ export function classifyModuleNotFound(err) {
|
|
|
129
409
|
// the lock / retired-dir / quiet signals only.
|
|
130
410
|
return { code, dialect: "unknown", specifier: "", importer: "", target: { kind: "unknown" } };
|
|
131
411
|
}
|
|
412
|
+
/**
|
|
413
|
+
* Detect a module-EVALUATION throw STRUCTURALLY, WITHOUT the node_modules
|
|
414
|
+
* boundary gate: an error with NO `code`, a `name` in the closed set
|
|
415
|
+
* {TypeError, ReferenceError, SyntaxError}, a CJS/ESM module-evaluation loader
|
|
416
|
+
* frame, and a resolvable throw-site path. This is the shape a half-written
|
|
417
|
+
* dependency file produces — require() read an empty module and returned `{}`, so
|
|
418
|
+
* calling one of its exports throws a code-less TypeError while the module's own
|
|
419
|
+
* top-level code runs. No message text is ever parsed. The caller applies its own
|
|
420
|
+
* packageRoot gate ({@link classifyEvalThrow} for recovery, the boundary for
|
|
421
|
+
* capture context), so this stays pure and reusable. Returns null for anything
|
|
422
|
+
* that is not this shape — a coded error (ERR_REQUIRE_ESM etc.), an Error /
|
|
423
|
+
* RangeError name, a throw with no loader frame, or no absolute throw site.
|
|
424
|
+
*/
|
|
425
|
+
export function evalThrowShape(err) {
|
|
426
|
+
if (err === null || typeof err !== "object")
|
|
427
|
+
return null;
|
|
428
|
+
const record = err;
|
|
429
|
+
if (record.code !== undefined)
|
|
430
|
+
return null;
|
|
431
|
+
const name = typeof record.name === "string" ? record.name : "";
|
|
432
|
+
if (!EVAL_THROW_NAMES.has(name))
|
|
433
|
+
return null;
|
|
434
|
+
if (typeof record.stack !== "string" || !hasModuleEvalFrame(record.stack))
|
|
435
|
+
return null;
|
|
436
|
+
const throwSite = evalThrowSite(record.stack);
|
|
437
|
+
if (throwSite === null)
|
|
438
|
+
return null;
|
|
439
|
+
return { errorName: name, throwSite };
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Classify a module-EVALUATION throw as a torn-install recovery candidate
|
|
443
|
+
* (HQ-CLI-1T) — the {@link evalThrowShape} fingerprint AND a throw site under
|
|
444
|
+
* `<packageRoot>/node_modules/`. A throw under the install's own `dist/` or
|
|
445
|
+
* `assets/`, outside the root, or with an unresolved root is NOT classified, so a
|
|
446
|
+
* genuine hq-cli code defect keeps its raw capture. Unlike the loader-race
|
|
447
|
+
* dialects the recovery seam gates this on a live writer signal before waiting.
|
|
448
|
+
* `packageRoot` comes from the seam's resolvePackageRoot (running-install → derived
|
|
449
|
+
* fallback). The target is `unknown` — an eval-throw carries no re-resolvable
|
|
450
|
+
* missing file, so recovery keys entirely on the writer signal + quiet window.
|
|
451
|
+
*/
|
|
452
|
+
export function classifyEvalThrow(err, packageRoot) {
|
|
453
|
+
const shape = evalThrowShape(err);
|
|
454
|
+
if (shape === null)
|
|
455
|
+
return null;
|
|
456
|
+
if (!packageRoot || !isUnderNodeModules(shape.throwSite, packageRoot))
|
|
457
|
+
return null;
|
|
458
|
+
return {
|
|
459
|
+
code: "EVAL_THROW",
|
|
460
|
+
dialect: "eval-throw",
|
|
461
|
+
specifier: shape.throwSite,
|
|
462
|
+
importer: "",
|
|
463
|
+
target: { kind: "unknown" },
|
|
464
|
+
errorName: shape.errorName,
|
|
465
|
+
};
|
|
466
|
+
}
|
|
132
467
|
const nodeInstallTreeFs = {
|
|
133
468
|
existsSync: (p) => nodeFs.existsSync(p),
|
|
134
469
|
statSync: (p) => nodeFs.statSync(p),
|
|
470
|
+
lstatSync: (p) => nodeFs.lstatSync(p),
|
|
135
471
|
readFileSync: (p, encoding) => nodeFs.readFileSync(p, encoding),
|
|
136
472
|
readdirSync: (p) => nodeFs.readdirSync(p),
|
|
137
473
|
};
|
|
@@ -145,6 +481,58 @@ function defaultIsPidAlive(pid) {
|
|
|
145
481
|
return err.code === "EPERM";
|
|
146
482
|
}
|
|
147
483
|
}
|
|
484
|
+
/** CJS extensions Node's LOAD_AS_FILE / LOAD_INDEX try, in order. */
|
|
485
|
+
const CJS_FILE_EXTENSIONS = [".js", ".json", ".node"];
|
|
486
|
+
/** Whether `p` exists AND is a regular file (not a directory); any fs error → false. */
|
|
487
|
+
function isResolvableFile(p, fs) {
|
|
488
|
+
try {
|
|
489
|
+
return fs.existsSync(p) && !fs.statSync(p).isDirectory();
|
|
490
|
+
}
|
|
491
|
+
catch {
|
|
492
|
+
return false;
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
/** Node's LOAD_AS_FILE(X): X itself, then X + each CJS extension — each must be a file. */
|
|
496
|
+
function loadAsFile(base, fs) {
|
|
497
|
+
if (isResolvableFile(base, fs))
|
|
498
|
+
return true;
|
|
499
|
+
return CJS_FILE_EXTENSIONS.some((ext) => isResolvableFile(base + ext, fs));
|
|
500
|
+
}
|
|
501
|
+
/** Node's LOAD_INDEX(X): X/index.{js,json,node} — each must be a file. */
|
|
502
|
+
function loadIndex(dir, fs) {
|
|
503
|
+
return CJS_FILE_EXTENSIONS.some((ext) => isResolvableFile(path.join(dir, `index${ext}`), fs));
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Whether a relative target's resolved `base` is loadable exactly as Node's CJS
|
|
507
|
+
* require would load it: LOAD_AS_FILE(base), else LOAD_AS_DIRECTORY(base) — its
|
|
508
|
+
* package.json `main` resolved as a file (or that main's index), else
|
|
509
|
+
* base/index.*. A bare or partially-extracted directory — one that holds neither
|
|
510
|
+
* a resolvable `main` nor an index file — is deliberately NOT loadable, so it
|
|
511
|
+
* reads as not-present and the single re-exec cannot fire on a still-torn tree
|
|
512
|
+
* (mirrors the MODULE_NOT_FOUND Node would still throw for that state).
|
|
513
|
+
*/
|
|
514
|
+
function relativeTargetResolvable(base, fs) {
|
|
515
|
+
if (loadAsFile(base, fs))
|
|
516
|
+
return true;
|
|
517
|
+
const manifest = path.join(base, "package.json");
|
|
518
|
+
if (isResolvableFile(manifest, fs)) {
|
|
519
|
+
let main = null;
|
|
520
|
+
try {
|
|
521
|
+
const parsed = JSON.parse(fs.readFileSync(manifest, "utf-8"));
|
|
522
|
+
if (typeof parsed.main === "string" && parsed.main.trim() !== "")
|
|
523
|
+
main = parsed.main;
|
|
524
|
+
}
|
|
525
|
+
catch {
|
|
526
|
+
main = null; // unreadable / unparseable manifest — fall back to index.*
|
|
527
|
+
}
|
|
528
|
+
if (main !== null) {
|
|
529
|
+
const mainBase = path.resolve(base, main);
|
|
530
|
+
if (loadAsFile(mainBase, fs) || loadIndex(mainBase, fs))
|
|
531
|
+
return true;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
return loadIndex(base, fs);
|
|
535
|
+
}
|
|
148
536
|
/**
|
|
149
537
|
* Whether the missing target is now present on disk — the readiness signal the
|
|
150
538
|
* settle wait polls. It re-resolves the SAME step Node's resolver took:
|
|
@@ -155,6 +543,13 @@ function defaultIsPidAlive(pid) {
|
|
|
155
543
|
* exact ancestor walk `getPackageJSONURL` performs, done WITHOUT
|
|
156
544
|
* `createRequire` so an ESM-only / export-conditioned package
|
|
157
545
|
* cannot false-negative.
|
|
546
|
+
* - `relative`: re-resolve `path.resolve(from, specifier)` as Node's CJS
|
|
547
|
+
* require would — a real file (exact / `.js` / `.json` / `.node`),
|
|
548
|
+
* or a directory whose package.json `main` (or that main's index)
|
|
549
|
+
* or own `index.*` is a real file. A bare or partially-extracted
|
|
550
|
+
* directory is NOT loadable and reads as not-present.
|
|
551
|
+
* - `exists`: the path exists at all (any file type) — presence only, because
|
|
552
|
+
* the vanished component may be a package/scope directory.
|
|
158
553
|
* - `unknown`: true (readiness turns on the other signals).
|
|
159
554
|
* Any filesystem error reads as "not present" rather than throwing.
|
|
160
555
|
*/
|
|
@@ -162,6 +557,12 @@ export function installTargetPresent(target, fs = nodeInstallTreeFs) {
|
|
|
162
557
|
try {
|
|
163
558
|
if (target.kind === "unknown")
|
|
164
559
|
return true;
|
|
560
|
+
// `exists` (resolve-enoent, HQ-CLI-1S): the lstat'ed component may be a
|
|
561
|
+
// package/scope DIRECTORY whose bare existence precedes its `package.json`, so
|
|
562
|
+
// presence alone is the signal here — the surrounding manifest-health /
|
|
563
|
+
// retired-sibling / quiet guards keep a premature re-exec bounded.
|
|
564
|
+
if (target.kind === "exists")
|
|
565
|
+
return fs.existsSync(target.path);
|
|
165
566
|
if (target.kind === "path") {
|
|
166
567
|
if (!fs.existsSync(target.path))
|
|
167
568
|
return false;
|
|
@@ -175,6 +576,15 @@ export function installTargetPresent(target, fs = nodeInstallTreeFs) {
|
|
|
175
576
|
}
|
|
176
577
|
return true;
|
|
177
578
|
}
|
|
579
|
+
if (target.kind === "relative") {
|
|
580
|
+
// Re-resolve exactly as Node's CJS require would from `from`, so the probe
|
|
581
|
+
// turns true only when the missing module is ACTUALLY loadable again — a
|
|
582
|
+
// bare or partially-extracted directory must not read as present, or the
|
|
583
|
+
// single re-exec would fire on a still-torn tree. The extensionless case
|
|
584
|
+
// matters — a production sibling shape (`./Base/TreeIterator`, HQ-CLI-1N)
|
|
585
|
+
// carries no extension, so an exact-path-only probe would stay false for it.
|
|
586
|
+
return relativeTargetResolvable(path.resolve(target.from, target.specifier), fs);
|
|
587
|
+
}
|
|
178
588
|
// package: ancestor walk from `from`.
|
|
179
589
|
let dir = path.resolve(target.from);
|
|
180
590
|
for (;;) {
|
|
@@ -191,6 +601,15 @@ export function installTargetPresent(target, fs = nodeInstallTreeFs) {
|
|
|
191
601
|
return false;
|
|
192
602
|
}
|
|
193
603
|
}
|
|
604
|
+
/**
|
|
605
|
+
* Default ceiling on the CUMULATIVE time the wait may spend observing a FRESH
|
|
606
|
+
* foreign lock held by a live pid. Equal to the shared update-lock contract's own
|
|
607
|
+
* staleness window ({@link UPDATE_LOCK_STALE_MS} — "no healthy npm install -g of
|
|
608
|
+
* this package runs 10 minutes"), so the wait trusts a live cooperating writer for
|
|
609
|
+
* exactly as long as the contract legitimises holding the lock, and never longer.
|
|
610
|
+
* Overridable by the seam (env HQ_INSTALL_SETTLE_LOCK_TIMEOUT_MS).
|
|
611
|
+
*/
|
|
612
|
+
const DEFAULT_INSTALL_SETTLE_LOCK_WAIT_MS = UPDATE_LOCK_STALE_MS;
|
|
194
613
|
/** The scope/leaf split of CLI_NAME, e.g. `@indigoai-us` / `hq-cli`. */
|
|
195
614
|
function cliNameParts() {
|
|
196
615
|
const slash = CLI_NAME.indexOf("/");
|
|
@@ -198,26 +617,32 @@ function cliNameParts() {
|
|
|
198
617
|
return { scope: null, leaf: CLI_NAME };
|
|
199
618
|
return { scope: CLI_NAME.slice(0, slash), leaf: CLI_NAME.slice(slash + 1) };
|
|
200
619
|
}
|
|
201
|
-
/**
|
|
202
|
-
|
|
620
|
+
/**
|
|
621
|
+
* The FRESH update lock held by a DIFFERENT live pid, or null. A non-null result
|
|
622
|
+
* blocks readiness AND extends the wait under the lock ceiling; the lock file is
|
|
623
|
+
* only ever READ. Freshness is decided by {@link isLockStale} exactly as before
|
|
624
|
+
* (parseable, `startedAt` younger than {@link UPDATE_LOCK_STALE_MS}, pid alive),
|
|
625
|
+
* and our own pid never counts.
|
|
626
|
+
*/
|
|
627
|
+
function freshForeignLock(lockPath, nowMs, isPidAlive, fs) {
|
|
203
628
|
let raw;
|
|
204
629
|
try {
|
|
205
630
|
raw = fs.readFileSync(lockPath, "utf-8");
|
|
206
631
|
}
|
|
207
632
|
catch {
|
|
208
|
-
return
|
|
633
|
+
return null; // no lock (ENOENT) or unreadable — not a fresh foreign holder
|
|
209
634
|
}
|
|
210
635
|
if (isLockStale(raw, nowMs, isPidAlive))
|
|
211
|
-
return
|
|
636
|
+
return null;
|
|
212
637
|
try {
|
|
213
638
|
const info = JSON.parse(raw);
|
|
214
639
|
if (info.pid === process.pid)
|
|
215
|
-
return
|
|
640
|
+
return null; // our own lock never blocks us
|
|
641
|
+
return info;
|
|
216
642
|
}
|
|
217
643
|
catch {
|
|
218
|
-
return
|
|
644
|
+
return null; // isLockStale already treats unparseable as stale, unreachable
|
|
219
645
|
}
|
|
220
|
-
return true;
|
|
221
646
|
}
|
|
222
647
|
/** Whether an npm retired/staging sibling (`.<leaf>-*`) sits beside packageRoot. */
|
|
223
648
|
function retiredSiblingPresent(packageRoot, fs) {
|
|
@@ -227,20 +652,302 @@ function retiredSiblingPresent(packageRoot, fs) {
|
|
|
227
652
|
const entries = fs.readdirSync(parent); // caller treats a throw as "not ready"
|
|
228
653
|
return entries.some((entry) => entry.startsWith(stagingPrefix));
|
|
229
654
|
}
|
|
655
|
+
/** Reduce an observed sibling basename to a closed kind without retaining it. */
|
|
656
|
+
function retiredSiblingKind(packageRoot, fs) {
|
|
657
|
+
if (!packageRoot)
|
|
658
|
+
return "unknown";
|
|
659
|
+
try {
|
|
660
|
+
const { leaf } = cliNameParts();
|
|
661
|
+
const prefix = "." + leaf + "-";
|
|
662
|
+
const siblings = fs
|
|
663
|
+
.readdirSync(path.dirname(packageRoot))
|
|
664
|
+
.filter((entry) => entry.startsWith(prefix))
|
|
665
|
+
.sort();
|
|
666
|
+
if (siblings.length === 0)
|
|
667
|
+
return "unknown";
|
|
668
|
+
const name = siblings[0];
|
|
669
|
+
if (/^\.hq-cli-staging-[A-Za-z0-9-]+$/.test(name))
|
|
670
|
+
return "hq_staging";
|
|
671
|
+
if (/^\.hq-cli-backup-[A-Za-z0-9-]+$/.test(name))
|
|
672
|
+
return "hq_backup";
|
|
673
|
+
if (/^\.hq-cli-[A-Za-z0-9]{8}$/.test(name))
|
|
674
|
+
return "npm_hash_retired";
|
|
675
|
+
return "other";
|
|
676
|
+
}
|
|
677
|
+
catch {
|
|
678
|
+
return "unknown";
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
/** Classify current target/manifest state without retaining paths or file contents. */
|
|
682
|
+
function installTargetState(target, packageRoot, fs) {
|
|
683
|
+
if (target.kind === "unknown")
|
|
684
|
+
return "unknown";
|
|
685
|
+
if (!installTargetPresent(target, fs))
|
|
686
|
+
return "missing";
|
|
687
|
+
if (!packageRoot)
|
|
688
|
+
return "unknown";
|
|
689
|
+
try {
|
|
690
|
+
const raw = fs.readFileSync(path.join(packageRoot, "package.json"), "utf-8");
|
|
691
|
+
let manifest;
|
|
692
|
+
try {
|
|
693
|
+
manifest = JSON.parse(raw);
|
|
694
|
+
}
|
|
695
|
+
catch {
|
|
696
|
+
return "manifest_invalid";
|
|
697
|
+
}
|
|
698
|
+
return manifest.name === CLI_NAME ? "manifest_valid" : "manifest_invalid";
|
|
699
|
+
}
|
|
700
|
+
catch (error) {
|
|
701
|
+
return error?.code === "ENOENT" ? "missing" : "unreadable";
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
/** Read only the lock's recorded owner PID; never retain or report the PID. */
|
|
705
|
+
function updaterPidAlive(lockPath, fs, isPidAlive) {
|
|
706
|
+
try {
|
|
707
|
+
const lock = JSON.parse(fs.readFileSync(lockPath, "utf-8"));
|
|
708
|
+
if (typeof lock.pid !== "number" || !Number.isSafeInteger(lock.pid) || lock.pid <= 0) {
|
|
709
|
+
return "unknown";
|
|
710
|
+
}
|
|
711
|
+
return isPidAlive(lock.pid) ? "true" : "false";
|
|
712
|
+
}
|
|
713
|
+
catch {
|
|
714
|
+
return "unknown";
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
/** Snapshot retired sibling trees so changes below their root stay observable. */
|
|
718
|
+
function retiredSiblingActivitySignature(packageRoot, fs) {
|
|
719
|
+
const { leaf } = cliNameParts();
|
|
720
|
+
const stagingPrefix = `.${leaf}-`;
|
|
721
|
+
const parent = path.dirname(packageRoot);
|
|
722
|
+
const siblings = fs.readdirSync(parent).filter((entry) => entry.startsWith(stagingPrefix)).sort();
|
|
723
|
+
const snapshots = [["names", siblings]];
|
|
724
|
+
let observed = true;
|
|
725
|
+
let visited = 0;
|
|
726
|
+
const maxEntries = 20_000;
|
|
727
|
+
const maxDepth = 64;
|
|
728
|
+
const visit = (absolutePath, relativePath, depth) => {
|
|
729
|
+
visited += 1;
|
|
730
|
+
if (visited > maxEntries) {
|
|
731
|
+
observed = false;
|
|
732
|
+
return;
|
|
733
|
+
}
|
|
734
|
+
try {
|
|
735
|
+
const stat = fs.lstatSync ? fs.lstatSync(absolutePath) : fs.statSync(absolutePath);
|
|
736
|
+
const symbolicLink = stat.isSymbolicLink?.() ?? false;
|
|
737
|
+
const directory = !symbolicLink && stat.isDirectory();
|
|
738
|
+
const mtimeMs = stat.mtimeMs;
|
|
739
|
+
if (typeof mtimeMs !== "number" || !Number.isFinite(mtimeMs))
|
|
740
|
+
observed = false;
|
|
741
|
+
snapshots.push([
|
|
742
|
+
relativePath,
|
|
743
|
+
symbolicLink ? "symlink" : directory ? "directory" : "file",
|
|
744
|
+
stat.size ?? null,
|
|
745
|
+
typeof mtimeMs === "number" && Number.isFinite(mtimeMs) ? mtimeMs : null,
|
|
746
|
+
]);
|
|
747
|
+
if (!directory)
|
|
748
|
+
return;
|
|
749
|
+
if (depth >= maxDepth) {
|
|
750
|
+
observed = false;
|
|
751
|
+
return;
|
|
752
|
+
}
|
|
753
|
+
for (const child of fs.readdirSync(absolutePath).sort()) {
|
|
754
|
+
visit(path.join(absolutePath, child), path.join(relativePath, child), depth + 1);
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
catch {
|
|
758
|
+
observed = false;
|
|
759
|
+
snapshots.push([relativePath, "unreadable"]);
|
|
760
|
+
}
|
|
761
|
+
};
|
|
762
|
+
for (const sibling of siblings) {
|
|
763
|
+
visit(path.join(parent, sibling), sibling, 0);
|
|
764
|
+
}
|
|
765
|
+
return { value: JSON.stringify(snapshots), observed, present: siblings.length > 0 };
|
|
766
|
+
}
|
|
230
767
|
/** Whether packageRoot's own manifest is healthy (`name === CLI_NAME`). */
|
|
231
768
|
function packageRootHealthy(packageRoot, fs) {
|
|
232
769
|
const manifest = JSON.parse(fs.readFileSync(path.join(packageRoot, "package.json"), "utf-8"));
|
|
233
770
|
return manifest.name === CLI_NAME;
|
|
234
771
|
}
|
|
772
|
+
function isWithinPath(candidate, root) {
|
|
773
|
+
const relative = path.relative(root, candidate);
|
|
774
|
+
return relative === "" ||
|
|
775
|
+
(!path.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${path.sep}`));
|
|
776
|
+
}
|
|
777
|
+
/** Paths whose presence, metadata, or immediate entries show activity for this import. */
|
|
778
|
+
function installTreeActivityPaths(target, packageRoot) {
|
|
779
|
+
const root = packageRoot ? path.resolve(packageRoot) : null;
|
|
780
|
+
const paths = new Set();
|
|
781
|
+
const directories = new Set();
|
|
782
|
+
const addPath = (candidate) => {
|
|
783
|
+
const resolved = path.resolve(candidate);
|
|
784
|
+
paths.add(resolved);
|
|
785
|
+
directories.add(path.dirname(resolved));
|
|
786
|
+
if (!root || !isWithinPath(resolved, root))
|
|
787
|
+
return;
|
|
788
|
+
let current = path.dirname(resolved);
|
|
789
|
+
for (;;) {
|
|
790
|
+
paths.add(current);
|
|
791
|
+
directories.add(current);
|
|
792
|
+
if (current === root)
|
|
793
|
+
break;
|
|
794
|
+
const parent = path.dirname(current);
|
|
795
|
+
if (parent === current || !isWithinPath(parent, root))
|
|
796
|
+
break;
|
|
797
|
+
current = parent;
|
|
798
|
+
}
|
|
799
|
+
};
|
|
800
|
+
if (root) {
|
|
801
|
+
for (const candidate of [
|
|
802
|
+
root,
|
|
803
|
+
path.join(root, "package.json"),
|
|
804
|
+
path.join(root, "dist"),
|
|
805
|
+
path.join(root, "node_modules"),
|
|
806
|
+
]) {
|
|
807
|
+
addPath(candidate);
|
|
808
|
+
directories.add(candidate);
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
if (target.kind === "path" || target.kind === "exists") {
|
|
812
|
+
addPath(target.path);
|
|
813
|
+
}
|
|
814
|
+
else if (target.kind === "relative") {
|
|
815
|
+
const base = path.resolve(target.from, target.specifier);
|
|
816
|
+
const candidates = [
|
|
817
|
+
base,
|
|
818
|
+
...CJS_FILE_EXTENSIONS.map((ext) => base + ext),
|
|
819
|
+
...CJS_FILE_EXTENSIONS.map((ext) => path.join(base, `index${ext}`)),
|
|
820
|
+
];
|
|
821
|
+
for (const candidate of candidates)
|
|
822
|
+
addPath(candidate);
|
|
823
|
+
}
|
|
824
|
+
else if (target.kind === "package") {
|
|
825
|
+
let from = path.resolve(target.from);
|
|
826
|
+
let ancestorCount = 0;
|
|
827
|
+
for (;;) {
|
|
828
|
+
if (root && !isWithinPath(from, root))
|
|
829
|
+
break;
|
|
830
|
+
addPath(path.join(from, "node_modules", target.name));
|
|
831
|
+
if (from === root)
|
|
832
|
+
break;
|
|
833
|
+
ancestorCount += 1;
|
|
834
|
+
if (!root && ancestorCount >= 12)
|
|
835
|
+
break;
|
|
836
|
+
const parent = path.dirname(from);
|
|
837
|
+
if (parent === from)
|
|
838
|
+
break;
|
|
839
|
+
from = parent;
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
return {
|
|
843
|
+
paths: [...paths].sort(),
|
|
844
|
+
directories: [...directories].sort(),
|
|
845
|
+
};
|
|
846
|
+
}
|
|
847
|
+
/** A local-only snapshot of the missing target and directories an installer may change. */
|
|
848
|
+
function installTreeActivitySignature(target, packageRoot, fs) {
|
|
849
|
+
const activity = installTreeActivityPaths(target, packageRoot);
|
|
850
|
+
const snapshots = [];
|
|
851
|
+
let observed = true;
|
|
852
|
+
let nonRetiredObserved = true;
|
|
853
|
+
let retiredSiblingPresent = null;
|
|
854
|
+
const errorCode = (err) => {
|
|
855
|
+
if (err !== null && typeof err === "object" && "code" in err && typeof err.code === "string") {
|
|
856
|
+
return err.code;
|
|
857
|
+
}
|
|
858
|
+
return "error";
|
|
859
|
+
};
|
|
860
|
+
for (const candidate of activity.paths) {
|
|
861
|
+
try {
|
|
862
|
+
if (!fs.existsSync(candidate)) {
|
|
863
|
+
snapshots.push([candidate, "missing"]);
|
|
864
|
+
continue;
|
|
865
|
+
}
|
|
866
|
+
const stat = fs.statSync(candidate);
|
|
867
|
+
snapshots.push([
|
|
868
|
+
candidate,
|
|
869
|
+
stat.isDirectory() ? "directory" : "file",
|
|
870
|
+
stat.size ?? null,
|
|
871
|
+
stat.mtimeMs ?? null,
|
|
872
|
+
]);
|
|
873
|
+
}
|
|
874
|
+
catch (err) {
|
|
875
|
+
observed = false;
|
|
876
|
+
nonRetiredObserved = false;
|
|
877
|
+
snapshots.push([candidate, `unreadable:${errorCode(err)}`]);
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
for (const directory of activity.directories) {
|
|
881
|
+
try {
|
|
882
|
+
if (!fs.existsSync(directory) || !fs.statSync(directory).isDirectory())
|
|
883
|
+
continue;
|
|
884
|
+
snapshots.push([directory, "entries", fs.readdirSync(directory).sort()]);
|
|
885
|
+
}
|
|
886
|
+
catch (err) {
|
|
887
|
+
observed = false;
|
|
888
|
+
nonRetiredObserved = false;
|
|
889
|
+
snapshots.push([directory, `entries-unreadable:${errorCode(err)}`]);
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
if (packageRoot) {
|
|
893
|
+
try {
|
|
894
|
+
const retired = retiredSiblingActivitySignature(packageRoot, fs);
|
|
895
|
+
snapshots.push(["retired-siblings", retired.value]);
|
|
896
|
+
retiredSiblingPresent = retired.present;
|
|
897
|
+
if (!retired.observed)
|
|
898
|
+
observed = false;
|
|
899
|
+
}
|
|
900
|
+
catch (err) {
|
|
901
|
+
observed = false;
|
|
902
|
+
snapshots.push(["retired-siblings-unreadable", errorCode(err)]);
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
return { value: JSON.stringify(snapshots), observed, nonRetiredObserved, retiredSiblingPresent };
|
|
906
|
+
}
|
|
907
|
+
function canProbeUnsettledRetiredSibling(snapshot) {
|
|
908
|
+
// A very large or unreadable retired npm tree can exceed the bounded recursive
|
|
909
|
+
// activity scan. Its stable partial signature is still useful when the live
|
|
910
|
+
// install paths are observable and npm's named retired sibling is present.
|
|
911
|
+
// This only selects the existing stale-tree repair outcome; it never removes
|
|
912
|
+
// files, and any observed signature change still suppresses stale classification.
|
|
913
|
+
return snapshot.observed ||
|
|
914
|
+
(snapshot.nonRetiredObserved && snapshot.retiredSiblingPresent === true);
|
|
915
|
+
}
|
|
916
|
+
const DEFAULT_INSTALL_TREE_STALE_PROBE_MS = 1_500;
|
|
235
917
|
/**
|
|
236
918
|
* Poll until the install tree has been continuously READY for `quietMs`, or the
|
|
237
|
-
*
|
|
238
|
-
* (ii) the missing target is present, and — when `packageRoot` is known —
|
|
239
|
-
* (iii) `<packageRoot>/package.json` parses with `name === CLI_NAME` and
|
|
240
|
-
*
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
* bounded, so
|
|
919
|
+
* wait exhausts its bounds. READY means: (i) no FRESH update lock held by another
|
|
920
|
+
* pid, (ii) the missing target is present, and — when `packageRoot` is known —
|
|
921
|
+
* (iii) `<packageRoot>/package.json` parses with `name === CLI_NAME` and (iv) no
|
|
922
|
+
* `.<leaf>-<rand>` retired sibling remains beside it. Every filesystem error makes
|
|
923
|
+
* its condition "not ready" rather than throwing.
|
|
924
|
+
*
|
|
925
|
+
* The wait is LOCK-AWARE and bounded, so a live cooperating writer (the desktop
|
|
926
|
+
* app, the box's update timer, another `hq`) cannot make a legitimately-in-progress
|
|
927
|
+
* reinstall look stale:
|
|
928
|
+
* - UNLOCKED time — wall time observed with no fresh foreign lock — is bounded
|
|
929
|
+
* by `deadlineMs`. If the target is still missing and the observable tree
|
|
930
|
+
* signature stays unchanged for `staleProbeMs`, the wait returns `staleTree`
|
|
931
|
+
* early. When only a named retired npm sibling's deep scan is incomplete,
|
|
932
|
+
* a stable partial signature ends the wait early as `retiredSiblingUnverified`
|
|
933
|
+
* instead. That outcome preserves uncertainty and tells the user to wait for
|
|
934
|
+
* any installer before attempting a repair. Any observed signature change
|
|
935
|
+
* keeps the ordinary settle deadline in force. `deadlineMs === 0` evaluates
|
|
936
|
+
* readiness once.
|
|
937
|
+
* - LOCKED time — wall time observed under a fresh foreign lock held by a live
|
|
938
|
+
* pid — is bounded SEPARATELY by `lockWaitMs` (default the lock contract's own
|
|
939
|
+
* 10-minute staleness window) and does NOT consume the settle budget. When
|
|
940
|
+
* that ceiling is reached with the lock still held, the result is unsettled
|
|
941
|
+
* with `lockHeldAtEnd` true so the seam can report a distinct `lock-held`
|
|
942
|
+
* outcome and remedy rather than telling the user to reinstall over a live
|
|
943
|
+
* writer.
|
|
944
|
+
* Each poll's REAL elapsed interval (now() deltas) is attributed to the locked or
|
|
945
|
+
* unlocked bucket by whether a fresh foreign lock was held when the interval
|
|
946
|
+
* began, so a starved event loop only makes the wait coarser, never unbounded. A
|
|
947
|
+
* stale lock (dead pid, older than the staleness window, unparseable) or our own
|
|
948
|
+
* pid never extends anything. The whole wait is bounded (≤ `deadlineMs +
|
|
949
|
+
* lockWaitMs`), and the unchanged-tree path normally returns after the much
|
|
950
|
+
* shorter `staleProbeMs` observation window.
|
|
244
951
|
*/
|
|
245
952
|
export async function waitForInstallTreeSettled(args) {
|
|
246
953
|
const now = args.now ?? Date.now;
|
|
@@ -250,16 +957,65 @@ export async function waitForInstallTreeSettled(args) {
|
|
|
250
957
|
const pollMs = args.pollMs ?? 250;
|
|
251
958
|
const quietMs = args.quietMs ?? 1500;
|
|
252
959
|
const deadlineMs = args.deadlineMs;
|
|
960
|
+
const lockWaitMs = args.lockWaitMs ?? DEFAULT_INSTALL_SETTLE_LOCK_WAIT_MS;
|
|
961
|
+
const staleProbeMs = Math.max(0, args.staleProbeMs ?? DEFAULT_INSTALL_TREE_STALE_PROBE_MS);
|
|
253
962
|
const start = now();
|
|
963
|
+
let lastActivitySnapshot = installTreeActivitySignature(args.target, args.packageRoot, fs);
|
|
964
|
+
let staleObservationStartedAt = canProbeUnsettledRetiredSibling(lastActivitySnapshot) ? start : null;
|
|
965
|
+
let sawTreeChange = false;
|
|
254
966
|
let readySince = null;
|
|
255
967
|
let sawLock = false;
|
|
256
968
|
let sawRetired = false;
|
|
969
|
+
let lockedMs = 0;
|
|
970
|
+
let unlockedMs = 0;
|
|
971
|
+
let lockTool = "";
|
|
972
|
+
let prevT = start;
|
|
973
|
+
let prevForeignLockHeld = false;
|
|
974
|
+
let lockExtendedFired = false;
|
|
257
975
|
for (;;) {
|
|
258
976
|
const t = now();
|
|
259
|
-
|
|
260
|
-
|
|
977
|
+
// Attribute the interval that just elapsed [prevT, t) to the bucket for the
|
|
978
|
+
// lock state that held when it BEGAN (real now() deltas, never nominal pollMs).
|
|
979
|
+
if (prevForeignLockHeld)
|
|
980
|
+
lockedMs += t - prevT;
|
|
981
|
+
else
|
|
982
|
+
unlockedMs += t - prevT;
|
|
983
|
+
const lock = freshForeignLock(args.lockPath, t, isPidAlive, fs);
|
|
984
|
+
const foreignLockHeld = lock !== null;
|
|
985
|
+
if (foreignLockHeld) {
|
|
261
986
|
sawLock = true;
|
|
262
|
-
|
|
987
|
+
lockTool = boundedDiagnosticValue(lock.tool, LOCK_TOOL_BYTES);
|
|
988
|
+
}
|
|
989
|
+
if (!sawTreeChange) {
|
|
990
|
+
const activitySnapshot = installTreeActivitySignature(args.target, args.packageRoot, fs);
|
|
991
|
+
const previousCanProbe = canProbeUnsettledRetiredSibling(lastActivitySnapshot);
|
|
992
|
+
const currentCanProbe = canProbeUnsettledRetiredSibling(activitySnapshot);
|
|
993
|
+
if (previousCanProbe && currentCanProbe && activitySnapshot.value !== lastActivitySnapshot.value) {
|
|
994
|
+
sawTreeChange = true;
|
|
995
|
+
staleObservationStartedAt = null;
|
|
996
|
+
}
|
|
997
|
+
else if (!currentCanProbe) {
|
|
998
|
+
staleObservationStartedAt = null;
|
|
999
|
+
}
|
|
1000
|
+
else if (!previousCanProbe) {
|
|
1001
|
+
staleObservationStartedAt = t;
|
|
1002
|
+
}
|
|
1003
|
+
lastActivitySnapshot = activitySnapshot;
|
|
1004
|
+
}
|
|
1005
|
+
let retiredPresent = null;
|
|
1006
|
+
let retiredCheckFailed = false;
|
|
1007
|
+
if (args.packageRoot) {
|
|
1008
|
+
try {
|
|
1009
|
+
retiredPresent = retiredSiblingPresent(args.packageRoot, fs);
|
|
1010
|
+
if (retiredPresent)
|
|
1011
|
+
sawRetired = true;
|
|
1012
|
+
}
|
|
1013
|
+
catch {
|
|
1014
|
+
retiredPresent = null;
|
|
1015
|
+
retiredCheckFailed = true;
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
let ready = !foreignLockHeld && installTargetPresent(args.target, fs);
|
|
263
1019
|
if (ready && args.packageRoot) {
|
|
264
1020
|
try {
|
|
265
1021
|
if (!packageRootHealthy(args.packageRoot, fs))
|
|
@@ -268,17 +1024,8 @@ export async function waitForInstallTreeSettled(args) {
|
|
|
268
1024
|
catch {
|
|
269
1025
|
ready = false;
|
|
270
1026
|
}
|
|
271
|
-
if (ready)
|
|
272
|
-
|
|
273
|
-
if (retiredSiblingPresent(args.packageRoot, fs)) {
|
|
274
|
-
sawRetired = true;
|
|
275
|
-
ready = false;
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
catch {
|
|
279
|
-
ready = false;
|
|
280
|
-
}
|
|
281
|
-
}
|
|
1027
|
+
if (ready && (retiredPresent || retiredCheckFailed))
|
|
1028
|
+
ready = false;
|
|
282
1029
|
}
|
|
283
1030
|
if (ready) {
|
|
284
1031
|
if (readySince === null)
|
|
@@ -289,16 +1036,137 @@ export async function waitForInstallTreeSettled(args) {
|
|
|
289
1036
|
}
|
|
290
1037
|
const waitedMs = t - start;
|
|
291
1038
|
if (ready && (deadlineMs === 0 || t - readySince >= quietMs)) {
|
|
292
|
-
|
|
1039
|
+
// Settling requires no foreign lock, so it is never held at the end here.
|
|
1040
|
+
return {
|
|
1041
|
+
settled: true,
|
|
1042
|
+
waitedMs,
|
|
1043
|
+
sawLock,
|
|
1044
|
+
sawRetired,
|
|
1045
|
+
lockHeldAtEnd: false,
|
|
1046
|
+
lockedMs,
|
|
1047
|
+
lockTool,
|
|
1048
|
+
sawTreeChange,
|
|
1049
|
+
staleTree: false,
|
|
1050
|
+
retiredSiblingPresent: retiredPresent,
|
|
1051
|
+
retiredSiblingKind: retiredSiblingKind(args.packageRoot, fs),
|
|
1052
|
+
installTargetState: installTargetState(args.target, args.packageRoot, fs),
|
|
1053
|
+
updaterPidAlive: updaterPidAlive(args.lockPath, fs, isPidAlive),
|
|
1054
|
+
};
|
|
1055
|
+
}
|
|
1056
|
+
if (!ready &&
|
|
1057
|
+
!foreignLockHeld &&
|
|
1058
|
+
!retiredCheckFailed &&
|
|
1059
|
+
!sawLock &&
|
|
1060
|
+
!sawTreeChange &&
|
|
1061
|
+
staleObservationStartedAt !== null &&
|
|
1062
|
+
t - staleObservationStartedAt >= staleProbeMs) {
|
|
1063
|
+
return {
|
|
1064
|
+
settled: false,
|
|
1065
|
+
waitedMs,
|
|
1066
|
+
sawLock,
|
|
1067
|
+
sawRetired,
|
|
1068
|
+
lockHeldAtEnd: false,
|
|
1069
|
+
lockedMs,
|
|
1070
|
+
lockTool,
|
|
1071
|
+
sawTreeChange,
|
|
1072
|
+
staleTree: lastActivitySnapshot.observed,
|
|
1073
|
+
retiredSiblingPresent: retiredPresent,
|
|
1074
|
+
retiredSiblingUnverified: !lastActivitySnapshot.observed && lastActivitySnapshot.retiredSiblingPresent === true,
|
|
1075
|
+
retiredSiblingKind: retiredSiblingKind(args.packageRoot, fs),
|
|
1076
|
+
installTargetState: installTargetState(args.target, args.packageRoot, fs),
|
|
1077
|
+
updaterPidAlive: updaterPidAlive(args.lockPath, fs, isPidAlive),
|
|
1078
|
+
};
|
|
1079
|
+
}
|
|
1080
|
+
// Give up when the TREE has had a full unlocked budget with no writer visible,
|
|
1081
|
+
// OR a writer is STILL holding the lock and has held it past its own staleness
|
|
1082
|
+
// ceiling. The lock ceiling is gated on a lock being held RIGHT NOW so that a
|
|
1083
|
+
// ceiling of 0 (HQ_INSTALL_SETTLE_LOCK_TIMEOUT_MS=0, "do not extend under a
|
|
1084
|
+
// lock") disables only the extension and does not collapse the ordinary
|
|
1085
|
+
// deadlineMs settle when no lock exists — `lockedMs` is 0 ≥ 0 on every poll.
|
|
1086
|
+
// `deadlineMs` 0 makes the unlocked test fire on the first poll (evaluate-once),
|
|
1087
|
+
// matching the pre-lock-aware contract; `lockHeldAtEnd` distinguishes the causes.
|
|
1088
|
+
if (unlockedMs >= deadlineMs || (foreignLockHeld && lockedMs >= lockWaitMs)) {
|
|
1089
|
+
return {
|
|
1090
|
+
settled: false,
|
|
1091
|
+
waitedMs,
|
|
1092
|
+
sawLock,
|
|
1093
|
+
sawRetired,
|
|
1094
|
+
lockHeldAtEnd: foreignLockHeld,
|
|
1095
|
+
lockedMs,
|
|
1096
|
+
lockTool,
|
|
1097
|
+
sawTreeChange,
|
|
1098
|
+
staleTree: false,
|
|
1099
|
+
retiredSiblingPresent: retiredPresent,
|
|
1100
|
+
retiredSiblingKind: retiredSiblingKind(args.packageRoot, fs),
|
|
1101
|
+
installTargetState: installTargetState(args.target, args.packageRoot, fs),
|
|
1102
|
+
updaterPidAlive: updaterPidAlive(args.lockPath, fs, isPidAlive),
|
|
1103
|
+
};
|
|
293
1104
|
}
|
|
294
|
-
|
|
295
|
-
|
|
1105
|
+
// The first poll at which the wait has reached `deadlineMs` while a lock is
|
|
1106
|
+
// still held is exactly where the pre-lock-aware wait gave up — announce the
|
|
1107
|
+
// extension once, and only when we are genuinely going to keep waiting.
|
|
1108
|
+
if (!lockExtendedFired && foreignLockHeld && waitedMs >= deadlineMs) {
|
|
1109
|
+
lockExtendedFired = true;
|
|
1110
|
+
args.onLockExtended?.();
|
|
296
1111
|
}
|
|
1112
|
+
prevT = t;
|
|
1113
|
+
prevForeignLockHeld = foreignLockHeld;
|
|
297
1114
|
await sleep(pollMs);
|
|
298
1115
|
}
|
|
299
1116
|
}
|
|
1117
|
+
/**
|
|
1118
|
+
* Whether packageRoot's own manifest is ABSENT (ENOENT) or name-mismatched — a
|
|
1119
|
+
* mid-extraction rewrite signal (npm has renamed the dir aside and is re-writing
|
|
1120
|
+
* package.json). A read error OTHER than ENOENT (EACCES/EPERM) is a benign
|
|
1121
|
+
* permission fault, not a rewrite, so it returns false rather than a false signal.
|
|
1122
|
+
*/
|
|
1123
|
+
function manifestRewriteSignal(packageRoot, fs) {
|
|
1124
|
+
let raw;
|
|
1125
|
+
try {
|
|
1126
|
+
raw = fs.readFileSync(path.join(packageRoot, "package.json"), "utf-8");
|
|
1127
|
+
}
|
|
1128
|
+
catch (err) {
|
|
1129
|
+
return err?.code === "ENOENT";
|
|
1130
|
+
}
|
|
1131
|
+
try {
|
|
1132
|
+
return JSON.parse(raw).name !== CLI_NAME;
|
|
1133
|
+
}
|
|
1134
|
+
catch {
|
|
1135
|
+
return true; // present but unparseable → mid-write
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
/**
|
|
1139
|
+
* Whether a global reinstall is PROVABLY rewriting the install tree right now —
|
|
1140
|
+
* the positive writer signal the eval-throw gate requires before it will pay a
|
|
1141
|
+
* settle wait. True iff (i) a fresh foreign update lock is held, (ii) packageRoot's
|
|
1142
|
+
* manifest is absent or name-mismatched (mid-extraction), or (iii) a
|
|
1143
|
+
* `.<leaf>-<hash>` retired sibling sits beside it. Crucially it is POSITIVE: a
|
|
1144
|
+
* benign filesystem error that merely prevents READING the manifest or LISTING the
|
|
1145
|
+
* parent (EACCES/EPERM) is NOT a signal, so a persistent third-party load-time
|
|
1146
|
+
* defect on an otherwise-usable install never pays a spurious 90s wait. Every
|
|
1147
|
+
* dependency is injectable so the recovery seam stays hermetic.
|
|
1148
|
+
*/
|
|
1149
|
+
export function installRewriteInProgress(args) {
|
|
1150
|
+
const now = (args.now ?? Date.now)();
|
|
1151
|
+
const fs = args.fs ?? nodeInstallTreeFs;
|
|
1152
|
+
const isPidAlive = args.isPidAlive ?? defaultIsPidAlive;
|
|
1153
|
+
// #570 renamed freshForeignLockHeld → freshForeignLock, which returns the lock
|
|
1154
|
+
// info (or null) instead of a boolean; a fresh foreign lock is held iff non-null.
|
|
1155
|
+
if (freshForeignLock(args.lockPath, now, isPidAlive, fs) !== null)
|
|
1156
|
+
return true;
|
|
1157
|
+
if (!args.packageRoot)
|
|
1158
|
+
return false;
|
|
1159
|
+
if (manifestRewriteSignal(args.packageRoot, fs))
|
|
1160
|
+
return true;
|
|
1161
|
+
try {
|
|
1162
|
+
return retiredSiblingPresent(args.packageRoot, fs);
|
|
1163
|
+
}
|
|
1164
|
+
catch {
|
|
1165
|
+
return false; // parent not listable — benign, not a rewrite signal
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
300
1168
|
/** The fixed, input-free carrier message (grouping cardinality stays bounded). */
|
|
301
|
-
const INSTALL_TREE_TORN_MESSAGE = "hq-cli install tree
|
|
1169
|
+
const INSTALL_TREE_TORN_MESSAGE = "hq-cli could not load a module from its install tree and automatic recovery did not complete";
|
|
302
1170
|
/**
|
|
303
1171
|
* A torn-install failure that stays VISIBLE in Sentry with bounded, hq-derived
|
|
304
1172
|
* diagnostics. Fixed `name`/`message` (no argv, path, or free text in either),
|
|
@@ -312,19 +1180,35 @@ export class InstallTreeTornError extends Error {
|
|
|
312
1180
|
super(INSTALL_TREE_TORN_MESSAGE);
|
|
313
1181
|
this.name = "InstallTreeTornError";
|
|
314
1182
|
this.cause = init.cause;
|
|
315
|
-
|
|
1183
|
+
const sawTreeChange = init.sawTreeChange ?? false;
|
|
1184
|
+
const treeState = init.treeState ?? (init.outcome === "stale_tree" ? "stale" : "in_flight");
|
|
1185
|
+
const diagnostics = {
|
|
316
1186
|
dialect: init.classified.dialect,
|
|
317
1187
|
code: init.classified.code,
|
|
318
1188
|
specifier: boundedDiagnosticValue(init.classified.specifier, SPECIFIER_BYTES),
|
|
319
1189
|
importer: boundedDiagnosticValue(init.classified.importer, IMPORTER_BYTES),
|
|
320
1190
|
packageRoot: boundedDiagnosticValue(init.packageRoot ?? "", PACKAGE_ROOT_BYTES),
|
|
321
1191
|
outcome: init.outcome,
|
|
1192
|
+
treeState,
|
|
322
1193
|
attempt: init.attempt,
|
|
323
1194
|
waitedMs: init.waitedMs,
|
|
324
1195
|
sawLock: init.sawLock,
|
|
325
1196
|
sawRetired: init.sawRetired,
|
|
1197
|
+
sawTreeChange,
|
|
1198
|
+
lockHeldAtEnd: init.lockHeldAtEnd ?? false,
|
|
1199
|
+
lockedMs: init.lockedMs ?? 0,
|
|
1200
|
+
lockTool: boundedDiagnosticValue(init.lockTool ?? "", LOCK_TOOL_BYTES),
|
|
326
1201
|
node: process.version,
|
|
1202
|
+
errorName: boundedDiagnosticValue(init.classified.errorName ?? "", ERRORNAME_BYTES),
|
|
1203
|
+
retiredSiblingKind: init.retiredSiblingKind ?? "unknown",
|
|
1204
|
+
installTargetState: init.installTargetState ?? "unknown",
|
|
1205
|
+
versionGatePhase: init.versionGatePhase ?? "unknown",
|
|
1206
|
+
updaterPidAlive: init.updaterPidAlive ?? "unknown",
|
|
327
1207
|
};
|
|
1208
|
+
if (typeof init.retiredSiblingPresent === "boolean") {
|
|
1209
|
+
diagnostics.retiredSiblingPresent = init.retiredSiblingPresent;
|
|
1210
|
+
}
|
|
1211
|
+
this.diagnostics = diagnostics;
|
|
328
1212
|
Object.setPrototypeOf(this, new.target.prototype);
|
|
329
1213
|
}
|
|
330
1214
|
}
|
|
@@ -332,8 +1216,45 @@ export function isInstallTreeTornError(err) {
|
|
|
332
1216
|
return err instanceof InstallTreeTornError;
|
|
333
1217
|
}
|
|
334
1218
|
/** The exact Sentry `contexts` payload for a captured torn-install failure. */
|
|
335
|
-
export function installTreeTornCaptureContext(err) {
|
|
336
|
-
|
|
1219
|
+
export function installTreeTornCaptureContext(err, homeDirectory = homedir()) {
|
|
1220
|
+
const diagnostics = err.diagnostics;
|
|
1221
|
+
return {
|
|
1222
|
+
contexts: {
|
|
1223
|
+
install_tree_torn: {
|
|
1224
|
+
...diagnostics,
|
|
1225
|
+
specifier: scrubHomeDirectoryPrefix(diagnostics.specifier, homeDirectory),
|
|
1226
|
+
importer: scrubHomeDirectoryPrefix(diagnostics.importer, homeDirectory),
|
|
1227
|
+
packageRoot: scrubHomeDirectoryPrefix(diagnostics.packageRoot, homeDirectory),
|
|
1228
|
+
},
|
|
1229
|
+
},
|
|
1230
|
+
};
|
|
1231
|
+
}
|
|
1232
|
+
function looksLikeWindowsPath(value) {
|
|
1233
|
+
return /^[a-zA-Z]:[\\/]/.test(value) || /^\\\\/.test(value);
|
|
1234
|
+
}
|
|
1235
|
+
/** Replace a home-directory prefix without matching similarly-named sibling folders. */
|
|
1236
|
+
export function scrubHomeDirectoryPrefix(value, homeDirectory = homedir()) {
|
|
1237
|
+
if (!value || !homeDirectory)
|
|
1238
|
+
return value;
|
|
1239
|
+
if (looksLikeWindowsPath(value) || looksLikeWindowsPath(homeDirectory)) {
|
|
1240
|
+
const home = path.win32.normalize(homeDirectory).replace(/[\\/]+$/, "");
|
|
1241
|
+
const normalized = path.win32.normalize(value);
|
|
1242
|
+
const foldedHome = home.toLowerCase();
|
|
1243
|
+
const foldedValue = normalized.toLowerCase();
|
|
1244
|
+
if (foldedValue === foldedHome)
|
|
1245
|
+
return "~";
|
|
1246
|
+
const prefix = `${foldedHome}\\`;
|
|
1247
|
+
if (foldedValue.startsWith(prefix))
|
|
1248
|
+
return `~\\${normalized.slice(home.length + 1)}`;
|
|
1249
|
+
return value;
|
|
1250
|
+
}
|
|
1251
|
+
const home = path.posix.normalize(homeDirectory).replace(/\/+$/, "");
|
|
1252
|
+
const normalized = path.posix.normalize(value);
|
|
1253
|
+
if (normalized === home)
|
|
1254
|
+
return "~";
|
|
1255
|
+
if (normalized.startsWith(`${home}/`))
|
|
1256
|
+
return `~/${normalized.slice(home.length + 1)}`;
|
|
1257
|
+
return value;
|
|
337
1258
|
}
|
|
338
1259
|
/**
|
|
339
1260
|
* The fixed, input-free operator remedy. It names the likely writers (so a
|
|
@@ -341,19 +1262,45 @@ export function installTreeTornCaptureContext(err) {
|
|
|
341
1262
|
* and interpolates NOTHING — the only per-event value is the bounded specifier
|
|
342
1263
|
* appended by {@link installTreeTornStderrLine}.
|
|
343
1264
|
*/
|
|
344
|
-
export const INSTALL_TREE_TORN_REMEDY = "
|
|
345
|
-
"
|
|
346
|
-
"
|
|
347
|
-
"
|
|
1265
|
+
export const INSTALL_TREE_TORN_REMEDY = "hq-cli could not finish automatic install-tree recovery. Re-run your command; " +
|
|
1266
|
+
"if it still fails, reinstall with `npm install -g @indigoai-us/hq-cli@latest` " +
|
|
1267
|
+
"(or `pnpm add -g @indigoai-us/hq-cli@latest` / `bun add -g @indigoai-us/hq-cli@latest` " +
|
|
1268
|
+
"when that manager owns your install).";
|
|
1269
|
+
/** Fixed repair guidance for an unchanged tree with no active updater signal. */
|
|
1270
|
+
export const INSTALL_TREE_STALE_REMEDY = "hq-cli's install tree is incomplete and no active updater was detected. " +
|
|
1271
|
+
"Reinstall with `npm install -g @indigoai-us/hq-cli@latest` " +
|
|
1272
|
+
"(or `pnpm add -g @indigoai-us/hq-cli@latest` / `bun add -g @indigoai-us/hq-cli@latest` " +
|
|
1273
|
+
"when that manager owns your install), then run the command again.";
|
|
1274
|
+
/** Guidance when a retired package sibling's activity could not be verified. */
|
|
1275
|
+
export const INSTALL_TREE_RETIRED_UNVERIFIED_REMEDY = "hq-cli found a retired install sibling but could not verify whether an installer is still using it. Wait for any npm or desktop CLI update to finish, then run the command again. If no install is running, repair with `npm install -g @indigoai-us/hq-cli@latest` " +
|
|
1276
|
+
"(or `pnpm add -g @indigoai-us/hq-cli@latest` / `bun add -g @indigoai-us/hq-cli@latest` " +
|
|
1277
|
+
"when that manager owns your install).";
|
|
1278
|
+
/**
|
|
1279
|
+
* The fixed, input-free remedy for the 'lock-held' outcome: a cooperating writer
|
|
1280
|
+
* held the shared update lock past its own staleness ceiling. Telling the user to
|
|
1281
|
+
* `npm i -g` here would collide with a live installer mid-rename — the exact race
|
|
1282
|
+
* update-lock.ts exists to prevent — so this remedy tells them to let the running
|
|
1283
|
+
* update finish and NEVER to reinstall over it. Interpolates NOTHING.
|
|
1284
|
+
*/
|
|
1285
|
+
export const INSTALL_TREE_LOCK_HELD_REMEDY = "another hq updater (the desktop app, the box's hq-cli-update timer, or another " +
|
|
1286
|
+
"hq command) was still installing hq-cli when this command stopped waiting. Let " +
|
|
1287
|
+
"that update finish, then re-run your command; do not reinstall while it is running.";
|
|
348
1288
|
/**
|
|
349
1289
|
* The single actionable stderr line for a captured torn-install failure: the
|
|
350
|
-
* fixed remedy plus the bounded, hq-derived missing specifier — the only
|
|
351
|
-
* interpolated value, never argv.
|
|
1290
|
+
* outcome's fixed remedy plus the bounded, hq-derived missing specifier — the only
|
|
1291
|
+
* interpolated value, never argv. A 'lock-held' outcome selects the "let the
|
|
1292
|
+
* update finish" remedy (never the reinstall advice); every other outcome keeps
|
|
1293
|
+
* {@link INSTALL_TREE_TORN_REMEDY} byte-for-byte.
|
|
352
1294
|
*/
|
|
353
1295
|
export function installTreeTornStderrLine(err) {
|
|
1296
|
+
const remedy = err.diagnostics.outcome === "lock-held"
|
|
1297
|
+
? INSTALL_TREE_LOCK_HELD_REMEDY
|
|
1298
|
+
: err.diagnostics.outcome === "stale_tree"
|
|
1299
|
+
? INSTALL_TREE_STALE_REMEDY
|
|
1300
|
+
: err.diagnostics.outcome === "retired_unverified"
|
|
1301
|
+
? INSTALL_TREE_RETIRED_UNVERIFIED_REMEDY
|
|
1302
|
+
: INSTALL_TREE_TORN_REMEDY;
|
|
354
1303
|
const specifier = err.diagnostics.specifier;
|
|
355
|
-
return specifier
|
|
356
|
-
? `${INSTALL_TREE_TORN_REMEDY} (missing: ${specifier})`
|
|
357
|
-
: INSTALL_TREE_TORN_REMEDY;
|
|
1304
|
+
return specifier ? `${remedy} (missing: ${specifier})` : remedy;
|
|
358
1305
|
}
|
|
359
1306
|
//# sourceMappingURL=install-tree-torn.js.map
|