{"_id":"@boozedog/pi-codemode","_rev":"7-2a2fc2d437a1c6847cce8e28b6f16876","name":"@boozedog/pi-codemode","dist-tags":{"latest":"0.5.1"},"versions":{"0.1.4":{"name":"@boozedog/pi-codemode","version":"0.1.4","keywords":["codemode","pi-extension","pi-package","sandbox","typescript"],"author":{"name":"Mario Zechner and contributors"},"license":"MIT","_id":"@boozedog/pi-codemode@0.1.4","maintainers":[{"name":"boozedog","email":"npmjs@boozedog.com"}],"homepage":"https://github.com/boozedog/pi-codemode#readme","bugs":{"url":"https://github.com/boozedog/pi-codemode/issues"},"pi":{"extensions":["./dist/index.js"]},"dist":{"shasum":"c44ba68077ef4cca5df89c2955082b331b62ec28","tarball":"https://registry.npmjs.org/@boozedog/pi-codemode/-/pi-codemode-0.1.4.tgz","fileCount":176,"integrity":"sha512-bDf4wehPkFhBtYQ2IluhsW26YApmifEVRe/lLTdQ+YKhOUpEdNMJ4plogWoWoAkJdgYIeVn+iGTsQp4jDMeAnQ==","signatures":[{"sig":"MEUCIQDeJchW2GGyKTzqV9uUEBM8UFuo0ZhwEfavVsvr8qYIEQIgWC101baguJFQ0y4Yjw8WECZyqbHfLcFboDVhAU9kjT4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":978233},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":"./dist/index.js"},"gitHead":"e838523229e3a68e015c5a22272d6272d489a917","scripts":{"dev":"tsc --watch","lint":"oxlint --deny warnings --vitest-plugin src","test":"vitest run","build":"tsc","check":"npm run format:check && npm run lint && npm run build && npm test","format":"oxfmt . --write","prepack":"npm run build","prepare":"npm run build","release":"./scripts/release.sh","publish:npm":"npm run check && npm run check:clean-tree && npm pack --dry-run && npm publish --access public","publish:tag":"npm run check && npm run check:clean-tree && npm pack --dry-run && git tag v$npm_package_version && git push origin v$npm_package_version","format:check":"oxfmt . --check","check:clean-tree":"git diff --quiet && git diff --cached --quiet || (echo \"Working tree is dirty; commit or stash changes before publishing.\" && git status --short && exit 1)"},"_npmUser":{"name":"boozedog","email":"npmjs@boozedog.com"},"repository":{"url":"git+ssh://git@github.com/boozedog/pi-codemode.git","type":"git"},"_npmVersion":"11.12.1","description":"Pi Codemode plugin - TypeScript code execution with sandboxed tools, just-bash shell, and MCP integration","directories":{},"_nodeVersion":"25.9.0","dependencies":{"just-bash":"3.0.0","minisearch":"^7.2.0","typescript":"^6.0.3","pi-mcp-adapter":"2.5.4","quickjs-emscripten":"^0.32.0"},"_hasShrinkwrap":false,"devDependencies":{"oxfmt":"^0.48.0","oxlint":"^1.63.0","vitest":"^4.1.5","@types/node":"^22.19.17","@types/json-schema":"^7.0.15","@mariozechner/pi-tui":"^0.73.1"},"peerDependencies":{"@mariozechner/pi-tui":"*","@mariozechner/pi-agent-core":"*","@mariozechner/pi-coding-agent":"*"},"_npmOperationalInternal":{"tmp":"tmp/pi-codemode_0.1.4_1778927497408_0.3499714784480139","host":"s3://npm-registry-packages-npm-production"}},"0.1.8":{"name":"@boozedog/pi-codemode","version":"0.1.8","keywords":["codemode","pi-extension","pi-package","sandbox","typescript"],"author":{"name":"Mario Zechner and contributors"},"license":"MIT","_id":"@boozedog/pi-codemode@0.1.8","maintainers":[{"name":"boozedog","email":"npmjs@boozedog.com"}],"homepage":"https://github.com/boozedog/pi-codemode#readme","bugs":{"url":"https://github.com/boozedog/pi-codemode/issues"},"pi":{"extensions":["./dist/index.js"]},"dist":{"shasum":"56c7e4c41f7fa51c6f23b3e168cf1e001e063a1a","tarball":"https://registry.npmjs.org/@boozedog/pi-codemode/-/pi-codemode-0.1.8.tgz","fileCount":176,"integrity":"sha512-HuQ499f+gyCU3l4h8Ddj7lbEmWcEIuTfJpuoT0zliQ0hL0nK/kO5rq4oe+UslozcVLAzhBg/JNgaf+aZhQLwlg==","signatures":[{"sig":"MEQCIFchMef5lq3LUvUHMg8QERsRZP0VXcqfhEAJow91gXwuAiBqt/zCEfskvP2ROJsyI0UAJffXve3XJyWPAOvs4SszNQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":995133},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":"./dist/index.js"},"gitHead":"5ee7fa2e8e7bff514fa2d8f9c449a39028f6dcac","scripts":{"dev":"tsc --watch","lint":"oxlint --deny warnings --vitest-plugin src","test":"vitest run","build":"tsc","check":"npm run format:check && npm run lint && npm run build && npm test","format":"oxfmt . --write","prepack":"npm run build","prepare":"npm run build","release":"./scripts/release.sh","publish:npm":"npm run check && npm run check:clean-tree && npm pack --dry-run && npm publish --access public","publish:tag":"npm run check && npm run check:clean-tree && npm pack --dry-run && git tag v$npm_package_version && git push origin v$npm_package_version","format:check":"oxfmt . --check","check:clean-tree":"git diff --quiet && git diff --cached --quiet || (echo \"Working tree is dirty; commit or stash changes before publishing.\" && git status --short && exit 1)"},"_npmUser":{"name":"boozedog","email":"npmjs@boozedog.com"},"repository":{"url":"git+ssh://git@github.com/boozedog/pi-codemode.git","type":"git"},"_npmVersion":"11.16.0","description":"Pi Codemode plugin - TypeScript code execution with sandboxed tools, just-bash shell, and MCP integration","directories":{},"_nodeVersion":"24.18.0","dependencies":{"just-bash":"3.0.0","minisearch":"^7.2.0","typescript":"^6.0.3","pi-mcp-adapter":"2.5.4","quickjs-emscripten-core":"^0.32.0","@jitl/quickjs-singlefile-mjs-release-sync":"^0.32.0"},"_hasShrinkwrap":false,"devDependencies":{"oxfmt":"^0.48.0","oxlint":"^1.63.0","vitest":"^4.1.5","@types/node":"^22.19.17","@types/json-schema":"^7.0.15","@mariozechner/pi-tui":"^0.73.1"},"peerDependencies":{"@mariozechner/pi-tui":"*","@mariozechner/pi-agent-core":"*","@mariozechner/pi-coding-agent":"*"},"_npmOperationalInternal":{"tmp":"tmp/pi-codemode_0.1.8_1785338678676_0.07465630939191548","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@boozedog/pi-codemode","version":"0.2.0","keywords":["codemode","pi-extension","pi-package","sandbox","typescript"],"author":{"name":"boozedog"},"license":"MIT","_id":"@boozedog/pi-codemode@0.2.0","maintainers":[{"name":"boozedog","email":"npmjs@boozedog.com"}],"contributors":[{"url":"original Pi / codemode patterns","name":"Mario Zechner"},{"name":"boozedog and contributors"}],"homepage":"https://github.com/boozedog/pi-codemode#readme","bugs":{"url":"https://github.com/boozedog/pi-codemode/issues"},"pi":{"extensions":["./dist/index.js"]},"dist":{"shasum":"42f8b73c769f8997b76e28ab7290c276f1682245","tarball":"https://registry.npmjs.org/@boozedog/pi-codemode/-/pi-codemode-0.2.0.tgz","fileCount":147,"integrity":"sha512-jM4uJPgpFk+2TqhN+/6b1ds+PuMUPUG8OFhTXrl8HPjKSzTE3wBuOmvJTd/q7k5+0LtrcSZzdK9GCMlB+xlX0A==","signatures":[{"sig":"MEUCIQDnaWfhdFzlYMvIDogGTfCyit+UibRCAbr96QoqLMYsOQIgT9L8DI4LRruLshLws/AWPloIqxQhcsobTe9eQ3NPga4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":711904},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":"./dist/index.js"},"gitHead":"5ee526841a63c0d79c6bbef3ca2e90b6c52af2d1","scripts":{"dev":"tsc --watch","lint":"oxlint --deny warnings --vitest-plugin src","test":"vitest run","build":"tsc","check":"npm run format:check && npm run lint && npm run build && npm test","format":"oxfmt . --write","prepack":"npm run build","prepare":"node ./scripts/prepare.mjs","release":"./scripts/release.sh","publish:npm":"npm run check && npm run check:clean-tree && npm pack --dry-run && npm publish --access public","publish:tag":"npm run check && npm run check:clean-tree && npm pack --dry-run && git tag v$npm_package_version && git push origin v$npm_package_version","format:check":"oxfmt . --check","check:clean-tree":"git diff --quiet && git diff --cached --quiet || (echo \"Working tree is dirty; commit or stash changes before publishing.\" && git status --short && exit 1)"},"_npmUser":{"name":"boozedog","email":"npmjs@boozedog.com"},"repository":{"url":"git+ssh://git@github.com/boozedog/pi-codemode.git","type":"git"},"_npmVersion":"11.16.0","description":"Pi Codemode plugin - TypeScript code execution with sandboxed tools, typed host CLI, and MCP integration","directories":{},"_nodeVersion":"24.18.1","dependencies":{"minisearch":"^7.2.0","typescript":"^6.0.3","pi-mcp-adapter":"2.5.4","quickjs-emscripten-core":"^0.32.0","@jitl/quickjs-singlefile-mjs-release-sync":"^0.32.0"},"_hasShrinkwrap":false,"devDependencies":{"oxfmt":"^0.48.0","oxlint":"^1.63.0","vitest":"^4.1.5","@types/node":"^22.19.17","@types/json-schema":"^7.0.15","@mariozechner/pi-tui":"^0.73.1"},"peerDependencies":{"@mariozechner/pi-tui":"*","@mariozechner/pi-agent-core":"*","@mariozechner/pi-coding-agent":"*"},"_npmOperationalInternal":{"tmp":"tmp/pi-codemode_0.2.0_1786363584551_0.4088115256463365","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@boozedog/pi-codemode","version":"0.3.0","keywords":["codemode","pi-extension","pi-package","sandbox","typescript"],"author":{"name":"boozedog"},"license":"MIT","_id":"@boozedog/pi-codemode@0.3.0","maintainers":[{"name":"boozedog","email":"npmjs@boozedog.com"}],"contributors":[{"url":"original Pi / codemode patterns","name":"Mario Zechner"},{"name":"boozedog and contributors"}],"homepage":"https://github.com/boozedog/pi-codemode#readme","bugs":{"url":"https://github.com/boozedog/pi-codemode/issues"},"pi":{"extensions":["./dist/index.js"]},"dist":{"shasum":"1e97114a557ac61adfade626e2fabe4baef9e067","tarball":"https://registry.npmjs.org/@boozedog/pi-codemode/-/pi-codemode-0.3.0.tgz","fileCount":147,"integrity":"sha512-eZtUX4Ra3HS1c5BP24rar2cvrGLwX4unM50xW5E4wizbhpJgzcqwJEQxTfeXUnXp6YUSVMe5apThTbZu98etrA==","signatures":[{"sig":"MEQCIEmz5syPgNexr1XRg8I244XxyL3hLgcgp6SBZVaUvB4mAiAG3KEa6cIPXF35v23p9m+WqmZ9xWnC307KFyu9x98oVw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":764258},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":"./dist/index.js"},"gitHead":"1390c938ef4f23a0d50b814e7e3a14c03a08d39d","scripts":{"dev":"tsc --watch","lint":"oxlint --deny warnings --vitest-plugin src","test":"vitest run","build":"tsc","check":"npm run format:check && npm run lint && npm run build && npm test","format":"oxfmt . --write","prepack":"npm run build","prepare":"node ./scripts/prepare.mjs","release":"./scripts/release.sh","publish:npm":"npm run check && npm run check:clean-tree && npm pack --dry-run && npm publish --access public","publish:tag":"npm run check && npm run check:clean-tree && npm pack --dry-run && git tag v$npm_package_version && git push origin v$npm_package_version","format:check":"oxfmt . --check","check:clean-tree":"git diff --quiet && git diff --cached --quiet || (echo \"Working tree is dirty; commit or stash changes before publishing.\" && git status --short && exit 1)"},"_npmUser":{"name":"boozedog","email":"npmjs@boozedog.com"},"repository":{"url":"git+ssh://git@github.com/boozedog/pi-codemode.git","type":"git"},"_npmVersion":"11.16.0","description":"Pi Codemode plugin - TypeScript code execution with sandboxed tools, typed host CLI, and MCP integration","directories":{},"_nodeVersion":"24.18.1","dependencies":{"ajv":"^8.20.0","minisearch":"^7.2.0","typescript":"^6.0.3","pi-mcp-adapter":"2.5.4","quickjs-emscripten-core":"^0.32.0","@jitl/quickjs-singlefile-mjs-release-sync":"^0.32.0"},"_hasShrinkwrap":false,"devDependencies":{"oxfmt":"^0.48.0","oxlint":"^1.63.0","vitest":"^4.1.5","@types/node":"^22.19.17","@types/json-schema":"^7.0.15","@mariozechner/pi-tui":"^0.73.1"},"peerDependencies":{"@mariozechner/pi-tui":"^0.73.1","@mariozechner/pi-agent-core":"^0.73.1","@mariozechner/pi-coding-agent":"^0.73.1"},"_npmOperationalInternal":{"tmp":"tmp/pi-codemode_0.3.0_1786482978286_0.37172239669137364","host":"s3://npm-registry-packages-npm-production"}},"0.4.4":{"name":"@boozedog/pi-codemode","version":"0.4.4","keywords":["codemode","pi-extension","pi-package","sandbox","typescript"],"author":{"name":"boozedog"},"license":"MIT","_id":"@boozedog/pi-codemode@0.4.4","maintainers":[{"name":"boozedog","email":"npmjs@boozedog.com"}],"contributors":[{"url":"original Pi / codemode patterns","name":"Mario Zechner"},{"name":"boozedog and contributors"}],"homepage":"https://github.com/boozedog/pi-codemode#readme","bugs":{"url":"https://github.com/boozedog/pi-codemode/issues"},"pi":{"extensions":["./dist/index.js"]},"dist":{"shasum":"811aa6ea35f5583a5380cc18c0906b310e4c9a59","tarball":"https://registry.npmjs.org/@boozedog/pi-codemode/-/pi-codemode-0.4.4.tgz","fileCount":163,"integrity":"sha512-ONubsvHVbvmuCBx8F2bb3EklfrNeLvKSxfoBINBheST+oucS0mOkjfkqpcFu7BFq1VDElCtVOi3NgurBnJKYlw==","signatures":[{"sig":"MEUCIEyh/qoipptDGBZomuYd+1RXOLw2ALf+347FSQ3w2PoRAiEA+LXZXy8+AZb6EQxAKl2dqFXt9XRgr2u2y42NNHhZrso=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@boozedog%2fpi-codemode@0.4.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":969324},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":"./dist/index.js"},"gitHead":"5017eff5005147a319c2463ee0e4ea775810e946","scripts":{"dev":"tsc --watch","lint":"oxlint --deny warnings --vitest-plugin src","test":"vitest run","build":"tsc","check":"npm run format:check && npm run lint && npm run build && npm test","format":"oxfmt . --write","prepack":"npm run build","prepare":"node ./scripts/prepare.mjs","release":"./scripts/release.sh","publish:tag":"npm run check && npm run check:clean-tree && npm pack --dry-run && git tag v$npm_package_version && git push origin v$npm_package_version","format:check":"oxfmt . --check","check:clean-tree":"git diff --quiet && git diff --cached --quiet || (echo \"Working tree is dirty; commit or stash changes before publishing.\" && git status --short && exit 1)"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","approver":{"name":"boozedog","email":"npmjs@boozedog.com"},"trustedPublisher":{"id":"github","oidcConfigId":"oidc:4dc3d63e-b03f-4d32-847c-44fc6d1156d8"}},"repository":{"url":"git+https://github.com/boozedog/pi-codemode.git","type":"git"},"_npmVersion":"11.19.1","description":"Pi Codemode plugin - TypeScript code execution with sandboxed tools, typed host CLI, and MCP integration","directories":{},"_nodeVersion":"24.20.0","dependencies":{"ajv":"^8.20.0","minisearch":"^7.2.0","typescript":"^6.0.3","quickjs-emscripten-core":"^0.32.0","@modelcontextprotocol/client":"^2.0.0","@jitl/quickjs-singlefile-mjs-release-sync":"^0.32.0"},"_hasShrinkwrap":false,"devDependencies":{"oxfmt":"^0.48.0","oxlint":"^1.63.0","vitest":"^4.1.5","@types/node":"^22.19.17","@types/json-schema":"^7.0.15","@mariozechner/pi-tui":"^0.73.1"},"peerDependencies":{"@mariozechner/pi-tui":"^0.73.1","@mariozechner/pi-agent-core":"^0.73.1","@mariozechner/pi-coding-agent":"^0.73.1"},"_npmOperationalInternal":{"tmp":"tmp/pi-codemode_0.4.4_1789770227391_0.22981390166167048","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@boozedog/pi-codemode","version":"0.5.0","keywords":["codemode","pi-extension","pi-package","sandbox","typescript"],"author":{"name":"boozedog"},"license":"MIT","_id":"@boozedog/pi-codemode@0.5.0","maintainers":[{"name":"boozedog","email":"npmjs@boozedog.com"}],"contributors":[{"url":"original Pi / codemode patterns","name":"Mario Zechner"},{"name":"boozedog and contributors"}],"homepage":"https://github.com/boozedog/pi-codemode#readme","bugs":{"url":"https://github.com/boozedog/pi-codemode/issues"},"pi":{"extensions":["./dist/index.js"]},"dist":{"shasum":"39fe1839f9b3d457e9c468622d9c04e86bc898eb","tarball":"https://registry.npmjs.org/@boozedog/pi-codemode/-/pi-codemode-0.5.0.tgz","fileCount":183,"integrity":"sha512-g+VHRKyF3YdVDthWpMIxS4WbgMXV4iEaWvF5/GHuNh0NFSTx3KzmR6U+QSXfR3w+keoBte8ShX4iJo+bIzH1qw==","signatures":[{"sig":"MEQCIHUVUdpVamiQVH6BDt5mnT9Q3/XOMvNWaCLJ9f63+YldAiBsqV7MvfsUxxegpHtr2XotvUUcwQw/4EeEkzItjeWC/w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@boozedog%2fpi-codemode@0.5.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1067516},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":"./dist/index.js"},"gitHead":"f45cdb40710355219a4ba65b458694284d1c1373","scripts":{"dev":"tsc --watch","lint":"oxlint --deny warnings --vitest-plugin src","test":"vitest run","build":"tsc","check":"npm run format:check && npm run lint && npm run build && npm test","format":"oxfmt . --write","prepack":"npm run build","prepare":"node ./scripts/prepare.mjs","release":"./scripts/release.sh","publish:tag":"npm run check && npm run check:clean-tree && npm pack --dry-run && git tag v$npm_package_version && git push origin v$npm_package_version","format:check":"oxfmt . --check","check:clean-tree":"git diff --quiet && git diff --cached --quiet || (echo \"Working tree is dirty; commit or stash changes before publishing.\" && git status --short && exit 1)"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","approver":{"name":"boozedog","email":"npmjs@boozedog.com"},"trustedPublisher":{"id":"github","oidcConfigId":"oidc:4dc3d63e-b03f-4d32-847c-44fc6d1156d8"}},"repository":{"url":"git+https://github.com/boozedog/pi-codemode.git","type":"git"},"_npmVersion":"11.19.1","description":"Pi Codemode plugin - TypeScript code execution with sandboxed tools, typed host CLI, and MCP integration","directories":{},"_nodeVersion":"24.20.0","dependencies":{"ajv":"^8.20.0","minisearch":"^7.2.0","typescript":"^6.0.3","quickjs-emscripten-core":"^0.32.0","@modelcontextprotocol/client":"^2.0.0","@jitl/quickjs-singlefile-mjs-release-sync":"^0.32.0"},"_hasShrinkwrap":false,"devDependencies":{"oxfmt":"^0.48.0","oxlint":"^1.63.0","vitest":"^4.1.5","@types/node":"^22.19.17","@types/json-schema":"^7.0.15","@mariozechner/pi-tui":"^0.73.1"},"peerDependencies":{"@mariozechner/pi-tui":"^0.73.1","@mariozechner/pi-agent-core":"^0.73.1","@mariozechner/pi-coding-agent":"^0.73.1"},"_npmOperationalInternal":{"tmp":"tmp/pi-codemode_0.5.0_1789912632635_0.057640523238770225","host":"s3://npm-registry-packages-npm-production"}},"0.5.1":{"pi":{"extensions":["./dist/index.js"]},"_id":"@boozedog/pi-codemode@0.5.1","bugs":{"url":"https://github.com/boozedog/pi-codemode/issues"},"dist":{"shasum":"6ee4698f22fd21ff21fe332f420cc1bc62d9cc48","tarball":"https://registry.npmjs.org/@boozedog/pi-codemode/-/pi-codemode-0.5.1.tgz","integrity":"sha512-TrLLJDGMuMgkuyYYYxGOFyZesq7pXkh+tdx0v2YWBQ+nBRU9QL51uwTB4Ta66kjmQunj0OLLXNz9I61bCdEvcQ==","fileCount":183,"unpackedSize":1075709,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@boozedog%2fpi-codemode@0.5.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIBRdFRjLeXIkjcL8sDNSXAg1gbb44lFQsYqchJfkjqIqAiAuxRjJwhnscbjcQsDa1cFjF0Sy4UU9aVj+ZmES4YaVdg=="}]},"main":"./dist/index.js","name":"@boozedog/pi-codemode","type":"module","types":"./dist/index.d.ts","author":{"name":"boozedog"},"exports":{".":"./dist/index.js"},"gitHead":"a08ba0461572c57441aa4e354925ac9828d98704","license":"MIT","scripts":{"dev":"tsc --watch","lint":"oxlint --deny warnings --vitest-plugin src","test":"vitest run","build":"tsc","check":"npm run format:check && npm run lint && npm run build && npm test","format":"oxfmt . --write","prepack":"npm run build","prepare":"node ./scripts/prepare.mjs","release":"./scripts/release.sh","publish:tag":"npm run check && npm run check:clean-tree && npm pack --dry-run && git tag v$npm_package_version && git push origin v$npm_package_version","format:check":"oxfmt . --check","check:clean-tree":"git diff --quiet && git diff --cached --quiet || (echo \"Working tree is dirty; commit or stash changes before publishing.\" && git status --short && exit 1)"},"version":"0.5.1","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:4dc3d63e-b03f-4d32-847c-44fc6d1156d8"},"approver":{"name":"boozedog","email":"npmjs@boozedog.com"}},"homepage":"https://github.com/boozedog/pi-codemode#readme","keywords":["codemode","pi-extension","pi-package","sandbox","typescript"],"repository":{"url":"git+https://github.com/boozedog/pi-codemode.git","type":"git"},"_npmVersion":"11.19.1","description":"Pi Codemode plugin - TypeScript code execution with sandboxed tools, typed host CLI, and MCP integration","directories":{},"maintainers":[{"name":"boozedog","email":"npmjs@boozedog.com"}],"_nodeVersion":"24.20.0","contributors":[{"url":"original Pi / codemode patterns","name":"Mario Zechner"},{"name":"boozedog and contributors"}],"dependencies":{"ajv":"^8.20.0","minisearch":"^7.2.0","typescript":"^6.0.3","quickjs-emscripten-core":"^0.32.0","@modelcontextprotocol/client":"^2.0.0","@jitl/quickjs-singlefile-mjs-release-sync":"^0.32.0"},"devDependencies":{"oxfmt":"^0.48.0","oxlint":"^1.63.0","vitest":"^4.1.5","@types/node":"^22.19.17","@types/json-schema":"^7.0.15","@mariozechner/pi-tui":"^0.73.1"},"peerDependencies":{"@mariozechner/pi-tui":"^0.73.1","@mariozechner/pi-agent-core":"^0.73.1","@mariozechner/pi-coding-agent":"^0.73.1"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pi-codemode_0.5.1_1789998168753_0.27673637202969514"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-16T10:31:37.313Z","modified":"2026-09-21T13:42:49.152Z","0.1.4":"2026-05-16T10:31:37.617Z","0.1.8":"2026-07-29T15:24:38.866Z","0.2.0":"2026-08-10T12:06:24.701Z","0.3.0":"2026-08-11T21:16:18.531Z","0.4.4":"2026-09-18T22:23:47.485Z","0.5.0":"2026-09-20T13:57:12.725Z","0.5.1":"2026-09-21T13:42:48.852Z"},"bugs":{"url":"https://github.com/boozedog/pi-codemode/issues"},"author":{"name":"boozedog"},"license":"MIT","homepage":"https://github.com/boozedog/pi-codemode#readme","keywords":["codemode","pi-extension","pi-package","sandbox","typescript"],"repository":{"url":"git+https://github.com/boozedog/pi-codemode.git","type":"git"},"description":"Pi Codemode plugin - TypeScript code execution with sandboxed tools, typed host CLI, and MCP integration","contributors":[{"url":"original Pi / codemode patterns","name":"Mario Zechner"},{"name":"boozedog and contributors"}],"maintainers":[{"name":"boozedog","email":"npmjs@boozedog.com"}],"readme":"# Pi Codemode\n\nPi Codemode is a Pi extension that replaces many small tool calls with one typed `execute_tools` call. The model writes a TypeScript code body, Pi type-checks it, then runs it in a sandbox with explicit tool globals.\n\n## Quickstart\n\nInstall the package in Pi as an extension package, then start Pi in a project as usual. Codemode starts in configured mode; the default is `on`, which exposes `execute_tools` plus Pi's normal non-bash tools.\n\nUseful controls:\n\n- `/codemode on` exposes `execute_tools` plus normal non-bash tools, write-locked to the project root.\n- `/codemode yolo` exposes everything from `on` plus native `bash` when available (the write escape hatch).\n- `/codemode off` restores normal Pi tools, including native `write`/`edit`/`bash`.\n- Bare `/codemode` toggles `off <-> on`.\n\n### Running jobs with arguments\n\nRun a skill or TypeScript entry without a model turn. The job name and arguments are\none string; quote the `--run` value when it contains arguments:\n\n```bash\npi -p --run 'daily-mail date=2026-08-10'\npi -p --run 'daily-mail --date 2026-08-10 --verbose'\npi -p --run 'daily-mail --date=2026-08-10'\npi -p --run daily-mail\n```\n\n`-p --run` is also the primary preflight-and-handoff workflow. A skill can opt in by\nsetting `handoff: true` in its `SKILL.md` frontmatter. Its markdown body is sent to\nthe normal model turn after the off-model entry completes. Use `{{result}}` for the\nserialized return value, `{{result.json}}` for JSON, and `{{args}}` for the parsed\narguments. In this mode stdout contains the final assistant text and the process\nwaits for that turn; a non-zero exit means either preflight or the model turn failed.\nSkills without `handoff: true` retain the pure off-model contract: stdout is the\nserialized return value and `-p` exits after the job. `/run` uses the same semantics\ninside the TUI. Prefer only `--run` for handoff invocations; combining it with extra\nbare `pi -p \"prompt\"` arguments is discouraged and has undefined ordering.\n\nThe interactive command uses the same grammar: `/run daily-mail --date 2026-08-10`.\nJobs read values from `args`, for example `args.date` (missing keys are `undefined`):\n\n```ts\nconst date = args.date ?? new Date().toISOString().slice(0, 10);\nreturn { date };\n```\n\nSupported forms are `key=value`, `--key=value`, `--key value`, and bare `--flag`\n(which gives `\"true\"`). Values are strings. Pi does not support sibling flags after\n`--run`: `pi -p --run daily-mail --date 2026-08-10` is rejected as an unknown Pi\noption. Put all arguments inside the single quoted `--run` string instead.\n\n### Write-door matrix\n\n`on` mode is **write-locked**: native write-capable tools (`write`, `edit`, `bash`) are stripped from the active set. The only write doors are the root-scoped patch tools and allowlisted `cli.*` operations.\n\n| Door                                                       | `on`            | `yolo`                   |\n| ---------------------------------------------------------- | --------------- | ------------------------ |\n| codemode guest (in-guest `read` only; no mutation helpers) | read-only       | read-only                |\n| patch tools `replace_in_file` / `apply_patch`              | **root-scoped** | **unrestricted**         |\n| native `write`                                             | **DENY**        | **DENY**                 |\n| native `edit`                                              | **DENY**        | **DENY**                 |\n| native `bash`                                              | **DENY**        | **ALLOW** (escape hatch) |\n| host `cli.*`                                               | allowlisted ops | allowlisted ops          |\n\n## The `execute_tools` shape\n\n`execute_tools` accepts a TypeScript **code body**, not a full function:\n\n```ts\nconst pkg = await read({ path: \"package.json\" });\nprint(\"package bytes\", pkg.length);\nreturn JSON.parse(pkg).name;\n```\n\nReturn a value to include it in the tool result. `print()` and `console.log()` output is captured before the return value. Type errors are reported before execution, so invalid code has no side effects. Runtime errors are returned as tool errors.\n\nLarge codemode calls, results, and file diffs render compactly in Pi by hiding their middle section. Use `Ctrl+O` to expand the hidden content, and `Ctrl+O` again to collapse.\n\n## Built-in globals\n\nGenerated code only receives explicit globals:\n\n- `read({ path, offset?, limit? })` reads a project file.\n- `write({ path, content })` writes a project file, creating parent directories.\n- `edit({ path, edits })` performs exact text replacements.\n- `codemode.search_tools({ query })` searches available Pi/MCP tools.\n- `codemode.list_mcp_servers()` lists configured MCP namespaces.\n- `codemode.list_tools({ namespace, offset?, limit? })` lists cached MCP tools with pagination.\n- `codemode.describe_tools({ namespace, tool? })` shows MCP namespace/tool details.\n- `codemode.plan_npm_script({ script })` decomposes a safe package script into visible `cli.*` calls without executing it.\n- `codemode.run_npm_script({ script, verbose? })` decomposes a safe package script, shows the plan, and executes only the surfaced `cli.*` calls.\n- `mcp.<namespace>.<tool>(args)` calls configured MCP tools. The legacy `codemode.<namespace>.<tool>(args)` form remains supported.\n- `cli.<tool>.<operation>(args)` calls configured typed CLI capabilities.\n- `print(...args)` emits result output.\n- `π.key` reads string constants passed in the `strings` parameter.\n- `jev.ask(state, questions)` _(optional)_ calls TypeSafe System One for calibrated **noul**, **choice**, and **score** answers composed inside your TypeScript program. Available only when a TypeSafe API key is configured; otherwise the global, types, and HTTP client are absent.\n\n### Optional `jev.ask` (TypeSafe)\n\nWhen a TypeSafe API key is present, Codemode injects guest `jev.ask` into QuickJS and the type checker. Without a key, Codemode is unchanged: no `jev` global, no HTTP, and no `@typesafe-ai/sdk` dependency.\n\nKey resolution (first present wins):\n\n1. `TYPESAFE_API_KEY` environment variable\n2. `jev.apiKeyFile` in `codemode.json` (if set)\n3. `~/.pi/agent/secrets/typesafe_api_key` (file contents, trimmed)\n\n```ts\nconst answers = await jev.ask(\n  { snippet: issueTitle },\n  {\n    urgent: { type: \"noul\", instructions: \"Is this customer-impacting?\" },\n    area: {\n      type: \"choice\",\n      instructions: \"Primary area\",\n      criteria: { billing: \"payments\", bug: \"defect\", docs: \"documentation\" },\n    },\n  },\n);\n\nif (answers.urgent?.type === \"noul\" && answers.urgent.noul > 0.7) {\n  return { escalate: true, area: answers.area };\n}\n```\n\nSlice state before calling; ask one factor per question; compose thresholds in TypeScript. Do not use Jev to choose which `cli.*` or `mcp.*` tools to call. `/codemode jev` reports armed vs not armed without printing the key.\n\n### File edits\n\n`edit` mirrors Pi's exact replacement model:\n\n```ts\nawait edit({\n  path: \"src/index.ts\",\n  edits: [{ oldText: \"const oldName =\", newText: \"const newName =\" }],\n});\n```\n\nEach `oldText` must match exactly once in the original file. Edits in one call must not overlap. Merge nearby changes into one larger replacement.\n\n### Hard-to-quote strings with `π`\n\nUse `strings` for file content that contains backticks, `${...}`, nested quotes, code blocks, or shell scripts:\n\n```json\n{\n  \"code\": \"await write({ path: 'script.sh', content: π.script });\",\n  \"strings\": {\n    \"script\": \"#!/usr/bin/env bash\\necho \\\"hello ${USER}\\\"\\n\"\n  }\n}\n```\n\nInside code, `π.script` is a normal string. The `strings` values only need JSON escaping, not JavaScript string-literal escaping.\n\n### Parallel calls\n\nUse `Promise.all` for independent work:\n\n```ts\nconst [pkg, tsconfig, readme] = await Promise.all([\n  read({ path: \"package.json\" }),\n  read({ path: \"tsconfig.json\" }),\n  read({ path: \"README.md\" }),\n]);\nreturn { files: [pkg.length, tsconfig.length, readme.length] };\n```\n\n## CLI capabilities\n\nCodemode does not expose a shell-string API. There is no `$`, `shell()`, `bash -c`, or raw argv passthrough in generated code. Instead, configured typed command capabilities are exposed under `cli`:\n\n```ts\nconst status = await cli.git.status({ short: true, branch: true });\nconst hits = await cli.rg.search({ pattern: \"TODO\", paths: [\"src\"], lineNumber: true });\n```\n\nEach `cli` tool/operation must be allowlisted in config and runs as a native host command (`backend: \"host\"`). There is no in-guest shell backend. Discovery never auto-exposes host binaries; only configured operations are available.\n\nHost command output is capped inline at 50 KiB per stream, with a truncation marker when exceeded. Non-zero command exits do not throw; inspect `exitCode`. Denied operations, missing executables, timeouts, and invalid runtime argument shapes throw clear CLI errors.\n\nGitHub issue relationship operations are intentionally curated. Codemode exposes narrow helpers matching GitHub's first-class issue dependency endpoint names: `cli.gh.issueListBlockedBy()`, `cli.gh.issueAddBlockedBy()`, and `cli.gh.issueListBlocking()`. These are backed by `GET/POST /repos/{owner}/{repo}/issues/{issue_number}/dependencies/blocked_by` and `GET /repos/{owner}/{repo}/issues/{issue_number}/dependencies/blocking`. Codemode does not expose generic `gh api` or arbitrary GraphQL execution to generated code; host code constructs the exact endpoint and resolves blocking issue numbers to same-repository REST database IDs internally.\n\n### npm script decomposition\n\nCodemode treats npm scripts as recipes to inspect, not shell commands to execute. Generated code should not call `npm`, `npx`, `node`, `bash`, or other abstraction layers directly. Instead, use the codemode npm-script helpers:\n\n```ts\nreturn await codemode.plan_npm_script({ script: \"build\" });\n```\n\nFor a package script such as:\n\n```json\n{\n  \"scripts\": {\n    \"build\": \"tsc\",\n    \"check\": \"npm run format:check && npm run lint && npm run build && npm test\",\n    \"format:check\": \"oxfmt . --check\",\n    \"lint\": \"oxlint --deny warnings --vitest-plugin src\",\n    \"test\": \"vitest run\"\n  }\n}\n```\n\nthe plan is surfaced as explicit calls:\n\n```text\nPlan for npm run check:\n- cli.oxfmt.check({\"paths\":[\".\"]})\n- cli.oxlint.run({\"deny\":\"warnings\",\"vitestPlugin\":true,\"paths\":[\"src\"]})\n- cli.tsc.build({})\n- cli.vitest.run({})\n\nNo commands were executed.\n```\n\nTo run the safe plan:\n\n```ts\nreturn await codemode.run_npm_script({ script: \"check\" });\n```\n\n`run_npm_script` prints the plan, executes only the surfaced `cli.*` calls, and stops on the first non-zero exit. By default, successful step output is compact; pass `verbose: true` to include stdout/stderr from successful steps:\n\n```ts\nreturn await codemode.run_npm_script({ script: \"check\", verbose: true });\n```\n\nScripts fail loudly before execution if they contain unsupported shell constructs, env expansion, command substitution, pipes/redirection, recursive cycles, or denied commands such as `node`, `npm`, `npx`, `bash`, or `python` outside the safe recursive `npm run <script>` / `npm test` subset.\n\nOperation-specific timeouts can be configured with object-form `operations`:\n\n```json\n{\n  \"cli\": {\n    \"rg\": {\n      \"backend\": \"host\",\n      \"operations\": {\n        \"search\": { \"timeoutMs\": 5000 }\n      }\n    }\n  }\n}\n```\n\n## MCP discovery workflow\n\nMCP tools are exposed under the preferred `mcp.*` namespace. The legacy `codemode.<namespace>.<tool>()` form remains supported:\n\n```ts\nconst github = await codemode.describe_tools({ namespace: \"github\" });\nprint(github);\n\nconst details = await codemode.describe_tools({ namespace: \"github\", tool: \"search_issues\" });\nprint(details);\n\nreturn await mcp.github.search_issues({ query: \"is:open label:bug\" });\n```\n\nUse `codemode.list_mcp_servers()` to see available namespaces and `codemode.list_tools({ namespace })` to page through large cached tool lists. Use `codemode.search_tools({ query })` when you do not know the namespace or exact tool name.\n\n## Configuration\n\nCodemode loads JSON config from:\n\n1. `~/.pi/agent/codemode.json` (global policy — operator-controlled)\n2. `$PROJECT/.pi/codemode.json` (project overlay)\n\nGlobal and project settings are shallow-merged for `executor` and `mcp`. **`mode` and `cli` are different:** when the global file explicitly sets `mode` or `cli`, the project file may only **narrow** those values (intersect CLI operations, lower mode permissiveness). A model-written project file cannot widen `on` to `yolo` or add CLI operations absent from the global pin. Set `\"lock\": true` in the global file to ignore project `mode` and `cli` entirely (MCP overlay from the project file still applies). `/codemode refresh` reloads config with the same non-widening rules; `/codemode on|off|yolo` no-ops with a warning when policy is locked.\n\nIn `on` mode, file writes through codemode patch tools are scoped to the project root but **denied** under `.pi/` and for project-root `.mcp.json`. That blocks minting policy files from inside the write lock; the merge rules above remain authoritative on `session_start` and refresh even if a policy file already exists.\n\nMCP servers are loaded from `~/.config/mcp/mcp.json` (global), then project `.mcp.json`, then `mcp.servers` in the Codemode config. URL servers try Streamable HTTP first and fall back to legacy SSE when that handshake fails for a transport reason. Optional `headers`, `bearerToken`, or adapter-style `bearerTokenEnv` values are sent on both URL transports. Stdio servers use `command`, `args`, `env`, and `cwd`. Stdio `env` values may use Cursor-style `${env:NAME}` to copy a named variable from the Pi parent process at spawn time; unset or empty parent values omit that key (the SDK still supplies its default allowlist such as `PATH` and `HOME`). Literal `env` entries overlay those defaults. Tool metadata is cached under `~/.cache/pi-codemode/mcp-metadata.json` so discovery can hydrate without reconnecting. Interactive OAuth browser flows and Pi MCP UI integration are not implemented; pre-auth with `bearerToken`/`bearerTokenEnv`/`headers` or use a stdio server. Copy `examples/codemode.json` to `~/.pi/agent/codemode.json` (global) or `$PROJECT/.pi/codemode.json` (project-local). Project `.pi/` is gitignored personal override space — do not commit it. The example is host-only `cli.*` with no personal MCP servers.\n\nDefault config:\n\n```json\n{\n  \"mode\": \"on\",\n  \"executor\": {\n    \"type\": \"quickjs\",\n    \"timeoutMs\": 120000\n  }\n}\n```\n\n`mode` can be `\"on\"`, `\"yolo\"`, or `\"off\"`. In `on`, Codemode exposes `execute_tools` plus normal non-bash tools, write-locked to the project root (native `write`/`edit`/`bash` are stripped; writes go through the root-scoped patch tools or allowlisted `cli.*`). In `yolo`, native `bash` is included if Pi provides it; if not, codemode gracefully falls back to normal codemode tools and notifies you. In `off`, normal Pi tools (including native `write`/`edit`/`bash`) are restored.\n\nCodemode-specific MCP servers and typed CLI capabilities can also be configured here:\n\n```json\n{\n  \"mcp\": {\n    \"servers\": {\n      \"github-mcp\": { \"command\": \"github-mcp\" }\n    }\n  },\n  \"cli\": {\n    \"git\": {\n      \"backend\": \"host\",\n      \"operations\": [\n        \"status\",\n        \"branch\",\n        \"diff\",\n        \"log\",\n        \"show\",\n        \"remote\",\n        \"revParse\",\n        \"add\",\n        \"commit\",\n        \"push\",\n        \"pull\",\n        \"switch\",\n        \"checkout\",\n        \"restore\",\n        \"reset\",\n        \"stash\",\n        \"tag\"\n      ]\n    },\n    \"gh\": {\n      \"backend\": \"host\",\n      \"operations\": [\n        \"issueView\",\n        \"issueList\",\n        \"issueCreate\",\n        \"issueEdit\",\n        \"issueComment\",\n        \"issueClose\",\n        \"labelCreate\",\n        \"labelList\",\n        \"prView\",\n        \"prList\",\n        \"prDiff\",\n        \"prChecks\",\n        \"prStatus\"\n      ]\n    },\n    \"rg\": { \"backend\": \"host\", \"operations\": [\"search\"] },\n    \"find\": { \"backend\": \"host\", \"operations\": [\"files\"] },\n    \"grep\": { \"backend\": \"host\", \"operations\": [\"search\"] },\n    \"ls\": { \"backend\": \"host\", \"operations\": [\"list\"] },\n    \"vitest\": { \"backend\": \"host\", \"operations\": [\"run\"] },\n    \"tsc\": { \"backend\": \"host\", \"operations\": [\"build\"] },\n    \"oxfmt\": { \"backend\": \"host\", \"operations\": [\"check\", \"write\"] },\n    \"oxlint\": { \"backend\": \"host\", \"operations\": [\"run\"] }\n  }\n}\n```\n\n`quickjs` is the default MVP executor. `deno` is optional/future support behind the same executor interface; if selected and unavailable, `execute_tools` reports a configured-executor runtime error.\n\n## Security model\n\nGenerated code is untrusted. The host dispatcher is the authority.\n\nDenied by default:\n\n- direct Node globals such as `process` and `require`\n- direct filesystem access from generated code\n- direct environment access\n- direct network access\n- subprocess spawning from generated code\n- unrestricted host bash or shell strings inside generated code\n\nIn `yolo` mode, Pi's native `bash` tool is available outside `execute_tools` as an explicit escape hatch and has broader host access. Use `on` mode when you want Codemode without the native bash escape hatch.\n\n- raw subprocess/argv passthrough from generated code\n\nAllowed capabilities are only the injected globals listed above. File tools validate paths against the project root and reject traversal outside it. Enabling host-backed `cli` operations expands trust boundaries and should be reviewed in config.\n\n## Attribution\n\nMaintained and published by **boozedog** as `@boozedog/pi-codemode`.\n\nThis project builds on Pi coding-agent extension patterns and Codemode-style typed tool execution ideas associated with Mario Zechner's Pi ecosystem and Cloudflare Codemode. See repository history and upstream projects for lineage.\n\n## Installation\n\n### Recommended install: npm package\n\nPi Codemode is published as a Pi package on npm and is discoverable in the `pi.dev` package catalog because `package.json` includes the `pi-package` keyword and a Pi extension manifest.\n\n```sh\npi install npm:@boozedog/pi-codemode\n```\n\nTo try the npm package for one Pi run without adding it to settings:\n\n```sh\npi -e npm:@boozedog/pi-codemode\n```\n\n### Alternative install: tagged GitHub release\n\nPi Codemode is distributed through normal Pi extension package installs using GitHub release tags. This does not require cloning this repository to a fixed local path:\n\n```sh\npi install git:github.com/boozedog/pi-codemode@<tag>\n```\n\nTo try a tagged release for one Pi run without adding it to settings:\n\n```sh\npi -e git:github.com/boozedog/pi-codemode@<tag>\n```\n\nFor unpinned development installs from GitHub, update with:\n\n```sh\npi update git:github.com/boozedog/pi-codemode\n# or update all Pi extensions\npi update --extensions\n```\n\nFor local development, keep using a path install from this checkout:\n\n```sh\nnpm install\nnpm run build\npi install /absolute/path/to/pi-codemode\n```\n\nThe package manifest points Pi at `./dist/index.js`. Runtime packages are normal `dependencies`; Pi-provided APIs are declared as `peerDependencies`. Git installs run `npm install`, and the package `prepare` script builds `dist/` after install. npm publishes run `prepack`, which also builds `dist/` before creating the tarball.\n\n### Dependency policy\n\nRuntime MCP support uses the official `@modelcontextprotocol/client` v2 package. Pure JavaScript libraries use caret ranges so compatible fixes can be installed. Host-coupled or deeply integrated dependencies are exact-pinned when a version change can alter runtime loading or integration behavior. The Pi peer packages are currently constrained to `^0.73.1`, matching the APIs Codemode integrates with and the development `pi-tui` floor. The upstream ecosystem is also transitioning from `@mariozechner/pi-*` packages to `@earendil-works/*`; this package keeps its existing peer names until that migration is verified.\n\n## Development\n\n```sh\nnpm install\nnpm test\nnpm run build\nnpm run check\n```\n\nInside Codemode itself, prefer the surfaced npm-script workflow instead of direct `npm run` execution:\n\n```ts\nawait codemode.plan_npm_script({ script: \"check\" });\nawait codemode.run_npm_script({ script: \"check\" });\n```\n\nSource lives in `src/`; generated build output lives in `dist/`.\n\n## Release checklist\n\nTo bump the version, run the release helper from a clean tree:\n\n```sh\nnpm run release -- --version 0.1.3\n```\n\nTo publish the current `package.json` version without bumping:\n\n```sh\nnpm run release\n```\n\nThe helper checks for a clean tree, updates `package.json`/`package-lock.json` when `--version` is provided, runs `npm run check`, commits the version bump, verifies package contents with `npm pack --dry-run`, then creates and pushes `v$npm_package_version`.\n\nAfter the tag is pushed:\n\n1. GitHub Actions runs `.github/workflows/publish.yml` and stages `@boozedog/pi-codemode` on npm with provenance (OIDC trusted publishing). No local `npm publish` step.\n2. Approve the staged version on npmjs.com (**Staged Packages**) or with `npm stage approve` (2FA). Until then the version is not installable.\n3. From a clean directory or machine, install the tag with `pi install git:github.com/boozedog/pi-codemode@<tag>` or `pi install npm:@boozedog/pi-codemode` once npm `latest` updates.\n4. Start Pi and confirm Codemode loads, the `codemode` tool can read files, typed host `cli.*` capabilities work, and the result UI renders.\n\nOnce npm indexes the package, `https://pi.dev/packages` discovers it from the `pi-package` keyword.\n\n### Publish to npm for pi.dev catalog discovery\n\nnpm publishing is CI-only and uses **staged publishing**. Pushing a `v*.*.*` tag (via `npm run release` / `publish:tag`) triggers `.github/workflows/publish.yml`, which runs `npm run check` and `npm stage publish --access public` on a GitHub-hosted runner. Provenance attestations are automatic via npm **trusted publishing** (OIDC); do not pass `--provenance` or a long-lived `NPM_TOKEN`. A maintainer must then 2FA-approve the staged version (`npm stage approve` or npmjs.com) before it is installable.\n\n**One-time npmjs.com setup** (after `publish.yml` is on `master`):\n\n1. Open https://www.npmjs.com/package/@boozedog/pi-codemode → Settings → **Publishing access** → **Add GitHub Actions trusted publisher**.\n2. Provider: GitHub Actions; organization or user: `boozedog`; repository: `pi-codemode`; workflow filename: `publish.yml` (filename only); environment: leave empty. Leave **Allow npm publish** unchecked so the publisher is stage-only (`npm stage publish` is always allowed).\n3. After the first successful staged publish and approval of `0.4.1`, enable **Require two-factor authentication and disallow tokens** under Publishing access so laptop `npm publish` cannot bypass provenance.\n\n**Catch-up or retry** for an existing tag (e.g. `v0.4.1` already on GitHub): Actions → Publish Package → **Run workflow** (`workflow_dispatch`), enter the tag name. That stages again; approve on npmjs.com. Do not publish from a laptop.\n\nConfirm provenance after approval:\n\n```sh\nnpm view @boozedog/pi-codemode@<version> dist.attestations\n```\n","readmeFilename":"README.md"}