mirror of
https://github.com/morluto/rea
synced 2026-10-26 06:16:17 -04:00
9c25dc4ed2
* fix(comparisons)!: preserve unknowns across partial observations Share absence and digest semantics, keep unobserved managed bodies unknown, and match unique managed type/name/signatures before structural fallback. BREAKING CHANGE: Managed comparison metadata adds exact-signature matching and its count, and name_matching now reports exact-signature-fallback. * fix(javascript): preserve projected result binding semantics Share syntax-aware property reads and assigned-result resolution. Retain destructuring paths and downgrade downstream whole-result relationships instead of resolving nested or wrapped calls as aliases. * fix(native)!: admit complete parser values and preserve typed failures Decode Mach headers by named columns, validate complete slice keys and lipo alignment, and preserve codesign runtime flags and tagged parser errors. Rename the Ghidra test dossier fixture and connect fake-backed suites to real verification lanes. BREAKING CHANGE: Native load-command results no longer contain the unused, always-null file_offset field. * fix(process): preserve host identity and actionable boundary failures Thread selected platform and environment through process and Doctor seams, stamp observed producer identity in Evidence, and retain PTY, filesystem, lease and lazy-provider failure causes. Drain cancelled lazy loads and omit exited descendants from verified lineage. * fix(browser): preserve cleanup and document-transition evidence Make V8 and Playwright teardown cancellation-aware, expose primary failures alongside incomplete cleanup, share frame-tree and navigation rules, and clear stale WebMCP registrations without pruning unrelated child frames. * fix(adapters): align managed targets and typed CLI outcomes Inspect managed PE/CLI targets independently of native provider selection, reuse successful managed selections, and keep evidence bound to the actual inspected target. Classify canonical CLI error envelopes and exhaustive setup/update/uninstall outcomes, audit registered CLI coverage, and assert platform-specific runtime results. * docs: refresh boundary contracts and shipped roadmap behavior
174 lines
6.0 KiB
TypeScript
174 lines
6.0 KiB
TypeScript
import { gt, valid } from "semver";
|
|
|
|
import { PRODUCT_IDENTITY } from "../identity.js";
|
|
import type { Result } from "../domain/result.js";
|
|
import type { IntegrationMaintenance } from "./UpdateMaintenance.js";
|
|
|
|
/** Global npm installation that owns the running package and its entry point. */
|
|
export interface NpmInstallation {
|
|
readonly prefix: string;
|
|
readonly packageRoot: string;
|
|
}
|
|
|
|
/** Output policy for the package manager subprocess. */
|
|
export type UpdateOutput = "human" | "structured";
|
|
|
|
/** Effects used to update and verify one identified REA installation. */
|
|
export interface UpdateHost {
|
|
installation(): Promise<NpmInstallation | undefined>;
|
|
latestVersion(
|
|
installation: NpmInstallation | undefined,
|
|
): Promise<Result<string, string>>;
|
|
installVersion(
|
|
installation: NpmInstallation,
|
|
version: string,
|
|
output: UpdateOutput,
|
|
): Promise<Result<void, string>>;
|
|
installedVersion(
|
|
installation: NpmInstallation,
|
|
): Promise<Result<string, string>>;
|
|
planMaintenance(
|
|
installation: NpmInstallation,
|
|
): Promise<IntegrationMaintenance>;
|
|
}
|
|
|
|
/** Verified update outcome, separate from the unapplied integration plan. */
|
|
export type UpdateResult =
|
|
| {
|
|
readonly status: "current";
|
|
readonly currentVersion: string;
|
|
readonly latestVersion: string;
|
|
readonly installMethod: "npm" | "unknown";
|
|
}
|
|
| {
|
|
readonly status: "updated";
|
|
readonly previousVersion: string;
|
|
readonly latestVersion: string;
|
|
readonly installedVersion: string;
|
|
readonly installMethod: "npm";
|
|
readonly command: readonly string[];
|
|
readonly maintenance: IntegrationMaintenance;
|
|
readonly remediation: string;
|
|
}
|
|
| {
|
|
readonly status: "failed";
|
|
readonly currentVersion: string;
|
|
readonly latestVersion: string | null;
|
|
readonly reason:
|
|
| "unknown-install-method"
|
|
| "version-check"
|
|
| "install"
|
|
| "verification";
|
|
readonly installedVersion?: string;
|
|
readonly remediation: string;
|
|
};
|
|
|
|
/** Whether the update command left the requested release unapplied. */
|
|
export const isUpdateFailure = (result: UpdateResult): boolean => {
|
|
const status = result.status;
|
|
switch (status) {
|
|
case "current":
|
|
case "updated":
|
|
return false;
|
|
case "failed":
|
|
return true;
|
|
default: {
|
|
const exhaustive: never = status;
|
|
throw new TypeError(
|
|
`Unhandled update result status: ${String(exhaustive)}`,
|
|
);
|
|
}
|
|
}
|
|
};
|
|
|
|
/** Resolve the exact npm command for the identified prefix and release. */
|
|
export const updateInstallCommand = (
|
|
installation: NpmInstallation,
|
|
version: string,
|
|
): readonly string[] => [
|
|
"npm",
|
|
"install",
|
|
"--global",
|
|
"--ignore-scripts",
|
|
"--prefix",
|
|
installation.prefix,
|
|
`${PRODUCT_IDENTITY.packageName}@${version}`,
|
|
];
|
|
|
|
/** Identify, resolve, install, and verify REA without applying setup changes. */
|
|
export const runUpdate = async (
|
|
currentVersion: string,
|
|
host: UpdateHost,
|
|
output: UpdateOutput = "human",
|
|
): Promise<UpdateResult> => {
|
|
const installation = await host.installation();
|
|
const release = await host.latestVersion(installation);
|
|
const latestVersion = release.ok ? release.value : null;
|
|
const targetVersion = release.ok ? valid(release.value) : null;
|
|
if (!release.ok || valid(currentVersion) === null || targetVersion === null)
|
|
return {
|
|
status: "failed",
|
|
currentVersion,
|
|
latestVersion,
|
|
reason: "version-check",
|
|
remediation: release.ok
|
|
? "REA received invalid version metadata. Check the installed version and npm registry, then rerun rea update."
|
|
: `REA could not resolve the latest release: ${release.error}. Retry rea update when registry access is available.`,
|
|
};
|
|
if (!gt(targetVersion, currentVersion))
|
|
return {
|
|
status: "current",
|
|
currentVersion,
|
|
latestVersion: targetVersion,
|
|
installMethod: installation === undefined ? "unknown" : "npm",
|
|
};
|
|
if (installation === undefined)
|
|
return {
|
|
status: "failed",
|
|
currentVersion,
|
|
latestVersion: targetVersion,
|
|
reason: "unknown-install-method",
|
|
remediation:
|
|
"Update this installation with the package manager or source checkout that owns it. For a one-off latest invocation, use npx rea-agents@latest.",
|
|
};
|
|
const installed = await host.installVersion(
|
|
installation,
|
|
targetVersion,
|
|
output,
|
|
);
|
|
if (!installed.ok)
|
|
return {
|
|
status: "failed",
|
|
currentVersion,
|
|
latestVersion: targetVersion,
|
|
reason: "install",
|
|
remediation: `REA could not install ${targetVersion} in ${installation.prefix}: ${installed.error}. Repair this npm installation, then rerun rea update.`,
|
|
};
|
|
const verified = await host.installedVersion(installation);
|
|
if (!verified.ok || verified.value !== targetVersion)
|
|
return {
|
|
status: "failed",
|
|
currentVersion,
|
|
latestVersion: targetVersion,
|
|
reason: "verification",
|
|
...(verified.ok ? { installedVersion: verified.value } : {}),
|
|
remediation: `npm completed, but REA could not verify ${targetVersion} in ${installation.packageRoot}: ${verified.ok ? `the executable reported ${verified.value}` : verified.error}. The installation may have changed; repair it before retrying.`,
|
|
};
|
|
const maintenance = await host.planMaintenance(installation);
|
|
return {
|
|
status: "updated",
|
|
previousVersion: currentVersion,
|
|
latestVersion: targetVersion,
|
|
installedVersion: verified.value,
|
|
installMethod: "npm",
|
|
command: updateInstallCommand(installation, targetVersion),
|
|
maintenance,
|
|
remediation:
|
|
maintenance.status === "planned"
|
|
? "REA is updated. Run the maintenance command to review and approve changes to existing REA integrations, then restart affected agents."
|
|
: maintenance.status === "unavailable"
|
|
? "REA is updated. Integration maintenance could not be planned; inspect the maintenance diagnostic before changing configuration."
|
|
: "REA is updated. Restart agents running this installation to load the new version.",
|
|
};
|
|
};
|