@static-var/keystone 0.1.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/plugins/marketplace.json +19 -21
- package/.agents/skills/keystone/SKILL.md +21 -0
- package/.claude-plugin/marketplace.json +24 -20
- package/.claude-plugin/plugin.json +6 -7
- package/.codex-plugin/plugin.json +2 -8
- package/.pi/extensions/keystone.ts +1 -1
- package/HOW_IT_WORKS.md +25 -19
- package/Makefile +6 -3
- package/README.md +85 -18
- package/package.json +2 -2
- package/packaging.allowlist +1 -1
- package/scripts/build-metadata.py +80 -15
- package/scripts/validate-keystone.py +174 -16
- package/scripts/validate-package.py +4 -1
- package/skills/keystone/SKILL.md +6 -1
- package/skills/keystone/modules/breakdown.md +7 -7
- package/skills/keystone/modules/build.md +2 -2
- package/skills/keystone/modules/debug.md +1 -1
- package/skills/keystone/modules/health.md +1 -1
- package/skills/keystone/modules/research.md +1 -1
- package/skills/keystone/modules/review.md +1 -1
- package/skills/keystone/modules/router.md +1 -1
- package/skills/keystone/modules/shape.md +1 -1
- package/skills/keystone/modules/helpers/subagents.md +0 -134
|
@@ -1,24 +1,22 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
"pi-package",
|
|
6
|
-
"agent-skills",
|
|
7
|
-
"keystone",
|
|
8
|
-
"claude-code",
|
|
9
|
-
"codex",
|
|
10
|
-
"opencode",
|
|
11
|
-
"copilot",
|
|
12
|
-
"pi-coding-agent",
|
|
13
|
-
"pi-extension",
|
|
14
|
-
"workflow",
|
|
15
|
-
"skills",
|
|
16
|
-
"agent-workflows"
|
|
17
|
-
],
|
|
18
|
-
"license": "MIT",
|
|
2
|
+
"interface": {
|
|
3
|
+
"displayName": "Keystone"
|
|
4
|
+
},
|
|
19
5
|
"name": "keystone",
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
6
|
+
"plugins": [
|
|
7
|
+
{
|
|
8
|
+
"category": "Development & Workflow",
|
|
9
|
+
"description": "Use when the user invokes /keystone or asks Keystone to route product, research, writing, UI, design, planning, implementation, debugging, review, shipping, or health work through its canonical orchestrator.",
|
|
10
|
+
"displayName": "Keystone",
|
|
11
|
+
"name": "keystone",
|
|
12
|
+
"policy": {
|
|
13
|
+
"authentication": "ON_USE",
|
|
14
|
+
"installation": "AVAILABLE"
|
|
15
|
+
},
|
|
16
|
+
"source": {
|
|
17
|
+
"path": "./",
|
|
18
|
+
"source": "local"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
]
|
|
24
22
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: keystone
|
|
3
|
+
description: Keystone adapter for Agent Skills hosts such as OpenCode, GitHub Copilot, and VS Code. Use when the user asks Keystone to route product, research, writing, UI, design, planning, implementation, debugging, review, shipping, or health work.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Keystone Agent Skills Adapter
|
|
7
|
+
|
|
8
|
+
This is a thin adapter for hosts that discover skills from `.agents/skills/<name>/SKILL.md`.
|
|
9
|
+
|
|
10
|
+
The canonical Keystone skill lives at:
|
|
11
|
+
|
|
12
|
+
```text
|
|
13
|
+
../../../skills/keystone/SKILL.md
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
When this adapter is loaded:
|
|
17
|
+
|
|
18
|
+
1. Read `../../../skills/keystone/SKILL.md`.
|
|
19
|
+
2. Follow the canonical Keystone entrypoint exactly.
|
|
20
|
+
3. Resolve Keystone module, gate, and helper paths relative to `skills/keystone/`, not relative to this adapter directory.
|
|
21
|
+
4. Keep the public surface as one Keystone skill. Do not expose internal modules as separate public commands.
|
|
@@ -1,24 +1,28 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
"
|
|
4
|
-
"keywords": [
|
|
5
|
-
"pi-package",
|
|
6
|
-
"agent-skills",
|
|
7
|
-
"keystone",
|
|
8
|
-
"claude-code",
|
|
9
|
-
"codex",
|
|
10
|
-
"opencode",
|
|
11
|
-
"copilot",
|
|
12
|
-
"pi-coding-agent",
|
|
13
|
-
"pi-extension",
|
|
14
|
-
"workflow",
|
|
15
|
-
"skills",
|
|
16
|
-
"agent-workflows"
|
|
17
|
-
],
|
|
18
|
-
"license": "MIT",
|
|
2
|
+
"$schema": "https://json.schemastore.org/claude-code-marketplace.json",
|
|
3
|
+
"description": "Keystone plugin marketplace for Claude Code.",
|
|
19
4
|
"name": "keystone",
|
|
20
|
-
"
|
|
21
|
-
"
|
|
5
|
+
"owner": {
|
|
6
|
+
"name": "static-var"
|
|
7
|
+
},
|
|
8
|
+
"plugins": [
|
|
9
|
+
{
|
|
10
|
+
"author": {
|
|
11
|
+
"name": "static-var"
|
|
12
|
+
},
|
|
13
|
+
"category": "productivity",
|
|
14
|
+
"description": "Use when the user invokes /keystone or asks Keystone to route product, research, writing, UI, design, planning, implementation, debugging, review, shipping, or health work through its canonical orchestrator.",
|
|
15
|
+
"name": "keystone",
|
|
16
|
+
"source": "./",
|
|
17
|
+
"tags": [
|
|
18
|
+
"workflow",
|
|
19
|
+
"skills",
|
|
20
|
+
"engineering",
|
|
21
|
+
"review",
|
|
22
|
+
"planning"
|
|
23
|
+
],
|
|
24
|
+
"version": "1.0.0"
|
|
25
|
+
}
|
|
22
26
|
],
|
|
23
|
-
"version": "
|
|
27
|
+
"version": "1.0.0"
|
|
24
28
|
}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/claude-code-plugin.json",
|
|
3
|
+
"author": {
|
|
4
|
+
"name": "static-var"
|
|
5
|
+
},
|
|
2
6
|
"description": "Use when the user invokes /keystone or asks Keystone to route product, research, writing, UI, design, planning, implementation, debugging, review, shipping, or health work through its canonical orchestrator.",
|
|
3
7
|
"license": "MIT",
|
|
4
8
|
"name": "keystone",
|
|
5
|
-
"
|
|
6
|
-
|
|
7
|
-
"name": "keystone",
|
|
8
|
-
"path": "../skills/keystone/SKILL.md"
|
|
9
|
-
}
|
|
10
|
-
],
|
|
11
|
-
"version": "0.1.0"
|
|
9
|
+
"repository": "https://github.com/static-var/Keystone",
|
|
10
|
+
"version": "1.0.0"
|
|
12
11
|
}
|
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"description": "Use when the user invokes /keystone or asks Keystone to route product, research, writing, UI, design, planning, implementation, debugging, review, shipping, or health work through its canonical orchestrator.",
|
|
3
|
-
"license": "MIT",
|
|
4
3
|
"name": "keystone",
|
|
5
|
-
"skills":
|
|
6
|
-
|
|
7
|
-
"name": "keystone",
|
|
8
|
-
"path": "../skills/keystone/SKILL.md"
|
|
9
|
-
}
|
|
10
|
-
],
|
|
11
|
-
"version": "0.1.0"
|
|
4
|
+
"skills": "./skills/",
|
|
5
|
+
"version": "1.0.0"
|
|
12
6
|
}
|
|
@@ -145,7 +145,7 @@ Pi has native skills, but Keystone should use this extension's \`/keystone\` com
|
|
|
145
145
|
|
|
146
146
|
Pi's built-in coding tools are lowercase: \`read\`, \`write\`, \`edit\`, \`bash\`, plus optional \`grep\`, \`find\`, and \`ls\`. Use those for file inspection, mutation, shell commands, and search.
|
|
147
147
|
|
|
148
|
-
|
|
148
|
+
Keystone is configured for \`@tintinweb/pi-subagents\` (https://github.com/tintinweb/pi-subagents). If that extension is installed, use its \`Agent\` tool for bounded delegation, \`get_subagent_result\` for background results, and \`steer_subagent\` only to redirect live work. Do not assume named roles, model selection, or thinking controls; use only the fields exposed by the active tool schema. Keep read-only work read-only. Use background/parallel subagents only for independent tasks with no shared mutable files. Do not invent unsupported subagent tools. If no subagent tool is available, do the work in this session.`;
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
function messageContainsBootstrap(message: unknown): boolean {
|
package/HOW_IT_WORKS.md
CHANGED
|
@@ -103,29 +103,28 @@ Each module has the same shape:
|
|
|
103
103
|
|
|
104
104
|
## Subagents and reasoning
|
|
105
105
|
|
|
106
|
-
Keystone
|
|
106
|
+
Keystone keeps subagent guidance inline in `skills/keystone/SKILL.md`, the Pi extension bootstrap, and each module's `Subagents and reasoning` section. There is no separate helper file to load.
|
|
107
107
|
|
|
108
|
-
|
|
109
|
-
skills/keystone/modules/helpers/subagents.md
|
|
110
|
-
```
|
|
108
|
+
Use subagents only when the active host exposes them and delegation has a clear boundary, useful artifact, and lower coordination cost than inline work.
|
|
111
109
|
|
|
112
|
-
|
|
110
|
+
For Pi, Keystone is configured for `@tintinweb/pi-subagents` (https://github.com/tintinweb/pi-subagents):
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
pi install npm:@tintinweb/pi-subagents
|
|
114
|
+
```
|
|
113
115
|
|
|
114
|
-
|
|
115
|
-
- whether they can set per-subagent reasoning or only model/prompt hints
|
|
116
|
-
- how to configure each host when support exists
|
|
117
|
-
- default reasoning levels for every Keystone module
|
|
116
|
+
When installed, Keystone may use `Agent`, `get_subagent_result`, and `steer_subagent` if the active tool schema exposes them. It does not assume named roles, model selection, or thinking controls from Pi; otherwise it works inline.
|
|
118
117
|
|
|
119
118
|
### Host capability summary
|
|
120
119
|
|
|
121
120
|
| Harness | Subagents | Reasoning control |
|
|
122
121
|
|---|---:|---|
|
|
123
|
-
| Pi coding agent with
|
|
122
|
+
| Pi coding agent with `@tintinweb/pi-subagents` | yes | use only controls exposed by the active tool schema; do not assume named roles, `model`, or `thinking` |
|
|
124
123
|
| Claude Code | yes | model selection and built-in Explore detail; no general custom-agent reasoning field confirmed |
|
|
125
124
|
| Codex CLI/app | host-dependent | global `model_reasoning_effort`; per-subagent effort not confirmed |
|
|
126
125
|
| T3 Code | not confirmed | not confirmed |
|
|
127
|
-
| OpenCode | yes | partial/provider-dependent: `model` plus provider-specific `variant`; no universal reasoning knob confirmed |
|
|
128
|
-
| GitHub Copilot / VS Code | yes | custom agent `model`; no general reasoning field confirmed |
|
|
126
|
+
| OpenCode | yes | partial/provider-dependent: `model` plus provider-specific `variant`; no universal reasoning knob confirmed; discovers Keystone through `.agents/skills` or symlinked canonical skill |
|
|
127
|
+
| GitHub Copilot / VS Code | yes | custom agent `model`; no general reasoning field confirmed; discovers Keystone through `.agents/skills`, `.github/skills`, or personal skill dirs |
|
|
129
128
|
|
|
130
129
|
### Module reasoning defaults
|
|
131
130
|
|
|
@@ -136,7 +135,7 @@ The helper records:
|
|
|
136
135
|
| breakdown, debug, review, high-stakes shape decisions | `high`, escalating to `xhigh` for hard or irreversible work |
|
|
137
136
|
| gates | `low`, escalating only when evidence is safety-critical |
|
|
138
137
|
|
|
139
|
-
The rule is simple:
|
|
138
|
+
The rule is simple: delegate the narrowest bounded task and request the lowest reasoning intensity that can safely complete it. Only use role names, model selection, or thinking controls when the active host schema exposes them. Escalate for ambiguity, irreversible decisions, security, data loss, release risk, or root-cause uncertainty.
|
|
140
139
|
|
|
141
140
|
## Gates
|
|
142
141
|
|
|
@@ -217,7 +216,8 @@ make regenerate
|
|
|
217
216
|
├─ .claude-plugin/plugin.json
|
|
218
217
|
├─ .claude-plugin/marketplace.json
|
|
219
218
|
├─ .codex-plugin/plugin.json
|
|
220
|
-
|
|
219
|
+
├─ .agents/plugins/marketplace.json
|
|
220
|
+
└─ .agents/skills/keystone/SKILL.md
|
|
221
221
|
│
|
|
222
222
|
▼
|
|
223
223
|
make package
|
|
@@ -320,12 +320,19 @@ Keystone currently provides:
|
|
|
320
320
|
| Host | Output |
|
|
321
321
|
|---|---|
|
|
322
322
|
| Pi | `.pi/extensions/keystone.ts` plus `package.json` with `pi.extensions` and `pi.skills` |
|
|
323
|
-
| Claude Code | `.claude-plugin/plugin.json
|
|
324
|
-
| Codex | `.codex-plugin/plugin.json` |
|
|
325
|
-
|
|
|
323
|
+
| Claude Code | `.claude-plugin/plugin.json` plus `.claude-plugin/marketplace.json` marketplace |
|
|
324
|
+
| Codex | `.codex-plugin/plugin.json` plus `.agents/plugins/marketplace.json` repo marketplace |
|
|
325
|
+
| OpenCode / GitHub Copilot / VS Code | `.agents/skills/keystone/SKILL.md` adapter plus canonical `skills/keystone/` |
|
|
326
|
+
| T3 Code | use the underlying Codex, Claude Code, or OpenCode install path |
|
|
327
|
+
|
|
328
|
+
The Claude Code plugin path uses Claude's marketplace pattern: `.claude-plugin/plugin.json` identifies the repository root as a plugin, and `.claude-plugin/marketplace.json` exposes a single installable `keystone` entry with source `./`. Users add it with `/plugin marketplace add static-var/Keystone`, install with `/plugin install keystone@keystone`, then invoke `/keystone:keystone`.
|
|
326
329
|
|
|
327
330
|
The Pi extension mirrors the Superpowers packaging pattern: it discovers bundled skills, registers `/keystone` as the public command, and injects a compact Pi-specific bootstrap while keeping internal modules private.
|
|
328
331
|
|
|
332
|
+
The Codex plugin path uses the Codex plugin marketplace pattern: `.codex-plugin/plugin.json` declares the bundled skill directory, while `.agents/plugins/marketplace.json` exposes a single installable Keystone entry whose local source is the repository root. Users can add it with `codex plugin marketplace add static-var/Keystone --ref main`, then install Keystone from `codex /plugins` or `codex plugin add keystone --marketplace keystone`.
|
|
333
|
+
|
|
334
|
+
OpenCode, GitHub Copilot, and VS Code support the Agent Skills standard directly. Keystone ships `.agents/skills/keystone/SKILL.md` as a thin adapter that points those hosts back to the canonical `skills/keystone/SKILL.md`, preserving one source of truth and one public Keystone skill.
|
|
335
|
+
|
|
329
336
|
The Pi package gallery at `https://pi.dev/packages` indexes npm packages. Keystone publishes as `@static-var/keystone` with the `pi-package` keyword, so installs use:
|
|
330
337
|
|
|
331
338
|
```bash
|
|
@@ -357,8 +364,7 @@ pi install npm:@static-var/keystone
|
|
|
357
364
|
2. Add a routing row in `skills/keystone/SKILL.md`.
|
|
358
365
|
3. Add routing fixture coverage.
|
|
359
366
|
4. Add a `Subagents and reasoning` section to the module.
|
|
360
|
-
5.
|
|
361
|
-
6. Ensure packaging includes the module directory through `packaging.allowlist`.
|
|
367
|
+
5. Ensure packaging includes the module directory through `packaging.allowlist`.
|
|
362
368
|
7. Run `make test`.
|
|
363
369
|
|
|
364
370
|
### Add maintainer-only guidance
|
package/Makefile
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
.PHONY: test validate package regenerate routing py-compile
|
|
1
|
+
.PHONY: test validate package regenerate routing unit py-compile
|
|
2
2
|
|
|
3
|
-
test: validate
|
|
3
|
+
test: validate unit py-compile
|
|
4
4
|
|
|
5
5
|
validate: package
|
|
6
6
|
python3 scripts/validate-keystone.py
|
|
@@ -9,8 +9,11 @@ validate: package
|
|
|
9
9
|
routing:
|
|
10
10
|
python3 -m unittest tests/test_routing.py
|
|
11
11
|
|
|
12
|
+
unit:
|
|
13
|
+
python3 -m unittest discover -s tests -p 'test_*.py'
|
|
14
|
+
|
|
12
15
|
py-compile:
|
|
13
|
-
python3 -m py_compile scripts/build-metadata.py scripts/validate-keystone.py scripts/validate-package.py tests/test_routing.py
|
|
16
|
+
python3 -m py_compile scripts/build-metadata.py scripts/validate-keystone.py scripts/validate-package.py tests/test_routing.py tests/test_package_validator.py
|
|
14
17
|
|
|
15
18
|
package: regenerate
|
|
16
19
|
scripts/package-keystone.sh
|
package/README.md
CHANGED
|
@@ -124,14 +124,16 @@ This file is not included in `dist/keystone.zip` and is not part of `/keystone`
|
|
|
124
124
|
.
|
|
125
125
|
├── skills/keystone/ # canonical skill source
|
|
126
126
|
│ ├── SKILL.md # public /keystone entrypoint
|
|
127
|
-
│ └── modules/ # internal modules
|
|
127
|
+
│ └── modules/ # internal modules and gates
|
|
128
128
|
├── scripts/ # metadata, validation, packaging
|
|
129
129
|
├── tests/routing/cases.yaml # routing fixture cases
|
|
130
130
|
├── tests/test_routing.py # stdlib routing test runner
|
|
131
|
+
├── tests/test_package_validator.py # package validator unit coverage
|
|
131
132
|
├── maintainers/ # repo-only, not shipped in package
|
|
132
133
|
├── .claude-plugin/ # generated Claude plugin metadata
|
|
133
134
|
├── .codex-plugin/ # generated Codex plugin metadata
|
|
134
|
-
├── .agents/plugins/ # generated
|
|
135
|
+
├── .agents/plugins/ # generated Codex repo marketplace
|
|
136
|
+
├── .agents/skills/ # generated Agent Skills adapter for OpenCode/Copilot-compatible hosts
|
|
135
137
|
├── packaging.allowlist # default-deny package contents
|
|
136
138
|
├── Makefile # test/package/regenerate targets
|
|
137
139
|
└── HOW_IT_WORKS.md # human-readable architecture guide
|
|
@@ -139,22 +141,15 @@ This file is not included in `dist/keystone.zip` and is not part of `/keystone`
|
|
|
139
141
|
|
|
140
142
|
## Subagent and reasoning support
|
|
141
143
|
|
|
142
|
-
Keystone
|
|
144
|
+
Keystone keeps subagent guidance inline in the root skill and each module. Use subagents only when the active host exposes them and delegation is cheaper than doing the work inline.
|
|
143
145
|
|
|
144
|
-
|
|
145
|
-
skills/keystone/modules/helpers/subagents.md
|
|
146
|
-
```
|
|
146
|
+
For Pi, install the supported subagent extension:
|
|
147
147
|
|
|
148
|
-
|
|
148
|
+
```bash
|
|
149
|
+
pi install npm:@tintinweb/pi-subagents
|
|
150
|
+
```
|
|
149
151
|
|
|
150
|
-
|
|
151
|
-
|---|---:|---:|
|
|
152
|
-
| Pi with `pi-subagents` | yes | yes: `thinking`, `model`, `profile` |
|
|
153
|
-
| Claude Code | yes | partial: model/detail controls, no general custom-agent reasoning knob |
|
|
154
|
-
| Codex CLI/app | host-dependent | partial/global: use prompt advisory unless host exposes per-agent effort |
|
|
155
|
-
| T3 Code | unconfirmed | unconfirmed |
|
|
156
|
-
| OpenCode | yes | partial/provider-dependent: `model` and provider `variant`; no universal reasoning knob confirmed |
|
|
157
|
-
| GitHub Copilot | yes | partial: custom agent `model`, no general reasoning knob |
|
|
152
|
+
Then Keystone can use `Agent`, `get_subagent_result`, and `steer_subagent` when the active tool schema exposes them. Keystone does not assume named roles, model selection, or thinking controls from Pi; if those controls are unavailable, it works inline or encodes intent in the prompt instead of inventing unsupported fields.
|
|
158
153
|
|
|
159
154
|
Each Keystone module includes a `Subagents and reasoning` section with its default reasoning level.
|
|
160
155
|
|
|
@@ -172,9 +167,81 @@ Keystone currently ships as:
|
|
|
172
167
|
}
|
|
173
168
|
```
|
|
174
169
|
- **Pi extension source** in `.pi/extensions/keystone.ts`, which registers `/keystone`, discovers the bundled skill, and adds a small Pi-specific bootstrap.
|
|
175
|
-
- **Claude plugin
|
|
176
|
-
- **Codex plugin
|
|
177
|
-
- **
|
|
170
|
+
- **Claude Code plugin manifest + marketplace** in `.claude-plugin/`
|
|
171
|
+
- **Codex plugin manifest** in `.codex-plugin/plugin.json`
|
|
172
|
+
- **Codex repo marketplace** in `.agents/plugins/marketplace.json`
|
|
173
|
+
- **Agent Skills adapter** in `.agents/skills/keystone/SKILL.md` for OpenCode, GitHub Copilot, VS Code, and other Agent Skills hosts
|
|
174
|
+
|
|
175
|
+
## Claude Code plugin install
|
|
176
|
+
|
|
177
|
+
Keystone is installable as a Claude Code plugin marketplace from this GitHub repo.
|
|
178
|
+
|
|
179
|
+
In Claude Code:
|
|
180
|
+
|
|
181
|
+
```text
|
|
182
|
+
/plugin marketplace add static-var/Keystone
|
|
183
|
+
/plugin install keystone@keystone
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Then invoke the namespaced Keystone skill:
|
|
187
|
+
|
|
188
|
+
```text
|
|
189
|
+
/keystone:keystone <task>
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Codex plugin install
|
|
193
|
+
|
|
194
|
+
Keystone is also installable as a Codex plugin from this GitHub repo marketplace.
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
codex plugin marketplace add static-var/Keystone --ref main
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Then open the plugin browser and install Keystone:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
codex /plugins
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
CLI install equivalent:
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
codex plugin add keystone --marketplace keystone
|
|
210
|
+
# or: codex plugin add keystone@keystone
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
After installation, invoke Keystone explicitly with `@keystone` / `$keystone` depending on your Codex surface, or ask Codex to use Keystone for workflow routing.
|
|
214
|
+
|
|
215
|
+
## OpenCode / Copilot / VS Code skills
|
|
216
|
+
|
|
217
|
+
Keystone ships a `.agents/skills/keystone` adapter because OpenCode and GitHub Copilot-compatible hosts discover Agent Skills from `.agents/skills`.
|
|
218
|
+
|
|
219
|
+
Project-local use: clone or vendor this repo into a project and those hosts can discover `.agents/skills/keystone/SKILL.md`.
|
|
220
|
+
|
|
221
|
+
Personal/global use is best done by linking the canonical skill directory, so module references stay intact:
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
# From a repo checkout
|
|
225
|
+
KS=/path/to/Keystone
|
|
226
|
+
|
|
227
|
+
# Or from global npm install
|
|
228
|
+
npm install -g @static-var/keystone
|
|
229
|
+
KS="$(npm root -g)/@static-var/keystone"
|
|
230
|
+
|
|
231
|
+
# OpenCode
|
|
232
|
+
mkdir -p ~/.config/opencode/skills
|
|
233
|
+
ln -s "$KS/skills/keystone" ~/.config/opencode/skills/keystone
|
|
234
|
+
|
|
235
|
+
# GitHub Copilot / VS Code
|
|
236
|
+
mkdir -p ~/.copilot/skills
|
|
237
|
+
ln -s "$KS/skills/keystone" ~/.copilot/skills/keystone
|
|
238
|
+
|
|
239
|
+
# Shared Agent Skills path for compatible hosts
|
|
240
|
+
mkdir -p ~/.agents/skills
|
|
241
|
+
ln -s "$KS/skills/keystone" ~/.agents/skills/keystone
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
T3 Code currently rides on underlying agents. Use the matching Codex, Claude Code, or OpenCode install path for the provider you run inside T3 Code.
|
|
178
245
|
|
|
179
246
|
## Release automation
|
|
180
247
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@static-var/keystone",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Keystone: one-router AI engineering workflow extension and skill system for Pi.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -46,7 +46,6 @@
|
|
|
46
46
|
"skills/keystone/modules/review.md",
|
|
47
47
|
"skills/keystone/modules/ship.md",
|
|
48
48
|
"skills/keystone/modules/health.md",
|
|
49
|
-
"skills/keystone/modules/helpers/subagents.md",
|
|
50
49
|
"skills/keystone/modules/gates/isolation.md",
|
|
51
50
|
"skills/keystone/modules/gates/proof.md",
|
|
52
51
|
"skills/keystone/modules/gates/red.md",
|
|
@@ -56,6 +55,7 @@
|
|
|
56
55
|
".claude-plugin/marketplace.json",
|
|
57
56
|
".codex-plugin/plugin.json",
|
|
58
57
|
".agents/plugins/marketplace.json",
|
|
58
|
+
".agents/skills/keystone/SKILL.md",
|
|
59
59
|
".pi/extensions/keystone.ts"
|
|
60
60
|
],
|
|
61
61
|
"publishConfig": {
|
package/packaging.allowlist
CHANGED
|
@@ -19,7 +19,6 @@ skills/keystone/modules/debug.md
|
|
|
19
19
|
skills/keystone/modules/review.md
|
|
20
20
|
skills/keystone/modules/ship.md
|
|
21
21
|
skills/keystone/modules/health.md
|
|
22
|
-
skills/keystone/modules/helpers/subagents.md
|
|
23
22
|
skills/keystone/modules/gates/isolation.md
|
|
24
23
|
skills/keystone/modules/gates/proof.md
|
|
25
24
|
skills/keystone/modules/gates/red.md
|
|
@@ -29,4 +28,5 @@ skills/keystone/modules/gates/ship.md
|
|
|
29
28
|
.claude-plugin/marketplace.json
|
|
30
29
|
.codex-plugin/plugin.json
|
|
31
30
|
.agents/plugins/marketplace.json
|
|
31
|
+
.agents/skills/keystone/SKILL.md
|
|
32
32
|
.pi/extensions/keystone.ts
|
|
@@ -12,6 +12,13 @@ PACKAGE = ROOT / "package.json"
|
|
|
12
12
|
NAME = "keystone"
|
|
13
13
|
|
|
14
14
|
|
|
15
|
+
AGENT_SKILL_DESCRIPTION = (
|
|
16
|
+
"Keystone adapter for Agent Skills hosts such as OpenCode, GitHub Copilot, and VS Code. "
|
|
17
|
+
"Use when the user asks Keystone to route product, research, writing, UI, design, planning, "
|
|
18
|
+
"implementation, debugging, review, shipping, or health work."
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
15
22
|
def read_package() -> dict:
|
|
16
23
|
if PACKAGE.exists():
|
|
17
24
|
return json.loads(PACKAGE.read_text())
|
|
@@ -60,38 +67,96 @@ def write_json(path: Path, data: dict) -> None:
|
|
|
60
67
|
path.write_text(json.dumps(data, indent=2, sort_keys=True) + "\n")
|
|
61
68
|
|
|
62
69
|
|
|
70
|
+
def write_agent_skill_adapter() -> None:
|
|
71
|
+
path = ROOT / ".agents" / "skills" / "keystone" / "SKILL.md"
|
|
72
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
73
|
+
path.write_text(
|
|
74
|
+
f"""---
|
|
75
|
+
name: keystone
|
|
76
|
+
description: {AGENT_SKILL_DESCRIPTION}
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
# Keystone Agent Skills Adapter
|
|
80
|
+
|
|
81
|
+
This is a thin adapter for hosts that discover skills from `.agents/skills/<name>/SKILL.md`.
|
|
82
|
+
|
|
83
|
+
The canonical Keystone skill lives at:
|
|
84
|
+
|
|
85
|
+
```text
|
|
86
|
+
../../../skills/keystone/SKILL.md
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
When this adapter is loaded:
|
|
90
|
+
|
|
91
|
+
1. Read `../../../skills/keystone/SKILL.md`.
|
|
92
|
+
2. Follow the canonical Keystone entrypoint exactly.
|
|
93
|
+
3. Resolve Keystone module, gate, and helper paths relative to `skills/keystone/`, not relative to this adapter directory.
|
|
94
|
+
4. Keep the public surface as one Keystone skill. Do not expose internal modules as separate public commands.
|
|
95
|
+
"""
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
|
|
63
99
|
def main() -> int:
|
|
64
100
|
package = read_package()
|
|
65
101
|
skill_text = SKILL.read_text() if SKILL.exists() else ""
|
|
66
|
-
fm = parse_frontmatter(skill_text)
|
|
67
102
|
description = skill_summary(skill_text) if skill_text else package.get("description", "Keystone skill.")
|
|
68
103
|
version = package.get("version", "0.0.0")
|
|
69
104
|
license_name = package.get("license", "UNLICENSED")
|
|
70
|
-
keywords = package.get("keywords", ["keystone", "skill"])
|
|
71
105
|
|
|
72
|
-
|
|
106
|
+
claude_plugin = {
|
|
107
|
+
"$schema": "https://json.schemastore.org/claude-code-plugin.json",
|
|
73
108
|
"name": NAME,
|
|
74
109
|
"version": version,
|
|
75
110
|
"description": description,
|
|
111
|
+
"author": {"name": "static-var"},
|
|
112
|
+
"repository": "https://github.com/static-var/Keystone",
|
|
76
113
|
"license": license_name,
|
|
77
|
-
"skills": [{"name": NAME, "path": "../skills/keystone/SKILL.md"}],
|
|
78
114
|
}
|
|
79
|
-
|
|
115
|
+
claude_marketplace = {
|
|
116
|
+
"$schema": "https://json.schemastore.org/claude-code-marketplace.json",
|
|
117
|
+
"name": NAME,
|
|
118
|
+
"version": version,
|
|
119
|
+
"description": "Keystone plugin marketplace for Claude Code.",
|
|
120
|
+
"owner": {"name": "static-var"},
|
|
121
|
+
"plugins": [
|
|
122
|
+
{
|
|
123
|
+
"name": NAME,
|
|
124
|
+
"source": "./",
|
|
125
|
+
"description": description,
|
|
126
|
+
"version": version,
|
|
127
|
+
"author": {"name": "static-var"},
|
|
128
|
+
"category": "productivity",
|
|
129
|
+
"tags": ["workflow", "skills", "engineering", "review", "planning"],
|
|
130
|
+
}
|
|
131
|
+
],
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
codex_plugin = {
|
|
80
135
|
"name": NAME,
|
|
81
|
-
"displayName": "Keystone",
|
|
82
136
|
"version": version,
|
|
83
137
|
"description": description,
|
|
84
|
-
"
|
|
85
|
-
|
|
86
|
-
|
|
138
|
+
"skills": "./skills/",
|
|
139
|
+
}
|
|
140
|
+
codex_marketplace = {
|
|
141
|
+
"name": NAME,
|
|
142
|
+
"interface": {"displayName": "Keystone"},
|
|
143
|
+
"plugins": [
|
|
144
|
+
{
|
|
145
|
+
"name": NAME,
|
|
146
|
+
"displayName": "Keystone",
|
|
147
|
+
"source": {"source": "local", "path": "./"},
|
|
148
|
+
"policy": {"installation": "AVAILABLE", "authentication": "ON_USE"},
|
|
149
|
+
"category": "Development & Workflow",
|
|
150
|
+
"description": description,
|
|
151
|
+
}
|
|
152
|
+
],
|
|
87
153
|
}
|
|
88
|
-
if isinstance(fm.get("author"), str):
|
|
89
|
-
marketplace["author"] = fm["author"]
|
|
90
154
|
|
|
91
|
-
write_json(ROOT / ".claude-plugin" / "plugin.json",
|
|
92
|
-
write_json(ROOT / ".claude-plugin" / "marketplace.json",
|
|
93
|
-
write_json(ROOT / ".codex-plugin" / "plugin.json",
|
|
94
|
-
write_json(ROOT / ".agents" / "plugins" / "marketplace.json",
|
|
155
|
+
write_json(ROOT / ".claude-plugin" / "plugin.json", claude_plugin)
|
|
156
|
+
write_json(ROOT / ".claude-plugin" / "marketplace.json", claude_marketplace)
|
|
157
|
+
write_json(ROOT / ".codex-plugin" / "plugin.json", codex_plugin)
|
|
158
|
+
write_json(ROOT / ".agents" / "plugins" / "marketplace.json", codex_marketplace)
|
|
159
|
+
write_agent_skill_adapter()
|
|
95
160
|
return 0
|
|
96
161
|
|
|
97
162
|
|
|
@@ -13,9 +13,13 @@ SKILL_DIR = ROOT / "skills" / "keystone"
|
|
|
13
13
|
SKILL = SKILL_DIR / "SKILL.md"
|
|
14
14
|
MODULE_DIR = SKILL_DIR / "modules"
|
|
15
15
|
PI_EXTENSION = ROOT / ".pi" / "extensions" / "keystone.ts"
|
|
16
|
+
CLAUDE_PLUGIN = ROOT / ".claude-plugin" / "plugin.json"
|
|
17
|
+
CLAUDE_MARKETPLACE = ROOT / ".claude-plugin" / "marketplace.json"
|
|
18
|
+
CODEX_PLUGIN = ROOT / ".codex-plugin" / "plugin.json"
|
|
19
|
+
CODEX_MARKETPLACE = ROOT / ".agents" / "plugins" / "marketplace.json"
|
|
20
|
+
AGENTS_SKILL_ADAPTER = ROOT / ".agents" / "skills" / "keystone" / "SKILL.md"
|
|
16
21
|
ALLOWLIST = ROOT / "packaging.allowlist"
|
|
17
22
|
SUBAGENT_HELPER = MODULE_DIR / "helpers" / "subagents.md"
|
|
18
|
-
TARGET_HARNESSES = ("Pi", "Claude", "Codex", "T3", "OpenCode", "Copilot")
|
|
19
23
|
COMMON_PLAYBOOK_HEADINGS = (
|
|
20
24
|
"## Core principle",
|
|
21
25
|
"## Load when",
|
|
@@ -165,28 +169,118 @@ def check_module_playbooks(skill_text: str) -> None:
|
|
|
165
169
|
fail(f"module {name} missing playbook headings: " + ", ".join(missing))
|
|
166
170
|
|
|
167
171
|
|
|
168
|
-
def
|
|
169
|
-
if
|
|
170
|
-
fail("
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
172
|
+
def check_inline_subagent_guidance(skill_text: str) -> None:
|
|
173
|
+
if SUBAGENT_HELPER.exists():
|
|
174
|
+
fail("subagent helper file must not be shipped; keep subagent guidance inline")
|
|
175
|
+
forbidden = "modules/helpers/subagents.md"
|
|
176
|
+
if forbidden in skill_text:
|
|
177
|
+
fail("Keystone skill must not reference the removed subagent helper file")
|
|
178
|
+
required_skill_phrases = (
|
|
179
|
+
"Use subagents when the active host exposes them",
|
|
180
|
+
"@tintinweb/pi-subagents",
|
|
181
|
+
"Agent",
|
|
182
|
+
"get_subagent_result",
|
|
183
|
+
"steer_subagent",
|
|
184
|
+
"Do not assume named roles, model selection, or thinking controls",
|
|
185
|
+
)
|
|
186
|
+
for phrase in required_skill_phrases:
|
|
187
|
+
if phrase not in skill_text:
|
|
188
|
+
fail(f"Keystone skill missing inline subagent guidance phrase: {phrase}")
|
|
189
|
+
for phrase in forbidden_pi_subagent_claims():
|
|
190
|
+
if phrase in skill_text:
|
|
191
|
+
fail(f"Keystone skill advertises non-portable pi-subagents capability: {phrase}")
|
|
192
|
+
|
|
175
193
|
primary_modules = routing_modules(skill_text)
|
|
176
194
|
if not primary_modules:
|
|
177
195
|
fail("no primary modules found in Keystone routing table")
|
|
178
|
-
missing_modules = [
|
|
179
|
-
name for name in sorted(primary_modules)
|
|
180
|
-
if f"modules/{name}.md" not in helper_text
|
|
181
|
-
]
|
|
182
|
-
if missing_modules:
|
|
183
|
-
fail("subagent helper missing module reasoning rows: " + ", ".join(missing_modules))
|
|
184
196
|
for name in sorted(primary_modules):
|
|
185
197
|
module = MODULE_DIR / f"{name}.md"
|
|
186
198
|
if not module.is_file():
|
|
187
199
|
fail(f"missing primary module file: modules/{name}.md")
|
|
188
|
-
|
|
200
|
+
module_text = module.read_text()
|
|
201
|
+
if "## Subagents and reasoning" not in module_text:
|
|
189
202
|
fail(f"module missing subagent reasoning section: modules/{name}.md")
|
|
203
|
+
if forbidden in module_text or "helpers/subagents.md" in module_text:
|
|
204
|
+
fail(f"module references removed subagent helper file: modules/{name}.md")
|
|
205
|
+
for phrase in forbidden_module_subagent_role_claims():
|
|
206
|
+
if phrase in module_text:
|
|
207
|
+
fail(f"module advertises named/non-portable subagent role language: modules/{name}.md: {phrase}")
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def forbidden_module_subagent_role_claims() -> tuple[str, ...]:
|
|
211
|
+
return (
|
|
212
|
+
"subagent roles",
|
|
213
|
+
"researcher subagents",
|
|
214
|
+
"architecture reviewer subagents",
|
|
215
|
+
"risk reviewer subagents",
|
|
216
|
+
"worker subagents",
|
|
217
|
+
"subagents/workers",
|
|
218
|
+
"oracle/debug subagents",
|
|
219
|
+
"oracle subagents",
|
|
220
|
+
"debug subagents",
|
|
221
|
+
"scout subagents",
|
|
222
|
+
"reviewer subagents",
|
|
223
|
+
"writer subagents",
|
|
224
|
+
"writer, UI, design, or architecture subagents",
|
|
225
|
+
"specify role,",
|
|
226
|
+
"<role, reasoning, context packet, expected artifact>",
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
def forbidden_pi_subagent_claims(markdown_escaped: bool = False) -> tuple[str, ...]:
|
|
231
|
+
tick = "\\`" if markdown_escaped else "`"
|
|
232
|
+
return (
|
|
233
|
+
"Prefer narrow roles",
|
|
234
|
+
"narrowest subagent role",
|
|
235
|
+
f"{tick}scout{tick}",
|
|
236
|
+
f"{tick}worker{tick}",
|
|
237
|
+
f"{tick}reviewer{tick}",
|
|
238
|
+
f"{tick}oracle{tick}",
|
|
239
|
+
f"{tick}writer{tick}",
|
|
240
|
+
f"{tick}thinking{tick} or {tick}model{tick}",
|
|
241
|
+
f"{tick}model{tick} or {tick}thinking{tick}",
|
|
242
|
+
f"{tick}thinking{tick} and {tick}model{tick}",
|
|
243
|
+
f"{tick}model{tick} and {tick}thinking{tick}",
|
|
244
|
+
f"{tick}thinking{tick}, {tick}model{tick}",
|
|
245
|
+
f"{tick}model{tick}, {tick}thinking{tick}",
|
|
246
|
+
f"{tick}profile{tick}",
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
def check_pi_subagent_docs() -> None:
|
|
251
|
+
for path in (ROOT / "README.md", ROOT / "HOW_IT_WORKS.md"):
|
|
252
|
+
if not path.is_file():
|
|
253
|
+
fail(f"missing {path.name}")
|
|
254
|
+
text = path.read_text()
|
|
255
|
+
if "@tintinweb/pi-subagents" not in text:
|
|
256
|
+
fail(f"{path.name} missing @tintinweb/pi-subagents install guidance")
|
|
257
|
+
if "Do not assume named roles" not in text and "does not assume named roles" not in text:
|
|
258
|
+
fail(f"{path.name} must say not to assume named roles or Pi subagent controls")
|
|
259
|
+
for phrase in forbidden_pi_subagent_claims():
|
|
260
|
+
if phrase in text:
|
|
261
|
+
fail(f"{path.name} advertises non-portable pi-subagents capability: {phrase}")
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def check_pi_subagents_extension_guidance() -> None:
|
|
265
|
+
if not PI_EXTENSION.is_file():
|
|
266
|
+
fail("missing Pi extension .pi/extensions/keystone.ts")
|
|
267
|
+
extension = PI_EXTENSION.read_text()
|
|
268
|
+
required_phrases = (
|
|
269
|
+
"@tintinweb/pi-subagents",
|
|
270
|
+
"Agent",
|
|
271
|
+
"get_subagent_result",
|
|
272
|
+
"steer_subagent",
|
|
273
|
+
"Do not invent unsupported subagent tools",
|
|
274
|
+
"Do not assume named roles, model selection, or thinking controls",
|
|
275
|
+
)
|
|
276
|
+
for phrase in required_phrases:
|
|
277
|
+
if phrase not in extension:
|
|
278
|
+
fail(f"Pi extension missing pi-subagents guidance phrase: {phrase}")
|
|
279
|
+
for phrase in forbidden_pi_subagent_claims(markdown_escaped=True) + ("`profile`",):
|
|
280
|
+
if phrase in extension:
|
|
281
|
+
fail(f"Pi extension advertises non-portable pi-subagents capability: {phrase}")
|
|
282
|
+
if "modules/helpers/subagents.md" in extension or "helpers/subagents.md" in extension:
|
|
283
|
+
fail("Pi extension must not reference removed subagent helper file")
|
|
190
284
|
|
|
191
285
|
|
|
192
286
|
def check_ignored_not_tracked() -> None:
|
|
@@ -209,6 +303,65 @@ def allowlist_entries() -> set[str]:
|
|
|
209
303
|
}
|
|
210
304
|
|
|
211
305
|
|
|
306
|
+
def check_agents_skill_adapter() -> None:
|
|
307
|
+
if not AGENTS_SKILL_ADAPTER.is_file():
|
|
308
|
+
fail("missing .agents/skills/keystone/SKILL.md adapter for OpenCode/Copilot-compatible hosts")
|
|
309
|
+
text = AGENTS_SKILL_ADAPTER.read_text()
|
|
310
|
+
if "../../../skills/keystone/SKILL.md" not in text:
|
|
311
|
+
fail(".agents skill adapter must point to canonical skills/keystone/SKILL.md")
|
|
312
|
+
if "Do not expose internal modules" not in text:
|
|
313
|
+
fail(".agents skill adapter must preserve one public Keystone surface")
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
def check_claude_metadata() -> None:
|
|
317
|
+
if not CLAUDE_PLUGIN.is_file():
|
|
318
|
+
fail("missing Claude plugin manifest .claude-plugin/plugin.json")
|
|
319
|
+
plugin = json.loads(CLAUDE_PLUGIN.read_text())
|
|
320
|
+
if plugin.get("name") != "keystone":
|
|
321
|
+
fail("Claude plugin name must be keystone")
|
|
322
|
+
if "skills" in plugin:
|
|
323
|
+
fail("Claude plugin manifest should rely on the bundled skills/ directory, not legacy skills entries")
|
|
324
|
+
if not CLAUDE_MARKETPLACE.is_file():
|
|
325
|
+
fail("missing Claude marketplace .claude-plugin/marketplace.json")
|
|
326
|
+
marketplace = json.loads(CLAUDE_MARKETPLACE.read_text())
|
|
327
|
+
if marketplace.get("name") != "keystone":
|
|
328
|
+
fail("Claude marketplace name must be keystone")
|
|
329
|
+
if not isinstance(marketplace.get("owner"), dict) or not marketplace["owner"].get("name"):
|
|
330
|
+
fail("Claude marketplace must include owner.name")
|
|
331
|
+
plugins = marketplace.get("plugins")
|
|
332
|
+
if not isinstance(plugins, list) or len(plugins) != 1:
|
|
333
|
+
fail("Claude marketplace must expose exactly one Keystone plugin entry")
|
|
334
|
+
entry = plugins[0]
|
|
335
|
+
if entry.get("name") != "keystone" or entry.get("source") != "./":
|
|
336
|
+
fail('Claude marketplace plugin entry must be keystone with source "./"')
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
def check_codex_metadata() -> None:
|
|
340
|
+
if not CODEX_PLUGIN.is_file():
|
|
341
|
+
fail("missing Codex plugin manifest .codex-plugin/plugin.json")
|
|
342
|
+
plugin = json.loads(CODEX_PLUGIN.read_text())
|
|
343
|
+
if plugin.get("name") != "keystone":
|
|
344
|
+
fail("Codex plugin name must be keystone")
|
|
345
|
+
if plugin.get("skills") != "./skills/":
|
|
346
|
+
fail('Codex plugin must expose bundled skills with skills: "./skills/"')
|
|
347
|
+
if not CODEX_MARKETPLACE.is_file():
|
|
348
|
+
fail("missing Codex marketplace .agents/plugins/marketplace.json")
|
|
349
|
+
marketplace = json.loads(CODEX_MARKETPLACE.read_text())
|
|
350
|
+
plugins = marketplace.get("plugins")
|
|
351
|
+
if not isinstance(plugins, list) or len(plugins) != 1:
|
|
352
|
+
fail("Codex marketplace must expose exactly one Keystone plugin entry")
|
|
353
|
+
entry = plugins[0]
|
|
354
|
+
if entry.get("name") != "keystone":
|
|
355
|
+
fail("Codex marketplace plugin entry must be named keystone")
|
|
356
|
+
if entry.get("source") != {"source": "local", "path": "./"}:
|
|
357
|
+
fail('Codex marketplace plugin source must be {"source": "local", "path": "./"}')
|
|
358
|
+
policy = entry.get("policy", {})
|
|
359
|
+
if policy.get("installation") != "AVAILABLE":
|
|
360
|
+
fail("Codex marketplace plugin must be installable")
|
|
361
|
+
if policy.get("authentication") not in {"ON_USE", "ON_INSTALL"}:
|
|
362
|
+
fail("Codex marketplace plugin authentication policy must be ON_USE or ON_INSTALL")
|
|
363
|
+
|
|
364
|
+
|
|
212
365
|
def check_package_json() -> None:
|
|
213
366
|
package_path = ROOT / "package.json"
|
|
214
367
|
if not package_path.is_file():
|
|
@@ -250,8 +403,13 @@ def main() -> int:
|
|
|
250
403
|
check_references(text)
|
|
251
404
|
check_product_modules(text)
|
|
252
405
|
check_module_playbooks(text)
|
|
253
|
-
|
|
406
|
+
check_inline_subagent_guidance(text)
|
|
407
|
+
check_pi_subagent_docs()
|
|
408
|
+
check_pi_subagents_extension_guidance()
|
|
254
409
|
check_ignored_not_tracked()
|
|
410
|
+
check_agents_skill_adapter()
|
|
411
|
+
check_claude_metadata()
|
|
412
|
+
check_codex_metadata()
|
|
255
413
|
check_package_json()
|
|
256
414
|
print("validate-keystone: ok")
|
|
257
415
|
return 0
|
|
@@ -30,13 +30,16 @@ REQUIRED = {
|
|
|
30
30
|
"skills/keystone/modules/review.md",
|
|
31
31
|
"skills/keystone/modules/ship.md",
|
|
32
32
|
"skills/keystone/modules/health.md",
|
|
33
|
-
"skills/keystone/modules/helpers/subagents.md",
|
|
34
33
|
"skills/keystone/modules/gates/isolation.md",
|
|
35
34
|
"skills/keystone/modules/gates/proof.md",
|
|
35
|
+
"skills/keystone/modules/gates/red.md",
|
|
36
|
+
"skills/keystone/modules/gates/review.md",
|
|
37
|
+
"skills/keystone/modules/gates/ship.md",
|
|
36
38
|
".claude-plugin/plugin.json",
|
|
37
39
|
".claude-plugin/marketplace.json",
|
|
38
40
|
".codex-plugin/plugin.json",
|
|
39
41
|
".agents/plugins/marketplace.json",
|
|
42
|
+
".agents/skills/keystone/SKILL.md",
|
|
40
43
|
}
|
|
41
44
|
FORBIDDEN_NAMES = {
|
|
42
45
|
"index.html",
|
package/skills/keystone/SKILL.md
CHANGED
|
@@ -18,6 +18,7 @@ Use these common paths unless the user's immediate next action clearly points el
|
|
|
18
18
|
- Product or feature work: `research -> shape -> breakdown -> build -> review -> ship`.
|
|
19
19
|
- Existing plan or approved design: `breakdown -> build -> review -> ship`.
|
|
20
20
|
- Direct implementation request: `build -> review -> ship`, loading `breakdown` first only when execution order or verification is unclear.
|
|
21
|
+
- Bug fix: `debug -> build -> proof gate -> review -> ship`.
|
|
21
22
|
- Debug loop: `debug -> build -> proof gate -> review`; return to `debug` if proof fails or new symptoms appear.
|
|
22
23
|
- Health finding that needs repair: `health -> build` for contained fixes, or `health -> review` when the finding needs independent validation before mutation.
|
|
23
24
|
|
|
@@ -48,7 +49,11 @@ When a module temporarily routes to another module and then resumes, the returni
|
|
|
48
49
|
|
|
49
50
|
## Subagents and reasoning
|
|
50
51
|
|
|
51
|
-
|
|
52
|
+
Use subagents when the active host exposes them and delegation has a clear boundary, useful artifact, and lower coordination cost than doing the work inline.
|
|
53
|
+
|
|
54
|
+
For Pi, Keystone is tuned for `@tintinweb/pi-subagents` (https://github.com/tintinweb/pi-subagents). Install it with `pi install npm:@tintinweb/pi-subagents`. When available, use `Agent` for bounded work, `get_subagent_result` for background results, and `steer_subagent` only to redirect live work. Do not assume named roles, model selection, or thinking controls; use only the fields exposed by the active tool schema.
|
|
55
|
+
|
|
56
|
+
Keep subagents read-only unless mutation is explicitly requested. Use background/parallel agents only for independent tasks with no shared mutable files. Treat subagent output as evidence, not truth; the parent must verify before acting. If the host cannot provide subagents or per-subagent reasoning, include the desired reasoning in the prompt or work inline. Do not invent unsupported subagent tools.
|
|
52
57
|
|
|
53
58
|
## Routing table
|
|
54
59
|
|
|
@@ -57,7 +57,7 @@ Use for new projects, tools, services, apps, packages, or substantial standalone
|
|
|
57
57
|
Use when behavior should remain stable while internals change. Focus on the current behavior contract, compatibility expectations, affected surfaces, consumers, migration seams, adapters, flags, dual-run paths, rollback strategy, observability, and characterization tests. Prefer strangler-style or seam-first slices over broad rewrites.
|
|
58
58
|
|
|
59
59
|
### Subagent-parallel breakdown
|
|
60
|
-
Use when independent workstreams can proceed safely in isolated workspaces. Build the dependency graph before delegation. Name shared files, interfaces, merge-risk hotspots,
|
|
60
|
+
Use when independent workstreams can proceed safely in isolated workspaces. Build the dependency graph before delegation. Name shared files, interfaces, merge-risk hotspots, delegation purpose, desired reasoning intensity, context packets, expected artifacts, integration order, and review checkpoints. Only parallelize slices that can be verified independently or integrated behind a clear contract.
|
|
61
61
|
|
|
62
62
|
## Process
|
|
63
63
|
|
|
@@ -137,12 +137,12 @@ Default reasoning: `high`.
|
|
|
137
137
|
|
|
138
138
|
Use subagents when planning benefits from independent context gathering, critique, or parallel workstream design:
|
|
139
139
|
|
|
140
|
-
-
|
|
141
|
-
- architecture
|
|
142
|
-
- risk
|
|
143
|
-
-
|
|
140
|
+
- read-only research on separate code areas, external APIs, or prior art
|
|
141
|
+
- architecture critique for greenfield foundations and migrations
|
|
142
|
+
- risk critique for security, data loss, compatibility, or release plans
|
|
143
|
+
- implementation delegation only after slices are independent and interfaces are stable
|
|
144
144
|
|
|
145
|
-
For each proposed
|
|
145
|
+
For each proposed delegation, specify purpose, desired reasoning intensity, context packet, expected output artifact, files or areas off limits, and integration/review checkpoint. Do not use subagents to bypass ambiguity. Resolve shared interfaces and sequencing first.
|
|
146
146
|
|
|
147
147
|
## Hard rules
|
|
148
148
|
|
|
@@ -230,7 +230,7 @@ Use this structure unless the user requested a different planning artifact:
|
|
|
230
230
|
- <risk, impact, mitigation>
|
|
231
231
|
|
|
232
232
|
## Subagent opportunities
|
|
233
|
-
- <
|
|
233
|
+
- <delegation purpose, desired reasoning intensity, context packet, expected artifact>
|
|
234
234
|
|
|
235
235
|
## Handoff
|
|
236
236
|
Next module: `<research|build|debug|review|health|ship|shape>` because <reason>.
|
|
@@ -15,7 +15,7 @@ Use Build when the user asks to:
|
|
|
15
15
|
- refactor existing code while preserving behavior
|
|
16
16
|
- change architecture, module boundaries, interfaces, or contracts
|
|
17
17
|
- apply an approved plan from `breakdown`
|
|
18
|
-
- delegate independent implementation work
|
|
18
|
+
- delegate independent implementation work when a subagent tool is available
|
|
19
19
|
- make focused content or configuration changes that require mutation
|
|
20
20
|
|
|
21
21
|
## Not for
|
|
@@ -220,7 +220,7 @@ Escalate to `high` when:
|
|
|
220
220
|
- data loss, security, billing, release, or migration risk exists
|
|
221
221
|
- the user asks for broad refactoring or platform-specific architecture judgment
|
|
222
222
|
|
|
223
|
-
Use subagents
|
|
223
|
+
Use subagents when:
|
|
224
224
|
|
|
225
225
|
- slices can be verified independently
|
|
226
226
|
- files do not overlap, or ownership is explicitly assigned
|
|
@@ -127,7 +127,7 @@ Escalation/stuck criteria:
|
|
|
127
127
|
- Escalation output must include symptom, impact, attempts, disproven hypotheses, missing evidence, requested help/access, and safest next action.
|
|
128
128
|
|
|
129
129
|
## Subagents and reasoning
|
|
130
|
-
Default reasoning: `high`. Use
|
|
130
|
+
Default reasoning: `high`. Use subagents for independent root-cause analysis, log review, performance profile interpretation, bisect planning, or hypothesis generation when the active host exposes safe delegation. Use `xhigh` for intermittent, cross-system, security, performance, data-loss, privacy, destructive, or production-impacting failures.
|
|
131
131
|
|
|
132
132
|
Subagents may inspect and reason independently, but fixes should converge on one evidence-backed root cause. Ask subagents for competing hypotheses and evidence gaps, not broad code review. When subagents disagree, run the smallest test that distinguishes their explanations. Do not let parallel analysis become parallel guess-and-check edits.
|
|
133
133
|
|
|
@@ -64,7 +64,7 @@ Health priority rubric:
|
|
|
64
64
|
9. Stop at reporting unless the user explicitly requested fixes. If repairs are requested, route to the appropriate module instead of silently switching modes.
|
|
65
65
|
|
|
66
66
|
## Subagents and reasoning
|
|
67
|
-
Default reasoning: `medium`. Use read-only
|
|
67
|
+
Default reasoning: `medium`. Use read-only subagents for broad inventory or independent risk triage when the active host exposes safe delegation. Use `high` for release readiness, security-sensitive audits, large monorepos, severe tooling drift, instruction drift affecting agent behavior, or when health findings affect go/no-go decisions. Subagents must remain read-only unless repairs are explicitly requested.
|
|
68
68
|
|
|
69
69
|
## Hard rules
|
|
70
70
|
- Read-only by default: no fixing, formatting, dependency updates, cleanup, generation, or config changes unless explicitly requested.
|
|
@@ -39,7 +39,7 @@ Deliver a research brief that states:
|
|
|
39
39
|
8. Recommend the smallest next step: `shape`, `debug`, `health`, `breakdown`, `build`, `review`, or stop.
|
|
40
40
|
|
|
41
41
|
## Subagents and reasoning
|
|
42
|
-
Default reasoning: `medium`. Use read-only
|
|
42
|
+
Default reasoning: `medium`. Use read-only subagents when the search space is large or evidence can be gathered independently. Use `low` for narrow file summaries. Use `high` when findings affect architecture, security, safety, release decisions, legal/market claims, or irreversible product direction. Subagents must remain read-only unless the user requested an artifact.
|
|
43
43
|
|
|
44
44
|
## Hard rules
|
|
45
45
|
- No mutation by default: do not edit files, run formatters, or alter state except harmless read-only commands.
|
|
@@ -179,7 +179,7 @@ Ask for every non-trivial review:
|
|
|
179
179
|
## Subagents and reasoning
|
|
180
180
|
Default reasoning: `high`.
|
|
181
181
|
|
|
182
|
-
Use read-only
|
|
182
|
+
Use read-only subagents for separable risks: security/privacy, test coverage,
|
|
183
183
|
architecture/API compatibility, persistence/migration, accessibility/user impact,
|
|
184
184
|
performance, concurrency, or release risk. Escalate to `xhigh` for security-sensitive,
|
|
185
185
|
data-loss, billing, permissions, public API, migration, or cross-system reviews.
|
|
@@ -16,7 +16,7 @@ Modify files, perform implementation, or expose internal modules as public slash
|
|
|
16
16
|
One primary module after classification. Gates only if that primary module requires them.
|
|
17
17
|
|
|
18
18
|
## Subagents and reasoning
|
|
19
|
-
Default reasoning: `low`. Do not deploy subagents for simple routing; ask one clarifying question if a safe single route is not clear.
|
|
19
|
+
Default reasoning: `low`. Do not deploy subagents for simple routing; ask one clarifying question if a safe single route is not clear.
|
|
20
20
|
|
|
21
21
|
## Routing heuristics
|
|
22
22
|
Prefer the module indicated by the user's strongest current need, not the first verb alone. Weigh multiple signals together:
|
|
@@ -50,7 +50,7 @@ Deliver a shaped proposal that includes:
|
|
|
50
50
|
9. Stop at the spec boundary. If the user asks for design plus build, finish Shape with the spec and recommended handoff to `build`; do not implement code.
|
|
51
51
|
|
|
52
52
|
## Subagents and reasoning
|
|
53
|
-
Default reasoning: `medium`. Use
|
|
53
|
+
Default reasoning: `medium`. Use subagents for bounded alternatives, critique, or parallel concepts when the active host exposes safe delegation. Use `high` for multi-screen flows, accessibility-sensitive experiences, design-system impact, pricing/positioning, architecture boundaries, or major scope decisions. Subagents should produce options or critique, not unrequested implementation.
|
|
54
54
|
|
|
55
55
|
## Hard rules
|
|
56
56
|
- Shape is not build: do not edit production code or runtime behavior.
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
# Keystone Subagents and Reasoning Helper
|
|
2
|
-
|
|
3
|
-
## Purpose
|
|
4
|
-
Teach Keystone when subagents can be used, which hosts support them, and what reasoning level each Keystone module should prefer.
|
|
5
|
-
|
|
6
|
-
This helper is advisory. Host capability wins over Keystone preference. If the current harness cannot set reasoning per subagent, encode the desired reasoning in the subagent prompt or do the work inline.
|
|
7
|
-
|
|
8
|
-
## Delegation rule
|
|
9
|
-
Use subagents only when the task has a clear boundary and a useful handoff artifact.
|
|
10
|
-
|
|
11
|
-
Good delegation targets:
|
|
12
|
-
- read-only reconnaissance
|
|
13
|
-
- independent implementation slices
|
|
14
|
-
- focused debugging/root-cause analysis
|
|
15
|
-
- read-only review
|
|
16
|
-
- documentation/copy drafting
|
|
17
|
-
|
|
18
|
-
Do not delegate when:
|
|
19
|
-
- the task needs tight conversational clarification
|
|
20
|
-
- one agent must continuously coordinate shared mutable state
|
|
21
|
-
- the host cannot preserve enough context for safe handoff
|
|
22
|
-
- the subagent would need secrets or permissions the parent should not share
|
|
23
|
-
- delegation setup, context packaging, merge/review effort, or verification overhead is likely greater than doing the task inline
|
|
24
|
-
|
|
25
|
-
## Delegation cost heuristic
|
|
26
|
-
|
|
27
|
-
Before spawning a subagent, compare expected benefit with coordination cost.
|
|
28
|
-
|
|
29
|
-
Delegate when at least one is true:
|
|
30
|
-
- the subtask can run in parallel with other independent work
|
|
31
|
-
- the subtask requires a different role, perspective, or reasoning depth
|
|
32
|
-
- the repository/source search is large enough that a scout can save parent context
|
|
33
|
-
- independent review or root-cause analysis materially reduces release risk
|
|
34
|
-
|
|
35
|
-
Do not delegate when most of these are true:
|
|
36
|
-
- the task can be done inline in a few minutes
|
|
37
|
-
- the parent would need to explain more context than the subagent can save
|
|
38
|
-
- outputs will require complex merge arbitration
|
|
39
|
-
- the work touches the same mutable files as another active agent without isolation
|
|
40
|
-
- verification cannot be independently stated in the prompt
|
|
41
|
-
|
|
42
|
-
If uncertain, prefer one narrow read-only scout/reviewer over multiple workers.
|
|
43
|
-
|
|
44
|
-
## Host capability matrix
|
|
45
|
-
|
|
46
|
-
| Harness | Subagents | Per-subagent reasoning/effort | How to configure | Keystone policy |
|
|
47
|
-
|---|---:|---:|---|---|
|
|
48
|
-
| Pi coding agent with `pi-subagents` | yes | yes | `.pi/agents/<name>.md` frontmatter `model`, `thinking`, `profile`, or `Agent({ subagent_type, thinking, model, profile })` | Use native roles; prefer role defaults unless Keystone needs a one-off override. |
|
|
49
|
-
| Claude Code | yes | partial | `.claude/agents/<name>.md` supports subagent config and `model`; built-in Explore accepts quick/medium/very-thorough style detail, but custom agents do not expose a general reasoning knob | Use `model` plus explicit prompt instructions; use built-in Explore detail when applicable. |
|
|
50
|
-
| Codex CLI/app | unclear/host-dependent | partial/global | known global config includes `model_reasoning_effort`; no stable per-subagent effort schema confirmed | Treat Keystone reasoning as advisory text unless the active Codex host exposes a per-agent effort control. |
|
|
51
|
-
| T3 Code | not confirmed | not confirmed | no confirmed public/local schema | Treat as unsupported; run inline or through the underlying Claude/Codex/OpenCode provider if available. |
|
|
52
|
-
| OpenCode | yes | partial/provider-dependent | agent config supports `mode: "subagent"`, `model`, and provider-specific `variant`; no universal reasoning field is confirmed | Use subagent mode; map Keystone reasoning to model/variant only where the provider exposes effort variants, otherwise write the desired reasoning in the prompt. |
|
|
53
|
-
| GitHub Copilot / VS Code | yes | partial | `.github/agents/*.agent.md` supports `model`, `agents`, `user-invocable`, `disable-model-invocation`; no general reasoning knob found | Use custom agents and model choice; put reasoning expectation in the agent prompt. |
|
|
54
|
-
|
|
55
|
-
## Canonical reasoning scale
|
|
56
|
-
|
|
57
|
-
Keystone uses this host-neutral scale:
|
|
58
|
-
|
|
59
|
-
| Level | Use for |
|
|
60
|
-
|---|---|
|
|
61
|
-
| `off` | deterministic formatting, mechanical edits, no reasoning needed |
|
|
62
|
-
| `minimal` | tiny lookups, simple classification, trivial copy changes |
|
|
63
|
-
| `low` | ordinary reading, straightforward writing, small scoped tasks |
|
|
64
|
-
| `medium` | normal implementation, UI decisions, moderate research |
|
|
65
|
-
| `high` | architecture, debugging, review, planning, ambiguous tradeoffs |
|
|
66
|
-
| `xhigh` | hard root-cause analysis, security-sensitive review, major design decisions |
|
|
67
|
-
|
|
68
|
-
If a host uses another vocabulary, map to the nearest equivalent. If no setting exists, write the desired level into the prompt, for example: "Use high reasoning; explore alternatives before deciding."
|
|
69
|
-
|
|
70
|
-
## Keystone module defaults
|
|
71
|
-
|
|
72
|
-
| Keystone file | Preferred role | Default reasoning | Escalate when |
|
|
73
|
-
|---|---|---:|---|
|
|
74
|
-
| `modules/router.md` | none or lightweight classifier | `low` | request is ambiguous across several irreversible actions |
|
|
75
|
-
| `modules/research.md` | scout/read-only explorer or oracle | `medium` | repository is large, source relationships are unclear, or claims affect architecture, market, safety, or release decisions (`high`) |
|
|
76
|
-
| `modules/shape.md` | writer, UI/design reviewer, or oracle | `medium` | visual systems, accessibility, complex positioning, architecture, product viability, or irreversible scope decisions are involved (`high`/`xhigh`) |
|
|
77
|
-
| `modules/breakdown.md` | planner plus reviewer | `high` | plan spans multiple independent agents or risky sequencing (`xhigh`) |
|
|
78
|
-
| `modules/build.md` | worker | `medium` | concurrency, migrations, broad refactors, or unfamiliar stack (`high`) |
|
|
79
|
-
| `modules/debug.md` | oracle/root-cause investigator | `high` | intermittent, cross-system, performance, or data-loss failures (`xhigh`) |
|
|
80
|
-
| `modules/review.md` | reviewer/read-only | `high` | security, release, data migration, or public API review (`xhigh`) |
|
|
81
|
-
| `modules/ship.md` | ship coordinator | `medium` | release has unresolved risk or multi-host packaging (`high`) |
|
|
82
|
-
| `modules/health.md` | scout plus reviewer | `medium` | broad repository/tooling drift or release readiness audit (`high`) |
|
|
83
|
-
| `modules/gates/*.md` | none | `low` | evidence is contradictory or safety-critical (`medium`) |
|
|
84
|
-
|
|
85
|
-
## Pi role mapping
|
|
86
|
-
|
|
87
|
-
When Pi subagents are available, use the narrowest role and usually keep its configured defaults:
|
|
88
|
-
|
|
89
|
-
| Need | Pi role | Typical thinking |
|
|
90
|
-
|---|---|---:|
|
|
91
|
-
| codebase exploration | `scout` | `low` |
|
|
92
|
-
| implementation | `worker` | `medium` |
|
|
93
|
-
| code/spec review | `reviewer` | `high` |
|
|
94
|
-
| architecture/root-cause second opinion | `oracle` | `high` or `xhigh` |
|
|
95
|
-
| docs/copy | `writer` | `low` |
|
|
96
|
-
|
|
97
|
-
Only override `thinking` when the module table says to escalate or de-escalate.
|
|
98
|
-
|
|
99
|
-
## Safe parallel work pattern
|
|
100
|
-
|
|
101
|
-
1. `breakdown` identifies independent tasks and their verification commands.
|
|
102
|
-
2. `build` passes `gates/isolation.md` before any mutation.
|
|
103
|
-
3. If the host supports isolated worktrees, each worker gets a separate worktree or host-isolated workspace.
|
|
104
|
-
4. Each worker reports files changed, tests run, and concerns.
|
|
105
|
-
5. Parent reconciles outputs before further mutation: accept, reject, or send back with a narrower prompt.
|
|
106
|
-
6. `review` runs as read-only, preferably in a separate reviewer subagent.
|
|
107
|
-
7. `ship` finalizes only after proof and review gates pass.
|
|
108
|
-
|
|
109
|
-
## Prompt contract for delegated work
|
|
110
|
-
|
|
111
|
-
Every subagent prompt should include:
|
|
112
|
-
|
|
113
|
-
- exact task scope
|
|
114
|
-
- files or areas allowed to change/read
|
|
115
|
-
- protected files
|
|
116
|
-
- expected output artifact or report
|
|
117
|
-
- reasoning level requested if the host cannot enforce it
|
|
118
|
-
- verification command expected
|
|
119
|
-
- instruction not to broaden scope
|
|
120
|
-
- timeout or stopping condition when the host supports it
|
|
121
|
-
|
|
122
|
-
For read-only subagents, explicitly say: "Do not edit files." For review subagents, explicitly say: "Return findings only; do not fix."
|
|
123
|
-
|
|
124
|
-
## Subagent result handling
|
|
125
|
-
|
|
126
|
-
Treat subagent output as evidence, not truth. The parent remains responsible for verification and final routing.
|
|
127
|
-
|
|
128
|
-
- Timeout or no response: mark the subtask incomplete, preserve any partial logs, and either finish inline or re-delegate with a smaller scope if the remaining work is still worth the overhead.
|
|
129
|
-
- Bad output or scope creep: reject the result, record why, and re-delegate only with a tighter prompt, protected-file list, and explicit expected artifact. Otherwise do it inline.
|
|
130
|
-
- Partial completion: accept only independently verified pieces; carry unfinished work in the handoff packet with files touched, tests run, and remaining risks.
|
|
131
|
-
- Conflicting outputs: compare evidence and reproduction/proof commands first. If both are plausible and risk is material, ask an oracle/reviewer for read-only arbitration or route to `debug`; do not merge contradictory fixes blindly.
|
|
132
|
-
- Failed verification: route through the appropriate Keystone module (`debug` for unexplained failures, `build` for contained fixes, `review` for risk assessment) and rerun the original proof before continuing.
|
|
133
|
-
|
|
134
|
-
Re-delegate only when the next prompt can be narrower than the failed one, the expected artifact is concrete, and the benefit still exceeds coordination cost. Otherwise continue inline and record the reason.
|