@devrouter/cli 0.6.2 → 0.6.3
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/dist/devrouter-lifecycle-worker.js +36 -5
- package/dist/devrouter.js +11 -7
- package/package.json +1 -1
- package/upgrade-prompts/0.6.3.md +51 -0
|
@@ -5589,7 +5589,7 @@ function retain(session, previous) {
|
|
|
5589
5589
|
|
|
5590
5590
|
// src/core/reliability-operation-store.ts
|
|
5591
5591
|
function installedCliVersion() {
|
|
5592
|
-
return true ? "0.6.
|
|
5592
|
+
return true ? "0.6.3" : "0.0.0-dev";
|
|
5593
5593
|
}
|
|
5594
5594
|
function compareCliVersions(left, right) {
|
|
5595
5595
|
const parts = (value) => value.split(".").map((part) => Number.parseInt(part, 10) || 0);
|
|
@@ -7772,7 +7772,7 @@ function loadRepoConfig(repoPath, read2 = (file) => import_node_fs19.default.rea
|
|
|
7772
7772
|
const config = parseRepoConfigSource(raw, configPath);
|
|
7773
7773
|
const requiredVersion = config.devrouter?.version;
|
|
7774
7774
|
if (requiredVersion && !hasWarnedVersionMismatch) {
|
|
7775
|
-
const cliVersion = true ? "0.6.
|
|
7775
|
+
const cliVersion = true ? "0.6.3" : "0.0.0-dev";
|
|
7776
7776
|
if (cliVersion !== "0.0.0-dev" && compareSemver2(requiredVersion, cliVersion) > 0) {
|
|
7777
7777
|
hasWarnedVersionMismatch = true;
|
|
7778
7778
|
process.stderr.write(
|
|
@@ -11776,9 +11776,9 @@ function createFreshBootstrap(options) {
|
|
|
11776
11776
|
return {
|
|
11777
11777
|
prepare(providerId, network) {
|
|
11778
11778
|
assertFreshBootstrapRequest(options.identity, { initializeNew: true });
|
|
11779
|
-
if (
|
|
11779
|
+
if (!["1.19.0", "1.24.0"].includes(requireReadyDevsyAgent().version))
|
|
11780
11780
|
throw new Error(
|
|
11781
|
-
"Fresh bootstrap is qualified for Devsy 1.19.0; ordinary startup is unchanged."
|
|
11781
|
+
"Fresh bootstrap is qualified for Devsy 1.19.0 or 1.24.0; ordinary startup is unchanged."
|
|
11782
11782
|
);
|
|
11783
11783
|
const declaration = loadRepoConfig(repoPath).managedRuntime?.devcontainer.freshBootstrap;
|
|
11784
11784
|
if (!declaration) throw new Error("Fresh-bootstrap declaration disappeared.");
|
|
@@ -14105,7 +14105,11 @@ function reliabilityRecovery(reason2, repoPath, variant) {
|
|
|
14105
14105
|
switch (reason2) {
|
|
14106
14106
|
case "stop-incomplete":
|
|
14107
14107
|
case "operation-unknown":
|
|
14108
|
-
return [
|
|
14108
|
+
return [
|
|
14109
|
+
`Run: devrouter stop ${checkout}`,
|
|
14110
|
+
"Verify the repository startup hooks preserve retained data and startup is authorized before continuing.",
|
|
14111
|
+
`Run: devrouter ensure ${checkout}${variantOption}`
|
|
14112
|
+
];
|
|
14109
14113
|
case "start-refused":
|
|
14110
14114
|
return [
|
|
14111
14115
|
`Run: devrouter doctor --repo ${checkout} to read the refused fixed host-port claim and its holder`,
|
|
@@ -16319,6 +16323,8 @@ function recoverUnattachedNetworkReservation(repoPath, managedRuntime) {
|
|
|
16319
16323
|
var DEVCONTAINER_OVERLAY = "docker-compose.devrouter.yml";
|
|
16320
16324
|
var DEFAULT_READINESS_TIMEOUT_MS = 12e4;
|
|
16321
16325
|
var POLL_INTERVAL_MS = 1e3;
|
|
16326
|
+
var WorkspaceEnsureRefusalError = class extends Error {
|
|
16327
|
+
};
|
|
16322
16328
|
function assertOverlay(container, repoPath) {
|
|
16323
16329
|
const workingDir = container.labels["com.docker.compose.project.working_dir"];
|
|
16324
16330
|
if (!workingDir || !sameWorkspacePath(workingDir, import_node_path42.default.join(repoPath, ".devcontainer"))) {
|
|
@@ -18016,6 +18022,17 @@ async function workspaceEnsure(requestedRepoPath, options = {}) {
|
|
|
18016
18022
|
return withLifecycleOperationLock(repoPath, async () => {
|
|
18017
18023
|
preflightRuntimeVariant(repoPath, options);
|
|
18018
18024
|
const preparationConfig = loadRepoConfig(repoPath);
|
|
18025
|
+
if (options.repair) {
|
|
18026
|
+
const workspace2 = linked ? readPersistedWorkspace(repoPath) : void 0;
|
|
18027
|
+
if (linked && !workspace2) throw new Error("Repair requires an existing workspace identity.");
|
|
18028
|
+
const retained2 = readManagedRuntimeState(repoPath, workspace2);
|
|
18029
|
+
if (retained2?.status !== "degraded") {
|
|
18030
|
+
const checkout = `'${repoPath.replaceAll("'", "'\\''")}'`;
|
|
18031
|
+
throw new WorkspaceEnsureRefusalError(
|
|
18032
|
+
`Repair requires a persisted degraded managed runtime. Inspect this checkout with: devrouter doctor --repo ${checkout} --json. Ordinary ensure may run repository startup hooks; verify their preservation contract before startup.`
|
|
18033
|
+
);
|
|
18034
|
+
}
|
|
18035
|
+
}
|
|
18019
18036
|
if (!options.repair)
|
|
18020
18037
|
recoverUnattachedNetworkReservation(repoPath, Boolean(preparationConfig.managedRuntime));
|
|
18021
18038
|
assertRetainedNetworkConfiguration({
|
|
@@ -18432,6 +18449,19 @@ function recordLifecycleUnknown(result) {
|
|
|
18432
18449
|
if (result !== void 0) record5.result = result;
|
|
18433
18450
|
});
|
|
18434
18451
|
}
|
|
18452
|
+
function recordLifecycleRefusal(result) {
|
|
18453
|
+
const request = activeWorker;
|
|
18454
|
+
if (request?.kind !== "ensure") return;
|
|
18455
|
+
updateReliabilityOperation(request.identity, (record5) => {
|
|
18456
|
+
if (!matchesFence(record5, request.fence) || record5.worker?.id !== request.workerId || record5.state.operation?.id !== request.operationId || record5.state.operation.status !== "RUNNING")
|
|
18457
|
+
return;
|
|
18458
|
+
stepRecord(
|
|
18459
|
+
record5,
|
|
18460
|
+
request.options.repair && !cancelled && process.connected ? { ...request.fence, type: "completion", operationId: request.operationId, exitCode: 1 } : { ...request.fence, type: "interrupted", operationId: request.operationId }
|
|
18461
|
+
);
|
|
18462
|
+
record5.result = result;
|
|
18463
|
+
});
|
|
18464
|
+
}
|
|
18435
18465
|
function proveLifecycleStopped() {
|
|
18436
18466
|
const request = activeWorker;
|
|
18437
18467
|
if (request?.kind !== "stop")
|
|
@@ -19092,6 +19122,7 @@ process.once("message", async (message) => {
|
|
|
19092
19122
|
message: error instanceof Error ? error.message : String(error)
|
|
19093
19123
|
};
|
|
19094
19124
|
if (error instanceof ExecutionOutcomeError) recordLifecycleOutcome(error.outcome, failure);
|
|
19125
|
+
else if (error instanceof WorkspaceEnsureRefusalError) recordLifecycleRefusal(failure);
|
|
19095
19126
|
else recordLifecycleUnknown(failure);
|
|
19096
19127
|
} catch {
|
|
19097
19128
|
}
|
package/dist/devrouter.js
CHANGED
|
@@ -4898,7 +4898,7 @@ function loadRepoConfig(repoPath, read2 = (file) => import_node_fs8.default.read
|
|
|
4898
4898
|
const config = parseRepoConfigSource(raw, configPath);
|
|
4899
4899
|
const requiredVersion = config.devrouter?.version;
|
|
4900
4900
|
if (requiredVersion && !hasWarnedVersionMismatch) {
|
|
4901
|
-
const cliVersion = true ? "0.6.
|
|
4901
|
+
const cliVersion = true ? "0.6.3" : "0.0.0-dev";
|
|
4902
4902
|
if (cliVersion !== "0.0.0-dev" && compareSemver(requiredVersion, cliVersion) > 0) {
|
|
4903
4903
|
hasWarnedVersionMismatch = true;
|
|
4904
4904
|
process.stderr.write(
|
|
@@ -7171,7 +7171,7 @@ var init_reliability_contract = __esm({
|
|
|
7171
7171
|
|
|
7172
7172
|
// src/core/reliability-operation-store.ts
|
|
7173
7173
|
function installedCliVersion() {
|
|
7174
|
-
return true ? "0.6.
|
|
7174
|
+
return true ? "0.6.3" : "0.0.0-dev";
|
|
7175
7175
|
}
|
|
7176
7176
|
function compareCliVersions(left, right) {
|
|
7177
7177
|
const parts = (value) => value.split(".").map((part) => Number.parseInt(part, 10) || 0);
|
|
@@ -17631,7 +17631,11 @@ function reliabilityRecovery(reason2, repoPath, variant) {
|
|
|
17631
17631
|
switch (reason2) {
|
|
17632
17632
|
case "stop-incomplete":
|
|
17633
17633
|
case "operation-unknown":
|
|
17634
|
-
return [
|
|
17634
|
+
return [
|
|
17635
|
+
`Run: devrouter stop ${checkout}`,
|
|
17636
|
+
"Verify the repository startup hooks preserve retained data and startup is authorized before continuing.",
|
|
17637
|
+
`Run: devrouter ensure ${checkout}${variantOption}`
|
|
17638
|
+
];
|
|
17635
17639
|
case "start-refused":
|
|
17636
17640
|
return [
|
|
17637
17641
|
`Run: devrouter doctor --repo ${checkout} to read the refused fixed host-port claim and its holder`,
|
|
@@ -23495,7 +23499,7 @@ function buildOnboardingPrompt(options = {}) {
|
|
|
23495
23499
|
"- Managed process reuse fingerprints command argv, workspace identity, and the exact adapter snapshot. Variant and current host-port identity always compose with an explicit --fingerprint. If a non-secret runtime value also affects reuse, set `DEVROUTER_PROCESS_FINGERPRINT_ENV` to its comma-separated environment names; secret-like names are rejected and raw values are never persisted.",
|
|
23496
23500
|
"- Managed adapters may use devrouter-process ensure --prepare-command <command> for synchronous dependency preparation under the process lock before app launch. Unchanged owned processes skip preparation; it participates in default fingerprints and must not daemonize or detach.",
|
|
23497
23501
|
"- Host-generated Compose inputs may use managedRuntime.devcontainer.prepareCommand as literal argv. Ensure runs it once from the checkout root before Compose inspection, with a 60-second bound and no implicit shell. Keep .devrouter.yml unchanged. Diagnostics never run it; changed warm mounts require separate verification.",
|
|
23498
|
-
"- Explicit first initialization: managedRuntime.devcontainer.freshBootstrap declares literal command argv, dataVolumes and optional sharedCaches keys. ensure <new-checkout> --initialize-new requires qualified Devsy 1.19.0, new local data volumes and repository-owned database identity/emptiness checks. A durable attempt prevents replay after failure, unknown completion, cancellation, stop, replacement or settlement. Ordinary hooks must preserve data. Consult docs/DEVCONTAINER.md for context and mount prerequisites; never clear the attempt fence or infer reset authority.",
|
|
23502
|
+
"- Explicit first initialization: managedRuntime.devcontainer.freshBootstrap declares literal command argv, dataVolumes and optional sharedCaches keys. ensure <new-checkout> --initialize-new requires qualified Devsy 1.19.0 or 1.24.0, new local data volumes and repository-owned database identity/emptiness checks. A durable attempt prevents replay after failure, unknown completion, cancellation, stop, replacement or settlement. Ordinary hooks must preserve data. Consult docs/DEVCONTAINER.md for context and mount prerequisites; never clear the attempt fence or infer reset authority.",
|
|
23499
23503
|
"- Managed Devsy startup on supported local Unix Docker endpoints captures exact stop ownership before application readiness. With that baseline, canonical stop tolerates changed or missing repository configuration and preserves containers and volumes. Older records without a baseline retain configuration-dependent stop; installing a new CLI does not establish historical ownership. Invalid or changed ownership never falls back. Do not replay destructive bootstrap hooks to obtain a baseline.",
|
|
23500
23504
|
"- Owner status is `present`, `missing`, `locked`, or `conflict`. Dirty or locked full down fails before side effects. `workspace gc` is a dry run; only `--yes` deletes exact eligible missing resources and records, never Git worktrees, branches, or prune state.",
|
|
23501
23505
|
"- `devrouter workspace cleanup --repo . --inactive-for 30d --check-merged --json` is report-only and never mutates the workspace runtime, routes, ownership, Git, Docker, applications, worktrees, or branches. It reports ownership, workspace runtime registration, runtime state (`running|stopped|busy|not-found|absent|unknown`), checkout, advisory activity, route, and integration evidence. Local DevPod/Devsy list/status checks always run; `--check-merged` alone enables read-only origin and matching GitHub/GitLab checks. Treat `not-found` as stale runtime after Docker pruning; busy, unavailable, or conflicting evidence suppresses destructive suggestions. Explicit `gc`/`down` can remove exact stale registration only after expected-ID `NotFound` proof and ownership revalidation. Runtime `lastUsed` remains advisory.",
|
|
@@ -25652,7 +25656,7 @@ function probeInstalledCliVersion(executable) {
|
|
|
25652
25656
|
}
|
|
25653
25657
|
function buildCliPathCheck(options = {}) {
|
|
25654
25658
|
const id5 = "global.cli-path";
|
|
25655
|
-
const runningVersion = options.runningVersion ?? (true ? "0.6.
|
|
25659
|
+
const runningVersion = options.runningVersion ?? (true ? "0.6.3" : "0.0.0-dev");
|
|
25656
25660
|
if (runningVersion === "0.0.0-dev") {
|
|
25657
25661
|
return {
|
|
25658
25662
|
id: id5,
|
|
@@ -26550,7 +26554,7 @@ async function buildDoctorReport(options = {}) {
|
|
|
26550
26554
|
suggestion: `Remedy ${expansionNotice.remedy.code}: set a named default profile other than '${expansionNotice.profile}'${remedyCandidates}.`
|
|
26551
26555
|
});
|
|
26552
26556
|
}
|
|
26553
|
-
const cliVersion = true ? "0.6.
|
|
26557
|
+
const cliVersion = true ? "0.6.3" : "0.0.0-dev";
|
|
26554
26558
|
const configVersion = config.devrouter?.version;
|
|
26555
26559
|
const installedKnown = cliVersion !== "0.0.0-dev";
|
|
26556
26560
|
const versionComparison = installedKnown && configVersion ? compareSemver(configVersion, cliVersion) : void 0;
|
|
@@ -42227,7 +42231,7 @@ var init_version = __esm({
|
|
|
42227
42231
|
|
|
42228
42232
|
// src/cli.ts
|
|
42229
42233
|
var import_commander = require("commander");
|
|
42230
|
-
var CLI_VERSION = true ? "0.6.
|
|
42234
|
+
var CLI_VERSION = true ? "0.6.3" : "0.0.0-dev";
|
|
42231
42235
|
var VERSION_FLAGS = /* @__PURE__ */ new Set(["-V", "--version"]);
|
|
42232
42236
|
function withErrorHandling(action2) {
|
|
42233
42237
|
return async (...args) => {
|
package/package.json
CHANGED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Upgrade to devrouter 0.6.3
|
|
2
|
+
|
|
3
|
+
This patch qualifies explicit fresh managed initialization on Devsy 1.24.0 in
|
|
4
|
+
addition to 1.19.0. The operation and its data, context and ownership guarantees
|
|
5
|
+
are unchanged. Early ineligible repair now refuses before repository preparation
|
|
6
|
+
and records a known failure; cancellation and uncertain completion stay distinct.
|
|
7
|
+
Use ordinary ensure for startup and inspect exact-checkout diagnostics when an
|
|
8
|
+
explicit recorded-profile repair is ineligible. Qualify preserving source hooks
|
|
9
|
+
before starting a retained environment. Ordinary startup retains its existing provider support.
|
|
10
|
+
|
|
11
|
+
## Task
|
|
12
|
+
|
|
13
|
+
Within an authorized consumer adaptation, install the published CLI, verify its
|
|
14
|
+
executable/version, bump `devrouter.version` in `.devrouter.yml`, and refresh
|
|
15
|
+
existing guidance with `devrouter repo agents`. Explicitly managed controllers
|
|
16
|
+
must use the matching initialization protocol. No configuration migration is
|
|
17
|
+
required for ordinary startup.
|
|
18
|
+
|
|
19
|
+
Before adopting a changed Devsy release, follow the explicit agent preparation
|
|
20
|
+
in `docs/GETTING_STARTED.md`: `devrouter setup --yes --workspace-runtime devsy`.
|
|
21
|
+
That machine setup needs its own authority. A host-governed readiness result
|
|
22
|
+
without a verified matching agent does not prove replacement can acquire one.
|
|
23
|
+
The 1.24.0 replacement qualification uses the matching verified Linux agent;
|
|
24
|
+
ordinary lifecycle calls never substitute an unverified inherited binary.
|
|
25
|
+
|
|
26
|
+
For a new disposable checkout, follow the current `docs/DEVCONTAINER.md`
|
|
27
|
+
`freshBootstrap` contract and request `ensure <path> --initialize-new` only
|
|
28
|
+
within existing consumer authority. Qualify the complete selected composition,
|
|
29
|
+
new local data volumes, explicit shared caches and repository-owned database
|
|
30
|
+
identity/emptiness checks. Unqualified provider versions and contexts refuse.
|
|
31
|
+
|
|
32
|
+
The durable attempt is consumed before provider creation. Failure, cancellation,
|
|
33
|
+
unknown completion, stop, replacement, registration loss and settlement never
|
|
34
|
+
rearm it. Preserve partial data and use supported preserving recovery. Never
|
|
35
|
+
clear the attempt or treat this operation as an existing-environment reset.
|
|
36
|
+
|
|
37
|
+
## Validation
|
|
38
|
+
|
|
39
|
+
1. Run the consumer's static configuration and bootstrap checks for actual edits.
|
|
40
|
+
2. With runtime authority, initialize a new disposable fixture on the exact
|
|
41
|
+
qualified provider version; verify actual work, retained synthetic data
|
|
42
|
+
through preserving stop/resume, and refusal of a repeated initialization.
|
|
43
|
+
3. Check failure/cancellation retention and replay refusal. End with canonical
|
|
44
|
+
`devrouter stop <path>` and verify stopped provider state and zero exact routes
|
|
45
|
+
unless the user explicitly retains the environment.
|
|
46
|
+
|
|
47
|
+
## Report
|
|
48
|
+
|
|
49
|
+
Report exact source/package/executable and provider identities, actual checks,
|
|
50
|
+
retained-data evidence, remaining consumer prerequisites and final runtime state.
|
|
51
|
+
A compatible release or installation alone does not prove consumer recovery.
|