@zalom/plastic 1.0.0-alpha.14 → 1.0.0-alpha.16
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 +18 -18
- package/README.md +13 -6
- package/agents/future-intent-researcher.md +1 -1
- package/agents/intent-curator.md +1 -1
- package/deprecations.yml +6 -5
- package/package.json +1 -1
- package/scripts/doctor.rb +37 -30
- package/scripts/hook-auto-arm +3 -3
- package/scripts/hook-continue +1 -1
- package/scripts/hook-gate-check +3 -3
- package/scripts/hook-session-start +1 -1
- package/scripts/install.rb +175 -119
- package/scripts/lib/bridge.rb +1 -1
- package/scripts/migrate-to-global +1 -1
- package/skills/_active-intent-gate.md +1 -1
- package/skills/auto/SKILL.md +6 -6
- package/skills/auto/evals/evals.json +17 -17
- package/skills/auto/references/agent-architecture.md +1 -1
- package/skills/brainstorming/SKILL.md +8 -8
- package/skills/brainstorming-grill-me/SKILL.md +5 -5
- package/skills/continuing/SKILL.md +4 -4
- package/skills/creating-intent/SKILL.md +1 -1
- package/skills/creating-project/SKILL.md +4 -4
- package/skills/doctor/SKILL.md +4 -4
- package/skills/evaluating-skills/SKILL.md +1 -1
- package/skills/executing-plan/SKILL.md +1 -1
- package/skills/install/SKILL.md +32 -8
- package/skills/intent-curator/SKILL.md +3 -3
- package/skills/linking-intents/SKILL.md +1 -1
- package/skills/managing-index/SKILL.md +1 -1
- package/skills/releasing/SKILL.md +3 -3
- package/skills/research/SKILL.md +2 -2
- package/skills/savepoint/SKILL.md +1 -1
- package/skills/uninstall/SKILL.md +39 -28
- package/skills/update/SKILL.md +2 -2
- package/skills/writing-instructions/SKILL.md +2 -2
- package/skills/writing-plans/SKILL.md +5 -5
- package/templates/agents.md +7 -7
package/PLASTIC.md
CHANGED
|
@@ -61,10 +61,10 @@ The connection: an intent's `## Insights` feeds the Coordinator's Observe phase.
|
|
|
61
61
|
|
|
62
62
|
| Stage | Section | Deliverable | Detail |
|
|
63
63
|
|-------|---------|-------------|--------|
|
|
64
|
-
| **What** | `## Intent` | `{ID}--{slug}.md` | `plastic
|
|
65
|
-
| **Why** | `## Context` + Decisions | `spec.md` | `plastic
|
|
66
|
-
| **How** | Planning | `plan.md` + `actions/` + `checklist.md` | `plastic
|
|
67
|
-
| **Exec** | Execution | `outcome.md` | `plastic
|
|
64
|
+
| **What** | `## Intent` | `{ID}--{slug}.md` | `plastic-creating-intent` |
|
|
65
|
+
| **Why** | `## Context` + Decisions | `spec.md` | `plastic-brainstorming` |
|
|
66
|
+
| **How** | Planning | `plan.md` + `actions/` + `checklist.md` | `plastic-writing-plans` |
|
|
67
|
+
| **Exec** | Execution | `outcome.md` | `plastic-executing-plan` |
|
|
68
68
|
|
|
69
69
|
`## Insights` — append-only work log captured throughout ALL stages.
|
|
70
70
|
For full lifecycle detail, the skills in the Detail column have references/.
|
|
@@ -136,7 +136,7 @@ A Zettelkasten structure note, not a table of contents. Clusters by meaning.
|
|
|
136
136
|
|
|
137
137
|
Sections: `## Active`, `## Future`, `## Clusters`, `## Abandoned`, `## Completed`.
|
|
138
138
|
|
|
139
|
-
For index maintenance, use `plastic
|
|
139
|
+
For index maintenance, use `plastic-managing-index`.
|
|
140
140
|
|
|
141
141
|
## Rules for Skills
|
|
142
142
|
|
|
@@ -165,16 +165,16 @@ Detailed conventions live inside the skills that use them, not in this file.
|
|
|
165
165
|
|
|
166
166
|
| Topic | Skill | References in skill |
|
|
167
167
|
|-------|-------|-------------------|
|
|
168
|
-
| Creating intents, lifecycle | `plastic
|
|
169
|
-
| Brainstorming, spec writing | `plastic
|
|
170
|
-
| Planning, actions | `plastic
|
|
171
|
-
| Execution, delivery | `plastic
|
|
172
|
-
| Autonomous delivery | `plastic
|
|
173
|
-
| Save/restore state | `plastic
|
|
174
|
-
| Knowledge graph, linking | `plastic
|
|
175
|
-
| Projects, hubs | `plastic
|
|
176
|
-
| Index maintenance | `plastic
|
|
177
|
-
| Releases, deprecations | `plastic
|
|
178
|
-
| Health diagnostics | `plastic
|
|
179
|
-
| Writing agent instructions | `plastic
|
|
180
|
-
| Evaluating skills, evals | `plastic
|
|
168
|
+
| Creating intents, lifecycle | `plastic-creating-intent` | lifecycle, wikilinks |
|
|
169
|
+
| Brainstorming, spec writing | `plastic-brainstorming` | — |
|
|
170
|
+
| Planning, actions | `plastic-writing-plans` | — |
|
|
171
|
+
| Execution, delivery | `plastic-executing-plan` | — |
|
|
172
|
+
| Autonomous delivery | `plastic-auto` | agent architecture |
|
|
173
|
+
| Save/restore state | `plastic-savepoint`, `plastic-continuing` | context management |
|
|
174
|
+
| Knowledge graph, linking | `plastic-linking-intents` | zettelkasten, wikilinks |
|
|
175
|
+
| Projects, hubs | `plastic-creating-project` | hubs, project stores |
|
|
176
|
+
| Index maintenance | `plastic-managing-index` | — |
|
|
177
|
+
| Releases, deprecations | `plastic-releasing` | deprecation process |
|
|
178
|
+
| Health diagnostics | `plastic-doctor` | gate enforcement, stuck detection |
|
|
179
|
+
| Writing agent instructions | `plastic-writing-instructions` | agentskills.io spec |
|
|
180
|
+
| Evaluating skills, evals | `plastic-evaluating-skills` | eval methodology, convention checks |
|
package/README.md
CHANGED
|
@@ -38,6 +38,13 @@ npx @zalom/plastic --claude
|
|
|
38
38
|
Replace `--claude` with `--codex` for Codex CLI, `--hermes` for Hermes, or
|
|
39
39
|
`--all` for all supported agents.
|
|
40
40
|
|
|
41
|
+
Bun users can substitute `bunx` for `npx` (e.g. `bunx @zalom/plastic@alpha --claude`).
|
|
42
|
+
Bun is never required.
|
|
43
|
+
|
|
44
|
+
Skills install as flat, hyphen-namespaced personal skills (`plastic-doctor`,
|
|
45
|
+
`plastic-auto`, …) — invoke them with a hyphen. Plastic is **not** a Claude Code
|
|
46
|
+
plugin; re-running the installer auto-removes any legacy plugin registration.
|
|
47
|
+
|
|
41
48
|
### Updating
|
|
42
49
|
|
|
43
50
|
From within your agent, say "update plastic" or run:
|
|
@@ -46,25 +53,25 @@ From within your agent, say "update plastic" or run:
|
|
|
46
53
|
npx @zalom/plastic@alpha --claude
|
|
47
54
|
```
|
|
48
55
|
|
|
49
|
-
The `plastic
|
|
56
|
+
The `plastic-update` command shows available versions across all channels and
|
|
50
57
|
lets you choose which to install.
|
|
51
58
|
|
|
52
59
|
## Quick Start
|
|
53
60
|
|
|
54
61
|
After installation, run `/clear` to load Plastic conventions, then:
|
|
55
62
|
|
|
56
|
-
1. Say "new intent" or run `/plastic
|
|
63
|
+
1. Say "new intent" or run `/plastic-creating-intent` to create your first intent
|
|
57
64
|
2. Describe what you want to accomplish
|
|
58
|
-
3. Use `/plastic
|
|
59
|
-
4. Use `/plastic
|
|
60
|
-
5. Use `/plastic
|
|
65
|
+
3. Use `/plastic-brainstorming` to explore the design
|
|
66
|
+
4. Use `/plastic-writing-plans` to create an implementation plan
|
|
67
|
+
5. Use `/plastic-executing-plan` to deliver it
|
|
61
68
|
|
|
62
69
|
Or say "auto" to let the agent handle the full lifecycle autonomously.
|
|
63
70
|
|
|
64
71
|
## Conventions
|
|
65
72
|
|
|
66
73
|
All conventions live in `AGENTS.md`, distributed to `~/.plastic/AGENTS.md`
|
|
67
|
-
during installation. Run `plastic
|
|
74
|
+
during installation. Run `plastic-doctor` to check installation health.
|
|
68
75
|
|
|
69
76
|
## License
|
|
70
77
|
|
package/agents/intent-curator.md
CHANGED
package/deprecations.yml
CHANGED
|
@@ -12,12 +12,13 @@
|
|
|
12
12
|
# link: optional URL to migration guide
|
|
13
13
|
|
|
14
14
|
deprecations:
|
|
15
|
-
- id: cc-plugin-to-
|
|
15
|
+
- id: cc-plugin-to-hyphen-skills
|
|
16
16
|
severity: warning
|
|
17
|
-
summary: "Plastic
|
|
17
|
+
summary: "Plastic now ships as flat hyphen-named personal skills (plastic-doctor), not a Claude Code plugin. Invocation changed from plastic:<name> to plastic-<name>."
|
|
18
18
|
migration_steps:
|
|
19
|
-
- "
|
|
20
|
-
- "
|
|
21
|
-
- "
|
|
19
|
+
- "Re-run the installer: npx @zalom/plastic@latest --claude (bunx also works)"
|
|
20
|
+
- "It auto-removes the old plugin/marketplace registration — no /plugin step needed"
|
|
21
|
+
- "Invoke skills with a hyphen now: /plastic-doctor, /plastic-auto, etc."
|
|
22
|
+
- "Run /plastic-doctor to verify"
|
|
22
23
|
introduced: "1.0.0"
|
|
23
24
|
removal: "2.0.0"
|
package/package.json
CHANGED
package/scripts/doctor.rb
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
require "json"
|
|
13
13
|
require "yaml"
|
|
14
14
|
require "time"
|
|
15
|
+
require "date"
|
|
15
16
|
|
|
16
17
|
PLASTIC_HOME = File.join(Dir.home, ".plastic")
|
|
17
18
|
|
|
@@ -150,21 +151,31 @@ def parse_frontmatter(path)
|
|
|
150
151
|
parts = content.split("---", 3)
|
|
151
152
|
return nil if parts.length < 3
|
|
152
153
|
|
|
153
|
-
|
|
154
|
+
# created: dates parse as Date objects, which safe_load rejects by default —
|
|
155
|
+
# permit Date/Time so valid frontmatter isn't misreported as missing.
|
|
156
|
+
YAML.safe_load(parts[1], permitted_classes: [Date, Time]) || {}
|
|
154
157
|
rescue
|
|
155
158
|
nil
|
|
156
159
|
end
|
|
157
160
|
|
|
158
161
|
# --- Collect all intent directories (global + project stores) ---
|
|
159
162
|
|
|
163
|
+
# Child directories of a store, excluding dotfiles/dot-directories
|
|
164
|
+
# (e.g. .obsidian, .git) which are tooling artifacts, not intents.
|
|
165
|
+
def store_intent_dirs(store)
|
|
166
|
+
Dir.children(store).reject { |e| e.start_with?(".") }.select do |e|
|
|
167
|
+
File.directory?(File.join(store, e))
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
160
171
|
def all_intent_dirs
|
|
161
172
|
dirs = []
|
|
162
173
|
|
|
163
174
|
global_store = File.join(PLASTIC_HOME, "store")
|
|
164
175
|
if File.directory?(global_store)
|
|
165
|
-
|
|
176
|
+
store_intent_dirs(global_store).each do |entry|
|
|
166
177
|
full = File.join(global_store, entry)
|
|
167
|
-
dirs << { path: full, name: entry, scope: "global" }
|
|
178
|
+
dirs << { path: full, name: entry, scope: "global" }
|
|
168
179
|
end
|
|
169
180
|
end
|
|
170
181
|
|
|
@@ -174,9 +185,9 @@ def all_intent_dirs
|
|
|
174
185
|
project_store = File.join(projects_root, project, "store")
|
|
175
186
|
next unless File.directory?(project_store)
|
|
176
187
|
|
|
177
|
-
|
|
188
|
+
store_intent_dirs(project_store).each do |entry|
|
|
178
189
|
full = File.join(project_store, entry)
|
|
179
|
-
dirs << { path: full, name: entry, scope: "project:#{project}" }
|
|
190
|
+
dirs << { path: full, name: entry, scope: "project:#{project}" }
|
|
180
191
|
end
|
|
181
192
|
end
|
|
182
193
|
end
|
|
@@ -227,7 +238,7 @@ def check_global_store
|
|
|
227
238
|
# orphaned_intents — directories in store/ not referenced in INDEX.md
|
|
228
239
|
store_dir = File.join(PLASTIC_HOME, "store")
|
|
229
240
|
if File.directory?(store_dir)
|
|
230
|
-
intent_dirs =
|
|
241
|
+
intent_dirs = store_intent_dirs(store_dir)
|
|
231
242
|
orphans = intent_dirs.reject { |d| content.include?("store/#{d}") }
|
|
232
243
|
|
|
233
244
|
if orphans.empty?
|
|
@@ -459,22 +470,30 @@ def check_claude_registration(agent_dir)
|
|
|
459
470
|
end
|
|
460
471
|
end
|
|
461
472
|
|
|
462
|
-
# skills_exist
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
473
|
+
# skills_exist — flat, hyphen-namespaced personal skills (plastic-<name>/)
|
|
474
|
+
checks << flat_skills_check(agent_dir, "--claude")
|
|
475
|
+
|
|
476
|
+
checks
|
|
477
|
+
end
|
|
478
|
+
|
|
479
|
+
# Plastic skills install as ~/.claude/skills/plastic-<name>/SKILL.md. Pass if at
|
|
480
|
+
# least one such skill is present.
|
|
481
|
+
def flat_skills_check(agent_dir, installer_flag)
|
|
482
|
+
skills_root = File.join(agent_dir, "skills")
|
|
483
|
+
found = Dir.glob(File.join(skills_root, "plastic-*", "SKILL.md"))
|
|
484
|
+
|
|
485
|
+
if !found.empty?
|
|
486
|
+
check(
|
|
466
487
|
category: "agent_registration", name: "skills_exist", status: "pass",
|
|
467
|
-
message: "
|
|
488
|
+
message: "#{found.size} plastic-* skill(s) installed in #{tilde(skills_root)}"
|
|
468
489
|
)
|
|
469
490
|
else
|
|
470
|
-
|
|
491
|
+
check(
|
|
471
492
|
category: "agent_registration", name: "skills_exist", status: "fail",
|
|
472
|
-
message: "
|
|
473
|
-
fixable: true, fix_hint: "Re-run the Plastic installer: npx @zalom/plastic@latest
|
|
493
|
+
message: "No plastic-* skills found in #{tilde(skills_root)}",
|
|
494
|
+
fixable: true, fix_hint: "Re-run the Plastic installer: npx @zalom/plastic@latest #{installer_flag}"
|
|
474
495
|
)
|
|
475
496
|
end
|
|
476
|
-
|
|
477
|
-
checks
|
|
478
497
|
end
|
|
479
498
|
|
|
480
499
|
def check_generic_agent_registration(agent_key, agent_dir)
|
|
@@ -482,19 +501,7 @@ def check_generic_agent_registration(agent_key, agent_dir)
|
|
|
482
501
|
config = AGENTS[agent_key]
|
|
483
502
|
|
|
484
503
|
# For codex/hermes: just check skills exist (no settings.json hooks)
|
|
485
|
-
|
|
486
|
-
if File.directory?(skills_dir) && !Dir.empty?(skills_dir)
|
|
487
|
-
checks << check(
|
|
488
|
-
category: "agent_registration", name: "skills_exist", status: "pass",
|
|
489
|
-
message: "Skills directory exists at #{tilde(skills_dir)}"
|
|
490
|
-
)
|
|
491
|
-
else
|
|
492
|
-
checks << check(
|
|
493
|
-
category: "agent_registration", name: "skills_exist", status: "fail",
|
|
494
|
-
message: "Skills directory missing or empty at #{tilde(skills_dir)}",
|
|
495
|
-
fixable: true, fix_hint: "Re-run the Plastic installer: npx @zalom/plastic@latest --#{agent_key}"
|
|
496
|
-
)
|
|
497
|
-
end
|
|
504
|
+
checks << flat_skills_check(agent_dir, "--#{agent_key}")
|
|
498
505
|
|
|
499
506
|
checks
|
|
500
507
|
end
|
|
@@ -695,7 +702,7 @@ def check_project_stores
|
|
|
695
702
|
checks << check(
|
|
696
703
|
category: "project_stores", name: "project_yml_exists", status: "warn",
|
|
697
704
|
message: "project.yml missing for project '#{slug}'",
|
|
698
|
-
fixable: true, fix_hint: "Create project.yml from template — see plastic
|
|
705
|
+
fixable: true, fix_hint: "Create project.yml from template — see plastic-creating-project"
|
|
699
706
|
)
|
|
700
707
|
end
|
|
701
708
|
|
package/scripts/hook-auto-arm
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
# Usage: hook-auto-arm <message>
|
|
6
6
|
# UserPromptSubmit arming (intent 27). Two jobs, both additive context — never blocks:
|
|
7
|
-
# 1. Detect auto-trigger phrases -> steer the agent to invoke plastic
|
|
7
|
+
# 1. Detect auto-trigger phrases -> steer the agent to invoke plastic-auto.
|
|
8
8
|
# 2. If auto mode is armed and the active intent hasn't reached How -> remind the agent
|
|
9
9
|
# that project-code edits are gate-blocked until plan.md + checklist.md exist.
|
|
10
10
|
# Outputs UserPromptSubmit hookSpecificOutput JSON, or exits silently.
|
|
@@ -16,11 +16,11 @@ message = (ARGV[0] || "").downcase
|
|
|
16
16
|
parts = []
|
|
17
17
|
|
|
18
18
|
# --- 1. Auto-trigger steering ---
|
|
19
|
-
AUTO_TRIGGERS = ["take it from here", "deliver this", "/plastic
|
|
19
|
+
AUTO_TRIGGERS = ["take it from here", "deliver this", "/plastic-auto", "auto mode"].freeze
|
|
20
20
|
# bare "auto" only as a standalone word to avoid matching "automatic", "automation", etc.
|
|
21
21
|
triggered = AUTO_TRIGGERS.any? { |p| message.include?(p) } || message.match?(/\bauto\b/)
|
|
22
22
|
if triggered
|
|
23
|
-
parts << "Auto-mode request detected. Invoke the plastic
|
|
23
|
+
parts << "Auto-mode request detected. Invoke the plastic-auto skill to deliver the " \
|
|
24
24
|
"active intent autonomously — it arms the lifecycle gate so project code " \
|
|
25
25
|
"cannot be edited before plan.md + checklist.md exist."
|
|
26
26
|
end
|
package/scripts/hook-continue
CHANGED
|
@@ -116,7 +116,7 @@ if stale.any?
|
|
|
116
116
|
parts << ""
|
|
117
117
|
end
|
|
118
118
|
|
|
119
|
-
parts << "Follow the plastic
|
|
119
|
+
parts << "Follow the plastic-continuing skill workflow.\n"
|
|
120
120
|
parts << "1. If active intents exist: read their state and resume\n"
|
|
121
121
|
parts << "2. If no active intents: present future intents as options\n"
|
|
122
122
|
parts << "3. If stale intents exist: surface them and ask user to decide"
|
package/scripts/hook-gate-check
CHANGED
|
@@ -102,9 +102,9 @@ if is_stage_file || is_action_file
|
|
|
102
102
|
stage_labels = { "what" => "What", "why" => "Why", "how" => "How", "exec" => "Exec", "done" => "Done" }
|
|
103
103
|
next_hints = {
|
|
104
104
|
"why" => "write spec.md",
|
|
105
|
-
"how" => "Why complete. Invoke plastic
|
|
106
|
-
"exec" => "How complete. Invoke plastic
|
|
107
|
-
"done" => "Exec complete. Intent must be completed now — write outcome.md, update INDEX.md, auto-commit. Use plastic
|
|
105
|
+
"how" => "Why complete. Invoke plastic-auto to deliver autonomously, or write plan.md manually.",
|
|
106
|
+
"exec" => "How complete. Invoke plastic-auto or plastic-executing-plan to execute, or work through the checklist manually.",
|
|
107
|
+
"done" => "Exec complete. Intent must be completed now — write outcome.md, update INDEX.md, auto-commit. Use plastic-auto or do it manually."
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
context_parts = ["PLASTIC"]
|
|
@@ -168,7 +168,7 @@ cache_file = "#{store_root}/.cache/update-check.json"
|
|
|
168
168
|
if File.exist?(cache_file)
|
|
169
169
|
cache = JSON.parse(File.read(cache_file)) rescue {}
|
|
170
170
|
if cache["updateAvailable"]
|
|
171
|
-
update_notice = "Plastic update available: #{cache["current"]} -> #{cache["latest"]} — run /plastic
|
|
171
|
+
update_notice = "Plastic update available: #{cache["current"]} -> #{cache["latest"]} — run /plastic-update"
|
|
172
172
|
end
|
|
173
173
|
end
|
|
174
174
|
|