@miller-tech/uap 2.21.2 → 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,549 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client registry — the fleet view's source of truth for which project
|
|
3
|
+
* folders exist and what state they are in.
|
|
4
|
+
*
|
|
5
|
+
* Two sources, merged and deduped by resolved path:
|
|
6
|
+
* 1. Manual entries in `~/.uap/clients.json` (always included, survive
|
|
7
|
+
* moves of the scan root, may pin a name and a dashboard port).
|
|
8
|
+
* 2. Auto-scan of a root directory (default: the parent of the host
|
|
9
|
+
* dashboard's cwd). A scanned dir qualifies as a `managed` client when
|
|
10
|
+
* it contains a real `.uap/` directory; a plain git repo is listed as
|
|
11
|
+
* `unmanaged` (greyed in the UI, no actions).
|
|
12
|
+
*
|
|
13
|
+
* Dashboard ports are STICKY: a client spawned on port P records P in the
|
|
14
|
+
* registry's `ports` map, so later fleet changes (a new folder sorting
|
|
15
|
+
* earlier) never silently move a live dashboard to a different port —
|
|
16
|
+
* the drift-orphan failure mode the architecture review flagged. Computed
|
|
17
|
+
* ports for never-spawned clients skip ports already taken by explicit
|
|
18
|
+
* assignments.
|
|
19
|
+
*
|
|
20
|
+
* Every read is fail-soft per client: one unreadable folder yields a
|
|
21
|
+
* `degraded` card, never a broken endpoint (the whole point of a fleet
|
|
22
|
+
* view is to keep working while one client is on fire).
|
|
23
|
+
*/
|
|
24
|
+
import { spawn, execSync } from 'child_process';
|
|
25
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, readlinkSync, renameSync, statSync, writeFileSync } from 'fs';
|
|
26
|
+
import { get as httpGet } from 'http';
|
|
27
|
+
import { createServer as netCreateServer } from 'net';
|
|
28
|
+
import { homedir } from 'os';
|
|
29
|
+
import { basename, dirname, join, resolve } from 'path';
|
|
30
|
+
import { randomBytes } from 'crypto';
|
|
31
|
+
import { listRuns } from '../delivery/run-state.js';
|
|
32
|
+
import { getTaskData } from './data-service.js';
|
|
33
|
+
import { resolveUapBin } from '../utils/resolve-uap-bin.js';
|
|
34
|
+
/** First port handed to spawned per-client dashboards (host default is 3847). */
|
|
35
|
+
export const CLIENT_BASE_PORT = 3861;
|
|
36
|
+
const DEFAULT_IGNORE = [
|
|
37
|
+
'worktrees', '.worktrees', 'node_modules', 'dist', 'build',
|
|
38
|
+
'*bkp*', '*.offline', '*backup*', 'uam-*',
|
|
39
|
+
];
|
|
40
|
+
const GIT_TTL_MS = 30_000; // branch/dirty don't change faster than 30s (matches data-service)
|
|
41
|
+
const gitCache = new Map();
|
|
42
|
+
export function registryFilePath() {
|
|
43
|
+
return process.env.UAP_CLIENTS_REGISTRY || join(homedir(), '.uap', 'clients.json');
|
|
44
|
+
}
|
|
45
|
+
function loadRegistryFile() {
|
|
46
|
+
try {
|
|
47
|
+
const raw = readFileSync(registryFilePath(), 'utf-8');
|
|
48
|
+
const parsed = JSON.parse(raw);
|
|
49
|
+
return parsed && typeof parsed === 'object' ? parsed : {};
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return {}; // missing/corrupt registry = pure auto-scan (fail-soft)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/** Atomic write: random tmp name in the same directory, O_EXCL ('wx') so a
|
|
56
|
+
* pre-planted symlink at the predictable tmp path can't be followed, then
|
|
57
|
+
* rename. Concurrent writers use distinct tmp names (no torn JSON). */
|
|
58
|
+
export function saveRegistryFile(reg) {
|
|
59
|
+
const file = registryFilePath();
|
|
60
|
+
mkdirSync(dirname(file), { recursive: true });
|
|
61
|
+
const tmp = join(dirname(file), `.clients.json.tmp-${process.pid}-${randomBytes(4).toString('hex')}`);
|
|
62
|
+
writeFileSync(tmp, JSON.stringify(reg, null, 2) + '\n', { flag: 'wx' });
|
|
63
|
+
renameSync(tmp, file);
|
|
64
|
+
}
|
|
65
|
+
/** Ignore match: glob patterns ('*' wildcard) or plain substring, against the
|
|
66
|
+
* lowercase basename. Patterns are bounded (length ≤ 64, ≤ 4 asterisks) so
|
|
67
|
+
* a hand-edited pathological pattern can't build a backtracking regex that
|
|
68
|
+
* stalls the unauthenticated fleet read. */
|
|
69
|
+
function isIgnored(name, patterns) {
|
|
70
|
+
const lower = name.toLowerCase();
|
|
71
|
+
return patterns.some((raw) => {
|
|
72
|
+
const pat = raw.toLowerCase();
|
|
73
|
+
if (!pat || pat.length > 64)
|
|
74
|
+
return false;
|
|
75
|
+
if (pat.includes('*')) {
|
|
76
|
+
if ((pat.match(/\*/g) || []).length > 4)
|
|
77
|
+
return false;
|
|
78
|
+
const re = new RegExp('^' + pat.replace(/[.+?^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '.*') + '$');
|
|
79
|
+
return re.test(lower);
|
|
80
|
+
}
|
|
81
|
+
return lower === pat || lower.includes(pat);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
function isValidPort(p) {
|
|
85
|
+
return typeof p === 'number' && Number.isInteger(p) && p >= 1024 && p <= 65535;
|
|
86
|
+
}
|
|
87
|
+
/** Coerce a registry-supplied port; NaN/garbage → NaN so callers fall back. */
|
|
88
|
+
function coercePort(p) {
|
|
89
|
+
const n = typeof p === 'string' ? Number(p) : p;
|
|
90
|
+
return isValidPort(n) ? n : NaN;
|
|
91
|
+
}
|
|
92
|
+
export function scanRootFor(hostCwd) {
|
|
93
|
+
const reg = loadRegistryFile();
|
|
94
|
+
if (process.env.UAP_CLIENTS_SCAN_ROOT)
|
|
95
|
+
return resolve(process.env.UAP_CLIENTS_SCAN_ROOT);
|
|
96
|
+
if (reg.scanRoot)
|
|
97
|
+
return resolve(reg.scanRoot);
|
|
98
|
+
return dirname(resolve(hostCwd));
|
|
99
|
+
}
|
|
100
|
+
/** Single managed predicate for discovery, summaries, AND the spawn gate:
|
|
101
|
+
* `.uap` must be a real directory (a stray file named `.uap` is not a client). */
|
|
102
|
+
function isManaged(root) {
|
|
103
|
+
try {
|
|
104
|
+
return statSync(join(root, '.uap')).isDirectory();
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
function isRepo(root) {
|
|
111
|
+
return existsSync(join(root, '.git'));
|
|
112
|
+
}
|
|
113
|
+
/** Merge manual registry entries + auto-scan into one sorted, port-assigned list.
|
|
114
|
+
* Port resolution: valid manual `port` → sticky `ports[path]` map → computed
|
|
115
|
+
* (CLIENT_BASE_PORT+n, skipping ports the first two sources already claimed). */
|
|
116
|
+
export function listClients(hostCwd) {
|
|
117
|
+
const reg = loadRegistryFile();
|
|
118
|
+
const hostResolved = resolve(hostCwd);
|
|
119
|
+
const ignore = reg.ignorePatterns && reg.ignorePatterns.length ? reg.ignorePatterns : DEFAULT_IGNORE;
|
|
120
|
+
const byPath = new Map();
|
|
121
|
+
const add = (absPath, opts) => {
|
|
122
|
+
const key = resolve(absPath);
|
|
123
|
+
if (byPath.has(key)) {
|
|
124
|
+
// Manual entry wins over a scan hit for the same folder: keep manual
|
|
125
|
+
// (it may pin name/port) but don't duplicate the card.
|
|
126
|
+
if (opts.manual) {
|
|
127
|
+
const prev = byPath.get(key);
|
|
128
|
+
if (isManaged(key))
|
|
129
|
+
prev.managed = true;
|
|
130
|
+
prev.manual = true;
|
|
131
|
+
if (opts.name)
|
|
132
|
+
prev.name = opts.name;
|
|
133
|
+
if (opts.port)
|
|
134
|
+
prev.port = opts.port;
|
|
135
|
+
}
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
byPath.set(key, {
|
|
139
|
+
path: key,
|
|
140
|
+
name: opts.name || basename(key),
|
|
141
|
+
managed: isManaged(key),
|
|
142
|
+
manual: opts.manual,
|
|
143
|
+
port: opts.port ?? 0, // assigned below
|
|
144
|
+
host: key === hostResolved,
|
|
145
|
+
});
|
|
146
|
+
};
|
|
147
|
+
for (const c of reg.clients ?? []) {
|
|
148
|
+
if (typeof c?.path !== 'string' || !c.path.trim())
|
|
149
|
+
continue;
|
|
150
|
+
add(c.path, { manual: true, name: typeof c.name === 'string' ? c.name : undefined, port: coercePort(c.port) });
|
|
151
|
+
}
|
|
152
|
+
const scanRoot = scanRootFor(hostCwd);
|
|
153
|
+
try {
|
|
154
|
+
for (const ent of readdirSync(scanRoot, { withFileTypes: true })) {
|
|
155
|
+
if (!ent.isDirectory() || ent.name.startsWith('.'))
|
|
156
|
+
continue;
|
|
157
|
+
if (isIgnored(ent.name, ignore))
|
|
158
|
+
continue;
|
|
159
|
+
const dir = join(scanRoot, ent.name);
|
|
160
|
+
// Qualify: managed (.uap) always; plain repos listed as unmanaged.
|
|
161
|
+
if (!isManaged(dir) && !isRepo(dir))
|
|
162
|
+
continue;
|
|
163
|
+
add(dir, { manual: false });
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
/* unreadable scan root → manual entries only */
|
|
168
|
+
}
|
|
169
|
+
const list = [...byPath.values()].filter((c) => existsSync(c.path)).sort((a, b) => a.name.localeCompare(b.name));
|
|
170
|
+
// Resolve ports: manual > sticky map > computed (skipping claimed ports).
|
|
171
|
+
const taken = new Set();
|
|
172
|
+
for (const c of list) {
|
|
173
|
+
if (isValidPort(c.port)) {
|
|
174
|
+
taken.add(c.port);
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
c.port = 0;
|
|
178
|
+
const sticky = reg.ports?.[c.path];
|
|
179
|
+
if (isValidPort(sticky)) {
|
|
180
|
+
c.port = sticky;
|
|
181
|
+
taken.add(sticky);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
let next = CLIENT_BASE_PORT;
|
|
186
|
+
for (const c of list) {
|
|
187
|
+
if (c.port)
|
|
188
|
+
continue;
|
|
189
|
+
while (taken.has(next))
|
|
190
|
+
next++;
|
|
191
|
+
c.port = next;
|
|
192
|
+
taken.add(next);
|
|
193
|
+
}
|
|
194
|
+
return list;
|
|
195
|
+
}
|
|
196
|
+
/** Record a sticky port assignment (spawn-on-demand persists the port it used). */
|
|
197
|
+
export function persistClientPort(clientPath, port) {
|
|
198
|
+
if (!isValidPort(port))
|
|
199
|
+
return;
|
|
200
|
+
const reg = loadRegistryFile();
|
|
201
|
+
const ports = { ...(reg.ports ?? {}) };
|
|
202
|
+
ports[resolve(clientPath)] = port;
|
|
203
|
+
saveRegistryFile({ ...reg, ports });
|
|
204
|
+
}
|
|
205
|
+
/** Record (or, with undefined, clear) the pid of a client's spawned dashboard.
|
|
206
|
+
* `start` is the pid's /proc starttime — recorded when readable so a later
|
|
207
|
+
* stop can refuse a recycled pid by identity, not just liveness.
|
|
208
|
+
*
|
|
209
|
+
* NOTE (security review P3): this is a load-modify-save over the whole
|
|
210
|
+
* registry file with no lock — concurrent serve/stop calls can lose one
|
|
211
|
+
* another's key writes (availability only: a lost pid record makes Stop
|
|
212
|
+
* refuse fail-closed; it can never mis-kill). Single-operator tool. */
|
|
213
|
+
export function recordClientPid(clientPath, pid, start) {
|
|
214
|
+
const reg = loadRegistryFile();
|
|
215
|
+
const pids = { ...(reg.pids ?? {}) };
|
|
216
|
+
const pidStarts = { ...(reg.pidStarts ?? {}) };
|
|
217
|
+
const key = resolve(clientPath);
|
|
218
|
+
if (pid === undefined) {
|
|
219
|
+
delete pids[key];
|
|
220
|
+
delete pidStarts[key];
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
pids[key] = pid;
|
|
224
|
+
if (start)
|
|
225
|
+
pidStarts[key] = start;
|
|
226
|
+
else
|
|
227
|
+
delete pidStarts[key];
|
|
228
|
+
}
|
|
229
|
+
saveRegistryFile({ ...reg, pids, pidStarts });
|
|
230
|
+
}
|
|
231
|
+
/** Linux /proc/<pid>/stat starttime (field 22) — a recycling-safe pid
|
|
232
|
+
* identity. Null when /proc is unreadable (non-Linux, permissions, or the
|
|
233
|
+
* process is already gone). */
|
|
234
|
+
function readPidStart(pid) {
|
|
235
|
+
try {
|
|
236
|
+
// comm (field 2) may contain spaces and parens; everything after the
|
|
237
|
+
// LAST ')' is fields 3.. — starttime is field 22 → index 22-3 = 19.
|
|
238
|
+
const stat = readFileSync(`/proc/${pid}/stat`, 'utf-8');
|
|
239
|
+
const rest = stat.slice(stat.lastIndexOf(')') + 2).trim().split(/\s+/);
|
|
240
|
+
return rest[19] || null;
|
|
241
|
+
}
|
|
242
|
+
catch {
|
|
243
|
+
return null;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
/** Registry mutation helpers (CLI `uap clients add/remove`). */
|
|
247
|
+
export function addManualClient(hostCwd, path, opts = {}) {
|
|
248
|
+
const abs = resolve(path);
|
|
249
|
+
let isDir = false;
|
|
250
|
+
try {
|
|
251
|
+
isDir = statSync(abs).isDirectory();
|
|
252
|
+
}
|
|
253
|
+
catch {
|
|
254
|
+
/* fall through to the clearer error below */
|
|
255
|
+
}
|
|
256
|
+
if (!isDir)
|
|
257
|
+
throw new Error(`not a directory: ${abs}`);
|
|
258
|
+
const reg = loadRegistryFile();
|
|
259
|
+
const clients = (reg.clients ?? []).filter((c) => resolve(c.path) !== abs);
|
|
260
|
+
clients.push({ path: abs, name: opts.name, port: opts.port });
|
|
261
|
+
saveRegistryFile({ ...reg, clients });
|
|
262
|
+
return listClients(hostCwd).find((c) => c.path === abs);
|
|
263
|
+
}
|
|
264
|
+
export function removeManualClient(path) {
|
|
265
|
+
const reg = loadRegistryFile();
|
|
266
|
+
const abs = resolve(path);
|
|
267
|
+
const before = reg.clients ?? [];
|
|
268
|
+
const after = before.filter((c) => resolve(c.path) !== abs);
|
|
269
|
+
if (after.length === before.length)
|
|
270
|
+
return false;
|
|
271
|
+
saveRegistryFile({ ...reg, clients: after });
|
|
272
|
+
return true;
|
|
273
|
+
}
|
|
274
|
+
// ─────────────────────────── per-client reads (fail-soft) ───────────────────────────
|
|
275
|
+
function gitInfo(root) {
|
|
276
|
+
const now = Date.now();
|
|
277
|
+
const cached = gitCache.get(root);
|
|
278
|
+
if (cached && cached.expiresAt > now)
|
|
279
|
+
return { branch: cached.branch, dirty: cached.dirty };
|
|
280
|
+
let branch = '?';
|
|
281
|
+
let dirty = 0;
|
|
282
|
+
try {
|
|
283
|
+
branch = execSync('git branch --show-current', { encoding: 'utf-8', cwd: root, stdio: ['pipe', 'pipe', 'pipe'] }).trim() || '?';
|
|
284
|
+
dirty = execSync('git status --porcelain', { encoding: 'utf-8', cwd: root, stdio: ['pipe', 'pipe', 'pipe'] }).trim().split('\n').filter(Boolean).length;
|
|
285
|
+
}
|
|
286
|
+
catch {
|
|
287
|
+
/* not a repo / git failed */
|
|
288
|
+
}
|
|
289
|
+
gitCache.set(root, { branch, dirty, expiresAt: now + GIT_TTL_MS });
|
|
290
|
+
return { branch, dirty };
|
|
291
|
+
}
|
|
292
|
+
function lastActivity(root) {
|
|
293
|
+
let latest = 0;
|
|
294
|
+
for (const rel of ['.uap', join('.uap', 'deliver-runs'), join('agents', 'data', 'memory')]) {
|
|
295
|
+
try {
|
|
296
|
+
const m = statSync(join(root, rel)).mtimeMs;
|
|
297
|
+
if (m > latest)
|
|
298
|
+
latest = m;
|
|
299
|
+
}
|
|
300
|
+
catch {
|
|
301
|
+
/* absent */
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return latest > 0 ? new Date(latest).toISOString() : null;
|
|
305
|
+
}
|
|
306
|
+
/** Probe `GET /api/health` on a candidate port; true only when a dashboard
|
|
307
|
+
* that serves `expectedRoot` answers. A wrong-root listener must NOT count
|
|
308
|
+
* as alive, or the UI would link to another client's dashboard. */
|
|
309
|
+
export function probeDashboard(port, expectedRoot) {
|
|
310
|
+
return new Promise((ret) => {
|
|
311
|
+
const done = (v) => ret(v);
|
|
312
|
+
const req = httpGet(`http://127.0.0.1:${port}/api/health`, { timeout: 400 }, (res) => {
|
|
313
|
+
let body = '';
|
|
314
|
+
res.on('data', (c) => { body += c; });
|
|
315
|
+
res.on('end', () => {
|
|
316
|
+
try {
|
|
317
|
+
const j = JSON.parse(body);
|
|
318
|
+
done(!!(j.ok && resolve(j.root || '') === resolve(expectedRoot)));
|
|
319
|
+
}
|
|
320
|
+
catch {
|
|
321
|
+
done(false);
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
// A response dying mid-body must not hang the fleet Promise.all.
|
|
325
|
+
res.on('error', () => done(false));
|
|
326
|
+
res.on('aborted', () => done(false));
|
|
327
|
+
});
|
|
328
|
+
req.on('timeout', () => { req.destroy(); done(false); });
|
|
329
|
+
req.on('error', () => done(false));
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
/** First bindable port at or after `start` (loopback). Distinguishes "free"
|
|
333
|
+
* from "occupied by a foreign listener", which a health probe alone cannot. */
|
|
334
|
+
export function findFreePort(start) {
|
|
335
|
+
return new Promise((ret) => {
|
|
336
|
+
const tryPort = (port) => {
|
|
337
|
+
const srv = netCreateServer();
|
|
338
|
+
srv.once('error', () => { tryPort(port + 1); });
|
|
339
|
+
srv.listen(port, '127.0.0.1', () => { srv.close(() => ret(port)); });
|
|
340
|
+
};
|
|
341
|
+
tryPort(start);
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
/** Fleet summary for every registered client. Concurrent probes; per-client
|
|
345
|
+
* failures degrade that card only. */
|
|
346
|
+
export async function getClientSummaries(hostCwd, hostPort) {
|
|
347
|
+
const hostResolved = resolve(hostCwd);
|
|
348
|
+
const entries = listClients(hostCwd);
|
|
349
|
+
const summaries = await Promise.all(entries.map(async (entry) => {
|
|
350
|
+
const s = {
|
|
351
|
+
...entry,
|
|
352
|
+
branch: '?',
|
|
353
|
+
dirty: 0,
|
|
354
|
+
deliver: { running: 0, interrupted: 0, failed: 0, total: 0 },
|
|
355
|
+
tasks: { open: 0, inProgress: 0, blocked: 0, total: 0 },
|
|
356
|
+
lastActivity: null,
|
|
357
|
+
dashboardAlive: false,
|
|
358
|
+
degraded: false,
|
|
359
|
+
};
|
|
360
|
+
if (!entry.managed)
|
|
361
|
+
return s; // unmanaged: no UAP state to read
|
|
362
|
+
// Structural re-check for display: `.uap` may have been swapped for a
|
|
363
|
+
// stray file since discovery — degrade loudly instead of reading zeros.
|
|
364
|
+
if (!isManaged(entry.path)) {
|
|
365
|
+
s.managed = false;
|
|
366
|
+
s.degraded = true;
|
|
367
|
+
s.error = '.uap is not a directory';
|
|
368
|
+
return s;
|
|
369
|
+
}
|
|
370
|
+
try {
|
|
371
|
+
const runs = listRuns(entry.path);
|
|
372
|
+
s.deliver = {
|
|
373
|
+
running: runs.filter((r) => r.status === 'running').length,
|
|
374
|
+
interrupted: runs.filter((r) => r.status === 'interrupted').length,
|
|
375
|
+
failed: runs.filter((r) => r.status === 'failed').length,
|
|
376
|
+
total: runs.length,
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
catch (e) {
|
|
380
|
+
s.degraded = true;
|
|
381
|
+
s.error = `deliver runs unreadable: ${e.message}`;
|
|
382
|
+
}
|
|
383
|
+
try {
|
|
384
|
+
const t = getTaskData(entry.path);
|
|
385
|
+
s.tasks = { open: t.open ?? 0, inProgress: t.inProgress ?? 0, blocked: t.blocked ?? 0, total: t.total ?? 0 };
|
|
386
|
+
}
|
|
387
|
+
catch (e) {
|
|
388
|
+
s.degraded = true;
|
|
389
|
+
s.error = s.error ? s.error + '; ' : '';
|
|
390
|
+
s.error += `tasks unreadable: ${e.message}`;
|
|
391
|
+
}
|
|
392
|
+
Object.assign(s, gitInfo(entry.path));
|
|
393
|
+
s.lastActivity = lastActivity(entry.path);
|
|
394
|
+
// The host project IS this dashboard — probe our own port, not the assigned one.
|
|
395
|
+
s.dashboardAlive = entry.host
|
|
396
|
+
? await probeDashboard(hostPort, hostResolved)
|
|
397
|
+
: await probeDashboard(entry.port, entry.path);
|
|
398
|
+
return s;
|
|
399
|
+
}));
|
|
400
|
+
return summaries;
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Spawn-on-demand: bring up the client's own dashboard server (full control
|
|
404
|
+
* surface — token-gated, loopback-bound, exactly like `uap dashboard serve`).
|
|
405
|
+
*
|
|
406
|
+
* Registry-only: the caller passes the HOST cwd; the client path is looked
|
|
407
|
+
* up in the registry — the dashboard must never be talked into spawning a
|
|
408
|
+
* process in an arbitrary folder.
|
|
409
|
+
*
|
|
410
|
+
* Ports are sticky: if the assigned port is held by a foreign listener, we
|
|
411
|
+
* fall through to the next bindable port and PERSIST it, so a live
|
|
412
|
+
* dashboard's port never drifts when the fleet list changes.
|
|
413
|
+
*
|
|
414
|
+
* Env is scrubbed of the host's UAP_CLIENTS_* overrides — the child serves
|
|
415
|
+
* ITS OWN folder and must scan its own siblings, not the host's test fixture.
|
|
416
|
+
* UAP_DASHBOARD_TOKEN is deliberately inherited so scripted control of the
|
|
417
|
+
* fleet keeps working (each instance still injects the token into its own
|
|
418
|
+
* same-origin page; sharing it grants no cross-origin read).
|
|
419
|
+
*/
|
|
420
|
+
export async function ensureClientDashboard(hostCwd, clientPath) {
|
|
421
|
+
const resolved = resolve(clientPath);
|
|
422
|
+
const entry = listClients(hostCwd).find((c) => c.path === resolved);
|
|
423
|
+
if (!entry)
|
|
424
|
+
throw new Error('client not in registry');
|
|
425
|
+
if (!entry.managed)
|
|
426
|
+
throw new Error('client is not UAP-managed (no .uap directory)');
|
|
427
|
+
if (entry.host)
|
|
428
|
+
throw new Error('client is served by this dashboard already');
|
|
429
|
+
if (await probeDashboard(entry.port, resolved)) {
|
|
430
|
+
return { port: entry.port, spawned: false, alive: true };
|
|
431
|
+
}
|
|
432
|
+
// Occupied by a foreign listener → next bindable port, persisted (sticky).
|
|
433
|
+
const port = await findFreePort(entry.port);
|
|
434
|
+
if (port !== entry.port)
|
|
435
|
+
persistClientPort(resolved, port);
|
|
436
|
+
const { cmd, preArgs } = resolveUapBin();
|
|
437
|
+
const childEnv = { ...process.env };
|
|
438
|
+
delete childEnv.UAP_CLIENTS_REGISTRY;
|
|
439
|
+
delete childEnv.UAP_CLIENTS_SCAN_ROOT;
|
|
440
|
+
// Client dashboards never run the idle sweep (§4.4.2): they share the
|
|
441
|
+
// host's ~/.uap ledger, and a second sweeper would race the operator's
|
|
442
|
+
// dashboard for the same residents. The host instance owns it.
|
|
443
|
+
childEnv.UAP_IDLE_SWEEP = '0';
|
|
444
|
+
const child = spawn(cmd, [...preArgs, 'dashboard', 'serve', '--port', String(port), '--host', '127.0.0.1'], {
|
|
445
|
+
cwd: resolved,
|
|
446
|
+
detached: true,
|
|
447
|
+
stdio: 'ignore',
|
|
448
|
+
env: childEnv,
|
|
449
|
+
});
|
|
450
|
+
// A missing/renamed bin (the bare-'uap' PATH fallback) emits an async
|
|
451
|
+
// 'error' — without a listener that is an uncaughtException that kills
|
|
452
|
+
// the host dashboard. Swallow it; the health loop below reports dead.
|
|
453
|
+
const spawnFailed = new Promise((ret) => child.once('error', () => ret(true)));
|
|
454
|
+
child.unref();
|
|
455
|
+
if (child.pid !== undefined)
|
|
456
|
+
recordClientPid(resolved, child.pid, readPidStart(child.pid));
|
|
457
|
+
// Wait for the health endpoint so the UI can link straight in.
|
|
458
|
+
for (let i = 0; i < 20; i++) {
|
|
459
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
460
|
+
if (await probeDashboard(port, resolved)) {
|
|
461
|
+
return { port, pid: child.pid, spawned: true, alive: true };
|
|
462
|
+
}
|
|
463
|
+
if (await spawnFailed)
|
|
464
|
+
break;
|
|
465
|
+
}
|
|
466
|
+
return { port, pid: child.pid, spawned: true, alive: false };
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Stop a client's spawned dashboard (the UI Stop action / `uap clients stop`).
|
|
470
|
+
*
|
|
471
|
+
* Never signals on liveness alone. The kill happens only after ALL of:
|
|
472
|
+
* (a) a root-matched live probe on the client's port,
|
|
473
|
+
* (b) the recorded pid is an integer > 1 and still alive,
|
|
474
|
+
* (c) identity pinning — the pid's /proc starttime matches the one recorded
|
|
475
|
+
* at spawn (a recycled pid is refused by identity, not liveness), and
|
|
476
|
+
* (d) on Linux, `/proc/<pid>/cwd` is the client root.
|
|
477
|
+
* Where /proc is unreadable (non-Linux) the recorded evidence above is what
|
|
478
|
+
* we have — fail-open there, fail-closed on every mismatch.
|
|
479
|
+
*/
|
|
480
|
+
export async function stopClientDashboard(hostCwd, clientPath) {
|
|
481
|
+
const resolved = resolve(clientPath);
|
|
482
|
+
const entry = listClients(hostCwd).find((c) => c.path === resolved);
|
|
483
|
+
if (!entry)
|
|
484
|
+
throw new Error('client not in registry');
|
|
485
|
+
if (entry.host)
|
|
486
|
+
throw new Error('client is served by this dashboard — stop the server it runs from');
|
|
487
|
+
const reg = loadRegistryFile();
|
|
488
|
+
const pid = reg.pids?.[resolved];
|
|
489
|
+
if (!(await probeDashboard(entry.port, resolved))) {
|
|
490
|
+
if (pid !== undefined)
|
|
491
|
+
recordClientPid(resolved, undefined); // stale bookkeeping
|
|
492
|
+
return { port: entry.port, stopped: false, wasAlive: false };
|
|
493
|
+
}
|
|
494
|
+
if (pid === undefined || !Number.isInteger(pid) || pid <= 1) {
|
|
495
|
+
return {
|
|
496
|
+
port: entry.port, stopped: false, wasAlive: true,
|
|
497
|
+
reason: `a dashboard answers on :${entry.port} but its pid is not recorded — stop it manually`,
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
try {
|
|
501
|
+
process.kill(pid, 0); // ESRCH when recycled/dead; RangeError on garbage → refusal
|
|
502
|
+
}
|
|
503
|
+
catch {
|
|
504
|
+
recordClientPid(resolved, undefined);
|
|
505
|
+
return {
|
|
506
|
+
port: entry.port, stopped: false, wasAlive: true,
|
|
507
|
+
reason: `recorded pid ${pid} is gone but a dashboard still answers on :${entry.port} — stop it manually`,
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
// Identity pinning: same pid, different process (reuse) → refuse.
|
|
511
|
+
const recordedStart = reg.pidStarts?.[resolved];
|
|
512
|
+
const currentStart = readPidStart(pid);
|
|
513
|
+
if (recordedStart && currentStart && recordedStart !== currentStart) {
|
|
514
|
+
return {
|
|
515
|
+
port: entry.port, stopped: false, wasAlive: true,
|
|
516
|
+
reason: `pid ${pid} was recycled (recorded start ${recordedStart} ≠ current ${currentStart}) — refusing to kill`,
|
|
517
|
+
};
|
|
518
|
+
}
|
|
519
|
+
try {
|
|
520
|
+
const procCwd = readlinkSync(`/proc/${pid}/cwd`);
|
|
521
|
+
if (resolve(procCwd) !== resolved) {
|
|
522
|
+
return {
|
|
523
|
+
port: entry.port, stopped: false, wasAlive: true,
|
|
524
|
+
reason: `pid ${pid} (cwd ${procCwd}) does not belong to this client — refusing to kill`,
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
catch {
|
|
529
|
+
/* /proc unreadable (non-Linux or permission): recorded pid + root-matched probe is our evidence */
|
|
530
|
+
}
|
|
531
|
+
try {
|
|
532
|
+
process.kill(pid, 'SIGTERM');
|
|
533
|
+
}
|
|
534
|
+
catch {
|
|
535
|
+
/* raced to exit — the confirmation loop decides */
|
|
536
|
+
}
|
|
537
|
+
for (let i = 0; i < 15; i++) {
|
|
538
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
539
|
+
if (!(await probeDashboard(entry.port, resolved))) {
|
|
540
|
+
recordClientPid(resolved, undefined);
|
|
541
|
+
return { port: entry.port, stopped: true, wasAlive: true };
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
return {
|
|
545
|
+
port: entry.port, stopped: false, wasAlive: true,
|
|
546
|
+
reason: `SIGTERM sent to pid ${pid} but the dashboard on :${entry.port} is still answering`,
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
//# sourceMappingURL=client-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-registry.js","sourceRoot":"","sources":["../../src/dashboard/client-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controls.d.ts","sourceRoot":"","sources":["../../src/dashboard/controls.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"controls.d.ts","sourceRoot":"","sources":["../../src/dashboard/controls.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAWH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAGhE,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAMpC,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAW3D;AACD,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAUvE;AACD,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAKtF;AACD,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAK7E;AACD,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAMxF;AAQD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAOpG;AACD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,CAIjE;AACD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAU5F;AAGD,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAWnF;AAGD,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,OAAO,CAAA;CAAE,CAKvF;AACD,wBAAgB,qBAAqB,IAAI;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAK3D;AAKD,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,EAAE,CAM9D;AACD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAgBhG;AACD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,CAiCjI;AACD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAQjH"}
|