diff --git a/bun.lock b/bun.lock index d5d5a5919..ada25e048 100644 --- a/bun.lock +++ b/bun.lock @@ -61,7 +61,7 @@ "name": "@oh-my-pi/pi-coding-agent", "version": "15.10.10", "bin": { - "omp": "dist/cli.js", + "omp": "src/cli.ts", }, "dependencies": { "@agentclientprotocol/sdk": "catalog:", diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index 508cdb9a5..4f9e2e5c8 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -6,7 +6,7 @@ - Added `streamIdleTimeoutMs`, `supportsLongPromptCacheRetention`, `requiresToolResultId`, and `replayUnsignedThinking` to the OpenAI `compat` schema so custom model entries can configure those provider-specific capabilities - New `omp usage` command: a detailed per-account breakdown of provider usage limits (bars, windows, reset times, plan metadata) covering every stored credential — accounts with no usage endpoint are listed as "no usage data" rows. Each provider section ends with per-window capacity stats ("capacity: 5h → 2.40/5 accounts used (2.60× quota left)"). Flags: `--provider` to filter, `--json` for the broker-shaped report payload, and `--redact` to mask account emails/ids down to a two-char anchor plus a minimal middle-out differentiator (`ca*9*`) for screenshot-safe sharing. - Startup hangs are now self-diagnosing (speculative fix for the "zero output, hangs even on `omp -h`" report class): a watchdog prints a stderr line every 10s naming the deepest in-flight startup phase (via `logger.openSpanPath()`) until a mode runner takes over, pausing around legitimate interactive waits (fork/move prompts, the `--resume` session picker); `PI_DEBUG_STARTUP` is restored as streaming synchronous `[startup]` phase markers covering command-module imports and the native addon load, which the post-startup `PI_TIMING` tree structurally cannot show for a hang; and waiting on piped-stdin EOF announces itself after 1s instead of blocking silently. -- npm installs now execute a prebundled single-file entry: `bin.omp` points at `dist/cli.js` (built by `scripts/bundle-dist.ts` during `prepack`, ~18MB minified, natives/transformers/mupdf external), cutting npm-install cold start by roughly 3x versus transpiling the raw TypeScript graph per launch; `src/**` stays published for SDK consumers and worker fallbacks +- npm installs now execute a prebundled single-file entry: the published `bin.omp` points at `dist/cli.js` (built by `scripts/bundle-dist.ts` during `prepack`, ~18MB minified, natives/transformers/mupdf external), cutting npm-install cold start by roughly 3x versus transpiling the raw TypeScript graph per launch; `src/**` stays published for SDK consumers and worker fallbacks. The on-repo manifest keeps `bin.omp` at `src/cli.ts` — release rewrites it via the `publishBin` override in `scripts/ci-release-publish.ts` — so source installs (`bun link`, `install.sh --source`) keep working without a build step - Plain interactive TTY launches print a dim two-line startup splash (`omp ` / `Initializing session…`) before session construction so first pixels appear immediately; suppressed for resume/fork/continue flows, quiet mode, `PI_TIMING`, and non-TTY stdio - Added `/stats` to launch the local stats dashboard from an active session, syncing session files first and opening the same browser dashboard as `omp stats`. - `/settings` now supports type-to-search filtering on setting labels, paths, descriptions, and values; Escape clears an active search before closing the panel. diff --git a/packages/coding-agent/package.json b/packages/coding-agent/package.json index aaa3f8b5c..75af8b617 100644 --- a/packages/coding-agent/package.json +++ b/packages/coding-agent/package.json @@ -28,7 +28,7 @@ "main": "./src/index.ts", "types": "./src/index.ts", "bin": { - "omp": "dist/cli.js" + "omp": "src/cli.ts" }, "scripts": { "build": "bun scripts/build-binary.ts", diff --git a/scripts/ci-release-publish.ts b/scripts/ci-release-publish.ts index 3e983d904..b5b9af951 100644 --- a/scripts/ci-release-publish.ts +++ b/scripts/ci-release-publish.ts @@ -11,10 +11,12 @@ * 1. Emit `.d.ts` declarations into `dist/types/` so consumers get * stable types regardless of their tsconfig `lib`. * 2. Rewrite `package.json` in place — every `types`/`exports[*].types` - * that points at `./src/*.ts(x)` is repointed to `./dist/types/*.d.ts` - * and `dist/types` (plus `dist/client` for `stats`) is added to - * `files`. The on-repo manifest keeps pointing at source so local - * dev resolves types without any build. + * that points at `./src/*.ts(x)` is repointed to `./dist/types/*.d.ts`, + * `dist/types` (plus `dist/client` for `stats`) is added to `files`, + * and packages with a `publishBin` override get their `bin` swapped to + * the prepack bundle (coding-agent: `src/cli.ts` → `dist/cli.js`). The + * on-repo manifest keeps pointing at source so local dev and source + * installs (`bun link`, `install.sh --source`) work without a build. * 3. Pack with `bun pm pack` (resolves the `catalog:`/`workspace:` * protocols npm cannot, and runs each package's `prepack` lifecycle), * then publish the resolved tarball with `npm publish` — see @@ -43,6 +45,12 @@ export interface PublishPackage { extraFiles?: readonly string[]; /** Extra tsgo invocations beyond `tsconfig.publish.json`. */ extraTypeConfigs?: readonly string[]; + /** + * `bin` map for the published manifest. The on-repo manifest points `bin` + * at TS source so source installs (`bun link`, `install.sh --source`) work + * without a build; publish swaps in the `prepack` bundle. + */ + publishBin?: Readonly>; } type JsonValue = string | number | boolean | null | JsonObject | JsonValue[]; @@ -91,7 +99,7 @@ export const packages: PublishPackage[] = [ extraTypeConfigs: ["tsconfig.publish.client.json"], }, { dir: "packages/agent", kind: "typescript" }, - { dir: "packages/coding-agent", kind: "typescript" }, + { dir: "packages/coding-agent", kind: "typescript", publishBin: { omp: "dist/cli.js" } }, ]; function rewriteSrcPath(value: string): string { @@ -123,9 +131,10 @@ function rewriteExports(exports: JsonValue): JsonValue { return out; } -async function rewriteManifest(pkgDir: string, extraFiles: readonly string[], write: boolean): Promise { - const manifestPath = path.join(pkgDir, "package.json"); +async function rewriteManifest(pkg: PublishPackage, write: boolean): Promise { + const manifestPath = path.join(repoRoot, pkg.dir, "package.json"); const manifest = (await Bun.file(manifestPath).json()) as PackageManifest; + if (pkg.publishBin) manifest.bin = { ...pkg.publishBin }; if (typeof manifest.types === "string" && manifest.types.startsWith("./src/")) { manifest.types = rewriteSrcPath(manifest.types); } @@ -133,7 +142,7 @@ async function rewriteManifest(pkgDir: string, extraFiles: readonly string[], wr const files = Array.isArray(manifest.files) ? [...manifest.files] : []; const hasDist = files.includes("dist"); if (!hasDist && !files.includes("dist/types")) files.push("dist/types"); - for (const extra of extraFiles) { + for (const extra of pkg.extraFiles ?? []) { if (!hasDist && !files.includes(extra)) files.push(extra); } manifest.files = files; @@ -150,7 +159,23 @@ async function preparePackage(pkg: PublishPackage): Promise { for (const cfg of pkg.extraTypeConfigs ?? []) { await $`bun x tsgo -p ${cfg}`.cwd(pkgDir); } - return rewriteManifest(pkgDir, pkg.extraFiles ?? [], !isDryRun); + return rewriteManifest(pkg, !isDryRun); +} + +/** + * Apply only the published `bin` rewrite to a package's working-tree + * manifest. Used by `scripts/install-tests/run-ci.sh` to pack the coding + * agent with its published topology (bin → prepack bundle) without running + * the type-emission steps; the caller backs up and restores the manifest. + */ +export async function applyPublishBin(pkgRelDir: string, write: boolean): Promise { + const pkg = packages.find(entry => entry.dir === pkgRelDir); + if (!pkg?.publishBin) throw new Error(`No publishBin override declared for ${pkgRelDir}`); + const manifestPath = path.join(repoRoot, pkgRelDir, "package.json"); + const manifest = (await Bun.file(manifestPath).json()) as PackageManifest; + manifest.bin = { ...pkg.publishBin }; + if (write) await Bun.write(manifestPath, `${JSON.stringify(manifest, null, "\t")}\n`); + return manifest; } function buildNativeOptionalDependencies(version: string): JsonObject { diff --git a/scripts/install-tests/run-ci.sh b/scripts/install-tests/run-ci.sh index 0d5114a97..a27736e69 100755 --- a/scripts/install-tests/run-ci.sh +++ b/scripts/install-tests/run-ci.sh @@ -93,14 +93,31 @@ core_rc=0 cp "$natives_pkg_backup" "$ROOT_DIR/packages/natives/package.json" [ "$core_rc" -eq 0 ] || exit "$core_rc" -# 3. Pack the remaining workspace packages (natives core handled above). -for pkg in utils hashline catalog ai mnemopi agent tui stats coding-agent; do +# 3. Pack the remaining workspace packages (natives core and coding-agent +# handled separately). +for pkg in utils hashline catalog ai mnemopi agent tui stats; do ( cd "$ROOT_DIR/packages/$pkg" bun pm pack --destination "$TARBALL_DIR" --quiet >/dev/null ) done +# 4. Pack the coding agent with its *published* manifest: release swaps +# `bin.omp` from `src/cli.ts` to the prepack bundle `dist/cli.js`. The repo +# manifest keeps pointing at source so `bun link`/`install.sh --source` +# work without a build, so the swap must be reproduced here for the smoke +# to exercise the bundled worker-host entry the published package ships. +# Always restore the working-tree manifest. +agent_pkg_backup="$WORK_DIR/coding-agent-package.json.orig" +cp "$ROOT_DIR/packages/coding-agent/package.json" "$agent_pkg_backup" +agent_rc=0 +{ + bun -e 'import { applyPublishBin } from "./scripts/ci-release-publish.ts"; await applyPublishBin("packages/coding-agent", true);' && + (cd "$ROOT_DIR/packages/coding-agent" && bun pm pack --destination "$TARBALL_DIR" --quiet >/dev/null) +} || agent_rc=$? +cp "$agent_pkg_backup" "$ROOT_DIR/packages/coding-agent/package.json" +[ "$agent_rc" -eq 0 ] || exit "$agent_rc" + utils_tgz="$(find_tarball "$TARBALL_DIR"/oh-my-pi-pi-utils-*.tgz)" natives_tgz="$(find_tarball "$TARBALL_DIR"/oh-my-pi-pi-natives-[0-9]*.tgz)" natives_leaf_tgz="$(find_tarball "$TARBALL_DIR"/oh-my-pi-pi-natives-"$host_tag"-*.tgz)"