@timurproko/a1 0.2.7-dev.1252 → 0.2.7-dev.1255
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/bin/ui.js +3 -3
- package/dist/app/session-shell/clipboard-diagnostics.d.ts +2 -2
- package/dist/app/session-shell/clipboard-image.d.ts +0 -1
- package/dist/app/session-shell/clipboard-image.js +1 -1
- package/dist/app/session-shell/dialog-coordinator.d.ts +6 -5
- package/dist/app/session-shell/dialog-coordinator.js +3 -4
- package/dist/app/session-shell/dock-chrome.d.ts +11 -6
- package/dist/app/session-shell/dock-chrome.js +5 -8
- package/dist/app/session-shell/editor-hyperlink-budget.d.ts +0 -2
- package/dist/app/session-shell/editor-hyperlink-budget.js +1 -1
- package/dist/app/session-shell/exit-notice.d.ts +2 -2
- package/dist/app/session-shell/exit-notice.js +1 -1
- package/dist/app/session-shell/extension-surface.d.ts +8 -7
- package/dist/app/session-shell/helper-pool.d.ts +3 -4
- package/dist/app/session-shell/helper-pool.js +1 -1
- package/dist/app/session-shell/image-preparation-client.d.ts +4 -3
- package/dist/app/session-shell/image-preparation.d.ts +0 -2
- package/dist/app/session-shell/image-preparation.js +2 -2
- package/dist/app/session-shell/image-source.d.ts +2 -3
- package/dist/app/session-shell/image-source.js +2 -2
- package/dist/app/session-shell/input-surface-switch.d.ts +9 -7
- package/dist/app/session-shell/input-surface-switch.js +1 -2
- package/dist/app/session-shell/login-interaction.d.ts +5 -4
- package/dist/app/session-shell/login-interaction.js +2 -3
- package/dist/app/session-shell/paste-executor.d.ts +4 -8
- package/dist/app/session-shell/paste-executor.js +2 -2
- package/dist/app/session-shell/paste-protocol.d.ts +2 -2
- package/dist/app/session-shell/path-chip-presentation.d.ts +0 -5
- package/dist/app/session-shell/path-chip-presentation.js +3 -3
- package/dist/app/session-shell/prompt-chips.d.ts +8 -7
- package/dist/app/session-shell/prompt-history-controller.d.ts +3 -3
- package/dist/app/session-shell/prompt-submission.d.ts +5 -2
- package/dist/app/session-shell/prompt-submission.js +4 -5
- package/dist/app/session-shell/quit-outro-effects.d.ts +3 -3
- package/dist/app/session-shell/quit-outro-effects.js +1 -4
- package/dist/app/session-shell/quit-outro.d.ts +9 -12
- package/dist/app/session-shell/quit-outro.js +11 -11
- package/dist/app/session-shell/response-copy-protocol.d.ts +3 -2
- package/dist/app/session-shell/response-copy-transport.d.ts +2 -14
- package/dist/app/session-shell/response-copy-transport.js +1 -1
- package/dist/app/session-shell/session-lifecycle.d.ts +2 -1
- package/dist/app/session-shell/session-shell-root.d.ts +74 -89
- package/dist/app/session-shell/session-shell-root.js +81 -113
- package/dist/app/session-shell/session-shell.d.ts +13 -16
- package/dist/app/session-shell/session-shell.js +144 -268
- package/dist/app/session-shell/session-viewport-controller.d.ts +7 -6
- package/dist/app/session-shell/session-viewport-controller.js +2 -2
- package/dist/app/session-shell/settings-bindings.d.ts +24 -2
- package/dist/app/session-shell/settings-bindings.js +24 -0
- package/dist/app/session-shell/share-operation.d.ts +3 -3
- package/dist/app/session-shell/share-operation.js +4 -6
- package/dist/app/session-shell/shell-clipboard.d.ts +59 -0
- package/dist/app/session-shell/shell-clipboard.js +119 -0
- package/dist/app/session-shell/shell-editor-factory.d.ts +8 -4
- package/dist/app/session-shell/shell-editor-factory.js +13 -15
- package/dist/app/session-shell/shell-host.d.ts +16 -17
- package/dist/app/session-shell/shell-host.js +18 -19
- package/dist/app/session-shell/shell-layout.d.ts +2 -2
- package/dist/app/session-shell/shell-prompt-suggestions.d.ts +26 -0
- package/dist/app/session-shell/shell-prompt-suggestions.js +48 -0
- package/dist/app/session-shell/suggestion-surface.d.ts +1 -6
- package/dist/app/session-shell/suggestion-surface.js +1 -1
- package/dist/app/session-shell/system-clipboard.d.ts +2 -14
- package/dist/app/session-shell/system-clipboard.js +2 -7
- package/dist/app/session-shell/transcript-document.d.ts +11 -8
- package/dist/app/session-shell/transcript-document.js +13 -14
- package/dist/app/session-shell/viewport-layout.d.ts +2 -2
- package/dist/app/session-shell/workflow-output.d.ts +5 -3
- package/dist/app/session-shell/workflow-output.js +13 -15
- package/dist/cli/package-messages.d.ts +0 -1
- package/dist/cli/package-messages.js +1 -1
- package/dist/cli/session-context.d.ts +1 -1
- package/dist/cli/uninstall.d.ts +3 -2
- package/dist/composition/owned-settings.d.ts +2 -1
- package/dist/composition/owned-settings.js +0 -3
- package/dist/composition/owned-ui.d.ts +1 -1
- package/dist/composition/owned-ui.js +27 -27
- package/dist/composition/reference-selection-options.d.ts +1 -1
- package/dist/composition/reference-selection-options.js +1 -1
- package/dist/composition/session-runtime-registry.d.ts +2 -1
- package/dist/composition/settings-route-host.js +3 -10
- package/dist/composition/settings-search-input.d.ts +2 -1
- package/dist/composition/startup-route.d.ts +2 -2
- package/dist/composition/startup-route.js +2 -2
- package/dist/contracts/owned-ui/extension-ui.d.ts +2 -1
- package/dist/contracts/owned-ui/index.d.ts +1 -0
- package/dist/contracts/owned-ui/session-presenters.d.ts +3 -0
- package/dist/contracts/owned-ui/shell-components.d.ts +543 -0
- package/dist/contracts/owned-ui/shell-components.js +1 -0
- package/dist/contracts/presentation/component.d.ts +17 -0
- package/dist/contracts/presentation/component.js +8 -0
- package/dist/contracts/presentation/index.d.ts +6 -15
- package/dist/contracts/presentation/index.js +2 -0
- package/dist/contracts/presentation/terminal.d.ts +290 -0
- package/dist/contracts/presentation/terminal.js +1 -0
- package/dist/contracts/presentation/theme.d.ts +46 -0
- package/dist/contracts/presentation/theme.js +1 -0
- package/dist/features/launch/development-launch.js +1 -1
- package/dist/features/launch/runtime-selection.d.ts +2 -2
- package/dist/features/launch/runtime-selection.js +2 -2
- package/dist/features/owned-ui/project-trust-prompt.d.ts +2 -2
- package/dist/features/owned-ui/project-trust-prompt.js +1 -1
- package/dist/features/owned-ui/release-note-state.d.ts +2 -1
- package/dist/features/owned-ui/settings-app.js +38 -219
- package/dist/features/owned-ui/settings-edits.d.ts +31 -0
- package/dist/features/owned-ui/settings-edits.js +139 -0
- package/dist/features/owned-ui/settings-scroll-rail.d.ts +29 -0
- package/dist/features/owned-ui/settings-scroll-rail.js +79 -0
- package/dist/features/owned-ui/settings-search-input.d.ts +2 -1
- package/dist/features/prompt-history/service.d.ts +3 -2
- package/dist/foundation/lifecycle/claim-gate.d.ts +2 -1
- package/dist/foundation/release/automatic-update.d.ts +5 -14
- package/dist/foundation/release/automatic-update.js +14 -14
- package/dist/foundation/release/bootstrap.js +4 -4
- package/dist/foundation/release/dependency-certification.d.ts +0 -1
- package/dist/foundation/release/dependency-certification.js +1 -1
- package/dist/foundation/release/early-accent.d.ts +2 -2
- package/dist/foundation/release/early-accent.js +1 -1
- package/dist/foundation/release/index.d.ts +2 -2
- package/dist/foundation/release/index.js +1 -1
- package/dist/foundation/release/latest-release.d.ts +3 -18
- package/dist/foundation/release/latest-release.js +10 -10
- package/dist/foundation/release/ordinary-launch-selection.d.ts +1 -1
- package/dist/foundation/release/ordinary-launch-selection.js +1 -1
- package/dist/foundation/release/release-gc.d.ts +3 -3
- package/dist/foundation/release/release-gc.js +4 -4
- package/dist/foundation/release/{cohort-state.d.ts → release-state.d.ts} +23 -23
- package/dist/foundation/release/{cohort-state.js → release-state.js} +8 -8
- package/dist/foundation/release/update-activation.js +2 -2
- package/dist/foundation/release/update-execution-lease.d.ts +2 -3
- package/dist/foundation/release/update-execution-lease.js +1 -1
- package/dist/foundation/release/update-launch.d.ts +2 -2
- package/dist/foundation/release/update.d.ts +0 -2
- package/dist/foundation/release/update.js +14 -14
- package/dist/foundation/startup/startup-budget.d.ts +5 -5
- package/dist/foundation/startup/startup-budget.js +2 -2
- package/dist/integrations/pi/components/editor-interaction.d.ts +4 -12
- package/dist/integrations/pi/components/index.d.ts +15 -9
- package/dist/integrations/pi/components/index.js +9 -5
- package/dist/integrations/pi/components/lazy-selectors.d.ts +2 -10
- package/dist/integrations/pi/components/lazy-selectors.js +1 -1
- package/dist/integrations/pi/components/modal-frame.d.ts +5 -22
- package/dist/integrations/pi/components/modal-frame.js +3 -23
- package/dist/integrations/pi/components/owned-editor-ux.d.ts +4 -3
- package/dist/integrations/pi/components/prompt-input-port.d.ts +2 -19
- package/dist/integrations/pi/components/resources/builtin-themes.d.ts +2 -1
- package/dist/integrations/pi/components/shell-editor-autocomplete.d.ts +3 -2
- package/dist/integrations/pi/components/shell-footer-status.d.ts +2 -2
- package/dist/integrations/pi/components/shell-footer-status.js +3 -2
- package/dist/integrations/pi/components/shell-presenters-info.d.ts +6 -5
- package/dist/integrations/pi/components/shell-presenters-info.js +2 -1
- package/dist/integrations/pi/components/shell-session-info-reference.d.ts +2 -1
- package/dist/integrations/pi/components/shell-shared-facade.d.ts +33 -227
- package/dist/integrations/pi/components/shell-shared-facade.js +8 -1
- package/dist/integrations/pi/components/skills-command.d.ts +1 -9
- package/dist/integrations/pi/components/skills-command.js +5 -5
- package/dist/integrations/pi/components/theme.d.ts +9 -2
- package/dist/integrations/pi/components/theme.js +17 -2
- package/dist/integrations/pi/components/thinking-selector-dialog.d.ts +2 -1
- package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.d.ts +2 -2
- package/dist/integrations/pi/engine/adapter.d.ts +3 -5
- package/dist/integrations/pi/engine/adapter.js +3 -12
- package/dist/integrations/pi/engine/changelog.d.ts +2 -2
- package/dist/integrations/pi/engine/changelog.js +3 -3
- package/dist/integrations/pi/engine/compaction-progress.d.ts +2 -3
- package/dist/integrations/pi/engine/compaction-progress.js +1 -1
- package/dist/integrations/pi/engine/conformance.d.ts +2 -1
- package/dist/integrations/pi/engine/default-model-setting.d.ts +0 -2
- package/dist/integrations/pi/engine/default-model-setting.js +1 -2
- package/dist/integrations/pi/engine/event-delivery.d.ts +2 -1
- package/dist/integrations/pi/engine/extension-ui-binding.d.ts +2 -1
- package/dist/integrations/pi/engine/host.js +2 -2
- package/dist/integrations/pi/engine/message-values.d.ts +0 -1
- package/dist/integrations/pi/engine/message-values.js +1 -1
- package/dist/integrations/pi/engine/pending-delivery.d.ts +0 -4
- package/dist/integrations/pi/engine/pending-delivery.js +3 -3
- package/dist/integrations/pi/engine/ports.d.ts +7 -1
- package/dist/integrations/pi/engine/ports.js +4 -0
- package/dist/integrations/pi/engine/project-trust-preflight.d.ts +2 -1
- package/dist/integrations/pi/engine/prompt-suggestions.d.ts +3 -2
- package/dist/integrations/pi/engine/provider-authentication.d.ts +1 -1
- package/dist/integrations/pi/engine/public-main-entry.d.ts +1 -5
- package/dist/integrations/pi/engine/public-main-entry.js +1 -1
- package/dist/integrations/pi/engine/repository-pr-rest.d.ts +1 -9
- package/dist/integrations/pi/engine/repository-pr-rest.js +2 -2
- package/dist/integrations/pi/engine/repository-pr.d.ts +1 -3
- package/dist/integrations/pi/engine/repository-pr.js +1 -1
- package/dist/integrations/pi/engine/resource-catalog.d.ts +2 -1
- package/dist/integrations/pi/engine/session-integration.d.ts +1 -1
- package/dist/integrations/pi/engine/session-runtime.d.ts +4 -3
- package/dist/integrations/pi/engine/settings-bridge.d.ts +0 -2
- package/dist/integrations/pi/engine/settings-bridge.js +1 -1
- package/dist/integrations/pi/engine/settings-port.d.ts +3 -2
- package/dist/integrations/pi/engine/transcript-projection.d.ts +2 -1
- package/dist/integrations/pi/engine/workflow-contexts.d.ts +1 -1
- package/dist/integrations/pi/engine/workflow-runner.d.ts +1 -1
- package/dist/integrations/pi/engine/workflow-support.d.ts +0 -6
- package/dist/integrations/pi/engine/workflow-support.js +4 -18
- package/dist/integrations/pi/engine/workflows.d.ts +5 -5
- package/dist/integrations/pi/session-presenters/components.d.ts +3 -0
- package/dist/integrations/pi/session-presenters/components.js +75 -0
- package/dist/integrations/pi/session-presenters/index.d.ts +1 -0
- package/dist/integrations/pi/session-presenters/index.js +1 -0
- package/dist/integrations/pi/session-presenters/presentation.d.ts +3 -0
- package/dist/integrations/pi/session-presenters/presentation.js +10 -0
- package/dist/integrations/pi/session-presenters/presenters.d.ts +2 -1
- package/dist/integrations/pi/session-presenters/presenters.js +3 -1
- package/dist/integrations/pi/tui-runtime/adapter.js +21 -30
- package/dist/integrations/pi/tui-runtime/contracts.d.ts +22 -166
- package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +5 -40
- package/dist/integrations/pi/tui-runtime/index.d.ts +1 -0
- package/dist/integrations/pi/tui-runtime/index.js +1 -0
- package/dist/integrations/pi/tui-runtime/input-presentation-coordinator.d.ts +4 -6
- package/dist/integrations/pi/tui-runtime/overlay-geometry.d.ts +2 -8
- package/dist/integrations/pi/tui-runtime/overlay-geometry.js +3 -9
- package/dist/integrations/pi/tui-runtime/runtime-factory.d.ts +3 -0
- package/dist/integrations/pi/tui-runtime/runtime-factory.js +11 -0
- package/dist/ui/components/index.d.ts +2 -2
- package/dist/ui/components/index.js +1 -1
- package/dist/ui/components/selection-copy.d.ts +0 -1
- package/dist/ui/components/selection-copy.js +0 -12
- package/dist/ui/components/theme.d.ts +4 -19
- package/dist/ui/components/theme.js +6 -0
- package/dist/ui/settings/declarations.d.ts +2 -3
- package/dist/ui/settings/declarations.js +2 -3
- package/dist/ui/settings/early-accent.js +1 -1
- package/dist/ui/settings/index.d.ts +3 -5
- package/dist/ui/settings/index.js +2 -3
- package/dist/ui/settings/manager.d.ts +0 -4
- package/dist/ui/settings/manager.js +6 -62
- package/dist/ui/settings/resolution.d.ts +6 -18
- package/dist/ui/settings/resolution.js +4 -103
- package/dist/ui/settings/sections.d.ts +0 -4
- package/dist/ui/settings/sections.js +1 -1
- package/docs/architecture/boundaries.md +2 -2
- package/docs/architecture/internal-naming.md +2 -0
- package/docs/architecture/project-structure.md +4 -2
- package/docs/validation.md +1 -1
- package/package.json +3 -4
- package/dist/integrations/pi/components/components.d.ts +0 -4
- package/dist/integrations/pi/components/components.js +0 -48
- package/dist/integrations/pi/components/conformance.d.ts +0 -18
- package/dist/integrations/pi/components/conformance.js +0 -70
- package/dist/integrations/pi/components/shell-components.d.ts +0 -7
- package/dist/integrations/pi/components/shell-components.js +0 -7
- package/dist/integrations/pi/components/upstream/theme/theme-controller.d.ts +0 -33
- package/dist/integrations/pi/components/upstream/theme/theme-controller.js +0 -114
- package/dist/ui/settings/migrations.d.ts +0 -19
- package/dist/ui/settings/migrations.js +0 -225
- package/dist/ui/settings/progress-palette.generated.d.ts +0 -139
- package/dist/ui/settings/progress-palette.generated.js +0 -139
- /package/dist/{foundation/release → contracts/presentation}/progress-palette.generated.d.ts +0 -0
- /package/dist/{foundation/release → contracts/presentation}/progress-palette.generated.js +0 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { scrollForTrackPage, scrollbarPresentation, ScrollbarRails, } from "../../ui/components/index.js";
|
|
2
|
+
/** Identity of the settings list rail in the shared rail state. */
|
|
3
|
+
const RAIL_KEY = "settings";
|
|
4
|
+
// Compatibility: the transcript rail stays lit this long after a scroll, and repaints just after.
|
|
5
|
+
const SCROLL_LINGER_MS = 900;
|
|
6
|
+
const SCROLL_LINGER_REPAINT_MS = 925;
|
|
7
|
+
/** The settings list's scrollbar rail: hover, thumb drag, track paging, and the lingering highlight after a scroll. */
|
|
8
|
+
export class SettingsScrollRail {
|
|
9
|
+
#rails = new ScrollbarRails();
|
|
10
|
+
#frame = null;
|
|
11
|
+
#activeUntil = 0;
|
|
12
|
+
#activityTimer;
|
|
13
|
+
#renderedScroll;
|
|
14
|
+
/** Notes the frame's scroll; a moved list keeps the rail lit and repaints once the highlight lapses. */
|
|
15
|
+
noteRenderedScroll(scroll, now, requestRender) {
|
|
16
|
+
// Rationale: every way of scrolling ends in this frame, so a moved list is noticed here
|
|
17
|
+
// once rather than at each wheel, drag, key, and search branch.
|
|
18
|
+
if (this.#renderedScroll !== undefined && this.#renderedScroll !== scroll) {
|
|
19
|
+
this.#activeUntil = Math.max(this.#activeUntil, now + SCROLL_LINGER_MS);
|
|
20
|
+
this.#clearTimer();
|
|
21
|
+
this.#activityTimer = setTimeout(() => {
|
|
22
|
+
this.#activityTimer = undefined;
|
|
23
|
+
requestRender();
|
|
24
|
+
}, SCROLL_LINGER_REPAINT_MS);
|
|
25
|
+
this.#activityTimer.unref?.();
|
|
26
|
+
}
|
|
27
|
+
this.#renderedScroll = scroll;
|
|
28
|
+
}
|
|
29
|
+
presentation(input) {
|
|
30
|
+
return scrollbarPresentation({
|
|
31
|
+
...input,
|
|
32
|
+
hovered: this.#rails.isHovered(RAIL_KEY),
|
|
33
|
+
dragging: this.#rails.isDragging(RAIL_KEY),
|
|
34
|
+
activeUntil: this.#activeUntil,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/** Records where the rail was painted, or null when this frame has no rail. */
|
|
38
|
+
setFrame(frame) {
|
|
39
|
+
this.#frame = frame === null ? null : { ...frame, rail: { ...frame.rail, key: RAIL_KEY } };
|
|
40
|
+
}
|
|
41
|
+
// Rationale: the rail takes its share of a pointer report first: hover, a thumb drag, or a
|
|
42
|
+
// track page. Owned means the list must not see the report; changed means the rail looks different.
|
|
43
|
+
pointer(event, scroll) {
|
|
44
|
+
const frame = this.#frame;
|
|
45
|
+
const wasHovered = this.#rails.isHovered(RAIL_KEY);
|
|
46
|
+
if (frame === null) {
|
|
47
|
+
this.#rails.clear();
|
|
48
|
+
return { owned: false, changed: wasHovered, overRail: false };
|
|
49
|
+
}
|
|
50
|
+
const pointer = { column: event.column, row: event.row - 1 };
|
|
51
|
+
if (this.#rails.isDragging(RAIL_KEY)) {
|
|
52
|
+
// Invariant: a drag keeps the pointer wherever it goes until the button comes up.
|
|
53
|
+
if (event.kind === "release") {
|
|
54
|
+
this.#rails.endDrag();
|
|
55
|
+
return { owned: true, changed: true, overRail: false };
|
|
56
|
+
}
|
|
57
|
+
const target = this.#rails.dragTo(frame.rail, frame.geometry, pointer);
|
|
58
|
+
return target === null ? { owned: true, changed: true, overRail: false } : { owned: true, changed: true, overRail: false, scroll: target };
|
|
59
|
+
}
|
|
60
|
+
const over = this.#rails.notePointer([frame.rail], pointer) !== null;
|
|
61
|
+
if (!over)
|
|
62
|
+
return { owned: false, changed: wasHovered, overRail: false };
|
|
63
|
+
if (event.kind === "press" && !this.#rails.beginDrag(frame.rail, frame.geometry, pointer)) {
|
|
64
|
+
return { owned: true, changed: true, overRail: true, scroll: scrollForTrackPage(frame.geometry, pointer.row - frame.rail.rowStart, scroll, frame.page) };
|
|
65
|
+
}
|
|
66
|
+
return { owned: true, changed: true, overRail: true };
|
|
67
|
+
}
|
|
68
|
+
/** Drops hover and any drag, as when a dialog takes the screen. */
|
|
69
|
+
clear() { this.#rails.clear(); }
|
|
70
|
+
dispose() {
|
|
71
|
+
this.#clearTimer();
|
|
72
|
+
this.#rails.clear();
|
|
73
|
+
}
|
|
74
|
+
#clearTimer() {
|
|
75
|
+
if (this.#activityTimer !== undefined)
|
|
76
|
+
clearTimeout(this.#activityTimer);
|
|
77
|
+
this.#activityTimer = undefined;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { UiTheme } from "../../ui/components/index.js";
|
|
2
|
-
|
|
2
|
+
interface SettingsSearchPointerEvent {
|
|
3
3
|
readonly kind: "press" | "motion" | "release";
|
|
4
4
|
readonly button: number;
|
|
5
5
|
readonly column: number;
|
|
@@ -27,3 +27,4 @@ export interface SettingsSearchInputFactory {
|
|
|
27
27
|
create(options: SettingsSearchInputOptions): SettingsSearchInput;
|
|
28
28
|
isTextInput(data: string): boolean;
|
|
29
29
|
}
|
|
30
|
+
export {};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { Worker } from "node:worker_threads";
|
|
2
2
|
import { type PromptHistoryFailure, type PromptHistoryPort, type PromptHistoryResult, type PromptHistorySnapshot, type PromptHistorySubmission } from "../../contracts/owned-ui/index.js";
|
|
3
3
|
import { type PromptHistoryScope } from "./paths.js";
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
type HistoryRecoveryState = "starting" | "ready" | "recovering" | "blocked-storage" | "closing" | "closed";
|
|
5
|
+
interface HistoryClock {
|
|
6
6
|
now(): number;
|
|
7
7
|
setTimeout(callback: () => void, milliseconds: number): ReturnType<typeof setTimeout>;
|
|
8
8
|
clearTimeout(timer: ReturnType<typeof setTimeout> | undefined): void;
|
|
@@ -57,3 +57,4 @@ export declare class PromptHistoryService implements PromptHistoryPort {
|
|
|
57
57
|
onFailure(listener: (code: PromptHistoryFailure) => void): () => void;
|
|
58
58
|
close(): Promise<void>;
|
|
59
59
|
}
|
|
60
|
+
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
interface ClaimGateHandle {
|
|
2
2
|
release(): void;
|
|
3
3
|
}
|
|
4
4
|
/**
|
|
@@ -6,3 +6,4 @@ export interface ClaimGateHandle {
|
|
|
6
6
|
* file; contention returns null so the caller keeps its own bounded retry.
|
|
7
7
|
*/
|
|
8
8
|
export declare function tryAcquireClaimGate(path: string): ClaimGateHandle | null;
|
|
9
|
+
export {};
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { type AvailableRelease, type ReleaseChannel } from "./latest-release.js";
|
|
2
|
-
|
|
3
|
-
export declare const AUTOMATIC_UPDATE_RETRY_MS: number;
|
|
4
|
-
export declare const ACTIVE_RELEASE_FALLBACK_MS = 5000;
|
|
2
|
+
declare const AUTOMATIC_UPDATE_STATE_SCHEMA = 1;
|
|
5
3
|
export interface AutomaticUpdateState {
|
|
6
4
|
readonly schema: typeof AUTOMATIC_UPDATE_STATE_SCHEMA;
|
|
7
5
|
readonly channel: ReleaseChannel;
|
|
@@ -12,24 +10,16 @@ export interface AutomaticUpdateState {
|
|
|
12
10
|
readonly installedVersion: string | null;
|
|
13
11
|
readonly failure: string | null;
|
|
14
12
|
}
|
|
15
|
-
|
|
16
|
-
readonly path: string;
|
|
17
|
-
constructor(dataDir: string);
|
|
18
|
-
read(): Promise<AutomaticUpdateState | null>;
|
|
19
|
-
write(value: AutomaticUpdateState): Promise<void>;
|
|
20
|
-
}
|
|
21
|
-
export interface ActiveReleaseObservationOptions {
|
|
13
|
+
interface ActiveReleaseObservationOptions {
|
|
22
14
|
readonly runningVersion: string;
|
|
23
15
|
readonly environment?: NodeJS.ProcessEnv;
|
|
24
16
|
readonly signal?: AbortSignal;
|
|
25
17
|
readonly onNewer: (version: string) => void;
|
|
26
18
|
readonly fallbackMs?: number;
|
|
27
19
|
}
|
|
28
|
-
/** Read the approved active release only when this process executes an older release on that channel. */
|
|
29
|
-
export declare function readNewerActiveRelease(runningVersion: string, environment?: NodeJS.ProcessEnv): Promise<string | null>;
|
|
30
20
|
/** Observe local release activation promptly, with a bounded fallback for missed filesystem events. */
|
|
31
21
|
export declare function observeNewerActiveRelease(options: ActiveReleaseObservationOptions): () => void;
|
|
32
|
-
|
|
22
|
+
interface AutomaticUpdateRequestOptions {
|
|
33
23
|
readonly release: AvailableRelease;
|
|
34
24
|
readonly runningVersion: string;
|
|
35
25
|
readonly environment?: NodeJS.ProcessEnv;
|
|
@@ -37,7 +27,7 @@ export interface AutomaticUpdateRequestOptions {
|
|
|
37
27
|
readonly now?: () => number;
|
|
38
28
|
readonly spawnWorker?: (entry: string, arguments_: readonly string[], environment: NodeJS.ProcessEnv) => Promise<void>;
|
|
39
29
|
readonly sleep?: (durationMs: number) => Promise<void>;
|
|
40
|
-
/** Focused-test seams; production resolves both from the certified launch
|
|
30
|
+
/** Focused-test seams; production resolves both from the certified launch release. */
|
|
41
31
|
readonly worker?: {
|
|
42
32
|
readonly entry: string;
|
|
43
33
|
readonly packageRoot: string;
|
|
@@ -47,3 +37,4 @@ export interface AutomaticUpdateRequestOptions {
|
|
|
47
37
|
/** Start or observe one silent update and resolve with the active newer version once restart is useful. */
|
|
48
38
|
export declare function requestAutomaticUpdate(options: AutomaticUpdateRequestOptions): Promise<string | null>;
|
|
49
39
|
export declare function runAutomaticUpdateWorker(argv: readonly string[], environment?: NodeJS.ProcessEnv): Promise<number>;
|
|
40
|
+
export {};
|
|
@@ -6,21 +6,21 @@ import { basename, dirname, resolve } from "node:path";
|
|
|
6
6
|
import { valid as validSemver } from "semver";
|
|
7
7
|
import { readLaunchContext } from "../launch-context/index.js";
|
|
8
8
|
import { resolveProductPaths } from "../lifecycle/index.js";
|
|
9
|
-
import {
|
|
9
|
+
import { ReleaseStateStore } from "./release-state.js";
|
|
10
10
|
import { processIsAlive } from "./process-liveness.js";
|
|
11
11
|
import { isNewerRelease, releaseChannelOf } from "./latest-release.js";
|
|
12
12
|
import { readCertifiedReleaseManifest, resolveReleaseEntryPoint } from "./release-store.js";
|
|
13
13
|
import { acquireUpdateExecutionLease, readUpdateExecutionOwner } from "./update-execution-lease.js";
|
|
14
14
|
import { UpdateTransactionStore } from "./update-transaction.js";
|
|
15
15
|
import { runSelfUpdate, UPDATE_ALREADY_RUNNING_EXIT_CODE } from "./update.js";
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
const AUTOMATIC_UPDATE_STATE_SCHEMA = 1;
|
|
17
|
+
const AUTOMATIC_UPDATE_RETRY_MS = 24 * 60 * 60_000;
|
|
18
18
|
const AUTOMATIC_UPDATE_STATE_FILENAME = "automatic-update.json";
|
|
19
19
|
const MAX_STATE_BYTES = 16_384;
|
|
20
20
|
const OBSERVER_POLL_MS = 250;
|
|
21
21
|
const WORKER_START_GRACE_MS = 5_000;
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
const ACTIVE_RELEASE_FALLBACK_MS = 5_000;
|
|
23
|
+
class AutomaticUpdateStateStore {
|
|
24
24
|
path;
|
|
25
25
|
constructor(dataDir) { this.path = resolve(dataDir, AUTOMATIC_UPDATE_STATE_FILENAME); }
|
|
26
26
|
async read() {
|
|
@@ -65,7 +65,7 @@ export class AutomaticUpdateStateStore {
|
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
/** Read the approved active release only when this process executes an older release on that channel. */
|
|
68
|
-
|
|
68
|
+
async function readNewerActiveRelease(runningVersion, environment = process.env) {
|
|
69
69
|
const channel = releaseChannelOf(runningVersion);
|
|
70
70
|
if (channel === null)
|
|
71
71
|
return null;
|
|
@@ -83,7 +83,7 @@ export function observeNewerActiveRelease(options) {
|
|
|
83
83
|
if (releaseChannelOf(options.runningVersion) === null || options.signal?.aborted)
|
|
84
84
|
return () => { };
|
|
85
85
|
const paths = resolveProductPaths(options.environment ?? process.env);
|
|
86
|
-
const store = new
|
|
86
|
+
const store = new ReleaseStateStore(paths.dataDir);
|
|
87
87
|
let closed = false;
|
|
88
88
|
let checking = false;
|
|
89
89
|
let requested = false;
|
|
@@ -193,8 +193,8 @@ export async function requestAutomaticUpdate(options) {
|
|
|
193
193
|
let worker = options.worker;
|
|
194
194
|
if (worker === undefined) {
|
|
195
195
|
const launch = readLaunchContext(environment, "release");
|
|
196
|
-
const
|
|
197
|
-
const record = launch.releaseId === undefined ? undefined :
|
|
196
|
+
const releaseState = await new ReleaseStateStore(paths.dataDir).read();
|
|
197
|
+
const record = launch.releaseId === undefined ? undefined : releaseState.releases[launch.releaseId];
|
|
198
198
|
if (!record || record.approval !== "approved" || record.releaseRoot !== launch.releaseRoot
|
|
199
199
|
|| record.contentDigest !== launch.releaseDigest)
|
|
200
200
|
return null;
|
|
@@ -248,8 +248,8 @@ export async function runAutomaticUpdateWorker(argv, environment = process.env)
|
|
|
248
248
|
let verified = false;
|
|
249
249
|
try {
|
|
250
250
|
const launch = readLaunchContext(environment, "release");
|
|
251
|
-
const
|
|
252
|
-
const record = launch.releaseId === undefined ? undefined :
|
|
251
|
+
const releaseState = await new ReleaseStateStore(paths.dataDir).read();
|
|
252
|
+
const record = launch.releaseId === undefined ? undefined : releaseState.releases[launch.releaseId];
|
|
253
253
|
if (record?.approval === "approved" && samePath(record.releaseRoot, launch.releaseRoot ?? "")
|
|
254
254
|
&& record.contentDigest === launch.releaseDigest) {
|
|
255
255
|
const selected = await readCertifiedReleaseManifest(record, resolve(paths.dataDir, "releases"));
|
|
@@ -360,11 +360,11 @@ function activeNewerPackageVersion(active, runningVersion, channel, minimum) {
|
|
|
360
360
|
? active.packageVersion : null;
|
|
361
361
|
}
|
|
362
362
|
async function activeRelease(dataDir) {
|
|
363
|
-
const
|
|
364
|
-
const activeId =
|
|
363
|
+
const releaseState = await new ReleaseStateStore(dataDir).read();
|
|
364
|
+
const activeId = releaseState.references.active;
|
|
365
365
|
if (activeId === null)
|
|
366
366
|
return null;
|
|
367
|
-
const active =
|
|
367
|
+
const active = releaseState.releases[activeId];
|
|
368
368
|
return active?.approval === "approved" ? active : null;
|
|
369
369
|
}
|
|
370
370
|
function state(parsed, status, attemptedAt, installedVersion, failure) {
|
|
@@ -4,7 +4,7 @@ import { deliverExitNotice, restoreAfterOwnedExit } from "../terminal-cleanup/in
|
|
|
4
4
|
import { chmod, mkdir, readFile, writeFile } from "node:fs/promises";
|
|
5
5
|
import { resolve } from "node:path";
|
|
6
6
|
import { selectOrdinaryLaunchReleaseId } from "./ordinary-launch-selection.js";
|
|
7
|
-
import {
|
|
7
|
+
import { ReleaseStateStore } from "./release-state.js";
|
|
8
8
|
import { assertLaunchProfileId, resolveProductPaths, sessionSelectionArguments } from "../lifecycle/index.js";
|
|
9
9
|
import { UpdateTransactionStore } from "./update-transaction.js";
|
|
10
10
|
import { selectUpdateLaunchRelease } from "./update-launch.js";
|
|
@@ -39,7 +39,7 @@ async function runBootstrapAttempt(options, retriesRemaining) {
|
|
|
39
39
|
output.write(`${PRODUCT_TEXT.diagnostic("active release changed repeatedly during startup; launch could not converge")}\n`);
|
|
40
40
|
return 1;
|
|
41
41
|
};
|
|
42
|
-
const stateStore = new
|
|
42
|
+
const stateStore = new ReleaseStateStore(paths.dataDir);
|
|
43
43
|
let state = await stateStore.read();
|
|
44
44
|
const launchDuringUpdate = async () => {
|
|
45
45
|
// Concurrency: read the journal before touching npm's mutable tree, including package.json.
|
|
@@ -55,7 +55,7 @@ async function runBootstrapAttempt(options, retriesRemaining) {
|
|
|
55
55
|
const duringUpdate = await launchDuringUpdate();
|
|
56
56
|
if (duringUpdate !== null)
|
|
57
57
|
return duringUpdate;
|
|
58
|
-
// Performance: reconciliation is serialized by
|
|
58
|
+
// Performance: reconciliation is serialized by the release state lock, but launch never awaits a physical
|
|
59
59
|
// backlog. The scheduler commits a plan and starts a detached bounded worker.
|
|
60
60
|
const scheduleMaintenance = options.scheduleMaintenance ?? scheduleReleaseCleanup;
|
|
61
61
|
void scheduleMaintenance(paths.dataDir, paths).catch(() => { });
|
|
@@ -149,7 +149,7 @@ async function runBootstrapAttempt(options, retriesRemaining) {
|
|
|
149
149
|
return await launchSelected(candidate);
|
|
150
150
|
}
|
|
151
151
|
/**
|
|
152
|
-
* Start the retained active
|
|
152
|
+
* Start the retained active release when the installed payload cannot be taken. The
|
|
153
153
|
* release already carries certified evidence, so this reuses it rather than
|
|
154
154
|
* certifying anything new, and reports no selection when there is nothing safe
|
|
155
155
|
* to fall back to.
|
|
@@ -3,7 +3,7 @@ import { chmod, lstat, mkdir, readFile, readdir, realpath, rename, rm, writeFile
|
|
|
3
3
|
import { basename, dirname, resolve } from "node:path";
|
|
4
4
|
import { PRODUCT_IDENTITY } from "../../product-identity.js";
|
|
5
5
|
import { immutablePlatformPolicy } from "./immutable-platform.js";
|
|
6
|
-
|
|
6
|
+
const DEPENDENCY_CERTIFICATIONS_DIRECTORY = "dependency-certifications";
|
|
7
7
|
/** Derive the canonical record path without accepting path components as layer identities. */
|
|
8
8
|
export function dependencyLayerCertificationPath(dataDir, layerId) {
|
|
9
9
|
assertLayerId(layerId);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
type UiAccentColor = "blue" | "purple" | "cyan" | "green" | "orange" | "pink";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
type EarlyAccentAppearance = "dark" | "light";
|
|
3
|
+
type EarlyAccentMode = "truecolor" | "256color";
|
|
4
4
|
/** Read only global profile data, never project settings or the interactive resource pipeline. */
|
|
5
5
|
export declare function resolveEarlyAccentColor(environment?: NodeJS.ProcessEnv, home?: () => string): UiAccentColor;
|
|
6
6
|
export declare function earlyAccentPalette(color: UiAccentColor, appearance?: EarlyAccentAppearance, mode?: EarlyAccentMode): {
|
|
@@ -2,7 +2,7 @@ import { readFileSync, statSync } from "node:fs";
|
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
3
|
import { isAbsolute, join } from "node:path";
|
|
4
4
|
import { PRODUCT_IDENTITY } from "../../product-identity.js";
|
|
5
|
-
import { SHARED_PROGRESS_PALETTE } from "
|
|
5
|
+
import { SHARED_PROGRESS_PALETTE } from "../../contracts/presentation/index.js";
|
|
6
6
|
const MAX_SETTINGS_BYTES = 256 * 1024;
|
|
7
7
|
/** Read only global profile data, never project settings or the interactive resource pipeline. */
|
|
8
8
|
export function resolveEarlyAccentColor(environment = process.env, home = homedir) {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export { certifyMaterializedRelease, recordParentCertifiedRelease, releaseEnvironment, runBootstrap, } from "./bootstrap.js";
|
|
2
2
|
export type { BootstrapOptions } from "./bootstrap.js";
|
|
3
3
|
export { selectOrdinaryLaunchReleaseId } from "./ordinary-launch-selection.js";
|
|
4
|
-
export {
|
|
5
|
-
export type { ActiveReleaseTransactionReference,
|
|
4
|
+
export { ReleaseStateStore, RELEASE_STATE_SCHEMA, RELEASE_RETENTION_MS, emptyState, planProtectedReleases, withinRetention } from "./release-state.js";
|
|
5
|
+
export type { ActiveReleaseTransactionReference, ReleaseState, OrphanReleaseDisposition, ProtectedReleaseInputs, ProtectedReleasePlan, ReleaseApproval, ReleaseCleanupDiagnostic, ReleaseCleanupDisposition, ReleaseCleanupStage, ReleaseCleanupState, ReleaseCleanupWorkerRun, ReleaseCleanupWorkerStatus, ReleaseCleanupWorkerSummary, ReleaseRecord, ReleaseReferences, ReleaseRetentionReconciliation, } from "./release-state.js";
|
|
6
6
|
export { DEPENDENCY_LAYER_MANIFEST, DEPENDENCY_LAYER_SCHEMA, RUNTIME_PAYLOAD_INVENTORY, dependencyLayerCertificationPath, dependencyReference, generateDependencyRuntimePayload, legacyDependencyLayerCertificationPath, materializeDependencyLayer, readCertifiedDependencyLayer, selectDependencyRuntimePayload, selectPublishedDependencyRuntimePayload, verifyDependencyLayer, } from "./dependency-layer.js";
|
|
7
7
|
export type { DependencyLayerIdentity, DependencyLayerOperationEvent, DependencyLayerReference, GeneratedRuntimePayload, MaterializeDependencyLayerOptions, MaterializedDependencyLayer, PublishedRuntimeFileClassification, PublishedRuntimePayload, ReadCertifiedDependencyLayerOptions, RuntimePayloadExclusion, RuntimePayloadInventory, SelectedRuntimePayload, } from "./dependency-layer.js";
|
|
8
8
|
export { processIsAlive } from "./process-liveness.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { certifyMaterializedRelease, recordParentCertifiedRelease, releaseEnvironment, runBootstrap, } from "./bootstrap.js";
|
|
2
2
|
export { selectOrdinaryLaunchReleaseId } from "./ordinary-launch-selection.js";
|
|
3
|
-
export {
|
|
3
|
+
export { ReleaseStateStore, RELEASE_STATE_SCHEMA, RELEASE_RETENTION_MS, emptyState, planProtectedReleases, withinRetention } from "./release-state.js";
|
|
4
4
|
export { DEPENDENCY_LAYER_MANIFEST, DEPENDENCY_LAYER_SCHEMA, RUNTIME_PAYLOAD_INVENTORY, dependencyLayerCertificationPath, dependencyReference, generateDependencyRuntimePayload, legacyDependencyLayerCertificationPath, materializeDependencyLayer, readCertifiedDependencyLayer, selectDependencyRuntimePayload, selectPublishedDependencyRuntimePayload, verifyDependencyLayer, } from "./dependency-layer.js";
|
|
5
5
|
export { processIsAlive } from "./process-liveness.js";
|
|
6
6
|
export { PRODUCT_PACKAGE_NAME, createReleaseIdentity, deriveReleaseIdentity, digestManifestFiles, discoverReleasePayload, packageRootFromModule, releaseFileIdentity, resolveWithin, } from "./release.js";
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
/** Published release channels: stable `X.Y.Z` on dist-tag `latest`, development `X.Y.Z-dev.N` on `next`. */
|
|
2
2
|
export type ReleaseChannel = "stable" | "development";
|
|
3
|
-
export type StartupUpdateMode = "auto" | "
|
|
4
|
-
export interface DistTagVersions {
|
|
5
|
-
readonly release: string | null;
|
|
6
|
-
readonly develop: string | null;
|
|
7
|
-
readonly error: string | null;
|
|
8
|
-
}
|
|
3
|
+
export type StartupUpdateMode = "auto" | "manual";
|
|
9
4
|
export type RegistryFetcher = (url: string) => Promise<{
|
|
10
5
|
readonly ok: boolean;
|
|
11
6
|
readonly status: number;
|
|
@@ -19,14 +14,13 @@ export interface AvailableRelease {
|
|
|
19
14
|
/** The GitHub Release page; development releases have none. */
|
|
20
15
|
readonly changelogUrl: string | null;
|
|
21
16
|
}
|
|
22
|
-
export declare const DEFAULT_NPM_REGISTRY = "https://registry.npmjs.org";
|
|
23
17
|
export declare const UPDATE_CHECK_INTERVAL_MS: number;
|
|
24
18
|
/** One published version with the pull request its manifest records, when it records one. */
|
|
25
19
|
export interface PublishedVersion {
|
|
26
20
|
readonly version: string;
|
|
27
21
|
readonly pullRequest: number | null;
|
|
28
22
|
}
|
|
29
|
-
|
|
23
|
+
interface PublishedVersions {
|
|
30
24
|
readonly versions: readonly PublishedVersion[];
|
|
31
25
|
readonly error: string | null;
|
|
32
26
|
}
|
|
@@ -37,23 +31,14 @@ export interface PublishedVersions {
|
|
|
37
31
|
export declare function releaseChannelOf(version: string): ReleaseChannel | null;
|
|
38
32
|
/** True only when both versions are valid semver and the candidate sorts strictly above the current one. */
|
|
39
33
|
export declare function isNewerRelease(candidate: string, current: string): boolean;
|
|
40
|
-
export declare function distTagsUrl(registry?: string): string;
|
|
41
|
-
/** Read `latest` (required) and `next` (optional) from a dist-tags object. */
|
|
42
|
-
export declare function parseDistTags(metadata: unknown, source: string): DistTagVersions;
|
|
43
|
-
export declare function queryRegistryDistTags(fetcher: RegistryFetcher, registry?: string): Promise<DistTagVersions>;
|
|
44
|
-
export declare function packageDocumentUrl(registry?: string): string;
|
|
45
|
-
/** The pull request a published or installed manifest records under `publication.pullRequest`, when valid. */
|
|
46
|
-
export declare function recordedPullRequest(manifest: unknown): number | null;
|
|
47
34
|
/**
|
|
48
35
|
* Every published version with its recorded pull request, read from the registry's full package
|
|
49
36
|
* document: its per-version manifests keep the publication metadata that version lists and the
|
|
50
37
|
* abbreviated install document leave out.
|
|
51
38
|
*/
|
|
52
39
|
export declare function queryPublishedVersions(fetcher: RegistryFetcher, registry?: string): Promise<PublishedVersions>;
|
|
53
|
-
export declare function parsePublishedVersions(document: unknown): PublishedVersions;
|
|
54
40
|
/** Forget the startup release check so the next interactive launch asks the registry again. */
|
|
55
41
|
export declare function invalidateReleaseCheckCache(configDir: string): Promise<void>;
|
|
56
|
-
export declare function unavailableDistTags(error: string): DistTagVersions;
|
|
57
42
|
export declare function createRegistryFetcher(timeoutMs: number, signal?: AbortSignal): RegistryFetcher;
|
|
58
43
|
export interface StartupReleaseCheckOptions {
|
|
59
44
|
readonly runningVersion: string;
|
|
@@ -77,4 +62,4 @@ export declare function startupReleaseCheckSkipReason(options: StartupReleaseChe
|
|
|
77
62
|
* answer replaces the cache. Every failure resolves to null: the notice is best-effort.
|
|
78
63
|
*/
|
|
79
64
|
export declare function checkForNewerRelease(options: StartupReleaseCheckOptions): Promise<AvailableRelease | null>;
|
|
80
|
-
export
|
|
65
|
+
export {};
|
|
@@ -4,7 +4,7 @@ import { join } from "node:path";
|
|
|
4
4
|
import { gt, prerelease, valid as validSemver } from "semver";
|
|
5
5
|
import lockfile from "proper-lockfile";
|
|
6
6
|
import { PRODUCT_IDENTITY, PRODUCT_TEXT } from "../../product-identity.js";
|
|
7
|
-
|
|
7
|
+
const DEFAULT_NPM_REGISTRY = "https://registry.npmjs.org";
|
|
8
8
|
export const UPDATE_CHECK_INTERVAL_MS = 15 * 60_000;
|
|
9
9
|
const STARTUP_FETCH_TIMEOUT_MS = 3_000;
|
|
10
10
|
const CACHE_FILENAME = "update-check.json";
|
|
@@ -30,11 +30,11 @@ export function isNewerRelease(candidate, current) {
|
|
|
30
30
|
const right = validSemver(current);
|
|
31
31
|
return left !== null && right !== null && gt(left, right);
|
|
32
32
|
}
|
|
33
|
-
|
|
33
|
+
function distTagsUrl(registry = DEFAULT_NPM_REGISTRY) {
|
|
34
34
|
return `${registry.replace(/\/+$/u, "")}/-/package/${encodeURIComponent(PRODUCT_TEXT.packageName)}/dist-tags`;
|
|
35
35
|
}
|
|
36
36
|
/** Read `latest` (required) and `next` (optional) from a dist-tags object. */
|
|
37
|
-
|
|
37
|
+
function parseDistTags(metadata, source) {
|
|
38
38
|
if (typeof metadata !== "object" || metadata === null || Array.isArray(metadata)) {
|
|
39
39
|
return unavailableDistTags(`${source} returned a non-object dist-tags value`);
|
|
40
40
|
}
|
|
@@ -48,7 +48,7 @@ export function parseDistTags(metadata, source) {
|
|
|
48
48
|
return unavailableDistTags(errorMessage(error));
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
-
|
|
51
|
+
async function queryRegistryDistTags(fetcher, registry) {
|
|
52
52
|
try {
|
|
53
53
|
const response = await fetcher(distTagsUrl(registry));
|
|
54
54
|
if (!response.ok)
|
|
@@ -59,11 +59,11 @@ export async function queryRegistryDistTags(fetcher, registry) {
|
|
|
59
59
|
return unavailableDistTags(errorMessage(error));
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
|
-
|
|
62
|
+
function packageDocumentUrl(registry = DEFAULT_NPM_REGISTRY) {
|
|
63
63
|
return `${registry.replace(/\/+$/u, "")}/${encodeURIComponent(PRODUCT_TEXT.packageName)}`;
|
|
64
64
|
}
|
|
65
65
|
/** The pull request a published or installed manifest records under `publication.pullRequest`, when valid. */
|
|
66
|
-
|
|
66
|
+
function recordedPullRequest(manifest) {
|
|
67
67
|
if (typeof manifest !== "object" || manifest === null)
|
|
68
68
|
return null;
|
|
69
69
|
const publication = manifest.publication;
|
|
@@ -91,7 +91,7 @@ export async function queryPublishedVersions(fetcher, registry) {
|
|
|
91
91
|
return { versions: [], error: errorMessage(error) };
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
|
-
|
|
94
|
+
function parsePublishedVersions(document) {
|
|
95
95
|
if (typeof document !== "object" || document === null || Array.isArray(document)) {
|
|
96
96
|
return { versions: [], error: "registry returned a non-object package document" };
|
|
97
97
|
}
|
|
@@ -108,7 +108,7 @@ export function parsePublishedVersions(document) {
|
|
|
108
108
|
export async function invalidateReleaseCheckCache(configDir) {
|
|
109
109
|
await withCacheLock(configDir, async () => { await rm(join(configDir, CACHE_FILENAME), { force: true }); });
|
|
110
110
|
}
|
|
111
|
-
|
|
111
|
+
function unavailableDistTags(error) {
|
|
112
112
|
return { release: null, develop: null, error };
|
|
113
113
|
}
|
|
114
114
|
export function createRegistryFetcher(timeoutMs, signal) {
|
|
@@ -126,7 +126,7 @@ export function startupReleaseCheckSkipReason(options) {
|
|
|
126
126
|
return "ci";
|
|
127
127
|
if (!options.interactive)
|
|
128
128
|
return "not-interactive";
|
|
129
|
-
if (options.settingMode === "
|
|
129
|
+
if (options.settingMode === "manual")
|
|
130
130
|
return "disabled-by-setting";
|
|
131
131
|
if (releaseChannelOf(options.runningVersion) === null)
|
|
132
132
|
return "unpublished-version";
|
|
@@ -170,7 +170,7 @@ export async function checkForNewerRelease(options) {
|
|
|
170
170
|
return null;
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
|
-
|
|
173
|
+
function availableRelease(channel, version) {
|
|
174
174
|
return {
|
|
175
175
|
channel,
|
|
176
176
|
version,
|
|
@@ -8,7 +8,7 @@ interface ApprovedOrdinaryLaunchRelease extends OrdinaryLaunchRelease {
|
|
|
8
8
|
/**
|
|
9
9
|
* Ordinary launch has no rollback authority: it may advance to its installed package, but an
|
|
10
10
|
* older package installation must follow a newer approved active release instead of moving the
|
|
11
|
-
* shared selector backward. Explicit update/rollback uses
|
|
11
|
+
* shared selector backward. Explicit update/rollback uses ReleaseStateStore.activate directly.
|
|
12
12
|
*/
|
|
13
13
|
export declare function selectOrdinaryLaunchReleaseId(candidate: OrdinaryLaunchRelease, active?: ApprovedOrdinaryLaunchRelease): string;
|
|
14
14
|
export {};
|
|
@@ -2,7 +2,7 @@ import { compare, valid as validSemver } from "semver";
|
|
|
2
2
|
/**
|
|
3
3
|
* Ordinary launch has no rollback authority: it may advance to its installed package, but an
|
|
4
4
|
* older package installation must follow a newer approved active release instead of moving the
|
|
5
|
-
* shared selector backward. Explicit update/rollback uses
|
|
5
|
+
* shared selector backward. Explicit update/rollback uses ReleaseStateStore.activate directly.
|
|
6
6
|
*/
|
|
7
7
|
export function selectOrdinaryLaunchReleaseId(candidate, active) {
|
|
8
8
|
if (!active || active.approval !== "approved")
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { rename, rm } from "node:fs/promises";
|
|
2
|
-
import {
|
|
2
|
+
import { ReleaseStateStore, type OrphanReleaseDisposition } from "./release-state.js";
|
|
3
3
|
import type { ProductPaths } from "../lifecycle/index.js";
|
|
4
4
|
import { UpdateTransactionStore } from "./update-transaction.js";
|
|
5
5
|
export interface ReleaseCleanupLimits {
|
|
@@ -58,11 +58,11 @@ interface DiscoveredCleanupInputs {
|
|
|
58
58
|
}[];
|
|
59
59
|
}
|
|
60
60
|
/**
|
|
61
|
-
* Reconcile age-based retention under the
|
|
61
|
+
* Reconcile age-based retention under the release-state lock and durably detach obsolete releases.
|
|
62
62
|
* This operation intentionally reads only manifests and directory metadata, never payload bytes.
|
|
63
63
|
*/
|
|
64
64
|
export declare function prepareReleaseCleanup(dataDir: string, _paths?: ProductPaths, options?: ReleaseCleanupOptions): Promise<{
|
|
65
|
-
readonly store:
|
|
65
|
+
readonly store: ReleaseStateStore;
|
|
66
66
|
readonly discovered: DiscoveredCleanupInputs;
|
|
67
67
|
}>;
|
|
68
68
|
/** Run a bounded, restart-safe physical cleanup pass over detached releases and abandoned artifacts. */
|
|
@@ -3,7 +3,7 @@ import { spawn } from "node:child_process";
|
|
|
3
3
|
import { lstat, mkdir, open, readFile, readdir, realpath, rename, rm, stat } from "node:fs/promises";
|
|
4
4
|
import { dirname, isAbsolute, relative, resolve, sep } from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
|
-
import {
|
|
6
|
+
import { ReleaseStateStore, } from "./release-state.js";
|
|
7
7
|
import { resolveProductPaths } from "../lifecycle/index.js";
|
|
8
8
|
import { RELEASE_MANIFEST_FILENAME } from "./release-store.js";
|
|
9
9
|
import { DEPENDENCY_LAYER_MANIFEST, readCertifiedDependencyLayer } from "./dependency-layer.js";
|
|
@@ -24,11 +24,11 @@ const WORKER_KEEP_ENV = "RELEASE_CLEANUP_KEEP";
|
|
|
24
24
|
const WORKER_RUN_ID_ENV = "RELEASE_CLEANUP_RUN_ID";
|
|
25
25
|
const WORKER_LEASE_FILENAME = "release-cleanup-worker.lock";
|
|
26
26
|
/**
|
|
27
|
-
* Reconcile age-based retention under the
|
|
27
|
+
* Reconcile age-based retention under the release-state lock and durably detach obsolete releases.
|
|
28
28
|
* This operation intentionally reads only manifests and directory metadata, never payload bytes.
|
|
29
29
|
*/
|
|
30
30
|
export async function prepareReleaseCleanup(dataDir, _paths, options = {}) {
|
|
31
|
-
const store = new
|
|
31
|
+
const store = new ReleaseStateStore(dataDir);
|
|
32
32
|
const discovered = await discoverCleanupInputs(dataDir, store, options);
|
|
33
33
|
const transactionStore = options.transactionStore ?? new UpdateTransactionStore(dataDir);
|
|
34
34
|
await store.reconcileRetention(async () => await protectionInputs(transactionStore, options), discovered.orphans);
|
|
@@ -152,7 +152,7 @@ export async function scheduleReleaseCleanup(dataDir, paths, options = {}) {
|
|
|
152
152
|
/** Entry used by the private cleanup executable shipped in every immutable release. */
|
|
153
153
|
export async function runReleaseCleanupWorker(environment = process.env, workerOptions = {}) {
|
|
154
154
|
const paths = resolveProductPaths(environment);
|
|
155
|
-
const store = new
|
|
155
|
+
const store = new ReleaseStateStore(paths.dataDir);
|
|
156
156
|
const runId = environment[WORKER_RUN_ID_ENV] ?? randomUUID();
|
|
157
157
|
const now = workerOptions.now ?? Date.now;
|
|
158
158
|
const sleep = workerOptions.sleep ?? (async (durationMs) => await new Promise(resolvePromise => setTimeout(resolvePromise, durationMs)));
|