Files
callstack__agent-device/scripts/layering/runtime-command-cutover-ast.ts
Michał Pierzchała d8a7d03faf refactor: route application lifecycle through runtime facts (#1759)
* refactor: route application lifecycle through runtime facts

Moves the canonical `open`, `prepare`, `close` and internal `runtime` descriptors
behind package-owned lifecycle bindings admitted from device runtime facts, while
daemon request/session policy and public response construction stay put.

Based on main, which already carries the boot unit, the parametrized cutover gate
and the apps unit. Readiness is package-owned there, so the Apple and Android
bindings call ensureAppleReady/ensureAndroidReady rather than a root readiness
bag; ensureAppleReady gained an onColdBootStart hook so open keeps warming the
runner cache in parallel with a cold boot, and a narrow markBooted port publishes
readiness' fresh observation so a flow still makes one simctl listing.

Cutover rows take R24-R27, clear of the accepted catalog and the sibling install
stack, and cutoverTableDefects rejects a duplicate rule id.

Two defects this unit introduced are fixed here rather than shipped:
`open <app> <url>` dropped the URL on a first open, and test-IME activation was
first fatal on an unobtainable helper and then over-caught. Helper unavailability
is a typed non-activation outcome now; fence, lock and post-record failures
propagate.

The duplication the unit had accumulated is gone: one runtime-admission module
instead of five per-command copies, one direct-lifecycle binding factory instead
of six hand-rolled packages, one transport-hint predicate, one session
finalization path, and no identity-wrapper module.

* fix: allocate lifecycle cutover rows after deployment

* chore: preserve lifecycle union reconstruction

* fix: reconcile lifecycle runtime stack

* refactor: tighten lifecycle runtime topology

* refactor: remove superseded runtime adapters

* fix: preserve stacked runtime cutovers

* test: preserve migrated runtime ownership

* test: move Android deployment retry ownership

* test: extract runtime hint fixtures

* fix: preserve lifecycle stack invariants

* fix: complete lifecycle runtime cutover

* fix: remove lifecycle cutover residue
2026-08-16 15:13:10 +02:00

43 lines
1.4 KiB
TypeScript

import { propertyName, visitAst } from './cutover-policy-ast.ts';
export type CutoverAstNode = Record<string, unknown>;
export function namedFunction(
program: CutoverAstNode,
expected: string,
): CutoverAstNode | undefined {
let match: CutoverAstNode | undefined;
visitAst(program, (node) => {
if (node.type === 'FunctionDeclaration' && identifierName(node.id) === expected) match = node;
});
return match;
}
export function countNamedCalls(functionNode: CutoverAstNode, expected: string): number {
let count = 0;
visitAst(functionNode, (node) => {
if (callName(node) === expected) count += 1;
});
return count;
}
export function callName(node: CutoverAstNode): string | undefined {
if (node.type !== 'CallExpression') return undefined;
const callee = node.callee as CutoverAstNode | undefined;
if (callee?.type === 'MemberExpression') return propertyName(callee.property);
return identifierName(callee);
}
export function lineOf(source: string, node: CutoverAstNode): number {
const start = typeof node.start === 'number' ? node.start : 0;
return source.slice(0, start).split('\n').length;
}
function identifierName(node: unknown): string | undefined {
if (!node || typeof node !== 'object') return undefined;
const candidate = node as CutoverAstNode;
return candidate.type === 'Identifier' && typeof candidate.name === 'string'
? candidate.name
: undefined;
}