@miller-tech/uap 2.21.3 → 2.36.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -10
- package/config/model-profiles/qwen38-coder390.json +46 -0
- package/config/model-profiles/qwen38.json +3 -2
- package/config/model-registry.json +110 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/benchmarks/paired/types.d.ts +2 -2
- package/dist/bin/cli.js +315 -20
- package/dist/bin/cli.js.map +1 -1
- package/dist/cli/attention.d.ts +6 -0
- package/dist/cli/attention.d.ts.map +1 -0
- package/dist/cli/attention.js +115 -0
- package/dist/cli/attention.js.map +1 -0
- package/dist/cli/bench-report.d.ts +82 -0
- package/dist/cli/bench-report.d.ts.map +1 -0
- package/dist/cli/bench-report.js +237 -0
- package/dist/cli/bench-report.js.map +1 -0
- package/dist/cli/clients.d.ts +6 -0
- package/dist/cli/clients.d.ts.map +1 -0
- package/dist/cli/clients.js +142 -0
- package/dist/cli/clients.js.map +1 -0
- package/dist/cli/dashboard-grants.d.ts +26 -0
- package/dist/cli/dashboard-grants.d.ts.map +1 -0
- package/dist/cli/dashboard-grants.js +69 -0
- package/dist/cli/dashboard-grants.js.map +1 -0
- package/dist/cli/dashboard-pace.d.ts +31 -0
- package/dist/cli/dashboard-pace.d.ts.map +1 -0
- package/dist/cli/dashboard-pace.js +42 -0
- package/dist/cli/dashboard-pace.js.map +1 -0
- package/dist/cli/dashboard-session.d.ts +25 -0
- package/dist/cli/dashboard-session.d.ts.map +1 -0
- package/dist/cli/dashboard-session.js +814 -0
- package/dist/cli/dashboard-session.js.map +1 -0
- package/dist/cli/dashboard-types.d.ts +18 -0
- package/dist/cli/dashboard-types.d.ts.map +1 -0
- package/dist/cli/dashboard-types.js +9 -0
- package/dist/cli/dashboard-types.js.map +1 -0
- package/dist/cli/dashboard.d.ts +2 -18
- package/dist/cli/dashboard.d.ts.map +1 -1
- package/dist/cli/dashboard.js +43 -793
- package/dist/cli/dashboard.js.map +1 -1
- package/dist/cli/deliver.d.ts +35 -0
- package/dist/cli/deliver.d.ts.map +1 -1
- package/dist/cli/deliver.js +93 -9
- package/dist/cli/deliver.js.map +1 -1
- package/dist/cli/diff.d.ts +85 -0
- package/dist/cli/diff.d.ts.map +1 -0
- package/dist/cli/diff.js +293 -0
- package/dist/cli/diff.js.map +1 -0
- package/dist/cli/eta.d.ts +35 -0
- package/dist/cli/eta.d.ts.map +1 -0
- package/dist/cli/eta.js +101 -0
- package/dist/cli/eta.js.map +1 -0
- package/dist/cli/handsfree.d.ts +7 -0
- package/dist/cli/handsfree.d.ts.map +1 -1
- package/dist/cli/handsfree.js +27 -0
- package/dist/cli/handsfree.js.map +1 -1
- package/dist/cli/hooks.d.ts.map +1 -1
- package/dist/cli/hooks.js +126 -5
- package/dist/cli/hooks.js.map +1 -1
- package/dist/cli/loops.d.ts +24 -5
- package/dist/cli/loops.d.ts.map +1 -1
- package/dist/cli/loops.js +92 -12
- package/dist/cli/loops.js.map +1 -1
- package/dist/cli/models.d.ts +62 -0
- package/dist/cli/models.d.ts.map +1 -0
- package/dist/cli/models.js +567 -0
- package/dist/cli/models.js.map +1 -0
- package/dist/cli/plan.d.ts +9 -0
- package/dist/cli/plan.d.ts.map +1 -1
- package/dist/cli/plan.js +57 -4
- package/dist/cli/plan.js.map +1 -1
- package/dist/cli/proxy-relay.d.ts +55 -0
- package/dist/cli/proxy-relay.d.ts.map +1 -0
- package/dist/cli/proxy-relay.js +116 -0
- package/dist/cli/proxy-relay.js.map +1 -0
- package/dist/cli/proxy.d.ts +4 -0
- package/dist/cli/proxy.d.ts.map +1 -1
- package/dist/cli/proxy.js +26 -1
- package/dist/cli/proxy.js.map +1 -1
- package/dist/cli/sandbox.d.ts +101 -4
- package/dist/cli/sandbox.d.ts.map +1 -1
- package/dist/cli/sandbox.js +393 -44
- package/dist/cli/sandbox.js.map +1 -1
- package/dist/cli/self.d.ts +13 -0
- package/dist/cli/self.d.ts.map +1 -0
- package/dist/cli/self.js +94 -0
- package/dist/cli/self.js.map +1 -0
- package/dist/cli/systemd-services.d.ts +2 -8
- package/dist/cli/systemd-services.d.ts.map +1 -1
- package/dist/cli/systemd-services.js +5 -20
- package/dist/cli/systemd-services.js.map +1 -1
- package/dist/cli/task.js +1 -1
- package/dist/cli/task.js.map +1 -1
- package/dist/cli/wizard-config.d.ts.map +1 -1
- package/dist/cli/wizard-config.js +31 -2
- package/dist/cli/wizard-config.js.map +1 -1
- package/dist/config/settings-registry.d.ts +1 -1
- package/dist/config/settings-registry.d.ts.map +1 -1
- package/dist/config/settings-registry.js +108 -0
- package/dist/config/settings-registry.js.map +1 -1
- package/dist/coordination/capability-router.js +2 -2
- package/dist/coordination/capability-router.js.map +1 -1
- package/dist/coordination/database.d.ts +13 -0
- package/dist/coordination/database.d.ts.map +1 -1
- package/dist/coordination/database.js +63 -7
- package/dist/coordination/database.js.map +1 -1
- package/dist/coordination/eta-inject.d.ts +32 -0
- package/dist/coordination/eta-inject.d.ts.map +1 -0
- package/dist/coordination/eta-inject.js +64 -0
- package/dist/coordination/eta-inject.js.map +1 -0
- package/dist/coordination/reactor.d.ts.map +1 -1
- package/dist/coordination/reactor.js +14 -0
- package/dist/coordination/reactor.js.map +1 -1
- package/dist/coordination/service.d.ts +18 -8
- package/dist/coordination/service.d.ts.map +1 -1
- package/dist/coordination/service.js +38 -28
- package/dist/coordination/service.js.map +1 -1
- package/dist/dashboard/client-registry.d.ts +163 -0
- package/dist/dashboard/client-registry.d.ts.map +1 -0
- package/dist/dashboard/client-registry.js +549 -0
- package/dist/dashboard/client-registry.js.map +1 -0
- package/dist/dashboard/controls.d.ts.map +1 -1
- package/dist/dashboard/controls.js +33 -4
- package/dist/dashboard/controls.js.map +1 -1
- package/dist/dashboard/data-seeder.d.ts +10 -7
- package/dist/dashboard/data-seeder.d.ts.map +1 -1
- package/dist/dashboard/data-seeder.js +31 -75
- package/dist/dashboard/data-seeder.js.map +1 -1
- package/dist/dashboard/data-service.d.ts +9 -0
- package/dist/dashboard/data-service.d.ts.map +1 -1
- package/dist/dashboard/data-service.js +32 -3
- package/dist/dashboard/data-service.js.map +1 -1
- package/dist/dashboard/placement-routes.d.ts +119 -0
- package/dist/dashboard/placement-routes.d.ts.map +1 -0
- package/dist/dashboard/placement-routes.js +331 -0
- package/dist/dashboard/placement-routes.js.map +1 -0
- package/dist/dashboard/server.d.ts.map +1 -1
- package/dist/dashboard/server.js +408 -2
- package/dist/dashboard/server.js.map +1 -1
- package/dist/delivery/attention.d.ts +130 -0
- package/dist/delivery/attention.d.ts.map +1 -0
- package/dist/delivery/attention.js +341 -0
- package/dist/delivery/attention.js.map +1 -0
- package/dist/delivery/decompose.d.ts +18 -0
- package/dist/delivery/decompose.d.ts.map +1 -1
- package/dist/delivery/decompose.js +22 -1
- package/dist/delivery/decompose.js.map +1 -1
- package/dist/delivery/eta-estimate.d.ts +111 -0
- package/dist/delivery/eta-estimate.d.ts.map +1 -0
- package/dist/delivery/eta-estimate.js +171 -0
- package/dist/delivery/eta-estimate.js.map +1 -0
- package/dist/delivery/eta.d.ts +23 -0
- package/dist/delivery/eta.d.ts.map +1 -0
- package/dist/delivery/eta.js +59 -0
- package/dist/delivery/eta.js.map +1 -0
- package/dist/delivery/orchestrated-mission.d.ts +10 -0
- package/dist/delivery/orchestrated-mission.d.ts.map +1 -1
- package/dist/delivery/orchestrated-mission.js +15 -1
- package/dist/delivery/orchestrated-mission.js.map +1 -1
- package/dist/delivery/plan-check.d.ts +7 -1
- package/dist/delivery/plan-check.d.ts.map +1 -1
- package/dist/delivery/plan-check.js +23 -2
- package/dist/delivery/plan-check.js.map +1 -1
- package/dist/delivery/run-state.d.ts +1 -1
- package/dist/delivery/run-state.d.ts.map +1 -1
- package/dist/delivery/run-state.js +8 -1
- package/dist/delivery/run-state.js.map +1 -1
- package/dist/delivery/task-orchestrator.d.ts +8 -3
- package/dist/delivery/task-orchestrator.d.ts.map +1 -1
- package/dist/delivery/task-orchestrator.js +75 -43
- package/dist/delivery/task-orchestrator.js.map +1 -1
- package/dist/delivery/task-sync.d.ts +21 -0
- package/dist/delivery/task-sync.d.ts.map +1 -1
- package/dist/delivery/task-sync.js +44 -8
- package/dist/delivery/task-sync.js.map +1 -1
- package/dist/delivery/task-workspace.d.ts +3 -3
- package/dist/delivery/task-workspace.js +3 -3
- package/dist/generators/self-card.d.ts +65 -0
- package/dist/generators/self-card.d.ts.map +1 -0
- package/dist/generators/self-card.js +256 -0
- package/dist/generators/self-card.js.map +1 -0
- package/dist/inference/probe.js +1 -1
- package/dist/inference/probe.js.map +1 -1
- package/dist/memory/prepopulate.d.ts.map +1 -1
- package/dist/memory/prepopulate.js +2 -0
- package/dist/memory/prepopulate.js.map +1 -1
- package/dist/models/analytics.d.ts +32 -0
- package/dist/models/analytics.d.ts.map +1 -1
- package/dist/models/analytics.js +68 -5
- package/dist/models/analytics.js.map +1 -1
- package/dist/models/plan-readability.d.ts +55 -0
- package/dist/models/plan-readability.d.ts.map +1 -0
- package/dist/models/plan-readability.js +339 -0
- package/dist/models/plan-readability.js.map +1 -0
- package/dist/placement/admission.d.ts +59 -0
- package/dist/placement/admission.d.ts.map +1 -0
- package/dist/placement/admission.js +197 -0
- package/dist/placement/admission.js.map +1 -0
- package/dist/placement/auto.d.ts +44 -0
- package/dist/placement/auto.d.ts.map +1 -0
- package/dist/placement/auto.js +212 -0
- package/dist/placement/auto.js.map +1 -0
- package/dist/placement/enforce.d.ts +128 -0
- package/dist/placement/enforce.d.ts.map +1 -0
- package/dist/placement/enforce.js +655 -0
- package/dist/placement/enforce.js.map +1 -0
- package/dist/placement/idle.d.ts +50 -0
- package/dist/placement/idle.d.ts.map +1 -0
- package/dist/placement/idle.js +213 -0
- package/dist/placement/idle.js.map +1 -0
- package/dist/placement/ledger.d.ts +323 -0
- package/dist/placement/ledger.d.ts.map +1 -0
- package/dist/placement/ledger.js +263 -0
- package/dist/placement/ledger.js.map +1 -0
- package/dist/placement/preview.d.ts +51 -0
- package/dist/placement/preview.d.ts.map +1 -0
- package/dist/placement/preview.js +61 -0
- package/dist/placement/preview.js.map +1 -0
- package/dist/placement/probes.d.ts +47 -0
- package/dist/placement/probes.d.ts.map +1 -0
- package/dist/placement/probes.js +207 -0
- package/dist/placement/probes.js.map +1 -0
- package/dist/placement/proxy-env.d.ts +21 -0
- package/dist/placement/proxy-env.d.ts.map +1 -0
- package/dist/placement/proxy-env.js +42 -0
- package/dist/placement/proxy-env.js.map +1 -0
- package/dist/placement/registry.d.ts +1038 -0
- package/dist/placement/registry.d.ts.map +1 -0
- package/dist/placement/registry.js +274 -0
- package/dist/placement/registry.js.map +1 -0
- package/dist/policies/liveness.d.ts +6 -8
- package/dist/policies/liveness.d.ts.map +1 -1
- package/dist/policies/liveness.js +6 -25
- package/dist/policies/liveness.js.map +1 -1
- package/dist/policies/sandbox-anchor.d.ts +91 -0
- package/dist/policies/sandbox-anchor.d.ts.map +1 -0
- package/dist/policies/sandbox-anchor.js +187 -0
- package/dist/policies/sandbox-anchor.js.map +1 -0
- package/dist/policies/sandbox-grants.d.ts +131 -0
- package/dist/policies/sandbox-grants.d.ts.map +1 -0
- package/dist/policies/sandbox-grants.js +562 -0
- package/dist/policies/sandbox-grants.js.map +1 -0
- package/dist/state/manifest.d.ts +4 -2
- package/dist/state/manifest.d.ts.map +1 -1
- package/dist/state/manifest.js +32 -16
- package/dist/state/manifest.js.map +1 -1
- package/dist/utils/checkout-root.d.ts +2 -0
- package/dist/utils/checkout-root.d.ts.map +1 -0
- package/dist/utils/checkout-root.js +43 -0
- package/dist/utils/checkout-root.js.map +1 -0
- package/dist/utils/resolve-uap-bin.d.ts +5 -0
- package/dist/utils/resolve-uap-bin.d.ts.map +1 -0
- package/dist/utils/resolve-uap-bin.js +33 -0
- package/dist/utils/resolve-uap-bin.js.map +1 -0
- package/dist/utils/terminal-safe.d.ts +12 -0
- package/dist/utils/terminal-safe.d.ts.map +1 -0
- package/dist/utils/terminal-safe.js +53 -0
- package/dist/utils/terminal-safe.js.map +1 -0
- package/docs/ATTRIBUTION.md +1 -0
- package/docs/DASHBOARD_UPLIFT_SPEC.md +8 -8
- package/docs/INDEX.md +6 -5
- package/docs/architecture/OVERVIEW.md +15 -3
- package/docs/architecture/PROTOCOL.md +7 -1
- package/docs/architecture/adr/0006-operator-directed-model-placement.md +86 -0
- package/docs/architecture/adr/0007-auto-displacement-allowlist-as-standing-consent.md +79 -0
- package/docs/architecture/adr/0008-fleet-clients-link-out.md +92 -0
- package/docs/architecture/adr/0009-completion-triggered-dispatch-and-per-leaf-model-dials.md +71 -0
- package/docs/architecture/adr/0010-attention-queue-and-afk-auto-decider.md +159 -0
- package/docs/architecture/adr/0011-sandbox-grants-and-network-egress-boundary.md +219 -0
- package/docs/architecture/adr/0012-operator-legibility-surfaces.md +175 -0
- package/docs/getting-started/INSTALLATION.md +1 -1
- package/docs/guides/AUTOMATIC_FEATURES.md +8 -0
- package/docs/guides/LOCAL_MODELS.md +1 -1
- package/docs/guides/PROXY.md +2 -1
- package/docs/guides/SANDBOX.md +91 -4
- package/docs/integrations/MCP_ROUTER.md +1 -1
- package/docs/plans/model-performance-proof-options.md +176 -0
- package/docs/reference/API.md +1 -1
- package/docs/reference/CLI.md +169 -4
- package/docs/reference/COMPARISON.md +1 -1
- package/docs/reference/CONFIGURATION.md +12 -3
- package/docs/reference/CONFIGURATION_REFERENCE.md +269 -14
- package/docs/reference/DATABASE_SCHEMA.md +1 -1
- package/docs/reference/FEATURES.md +15 -3
- package/docs/reference/PATTERNS.md +1 -1
- package/docs/reference/PLATFORMS.md +14 -1
- package/docs/specs/operator-model-placement.md +1314 -0
- package/docs/specs/operator-model-placement.review.md +339 -0
- package/package.json +2 -2
- package/scripts/maintenance/publish-npm.sh +23 -11
- package/scripts/version-bump.sh +6 -51
- package/src/policies/enforcers/__pycache__/_common.cpython-311.pyc +0 -0
- package/src/policies/enforcers/__pycache__/expert_review_required.cpython-311.pyc +0 -0
- package/src/policies/enforcers/__pycache__/quality_metrics_gate.cpython-311.pyc +0 -0
- package/src/policies/schemas/policies/mandatory-testing-deployment.md +2 -5
- package/templates/hooks/__pycache__/deliver_autoroute.cpython-311.pyc +0 -0
- package/templates/hooks/session-start.sh +44 -0
- package/tools/agents/UAP/cli.py +14 -3
- package/tools/agents/UAP/paths.py +50 -0
- package/tools/agents/scripts/__pycache__/toolcall_path_normalizer.cpython-311.pyc +0 -0
- package/tools/agents/scripts/anthropic_proxy.py +1386 -99
- package/tools/agents/scripts/toolcall_path_normalizer.py +46 -1
- package/tools/agents/tests/test_anthropic_proxy_streaming.py +29 -6
- package/tools/agents/tests/test_doubling_break.py +64 -5
- package/tools/agents/tests/test_error_loop_break.py +10 -4
- package/tools/agents/tests/test_error_loop_ignores_correctives.py +13 -2
- package/tools/agents/tests/test_lockstep_escalation.py +280 -9
- package/tools/agents/tests/test_path_containment.py +94 -0
- package/tools/agents/tests/test_proxy_unix_socket.py +162 -0
- package/tools/agents/tests/test_signature_quality.py +349 -0
- package/tools/agents/tests/test_uap_compliance.py +11 -1
- package/web/dash/core.js +1 -0
- package/web/dash/tab-clients.js +196 -0
- package/web/dash/tab-models.js +387 -8
- package/web/dash/tab-policies.js +87 -4
- package/web/dash/tabs.js +77 -73
- package/web/dashboard.html +6 -0
- package/src/policies/enforcers/__pycache__/_common.cpython-312.pyc +0 -0
- package/src/policies/enforcers/__pycache__/expert_review_required.cpython-312.pyc +0 -0
- package/src/policies/enforcers/__pycache__/quality_metrics_gate.cpython-312.pyc +0 -0
- package/templates/hooks/__pycache__/deliver_autoroute.cpython-312.pyc +0 -0
- package/tools/agents/scripts/__pycache__/toolcall_path_normalizer.cpython-312.pyc +0 -0
- package/web/dash/tab-agents.js +0 -21
- package/web/dash/tab-deliver.js +0 -12
- package/web/dash/tab-memory.js +0 -12
- package/web/dash/tab-orchestration.js +0 -21
- package/web/dash/tab-overview.js +0 -21
- package/web/dash/tab-tasks.js +0 -21
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bench-report.d.ts","sourceRoot":"","sources":["../../src/cli/bench-report.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,kBAAkB;IACjC,+EAA+E;IAC/E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,yEAAyE;IACzE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE;QACN,IAAI,CAAC,EAAE;YACL,KAAK,CAAC,EAAE,MAAM,CAAC;YACf,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,MAAM,CAAC,EAAE,MAAM,CAAC;YAChB,SAAS,CAAC,EAAE,MAAM,CAAC;YACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;YAClB,SAAS,CAAC,EAAE,MAAM,CAAC;SACpB,CAAC;QACF,YAAY,CAAC,EAAE,KAAK,CAAC;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,WAAW,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACxE,WAAW,CAAC,EAAE,KAAK,CAAC;YAClB,KAAK,EAAE,MAAM,CAAC;YACd,QAAQ,CAAC,EAAE,MAAM,CAAC;YAClB,WAAW,CAAC,EAAE;gBACZ,KAAK,CAAC,EAAE;oBAAE,SAAS,CAAC,EAAE,MAAM,CAAC;oBAAC,EAAE,CAAC,EAAE;wBAAE,KAAK,CAAC,EAAE,MAAM,CAAC;wBAAC,KAAK,CAAC,EAAE,MAAM,CAAA;qBAAE,CAAC;oBAAC,MAAM,CAAC,EAAE,MAAM,CAAA;iBAAE,CAAC;gBACzF,OAAO,CAAC,EAAE,MAAM,CAAC;gBACjB,OAAO,CAAC,EAAE;oBAAE,CAAC,CAAC,EAAE,MAAM,CAAC;oBAAC,CAAC,CAAC,EAAE,MAAM,CAAA;iBAAE,CAAC;aACtC,CAAC;YACF,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;gBAAE,SAAS,CAAC,EAAE,MAAM,CAAC;gBAAC,EAAE,CAAC,EAAE;oBAAE,KAAK,CAAC,EAAE,MAAM,CAAC;oBAAC,KAAK,CAAC,EAAE,MAAM,CAAA;iBAAE,CAAC;gBAAC,OAAO,CAAC,EAAE,MAAM,CAAA;aAAE,CAAC,CAAC;SAC7G,CAAC,CAAC;QACH,cAAc,CAAC,EAAE;YAAE,MAAM,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,OAAO,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAC;YAAC,gBAAgB,CAAC,EAAE,OAAO,CAAA;SAAE,CAAC;KACrG,CAAC;CACH;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,SAA2C,GAAG,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CA0B7H;AAED;;+EAE+E;AAC/E,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAqB3D;AAOD,8EAA8E;AAC9E,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CA2ChE;AAED,oEAAoE;AACpE,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,YAAY,GAAG,MAAM,CA0CzE;AA+BD,wBAAsB,kBAAkB,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsExF"}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// `uap bench report` — the paired-report reader (the delta report
|
|
3
|
+
// as an operator surface). Reports accumulate under benchmark-results/paired-*/;
|
|
4
|
+
// the operator's questions are "what did the latest run measure" and "did the
|
|
5
|
+
// delta HOLD since the last run" — and per the reliability-ladder rule, a delta
|
|
6
|
+
// is never cited without its discrimination status.
|
|
7
|
+
//
|
|
8
|
+
// Split from bench.ts (the paired-run driver) at review: the reader and the
|
|
9
|
+
// driver are separable commands, and the repo pattern is one command per file.
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
import chalk from 'chalk';
|
|
12
|
+
import { existsSync, readdirSync, readFileSync, statSync } from 'fs';
|
|
13
|
+
import { basename, join, resolve } from 'path';
|
|
14
|
+
import { termSafe } from '../utils/terminal-safe.js';
|
|
15
|
+
/** One report file read is bounded (P5 polish): these are small harness
|
|
16
|
+
* artifacts, and a multi-GB or planted file must not be slurped whole. */
|
|
17
|
+
const MAX_REPORT_BYTES = 4 * 1024 * 1024;
|
|
18
|
+
/**
|
|
19
|
+
* Paired-run dirs that hold a report.json, newest-first. One bad entry (a
|
|
20
|
+
* dangling symlink, a vanished dir) must not hide the good reports behind a
|
|
21
|
+
* misleading "no reports found" — fail-soft per entry, not per directory.
|
|
22
|
+
*/
|
|
23
|
+
export function listPairedReportDirs(root = join(process.cwd(), 'benchmark-results')) {
|
|
24
|
+
let entries = [];
|
|
25
|
+
try {
|
|
26
|
+
entries = readdirSync(root);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
const found = [];
|
|
32
|
+
for (const e of entries) {
|
|
33
|
+
const dir = join(root, e);
|
|
34
|
+
try {
|
|
35
|
+
if (!statSync(dir).isDirectory())
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
continue; // dangling symlink / unreadable entry — skip it, keep the rest
|
|
40
|
+
}
|
|
41
|
+
const reportPath = join(dir, 'report.json');
|
|
42
|
+
if (!existsSync(reportPath))
|
|
43
|
+
continue;
|
|
44
|
+
try {
|
|
45
|
+
found.push({ dir, mtimeMs: statSync(reportPath).mtimeMs });
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
/* unreadable mtime — skip */
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// Newest-first. Ties (e.g. a bulk copy resets mtimes) fall back to the dir
|
|
52
|
+
// name — paired-run dirs are ISO-timestamped, so lexical order is dated too.
|
|
53
|
+
return found.sort((a, b) => b.mtimeMs - a.mtimeMs || b.dir.localeCompare(a.dir));
|
|
54
|
+
}
|
|
55
|
+
/** Read one paired-run dir's report.json; null when unreadable.
|
|
56
|
+
* The harness writes `{ ablation, report: AnalysisReport }` — the reader
|
|
57
|
+
* unwraps that shape and also accepts a bare report for hand-made fixtures. */
|
|
58
|
+
export function loadReport(dir) {
|
|
59
|
+
try {
|
|
60
|
+
const reportPath = join(dir, 'report.json');
|
|
61
|
+
const st = statSync(reportPath);
|
|
62
|
+
// Bounded read (P5 polish): these are small harness artifacts — a huge
|
|
63
|
+
// or planted report.json must not be slurped whole. Oversized is NAMED
|
|
64
|
+
// and skipped, never a silent drop or a crash.
|
|
65
|
+
if (st.size > MAX_REPORT_BYTES) {
|
|
66
|
+
console.warn(`[bench report] ${basename(dir)}/report.json is ${st.size} bytes (over the ${MAX_REPORT_BYTES / (1024 * 1024)} MiB read cap) — skipped`);
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
const raw = JSON.parse(readFileSync(reportPath, 'utf-8'));
|
|
70
|
+
const report = raw.report ?? raw;
|
|
71
|
+
return { dir, mtimeMs: st.mtimeMs, report };
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
const pp = (x) => Number.isFinite(x) ? `${(x * 100).toFixed(1)}pp` : '—';
|
|
78
|
+
const sign = (x) => !Number.isFinite(x) ? '—' : `${x >= 0 ? '+' : ''}${(x * 100).toFixed(1)}pp`;
|
|
79
|
+
/** Compact delta summary of ONE report — deltas WITH their status, always. */
|
|
80
|
+
export function renderReportSummary(loaded) {
|
|
81
|
+
const r = loaded.report;
|
|
82
|
+
const meta = r.meta ?? {};
|
|
83
|
+
const disc = r.discrimination ?? {};
|
|
84
|
+
const lines = [];
|
|
85
|
+
lines.push(chalk.bold(`Paired bench report — ${termSafe(basename(loaded.dir))}`));
|
|
86
|
+
lines.push(chalk.dim(` model=${termSafe(String(meta.model ?? '?'))} adapter=${termSafe(String(meta.adapter ?? '?'))} epochs=${meta.epochs ?? '?'} ` +
|
|
87
|
+
`tasks=${meta.taskCount ?? '?'} started=${termSafe(String(meta.startedAt ?? '?'))}`));
|
|
88
|
+
lines.push(` discrimination: ${disc.usable ? chalk.green('usable') : chalk.red('NOT usable')} ` +
|
|
89
|
+
`(${termSafe(String(disc.status ?? '?'))}${disc.reason ? chalk.dim(` — ${termSafe(String(disc.reason))}`) : ''})`);
|
|
90
|
+
for (const c of r.comparisons ?? []) {
|
|
91
|
+
const corr = c.correctness ?? {};
|
|
92
|
+
const d = corr.delta ?? {};
|
|
93
|
+
const verdict = corr.verdict ?? '—';
|
|
94
|
+
const verdictColor = verdict === 'win' ? chalk.green : verdict === 'loss' ? chalk.red : chalk.yellow;
|
|
95
|
+
lines.push(` ${chalk.cyan(termSafe(c.label))} vs ${chalk.dim(termSafe(String(c.baseline ?? 'baseline')))}: correctness ` +
|
|
96
|
+
`${sign(d.meanDelta)} CI [${pp(d.ci?.lower)}, ${pp(d.ci?.upper)}] p=${Number.isFinite(d.pValue) ? d.pValue.toFixed(3) : '—'} ` +
|
|
97
|
+
`→ ${verdictColor(termSafe(verdict))}${chalk.dim(` (McNemar discordant ${(corr.mcnemar?.b ?? 0) + (corr.mcnemar?.c ?? 0)})`)}`);
|
|
98
|
+
const metrics = Object.entries(c.metrics ?? {});
|
|
99
|
+
if (metrics.length > 0) {
|
|
100
|
+
const parts = metrics
|
|
101
|
+
.slice(0, 4)
|
|
102
|
+
.map(([name, m]) => `${termSafe(name)}: ${sign(m.meanDelta)}${m.verdict ? ` (${termSafe(String(m.verdict))})` : ''}`);
|
|
103
|
+
lines.push(chalk.dim(` metrics: ${parts.join(' · ')}`));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
lines.push(chalk.dim(disc.usable
|
|
107
|
+
? ' (deltas above carry their CI and verdict; see report.md for the full analysis)'
|
|
108
|
+
: ' (an unusable run is NO MEASUREMENT — fix the suite/adapter before citing any delta)'));
|
|
109
|
+
return lines.join('\n');
|
|
110
|
+
}
|
|
111
|
+
/** Two-run delta drift: which deltas held, flipped, or narrowed. */
|
|
112
|
+
export function renderComparison(a, b) {
|
|
113
|
+
// `b` is the NEWER run by caller convention.
|
|
114
|
+
const lines = [];
|
|
115
|
+
lines.push(chalk.bold('Paired bench delta drift — two most recent runs'));
|
|
116
|
+
lines.push(chalk.dim(` now: ${termSafe(basename(b.dir))} (${termSafe(String(b.report.meta?.startedAt ?? '?'))})`));
|
|
117
|
+
lines.push(chalk.dim(` prev: ${termSafe(basename(a.dir))} (${termSafe(String(a.report.meta?.startedAt ?? '?'))})`));
|
|
118
|
+
const discA = a.report.discrimination ?? {};
|
|
119
|
+
const discB = b.report.discrimination ?? {};
|
|
120
|
+
lines.push(` discrimination now/prev: ${discB.usable ? 'usable' : 'NOT usable'}/${discA.usable ? 'usable' : 'NOT usable'} ` +
|
|
121
|
+
`(${termSafe(String(discB.status ?? '?'))}/${termSafe(String(discA.status ?? '?'))})`);
|
|
122
|
+
if (!discB.usable || !discA.usable) {
|
|
123
|
+
lines.push(chalk.yellow(' ⚠ at least one run could not measure — drift between unusable runs is NO MEASUREMENT.'));
|
|
124
|
+
}
|
|
125
|
+
const byLabel = (r) => new Map((r.report.comparisons ?? []).map((c) => [c.label, c]));
|
|
126
|
+
const prev = byLabel(a);
|
|
127
|
+
const now = byLabel(b);
|
|
128
|
+
for (const [label, nowC] of now) {
|
|
129
|
+
const prevC = prev.get(label);
|
|
130
|
+
if (!prevC) {
|
|
131
|
+
lines.push(chalk.dim(` ${termSafe(label)}: no previous comparison to drift against`));
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
const pd = prevC.correctness?.delta?.meanDelta;
|
|
135
|
+
const nd = nowC.correctness?.delta?.meanDelta;
|
|
136
|
+
const pv = prevC.correctness?.verdict ?? '—';
|
|
137
|
+
const nv = nowC.correctness?.verdict ?? '—';
|
|
138
|
+
const flipped = pv !== nv;
|
|
139
|
+
const drift = Number.isFinite(pd) && Number.isFinite(nd)
|
|
140
|
+
? `${(nd - pd) * 100 >= 0 ? '+' : ''}${((nd - pd) * 100).toFixed(1)}pp`
|
|
141
|
+
: '—';
|
|
142
|
+
lines.push(` ${chalk.cyan(termSafe(label))}: correctness ${sign(pd)} (${termSafe(pv)}) → ${sign(nd)} (${termSafe(nv)})` +
|
|
143
|
+
` drift ${drift}${flipped ? chalk.yellow(` — VERDICT FLIPPED`) : ''}`);
|
|
144
|
+
}
|
|
145
|
+
return lines.join('\n');
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Print the stored report.md. The harness writes report.json THEN report.md —
|
|
149
|
+
* an interrupted run can leave the first without the second. That is a
|
|
150
|
+
* missing-file degradation, never a stack trace: say so, fall back to the
|
|
151
|
+
* delta summary, exit non-zero. An oversized report.md is the same
|
|
152
|
+
* degradation (bounded read, P5 polish): named, never slurped.
|
|
153
|
+
*/
|
|
154
|
+
function printFullReport(loaded) {
|
|
155
|
+
try {
|
|
156
|
+
const mdPath = join(loaded.dir, 'report.md');
|
|
157
|
+
const st = statSync(mdPath);
|
|
158
|
+
if (st.size > MAX_REPORT_BYTES) {
|
|
159
|
+
console.error(chalk.red(`report.md in ${basename(loaded.dir)}/ is ${st.size} bytes (over the ${MAX_REPORT_BYTES / (1024 * 1024)} MiB read cap) — showing the summary instead.`));
|
|
160
|
+
console.log(renderReportSummary(loaded));
|
|
161
|
+
process.exitCode = 1;
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
console.log(readFileSync(mdPath, 'utf-8'));
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
console.error(chalk.red(`No report.md stored in ${basename(loaded.dir)}/ — the run may have been interrupted; showing the summary instead.`));
|
|
168
|
+
console.log(renderReportSummary(loaded));
|
|
169
|
+
process.exitCode = 1;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
export async function benchReportCommand(options = {}) {
|
|
173
|
+
const root = options.root ? resolve(options.root) : join(process.cwd(), 'benchmark-results');
|
|
174
|
+
if (options.dir) {
|
|
175
|
+
if (options.compare) {
|
|
176
|
+
console.log(chalk.dim(' (--dir pins a single run; --compare is ignored)'));
|
|
177
|
+
}
|
|
178
|
+
const one = loadReport(resolve(options.dir));
|
|
179
|
+
if (!one) {
|
|
180
|
+
console.error(chalk.red(`No readable report.json under '${options.dir}'.`));
|
|
181
|
+
process.exitCode = 1;
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
if (options.json) {
|
|
185
|
+
console.log(JSON.stringify(one.report, null, 2));
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
if (options.full) {
|
|
189
|
+
printFullReport(one);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
console.log(renderReportSummary(one));
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
const dirs = listPairedReportDirs(root);
|
|
196
|
+
if (dirs.length === 0) {
|
|
197
|
+
console.error(chalk.red('No paired reports found under benchmark-results/ — run `uap bench paired` first.'));
|
|
198
|
+
process.exitCode = 1;
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
if (options.compare) {
|
|
202
|
+
if (dirs.length < 2) {
|
|
203
|
+
console.error(chalk.red('Only one paired report exists — nothing to compare yet.'));
|
|
204
|
+
process.exitCode = 1;
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
const [newer, older] = [loadReport(dirs[0].dir), loadReport(dirs[1].dir)];
|
|
208
|
+
if (!newer || !older) {
|
|
209
|
+
console.error(chalk.red('The two newest report.json files were not readable.'));
|
|
210
|
+
process.exitCode = 1;
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
if (options.json) {
|
|
214
|
+
console.log(JSON.stringify({ now: newer.report, prev: older.report }, null, 2));
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
console.log(renderComparison(older, newer));
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
const latest = loadReport(dirs[0].dir);
|
|
221
|
+
if (!latest) {
|
|
222
|
+
console.error(chalk.red(`The newest report (${dirs[0].dir}) was not readable.`));
|
|
223
|
+
process.exitCode = 1;
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
if (options.json) {
|
|
227
|
+
console.log(JSON.stringify(latest.report, null, 2));
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
if (options.full) {
|
|
231
|
+
printFullReport(latest);
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
console.log(renderReportSummary(latest));
|
|
235
|
+
console.log(chalk.dim(`\n (${dirs.length} report(s) on disk — \`uap bench report --compare\` for run-to-run drift, --full for the stored markdown)`));
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=bench-report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bench-report.js","sourceRoot":"","sources":["../../src/cli/bench-report.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,kEAAkE;AAClE,iFAAiF;AACjF,8EAA8E;AAC9E,gFAAgF;AAChF,oDAAoD;AACpD,EAAE;AACF,4EAA4E;AAC5E,+EAA+E;AAC/E,8EAA8E;AAE9E,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AACrE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAErD;2EAC2E;AAC3E,MAAM,gBAAgB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAyCzC;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,mBAAmB,CAAC;IAClF,IAAI,OAAO,GAAa,EAAE,CAAC;IAC3B,IAAI,CAAC;QACH,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,KAAK,GAA4C,EAAE,CAAC;IAC1D,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAC1B,IAAI,CAAC;YACH,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE;gBAAE,SAAS;QAC7C,CAAC;QAAC,MAAM,CAAC;YACP,SAAS,CAAC,+DAA+D;QAC3E,CAAC;QACD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QAC5C,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;YAAE,SAAS;QACtC,IAAI,CAAC;YACH,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QAC7D,CAAC;QAAC,MAAM,CAAC;YACP,6BAA6B;QAC/B,CAAC;IACH,CAAC;IACD,2EAA2E;IAC3E,6EAA6E;IAC7E,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AACnF,CAAC;AAED;;+EAE+E;AAC/E,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QAC5C,MAAM,EAAE,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;QAChC,uEAAuE;QACvE,uEAAuE;QACvE,+CAA+C;QAC/C,IAAI,EAAE,CAAC,IAAI,GAAG,gBAAgB,EAAE,CAAC;YAC/B,OAAO,CAAC,IAAI,CACV,kBAAkB,QAAQ,CAAC,GAAG,CAAC,mBAAmB,EAAE,CAAC,IAAI,oBAAoB,gBAAgB,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,0BAA0B,CACxI,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAEvD,CAAC;QACF,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC;QACjC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,EAAE,GAAG,CAAC,CAAqB,EAAU,EAAE,CAC3C,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAE,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC;AAC1D,MAAM,IAAI,GAAG,CAAC,CAAqB,EAAU,EAAE,CAC7C,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAE,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAE,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AAEhF,8EAA8E;AAC9E,MAAM,UAAU,mBAAmB,CAAC,MAAoB;IACtD,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;IACxB,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;IAC1B,MAAM,IAAI,GAAG,CAAC,CAAC,cAAc,IAAI,EAAE,CAAC;IACpC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,yBAAyB,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAClF,KAAK,CAAC,IAAI,CACR,KAAK,CAAC,GAAG,CACP,WAAW,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC,YAAY,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,GAAG,CAAC,CAAC,WAAW,IAAI,CAAC,MAAM,IAAI,GAAG,GAAG;QAC7H,SAAS,IAAI,CAAC,SAAS,IAAI,GAAG,YAAY,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,IAAI,GAAG,CAAC,CAAC,EAAE,CACtF,CACF,CAAC;IACF,KAAK,CAAC,IAAI,CACR,qBAAqB,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG;QACnF,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CACpH,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,CAAC,CAAC,WAAW,IAAI,EAAE,CAAC;QACjC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,GAAG,CAAC;QACpC,MAAM,YAAY,GAChB,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;QAClF,KAAK,CAAC,IAAI,CACR,KAAK,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,IAAI,UAAU,CAAC,CAAC,CAAC,gBAAgB;YAC5G,GAAG,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG;YAC/H,KAAK,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,wBAAwB,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CACjI,CAAC;QACF,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;QAChD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,KAAK,GAAG,OAAO;iBAClB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;iBACX,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACxH,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,gBAAgB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IACD,KAAK,CAAC,IAAI,CACR,KAAK,CAAC,GAAG,CACP,IAAI,CAAC,MAAM;QACT,CAAC,CAAC,kFAAkF;QACpF,CAAC,CAAC,uFAAuF,CAC5F,CACF,CAAC;IACF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,gBAAgB,CAAC,CAAe,EAAE,CAAe;IAC/D,6CAA6C;IAC7C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC,CAAC;IAC1E,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACvH,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACvH,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,cAAc,IAAI,EAAE,CAAC;IAC5C,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,cAAc,IAAI,EAAE,CAAC;IAC5C,KAAK,CAAC,IAAI,CACR,8BAA8B,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,GAAG;QAC/G,IAAI,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CACxF,CAAC;IACF,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QACnC,KAAK,CAAC,IAAI,CACR,KAAK,CAAC,MAAM,CAAC,yFAAyF,CAAC,CACxG,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,CAAC,CAAe,EAAE,EAAE,CAClC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACjE,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACxB,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACvB,KAAK,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;QAChC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,QAAQ,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC,CAAC;YACvF,SAAS;QACX,CAAC;QACD,MAAM,EAAE,GAAG,KAAK,CAAC,WAAW,EAAE,KAAK,EAAE,SAAS,CAAC;QAC/C,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,EAAE,KAAK,EAAE,SAAS,CAAC;QAC9C,MAAM,EAAE,GAAG,KAAK,CAAC,WAAW,EAAE,OAAO,IAAI,GAAG,CAAC;QAC7C,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,EAAE,OAAO,IAAI,GAAG,CAAC;QAC5C,MAAM,OAAO,GAAG,EAAE,KAAK,EAAE,CAAC;QAC1B,MAAM,KAAK,GACT,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;YACxC,CAAC,CAAC,GAAG,CAAC,EAAG,GAAG,EAAG,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAG,GAAG,EAAG,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI;YAC3E,CAAC,CAAC,GAAG,CAAC;QACV,KAAK,CAAC,IAAI,CACR,KAAK,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,iBAAiB,IAAI,CAAC,EAAE,CAAC,KAAK,QAAQ,CAAC,EAAE,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,KAAK,QAAQ,CAAC,EAAE,CAAC,GAAG;YAC3G,UAAU,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CACxE,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;;;;;GAMG;AACH,SAAS,eAAe,CAAC,MAAoB;IAC3C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QAC7C,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC5B,IAAI,EAAE,CAAC,IAAI,GAAG,gBAAgB,EAAE,CAAC;YAC/B,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,GAAG,CAAC,gBAAgB,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,IAAI,oBAAoB,gBAAgB,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,+CAA+C,CAAC,CAClK,CAAC;YACF,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC;YACzC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,GAAG,CAAC,0BAA0B,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,qEAAqE,CAAC,CAC/H,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC;QACzC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,UAA8B,EAAE;IACvE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,mBAAmB,CAAC,CAAC;IAE7F,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAChB,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC,CAAC;QAC9E,CAAC;QACD,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7C,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,kCAAkC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;YAC5E,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QACD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YACjD,OAAO;QACT,CAAC;QACD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,eAAe,CAAC,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC;QACtC,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,GAAG,CAAC,kFAAkF,CAAC,CAC9F,CAAC;QACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC,CAAC;YACpF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QACD,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC1E,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;YACrB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC,CAAC;YAChF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QACD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAChF,OAAO;QACT,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;QAC5C,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,sBAAsB,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,qBAAqB,CAAC,CAAC,CAAC;QACjF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACpD,OAAO;IACT,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,eAAe,CAAC,MAAM,CAAC,CAAC;QACxB,OAAO;IACT,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,IAAI,CAAC,MAAM,2GAA2G,CAAC,CAAC,CAAC;AACzJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clients.d.ts","sourceRoot":"","sources":["../../src/cli/clients.ts"],"names":[],"mappings":"AAmBA,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAMD,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAUf"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `uap clients` — the fleet registry CLI.
|
|
3
|
+
*
|
|
4
|
+
* Terminal twin of the dashboard's Clients tab: list discovered client
|
|
5
|
+
* folders with live summaries, pin/remove manual entries in
|
|
6
|
+
* `~/.uap/clients.json`, and show what auto-scan finds. The registry feeds
|
|
7
|
+
* both this command and the `GET /api/clients` route behind the tab.
|
|
8
|
+
*/
|
|
9
|
+
import { resolve } from 'path';
|
|
10
|
+
import { addManualClient, getClientSummaries, listClients, registryFilePath, removeManualClient, scanRootFor, stopClientDashboard, } from '../dashboard/client-registry.js';
|
|
11
|
+
function pad(s, n) {
|
|
12
|
+
return (s + ' '.repeat(n)).slice(0, Math.max(n, s.length + 1));
|
|
13
|
+
}
|
|
14
|
+
export async function clientsCommand(action, pathArg, options = {}) {
|
|
15
|
+
const hostCwd = process.cwd();
|
|
16
|
+
try {
|
|
17
|
+
await dispatch(action, pathArg, options, hostCwd);
|
|
18
|
+
}
|
|
19
|
+
catch (e) {
|
|
20
|
+
// Registry/stop rejections are operator errors ('client not in registry',
|
|
21
|
+
// 'not a directory'), not stack traces.
|
|
22
|
+
console.error(e.message);
|
|
23
|
+
process.exitCode = 1;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
async function dispatch(action, pathArg, options, hostCwd) {
|
|
27
|
+
switch (action) {
|
|
28
|
+
case 'list':
|
|
29
|
+
await listCmd(hostCwd);
|
|
30
|
+
break;
|
|
31
|
+
case 'add':
|
|
32
|
+
addCmd(hostCwd, pathArg, options);
|
|
33
|
+
break;
|
|
34
|
+
case 'remove':
|
|
35
|
+
removeCmd(pathArg);
|
|
36
|
+
break;
|
|
37
|
+
case 'scan':
|
|
38
|
+
scanCmd(hostCwd);
|
|
39
|
+
break;
|
|
40
|
+
case 'stop':
|
|
41
|
+
await stopCmd(hostCwd, pathArg);
|
|
42
|
+
break;
|
|
43
|
+
default:
|
|
44
|
+
console.log(`Usage: uap clients <list|add|remove|scan|stop>
|
|
45
|
+
|
|
46
|
+
list Fleet summary for every discovered client (live reads: deliver
|
|
47
|
+
runs, task queue, git, dashboard health probe)
|
|
48
|
+
add Pin a client folder manually: uap clients add <path> [--name n] [--port p]
|
|
49
|
+
remove Unpin a manually added client: uap clients remove <path>
|
|
50
|
+
scan Show what auto-scan discovers (managed + unmanaged folders)
|
|
51
|
+
stop Stop a client's spawned dashboard: uap clients stop <path>
|
|
52
|
+
|
|
53
|
+
Registry: ${registryFilePath()}`);
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async function listCmd(hostCwd) {
|
|
58
|
+
console.log(`Scan root: ${scanRootFor(hostCwd)}`);
|
|
59
|
+
console.log(`Registry: ${registryFilePath()}`);
|
|
60
|
+
const clients = await getClientSummaries(hostCwd, 0);
|
|
61
|
+
if (!clients.length) {
|
|
62
|
+
console.log('No client folders discovered.');
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
console.log('');
|
|
66
|
+
console.log(pad('CLIENT', 22) + pad('STATE', 16) + pad('BRANCH', 14) + pad('QUEUE', 24) + pad('DELIVER', 24) + 'DASH');
|
|
67
|
+
for (const c of clients) {
|
|
68
|
+
const state = c.host ? 'this host' : c.managed ? (c.dashboardAlive ? 'up' : 'down') : 'unmanaged';
|
|
69
|
+
const queue = `${c.tasks.inProgress} ip · ${c.tasks.open} open · ${c.tasks.blocked} blocked`;
|
|
70
|
+
const deliver = `${c.deliver.running} run · ${c.deliver.interrupted} int · ${c.deliver.failed} fail`;
|
|
71
|
+
// The CLI doesn't know which port the host dashboard is live on (only the
|
|
72
|
+
// server does), so the host row never claims a probe result.
|
|
73
|
+
const dash = c.host ? 'this' : c.dashboardAlive ? `:${c.port}` : '-';
|
|
74
|
+
console.log(pad(c.name, 22) + pad(state, 16) + pad(c.branch === '?' ? '-' : c.branch, 14) + pad(queue, 24) + pad(deliver, 24) +
|
|
75
|
+
dash + (c.degraded ? ' (degraded)' : ''));
|
|
76
|
+
}
|
|
77
|
+
console.log('');
|
|
78
|
+
console.log(`Open a client's dashboard from the web UI Clients tab, or: uap dashboard serve (inside the client).`);
|
|
79
|
+
}
|
|
80
|
+
function addCmd(hostCwd, pathArg, options) {
|
|
81
|
+
if (!pathArg) {
|
|
82
|
+
console.error('Usage: uap clients add <path> [--name <name>] [--port <port>]');
|
|
83
|
+
process.exitCode = 1;
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const port = options.port ? Number(options.port) : undefined;
|
|
87
|
+
if (port !== undefined && (!Number.isInteger(port) || port < 1024 || port > 65535)) {
|
|
88
|
+
console.error('--port must be an integer in 1024..65535');
|
|
89
|
+
process.exitCode = 1;
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const entry = addManualClient(hostCwd, resolve(pathArg), { name: options.name, port });
|
|
93
|
+
console.log(`Pinned client "${entry.name}" (${entry.path})${entry.port ? ` — dashboard port ${entry.port}` : ''}`);
|
|
94
|
+
}
|
|
95
|
+
function removeCmd(pathArg) {
|
|
96
|
+
if (!pathArg) {
|
|
97
|
+
console.error('Usage: uap clients remove <path>');
|
|
98
|
+
process.exitCode = 1;
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
if (removeManualClient(resolve(pathArg))) {
|
|
102
|
+
console.log(`Unpinned ${resolve(pathArg)}`);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
console.log(`No manual entry for ${resolve(pathArg)} (auto-scanned folders need no removal — they drop out when the folder moves or a pattern ignores them).`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function scanCmd(hostCwd) {
|
|
109
|
+
const entries = listClients(hostCwd);
|
|
110
|
+
const root = scanRootFor(hostCwd);
|
|
111
|
+
console.log(`Scanning ${root}`);
|
|
112
|
+
if (!entries.length) {
|
|
113
|
+
console.log('Nothing found.');
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
for (const c of entries) {
|
|
117
|
+
const tags = [c.host ? 'this host' : '', c.managed ? 'managed' : 'unmanaged', c.manual ? 'pinned' : 'scanned']
|
|
118
|
+
.filter(Boolean)
|
|
119
|
+
.join(', ');
|
|
120
|
+
console.log(` ${pad(c.name, 26)} ${tags}${c.port ? ` (port ${c.port})` : ''}`);
|
|
121
|
+
}
|
|
122
|
+
console.log(`\n${entries.filter((c) => c.manual).length} pinned, ${entries.filter((c) => !c.manual).length} scanned.`);
|
|
123
|
+
}
|
|
124
|
+
async function stopCmd(hostCwd, pathArg) {
|
|
125
|
+
if (!pathArg) {
|
|
126
|
+
console.error('Usage: uap clients stop <path>');
|
|
127
|
+
process.exitCode = 1;
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
const res = await stopClientDashboard(hostCwd, resolve(pathArg));
|
|
131
|
+
if (res.stopped) {
|
|
132
|
+
console.log(`Stopped client dashboard on :${res.port}`);
|
|
133
|
+
}
|
|
134
|
+
else if (!res.wasAlive) {
|
|
135
|
+
console.log('No live dashboard for that client.');
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
console.error(`Could not stop: ${res.reason}`);
|
|
139
|
+
process.exitCode = 1;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=clients.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clients.js","sourceRoot":"","sources":["../../src/cli/clients.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The dashboard's Sandbox Grants section (the ADR 0011-named operator
|
|
3
|
+
* surface: active authority per session, the trust-anchor verdict, and the
|
|
4
|
+
* revoke command per grant).
|
|
5
|
+
*
|
|
6
|
+
* Split from src/cli/dashboard.ts: the dashboard module is the repo's worst
|
|
7
|
+
* LOC offender, and new sections follow the export-for-test pattern — a
|
|
8
|
+
* separate module keeps the render file
|
|
9
|
+
* from growing with every surface and gives the tests a direct import.
|
|
10
|
+
*/
|
|
11
|
+
/** Humanize the remaining TTL of a grant (ISO expiry) for one glance. */
|
|
12
|
+
export declare function humanRemaining(expiresAt: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* The Sandbox Grants section as plain lines — active authority per session,
|
|
15
|
+
* the trust-anchor verdict, and the revoke command per grant. The ADR
|
|
16
|
+
* 0011-named surface ("a dashboard grants view... one click to revoke" — the
|
|
17
|
+
* CLI's one click is the printed command). Pure w.r.t. projectRoot + the
|
|
18
|
+
* env pins, so tests seed a ledger and call directly.
|
|
19
|
+
* A line starting with ⚠ (after leading indent) is a warning the caller
|
|
20
|
+
* colors red.
|
|
21
|
+
*/
|
|
22
|
+
export declare function sandboxGrantsLines(projectRoot: string, maxGrants?: number): {
|
|
23
|
+
lines: string[];
|
|
24
|
+
mismatch: boolean;
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=dashboard-grants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard-grants.d.ts","sourceRoot":"","sources":["../../src/cli/dashboard-grants.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,yEAAyE;AACzE,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CASxD;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,SAAI,GAAG;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CA4B7G"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The dashboard's Sandbox Grants section (the ADR 0011-named operator
|
|
3
|
+
* surface: active authority per session, the trust-anchor verdict, and the
|
|
4
|
+
* revoke command per grant).
|
|
5
|
+
*
|
|
6
|
+
* Split from src/cli/dashboard.ts: the dashboard module is the repo's worst
|
|
7
|
+
* LOC offender, and new sections follow the export-for-test pattern — a
|
|
8
|
+
* separate module keeps the render file
|
|
9
|
+
* from growing with every surface and gives the tests a direct import.
|
|
10
|
+
*/
|
|
11
|
+
import { listAuthority, verifyLedgerIntegrity } from '../policies/sandbox-grants.js';
|
|
12
|
+
/** Humanize the remaining TTL of a grant (ISO expiry) for one glance. */
|
|
13
|
+
export function humanRemaining(expiresAt) {
|
|
14
|
+
const ms = Date.parse(expiresAt) - Date.now();
|
|
15
|
+
if (!Number.isFinite(ms))
|
|
16
|
+
return 'unknown';
|
|
17
|
+
if (ms <= 0)
|
|
18
|
+
return 'expired';
|
|
19
|
+
const mins = Math.floor(ms / 60_000);
|
|
20
|
+
if (mins < 60)
|
|
21
|
+
return `~${Math.max(1, mins)}m left`;
|
|
22
|
+
const hours = Math.floor(mins / 60);
|
|
23
|
+
if (hours < 48)
|
|
24
|
+
return `~${hours}h ${mins % 60}m left`;
|
|
25
|
+
return `~${Math.floor(hours / 24)}d left`;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The Sandbox Grants section as plain lines — active authority per session,
|
|
29
|
+
* the trust-anchor verdict, and the revoke command per grant. The ADR
|
|
30
|
+
* 0011-named surface ("a dashboard grants view... one click to revoke" — the
|
|
31
|
+
* CLI's one click is the printed command). Pure w.r.t. projectRoot + the
|
|
32
|
+
* env pins, so tests seed a ledger and call directly.
|
|
33
|
+
* A line starting with ⚠ (after leading indent) is a warning the caller
|
|
34
|
+
* colors red.
|
|
35
|
+
*/
|
|
36
|
+
export function sandboxGrantsLines(projectRoot, maxGrants = 6) {
|
|
37
|
+
const lines = [];
|
|
38
|
+
const integrity = verifyLedgerIntegrity(projectRoot);
|
|
39
|
+
const active = listAuthority(projectRoot);
|
|
40
|
+
lines.push('Sandbox Grants (active authority)');
|
|
41
|
+
if (active.length === 0) {
|
|
42
|
+
lines.push(' no active grants — the default is least authority');
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
for (const g of active.slice(0, maxGrants)) {
|
|
46
|
+
lines.push(` ${g.id} session '${g.sessionId}' ${humanRemaining(g.expiresAt)} (granted by ${g.grantedBy})`);
|
|
47
|
+
lines.push(` reason: ${g.reason}`);
|
|
48
|
+
for (const p of g.paths.slice(0, 3))
|
|
49
|
+
lines.push(` ${p}`);
|
|
50
|
+
if (g.paths.length > 3)
|
|
51
|
+
lines.push(` … and ${g.paths.length - 3} more path(s)`);
|
|
52
|
+
lines.push(` revoke: uap sandbox revoke ${g.id}`);
|
|
53
|
+
}
|
|
54
|
+
if (active.length > maxGrants)
|
|
55
|
+
lines.push(` … and ${active.length - maxGrants} more grant(s)`);
|
|
56
|
+
}
|
|
57
|
+
if (integrity.state === 'ok') {
|
|
58
|
+
lines.push(' ledger verified against its trust anchor');
|
|
59
|
+
}
|
|
60
|
+
else if (integrity.state === 'unanchored') {
|
|
61
|
+
lines.push(` ${integrity.detail}`);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
lines.push(` ⚠ INTEGRITY MISMATCH — ${integrity.detail}.`);
|
|
65
|
+
lines.push(' ⚠ Rows above are listed but UNVERIFIED; a sandbox session opens ZERO grant-derived holes.');
|
|
66
|
+
}
|
|
67
|
+
return { lines, mismatch: integrity.state === 'mismatch' };
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=dashboard-grants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard-grants.js","sourceRoot":"","sources":["../../src/cli/dashboard-grants.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The dashboard's Measured Pace rows — the compute/render
|
|
3
|
+
* split. Extracted from src/cli/dashboard.ts so the shaping contract (the
|
|
4
|
+
* estimate gate, most-attempts-first ranking, the honest thin/beyond-cap
|
|
5
|
+
* counts) is testable WITHOUT the cwd-pinned `getModelAnalytics()` singleton:
|
|
6
|
+
* tests construct their own ModelAnalytics at a tmp path and pass it in.
|
|
7
|
+
*/
|
|
8
|
+
import { ModelAnalytics } from '../models/analytics.js';
|
|
9
|
+
/** One row of the dashboard's Measured Pace table (plain display strings —
|
|
10
|
+
* the caller pads and colors). */
|
|
11
|
+
export interface PaceRow {
|
|
12
|
+
modelId: string;
|
|
13
|
+
key: string;
|
|
14
|
+
perTask: string;
|
|
15
|
+
spread: string;
|
|
16
|
+
n: string;
|
|
17
|
+
successPct: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Compute the Measured Pace rows + honest caveats: the agent's own EWMA
|
|
21
|
+
* estimate per (model, taskType, complexity) key — the operator's legibility
|
|
22
|
+
* surface for "how long does this model actually take here". Only keys with
|
|
23
|
+
* a real estimate get a row; the honest caveats (thin keys, keys beyond the
|
|
24
|
+
* cap) travel as counts. Pure with respect to the instance.
|
|
25
|
+
*/
|
|
26
|
+
export declare function computeMeasuredPace(analytics: ModelAnalytics, cap?: number): Promise<{
|
|
27
|
+
rows: PaceRow[];
|
|
28
|
+
thin: number;
|
|
29
|
+
more: number;
|
|
30
|
+
}>;
|
|
31
|
+
//# sourceMappingURL=dashboard-pace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard-pace.d.ts","sourceRoot":"","sources":["../../src/cli/dashboard-pace.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAGxD;mCACmC;AACnC,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,CAAC,EAAE,MAAM,CAAC;IACV,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,cAAc,EACzB,GAAG,SAAI,GACN,OAAO,CAAC;IAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAuB1D"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The dashboard's Measured Pace rows — the compute/render
|
|
3
|
+
* split. Extracted from src/cli/dashboard.ts so the shaping contract (the
|
|
4
|
+
* estimate gate, most-attempts-first ranking, the honest thin/beyond-cap
|
|
5
|
+
* counts) is testable WITHOUT the cwd-pinned `getModelAnalytics()` singleton:
|
|
6
|
+
* tests construct their own ModelAnalytics at a tmp path and pass it in.
|
|
7
|
+
*/
|
|
8
|
+
import { ewmaEstimate, formatDurationMs } from '../delivery/eta-estimate.js';
|
|
9
|
+
import { termSafe } from '../utils/terminal-safe.js';
|
|
10
|
+
/**
|
|
11
|
+
* Compute the Measured Pace rows + honest caveats: the agent's own EWMA
|
|
12
|
+
* estimate per (model, taskType, complexity) key — the operator's legibility
|
|
13
|
+
* surface for "how long does this model actually take here". Only keys with
|
|
14
|
+
* a real estimate get a row; the honest caveats (thin keys, keys beyond the
|
|
15
|
+
* cap) travel as counts. Pure with respect to the instance.
|
|
16
|
+
*/
|
|
17
|
+
export async function computeMeasuredPace(analytics, cap = 8) {
|
|
18
|
+
const allPaceKeys = analytics.distinctOutcomeKeys();
|
|
19
|
+
const paceKeys = allPaceKeys.slice(0, cap);
|
|
20
|
+
const rows = [];
|
|
21
|
+
for (const k of paceKeys) {
|
|
22
|
+
const est = ewmaEstimate(analytics.recentDurations(k.modelId, k.taskType, k.complexity));
|
|
23
|
+
if (!est)
|
|
24
|
+
continue;
|
|
25
|
+
// Foreign strings (the id especially can arrive from env/config) are
|
|
26
|
+
// termSafe'd at the compute choke point; the caller only pads/colors.
|
|
27
|
+
rows.push({
|
|
28
|
+
modelId: termSafe(k.modelId),
|
|
29
|
+
key: termSafe(`${k.taskType}/${k.complexity}`),
|
|
30
|
+
perTask: `~${formatDurationMs(est.etaMs)}`,
|
|
31
|
+
spread: `${formatDurationMs(est.minMs)}–${formatDurationMs(est.maxMs)}`,
|
|
32
|
+
n: `${est.samples}/${est.observed}`,
|
|
33
|
+
successPct: (100 * est.successRate).toFixed(0) + '%',
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
rows,
|
|
38
|
+
thin: paceKeys.length - rows.length,
|
|
39
|
+
more: Math.max(0, allPaceKeys.length - cap),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=dashboard-pace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard-pace.js","sourceRoot":"","sources":["../../src/cli/dashboard-pace.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAE7E,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAarD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,SAAyB,EACzB,GAAG,GAAG,CAAC;IAEP,MAAM,WAAW,GAAG,SAAS,CAAC,mBAAmB,EAAE,CAAC;IACpD,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC3C,MAAM,IAAI,GAAc,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,YAAY,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;QACzF,IAAI,CAAC,GAAG;YAAE,SAAS;QACnB,qEAAqE;QACrE,sEAAsE;QACtE,IAAI,CAAC,IAAI,CAAC;YACR,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;YAC5B,GAAG,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;YAC9C,OAAO,EAAE,IAAI,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;YAC1C,MAAM,EAAE,GAAG,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;YACvE,CAAC,EAAE,GAAG,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,QAAQ,EAAE;YACnC,UAAU,EAAE,CAAC,GAAG,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG;SACrD,CAAC,CAAC;IACL,CAAC;IACD,OAAO;QACL,IAAI;QACJ,IAAI,EAAE,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM;QACnC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,MAAM,GAAG,GAAG,CAAC;KAC5C,CAAC;AACJ,CAAC"}
|