repositories / pi-ext
pi-ext
bugabingas pi extensions
owned by admin
mise.toml
Rawmonorepo_root = true
[monorepo]
config_roots = ["extensions/*"]
[tools]
node = "latest"
go = "latest"
biome = "latest"
"aqua:mikefarah/yq" = "latest"
"aqua:rvben/rumdl" = "latest"
"aqua:tamasfe/taplo" = "latest"
# README demo recordings: asciicast → GIF.
"github:asciinema/agg" = "latest"
"go:golang.org/x/perf/cmd/benchstat" = "latest"
[tasks.default]
description = "List tasks"
run = "mise tasks ls"
[tasks.install]
description = "Install Node dependencies"
run = "npm ci"
sources = ["package.json", "package-lock.json"]
outputs = ["node_modules/vitest/package.json"]
[tasks.lock]
description = "Regenerate package lock; optional package names refresh selected dependencies"
usage = '''
arg "[packages]" var=#true
'''
run = '''
{% if usage.packages %}npm update --package-lock-only{% for package in usage.packages %} "{{ package }}"{% endfor %}{% else %}npm install --package-lock-only{% endif %}
'''
[tasks.codegen]
description = "Write configured generated extension files"
run = "node scripts/codegen.ts"
[tasks.demo]
description = "Record README demos from extensions/<name>/demo/scene.json into assets/demo.{cast,gif}; --assert-only runs the scenes without writing"
depends = ["install"]
usage = '''
arg "[args]" var=#true help="Extension names, or --assert-only; default every extension with a scene"
'''
run = 'node scripts/demo/runner.ts{% if usage.args %}{% for arg in usage.args %} "{{ arg }}"{% endfor %}{% endif %}'
[tasks.demo-check]
description = "Run README demo scenes against the built packages without writing recordings; a failing scene means the demo is stale. Pass extension names to limit the run"
depends = ["build-all"]
usage = '''
arg "[extensions]" var=#true help="Extension names; default every extension with a scene"
'''
run = 'node scripts/demo/runner.ts --assert-only{% if usage.extensions %}{% for arg in usage.extensions %} "{{ arg }}"{% endfor %}{% endif %}'
[tasks.banners]
description = "Write every extension's README banner from its name, pi-ext.logo, and assets/nugu.json"
usage = '''
arg "[args]" var=#true help="Extension directory names, or --check; default all"
'''
run = 'node scripts/readme/banners.ts{% if usage.args %}{% for arg in usage.args %} "{{ arg }}"{% endfor %}{% endif %}'
[tasks.readme-config]
description = "Write generated extension README configuration references"
depends = ["install"]
usage = '''
arg "[extensions]" var=#true help="Extension names; default all"
'''
run = 'node scripts/readme/check.ts --write{% if usage.extensions %}{% for extension in usage.extensions %} "{{ extension }}"{% endfor %}{% endif %}'
[tasks.check-readmes]
description = "Verify extension README structure and generated configuration references"
depends = ["install"]
usage = '''
arg "[extensions]" var=#true help="Extension names; default all"
'''
run = 'node scripts/readme/check.ts{% if usage.extensions %}{% for extension in usage.extensions %} "{{ extension }}"{% endfor %}{% endif %}'
[tasks.readme-test]
description = "Run focused README automation tests"
depends = ["install"]
run = [
"biome check scripts/readme",
{ task = "//:test", args = ["scripts/readme"] },
]
[tasks.fmt]
description = "Format repo"
depends = ["install"]
run = [
"npm run fmt",
"rumdl fmt .",
"taplo format",
]
[tasks.format-files]
description = "Format selected repository TypeScript files without touching unrelated work"
depends = ["install"]
usage = '''
arg "<files>" var=#true
'''
run = '''biome check --write{% for file in usage.files %} "{{ file }}"{% endfor %}'''
[tasks.lint]
description = "Verify formatting and lint"
depends = ["install"]
run = [
"npm run lint",
"taplo format --check",
"node scripts/check_frontmatter.ts",
"node scripts/check_skills.ts",
]
[tasks.test]
description = "Run tests"
tools."aqua:nushell/nushell" = "latest"
depends = ["install"]
usage = '''
arg "[args]" var=#true
'''
run = [
'''npm run test --{% for arg in usage.args %} "{{ arg }}"{% endfor %}''',
{ task = "//:modernize-test" },
]
[tasks.modernize-test]
description = "Test modernize installation discovery and audit evidence"
run = "node --test .pi/skills/modernize/scripts/audit.test.mjs"
[tasks.mutate]
description = "Author-driven Stryker mutation testing (vitest runner, per-extension incremental cache). Never in hooks or CI. Usage: mutate <extension> <file-or-glob under the extension>"
depends = ["install"]
usage = '''
arg "<extension>"
arg "<target>" help="Path under extensions/<extension>/ to mutate (file or glob)"
'''
run = '''
npx stryker run --mutate "extensions/{{ usage.extension }}/{{ usage.target }}" --incrementalFile ".stryker-tmp/incremental-{{ usage.extension }}.json"
'''
[tasks.bump]
description = "Deliberately update npm deps within their ranges and bump mise tool versions, then re-lock. Pass --dry-run to preview."
depends = ["install"]
run = '''
node scripts/bump.ts{% if usage.args %}{% for arg in usage.args %} "{{ arg }}"{% endfor %}{% endif %}
'''
usage = '''
arg "[args]" var=#true
'''
[tasks.fuzz]
description = "Author-driven hostile-input fuzz campaign over a parser (seeded; minimized findings become replay regression tests). Never in hooks or CI. Usage: fuzz <extension> <target>; FUZZ_RUNS overrides the run count."
depends = ["install"]
usage = '''
arg "<extension>"
arg "<target>" help="Fuzz target at extensions/<extension>/__fuzz__/<target>.fuzz.ts"
'''
run = '''
node "extensions/{{ usage.extension }}/__fuzz__/{{ usage.target }}.fuzz.ts"
'''
[tasks.mutate-all]
description = "Full Stryker mutation report across all extensions (author-driven; slow; never in CI)."
depends = ["install"]
run = "npx stryker run --incrementalFile .stryker-tmp/incremental-all.json"
[tasks.snapshot-update]
description = "Explicitly update committed snapshots (normal `test` runs never rewrite them). Pass test paths to narrow."
depends = ["install"]
usage = '''
arg "[args]" var=#true
'''
run = '''
npm run test -- -u{% for arg in usage.args %} "{{ arg }}"{% endfor %}
'''
[tasks.coverage]
description = "Non-gating V8 coverage (chosen over Istanbul: 37s vs 44s on the suite, lower transform overhead, ast-aware line/branch/function) over the deterministic test projects, all owned production files. Pass an extension to scope the report."
depends = ["install"]
usage = '''
arg "[extension]" help="Extension slug to scope coverage to"
'''
run = '''
npm run test -- --project unit --project contract --project isolated-serial --project native{% if usage.extension %} "extensions/{{ usage.extension }}/"{% endif %} --coverage.enabled=true --coverage.all=true{% if usage.extension %} "--coverage.include=extensions/{{ usage.extension }}/**/*.ts"{% endif %}
'''
[tasks.knip]
description = "Report unused files, dependencies, and exports (author-driven; not a gate)"
depends = ["install"]
# Shared extensions/* entry globs cannot match in every extension, so the
# resulting "no matches" hints are structural noise rather than config drift.
run = "npx knip --no-config-hints"
[tasks.context-startup]
description = "Compare stock, configured, and no-Pi-text headless context (three live requests)"
usage = '''
arg "[cwd]" help="Project directory to measure"
'''
run = '''
node scripts/context-startup.ts{% if usage.cwd %} "{{ usage.cwd }}"{% endif %}
'''
[tasks.context-startup-sources]
description = "Estimate APPEND_SYSTEM and skill tokens by source (no measurement prompt)"
run = "node scripts/context-startup-session.ts --sources"
[tasks.context-startup-skill-descriptions]
description = "Rank pi/agent skill descriptions by size and show the largest five"
run = "node scripts/context-startup-session.ts --skill-descriptions"
[tasks.context-extensions]
description = "Inspect runtime extensions and measure leave-one-out input tokens (N+2 live requests)"
usage = '''
arg "[cwd]" help="Project directory to measure"
'''
run = '''
node scripts/context-extensions.ts{% if usage.cwd %} "{{ usage.cwd }}"{% endif %}
'''
[tasks.context-guidance-check]
description = "Read-only live activation check for tool-owned mockup guidance"
depends = ["install"]
env.PI_OFFLINE = "1"
run = '''
pi --print --mode json --no-session --no-extensions --extension extensions/mockup/index.ts --no-context-files --tools read,mockup "Plan an interactive 80-column terminal task-list mockup with keyboard selection. Planning only: do not create or edit files, execute commands, call mockup, or open a browser. Load the applicable authoring guidance using read only, then explain the document boundary and target-platform constraints." | node --input-type=module -e "
import { createInterface } from 'node:readline';
import { basename, dirname } from 'node:path';
const missing = new Set(['mockup-html']);
const calls = new Map();
let completed = false;
for await (const line of createInterface({ input: process.stdin })) {
const event = JSON.parse(line);
if (event.type === 'tool_execution_start') {
if (event.toolName !== 'read') throw new Error('Unexpected tool: ' + event.toolName);
console.log('read ' + event.args.path);
if (basename(event.args.path) === 'SKILL.md') calls.set(event.toolCallId, basename(dirname(event.args.path)));
}
if (event.type === 'tool_execution_end' && !event.isError) missing.delete(calls.get(event.toolCallId));
if (event.type === 'message_end' && event.message.role === 'assistant' && event.message.stopReason === 'stop') {
completed = true;
console.log(event.message.content.filter(part => part.type === 'text').map(part => part.text).join('\n'));
}
}
if (missing.size || !completed) throw new Error('Incomplete guidance check: ' + [...missing].join(', '));
console.log('PASS: mockup guidance read; only read tools used; turn completed.');
"
'''
[tasks.context-startup-test]
description = "Check the startup context measurement script"
depends = ["install"]
run = [
"biome check scripts/context-startup.ts scripts/context-startup-session.ts scripts/context-startup.test.ts scripts/context-extensions.ts scripts/context-extensions.test.ts",
"rumdl check scripts/context-startup.md",
"taplo format --check mise.toml",
{ task = "//:test", args = [
"scripts/context-startup.test.ts",
"scripts/context-extensions.test.ts",
] },
]
[tasks.context-startup-fmt]
description = "Format context measurement files only"
depends = ["install"]
run = [
"biome check --write scripts/context-startup.ts scripts/context-startup-session.ts scripts/context-startup.test.ts scripts/context-extensions.ts scripts/context-extensions.test.ts",
"rumdl fmt scripts/context-startup.md",
"taplo format mise.toml",
]
[tasks.bench]
description = "Run all extension benchmarks sequentially"
depends = ["install"]
run = "mise run --jobs 1 //extensions/...:bench"
[tasks.modernize-bench]
description = "Benchmark modernize audit"
tools.hyperfine = "latest"
usage = '''
arg "[args]" var=#true
'''
run = '''
node .pi/skills/modernize/scripts/audit.bench.mjs{% for arg in usage.args %} "{{ arg }}"{% endfor %}
'''
[tasks.extension-startup-bench]
description = "Benchmark configured extension startup to RPC readiness"
depends = ["install"]
run = "node scripts/extension-startup.bench.ts"
[tasks.debug-bench]
description = "Benchmark the generated debug writer at startup and per record"
depends = ["install"]
usage = '''
arg "[template]" help="Template copy to measure, defaults to the current template"
'''
run = 'node scripts/codegen/pi-ext-debug.bench.ts{% if usage.template %} "{{ usage.template }}"{% endif %}'
[tasks.extension-startup-benchstat]
description = "Compare extension startup benchmark results"
depends = ["install"]
usage = '''
arg "<baseline>"
arg "<candidate>"
'''
run = 'benchstat "{{ usage.baseline }}" "{{ usage.candidate }}"'
[tasks.e2e]
description = "Run local E2E in disposable OS temp (PI_EXT_E2E_FILTER=<extension> for one suite; real S3: //extensions/bak:e2e-s3)"
depends = ["install"]
run = "node scripts/e2e.ts //extensions/chrome-cdp:e2e //extensions/klaus:e2e //extensions/mockup:e2e //extensions/strata:e2e //extensions/the-system:e2e"
[tasks.e2e-extension]
description = "Run one extension acceptance suite with isolated browser provisioning in OS temp"
depends = ["install"]
usage = '''
arg "<extension>"
'''
run = 'node scripts/e2e.ts "//extensions/{{ usage.extension }}:e2e"'
[tasks.build-ext]
description = "Build selected extension packages into dist/<name> (--release for the release variant)"
depends = ["install"]
usage = '''
arg "<extensions>" var=#true
flag "--release" help="Minified release variant without sourcemaps"
'''
run = '''
node --no-warnings scripts/build/cli.ts{% if usage.release %} --release{% endif %}{% for extension in usage.extensions %} "{{ extension }}"{% endfor %}
'''
[tasks.build-all]
description = "Build every extension package into dist/ (--release for the release variant)"
depends = ["install"]
usage = '''
flag "--release" help="Minified release variant without sourcemaps"
'''
run = '''
node --no-warnings scripts/build/cli.ts --all{% if usage.release %} --release{% endif %}
'''
[tasks.settings-entries]
description = "Print the explicit dist/<name> package list for ~/.pi/agent/settings.json packages"
run = "node --no-warnings scripts/build/settings-entries.ts"
[tasks.verify-packages]
description = "Build release packages and verify relocated collection against minimum Pi or PI_EXT_MATRIX_PI"
depends = ["install"]
env = { PI_EXT_VERIFY_PACKAGES = "1" }
run = [
"node --no-warnings scripts/build/cli.ts --all --release",
"npm run test -- --project packages",
]
[tasks.build]
description = "Typecheck and statically validate extensions"
depends = ["install"]
usage = '''
arg "[extensions]" var=#true
'''
run = [
"npm run typecheck",
'''node scripts/extensions.ts check{% for extension in usage.extensions %} "{{ extension }}"{% endfor %}''',
]
[tasks.check]
description = "Typecheck and run static extension checks"
depends = ["install"]
run = [
"npm run typecheck",
"node scripts/check_skills.ts",
"node scripts/test_extensions_static_check.ts",
"node scripts/extensions.ts check",
"node scripts/compatibility.ts",
"node scripts/readme/banners.ts --check",
{ task = "//:check-readmes" },
]
[tasks.release-all]
description = "Build and validate all release packages and exact archives"
depends = ["install"]
run = "node --no-warnings scripts/build/release.ts"
[tasks.ci]
description = "Release gate"
run = [
{ tasks = ["check", "lint"] },
{ task = "test" },
{ task = "e2e" },
{ task = "demo-check" },
{ task = "release-all" },
{ task = "verify-packages" },
]
[tasks.list]
description = "List extensions"
usage = '''
arg "[extensions]" var=#true
'''
run = '''
node scripts/extensions.ts list{% for extension in usage.extensions %} "{{ extension }}"{% endfor %}
'''
[tasks.changelog]
description = "Generate changelog"
usage = '''
arg "<extensions>" var=#true
'''
run = '''
node scripts/extensions.ts changelog{% for extension in usage.extensions %} "{{ extension }}"{% endfor %}
'''
[tasks.readme]
description = "Generate/update READMEs"
usage = '''
arg "[extensions]" var=#true
flag "--model <model>"
'''
run = '''
node scripts/extensions.ts readme --write{% if usage.model %} --model "{{ usage.model }}"{% endif %}{% for extension in usage.extensions %} "{{ extension }}"{% endfor %}
'''
[tasks.release-snapshot]
description = "Snapshot explicitly selected eligible release packages"
depends = ["install"]
usage = '''
arg "<extensions>" var=#true
'''
run = '''
npm run release:snapshot --{% for extension in usage.extensions %} "{{ extension }}"{% endfor %}
'''
[tasks.release-plan]
description = "Validate explicitly selected release eligibility"
usage = '''
arg "<extensions>" var=#true
'''
run = '''
npm run release:snapshot --{% for extension in usage.extensions %} "{{ extension }}"{% endfor %}
'''
[tasks.release-prepare]
description = "Create verified snapshots for explicitly selected extensions after their README demos still pass"
usage = '''
arg "<extensions>" var=#true
'''
run = [
'''node scripts/demo/runner.ts --assert-only{% for extension in usage.extensions %} "{{ extension }}"{% endfor %}''',
'''npm run release:snapshot --{% for extension in usage.extensions %} "{{ extension }}"{% endfor %}''',
]
[tasks.clean]
description = "Remove generated caches and scratch artifacts"
run = '''
find . -path ./.git -prune -o -path ./.jj -prune -o -type d -name node_modules -prune -exec rm -rf {} +
'''
[tasks.publish]
description = "Create local Git delivery from selected verified snapshots; --push is required for remote delivery"
depends = ["install"]
usage = '''
arg "<extensions>" var=#true
flag "--push" help="Push temporary distribution repositories to declared remotes"
'''
run = '''
npm run release:publish --{% if usage.push %} --push{% endif %}{% for extension in usage.extensions %} "{{ extension }}"{% endfor %}
'''
[tasks.pre-commit]
description = "Pre-commit hook: changed-scope check + lint (repository-wide when shared files are staged)"
run = "node scripts/scope.ts"
[tasks.pre-push]
description = "Pre-push hook: check + lint"
run = [{ tasks = ["check", "lint"] }]