Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions apps/server/scripts/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ import * as Path from "effect/Path";
import { Command, Flag } from "effect/cli";
import { ChildProcess, ChildProcessSpawner } from "effect/process";

import { withFiniteProduction } from "../../../scripts/jones/direct-producers/finite-production.ts";
import {
withFiniteProduction,
type FiniteProductionEvidence,
} from "../../../scripts/jones/direct-producers/finite-production.ts";
import { DEVELOPMENT_ICON_OVERRIDES } from "../../../scripts/lib/brand-assets.ts";
import { findEsmImportsOfExternalPackages } from "../../../scripts/lib/cli-executable-imports.ts";
import rootPackageJson from "../../../package.json" with { type: "json" };
Expand All @@ -26,9 +29,14 @@ const RepoRoot = Effect.service(Path.Path).pipe(
Effect.flatMap((path) => path.fromFileUrl(new URL("../../..", import.meta.url))),
);

const runCommand = Effect.fn("runCommand")(function* (command: ChildProcess.StandardCommand) {
const runCommand = Effect.fn("runCommand")(function* (
command: ChildProcess.StandardCommand,
spawn?: FiniteProductionEvidence["spawn"],
) {
const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
const child = yield* spawner.spawn(command);
const child = yield* spawn
? spawn(() => spawner.spawn(command), command.options.detached === true)
: spawner.spawn(command);
const exitCode = yield* child.exitCode;

if (exitCode !== 0) {
Expand Down Expand Up @@ -82,14 +90,16 @@ const buildCmd = Command.make(
(evidence) =>
Effect.gen(function* () {
yield* Effect.log("[cli] Running tsdown...");
yield* Effect.sync(evidence.commandStarted);
yield* runCommand(
ChildProcess.make(process.execPath, ["--run", "build:bundle"], {
cwd: serverDir,
stdout: config.verbose ? "inherit" : "ignore",
stderr: "inherit",
shell: false,
// oxlint-disable-next-line t3code/no-global-process-runtime -- The actual Node spawner ABI determines detached-session capture, independently of application runtime references.
detached: process.platform !== "win32",
}),
evidence.spawn,
).pipe(
Effect.tap(() => Effect.sync(evidence.leaderExited)),
Effect.tapError((error) =>
Expand Down Expand Up @@ -142,7 +152,6 @@ const buildExeCmd = Command.make(
Effect.gen(function* () {
yield* Effect.log("[cli] Building single-executable...");
const spawnCommand = yield* resolveSpawnCommand("vp", ["pack"]);
yield* Effect.sync(evidence.commandStarted);
yield* runCommand(
ChildProcess.make(spawnCommand.command, spawnCommand.args, {
cwd: serverDir,
Expand All @@ -157,7 +166,10 @@ const buildExeCmd = Command.make(
stdout: config.verbose ? "inherit" : "ignore",
stderr: "inherit",
shell: spawnCommand.shell,
// oxlint-disable-next-line t3code/no-global-process-runtime -- The actual Node spawner ABI determines detached-session capture, independently of application runtime references.
detached: process.platform !== "win32",
}),
evidence.spawn,
).pipe(
Effect.tap(() => Effect.sync(evidence.leaderExited)),
Effect.tapError((error) =>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { it } from "vite-plus/test";
import {
resolutionCases,
capacityCases,
} from "../../../../../scripts/jones/direct-producers/finite-production.testkit.ts";

import * as NodeServices from "@effect/platform-node/NodeServices";
import { it as effectIt, expect } from "@effect/vitest";
import { DEFAULT_SERVER_SETTINGS } from "@t3tools/contracts";
import { resolveWorktreeCleanup } from "@t3tools/shared/projectSettings";
import * as DateTime from "effect/DateTime";
import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";
import * as Path from "effect/Path";
import { fixture, projectId } from "../workspaceLifecycle/ManagedConsumer.testkit.ts";
import { LifecycleRegistry } from "../workspaceLifecycle/RegistryCli.ts";
import { NativeObservations } from "./NativeObservations.ts";
import { beginProduction } from "./ProducerFinalizer.ts";
import { evaluate } from "./Runtime.ts";

it.each(Object.entries({ ...resolutionCases, ...capacityCases }))("%s", (_name, run) => run());

// Configured-runtime oracle only. It uses real private Git/SQLite and never
// launches a provider or grants removal authority; the Node seam does not run it.
effectIt.effect(
"Runtime reconciles only its target and reports exact duties with retirement disabled",
() =>
Effect.scoped(
Effect.gen(function* () {
const f = yield* fixture;
const path = yield* Path.Path;
yield* Effect.gen(function* () {
yield* f.seed;
const worktree = yield* f.fs.realPath(f.linked);
const root = path.join(worktree, "dist");
const session = yield* Effect.promise(() =>
beginProduction(worktree, "fixture-runtime", [root]),
);
const rules = {
...resolveWorktreeCleanup(DEFAULT_SERVER_SETTINGS, projectId),
worktreeSettledAfterDays: null,
};
const result = yield* evaluate({
worktree,
projectRoot: f.repo,
threadId: null,
rules,
cause: "settlement",
execute: false,
admit: Effect.die("Disabled retirement must not acquire removal authority"),
revalidate: Effect.die("Disabled retirement must not remove a checkout"),
});
expect(result.outcome.outputObligations).toContainEqual({
id: session.record.id,
path: root,
owner: session.record.owner,
state: "active",
});
const detail = result.outcome.details.find((entry) =>
entry.lineage.some((lineage) => lineage.productionId === session.record.id),
);
expect(detail?.fact).toContain("status active and outcome unresolved");
expect(detail?.nextAction).toContain("direct-producers/resolve.ts --worktree");
expect(yield* f.fs.exists(f.linked)).toBe(true);
const record = JSON.parse(yield* f.fs.readFileString(session.path));
expect(record.holders.admission_closed).toBe(true);
expect(record.status).toBe("active");
expect(record.finished_at).toBeUndefined();
}).pipe(
Effect.provideService(NativeObservations, {
services: async () => ({
observedAt: DateTime.toEpochMillis(DateTime.nowUnsafe()),
status: "complete",
paths: [],
limits: [],
}),
processes: async () => ({
observedAt: DateTime.toEpochMillis(DateTime.nowUnsafe()),
status: "complete",
paths: [],
limits: [],
}),
workloads: () =>
Effect.succeed({
observedAt: DateTime.toEpochMillis(DateTime.nowUnsafe()),
status: "complete",
paths: [],
limits: [],
}),
temporaryRoots: [],
}),
Effect.provideService(LifecycleRegistry, {
resume: () => Effect.die("No provider or checkout resume"),
show: () => Effect.sync(f.state.view),
outputs: () => Effect.succeed([]),
}),
Effect.provide(f.layer.pipe(Layer.provideMerge(f.configured))),
);
}),
).pipe(Effect.provide(NodeServices.layer)),
);
Loading
Loading