@static-var/keystone 0.1.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/README.md ADDED
@@ -0,0 +1,253 @@
1
+ # Keystone
2
+
3
+ > One public `/keystone` doorway for disciplined AI workflows.
4
+
5
+ Keystone is a hybrid workflow/skill system for coding agents. It keeps the public surface small, routes each request to one internal module, and uses gates to prevent the common failure modes: editing too early, planning without proof, reviewing while mutating, or shipping unverified work.
6
+
7
+ Keystone borrows the best parts of Waza-style routing/review/release discipline and Superpowers-style planning, TDD, debugging, and verification habits.
8
+
9
+ ## What Keystone gives you
10
+
11
+ - **One public entrypoint:** `/keystone`
12
+ - **Private internal modules:** router, research, shape, breakdown, build, debug, review, ship, and health
13
+ - **A renamed planner:** `breakdown`, not `plan`, to avoid `/plan` collisions
14
+ - **Safety gates:** isolation, red, proof, review, and ship
15
+ - **Subagent guidance:** host capability matrix plus recommended reasoning level per module
16
+ - **Package tooling:** generated platform manifests, allowlisted archive builds, validators, and routing tests
17
+ - **Multi-host packaging:** Pi extension + skill package metadata plus Claude/Codex/agents plugin manifests
18
+
19
+ ## Quick start
20
+
21
+ ```bash
22
+ # Validate source, package, routing fixtures, and Python scripts
23
+ make test
24
+
25
+ # Regenerate host metadata
26
+ make regenerate
27
+
28
+ # Build the distributable archive
29
+ make package
30
+ ```
31
+
32
+ The package archive is written to:
33
+
34
+ ```text
35
+ dist/keystone.zip
36
+ ```
37
+
38
+ `dist/` is generated and ignored by git.
39
+
40
+ Install in Pi from npm after release:
41
+
42
+ ```bash
43
+ pi install npm:@static-var/keystone
44
+ ```
45
+
46
+ Or install directly from GitHub:
47
+
48
+ ```bash
49
+ pi install git:github.com/static-var/Keystone
50
+ ```
51
+
52
+ Then invoke:
53
+
54
+ ```text
55
+ /keystone <task>
56
+ ```
57
+
58
+ Pi package gallery listing: once `@static-var/keystone` is published to npm with the `pi-package` keyword, it appears on `https://pi.dev/packages`.
59
+
60
+ ## How it works in one picture
61
+
62
+ ```text
63
+ User request
64
+
65
+
66
+ /keystone public skill
67
+
68
+
69
+ Router chooses exactly one primary module
70
+
71
+ ├─ router / research / shape / breakdown
72
+ └─ build / debug / review / ship / health
73
+
74
+
75
+ Module contract decides what is allowed
76
+
77
+
78
+ Gate checks when required
79
+
80
+ ├─ isolation: safe before mutation
81
+ ├─ red: failing check before implementation when practical
82
+ ├─ proof: evidence before success claims
83
+ ├─ review: no blocking review findings
84
+ └─ ship: verified, reviewed, ready to hand off
85
+ ```
86
+
87
+ ## Core rule
88
+
89
+ Keystone exposes **one public skill**:
90
+
91
+ ```text
92
+ skills/keystone/SKILL.md
93
+ ```
94
+
95
+ Everything else under `skills/keystone/modules/` is internal. Internal modules are not public slash commands.
96
+
97
+ ## Routing map
98
+
99
+ | User wants to... | Keystone routes to... |
100
+ |---|---|
101
+ | classify an ambiguous request | `router` |
102
+ | inspect, summarize, research, or compare sources | `research` |
103
+ | draft prose, shape product direction, design UI, or make architecture/scope tradeoffs | `shape` |
104
+ | turn approved direction into tasks | `breakdown` |
105
+ | edit files or implement work | `build` |
106
+ | diagnose bugs or failures | `debug` |
107
+ | review work without changing it | `review` |
108
+ | finalize completed work | `ship` |
109
+ | assess project/tooling health | `health` |
110
+
111
+ ## Repository-only maintainer notes
112
+
113
+ Keystone maintainer guidance can live in the repository without shipping as product. Current maintainer-only notes are in:
114
+
115
+ ```text
116
+ maintainers/skill-engineering.md
117
+ ```
118
+
119
+ This file is not included in `dist/keystone.zip` and is not part of `/keystone` routing.
120
+
121
+ ## Repository layout
122
+
123
+ ```text
124
+ .
125
+ ├── skills/keystone/ # canonical skill source
126
+ │ ├── SKILL.md # public /keystone entrypoint
127
+ │ └── modules/ # internal modules, helpers, and gates
128
+ ├── scripts/ # metadata, validation, packaging
129
+ ├── tests/routing/cases.yaml # routing fixture cases
130
+ ├── tests/test_routing.py # stdlib routing test runner
131
+ ├── maintainers/ # repo-only, not shipped in package
132
+ ├── .claude-plugin/ # generated Claude plugin metadata
133
+ ├── .codex-plugin/ # generated Codex plugin metadata
134
+ ├── .agents/plugins/ # generated agents marketplace metadata
135
+ ├── packaging.allowlist # default-deny package contents
136
+ ├── Makefile # test/package/regenerate targets
137
+ └── HOW_IT_WORKS.md # human-readable architecture guide
138
+ ```
139
+
140
+ ## Subagent and reasoning support
141
+
142
+ Keystone documents host-specific subagent support in:
143
+
144
+ ```text
145
+ skills/keystone/modules/helpers/subagents.md
146
+ ```
147
+
148
+ Current summary:
149
+
150
+ | Harness | Subagents | Per-subagent reasoning |
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 |
158
+
159
+ Each Keystone module includes a `Subagents and reasoning` section with its default reasoning level.
160
+
161
+ ## Platform support
162
+
163
+ Keystone currently ships as:
164
+
165
+ - **Pi extension + skill package** via `package.json`:
166
+ ```json
167
+ {
168
+ "pi": {
169
+ "extensions": ["./.pi/extensions/keystone.ts"],
170
+ "skills": ["./skills"]
171
+ }
172
+ }
173
+ ```
174
+ - **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 metadata** in `.claude-plugin/`
176
+ - **Codex plugin metadata** in `.codex-plugin/`
177
+ - **Agents marketplace metadata** in `.agents/plugins/`
178
+
179
+ ## Release automation
180
+
181
+ Pi package discovery is npm-based. The package name is `@static-var/keystone`; the unscoped `keystone` name is already taken on npm.
182
+
183
+ CI/CD:
184
+
185
+ - `.github/workflows/ci.yml` runs on PRs and `main`: `npm ci`, Pi extension typecheck, `make test`, npm pack dry-run, and uploads `dist/keystone.zip`.
186
+ - `.github/workflows/release.yml` runs on `v*.*.*` tags or manual dispatch: verifies the tag matches `package.json` version, validates, publishes to npm through Trusted Publishing/OIDC with provenance, and creates a GitHub Release with both `dist/keystone.zip` and the npm tarball.
187
+
188
+ Trusted Publishing setup on npm:
189
+
190
+ 1. Confirm you own the npm scope in `package.json`. Keystone currently publishes as `@static-var/keystone`; if your npm username/org is different, rename the package before publishing.
191
+ 2. Bootstrap the package once, because npm only shows the package access / Trusted Publisher UI after the package exists:
192
+ ```bash
193
+ npm login
194
+ npm run typecheck
195
+ make test
196
+ npm publish --access public --provenance=false
197
+ ```
198
+ If npm requires 2FA, append `--otp <code>`. Local bootstrap disables provenance because provenance is provided by future OIDC releases.
199
+ 3. Open `https://www.npmjs.com/package/@static-var/keystone/access`.
200
+ 4. In **Trusted Publisher**, choose **GitHub Actions**.
201
+ 5. Configure:
202
+ - Organization or user: `static-var`
203
+ - Repository: `Keystone`
204
+ - Workflow filename: `release.yml`
205
+ - Environment name: leave blank unless you add a GitHub deployment environment
206
+ - Allowed actions: `npm publish`
207
+ 6. Save. Future releases use OIDC; no `NPM_TOKEN` secret is needed.
208
+
209
+ Release:
210
+
211
+ ```bash
212
+ npm version patch --no-git-tag-version # or minor/major; edit changelog if added later
213
+ make test
214
+ VERSION=$(node -p "require('./package.json').version")
215
+ git add package.json package-lock.json
216
+ git commit -m "chore: release v${VERSION}"
217
+ git tag "v${VERSION}"
218
+ git push origin main --tags
219
+ ```
220
+
221
+ ## Maintainer commands
222
+
223
+ ```bash
224
+ make regenerate # rebuild generated plugin/marketplace metadata
225
+ make validate # build package, validate source, validate archive
226
+ make routing # run routing fixture tests
227
+ make package # write dist/keystone.zip from packaging.allowlist
228
+ make test # run the full local check suite
229
+ npm run typecheck # typecheck the Pi extension
230
+ npm run pack:dry-run # preview npm package contents
231
+ ```
232
+
233
+ ## Guardrails
234
+
235
+ - Do not add public slash commands for internal modules.
236
+ - Do not rename `breakdown` to `plan`.
237
+ - Do not let `build` edit before the isolation gate.
238
+ - Do not let `review` fix, commit, or ship.
239
+ - Do not let `ship` start new implementation.
240
+ - Do not hand-edit generated manifests; update source and run `make regenerate`.
241
+ - Do not package ignored local artifacts such as `index.html`, `styles.css`, `plans/`, `docs/`, `dist/`, or pycache files.
242
+
243
+ ## Read next
244
+
245
+ For the full mental model, routing lifecycle, packaging flow, and maintainer workflow, read:
246
+
247
+ ```text
248
+ HOW_IT_WORKS.md
249
+ ```
250
+
251
+ ## License
252
+
253
+ MIT
package/package.json ADDED
@@ -0,0 +1,86 @@
1
+ {
2
+ "name": "@static-var/keystone",
3
+ "version": "0.1.0",
4
+ "description": "Keystone: one-router AI engineering workflow extension and skill system for Pi.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/static-var/Keystone.git"
10
+ },
11
+ "bugs": {
12
+ "url": "https://github.com/static-var/Keystone/issues"
13
+ },
14
+ "homepage": "https://github.com/static-var/Keystone#readme",
15
+ "keywords": [
16
+ "pi-package",
17
+ "agent-skills",
18
+ "keystone",
19
+ "claude-code",
20
+ "codex",
21
+ "opencode",
22
+ "copilot",
23
+ "pi-coding-agent",
24
+ "pi-extension",
25
+ "workflow",
26
+ "skills",
27
+ "agent-workflows"
28
+ ],
29
+ "files": [
30
+ "README.md",
31
+ "HOW_IT_WORKS.md",
32
+ "package.json",
33
+ "packaging.allowlist",
34
+ "Makefile",
35
+ "scripts/build-metadata.py",
36
+ "scripts/validate-keystone.py",
37
+ "scripts/validate-package.py",
38
+ "scripts/package-keystone.sh",
39
+ "skills/keystone/SKILL.md",
40
+ "skills/keystone/modules/router.md",
41
+ "skills/keystone/modules/research.md",
42
+ "skills/keystone/modules/shape.md",
43
+ "skills/keystone/modules/breakdown.md",
44
+ "skills/keystone/modules/build.md",
45
+ "skills/keystone/modules/debug.md",
46
+ "skills/keystone/modules/review.md",
47
+ "skills/keystone/modules/ship.md",
48
+ "skills/keystone/modules/health.md",
49
+ "skills/keystone/modules/helpers/subagents.md",
50
+ "skills/keystone/modules/gates/isolation.md",
51
+ "skills/keystone/modules/gates/proof.md",
52
+ "skills/keystone/modules/gates/red.md",
53
+ "skills/keystone/modules/gates/review.md",
54
+ "skills/keystone/modules/gates/ship.md",
55
+ ".claude-plugin/plugin.json",
56
+ ".claude-plugin/marketplace.json",
57
+ ".codex-plugin/plugin.json",
58
+ ".agents/plugins/marketplace.json",
59
+ ".pi/extensions/keystone.ts"
60
+ ],
61
+ "publishConfig": {
62
+ "access": "public",
63
+ "provenance": true
64
+ },
65
+ "pi": {
66
+ "extensions": [
67
+ "./.pi/extensions/keystone.ts"
68
+ ],
69
+ "skills": [
70
+ "./skills"
71
+ ]
72
+ },
73
+ "devDependencies": {
74
+ "@earendil-works/pi-coding-agent": "0.80.2",
75
+ "@types/node": "26.0.1",
76
+ "typescript": "6.0.3"
77
+ },
78
+ "scripts": {
79
+ "regenerate": "python3 scripts/build-metadata.py",
80
+ "validate": "make validate",
81
+ "package": "scripts/package-keystone.sh",
82
+ "test": "make test",
83
+ "typecheck": "tsc --noEmit --target ES2022 --module NodeNext --moduleResolution NodeNext --skipLibCheck .pi/extensions/keystone.ts",
84
+ "pack:dry-run": "npm pack --dry-run"
85
+ }
86
+ }
@@ -0,0 +1,32 @@
1
+ # Default-deny shipping allowlist for Keystone packaging.
2
+ # Entries are newline-delimited paths relative to the repository root.
3
+ README.md
4
+ HOW_IT_WORKS.md
5
+ package.json
6
+ packaging.allowlist
7
+ Makefile
8
+ scripts/build-metadata.py
9
+ scripts/validate-keystone.py
10
+ scripts/validate-package.py
11
+ scripts/package-keystone.sh
12
+ skills/keystone/SKILL.md
13
+ skills/keystone/modules/router.md
14
+ skills/keystone/modules/research.md
15
+ skills/keystone/modules/shape.md
16
+ skills/keystone/modules/breakdown.md
17
+ skills/keystone/modules/build.md
18
+ skills/keystone/modules/debug.md
19
+ skills/keystone/modules/review.md
20
+ skills/keystone/modules/ship.md
21
+ skills/keystone/modules/health.md
22
+ skills/keystone/modules/helpers/subagents.md
23
+ skills/keystone/modules/gates/isolation.md
24
+ skills/keystone/modules/gates/proof.md
25
+ skills/keystone/modules/gates/red.md
26
+ skills/keystone/modules/gates/review.md
27
+ skills/keystone/modules/gates/ship.md
28
+ .claude-plugin/plugin.json
29
+ .claude-plugin/marketplace.json
30
+ .codex-plugin/plugin.json
31
+ .agents/plugins/marketplace.json
32
+ .pi/extensions/keystone.ts
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env python3
2
+ """Generate Keystone platform metadata from the canonical skill source."""
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import re
7
+ from pathlib import Path
8
+
9
+ ROOT = Path(__file__).resolve().parents[1]
10
+ SKILL = ROOT / "skills" / "keystone" / "SKILL.md"
11
+ PACKAGE = ROOT / "package.json"
12
+ NAME = "keystone"
13
+
14
+
15
+ def read_package() -> dict:
16
+ if PACKAGE.exists():
17
+ return json.loads(PACKAGE.read_text())
18
+ return {}
19
+
20
+
21
+ def parse_frontmatter(text: str) -> dict:
22
+ if not text.startswith("---\n"):
23
+ return {}
24
+ end = text.find("\n---", 4)
25
+ if end == -1:
26
+ return {}
27
+ data: dict[str, object] = {}
28
+ current_key = None
29
+ for raw in text[4:end].splitlines():
30
+ line = raw.rstrip()
31
+ if not line or line.lstrip().startswith("#"):
32
+ continue
33
+ if line.startswith(" - ") and current_key:
34
+ data.setdefault(current_key, []).append(line[4:].strip().strip('"\''))
35
+ continue
36
+ if ":" in line:
37
+ key, value = line.split(":", 1)
38
+ current_key = key.strip()
39
+ value = value.strip()
40
+ if value == "":
41
+ data[current_key] = []
42
+ else:
43
+ data[current_key] = value.strip('"\'')
44
+ return data
45
+
46
+
47
+ def skill_summary(text: str) -> str:
48
+ fm = parse_frontmatter(text)
49
+ for key in ("description", "summary"):
50
+ if isinstance(fm.get(key), str) and fm[key]:
51
+ return str(fm[key])
52
+ match = re.search(r"^#\s+(.+)$", text, re.M)
53
+ if match:
54
+ return match.group(1).strip()
55
+ return "Keystone skill."
56
+
57
+
58
+ def write_json(path: Path, data: dict) -> None:
59
+ path.parent.mkdir(parents=True, exist_ok=True)
60
+ path.write_text(json.dumps(data, indent=2, sort_keys=True) + "\n")
61
+
62
+
63
+ def main() -> int:
64
+ package = read_package()
65
+ skill_text = SKILL.read_text() if SKILL.exists() else ""
66
+ fm = parse_frontmatter(skill_text)
67
+ description = skill_summary(skill_text) if skill_text else package.get("description", "Keystone skill.")
68
+ version = package.get("version", "0.0.0")
69
+ license_name = package.get("license", "UNLICENSED")
70
+ keywords = package.get("keywords", ["keystone", "skill"])
71
+
72
+ plugin = {
73
+ "name": NAME,
74
+ "version": version,
75
+ "description": description,
76
+ "license": license_name,
77
+ "skills": [{"name": NAME, "path": "../skills/keystone/SKILL.md"}],
78
+ }
79
+ marketplace = {
80
+ "name": NAME,
81
+ "displayName": "Keystone",
82
+ "version": version,
83
+ "description": description,
84
+ "license": license_name,
85
+ "keywords": keywords,
86
+ "skills": [NAME],
87
+ }
88
+ if isinstance(fm.get("author"), str):
89
+ marketplace["author"] = fm["author"]
90
+
91
+ write_json(ROOT / ".claude-plugin" / "plugin.json", plugin)
92
+ write_json(ROOT / ".claude-plugin" / "marketplace.json", marketplace)
93
+ write_json(ROOT / ".codex-plugin" / "plugin.json", plugin)
94
+ write_json(ROOT / ".agents" / "plugins" / "marketplace.json", marketplace)
95
+ return 0
96
+
97
+
98
+ if __name__ == "__main__":
99
+ raise SystemExit(main())
@@ -0,0 +1,59 @@
1
+ #!/bin/sh
2
+ set -eu
3
+
4
+ ROOT=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
5
+ ALLOWLIST="$ROOT/packaging.allowlist"
6
+ DIST="$ROOT/dist"
7
+ ARCHIVE="$DIST/keystone.zip"
8
+ TMP_LIST="$DIST/keystone.files"
9
+
10
+ cd "$ROOT"
11
+
12
+ if [ ! -f "$ALLOWLIST" ]; then
13
+ echo "package-keystone: missing packaging.allowlist" >&2
14
+ exit 1
15
+ fi
16
+
17
+ python3 scripts/build-metadata.py
18
+ python3 scripts/validate-keystone.py
19
+
20
+ mkdir -p "$DIST"
21
+ : > "$TMP_LIST"
22
+
23
+ while IFS= read -r path || [ -n "$path" ]; do
24
+ case "$path" in
25
+ ''|'#'*) continue ;;
26
+ esac
27
+ case "$path" in
28
+ docs|docs/*|plans|plans/*|maintainers|maintainers/*|index.html|styles.css|.git|.git/*|dist|dist/*|skill-engineering.md|*/skill-engineering.md|*.plan.md|*-plan.md|*.design.md|*-design.md|*/__pycache__/*|*.pyc|.DS_Store)
29
+ echo "package-keystone: forbidden allowlist entry: $path" >&2
30
+ exit 1
31
+ ;;
32
+ esac
33
+ if [ ! -e "$path" ]; then
34
+ echo "package-keystone: allowlisted path missing: $path" >&2
35
+ exit 1
36
+ fi
37
+ if [ -d "$path" ]; then
38
+ find "$path" -type f \
39
+ ! -name '.DS_Store' \
40
+ ! -name '*.pyc' \
41
+ ! -path '*/__pycache__/*' \
42
+ ! -path 'docs/*' \
43
+ ! -path 'plans/*' \
44
+ ! -path 'maintainers/*' \
45
+ ! -name 'skill-engineering.md' \
46
+ ! -name '*.plan.md' \
47
+ ! -name '*-plan.md' \
48
+ ! -name '*.design.md' \
49
+ ! -name '*-design.md' >> "$TMP_LIST"
50
+ else
51
+ printf '%s\n' "$path" >> "$TMP_LIST"
52
+ fi
53
+ done < "$ALLOWLIST"
54
+
55
+ sort -u "$TMP_LIST" -o "$TMP_LIST"
56
+ rm -f "$ARCHIVE"
57
+ zip -q -X "$ARCHIVE" -@ < "$TMP_LIST"
58
+ python3 scripts/validate-package.py "$ARCHIVE"
59
+ echo "package-keystone: wrote $ARCHIVE"