@timurproko/a1 0.1.8-dev.299 → 0.1.8-dev.332
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 +16 -4
- package/bin/guardian.js +4 -3
- package/bin/ui.js +4 -2
- package/bin/update-recovery.js +3 -1
- package/dist/cli/dispatch.js +1 -1
- package/dist/composition/owned-ui.js +2 -1
- package/dist/features/launch/profile-paths.d.ts +2 -0
- package/dist/features/launch/profile-paths.js +11 -0
- package/dist/features/owned-ui/project-trust-prompt.js +1 -1
- package/dist/features/owned-ui/settings-app.js +1 -1
- package/dist/features/prompt-history/service.d.ts +31 -1
- package/dist/features/prompt-history/service.js +294 -129
- package/dist/features/prompt-history/store.d.ts +2 -1
- package/dist/features/prompt-history/store.js +17 -4
- package/dist/features/prompt-history/worker.js +6 -3
- package/dist/foundation/launch-context/index.d.ts +59 -0
- package/dist/foundation/launch-context/index.js +136 -0
- package/dist/foundation/launch-guardian/main.js +6 -4
- package/dist/foundation/release/bootstrap.d.ts +6 -1
- package/dist/foundation/release/bootstrap.js +59 -13
- package/dist/foundation/release/cohort-state.d.ts +1 -0
- package/dist/foundation/release/cohort-state.js +1 -0
- package/dist/foundation/release/dependency-certification-retention.d.ts +7 -0
- package/dist/foundation/release/dependency-certification-retention.js +88 -0
- package/dist/foundation/release/dependency-certification.d.ts +24 -0
- package/dist/foundation/release/dependency-certification.js +208 -0
- package/dist/foundation/release/dependency-layer.d.ts +3 -4
- package/dist/foundation/release/dependency-layer.js +6 -37
- package/dist/foundation/release/release-gc.js +74 -46
- package/dist/foundation/release/release-store.d.ts +2 -0
- package/dist/foundation/release/release-store.js +11 -3
- package/dist/foundation/release/release.d.ts +3 -1
- package/dist/foundation/release/release.js +7 -3
- package/dist/foundation/release/restart-certification.d.ts +1 -0
- package/dist/foundation/release/restart-certification.js +17 -1
- package/dist/foundation/release/update-recovery.d.ts +2 -0
- package/dist/foundation/release/update-recovery.js +4 -0
- package/dist/foundation/release/update.js +1 -1
- package/dist/foundation/release/warmup.d.ts +1 -1
- package/dist/foundation/release/warmup.js +18 -6
- package/dist/foundation/startup/startup-runtime.js +13 -11
- package/dist/foundation/supervision/main.js +8 -7
- package/dist/integrations/pi/components/owned-editor-ux.d.ts +2 -1
- package/dist/integrations/pi/components/owned-editor-ux.js +105 -30
- package/dist/integrations/pi/components/shell-editor-autocomplete.js +3 -0
- package/dist/integrations/pi/components/shell-presenters-info.d.ts +9 -2
- package/dist/integrations/pi/components/shell-presenters-info.js +35 -4
- package/dist/integrations/pi/components/shell-selectors-dialogs.d.ts +3 -2
- package/dist/integrations/pi/components/shell-selectors-dialogs.js +8 -5
- package/dist/integrations/pi/components/shell-shared-facade.d.ts +9 -2
- package/dist/integrations/pi/components/upstream/assets/earendil-image.json +12 -0
- package/dist/integrations/pi/components/upstream/components/earendil-announcement.js +25 -2
- package/dist/integrations/pi/engine/adapter.d.ts +33 -1
- package/dist/integrations/pi/engine/adapter.js +309 -112
- package/dist/integrations/pi/engine/changelog.d.ts +2 -0
- package/dist/integrations/pi/engine/changelog.js +63 -0
- package/dist/integrations/pi/engine/pending-delivery.d.ts +26 -0
- package/dist/integrations/pi/engine/pending-delivery.js +149 -0
- package/dist/integrations/pi/engine/resources/changelog.json +12 -0
- package/dist/integrations/pi/engine/workflow-controllers.d.ts +1 -1
- package/dist/integrations/pi/engine/workflows.d.ts +1 -1
- package/dist/integrations/pi/session-ui/prompt-chips.d.ts +3 -1
- package/dist/integrations/pi/session-ui/prompt-chips.js +74 -37
- package/dist/integrations/pi/session-ui/prompt-history-controller.d.ts +0 -2
- package/dist/integrations/pi/session-ui/prompt-history-controller.js +3 -8
- package/dist/integrations/pi/session-ui/session-shell-root.d.ts +26 -1
- package/dist/integrations/pi/session-ui/session-shell-root.js +70 -75
- package/dist/integrations/pi/session-ui/session-shell.d.ts +1 -1
- package/dist/integrations/pi/session-ui/session-shell.js +67 -13
- package/dist/integrations/pi/session-ui/session-viewport-controller.d.ts +7 -2
- package/dist/integrations/pi/session-ui/session-viewport-controller.js +25 -20
- package/dist/integrations/pi/session-ui/text-paste.d.ts +5 -0
- package/dist/integrations/pi/session-ui/text-paste.js +16 -0
- package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +9 -2
- package/dist/integrations/pi/tui-runtime/damage-aware-terminal.js +87 -43
- package/dist/native/darwin-arm64/manifest.json +1 -1
- package/dist/native/linux-x64/manifest.json +1 -1
- package/dist/native/win32-x64/manifest.json +2 -2
- package/dist/native/win32-x64/process-guardian.exe +0 -0
- package/dist/product-identity.d.ts +1 -1
- package/dist/product-identity.js +2 -35
- package/dist/product-identity.json +1 -23
- package/dist/ui/components/transcript-viewport.d.ts +8 -0
- package/dist/ui/components/transcript-viewport.js +23 -2
- package/dist/ui/components/visible-hyperlinks.d.ts +7 -0
- package/dist/ui/components/visible-hyperlinks.js +1 -0
- package/dist/ui/settings/declarations.js +1 -0
- package/dist/ui/settings/sections.js +11 -1
- package/docs/architecture/boundaries.md +2 -1
- package/docs/architecture/internal-naming.md +91 -0
- package/docs/architecture/resource-and-data-policy.md +9 -4
- package/docs/architecture/toolchain.md +15 -1
- package/docs/features/prompt-history.md +39 -11
- package/docs/manual-code-streaming-cleanup.md +88 -0
- package/package.json +8 -3
package/dist/product-identity.js
CHANGED
|
@@ -1,40 +1,7 @@
|
|
|
1
1
|
import rawIdentity from "./product-identity.json" with { type: "json" };
|
|
2
2
|
const ENVIRONMENT_KEYS = [
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"dataDir",
|
|
6
|
-
"databasePath",
|
|
7
|
-
"developmentInstanceId",
|
|
8
|
-
"developmentRoot",
|
|
9
|
-
"endpoint",
|
|
10
|
-
"fixture",
|
|
11
|
-
"fixtureInput",
|
|
12
|
-
"fixtureToken",
|
|
13
|
-
"inputAcknowledgement",
|
|
14
|
-
"immutableWarmup",
|
|
15
|
-
"internalPackaging",
|
|
16
|
-
"launchProfile",
|
|
17
|
-
"nativePi",
|
|
18
|
-
"paneId",
|
|
19
|
-
"piParityIntentionalMutation",
|
|
20
|
-
"piPortRoot",
|
|
21
|
-
"piSourceLedgerPath",
|
|
22
|
-
"piSourceScanRoot",
|
|
23
|
-
"probeTrace",
|
|
24
|
-
"processGuardianPath",
|
|
25
|
-
"profileHome",
|
|
26
|
-
"protocolVersion",
|
|
27
|
-
"releaseDigest",
|
|
28
|
-
"releaseId",
|
|
29
|
-
"releaseLayers",
|
|
30
|
-
"releaseRoot",
|
|
31
|
-
"releaseRunnerLabel",
|
|
32
|
-
"runtimeDir",
|
|
33
|
-
"structuredFlowLimits",
|
|
34
|
-
"startupTrace",
|
|
35
|
-
"terminalArgumentsJson",
|
|
36
|
-
"terminalExecutable",
|
|
37
|
-
"terminalSessionId",
|
|
3
|
+
"configDir", "dataDir", "databasePath", "developmentInstanceId", "developmentRoot", "endpoint",
|
|
4
|
+
"paneId", "probeTrace", "processGuardianPath", "profileHome", "runtimeDir", "startupTrace", "terminalSessionId",
|
|
38
5
|
];
|
|
39
6
|
const FILESYSTEM_KEYS = ["slug", "windowsDirectory", "unixDirectory", "temporaryPrefix"];
|
|
40
7
|
const STATE_KEYS = ["windowsControlDirectory", "unixControlDirectory", "developmentDirectory", "piAgentProfile", "piVanillaProfile"];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "a1-product-identity-v1",
|
|
3
|
-
"displayName": "
|
|
3
|
+
"displayName": "a1",
|
|
4
4
|
"commandName": "a1",
|
|
5
5
|
"packageName": "@timurproko/a1",
|
|
6
6
|
"filesystem": {
|
|
@@ -10,40 +10,18 @@
|
|
|
10
10
|
"temporaryPrefix": "a1-"
|
|
11
11
|
},
|
|
12
12
|
"environment": {
|
|
13
|
-
"certificationTarball": "A1_CERTIFICATION_TARBALL",
|
|
14
13
|
"configDir": "A1_CONFIG_DIR",
|
|
15
14
|
"dataDir": "A1_DATA_DIR",
|
|
16
15
|
"databasePath": "A1_DATABASE_PATH",
|
|
17
16
|
"developmentInstanceId": "A1_DEV_INSTANCE_ID",
|
|
18
17
|
"developmentRoot": "A1_DEV_ROOT",
|
|
19
18
|
"endpoint": "A1_ENDPOINT",
|
|
20
|
-
"fixture": "A1_FIXTURE",
|
|
21
|
-
"fixtureInput": "A1_FIXTURE_INPUT",
|
|
22
|
-
"fixtureToken": "A1_FIXTURE_TOKEN",
|
|
23
|
-
"inputAcknowledgement": "A1_INPUT_ACK",
|
|
24
|
-
"immutableWarmup": "A1_IMMUTABLE_WARMUP",
|
|
25
|
-
"internalPackaging": "A1_INTERNAL_PACKAGING",
|
|
26
|
-
"launchProfile": "A1_LAUNCH_PROFILE",
|
|
27
|
-
"nativePi": "A1_NATIVE_PI",
|
|
28
19
|
"paneId": "A1_PANE_ID",
|
|
29
|
-
"piParityIntentionalMutation": "A1_PI_PARITY_INTENTIONAL_MUTATION",
|
|
30
|
-
"piPortRoot": "A1_PI_PORT_ROOT",
|
|
31
|
-
"piSourceLedgerPath": "A1_PI_SOURCE_LEDGER_PATH",
|
|
32
|
-
"piSourceScanRoot": "A1_PI_SOURCE_SCAN_ROOT",
|
|
33
20
|
"probeTrace": "A1_PROBE_TRACE",
|
|
34
21
|
"processGuardianPath": "A1_PROCESS_GUARDIAN_PATH",
|
|
35
22
|
"profileHome": "A1_PROFILE_HOME",
|
|
36
|
-
"protocolVersion": "A1_PROTOCOL_VERSION",
|
|
37
|
-
"releaseDigest": "A1_RELEASE_DIGEST",
|
|
38
|
-
"releaseId": "A1_RELEASE_ID",
|
|
39
|
-
"releaseLayers": "A1_RELEASE_LAYERS",
|
|
40
|
-
"releaseRoot": "A1_RELEASE_ROOT",
|
|
41
|
-
"releaseRunnerLabel": "A1_RELEASE_RUNNER_LABEL",
|
|
42
23
|
"runtimeDir": "A1_RUNTIME_DIR",
|
|
43
|
-
"structuredFlowLimits": "A1_STRUCTURED_FLOW_LIMITS",
|
|
44
24
|
"startupTrace": "A1_STARTUP_TRACE",
|
|
45
|
-
"terminalArgumentsJson": "A1_TERMINAL_ARGUMENTS_JSON",
|
|
46
|
-
"terminalExecutable": "A1_TERMINAL_EXECUTABLE",
|
|
47
25
|
"terminalSessionId": "A1_TERMINAL_SESSION_ID"
|
|
48
26
|
},
|
|
49
27
|
"state": {
|
|
@@ -24,6 +24,12 @@ export interface TranscriptViewportFrameInput {
|
|
|
24
24
|
readonly paintDocumentRow?: (row: string) => string;
|
|
25
25
|
/** Leading document rows that participate in pointer selection and copying. */
|
|
26
26
|
readonly selectableDocumentRowCount?: number;
|
|
27
|
+
/**
|
|
28
|
+
* First document row owned by the block that is currently streaming, if any. Rows from
|
|
29
|
+
* here to the end of the selectable document reflow together whenever that block
|
|
30
|
+
* re-renders, so the frame can declare how much damage is legitimately its own.
|
|
31
|
+
*/
|
|
32
|
+
readonly liveTailStartRow?: number;
|
|
27
33
|
/** Final transient rows to bottom-align with unused viewport space while content fits. */
|
|
28
34
|
readonly bottomAlignedTailRowCount?: number;
|
|
29
35
|
readonly dockRows: readonly string[];
|
|
@@ -94,6 +100,8 @@ export interface TranscriptViewportFrameDescriptor {
|
|
|
94
100
|
readonly transientAlignmentGapRows: number;
|
|
95
101
|
/** Live status rows at the end of the transient suffix. */
|
|
96
102
|
readonly bottomAlignedTailRowCount: number;
|
|
103
|
+
/** Visible rows owned by the currently streaming transcript block. */
|
|
104
|
+
readonly liveTailRows: number;
|
|
97
105
|
readonly verticalShiftRows: number;
|
|
98
106
|
readonly safeVerticalShift: boolean;
|
|
99
107
|
/** Monotonic interaction revision used to reject stale selection evidence. */
|
|
@@ -358,9 +358,9 @@ export class TranscriptViewport {
|
|
|
358
358
|
const frameRows = [...visible, ...dock].slice(0, height);
|
|
359
359
|
let bottomHit = null;
|
|
360
360
|
if (this.#maxScroll > 0 && !this.#followingEnd && frameRows.length > 0) {
|
|
361
|
-
const genericLabel = " Jump to bottom (End) ";
|
|
361
|
+
const genericLabel = " Jump to bottom (Ctrl+End) ↓ ";
|
|
362
362
|
const countedLabel = this.#newMessages > 0
|
|
363
|
-
? ` ${this.#newMessages} new message${this.#newMessages === 1 ? "" : "s"} (End) `
|
|
363
|
+
? ` ${this.#newMessages} new message${this.#newMessages === 1 ? "" : "s"} (Ctrl+End) ↓ `
|
|
364
364
|
: genericLabel;
|
|
365
365
|
const label = displayWidth(countedLabel) <= contentWidth ? countedLabel : genericLabel;
|
|
366
366
|
const labelWidth = displayWidth(label);
|
|
@@ -406,6 +406,7 @@ export class TranscriptViewport {
|
|
|
406
406
|
transientRowCount: Math.max(0, documentRows.length - this.#selectableDocumentRowCount),
|
|
407
407
|
transientAlignmentGapRows,
|
|
408
408
|
bottomAlignedTailRowCount,
|
|
409
|
+
liveTailRows: visibleLiveTailRows(input.liveTailStartRow, this.#selectableDocumentRowCount, this.#scrollTop, viewportHeight),
|
|
409
410
|
verticalShiftRows,
|
|
410
411
|
safeVerticalShift,
|
|
411
412
|
selectionRevision: composingSelectionRevision,
|
|
@@ -480,6 +481,7 @@ export class TranscriptViewport {
|
|
|
480
481
|
transientRowCount: previous.descriptor.transientRowCount,
|
|
481
482
|
transientAlignmentGapRows: previous.descriptor.transientAlignmentGapRows,
|
|
482
483
|
bottomAlignedTailRowCount: previous.descriptor.bottomAlignedTailRowCount,
|
|
484
|
+
liveTailRows: previous.descriptor.liveTailRows,
|
|
483
485
|
verticalShiftRows: 0,
|
|
484
486
|
safeVerticalShift: false,
|
|
485
487
|
selectionRevision: this.#selectionRevision,
|
|
@@ -568,6 +570,18 @@ function trimCache(cache, limit) {
|
|
|
568
570
|
while (cache.size > limit)
|
|
569
571
|
cache.delete(cache.keys().next().value);
|
|
570
572
|
}
|
|
573
|
+
/**
|
|
574
|
+
* Rows of the streaming block that the visible window actually shows. Gap insertion happens
|
|
575
|
+
* after the selectable document, so live-block indices need no adjustment here.
|
|
576
|
+
*/
|
|
577
|
+
function visibleLiveTailRows(liveTailStartRow, selectableDocumentRowCount, scrollTop, viewportHeight) {
|
|
578
|
+
if (liveTailStartRow === undefined || !Number.isSafeInteger(liveTailStartRow))
|
|
579
|
+
return 0;
|
|
580
|
+
const start = clamp(liveTailStartRow, 0, selectableDocumentRowCount);
|
|
581
|
+
const visibleStart = Math.max(start, scrollTop);
|
|
582
|
+
const visibleEnd = Math.min(selectableDocumentRowCount, scrollTop + viewportHeight);
|
|
583
|
+
return Math.max(0, visibleEnd - visibleStart);
|
|
584
|
+
}
|
|
571
585
|
function governingPrompt(anchors, scrollTop) {
|
|
572
586
|
let result = null;
|
|
573
587
|
for (const anchor of anchors) {
|
|
@@ -611,6 +625,13 @@ export function assertTranscriptViewportFrameDescriptor(descriptor) {
|
|
|
611
625
|
|| descriptor.transientAlignmentGapRows + descriptor.bottomAlignedTailRowCount > descriptor.transientRowCount) {
|
|
612
626
|
throw new TypeError("viewport frame descriptor transient geometry is invalid");
|
|
613
627
|
}
|
|
628
|
+
const transcriptHeight = descriptor.transcript === null
|
|
629
|
+
? 0
|
|
630
|
+
: descriptor.transcript.rowEnd - descriptor.transcript.rowStart + 1;
|
|
631
|
+
if (!Number.isSafeInteger(descriptor.liveTailRows) || descriptor.liveTailRows < 0
|
|
632
|
+
|| descriptor.liveTailRows > transcriptHeight) {
|
|
633
|
+
throw new TypeError("viewport frame descriptor live tail is invalid");
|
|
634
|
+
}
|
|
614
635
|
if (!Number.isSafeInteger(descriptor.verticalShiftRows))
|
|
615
636
|
throw new TypeError("viewport frame descriptor shift is invalid");
|
|
616
637
|
if (descriptor.previousDocumentRange === null && descriptor.verticalShiftRows !== 0) {
|
|
@@ -6,6 +6,13 @@ export interface VisibleHyperlinkRange {
|
|
|
6
6
|
}
|
|
7
7
|
export interface VisibleHyperlinkRow {
|
|
8
8
|
readonly ranges: readonly VisibleHyperlinkRange[];
|
|
9
|
+
/**
|
|
10
|
+
* Whether the row declares a terminal hyperlink of its own. Only a declared link gives the
|
|
11
|
+
* terminal per-cell link identity that moving the row can misattribute, so movement safety
|
|
12
|
+
* asks this rather than counting ranges: a candidate range is host-hover text such as
|
|
13
|
+
* `obj.method` or `./src/index.ts`, which ordinary code produces on nearly every row.
|
|
14
|
+
*/
|
|
15
|
+
readonly hasExplicitLink: boolean;
|
|
9
16
|
/** False for unclosed links, malformed escapes, images, or row-moving controls. */
|
|
10
17
|
readonly replaySafe: boolean;
|
|
11
18
|
readonly width: number;
|
|
@@ -55,6 +55,7 @@ export function readVisibleHyperlinks(line, widthOf = displayWidth) {
|
|
|
55
55
|
ranges.sort((left, right) => left.from - right.from);
|
|
56
56
|
return {
|
|
57
57
|
ranges,
|
|
58
|
+
hasExplicitLink: ranges.some(range => range.kind === "explicit"),
|
|
58
59
|
replaySafe,
|
|
59
60
|
width: column,
|
|
60
61
|
// Rationale: a path with spaces or a wrapped host match may extend beyond
|
|
@@ -51,6 +51,7 @@ export const OWNED_UI_SETTING_DECLARATIONS = Object.freeze([
|
|
|
51
51
|
Object.freeze({
|
|
52
52
|
id: "promptSuggestions",
|
|
53
53
|
label: "Prompt suggestions",
|
|
54
|
+
section: Object.freeze({ id: "agent", title: "Agent" }),
|
|
54
55
|
description: "Predict likely next prompts with one additional background request using the selected model.",
|
|
55
56
|
application: "live",
|
|
56
57
|
defaultValue: true,
|
|
@@ -25,6 +25,8 @@ export function buildOwnedUiSettingsSections(input) {
|
|
|
25
25
|
});
|
|
26
26
|
grouped.set(section.id, group);
|
|
27
27
|
}
|
|
28
|
+
const ownedAgentEntries = grouped.get(AGENT_SECTION_ID)?.entries ?? [];
|
|
29
|
+
grouped.delete(AGENT_SECTION_ID);
|
|
28
30
|
const ownedSections = [...grouped].map(([id, group]) => ({
|
|
29
31
|
id,
|
|
30
32
|
title: group.title,
|
|
@@ -32,7 +34,15 @@ export function buildOwnedUiSettingsSections(input) {
|
|
|
32
34
|
unavailableReason: null,
|
|
33
35
|
readOnlyReason: null,
|
|
34
36
|
}));
|
|
35
|
-
|
|
37
|
+
const agent = agentSection(input.agent);
|
|
38
|
+
// Invariant: presentation grouping does not transfer ownership or engine availability to owned entries.
|
|
39
|
+
const combinedAgent = ownedAgentEntries.length === 0 ? agent : {
|
|
40
|
+
...agent,
|
|
41
|
+
entries: Object.freeze([...agent.entries, ...ownedAgentEntries]),
|
|
42
|
+
unavailableReason: null,
|
|
43
|
+
readOnlyReason: null,
|
|
44
|
+
};
|
|
45
|
+
return Object.freeze([...ownedSections, combinedAgent]);
|
|
36
46
|
}
|
|
37
47
|
export function findOwnedUiSettingsEntry(sections, id, backend) {
|
|
38
48
|
for (const section of sections) {
|
|
@@ -28,7 +28,8 @@ The owned Pi-backed surface is not an arbitrary-CLI terminal multiplexer. A feat
|
|
|
28
28
|
- `structured-agent-runtime`: planned typed event/command/snapshot runtime. It must not infer semantics from terminal text, own pseudoterminals, or reconstruct screens.
|
|
29
29
|
- `native-host-protocol`: bounded typed local boundary for terminal-host identity, topology revisions, lifecycle, and recovery. Terminal bytes, per-event child input, and rendered cells are forbidden across it.
|
|
30
30
|
- `protocol`: additive control handshake, bounded line framing, authenticated launch-instance commands, typed stop intent, snapshots, and command results.
|
|
31
|
-
- `
|
|
31
|
+
- `launch`: resolves the effective profile home and the history-specific data root. Composition uses its public path resolver to select `~/.a1/data` for history unless `A1_DATA_DIR` is explicit; global control/release/runtime/cache paths stay unchanged.
|
|
32
|
+
- `prompt-history`: narrowly typed user-input retention in separate profile-owned databases under `~/.a1/data/history` (or `<A1_DATA_DIR>/history`), with bounded worker queues and no supervisor/control-store payloads. It receives a resolved root rather than importing launch-feature internals; it never probes, imports, or deletes the former platform-default history. The editor's owned history state machine remains inside the Pi component boundary; the session UI only coordinates snapshots and classified submissions.
|
|
32
33
|
- `storage`: SQLite migrations, prior-boot reconciliation, and plural launch-instance persistence. Legacy foreground rows are historical migration input and never authorize current ownership.
|
|
33
34
|
- `supervisor`: endpoint identity, plural cohort ownership, per-instance reconciliation, and aggregate release shutdown coordination. It owns no terminal surface.
|
|
34
35
|
- `pi-engine-adapter`, `pi-component-adapter`, `pi-tui-runtime-adapter`, and `pi-session-ui-integration`: isolate pinned Pi engine and presentation knowledge behind neutral contracts; product features do not import them directly. The session UI render root assembles semantic document and dock rows, while its focused viewport controller owns follow state, pointer routing, selection, and interaction timers. Owned-app route lifecycle belongs to the neutral `ui-apps` owner and is only hosted by the Pi session UI.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Internal naming and private launch context
|
|
2
|
+
|
|
3
|
+
Internal code names contain no case-insensitive `a1` substring. This includes constants, variables, parameters, functions, methods, classes, types, private fields, aliases, and quoted/constant-computed member names. Branding remains at supported external boundaries: the `a1` command, public package identity, user-visible text, user directories, public settings, and declared serialized fields.
|
|
4
|
+
|
|
5
|
+
## Required PR validation
|
|
6
|
+
|
|
7
|
+
The required **Internal naming validation** job scans complete added, modified, copied, and renamed-to files at the exact PR head against the complete merge-base diff. It does not inspect only changed lines. Policy, exception, ownership, parser-dependency, and selection changes require a full audit and inspector regression tests. A stale, missing, failed, or unexpectedly skipped required result blocks the aggregate development check.
|
|
8
|
+
|
|
9
|
+
The nightly release workflow runs `full-release`, including `naming-full`, against the entire tracked codebase at its selected source commit. It does not use PR changed-file selection, including when it verifies an already-published immutable package. Naming failure fails platform validation and blocks publication. `naming-selection.test.ts` locks down this nightly wiring and checks that unchanged source is audited.
|
|
10
|
+
|
|
11
|
+
- Full local audit: `npm run check:names` (tracked files, including staged new files).
|
|
12
|
+
- Exact selected PR audit: `npm run check:names:changed` after producing `.artifacts/validation/impact.json`.
|
|
13
|
+
- Evidence: `.artifacts/validation/naming.json`, uploaded as `development-naming-validation`.
|
|
14
|
+
- Parser fixtures: `test/repository-governance/naming-inspection.test.ts`.
|
|
15
|
+
- Git selection fixtures: `test/repository-governance/naming-selection.test.ts`.
|
|
16
|
+
|
|
17
|
+
TypeScript/JavaScript and Python use syntax trees. Rust uses a token-aware scanner. Workflow environment maps, embedded Node scripts, JSON environment definitions, and supported shell assignments are inspected. Dependencies, immutable vendor files, generated output, and other worktrees are excluded; owned test helpers and locally adapted source ports are not. Unsupported owned inputs fail explicitly. Python inspection uses a bundled development-only grammar, not an installed Python interpreter.
|
|
18
|
+
|
|
19
|
+
The exact externally branded key/member authority is `config/internal-naming-policy.json`. It records each setting's owner, evidence, exposure, and value semantics. Arbitrary uppercase properties are not public environment settings. No compatibility-alias exposure category is allowed. Test snippets and negative-test input data are not declarations or supported aliases.
|
|
20
|
+
|
|
21
|
+
## Environment ownership inventory
|
|
22
|
+
|
|
23
|
+
### Supported branded external settings
|
|
24
|
+
|
|
25
|
+
| Keys | Producer / consumer and exposure |
|
|
26
|
+
| --- | --- |
|
|
27
|
+
| `A1_CONFIG_DIR`, `A1_DATA_DIR`, `A1_RUNTIME_DIR`, `A1_DATABASE_PATH`, `A1_ENDPOINT` | User/shell configuration consumed by `src/foundation/lifecycle/paths.ts`; documented public overrides, unchanged. |
|
|
28
|
+
| `A1_PROFILE_HOME` | Caller-supplied profile-home override consumed by `src/features/launch/profile-paths.ts`; exact existing exposure-review entry. |
|
|
29
|
+
| `A1_STARTUP_TRACE` | Caller-supplied diagnostic path and trace context in `src/foundation/startup/startup-runtime.ts`; exact existing exposure-review entry. |
|
|
30
|
+
| `A1_DEV_INSTANCE_ID`, `A1_DEV_ROOT` | Caller-supplied development overrides consumed by `src/features/launch/development-launch.ts`; exact existing exposure-review entries. |
|
|
31
|
+
| `A1_PROCESS_GUARDIAN_PATH` | Explicit executable override in `src/foundation/process-containment/native-guardian-containment.ts`, also configured by CI; exact existing exposure-review entry. |
|
|
32
|
+
| `A1_PROBE_TRACE` | Opt-in diagnostics read by native terminal-host code; exact existing exposure-review entry. |
|
|
33
|
+
| `A1_BUILD_VERBOSE`, `A1_DEV_SHELL` | Developer invocation controls in the build helper and development launcher; exact existing exposure-review entries. |
|
|
34
|
+
| `A1_PANE_ID`, `A1_TERMINAL_SESSION_ID` | Produced by `native/terminal-host/src/workspace.rs` and exported to launched programs; external integration names, unchanged. |
|
|
35
|
+
|
|
36
|
+
Pending review preserves a possible external interface, not an obsolete private alias. Once a setting is established as private, it cannot keep its branded spelling through that category.
|
|
37
|
+
|
|
38
|
+
### Current private settings
|
|
39
|
+
|
|
40
|
+
| Keys | Producer / consumer and value semantics |
|
|
41
|
+
| --- | --- |
|
|
42
|
+
| `LAUNCH_CONTEXT_RELEASE_ROOT`, `LAUNCH_CONTEXT_RELEASE_ID`, `LAUNCH_CONTEXT_RELEASE_DIGEST`, `LAUNCH_CONTEXT_RELEASE_LAYERS` | Release bootstrap writes the selected verified immutable identity; supervision, guardian, and startup/cache readers consume it. Layers are comma-separated and can be empty. |
|
|
43
|
+
| `LAUNCH_CONTEXT_PROFILE` | Bootstrap or the development launcher writes the selected `a1`/`pi` profile; guardian and UI entries consume it. |
|
|
44
|
+
| `LAUNCH_CONTEXT_WARMUP` | Release warmup writes exactly `1`; the private warmup entry requires it together with release context. |
|
|
45
|
+
| `RELEASE_CLEANUP_HOLDS`, `RELEASE_CLEANUP_RUN_ID` | Cleanup scheduler/worker handoff in `src/foundation/release/release-gc.ts`; serialized holds and a worker run identity. |
|
|
46
|
+
| `SOURCE_LEDGER_PATH`, `SOURCE_LEDGER_SCAN_ROOT`, `SOURCE_LEDGER_PORT_ROOT` | Source-ledger governance fixture overrides; produced by its tests and consumed by `check-pinned-pi-source-ledger.mjs`. |
|
|
47
|
+
| `RELEASE_RUNNER_LABEL` | Release/full-regression workflows supply certification-runner provenance to `run-release-gates.mjs`. |
|
|
48
|
+
| `TERMINAL_FIXTURE_INPUT`, `TERMINAL_FIXTURE_TOKEN` | Native terminal probe producer/consumer in `native/terminal-host/src/main.rs`; expected input and fixture token. |
|
|
49
|
+
| `DOCS_AUTO_MERGE_POLL_ATTEMPTS`, `DOCS_AUTO_MERGE_POLL_MS` | Documentation automation polling controls, produced by governance tests and consumed by `manage-documentation-auto-merge.mjs`. |
|
|
50
|
+
| `VALIDATION_JOB_STARTED_MS`, `RENDERING_JOB_STARTED_MS` | CI timing handoffs within `.github/workflows/ci.yml`; epoch milliseconds. |
|
|
51
|
+
| `RUN_PROCESS_CONTAINMENT_INTEGRATION` | CI enables the real containment fixture with exactly `1`; platform containment tests consume it. |
|
|
52
|
+
| `PACKAGE_MESSAGE_SCENARIO` | Package-message worker parent/child JSON scenario handoff. |
|
|
53
|
+
| `RECOVERY_TEST_CANCEL_AFTER`, `RECOVERY_TEST_REMOVAL_MARKER` | Recovery test parent/fake-npm handoff; mutation index and disposable sentinel path. |
|
|
54
|
+
|
|
55
|
+
The private launch contract is `neutral-launch-v1`, declared by the package's `privateLaunchContract` metadata and bound into immutable release identity. It is validated before activation or execution. There is one reader/writer and no mapping from obsolete private names.
|
|
56
|
+
|
|
57
|
+
### Existing neutral automation and third-party boundaries
|
|
58
|
+
|
|
59
|
+
These names are already neutral; their definitions and consumers remain the authority for their existing behavior:
|
|
60
|
+
|
|
61
|
+
- Development aggregate: `CHANGES_RESULT`, `DOCS_RESULT`, `DOCUMENTATION_RESULT`, `DOCUMENTATION_REQUIRED`, `VALIDATE_RESULT`, `CONTAINMENT_RESULT`, `STARTUP_RESULT`, `RENDERING_RESULT`, `RENDERING_TIER`, `DOCS_ONLY`, `VERSION_ONLY`, `OPENSPEC_TOUCHED`, `SELECTED_HEAD`, `EXPECTED_HEAD`, `EVENT_BASE_SHA`, `EVENT_HEAD_SHA`. The workflow produces these and `require-development-validation.mjs` or the selector consumes them.
|
|
62
|
+
- Naming aggregate: `NAMING_RESULT`, `NAMING_REQUIRED`, `NAMING_HEAD`, produced by CI and consumed by the same required aggregate.
|
|
63
|
+
- Validation: `VALIDATION_BUILD_READY`, `VALIDATION_CANDIDATE_TARBALL`, `VALIDATION_DOCUMENTATION_FULL_READY`, `VALIDATION_SELECTION_JSON`, `STARTUP_PERFORMANCE_RESULT`, owned by validation orchestration and exact-package fixtures.
|
|
64
|
+
- Publication workflow-local handoffs: `BUILD`, `EVENT_NAME`, `EXISTS`, `EXPECTED_INTEGRITY`, `EXPECTED_REGISTRY_INTEGRITY`, `EXPECTED_REGISTRY_SHASUM`, `EXPECTED_SHASUM`, `MODE`, `PACKAGE`, `PLAN`, `PUBLISH`, `PULLS_PATH`, `PULL_REQUEST`, `REGISTRY_TARBALL`, `RELEASE_CHANNEL`, `RELEASE_VERSION`, `REQUESTED_CHANNEL`, `REQUESTED_SHA`, `SOURCE_SHA`, `VALIDATE`, `VERSION`, `WORK`, defined and consumed in `.github/workflows/release.yml`.
|
|
65
|
+
- Isolated fixture controls: `PROMPT_SUGGESTION_AGENT_DIR`, `RUN_PROMPT_SUGGESTION_PROVIDER_TEST`, `TEST_SUPERVISOR_SECRET`, owned by their specific provider/supervisor tests.
|
|
66
|
+
- Host/tool integration: `CARGO`, `ZIG`, `PATH`, `HOME`, `USERPROFILE`, `APPDATA`, `LOCALAPPDATA`, XDG directory variables, `TERM`, `COLORTERM`, `TERM_PROGRAM`, `WT_SESSION`, `EXEPATH`, `MINGW_PREFIX`, `MSYSTEM`, and third-party `PI_*`, `GITHUB_*`, `GH_TOKEN`, and npm variables. Their external spellings and caller values are not private product naming targets. The forwarding of an arbitrary user's environment is distinct from defining an owned setting.
|
|
67
|
+
|
|
68
|
+
### Removed or reclassified registry entries
|
|
69
|
+
|
|
70
|
+
The old environment registry included `fixture` and `inputAcknowledgement`, but their values describe native probe stdout markers, not environment settings. Their existing external wire spellings stay in that protocol, not in the public environment registry.
|
|
71
|
+
|
|
72
|
+
`certificationTarball`, `internalPackaging`, `nativePi`, `piParityIntentionalMutation`, `protocolVersion`, `structuredFlowLimits`, `terminalArgumentsJson`, and `terminalExecutable` had no active runtime consumer in the reviewed tree. They are removed from the current environment authority, not renamed into new settings. Rejection patterns and immutable historical evidence remain factual.
|
|
73
|
+
|
|
74
|
+
## Negotiated handoff and protected state
|
|
75
|
+
|
|
76
|
+
An update is performed by the release that is already installed, so the contract is negotiated rather than cut over. `neutral-launch-v1` is the only contract this build **writes** for its own releases, and the superseded `A1_RELEASE_*`/`A1_IMMUTABLE_WARMUP` keys are still **read** when an older launcher starts this build, and still **written** when this build starts a retained release that declares no contract. An installation therefore stays launchable across the cutover in both directions, and no user is asked to stop processes and reinstall by hand.
|
|
77
|
+
|
|
78
|
+
Metadata that predates contract declaration is stale, never fatal. A pre-cutover active record does not stop a launch: it is ignored, the installed payload is materialized, and ordinary cohort selection activates it. A launch that cannot take the installed payload at all — an installation being replaced right now — starts the retained active release instead of failing, and leaves activation to the next launch. What still requires `neutral-launch-v1` outright is narrow and never blocks a launch: the installed package's own manifest must declare it, and an update recovery capsule is never translated.
|
|
79
|
+
|
|
80
|
+
`test/foundation/release/update-predecessor.integration.test.ts` is the gate for this. It installs each of the most recent published releases and drives the candidate through **that release's own** materialization and warmup, because a fixture built from the candidate would only prove the candidate agrees with itself. No reset or migration runs automatically. If disposable state blocks installation, inspect its resolved paths and obtain separate approval before removal.
|
|
81
|
+
|
|
82
|
+
| State | Treatment |
|
|
83
|
+
| --- | --- |
|
|
84
|
+
| `<configDir>` and its settings | Preserve. |
|
|
85
|
+
| `~/.a1/agent`, credentials, extensions, and session files | Preserve. |
|
|
86
|
+
| Prompt-history databases under the selected data/history owner | Preserve; this change does not relocate history. |
|
|
87
|
+
| `<dataDir>/releases`, release references/certification records, `<dataDir>/update-recovery`, update journal | Disposable runtime/release candidates only; inspect exact paths and live ownership before any separately approved manual reset. |
|
|
88
|
+
| `<runtimeDir>` endpoints, locks, and worker records | Reset candidates only after all affected processes stop and their precise scope is confirmed. |
|
|
89
|
+
| The whole `<dataDir>` or `<configDir>` | Never delete as a shortcut: disposable and user data can share these roots. |
|
|
90
|
+
|
|
91
|
+
`test/foundation/launch-context/cutover.test.ts` places protected settings/session/history sentinels next to incompatible runtime fixtures and verifies failed admission does not change them. No test or implementation command uses actual user data as its cleanup fixture.
|
|
@@ -47,8 +47,10 @@ Sanitization must classify before logging or storing. Unknown or untyped values
|
|
|
47
47
|
|
|
48
48
|
The `prompt-history` feature owns only reusable interactive user input, not
|
|
49
49
|
structured-message archives. It stores one independent profile database under
|
|
50
|
-
`<
|
|
51
|
-
|
|
50
|
+
`<effective-home>/.a1/data/history`, or `<A1_DATA_DIR>/history` when explicitly
|
|
51
|
+
overridden, never agent resources or cache/release directories. The default home
|
|
52
|
+
follows launch-profile resolution, including `A1_PROFILE_HOME`; other product
|
|
53
|
+
data paths are unchanged. Text is unencrypted and potentially sensitive. Retain up to 100 unique entries (configured
|
|
52
54
|
10-100), at most 1 MiB per entry and 8 MiB total canonical text. Background queues
|
|
53
55
|
are limited to 32 writes/8 MiB per instance; reads are coalesced, lock retries are
|
|
54
56
|
bounded to one second off-thread, and graceful shutdown drains for at most two
|
|
@@ -59,8 +61,11 @@ Only typed canonical text, submission identity, recency/timestamp, input kind,
|
|
|
59
61
|
and bounded cwd/session provenance are allowed. No image bytes, transformed
|
|
60
62
|
agent prompts, environment/credential copies, tool results, terminal streams, or
|
|
61
63
|
private input in diagnostics are permitted. Disabling persistence is next-start
|
|
62
|
-
and does not erase data or stop other live instances.
|
|
63
|
-
must not touch history.
|
|
64
|
+
and does not erase data or stop other live instances. Upgrades, ordinary npm
|
|
65
|
+
uninstall/reinstall, and cache/release cleanup must not touch history. The new
|
|
66
|
+
default starts fresh without probing, importing, or deleting the old platform
|
|
67
|
+
store. Any old-store removal is a separate manual operation after its users have
|
|
68
|
+
stopped, not startup or cleanup behavior. See [prompt history](../features/prompt-history.md) for
|
|
64
69
|
retention, failure semantics, profile identity, and stopped-instance removal.
|
|
65
70
|
|
|
66
71
|
## Required architectural outcomes
|
|
@@ -82,7 +82,7 @@ These paths are A1 control and release state, not Pi profile roots. All are over
|
|
|
82
82
|
| Purpose | Override | Windows default | Unix default |
|
|
83
83
|
|---|---|---|---|
|
|
84
84
|
| Config | `A1_CONFIG_DIR` | `%APPDATA%\\a1` | `$XDG_CONFIG_HOME/a1` or `~/.config/a1` |
|
|
85
|
-
|
|
|
85
|
+
| Control/release data | `A1_DATA_DIR` | `%LOCALAPPDATA%\\a1` | `$XDG_DATA_HOME/a1` or `~/.local/share/a1` |
|
|
86
86
|
| Runtime | `A1_RUNTIME_DIR` | `%LOCALAPPDATA%\\a1\\runtime` | `$XDG_RUNTIME_DIR/a1` or `<data>/runtime` |
|
|
87
87
|
| Database | `A1_DATABASE_PATH` | `<data>/control.sqlite3` | `<data>/control.sqlite3` |
|
|
88
88
|
| Endpoint | `A1_ENDPOINT` | runtime-scoped `a1-*` named pipe | `<runtime>/supervisor.sock` |
|
|
@@ -96,3 +96,17 @@ Do **not** remove `~/.a1/agent`; it is A1's current Pi profile root. `~/.pi/agen
|
|
|
96
96
|
The obsolete npm package `@timurproko/addone` is deprecated with the registry message `This package is obsolete. Use @timurproko/a1 instead.` It is not a current identity, compatibility channel, or rollback source. Whole-package unpublication was rejected by npm policy; any later removal is owner-controlled registry administration and does not change the A1 runtime contract.
|
|
97
97
|
|
|
98
98
|
The launch-profile feature separately owns A1's `~/.a1/agent` root and preserves ordinary Pi resolution through `~/.pi/agent`.
|
|
99
|
+
|
|
100
|
+
## Internal naming validation
|
|
101
|
+
|
|
102
|
+
The required PR naming job inspects complete new and changed source files. `npm run check:names` performs the full tracked audit, also required by nightly full-release validation. See [internal naming and clean cutover](internal-naming.md) for public/private environment ownership, required checks, and protected user data.
|
|
103
|
+
|
|
104
|
+
### Prompt history
|
|
105
|
+
|
|
106
|
+
Prompt history has a separate default: `<effective-home>/.a1/data/history/<profile-id>.sqlite3`
|
|
107
|
+
on Windows, Linux, and macOS. The effective home follows launch-profile resolution
|
|
108
|
+
(`A1_PROFILE_HOME` or the OS home), not `XDG_DATA_HOME`. An explicit `A1_DATA_DIR`
|
|
109
|
+
continues to select `<A1_DATA_DIR>/history` as well as the control/release data root.
|
|
110
|
+
The home-based history default does not relocate the paths above or the compile
|
|
111
|
+
cache at `<data>/cache/compile`. See [prompt history](../features/prompt-history.md)
|
|
112
|
+
for the deliberate fresh start without migration, privacy, and manual removal.
|
|
@@ -36,10 +36,23 @@ imported automatically.
|
|
|
36
36
|
|
|
37
37
|
| Platform | Default durable location |
|
|
38
38
|
|---|---|
|
|
39
|
-
| Windows | `%
|
|
40
|
-
|
|
|
39
|
+
| Windows | `%USERPROFILE%/.a1/data/history/<profile-id>.sqlite3` |
|
|
40
|
+
| Linux and macOS | `~/.a1/data/history/<profile-id>.sqlite3` |
|
|
41
41
|
| Explicit override | `<A1_DATA_DIR>/history/<profile-id>.sqlite3` |
|
|
42
42
|
|
|
43
|
+
The default uses A1's effective profile home: `A1_PROFILE_HOME` when set, otherwise
|
|
44
|
+
the operating-system home. A custom agent-profile directory changes the history
|
|
45
|
+
identity, not this default root. `A1_DATA_DIR` takes precedence for storage;
|
|
46
|
+
`XDG_DATA_HOME` does not redirect default history. Control metadata, settings,
|
|
47
|
+
agent resources, releases, logs, runtime files, and caches keep their existing
|
|
48
|
+
locations.
|
|
49
|
+
|
|
50
|
+
**The home-based default starts fresh.** Previous versions used
|
|
51
|
+
`%LOCALAPPDATA%/a1/history` on Windows, or `$XDG_DATA_HOME/a1/history` /
|
|
52
|
+
`~/.local/share/a1/history` on Unix. A1 does not probe, import, merge, delete, or
|
|
53
|
+
fall back to those stores. Explicit `A1_DATA_DIR` selections still work normally.
|
|
54
|
+
Old and new releases using different roots do not synchronize history.
|
|
55
|
+
|
|
43
56
|
The profile filename is `a1-` followed by a SHA-256 digest of a versioned tuple
|
|
44
57
|
containing the launch kind and normalized effective agent-profile path. It is
|
|
45
58
|
independent of project, session, checkout, and release. Windows ordinary case and
|
|
@@ -48,13 +61,16 @@ files. Moving a profile, unresolved symlink aliases, or selecting a different
|
|
|
48
61
|
data root can select a different history; A1 never silently merges or imports it.
|
|
49
62
|
|
|
50
63
|
The database is separate from `control.sqlite3`, agent resources, and disposable
|
|
51
|
-
caches. Upgrades, release rollback, cache cleanup,
|
|
52
|
-
not clear it.
|
|
64
|
+
caches. Upgrades, ordinary npm uninstall/reinstall, release rollback, cache cleanup,
|
|
65
|
+
and conversation deletion do not clear it. Reusing saved history requires the
|
|
66
|
+
same profile and history root; explicitly deleting user data still removes it.
|
|
67
|
+
SQLite may keep `-wal` and `-shm` sidecars beside the database.
|
|
53
68
|
|
|
54
69
|
**History is unencrypted potentially sensitive user text.** Owner permissions
|
|
55
|
-
are restricted where supported; Windows uses the
|
|
56
|
-
|
|
57
|
-
|
|
70
|
+
are restricted where supported; Windows uses inherited ACLs at the selected
|
|
71
|
+
history directory. Review parent-directory permissions if you customize your home
|
|
72
|
+
or override root. These protections do not make it safe to submit secrets.
|
|
73
|
+
Credential files, image data, arbitrary environment values, assistant/tool output, and terminal
|
|
58
74
|
streams are not copied into this store. Prompt content and private provenance
|
|
59
75
|
must not appear in history diagnostics or test evidence.
|
|
60
76
|
|
|
@@ -96,15 +112,27 @@ two seconds and reports an incomplete flush without preventing exit.
|
|
|
96
112
|
|
|
97
113
|
First close **every instance using the selected profile**. Then remove only that
|
|
98
114
|
profile's `.sqlite3` file and its matching `-wal` and `-shm` sidecars, if present.
|
|
99
|
-
Do not delete an open database
|
|
100
|
-
setting alone is not an erase operation.
|
|
101
|
-
command in this release.
|
|
115
|
+
Do not delete an open database, the whole `.a1` directory, or the whole
|
|
116
|
+
application-data root. Disabling the setting alone is not an erase operation.
|
|
117
|
+
There is no interactive clear/export command in this release.
|
|
118
|
+
|
|
119
|
+
Removing a former default store is likewise a one-time manual cleanup, not an
|
|
120
|
+
application feature. Wait until you have switched to the new version and closed
|
|
121
|
+
all instances using the old store; an older running version can otherwise keep
|
|
122
|
+
using or recreate it. Remove only the identified old profile database and matching
|
|
123
|
+
sidecars, not other profiles or either application's caches.
|
|
102
124
|
|
|
103
125
|
## Manual acceptance
|
|
104
126
|
|
|
105
127
|
Build the checkout, then launch it through `./scripts/dev`. Use an isolated
|
|
106
128
|
`A1_DATA_DIR` for disposable history checks; keep that same directory on each
|
|
107
|
-
restart and in both concurrent terminals.
|
|
129
|
+
restart and in both concurrent terminals. The development launcher always sets
|
|
130
|
+
an isolated `A1_DATA_DIR`; to try the home-based location in that launcher,
|
|
131
|
+
explicitly select `A1_DATA_DIR=<effective-home>/.a1/data` and keep
|
|
132
|
+
`A1_DATABASE_PATH` in a separate disposable directory so control metadata is not
|
|
133
|
+
placed beside history. For a history-only review, `NODE_DISABLE_COMPILE_CACHE=1`
|
|
134
|
+
also avoids creating compile-cache files under that explicitly overridden root.
|
|
135
|
+
The focused path/composition tests cover normal no-override selection. Test:
|
|
108
136
|
|
|
109
137
|
1. Submit two text prompts and one repeated prompt; start `/new`, then restart.
|
|
110
138
|
The latest unique prompts remain recallable.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Bounded code-streaming and hyperlink cleanup review
|
|
2
|
+
|
|
3
|
+
This candidate finishes the hyperlink portion of `eliminate-code-block-streaming-flicker`
|
|
4
|
+
(specification PR #318), following the partial implementation in #321. It is a prerequisite
|
|
5
|
+
for `keep-streaming-ui-responsive-during-selection` (#325), not that larger change's completed
|
|
6
|
+
selection/wheel performance fix.
|
|
7
|
+
|
|
8
|
+
## What changed
|
|
9
|
+
|
|
10
|
+
- Candidate-looking text (paths, dotted identifiers) no longer vetoes a proven followed shift.
|
|
11
|
+
Real OSC 8 links, unsafe escapes, images, overlays, and selections retain their conservative
|
|
12
|
+
movement rules.
|
|
13
|
+
- Ordinary streamed text changes no longer request hyperlink cleanup.
|
|
14
|
+
- Pointer transitions identify the former hovered row. Editor link deletion and discarded
|
|
15
|
+
presentation state retain explicit cleanup requests, including when replacement content
|
|
16
|
+
has no links. Unscoped cleanup considers every previously linked row; a missing pointer
|
|
17
|
+
report is not treated as proof that no host decoration exists.
|
|
18
|
+
- Cleanup paints affected and changed rows without manufacturing an erase-display. After
|
|
19
|
+
unknown paint or lost geometry, it waits for a complete safe frame instead of guessing.
|
|
20
|
+
- Same-geometry forced frames preserve current cells without repainting unchanged rows.
|
|
21
|
+
Structural entry, resize, and unsafe-protocol fallbacks are still conservative.
|
|
22
|
+
|
|
23
|
+
## Automated evidence
|
|
24
|
+
|
|
25
|
+
`test/fixtures/rendering/baseline-code-streaming.json` is the pre-production-change capture
|
|
26
|
+
from `6c5af810`, repeated twice with no production diff. Its synthetic content and cell hashes
|
|
27
|
+
contain no private session input. The fixture predates the added dual-synchronization summary
|
|
28
|
+
field; it remains a historical baseline rather than a regenerated candidate result.
|
|
29
|
+
|
|
30
|
+
| Bare-A1 fullscreen workload | Baseline post-startup clears | Candidate post-startup clears |
|
|
31
|
+
| --- | ---: | ---: |
|
|
32
|
+
| Streamed fenced code | 3 | 0 |
|
|
33
|
+
| Path-bearing prose | 3 | 0 |
|
|
34
|
+
| Tall live tail | 0 | 0 |
|
|
35
|
+
|
|
36
|
+
The deterministic producers use a shared scripted clock so cold imports do not advance spinner
|
|
37
|
+
or presentation timers unpredictably. Independent comparison processes remain outside the owned
|
|
38
|
+
damage adapter. Current budgets also fail candidate-only fallback, repaint of settled rows,
|
|
39
|
+
stale final content, or divergent final cells with synchronization honored versus ignored.
|
|
40
|
+
The dual-model replay reuses producer bytes rather than launching duplicate producers.
|
|
41
|
+
|
|
42
|
+
Generate current evidence (non-interactive; writes only the named report):
|
|
43
|
+
|
|
44
|
+
```sh
|
|
45
|
+
cd D:/Git/a1/.worktrees/finish-bounded-link-cleanup && node --import tsx scripts/pi/report-code-streaming.ts --phase current --repeat 2 --output .artifacts/rendering/code-streaming-current.json
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The baseline mode rejects dirty production sources. Do not replace the committed baseline with
|
|
49
|
+
post-fix results. Repeated reports compare cells, row damage, decisions, and budgets, not elapsed
|
|
50
|
+
machine timings. This is a paint regression check, not a CPU or input-latency benchmark.
|
|
51
|
+
|
|
52
|
+
## Physical Windows Terminal review
|
|
53
|
+
|
|
54
|
+
Use the candidate branch `fix/bounded-hyperlink-cleanup` and record its exact `git rev-parse HEAD`.
|
|
55
|
+
Build and start the owned UI through the color-preserving shell entry:
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
cd D:/Git/a1/.worktrees/finish-bounded-link-cleanup && npm run build && ./scripts/dev
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
1. Ask the agent, without writing files, to produce a long fenced TypeScript example containing
|
|
62
|
+
`obj.method`, `package.json`, and `./src/index.ts`, followed by a short explanation and a real
|
|
63
|
+
Markdown hyperlink. Check that ordinary code/path streaming no longer blanks the screen.
|
|
64
|
+
2. Hover a real hyperlink, then scroll it away without moving the pointer. Repeat with a
|
|
65
|
+
terminal-detected URL and file-like text inside code. Try both short and wrapped links,
|
|
66
|
+
duplicate targets, blank rows replacing links, and a smaller terminal.
|
|
67
|
+
3. Move off a hovered link, select linked text, wheel/auto-scroll during selection, release,
|
|
68
|
+
and copy. Check exact copied text, normal link colors/activation, and no leftover solid
|
|
69
|
+
underlines on unrelated text, padding, or controls.
|
|
70
|
+
4. Paste a URL chip into the editor and delete it. Open and close a covering overlay, and resize
|
|
71
|
+
while a link is visible. Check that obsolete targets/underlines are removed and restored
|
|
72
|
+
links have their correct targets.
|
|
73
|
+
5. Verify that the dock stays intact and terminal mouse/cursor behavior is restored on exit.
|
|
74
|
+
|
|
75
|
+
Use the same geometry for the independent comparison profile:
|
|
76
|
+
|
|
77
|
+
```sh
|
|
78
|
+
cd D:/Git/a1/.worktrees/finish-bounded-link-cleanup && npm run build && ./scripts/dev pi
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Record terminal/version, geometry, synchronized-update support, explicit versus auto-detected
|
|
82
|
+
link case, commit, and pass/fail. Test both before and after any pointer report: lack of a report
|
|
83
|
+
must not be interpreted as evidence of an absent pointer.
|
|
84
|
+
|
|
85
|
+
**Known gaps:** native Windows Terminal hover rasterization cannot be certified by headless cell
|
|
86
|
+
replay. Visual acceptance and merge authorization are pending. The broader selection/wheel
|
|
87
|
+
scheduling and collapsed-tool preparation optimizations have not been implemented in this PR.
|
|
88
|
+
Do not merge on automated results alone; a ghost-underline or flicker regression blocks acceptance.
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@timurproko/a1",
|
|
3
|
-
"version": "0.1.8-dev.
|
|
3
|
+
"version": "0.1.8-dev.332",
|
|
4
4
|
"description": "Standalone terminal workspace for supervised native and managed agents",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"privateLaunchContract": "neutral-launch-v1",
|
|
6
7
|
"packageManager": "npm@11.13.0",
|
|
7
8
|
"bin": {
|
|
8
9
|
"a1": "bin/cli.js"
|
|
@@ -26,7 +27,9 @@
|
|
|
26
27
|
"build": "npm run clean && tsc -p tsconfig.build.json && node scripts/development/build-process-guardian.mjs && node scripts/release/generate-runtime-payload-inventory.mjs",
|
|
27
28
|
"build:process-guardian": "node scripts/development/build-process-guardian.mjs",
|
|
28
29
|
"typecheck": "tsgo -p tsconfig.json --noEmit",
|
|
29
|
-
"check:architecture": "node scripts/governance/check-architecture.mjs && node scripts/governance/
|
|
30
|
+
"check:architecture": "node scripts/governance/check-architecture.mjs && node scripts/governance/check-product-identity-boundaries.mjs && node scripts/governance/check-package-identity.mjs && node scripts/governance/check-pinned-pi-source-ledger.mjs && node scripts/governance/check-terminal-host-provenance.mjs",
|
|
31
|
+
"check:names": "node scripts/governance/product-identifier-policy.mjs --check",
|
|
32
|
+
"check:names:changed": "node scripts/governance/product-identifier-policy.mjs --check --selection .artifacts/validation/impact.json",
|
|
30
33
|
"check:code-documentation": "node scripts/governance/check-code-documentation.mjs --mode full",
|
|
31
34
|
"check:code-documentation:changed": "node scripts/release/run-changed-documentation.mjs",
|
|
32
35
|
"select:validation-impact": "node scripts/release/select-validation-impact.mjs",
|
|
@@ -70,6 +73,7 @@
|
|
|
70
73
|
"undici": "8.9.0"
|
|
71
74
|
},
|
|
72
75
|
"devDependencies": {
|
|
76
|
+
"@lezer/python": "1.1.19",
|
|
73
77
|
"@types/cross-spawn": "6.0.6",
|
|
74
78
|
"@types/node": "24.2.1",
|
|
75
79
|
"@types/semver": "7.8.0",
|
|
@@ -78,7 +82,8 @@
|
|
|
78
82
|
"node-pty": "1.1.0",
|
|
79
83
|
"tsx": "4.20.3",
|
|
80
84
|
"typescript": "5.9.2",
|
|
81
|
-
"vitest": "3.2.7"
|
|
85
|
+
"vitest": "3.2.7",
|
|
86
|
+
"yaml": "2.9.1"
|
|
82
87
|
},
|
|
83
88
|
"keywords": [
|
|
84
89
|
"cli",
|