@zalom/plastic 1.0.0-alpha.9 → 1.0.0-beta.2
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/PLASTIC.md +163 -469
- package/README.md +95 -58
- package/agents/plastic-brainstorming.md +37 -0
- package/agents/plastic-enforcer.md +36 -0
- package/agents/plastic-executor.md +37 -0
- package/agents/{future-intent-researcher.md → plastic-future-intent-researcher.md} +1 -1
- package/agents/{intent-curator.md → plastic-intent-curator.md} +1 -1
- package/agents/plastic-planner.md +37 -0
- package/agents/plastic-spec-specialist.md +37 -0
- package/bin/plastic.js +57 -0
- package/bin/test +28 -0
- package/deprecations.yml +1 -10
- package/hooks/auto-arm +5 -0
- package/hooks/bash-gate +3 -0
- package/hooks/check-update +12 -8
- package/hooks/code-gate +12 -0
- package/hooks/create-gate +3 -0
- package/hooks/gate-check +3 -1
- package/hooks/hooks.json +52 -0
- package/hooks/qmd-search +8 -0
- package/package.json +2 -2
- package/scripts/dashboard.rb +687 -0
- package/scripts/doctor.rb +1054 -628
- package/scripts/hook-auto-arm +51 -0
- package/scripts/hook-bash-gate +41 -0
- package/scripts/hook-code-gate +27 -0
- package/scripts/hook-continue +15 -114
- package/scripts/hook-create-gate +59 -0
- package/scripts/hook-gate-check +47 -32
- package/scripts/hook-qmd-search +44 -0
- package/scripts/hook-session-start +106 -38
- package/scripts/install.rb +91 -529
- package/scripts/lib/boot_banner.rb +28 -0
- package/scripts/lib/bridge.rb +404 -19
- package/scripts/lib/installer_core.rb +807 -0
- package/scripts/lib/intent_validator.rb +235 -0
- package/scripts/lib/qmd_hook.rb +44 -0
- package/scripts/lib/qmd_sync.rb +209 -0
- package/scripts/lib/store_provisioning.rb +100 -0
- package/scripts/migrate-to-global +1 -1
- package/scripts/new-intent +226 -0
- package/scripts/provision-project-store +53 -0
- package/scripts/qmd-sync +92 -0
- package/scripts/select-update-target +93 -0
- package/scripts/spawn-preamble +121 -0
- package/scripts/uninstall.rb +53 -0
- package/scripts/update.rb +164 -0
- package/scripts/validate-intent +54 -0
- package/scripts/versions.rb +141 -0
- package/skills/_active-intent-gate.md +1 -1
- package/skills/add-project-store/SKILL.md +54 -0
- package/skills/auto/SKILL.md +77 -7
- package/skills/auto/evals/evals.json +207 -0
- package/skills/auto/references/agent-architecture.md +135 -0
- package/skills/brainstorming/SKILL.md +9 -9
- package/skills/brainstorming-grill-me/SKILL.md +6 -6
- package/skills/continuing/SKILL.md +92 -82
- package/skills/continuing/evals/evals.json +136 -0
- package/skills/continuing/references/context-management.md +32 -0
- package/skills/creating-intent/SKILL.md +74 -36
- package/skills/creating-intent/evals/evals.json +56 -0
- package/skills/creating-intent/references/lifecycle.md +76 -0
- package/skills/creating-intent/references/wikilinks.md +8 -0
- package/skills/creating-project/SKILL.md +40 -8
- package/skills/creating-project/references/hubs-projects.md +55 -0
- package/skills/dashboard/SKILL.md +121 -0
- package/skills/dashboard/templates/dashboard-global.md +31 -0
- package/skills/dashboard/templates/dashboard-project.md +40 -0
- package/skills/doctor/SKILL.md +51 -4
- package/skills/doctor/references/gates-stuck-detection.md +38 -0
- package/skills/doctor/report.md +4 -0
- package/skills/evaluating-skills/SKILL.md +140 -0
- package/skills/evaluating-skills/assets/eval-template.json +12 -0
- package/skills/evaluating-skills/evals/evals.json +75 -0
- package/skills/evaluating-skills/references/convention-checks.md +76 -0
- package/skills/evaluating-skills/references/eval-methodology.md +154 -0
- package/skills/executing-plan/SKILL.md +5 -3
- package/skills/install/SKILL.md +69 -8
- package/skills/intent-curator/SKILL.md +3 -3
- package/skills/linking-intents/SKILL.md +16 -7
- package/skills/linking-intents/references/zettelkasten.md +38 -0
- package/skills/managing-index/SKILL.md +5 -1
- package/skills/managing-index/references/zettelkasten-linking.md +1 -1
- package/skills/releasing/SKILL.md +80 -23
- package/skills/releasing/references/deprecations.md +60 -0
- package/skills/research/SKILL.md +2 -2
- package/skills/savepoint/SKILL.md +46 -37
- package/skills/savepoint/references/context-management.md +32 -0
- package/skills/uninstall/SKILL.md +39 -28
- package/skills/update/SKILL.md +41 -44
- package/skills/versions/SKILL.md +65 -0
- package/skills/writing-instructions/SKILL.md +159 -0
- package/skills/writing-instructions/references/agentskills-spec.md +135 -0
- package/skills/writing-plans/SKILL.md +5 -5
- package/templates/agents.md +7 -7
- package/templates/outcome.md +13 -0
- package/templates/savepoint.md +14 -13
- package/templates/spec.md +25 -0
- package/bin/install.js +0 -29
package/README.md
CHANGED
|
@@ -1,87 +1,124 @@
|
|
|
1
1
|
# Plastic
|
|
2
2
|
|
|
3
|
-
>
|
|
4
|
-
>
|
|
3
|
+
> **Alpha software.** Expect breaking changes between releases.
|
|
4
|
+
> Install: `npx @zalom/plastic@alpha --claude`
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
Intent-driven idea development system for AI coding agents. Named after
|
|
7
|
+
**neuroplasticity**: adaptive, malleable, dynamic, resilient.
|
|
7
8
|
|
|
8
|
-
Plastic
|
|
9
|
+
Plastic thinks in **intents**, not tasks. An intent is a desire, something
|
|
10
|
+
you want to accomplish, explore, or understand. Intents are atomic thoughts
|
|
11
|
+
that get developed through two nested processes.
|
|
9
12
|
|
|
10
|
-
##
|
|
13
|
+
## The Two Cycles
|
|
11
14
|
|
|
12
|
-
|
|
15
|
+
**Coordinator loop (B→O→R):** Brainstorm → Organize → Review. The human and
|
|
16
|
+
agent explore ideas, structure them into intents, and validate the results.
|
|
17
|
+
This loop runs continuously across sessions.
|
|
13
18
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
```
|
|
19
|
+
**Intent lifecycle (W→W→H→E):** Why → What → How → Execute. Each intent moves
|
|
20
|
+
from motivation through specification, planning, to delivery. Intents produce
|
|
21
|
+
artifacts: `spec.md`, `plan.md`, `checklist.md`, `outcome.md`.
|
|
18
22
|
|
|
19
|
-
|
|
23
|
+
## How Plastic Works
|
|
20
24
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
/plugin add plastic@plastic
|
|
24
|
-
```
|
|
25
|
+
Plastic is a **thinking system**, a blueprint for taking a desire from intent to
|
|
26
|
+
delivery. It splits the work in two:
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
- **The blueprint (deterministic).** The conventions, templates, directory structure,
|
|
29
|
+
lifecycle, and linking rules. This is *how to fill in the work*, and it comes out
|
|
30
|
+
identically no matter who or what is working.
|
|
31
|
+
- **The brain (non-deterministic).** The human or LLM that does the actual thinking.
|
|
32
|
+
Plastic never replaces it. It only **steers and validates** it.
|
|
27
33
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
Determinism lives in the **form** of the work (section sets, ordering, schemas, naming,
|
|
35
|
+
IDs, file layout), never in the brain's reasoning. The framework stays constant while the
|
|
36
|
+
thinking varies. Run Plastic on Claude Code, Codex, Hermes, OpenClaw, or by hand on paper
|
|
37
|
+
in Obsidian or Word, and the only thing that changes is the *quality of thought*. The
|
|
38
|
+
proof is the paper test: if a person with no tooling and no AI can reproduce a
|
|
39
|
+
correctly-shaped intent, the determinism is in the form, not the agent.
|
|
32
40
|
|
|
33
|
-
|
|
41
|
+
**Deterministic by design, free by intent.** The rigid part is rigid on purpose. It is
|
|
42
|
+
what makes work portable, reviewable, and resumable across any agent. The free part is
|
|
43
|
+
free on purpose. It is where the brain's creativity lives. Plastic draws the line between
|
|
44
|
+
the two and holds it.
|
|
34
45
|
|
|
35
|
-
**
|
|
46
|
+
**Harnesses are how it holds the line.** Shared harnesses (conventions, templates, and
|
|
47
|
+
directory structure) constrain humans and agents alike. Agent-extra harnesses (evals that
|
|
48
|
+
check a skill's output, plus hooks and instructions that steer reasoning) give an agent
|
|
49
|
+
the instincts a careful person already has: stop and save state, leave a note when the
|
|
50
|
+
context runs out, never plan before specifying.
|
|
36
51
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
52
|
+
This is **intent-driven delivery**, a new shape for the software lifecycle in the age of
|
|
53
|
+
agentic engineering. The unit of work is an *intent*, not a ticket, and every intent
|
|
54
|
+
carries its own spec, plan, checklist, and outcome as it moves through Why, What, How, and
|
|
55
|
+
Execute. What you get is agent-agnostic, auditable, and additive: a knowledge graph of
|
|
56
|
+
*why* things were built, not just what.
|
|
40
57
|
|
|
41
|
-
|
|
58
|
+
## Install
|
|
42
59
|
|
|
43
|
-
|
|
44
|
-
|
|
60
|
+
Plastic requires Ruby (pre-installed on macOS/Linux) and Node.js 18+.
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# Alpha (current, active development)
|
|
64
|
+
npx @zalom/plastic@alpha --claude
|
|
65
|
+
|
|
66
|
+
# Beta (when available, API-stable, bug hunting)
|
|
67
|
+
npx @zalom/plastic@beta --claude
|
|
68
|
+
|
|
69
|
+
# Stable (when available, general use)
|
|
70
|
+
npx @zalom/plastic --claude
|
|
45
71
|
```
|
|
46
72
|
|
|
47
|
-
|
|
73
|
+
Replace `--claude` with `--codex` for Codex CLI, `--hermes` for Hermes, or
|
|
74
|
+
`--all` for all supported agents.
|
|
48
75
|
|
|
49
|
-
|
|
76
|
+
Bun users can substitute `bunx` for `npx` (e.g. `bunx @zalom/plastic@alpha --claude`).
|
|
77
|
+
Bun is never required.
|
|
50
78
|
|
|
51
|
-
|
|
79
|
+
Skills install as flat, hyphen-namespaced personal skills (`plastic-doctor`,
|
|
80
|
+
`plastic-auto`, and so on). Invoke them with a hyphen. Plastic is **not** a Claude Code
|
|
81
|
+
plugin; re-running the installer auto-removes any legacy plugin registration.
|
|
52
82
|
|
|
83
|
+
### Updating
|
|
84
|
+
|
|
85
|
+
From within your agent, say "update plastic" or run:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
npx @zalom/plastic@alpha --claude
|
|
53
89
|
```
|
|
54
|
-
.plastic/
|
|
55
|
-
├── AGENTS.md # Conventions contract for all agents
|
|
56
|
-
├── config.yml # Plugin configuration
|
|
57
|
-
├── INDEX.md # Brain's entry point
|
|
58
|
-
└── store/
|
|
59
|
-
└── ID--three-to-five-words/
|
|
60
|
-
├── {ID}--{slug}.md # Always present (e.g., 1a1--design-plastic.md)
|
|
61
|
-
├── spec.md # Optional (brainstorming output)
|
|
62
|
-
├── plan.md # Optional (implementation plan)
|
|
63
|
-
├── checklist.md # Optional (progress tracking)
|
|
64
|
-
└── savepoint.md # Optional (session state)
|
|
65
|
-
```
|
|
66
90
|
|
|
67
|
-
|
|
91
|
+
The `plastic-update` command shows available versions across all channels and
|
|
92
|
+
lets you choose which to install.
|
|
93
|
+
|
|
94
|
+
## Quick Start
|
|
95
|
+
|
|
96
|
+
After installation, run `/clear` to load Plastic conventions, then:
|
|
97
|
+
|
|
98
|
+
1. Say "new intent" or run `/plastic-creating-intent` to create your first intent
|
|
99
|
+
2. Describe what you want to accomplish
|
|
100
|
+
3. Use `/plastic-brainstorming` to explore the design
|
|
101
|
+
4. Use `/plastic-writing-plans` to create an implementation plan
|
|
102
|
+
5. Use `/plastic-executing-plan` to deliver it
|
|
103
|
+
|
|
104
|
+
Or say "auto" to let the agent handle the full lifecycle autonomously.
|
|
105
|
+
|
|
106
|
+
## Documentation
|
|
68
107
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
| `savepoint` | Save active intent state before context reset |
|
|
74
|
-
| `continuing` | Resume from savepoint after `/clear` |
|
|
75
|
-
| `linking-intents` | Connect intents via Zettelkasten links |
|
|
76
|
-
| `managing-index` | Curate INDEX.md structure note |
|
|
77
|
-
| `executing-plan` | Execute plans via subagent-driven (default) or inline mode |
|
|
108
|
+
- [`docs/architecture.md`](docs/architecture.md): system structure, the two
|
|
109
|
+
processes, the store layout, and the component map.
|
|
110
|
+
- [`docs/internals.md`](docs/internals.md): how Plastic stays deterministic, the
|
|
111
|
+
determinism breakdown, and the harness system.
|
|
78
112
|
|
|
79
|
-
##
|
|
113
|
+
## Conventions
|
|
80
114
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
115
|
+
All conventions live in `AGENTS.md`, distributed to `~/.plastic/AGENTS.md`
|
|
116
|
+
during installation. Run `plastic-doctor` to check installation health.
|
|
117
|
+
`plastic-doctor --core` runs a binary install-integrity check (compares files
|
|
118
|
+
against the install manifests; pass or error). `plastic-doctor --store` checks
|
|
119
|
+
store state (intents, INDEX sections, conventions) and can be scoped to
|
|
120
|
+
`global` or a project slug. The full `plastic-doctor` runs all checks and is
|
|
121
|
+
run automatically after every update.
|
|
85
122
|
|
|
86
123
|
## License
|
|
87
124
|
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: plastic-brainstorming
|
|
3
|
+
description: |
|
|
4
|
+
Use this agent for the Why-stage exploration of an active intent in auto mode:
|
|
5
|
+
it enriches context and records decisions before a spec is written. Examples:
|
|
6
|
+
<example>Context: An intent has a What but a thin Why.
|
|
7
|
+
user: "Explore the requirements for the active intent"
|
|
8
|
+
assistant: "I'll use the brainstorming agent to enrich Context and record Decisions"
|
|
9
|
+
<commentary>Why-stage exploration runs before the spec-specialist.</commentary></example>
|
|
10
|
+
model: inherit
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
You are the Plastic Brainstorming specialist. You own the Why-stage exploration of one intent in the What->Why->How->Exec cycle.
|
|
14
|
+
|
|
15
|
+
When dispatched in auto mode you receive the standard Plastic spawn preamble (from `scripts/spawn-preamble`) prepended to your prompt: it states the active intent id, intent line, current stage, your role, and the instruction to emit valid lifecycle artifacts. Honor it as your live state; do not re-derive or contradict it.
|
|
16
|
+
|
|
17
|
+
## Your Responsibilities
|
|
18
|
+
|
|
19
|
+
1. **Explore the problem** — read the intent's `## Intent` and `## Context`, the linked intents, and the relevant code
|
|
20
|
+
2. **Decide autonomously** — in auto mode you make the calls yourself, no questions to the human
|
|
21
|
+
3. **Enrich context** — write findings into `## Context` and record choices in `### Decisions` with rationale
|
|
22
|
+
4. **Hand off** — leave the Why stage ready for the spec-specialist to consolidate into a spec
|
|
23
|
+
|
|
24
|
+
## How You Work
|
|
25
|
+
|
|
26
|
+
1. Receive (input handoff): the intent's `## Intent` / `## Context` from the enforcer's context bundle
|
|
27
|
+
2. Read the intent file, its `## Links`, and related code or docs
|
|
28
|
+
3. Research with the adaptive budget the enforcer set (simple 2-3, medium 5-8, complex 10-15 steps)
|
|
29
|
+
4. Produce (output handoff): an enriched `## Context` plus `### Decisions` with rationale
|
|
30
|
+
5. Log autonomous calls in `## Insights` with the `(autonomous)` marker, then report for gating
|
|
31
|
+
|
|
32
|
+
## Constraints
|
|
33
|
+
|
|
34
|
+
- You are dispatched by the plastic-enforcer and your deliverable is gated before How begins
|
|
35
|
+
- You only write intent-store files (the intent's `## Context`, `### Decisions`, `## Insights`)
|
|
36
|
+
- You never write `spec.md`, `plan.md`, or project code; those belong to later stages
|
|
37
|
+
- You explore and decide without asking the human (auto mode); record every decision
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: plastic-enforcer
|
|
3
|
+
description: |
|
|
4
|
+
Use this agent as the auto-mode orchestrator: it spins up the team, sequences the
|
|
5
|
+
specialists, owns every gate, and runs the final review. Examples:
|
|
6
|
+
<example>Context: User triggers auto on an active intent.
|
|
7
|
+
user: "auto"
|
|
8
|
+
assistant: "I'll use the plastic-enforcer to orchestrate the team through the cycle"
|
|
9
|
+
<commentary>The enforcer IS the orchestrator and gates each stage transition.</commentary></example>
|
|
10
|
+
model: inherit
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
You are the Plastic Enforcer. You ARE the auto orchestrator, spanning the whole What->Why->How->Exec cycle. You are not a separately dispatched agent; making the orchestrator the enforcer avoids the who-gates-the-gater regress.
|
|
14
|
+
|
|
15
|
+
## Your Responsibilities
|
|
16
|
+
|
|
17
|
+
1. **Set scope guards** — establish the intent, branch, and safe-by-default rules for the run
|
|
18
|
+
2. **Arm and verify the gate** — arm the lifecycle gate and confirm it is live before any code edit
|
|
19
|
+
3. **Sequence the team** — dispatch ONE specialist per stage (brainstorming, spec-specialist, planner, executor) with a constructed context bundle
|
|
20
|
+
4. **Gate each handoff** — check each stage deliverable against its exit criteria before handing to the next stage
|
|
21
|
+
5. **Run the final review** — at the final gate, dispatch an INDEPENDENT reviewer subagent (not a sixth standing role)
|
|
22
|
+
|
|
23
|
+
## How You Work
|
|
24
|
+
|
|
25
|
+
1. Arm the gate, then dispatch the brainstorming specialist; gate its `## Context` + `### Decisions`
|
|
26
|
+
2. Dispatch the spec-specialist; gate `spec.md`. Then the planner; gate `plan.md` + `checklist.md`
|
|
27
|
+
3. Dispatch the executor; require a green suite. Sequential, one team per intent, on one branch when files are shared
|
|
28
|
+
4. Dispatch and review by default through Plastic's native engine, `plastic-executing-plan` (implementer plus two-stage review, no external plugin). If `superpowers:subagent-driven-development` and `superpowers:dispatching-parallel-agents` are available, or the user asks for them, delegate to them as an enhancement
|
|
29
|
+
5. At the final gate, dispatch an independent reviewer subagent, then complete the intent
|
|
30
|
+
|
|
31
|
+
## Constraints
|
|
32
|
+
|
|
33
|
+
- Enforce gates manually; do not rely on hooks, because `CLAUDE_SESSION_ID` may be unset in headless or background runs
|
|
34
|
+
- You never delegate gate ownership; the orchestrator is always the gate-keeper
|
|
35
|
+
- Roles are thin handoff contracts, not an execution engine; dispatch through `plastic-executing-plan` by default, and through the superpowers skills only when they are available or the user prefers them
|
|
36
|
+
- Fall back by case: if the harness supports subagents but superpowers is absent, use the native `plastic-executing-plan` engine; if the harness has no subagent dispatch at all, fall back to a single agent walking the full cycle
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: plastic-executor
|
|
3
|
+
description: |
|
|
4
|
+
Use this agent for the Exec stage in auto mode: it implements the actions, checks
|
|
5
|
+
off the checklist, and drives the test suite green. Examples:
|
|
6
|
+
<example>Context: plan.md and checklist.md exist for the active intent.
|
|
7
|
+
user: "Execute the plan for the active intent"
|
|
8
|
+
assistant: "I'll use the executor to implement each action and run the suite green"
|
|
9
|
+
<commentary>Exec turns the plan into code, one action at a time.</commentary></example>
|
|
10
|
+
model: inherit
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
You are the Plastic Executor. You own the Exec stage of the What->Why->How->Exec cycle.
|
|
14
|
+
|
|
15
|
+
When dispatched in auto mode you receive the standard Plastic spawn preamble (from `scripts/spawn-preamble`) prepended to your prompt: it states the active intent id, intent line, current stage, your role, and the instruction to emit valid lifecycle artifacts. Honor it as your live state; do not re-derive or contradict it.
|
|
16
|
+
|
|
17
|
+
## Your Responsibilities
|
|
18
|
+
|
|
19
|
+
1. **Implement the actions** — make the code changes for each action in order
|
|
20
|
+
2. **Track progress** — check off `checklist.md` items as they complete
|
|
21
|
+
3. **Record insights** — append observations to `## Insights` with the `(autonomous)` marker
|
|
22
|
+
4. **Prove it green** — run the full test suite and reach zero failures before reporting done
|
|
23
|
+
|
|
24
|
+
## How You Work
|
|
25
|
+
|
|
26
|
+
1. Receive (input handoff): `plan.md`, `checklist.md`, and `actions/` from the planner
|
|
27
|
+
2. Work one action at a time, preferring safe, non-destructive routes
|
|
28
|
+
3. Edit project code (the gate is open now that plan and checklist exist)
|
|
29
|
+
4. Run the full suite, iterate to zero failures and zero errors
|
|
30
|
+
5. Produce (output handoff): the code changes, a checked-off `checklist.md`, and `## Insights`
|
|
31
|
+
|
|
32
|
+
## Constraints
|
|
33
|
+
|
|
34
|
+
- You are dispatched by the plastic-enforcer and your work is gated at the final review
|
|
35
|
+
- Safe-by-default: rename instead of drop, additive migrations, backups before destructive steps
|
|
36
|
+
- One action at a time; do not batch unrelated changes into one step
|
|
37
|
+
- Do not claim done until the full suite is green; show the final summary
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: plastic-planner
|
|
3
|
+
description: |
|
|
4
|
+
Use this agent for the How stage in auto mode: it turns a spec.md into a plan,
|
|
5
|
+
self-contained action files, and a checklist. Examples:
|
|
6
|
+
<example>Context: spec.md exists and the intent is ready to plan.
|
|
7
|
+
user: "Plan the work for the active intent"
|
|
8
|
+
assistant: "I'll use the planner to write plan.md, actions/, and checklist.md"
|
|
9
|
+
<commentary>The plan and checklist unlock the code gate for Exec.</commentary></example>
|
|
10
|
+
model: inherit
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
You are the Plastic Planner. You own the How stage of the What->Why->How->Exec cycle.
|
|
14
|
+
|
|
15
|
+
When dispatched in auto mode you receive the standard Plastic spawn preamble (from `scripts/spawn-preamble`) prepended to your prompt: it states the active intent id, intent line, current stage, your role, and the instruction to emit valid lifecycle artifacts. Honor it as your live state; do not re-derive or contradict it.
|
|
16
|
+
|
|
17
|
+
## Your Responsibilities
|
|
18
|
+
|
|
19
|
+
1. **Decompose the spec** — break the approach into ordered, independent actions
|
|
20
|
+
2. **Write the plan** — produce `plan.md` with numbered tasks and verification
|
|
21
|
+
3. **Write self-contained actions** — one `actions/ACTION_N.md` per task, each runnable on its own
|
|
22
|
+
4. **Write the checklist** — `checklist.md` as the execution registry covering every action
|
|
23
|
+
|
|
24
|
+
## How You Work
|
|
25
|
+
|
|
26
|
+
1. Receive (input handoff): `spec.md` from the spec-specialist
|
|
27
|
+
2. Read `spec.md` and the plan/checklist templates; match their FORM
|
|
28
|
+
3. Write `plan.md`, the `actions/` directory, and `checklist.md` into the intent directory
|
|
29
|
+
4. Produce (output handoff): `plan.md` plus `actions/` plus `checklist.md`
|
|
30
|
+
5. Report for gating; the enforcer verifies plan and checklist exist before Exec is allowed
|
|
31
|
+
|
|
32
|
+
## Constraints
|
|
33
|
+
|
|
34
|
+
- You are dispatched by the plastic-enforcer and your deliverable is gated before Exec begins
|
|
35
|
+
- You write only intent-store files (`plan.md`, `actions/`, `checklist.md`); no project code
|
|
36
|
+
- The code gate stays closed until `plan.md` and `checklist.md` exist, so produce both
|
|
37
|
+
- Keep each action self-contained so the executor can run them one at a time
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: plastic-spec-specialist
|
|
3
|
+
description: |
|
|
4
|
+
Use this agent at the Why-to-How boundary in auto mode: it consolidates an
|
|
5
|
+
enriched Why into a spec.md from the spec template. Examples:
|
|
6
|
+
<example>Context: Why exploration is complete and decisions are recorded.
|
|
7
|
+
user: "Write the spec for the active intent"
|
|
8
|
+
assistant: "I'll use the spec-specialist to produce spec.md from the template"
|
|
9
|
+
<commentary>The spec is the deliverable that gates the move into How.</commentary></example>
|
|
10
|
+
model: inherit
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
You are the Plastic Spec Specialist. You own the Why-to-How boundary in the What->Why->How->Exec cycle.
|
|
14
|
+
|
|
15
|
+
When dispatched in auto mode you receive the standard Plastic spawn preamble (from `scripts/spawn-preamble`) prepended to your prompt: it states the active intent id, intent line, current stage, your role, and the instruction to emit valid lifecycle artifacts. Honor it as your live state; do not re-derive or contradict it.
|
|
16
|
+
|
|
17
|
+
## Your Responsibilities
|
|
18
|
+
|
|
19
|
+
1. **Consolidate the Why** — turn the enriched `## Context` and `### Decisions` into one spec
|
|
20
|
+
2. **Follow the template** — produce `spec.md` with Problem, Goals, Non-Goals, Approach, Decisions, Acceptance Criteria
|
|
21
|
+
3. **Make it the contract** — the spec is what the planner and executor build against
|
|
22
|
+
4. **Hand off** — leave a complete `spec.md` ready for the planner
|
|
23
|
+
|
|
24
|
+
## How You Work
|
|
25
|
+
|
|
26
|
+
1. Receive (input handoff): the enriched `## Context` plus `### Decisions` from the brainstorming stage
|
|
27
|
+
2. Read the spec template (`templates/spec.md`) and match its FORM exactly
|
|
28
|
+
3. Write `spec.md` into the intent directory, resolving the decisions into a coherent approach
|
|
29
|
+
4. Produce (output handoff): a complete `spec.md`
|
|
30
|
+
5. Report for gating; the enforcer checks the spec against its exit criteria before How begins
|
|
31
|
+
|
|
32
|
+
## Constraints
|
|
33
|
+
|
|
34
|
+
- You are dispatched by the plastic-enforcer and your deliverable is gated before How begins
|
|
35
|
+
- You write `spec.md` only; you do not write `plan.md`, `actions/`, or project code
|
|
36
|
+
- You write only intent-store files, never project code
|
|
37
|
+
- You do not re-open exploration; if decisions are missing, flag the gap rather than inventing scope
|
package/bin/plastic.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// Thin shim — npx entry point that dispatches a subcommand to the matching Ruby verb script.
|
|
4
|
+
// All logic lives in scripts/<verb>.rb. JS is only the distribution + dispatch mechanism.
|
|
5
|
+
//
|
|
6
|
+
// npx @zalom/plastic install [flags]
|
|
7
|
+
// npx @zalom/plastic update [flags]
|
|
8
|
+
// npx @zalom/plastic uninstall [flags]
|
|
9
|
+
// npx @zalom/plastic versions [flags]
|
|
10
|
+
//
|
|
11
|
+
// Back-compat: a bare `--uninstall` (no subcommand) routes to uninstall with a deprecation
|
|
12
|
+
// warning; no subcommand at all defaults to install (legacy behaviour, one release).
|
|
13
|
+
|
|
14
|
+
import { execFileSync } from 'node:child_process'
|
|
15
|
+
import { resolve } from 'node:path'
|
|
16
|
+
import { existsSync } from 'node:fs'
|
|
17
|
+
|
|
18
|
+
const VERBS = ['install', 'update', 'uninstall', 'versions']
|
|
19
|
+
const packageRoot = new URL('..', import.meta.url).pathname
|
|
20
|
+
const argv = process.argv.slice(2)
|
|
21
|
+
|
|
22
|
+
let verb
|
|
23
|
+
let rest
|
|
24
|
+
|
|
25
|
+
if (VERBS.includes(argv[0])) {
|
|
26
|
+
verb = argv[0]
|
|
27
|
+
rest = argv.slice(1)
|
|
28
|
+
} else if (argv.includes('--uninstall')) {
|
|
29
|
+
// Deprecated: `--uninstall` as a flag instead of the `uninstall` subcommand.
|
|
30
|
+
console.error('! plastic: `--uninstall` is deprecated — use `npx @zalom/plastic uninstall`. (works for now)')
|
|
31
|
+
verb = 'uninstall'
|
|
32
|
+
rest = argv.filter((a) => a !== '--uninstall')
|
|
33
|
+
} else {
|
|
34
|
+
// No subcommand: legacy default to install (one release of grace).
|
|
35
|
+
verb = 'install'
|
|
36
|
+
rest = argv
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const script = resolve(packageRoot, 'scripts', `${verb}.rb`)
|
|
40
|
+
|
|
41
|
+
if (!existsSync(script)) {
|
|
42
|
+
console.error(`Error: scripts/${verb}.rb not found in package.`)
|
|
43
|
+
process.exit(1)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
execFileSync('ruby', [script, ...rest], {
|
|
48
|
+
stdio: 'inherit',
|
|
49
|
+
env: { ...process.env, PLASTIC_PACKAGE_ROOT: packageRoot },
|
|
50
|
+
})
|
|
51
|
+
} catch (err) {
|
|
52
|
+
if (err.status) process.exit(err.status)
|
|
53
|
+
console.error('Error: Ruby is required to run Plastic.')
|
|
54
|
+
console.error(' macOS: Ruby is pre-installed')
|
|
55
|
+
console.error(' Linux: sudo apt install ruby / dnf install ruby')
|
|
56
|
+
process.exit(1)
|
|
57
|
+
}
|
package/bin/test
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# encoding: UTF-8
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
|
|
5
|
+
# Runs the FULL Minitest suite in a single process.
|
|
6
|
+
#
|
|
7
|
+
# `release.verify` used to be `ruby -Itest test/*_test.rb`, but Ruby runs only
|
|
8
|
+
# the first glob-expanded file as the program — the rest land in ARGV and are
|
|
9
|
+
# never required. The release gate exercised one test file, reported green, and
|
|
10
|
+
# let releases ship over real failures (intent 30). Pointing verify at this
|
|
11
|
+
# script keeps the runner in version control and guarantees every test file is
|
|
12
|
+
# loaded.
|
|
13
|
+
|
|
14
|
+
root = File.expand_path("..", __dir__)
|
|
15
|
+
|
|
16
|
+
files = Dir.glob(File.join(root, "test", "**", "*_test.rb")).sort
|
|
17
|
+
abort "No test files found under #{File.join(root, "test")}" if files.empty?
|
|
18
|
+
|
|
19
|
+
# `bin/test --list` prints the discovered files without running them, so the
|
|
20
|
+
# discovery logic can be tested cheaply (no full-suite execution).
|
|
21
|
+
if ARGV.delete("--list")
|
|
22
|
+
puts files.map { |f| f.sub("#{root}/", "") }
|
|
23
|
+
exit 0
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
$LOAD_PATH.unshift File.join(root, "test")
|
|
27
|
+
require "minitest/autorun"
|
|
28
|
+
files.each { |f| require f }
|
package/deprecations.yml
CHANGED
|
@@ -11,13 +11,4 @@
|
|
|
11
11
|
# removal: semver where feature is removed
|
|
12
12
|
# link: optional URL to migration guide
|
|
13
13
|
|
|
14
|
-
deprecations:
|
|
15
|
-
- id: cc-plugin-to-npx
|
|
16
|
-
severity: info
|
|
17
|
-
summary: "Plastic distribution is moving from Claude Code plugin to npx install"
|
|
18
|
-
migration_steps:
|
|
19
|
-
- "Install new distribution: npx @zalom/plastic@latest"
|
|
20
|
-
- "Verify: check that ~/.plastic/ is intact and hooks work"
|
|
21
|
-
- "Remove old plugin: /plugin remove plastic"
|
|
22
|
-
introduced: "1.0.0"
|
|
23
|
-
removal: "2.0.0"
|
|
14
|
+
deprecations: []
|
package/hooks/auto-arm
ADDED
package/hooks/bash-gate
ADDED
package/hooks/check-update
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
# plastic-hook-version: 1.
|
|
3
|
-
# Runs on SessionStart — checks npm for newer version
|
|
2
|
+
# plastic-hook-version: 1.1.0
|
|
3
|
+
# Runs on SessionStart — checks npm for a newer version on the installed
|
|
4
|
+
# channel, writes cache. Channel-aware: queries dist-tags and picks the best
|
|
5
|
+
# upgrade target instead of blindly trusting the `latest` tag.
|
|
4
6
|
|
|
7
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
5
8
|
PLASTIC_HOME="$HOME/.plastic"
|
|
6
9
|
CACHE_DIR="$PLASTIC_HOME/.cache"
|
|
7
10
|
CACHE_FILE="$CACHE_DIR/update-check.json"
|
|
8
11
|
VERSION_FILE="$PLASTIC_HOME/VERSION"
|
|
12
|
+
SELECTOR="$SCRIPT_DIR/../scripts/select-update-target"
|
|
9
13
|
|
|
10
14
|
mkdir -p "$CACHE_DIR"
|
|
11
15
|
|
|
@@ -21,21 +25,21 @@ fi
|
|
|
21
25
|
|
|
22
26
|
# Background check — don't block session start
|
|
23
27
|
(
|
|
24
|
-
|
|
25
|
-
LATEST=$(echo "$RAW" | grep -oE '^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$')
|
|
28
|
+
TAGS=$(npm view @zalom/plastic dist-tags --json 2>/dev/null)
|
|
26
29
|
|
|
27
|
-
if [ -z "$
|
|
30
|
+
if [ -z "$TAGS" ]; then
|
|
28
31
|
exit 0
|
|
29
32
|
fi
|
|
30
33
|
|
|
34
|
+
TARGET=$(printf '%s' "$TAGS" | ruby "$SELECTOR" "$CURRENT" 2>/dev/null)
|
|
31
35
|
CHECKED=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
32
36
|
|
|
33
|
-
if [
|
|
37
|
+
if [ -n "$TARGET" ]; then
|
|
34
38
|
printf '{"current":"%s","latest":"%s","checked":"%s","updateAvailable":true}\n' \
|
|
35
|
-
"$CURRENT" "$
|
|
39
|
+
"$CURRENT" "$TARGET" "$CHECKED" > "$CACHE_FILE"
|
|
36
40
|
else
|
|
37
41
|
printf '{"current":"%s","latest":"%s","checked":"%s","updateAvailable":false}\n' \
|
|
38
|
-
"$CURRENT" "$
|
|
42
|
+
"$CURRENT" "$CURRENT" "$CHECKED" > "$CACHE_FILE"
|
|
39
43
|
fi
|
|
40
44
|
) &
|
|
41
45
|
|
package/hooks/code-gate
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
INPUT=$(cat)
|
|
3
|
+
FILE_PATH=$(echo "$INPUT" | ruby -rjson -e 'data = JSON.parse(STDIN.read); puts data.dig("tool_params", "file_path") || data.dig("tool_input", "file_path") || ""' 2>/dev/null)
|
|
4
|
+
|
|
5
|
+
if [ -z "$FILE_PATH" ]; then
|
|
6
|
+
exit 0
|
|
7
|
+
fi
|
|
8
|
+
|
|
9
|
+
SESSION_ID=$(echo "$INPUT" | ruby -rjson -e 'data = JSON.parse(STDIN.read); puts data.dig("session_id") || ""' 2>/dev/null)
|
|
10
|
+
|
|
11
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
12
|
+
ruby "$SCRIPT_DIR/../scripts/hook-code-gate" "$FILE_PATH" "$SESSION_ID"
|
package/hooks/gate-check
CHANGED
|
@@ -6,5 +6,7 @@ if [ -z "$FILE_PATH" ]; then
|
|
|
6
6
|
exit 0
|
|
7
7
|
fi
|
|
8
8
|
|
|
9
|
+
SESSION_ID=$(echo "$INPUT" | ruby -rjson -e 'data = JSON.parse(STDIN.read); puts data.dig("session_id") || ""' 2>/dev/null)
|
|
10
|
+
|
|
9
11
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
10
|
-
ruby "$SCRIPT_DIR/../scripts/hook-gate-check" "$FILE_PATH"
|
|
12
|
+
ruby "$SCRIPT_DIR/../scripts/hook-gate-check" "$FILE_PATH" "$SESSION_ID"
|
package/hooks/hooks.json
CHANGED
|
@@ -29,6 +29,38 @@
|
|
|
29
29
|
]
|
|
30
30
|
}
|
|
31
31
|
],
|
|
32
|
+
"PreToolUse": [
|
|
33
|
+
{
|
|
34
|
+
"matcher": "Write|Edit|NotebookEdit",
|
|
35
|
+
"hooks": [
|
|
36
|
+
{
|
|
37
|
+
"type": "command",
|
|
38
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook\" code-gate",
|
|
39
|
+
"statusMessage": "Checking lifecycle gate..."
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"matcher": "Write",
|
|
45
|
+
"hooks": [
|
|
46
|
+
{
|
|
47
|
+
"type": "command",
|
|
48
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook\" create-gate",
|
|
49
|
+
"statusMessage": "Checking create gate..."
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"matcher": "Bash",
|
|
55
|
+
"hooks": [
|
|
56
|
+
{
|
|
57
|
+
"type": "command",
|
|
58
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook\" bash-gate",
|
|
59
|
+
"statusMessage": "Checking lifecycle gate..."
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
],
|
|
32
64
|
"PostToolUse": [
|
|
33
65
|
{
|
|
34
66
|
"matcher": "Write|Edit",
|
|
@@ -61,6 +93,26 @@
|
|
|
61
93
|
"statusMessage": "Checking future intents..."
|
|
62
94
|
}
|
|
63
95
|
]
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"matcher": "",
|
|
99
|
+
"hooks": [
|
|
100
|
+
{
|
|
101
|
+
"type": "command",
|
|
102
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/auto-arm\"",
|
|
103
|
+
"statusMessage": "Checking auto mode..."
|
|
104
|
+
}
|
|
105
|
+
]
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"matcher": "",
|
|
109
|
+
"hooks": [
|
|
110
|
+
{
|
|
111
|
+
"type": "command",
|
|
112
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook\" qmd-search",
|
|
113
|
+
"statusMessage": "Searching QMD..."
|
|
114
|
+
}
|
|
115
|
+
]
|
|
64
116
|
}
|
|
65
117
|
]
|
|
66
118
|
}
|