diff --git a/.gitignore b/.gitignore index 40b010c..5c367c8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .worktrees/ node_modules/ +.pi/ diff --git a/README.md b/README.md index 9715fde..d8f5673 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,17 @@ ## Install -Use it as a local package root today: +Local path: ```bash pi install /absolute/path/to/subagents ``` -After this folder is moved into its own repository, the same package can be installed from git. +Git: + +```bash +pi install https://gitea.rwiesner.com/pi/pi-subagents +``` ## Resources diff --git a/package.json b/package.json index 6282b51..c434435 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,13 @@ { "name": "pi-subagents", "version": "0.1.0", + "description": "Pi extension package that runs subagent tasks in separate child sessions and ships the prompts and wrapper code needed to execute those runs.", "type": "module", "keywords": ["pi-package"], + "repository": { + "type": "git", + "url": "https://gitea.rwiesner.com/pi/pi-subagents" + }, "scripts": { "test": "tsx --test src/*.test.ts src/**/*.test.ts" }, diff --git a/src/.npmignore b/src/.npmignore new file mode 100644 index 0000000..8c1ce17 --- /dev/null +++ b/src/.npmignore @@ -0,0 +1,2 @@ +*.test.ts +**/*.test.ts diff --git a/src/package-manifest.test.ts b/src/package-manifest.test.ts index d5f6238..60683ac 100644 --- a/src/package-manifest.test.ts +++ b/src/package-manifest.test.ts @@ -1,5 +1,6 @@ import test from "node:test"; import assert from "node:assert/strict"; +import { execFileSync } from "node:child_process"; import { existsSync, readFileSync } from "node:fs"; import { dirname, resolve } from "node:path"; import { fileURLToPath } from "node:url"; @@ -7,6 +8,17 @@ import { fileURLToPath } from "node:url"; const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), ".."); const pkg = JSON.parse(readFileSync(resolve(packageRoot, "package.json"), "utf8")); +function getPackedPaths() { + const output = execFileSync("npm", ["pack", "--dry-run", "--json"], { + cwd: packageRoot, + encoding: "utf8", + stdio: ["ignore", "pipe", "pipe"], + timeout: 30_000, + }); + const [packResult] = JSON.parse(output) as Array<{ files: Array<{ path: string }> }>; + return packResult.files.map((file) => file.path); +} + test("package.json exposes pi-subagents as a standalone pi package", () => { assert.equal(pkg.name, "pi-subagents"); assert.equal(pkg.type, "module"); @@ -31,3 +43,21 @@ test("package.json exposes pi-subagents as a standalone pi package", () => { assert.ok(existsSync(resolve(packageRoot, "prompts/implement-and-review.md"))); assert.ok(existsSync(resolve(packageRoot, "prompts/scout-and-plan.md"))); }); + +test("README documents local install, git install, and tmux PATH requirement", () => { + const readme = readFileSync(resolve(packageRoot, "README.md"), "utf8"); + assert.match(readme, /pi install \/absolute\/path\/to\/subagents/); + assert.match(readme, /pi install https:\/\/gitea\.rwiesner\.com\/pi\/pi-subagents/); + assert.match(readme, /tmux.*PATH/i); +}); + +test("npm pack includes runtime package assets", () => { + const packedPaths = getPackedPaths(); + + assert.ok(packedPaths.includes("index.ts")); + assert.ok(packedPaths.includes("prompts/implement.md")); + assert.ok(packedPaths.includes("prompts/implement-and-review.md")); + assert.ok(packedPaths.includes("prompts/scout-and-plan.md")); + assert.ok(packedPaths.includes("src/wrapper/cli.mjs")); + assert.deepEqual(packedPaths.filter((p) => p.endsWith(".test.ts")), []); +});