From f246e99083fd8b111000d53ed05f540f965d3d2e Mon Sep 17 00:00:00 2001 From: hackernotfound <46266726+hackernotfound@users.noreply.github.com> Date: Fri, 2 Oct 2026 10:38:33 +0200 Subject: [PATCH] feat: rename to pstack-copilot on the Agent Plugins 1.0 format --- .github/plugin/marketplace.json | 4 +-- NOTICE.md | 2 +- README.md | 12 ++++---- VERSION | 2 +- docs/maintaining.md | 2 +- overlay/README.md | 2 +- .../{ => com.github.copilot}/hooks/hooks.json | 2 +- .../hooks/session-start.sh | 0 plugins/pstack/README.md | 2 +- .../{ => com.github.copilot}/hooks/hooks.json | 2 +- .../hooks/session-start-context.json | 0 .../hooks/session-start-context.md | 0 .../hooks/session-start.sh | 0 plugins/pstack/plugin.json | 13 +++++---- tools/build.mjs | 28 +++++++++++-------- tools/check.mjs | 26 ++++++++++++----- tools/eval-vscode.mjs | 4 +-- tools/eval.sh | 4 +-- 18 files changed, 64 insertions(+), 41 deletions(-) rename overlay/{ => com.github.copilot}/hooks/hooks.json (70%) rename overlay/{ => com.github.copilot}/hooks/session-start.sh (100%) rename plugins/pstack/{ => com.github.copilot}/hooks/hooks.json (70%) rename plugins/pstack/{ => com.github.copilot}/hooks/session-start-context.json (100%) rename plugins/pstack/{ => com.github.copilot}/hooks/session-start-context.md (100%) rename plugins/pstack/{ => com.github.copilot}/hooks/session-start.sh (100%) diff --git a/.github/plugin/marketplace.json b/.github/plugin/marketplace.json index 31fd8f8..e3a8a21 100644 --- a/.github/plugin/marketplace.json +++ b/.github/plugin/marketplace.json @@ -7,10 +7,10 @@ "description": "GitHub Copilot port of pstack for Copilot CLI and the VS Code agents window.", "plugins": [ { - "name": "pstack", + "name": "pstack-copilot", "source": "./plugins/pstack", "description": "if you want to go fast, go deep first. pstack helps you write less, but higher quality code. rigorous agent workflows you can parallelize with confidence. GitHub Copilot port of pstack-claude 0.9.57. Original pstack by Lauren Tan (poteto); Claude Code port by Michael Denyer.", - "version": "1.1.1" + "version": "1.2.0" } ] } diff --git a/NOTICE.md b/NOTICE.md index d5689db..2f0f756 100644 --- a/NOTICE.md +++ b/NOTICE.md @@ -5,7 +5,7 @@ This repository is a GitHub Copilot port of [pstack-claude](https://github.com/m `plugins/pstack/` is generated by [`tools/build.mjs`](tools/build.mjs) from that commit. The port's own work is: - `overlay/skills/poteto-mode/references/copilot-tools.md` -- `overlay/hooks/hooks.json` and `overlay/hooks/session-start.sh` +- `overlay/com.github.copilot/hooks/hooks.json` and `overlay/com.github.copilot/hooks/session-start.sh` - the `edits` table, mandate rewrite, and manifests in `tools/build.mjs` - `tools/check.mjs` and `tools/eval.sh` diff --git a/README.md b/README.md index cb7b148..379c44d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # pstack for GitHub Copilot -[![check](https://github.com/hackernotfound/pstack-vscode/actions/workflows/check.yml/badge.svg)](https://github.com/hackernotfound/pstack-vscode/actions/workflows/check.yml) [![license: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) [![version](https://img.shields.io/badge/version-1.1.1-7C3AED.svg)](https://github.com/hackernotfound/pstack-vscode/releases/tag/v1.1.1) +[![check](https://github.com/hackernotfound/pstack-vscode/actions/workflows/check.yml/badge.svg)](https://github.com/hackernotfound/pstack-vscode/actions/workflows/check.yml) [![license: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) [![version](https://img.shields.io/badge/version-1.2.0-7C3AED.svg)](https://github.com/hackernotfound/pstack-vscode/releases/tag/v1.2.0) **Run [pstack](https://github.com/cursor/plugins/tree/main/pstack) in the VS Code agents window with GitHub Copilot.** @@ -32,10 +32,10 @@ This port fixes all four and leaves pstack's own content untouched. Each fix is "chat.plugins.marketplaces": ["hackernotfound/pstack-vscode"] ``` -2. In the Extensions view, search `@agentPlugins`, install **pstack**, and accept the trust prompt. +2. In the Extensions view, search `@agentPlugins`, install **pstack-copilot**, and accept the trust prompt. 3. Open the agents window and pick **Copilot** in the session target picker. -That's it. Under **Customizations**, pstack now shows up in **Plugins**, its hook in **Hooks**, and `poteto-mode` in **Skills**. +That's it. Under **Customizations**, pstack-copilot now shows up in **Plugins**, its hook in **Hooks**, and `poteto-mode` in **Skills**. **Want to see your subagents while they run?** Follow the one-time [agents window setup](docs/agents-window.md). It adds a live list of running subagents, side-by-side subagent panes, and chat tabs, close to [T3 Code](https://t3.codes). @@ -43,11 +43,13 @@ That's it. Under **Customizations**, pstack now shows up in **Plugins**, its hoo ```shell copilot plugin marketplace add hackernotfound/pstack-vscode -copilot plugin install pstack@pstack-vscode +copilot plugin install pstack-copilot@pstack-vscode ``` VS Code also lists plugins you install this way. +> **Installed 1.1.1 or earlier?** The plugin was called `pstack` then. Run `copilot plugin uninstall pstack`, then install `pstack-copilot` as above. In VS Code, uninstall **pstack** and install **pstack-copilot**. A `chat.pluginLocations` path to `plugins/pstack` keeps working as it is. + > **Using the Claude target too?** The Claude target loads your Claude Code plugins from `~/.claude`. Keep pstack-claude for that target, and use this port for **Copilot**. ## Use it @@ -106,7 +108,7 @@ flowchart LR - **A Copilot tool map.** [`copilot-tools.md`](overlay/skills/poteto-mode/references/copilot-tools.md) translates every Claude tool and model name the skills use. `poteto-mode` points Copilot at it. - **Bare skill names** in the startup instructions, such as `poteto-mode` rather than `pstack:poteto-mode`. - **No plugin agents.** Copilot dispatches its built-in `general-purpose` agent and has it load `poteto-mode` first, which is all `pstack:poteto-agent` does. Shipping no agents also keeps VS Code's agent picker free of duplicates. -- **A Copilot-only manifest.** VS Code treats any plugin with a `.claude-plugin/` folder as a Claude plugin, so the port ships only a Copilot `plugin.json`. +- **An [Agent Plugins 1.0](https://agent-plugins.org) manifest.** The startup hook lives under `com.github.copilot/`, where Copilot looks for it in that format. The port ships no `.claude-plugin/` folder, because VS Code treats any plugin with one as a Claude plugin. Tested on VS Code 1.140.0 and its bundled Copilot runtime, and on Copilot CLI 1.0.91. Updating to a newer pstack, the generated files, and the live tests are covered in [docs/maintaining.md](docs/maintaining.md). diff --git a/VERSION b/VERSION index 524cb55..26aaba0 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.1.1 +1.2.0 diff --git a/docs/maintaining.md b/docs/maintaining.md index c6910e1..99b462f 100644 --- a/docs/maintaining.md +++ b/docs/maintaining.md @@ -15,7 +15,7 @@ `node tools/check.mjs` runs in CI on every push and pull request. It rebuilds the plugin and fails if: - the rebuilt tree differs from the committed one -- a manifest, agent, hook, or skill is missing or malformed +- the manifest is not Agent Plugins 1.0, or an agent, hook, or skill is missing or malformed - the startup instructions name a skill with the `pstack:` prefix, or the hook output is not top-level `additionalContext` - the plugin contains a symlink, or an executable outside the reviewed list - the plugin ships any agent (VS Code's agents window lists every plugin agent twice) diff --git a/overlay/README.md b/overlay/README.md index 7e87e8b..3642d4a 100644 --- a/overlay/README.md +++ b/overlay/README.md @@ -1,4 +1,4 @@ -# pstack (GitHub Copilot port) +# pstack-copilot (GitHub Copilot port of pstack) Lauren Tan's [pstack](https://github.com/cursor/plugins/tree/main/pstack) is an opinionated skill stack that improves agent outcomes. This build runs it on GitHub Copilot: the VS Code agents window with the Copilot target, and Copilot CLI. It is generated from Michael Denyer's [pstack-claude](https://github.com/michael-denyer/pstack-claude). diff --git a/overlay/hooks/hooks.json b/overlay/com.github.copilot/hooks/hooks.json similarity index 70% rename from overlay/hooks/hooks.json rename to overlay/com.github.copilot/hooks/hooks.json index 7d4b7fd..e5182c6 100644 --- a/overlay/hooks/hooks.json +++ b/overlay/com.github.copilot/hooks/hooks.json @@ -6,7 +6,7 @@ "hooks": [ { "type": "command", - "command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/session-start.sh\"" + "command": "\"${PLUGIN_ROOT}/com.github.copilot/hooks/session-start.sh\"" } ] } diff --git a/overlay/hooks/session-start.sh b/overlay/com.github.copilot/hooks/session-start.sh similarity index 100% rename from overlay/hooks/session-start.sh rename to overlay/com.github.copilot/hooks/session-start.sh diff --git a/plugins/pstack/README.md b/plugins/pstack/README.md index 7e87e8b..3642d4a 100644 --- a/plugins/pstack/README.md +++ b/plugins/pstack/README.md @@ -1,4 +1,4 @@ -# pstack (GitHub Copilot port) +# pstack-copilot (GitHub Copilot port of pstack) Lauren Tan's [pstack](https://github.com/cursor/plugins/tree/main/pstack) is an opinionated skill stack that improves agent outcomes. This build runs it on GitHub Copilot: the VS Code agents window with the Copilot target, and Copilot CLI. It is generated from Michael Denyer's [pstack-claude](https://github.com/michael-denyer/pstack-claude). diff --git a/plugins/pstack/hooks/hooks.json b/plugins/pstack/com.github.copilot/hooks/hooks.json similarity index 70% rename from plugins/pstack/hooks/hooks.json rename to plugins/pstack/com.github.copilot/hooks/hooks.json index 7d4b7fd..e5182c6 100644 --- a/plugins/pstack/hooks/hooks.json +++ b/plugins/pstack/com.github.copilot/hooks/hooks.json @@ -6,7 +6,7 @@ "hooks": [ { "type": "command", - "command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/session-start.sh\"" + "command": "\"${PLUGIN_ROOT}/com.github.copilot/hooks/session-start.sh\"" } ] } diff --git a/plugins/pstack/hooks/session-start-context.json b/plugins/pstack/com.github.copilot/hooks/session-start-context.json similarity index 100% rename from plugins/pstack/hooks/session-start-context.json rename to plugins/pstack/com.github.copilot/hooks/session-start-context.json diff --git a/plugins/pstack/hooks/session-start-context.md b/plugins/pstack/com.github.copilot/hooks/session-start-context.md similarity index 100% rename from plugins/pstack/hooks/session-start-context.md rename to plugins/pstack/com.github.copilot/hooks/session-start-context.md diff --git a/plugins/pstack/hooks/session-start.sh b/plugins/pstack/com.github.copilot/hooks/session-start.sh similarity index 100% rename from plugins/pstack/hooks/session-start.sh rename to plugins/pstack/com.github.copilot/hooks/session-start.sh diff --git a/plugins/pstack/plugin.json b/plugins/pstack/plugin.json index cfe0f0c..300e9ab 100644 --- a/plugins/pstack/plugin.json +++ b/plugins/pstack/plugin.json @@ -1,12 +1,14 @@ { - "name": "pstack", - "displayName": "pstack (GitHub Copilot port)", - "version": "1.1.1", + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", + "name": "pstack-copilot", + "version": "1.2.0", "description": "if you want to go fast, go deep first. pstack helps you write less, but higher quality code. rigorous agent workflows you can parallelize with confidence. GitHub Copilot port of pstack-claude 0.9.57. Original pstack by Lauren Tan (poteto); Claude Code port by Michael Denyer.", "author": { "name": "hackernotfound", "url": "https://github.com/hackernotfound" }, + "homepage": "https://github.com/hackernotfound/pstack-vscode", + "repository": "https://github.com/hackernotfound/pstack-vscode", "license": "MIT", "keywords": [ "pstack", @@ -16,6 +18,7 @@ "skills", "subagents" ], - "skills": "./skills/", - "hooks": "./hooks/hooks.json" + "extensions": { + "com.github.copilot": {} + } } diff --git a/tools/build.mjs b/tools/build.mjs index 60ed61e..8275270 100755 --- a/tools/build.mjs +++ b/tools/build.mjs @@ -1,6 +1,6 @@ #!/usr/bin/env node import { execFileSync } from 'node:child_process'; -import { cpSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from 'node:fs'; +import { cpSync, existsSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from 'node:fs'; import { dirname, join, relative, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; @@ -9,6 +9,9 @@ const upstream = JSON.parse(readFileSync(join(root, 'upstream.json'), 'utf8')); const version = readFileSync(join(root, 'VERSION'), 'utf8').trim(); if (!/^\d+\.\d+\.\d+$/.test(version)) throw new Error(`VERSION must be MAJOR.MINOR.PATCH, got ${JSON.stringify(version)}`); const out = join(root, 'plugins/pstack'); +const name = 'pstack-copilot'; +// Agent Plugins 1.0 keeps Copilot-only parts, such as hooks, under this namespace folder. +const hooks = 'com.github.copilot/hooks'; function fetchSource() { const dir = join(root, '.cache', `pstack-claude-${upstream.sha.slice(0, 12)}`); @@ -37,7 +40,7 @@ const skillNames = () => .filter((d) => d.isDirectory() && existsSync(join(out, 'skills', d.name, 'SKILL.md'))) .map((d) => d.name); -const removals = ['.codex-plugin', '.claude-plugin', 'hooks/codex-hooks.json', 'agents', 'effort-agents']; +const removals = ['.codex-plugin', '.claude-plugin', 'hooks/codex-hooks.json', 'hooks/hooks.json', 'hooks/session-start.sh', 'agents', 'effort-agents']; const edits = [ { @@ -103,7 +106,7 @@ function unlinkCrossSkillReferences() { function buildMandate() { const names = new Set(skillNames()); let rewrites = 0; - const text = read('hooks/session-start-context.md').replace(/pstack:([a-z0-9-]+)/g, (m, name) => { + const text = read(`${hooks}/session-start-context.md`).replace(/pstack:([a-z0-9-]+)/g, (m, name) => { if (!names.has(name)) return m; rewrites++; return name; @@ -113,29 +116,30 @@ function buildMandate() { '\nOn GitHub Copilot, skills load through the `skill` tool by bare name, such as `poteto-mode`. This plugin ships no agents; where a skill names a pstack agent, dispatch `general-purpose` as copilot-tools.md says. When a pstack skill names a Claude tool or model, read the pstack plugin\'s `skills/poteto-mode/references/copilot-tools.md`.\n'; const mandate = text.replace('', `${pointer}`); if (mandate === text) throw new Error('mandate: closing tag not found'); - write('hooks/session-start-context.md', mandate); - write('hooks/session-start-context.json', `${JSON.stringify({ additionalContext: mandate })}\n`); + write(`${hooks}/session-start-context.md`, mandate); + write(`${hooks}/session-start-context.json`, `${JSON.stringify({ additionalContext: mandate })}\n`); } function writeManifests(source) { const claude = JSON.parse(readFileSync(join(source, 'plugins/pstack/.claude-plugin/plugin.json'), 'utf8')); const plugin = { - name: 'pstack', - displayName: 'pstack (GitHub Copilot port)', + $schema: 'https://agent-plugins.org/schemas/1.0.0/plugin.schema.json', + name, version, description: `${claude.description.split(' Ported from')[0]} GitHub Copilot port of pstack-claude ${upstream.version}. Original pstack by Lauren Tan (poteto); Claude Code port by Michael Denyer.`, author: { name: 'hackernotfound', url: 'https://github.com/hackernotfound' }, + homepage: 'https://github.com/hackernotfound/pstack-vscode', + repository: 'https://github.com/hackernotfound/pstack-vscode', license: 'MIT', keywords: ['pstack', 'poteto-mode', 'copilot', 'vscode', 'skills', 'subagents'], - skills: './skills/', - hooks: './hooks/hooks.json', + extensions: { 'com.github.copilot': {} }, }; write('plugin.json', `${JSON.stringify(plugin, null, 2)}\n`); const marketplace = { name: 'pstack-vscode', owner: { name: 'hackernotfound', url: 'https://github.com/hackernotfound' }, description: 'GitHub Copilot port of pstack for Copilot CLI and the VS Code agents window.', - plugins: [{ name: 'pstack', source: './plugins/pstack', description: plugin.description, version }], + plugins: [{ name, source: './plugins/pstack', description: plugin.description, version }], }; mkdirSync(join(root, '.github/plugin'), { recursive: true }); writeFileSync(join(root, '.github/plugin/marketplace.json'), `${JSON.stringify(marketplace, null, 2)}\n`); @@ -154,10 +158,12 @@ const source = fetchSource(); rmSync(out, { recursive: true, force: true }); cpSync(join(source, 'plugins/pstack'), out, { recursive: true }); for (const rel of removals) rmSync(join(out, rel), { recursive: true, force: true }); +mkdirSync(dirname(join(out, hooks)), { recursive: true }); +renameSync(join(out, 'hooks'), join(out, hooks)); cpSync(join(root, 'overlay'), out, { recursive: true }); edits.forEach(applyEdit); unlinkCrossSkillReferences(); buildMandate(); writeManifests(source); copyLicenses(source); -console.log(`built plugins/pstack ${version} from ${upstream.sha.slice(0, 7)}`); +console.log(`built plugins/pstack (${name}) ${version} from ${upstream.sha.slice(0, 7)}`); diff --git a/tools/check.mjs b/tools/check.mjs index 8c8222f..9e2c77b 100755 --- a/tools/check.mjs +++ b/tools/check.mjs @@ -20,7 +20,14 @@ check('build is idempotent (rebuild leaves no diff)', dirty === ''); const plugin = JSON.parse(read('plugin.json')); const upstream = JSON.parse(readFileSync(join(root, 'upstream.json'), 'utf8')); -check('plugin.json name is pstack', plugin.name === 'pstack'); +check('plugin.json name is pstack-copilot', plugin.name === 'pstack-copilot'); +const manifestKeys = ['$schema', 'author', 'description', 'extensions', 'homepage', 'keywords', 'license', 'name', 'repository', 'version']; +check( + 'plugin.json is Agent Plugins 1.0 (schema URL, only schema properties, Copilot namespace)', + plugin.$schema === 'https://agent-plugins.org/schemas/1.0.0/plugin.schema.json' && + Object.keys(plugin).every((k) => manifestKeys.includes(k)) && + JSON.stringify(plugin.extensions) === '{"com.github.copilot":{}}', +); const version = readFileSync(join(root, 'VERSION'), 'utf8').trim(); check('plugin.json version matches VERSION and is MAJOR.MINOR.PATCH', /^\d+\.\d+\.\d+$/.test(version) && plugin.version === version); const readme = readFileSync(join(root, 'README.md'), 'utf8'); @@ -28,28 +35,33 @@ check('README version badge matches VERSION', readme.includes(`version-${version check('plugin.json names the pinned upstream version', plugin.description.includes(`pstack-claude ${upstream.version}`)); check('no .claude-plugin manifest (VS Code would parse it as Claude format)', !existsSync(join(out, '.claude-plugin'))); check('plugin ships no agents (the VS Code agents window lists each plugin agent twice)', !('agents' in plugin) && !existsSync(join(out, 'agents')) && !readdirSync(out, { recursive: true }).some((rel) => /(^|\/)agents\/[^/]+\.md$/.test(rel) && !rel.startsWith('skills/'))); -check('hooks file exists', existsSync(join(out, plugin.hooks))); +const hooks = 'com.github.copilot/hooks'; +const hookCommands = JSON.parse(read(`${hooks}/hooks.json`)).hooks.SessionStart.flatMap((g) => g.hooks.map((h) => h.command)); +check( + 'SessionStart hook runs a script that ships, via ${PLUGIN_ROOT}', + hookCommands.length === 1 && hookCommands.every((c) => c.startsWith('"${PLUGIN_ROOT}/') && existsSync(join(out, c.slice('"${PLUGIN_ROOT}/'.length, -1)))), +); const market = JSON.parse(readFileSync(join(root, '.github/plugin/marketplace.json'), 'utf8')); -check('marketplace source points at the plugin', market.plugins.some((p) => existsSync(join(root, p.source, 'plugin.json')))); +check('marketplace entry points at the plugin by its name', market.plugins.some((p) => p.name === plugin.name && existsSync(join(root, p.source, 'plugin.json')))); const skills = readdirSync(join(out, 'skills')).filter((d) => existsSync(join(out, 'skills', d, 'SKILL.md'))); check('every SKILL.md name matches its directory', skills.every((d) => new RegExp(`^name: ${d}$`, 'm').test(read(`skills/${d}/SKILL.md`)))); -const mandate = read('hooks/session-start-context.md'); -const ctx = JSON.parse(read('hooks/session-start-context.json')); +const mandate = read(`${hooks}/session-start-context.md`); +const ctx = JSON.parse(read(`${hooks}/session-start-context.json`)); check('hook JSON carries the mandate as top-level additionalContext', ctx.additionalContext === mandate); check('mandate names no pstack:', !skills.some((s) => mandate.includes(`pstack:${s}`))); check('mandate under Claude Code 10k cap', mandate.length < 10000); -const hookOut = execFileSync(join(out, 'hooks/session-start.sh'), { env: { ...process.env, COPILOT_HOME: '/nonexistent' }, encoding: 'utf8' }); +const hookOut = execFileSync(join(out, hooks, 'session-start.sh'), { env: { ...process.env, COPILOT_HOME: '/nonexistent' }, encoding: 'utf8' }); check('hook script prints the JSON', JSON.parse(hookOut).additionalContext === mandate); check('poteto-mode links copilot-tools.md', read('skills/poteto-mode/SKILL.md').includes('references/copilot-tools.md')); check('copilot-tools.md shipped', existsSync(join(out, 'skills/poteto-mode/references/copilot-tools.md'))); const executables = [ - 'hooks/session-start.sh', + 'com.github.copilot/hooks/session-start.sh', 'skills/poteto-mode/scripts/orch/orch.ts', 'skills/poteto-mode/scripts/watch-pr/ship-pr', 'skills/poteto-mode/scripts/watch-pr/watch-pr', diff --git a/tools/eval-vscode.mjs b/tools/eval-vscode.mjs index c313bf7..b3b6482 100644 --- a/tools/eval-vscode.mjs +++ b/tools/eval-vscode.mjs @@ -114,12 +114,12 @@ const rejectedDispatch = (cs) => cs.some((t) => t.t === 'task' && !t.ok); const agentNames = await run('context', 'Do not run tools. 1) Quote verbatim the sentence in your context that starts with "On GitHub Copilot, skills load". 2) Print the full enum of the agent_type parameter of your task tool, comma separated. 3) Print the number of skills available to you whose name starts with "principle-".', 5 * 60_000); check('mandate injected by sessionStart hook', final('context').includes('skills load through the')); -check('runtime lists no pstack plugin agents', !agentNames.some((n) => n.startsWith('pstack:'))); +check('runtime lists no pstack plugin agents', !agentNames.some((n) => /^pstack(-copilot)?:/.test(n))); await run('route', 'Explain how main.js gets its output in this repo. Use poteto-mode, and delegate the code reading to one pstack subagent.', 20 * 60_000); const route = calls('route'); check('poteto-mode loaded via skill tool', route.some((c) => c.t === 'skill' && String(c.a.skill).includes('poteto-mode') && c.ok)); -check('no namespaced skill lookups', !route.some((c) => String(c.a.skill ?? '').startsWith('pstack:'))); +check('no namespaced skill lookups', !route.some((c) => /^pstack(-copilot)?:/.test(String(c.a.skill ?? '')))); check('a subagent ran and loaded a pstack skill itself', subagentRanPstack(route)); check('no subagent dispatch was rejected', !rejectedDispatch(route)); check('no Claude-only tool names called', !route.some((c) => /^(Agent|Skill|Task|AskUserQuestion|TodoWrite)$/.test(c.t))); diff --git a/tools/eval.sh b/tools/eval.sh index db064b0..5f9e052 100755 --- a/tools/eval.sh +++ b/tools/eval.sh @@ -57,11 +57,11 @@ git add -A && git -c user.name=eval -c user.email=eval@local commit -qm init run context -s -p 'Do not run tools. 1) Quote verbatim the sentence in your context that starts with "On GitHub Copilot, skills load". 2) Print the full enum of the agent_type parameter of your task tool, comma separated. 3) Print the number of skills available to you whose name starts with "principle-".' check "mandate injected by sessionStart hook" 'final context | grep -q "skills load through the"' -check "task offers no pstack plugin agents" '! final context | grep -q "pstack:"' +check "task offers no pstack plugin agents" '! final context | grep -Eq "pstack(-copilot)?:"' run route -p 'Explain how main.js gets its output in this repo. Use poteto-mode, and delegate the code reading to one pstack subagent.' check "poteto-mode loaded via skill tool" 'poteto_mode_loaded route' -check "no namespaced skill lookups" '! calls route | grep -q "\"skill\":\"pstack:"' +check "no namespaced skill lookups" '! calls route | grep -Eq "\"skill\":\"pstack(-copilot)?:"' check "a subagent ran and loaded a pstack skill itself" 'subagent_ran_pstack route' check "no subagent dispatch was rejected" '! rejected_dispatch route' check "no Claude-only tool names called" '! calls route | grep -qE "\"t\":\"(Agent|Skill|Task|AskUserQuestion|TodoWrite)\""'