@zalom/plastic 2.0.0-alpha.9 → 2.0.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.
Files changed (326) hide show
  1. package/PLASTIC.md +13 -136
  2. package/README.md +357 -133
  3. package/agents/plastic-enforcer.md +21 -16
  4. package/agents/plastic-executor.md +15 -4
  5. package/agents/plastic-node-research.md +30 -0
  6. package/agents/plastic-node-verify.md +28 -0
  7. package/agents/plastic-node-work.md +33 -0
  8. package/agents/{plastic-advisor.md → plastic-primary-advisor.md} +7 -9
  9. package/agents/{plastic-faux-advisor.md → plastic-secondary-advisor.md} +9 -12
  10. package/assets/plastic-logo.svg +1 -0
  11. package/bin/crap +4 -0
  12. package/bin/lib/context_budget.rb +43 -6
  13. package/bin/lib/skill_census.rb +839 -0
  14. package/bin/plastic +8 -0
  15. package/bin/plastic-skill-census +114 -0
  16. package/bin/test +24 -4
  17. package/bin/verify-change +345 -0
  18. package/config_asks.yml +4 -4
  19. package/deprecations.yml +1 -1
  20. package/{skills/agent-advisor/references → docs/help}/advisor-protocol.md +19 -24
  21. package/{skills/auto/references → docs/help}/agent-architecture.md +16 -14
  22. package/docs/help/completion-and-done.md +53 -0
  23. package/docs/help/human-report-contract.md +152 -0
  24. package/{skills/conventions/references → docs/help}/knowledge-graph.md +9 -0
  25. package/{skills/conventions/references → docs/help}/locks-and-worktrees.md +11 -13
  26. package/{skills/conventions/references → docs/help}/maintenance-and-revisions.md +1 -1
  27. package/{skills/conventions/references → docs/help}/roadmaps.md +5 -4
  28. package/{skills/tutorial/references → docs/help}/track-1-guided.md +28 -47
  29. package/{skills/tutorial/references → docs/help}/track-2-auto.md +8 -8
  30. package/{skills/tutorial/references → docs/help}/track-3-projects-and-roadmaps.md +24 -17
  31. package/hooks/call-budget +4 -0
  32. package/hooks/hooks.json +24 -0
  33. package/hooks/message-display +55 -2
  34. package/hooks/session-start +5 -1
  35. package/hooks/statusline +32 -27
  36. package/hooks/stop +5 -0
  37. package/package.json +5 -3
  38. package/scripts/append-ledger +2 -1
  39. package/scripts/dashboard.rb +267 -16
  40. package/scripts/day-summary +2 -1
  41. package/scripts/doctor.rb +680 -39
  42. package/scripts/end-intent +378 -56
  43. package/scripts/exec-worktree +5 -5
  44. package/scripts/file-session-intent +2 -1
  45. package/scripts/graph-measure +249 -0
  46. package/scripts/hook-call-budget +222 -0
  47. package/scripts/hook-capture +24 -123
  48. package/scripts/hook-close +2 -1
  49. package/scripts/hook-message-display +7 -0
  50. package/scripts/hook-record +24 -16
  51. package/scripts/hook-savepoint +27 -3
  52. package/scripts/hook-session-start +359 -321
  53. package/scripts/hook-stop +58 -0
  54. package/scripts/index-projection +74 -0
  55. package/scripts/insight-append +17 -4
  56. package/scripts/install.rb +9 -7
  57. package/scripts/lib/action_graph_shim.rb +279 -0
  58. package/scripts/lib/active_delivery.rb +105 -0
  59. package/scripts/lib/agent_models.rb +63 -25
  60. package/scripts/lib/arm.rb +74 -91
  61. package/scripts/lib/atomic_write.rb +31 -0
  62. package/scripts/lib/backup.rb +65 -0
  63. package/scripts/lib/cli/command.rb +92 -0
  64. package/scripts/lib/cli/commands/auto.rb +18 -0
  65. package/scripts/lib/cli/commands/auto_brief.rb +44 -0
  66. package/scripts/lib/cli/commands/auto_lock.rb +111 -0
  67. package/scripts/lib/cli/commands/auto_report.rb +50 -0
  68. package/scripts/lib/cli/commands/auto_take.rb +68 -0
  69. package/scripts/lib/cli/commands/backup.rb +43 -0
  70. package/scripts/lib/cli/commands/checkout.rb +25 -0
  71. package/scripts/lib/cli/commands/continue.rb +66 -0
  72. package/scripts/lib/cli/commands/doctor.rb +81 -0
  73. package/scripts/lib/cli/commands/feedback.rb +40 -0
  74. package/scripts/lib/cli/commands/help.rb +69 -0
  75. package/scripts/lib/cli/commands/hook.rb +32 -0
  76. package/scripts/lib/cli/commands/index.rb +23 -0
  77. package/scripts/lib/cli/commands/install.rb +21 -0
  78. package/scripts/lib/cli/commands/installer_verb.rb +37 -0
  79. package/scripts/lib/cli/commands/intent.rb +19 -0
  80. package/scripts/lib/cli/commands/intent_answer.rb +37 -0
  81. package/scripts/lib/cli/commands/intent_command.rb +58 -0
  82. package/scripts/lib/cli/commands/intent_end.rb +75 -0
  83. package/scripts/lib/cli/commands/intent_new.rb +62 -0
  84. package/scripts/lib/cli/commands/intent_note.rb +43 -0
  85. package/scripts/lib/cli/commands/intent_rule.rb +36 -0
  86. package/scripts/lib/cli/commands/intent_show.rb +32 -0
  87. package/scripts/lib/cli/commands/intent_spec.rb +44 -0
  88. package/scripts/lib/cli/commands/intent_step.rb +79 -0
  89. package/scripts/lib/cli/commands/intent_verify.rb +26 -0
  90. package/scripts/lib/cli/commands/migrate.rb +16 -0
  91. package/scripts/lib/cli/commands/migrate_stores.rb +31 -0
  92. package/scripts/lib/cli/commands/next.rb +54 -0
  93. package/scripts/lib/cli/commands/project.rb +19 -0
  94. package/scripts/lib/cli/commands/project_links.rb +46 -0
  95. package/scripts/lib/cli/commands/project_list.rb +20 -0
  96. package/scripts/lib/cli/commands/project_new.rb +95 -0
  97. package/scripts/lib/cli/commands/query.rb +31 -0
  98. package/scripts/lib/cli/commands/render.rb +35 -0
  99. package/scripts/lib/cli/commands/roadmap.rb +19 -0
  100. package/scripts/lib/cli/commands/roadmap_check.rb +54 -0
  101. package/scripts/lib/cli/commands/roadmap_log.rb +54 -0
  102. package/scripts/lib/cli/commands/roadmap_migrate.rb +53 -0
  103. package/scripts/lib/cli/commands/roadmap_next.rb +77 -0
  104. package/scripts/lib/cli/commands/roadmap_show.rb +65 -0
  105. package/scripts/lib/cli/commands/rollback.rb +20 -0
  106. package/scripts/lib/cli/commands/search.rb +60 -0
  107. package/scripts/lib/cli/commands/session.rb +18 -0
  108. package/scripts/lib/cli/commands/session_commit.rb +42 -0
  109. package/scripts/lib/cli/commands/session_handoff.rb +34 -0
  110. package/scripts/lib/cli/commands/session_summary.rb +35 -0
  111. package/scripts/lib/cli/commands/status.rb +68 -0
  112. package/scripts/lib/cli/commands/subcommand_list.rb +36 -0
  113. package/scripts/lib/cli/commands/sync.rb +55 -0
  114. package/scripts/lib/cli/commands/uninstall.rb +20 -0
  115. package/scripts/lib/cli/commands/update.rb +20 -0
  116. package/scripts/lib/cli/commands/version.rb +53 -0
  117. package/scripts/lib/cli/frontier.rb +86 -0
  118. package/scripts/lib/cli/intent_progress.rb +36 -0
  119. package/scripts/lib/cli/legacy.rb +80 -0
  120. package/scripts/lib/cli/output.rb +137 -0
  121. package/scripts/lib/cli/scope.rb +134 -0
  122. package/scripts/lib/cli/table.rb +65 -0
  123. package/scripts/lib/cli.rb +94 -0
  124. package/scripts/lib/codex_adapter.rb +198 -0
  125. package/scripts/lib/compact_instructions.rb +13 -5
  126. package/scripts/lib/core_integrity.rb +71 -0
  127. package/scripts/lib/dashboard_screen.rb +40 -0
  128. package/scripts/lib/data_boundary.rb +132 -0
  129. package/scripts/lib/day_summary.rb +23 -14
  130. package/scripts/lib/doctor_core.rb +114 -38
  131. package/scripts/lib/doctor_session_ledger.rb +5 -53
  132. package/scripts/lib/engine_permissions.rb +88 -0
  133. package/scripts/lib/exec_worktree.rb +24 -21
  134. package/scripts/lib/feedback_report.rb +1 -1
  135. package/scripts/lib/graph_edges.rb +137 -0
  136. package/scripts/lib/graph_file.rb +246 -0
  137. package/scripts/lib/graph_measure.rb +645 -0
  138. package/scripts/lib/graph_measure_budget.rb +409 -0
  139. package/scripts/lib/graph_measure_cohorts.rb +487 -0
  140. package/scripts/lib/graph_measure_models.rb +413 -0
  141. package/scripts/lib/graph_measure_report.rb +532 -0
  142. package/scripts/lib/graph_tree.rb +98 -0
  143. package/scripts/lib/guarded_append.rb +155 -0
  144. package/scripts/lib/handoff.rb +40 -13
  145. package/scripts/lib/harness_adapter.rb +184 -0
  146. package/scripts/lib/hook_registry.rb +27 -3
  147. package/scripts/lib/hook_replay.rb +235 -0
  148. package/scripts/lib/index_entry.rb +62 -0
  149. package/scripts/lib/index_projection.rb +201 -0
  150. package/scripts/lib/insights.rb +1 -1
  151. package/scripts/lib/installer_core.rb +543 -71
  152. package/scripts/lib/intent_screen.rb +4 -4
  153. package/scripts/lib/intent_screen_ansi.rb +73 -12
  154. package/scripts/lib/intent_validator.rb +2 -2
  155. package/scripts/lib/lock.rb +10 -11
  156. package/scripts/lib/message_display.rb +350 -54
  157. package/scripts/lib/meter_watch.rb +185 -0
  158. package/scripts/lib/node_file.rb +234 -0
  159. package/scripts/lib/node_ids.rb +99 -0
  160. package/scripts/lib/node_input.rb +921 -0
  161. package/scripts/lib/node_input_compatibility.rb +62 -0
  162. package/scripts/lib/node_ledger.rb +386 -0
  163. package/scripts/lib/node_progress.rb +153 -0
  164. package/scripts/lib/node_return.rb +204 -0
  165. package/scripts/lib/node_worktree.rb +337 -0
  166. package/scripts/lib/outcome_report.rb +440 -0
  167. package/scripts/lib/preflight.rb +4 -6
  168. package/scripts/lib/project_config.rb +46 -0
  169. package/scripts/lib/project_validator.rb +3 -2
  170. package/scripts/lib/qmd_sync.rb +8 -7
  171. package/scripts/lib/ready_set.rb +462 -0
  172. package/scripts/lib/reference_archive.rb +45 -0
  173. package/scripts/lib/release_guard.rb +18 -0
  174. package/scripts/lib/report_screen.rb +1371 -47
  175. package/scripts/lib/rlm/corpus.rb +13 -0
  176. package/scripts/lib/rlm/probe.rb +29 -0
  177. package/scripts/lib/rlm/query.rb +22 -0
  178. package/scripts/lib/roadmap_graph.rb +210 -0
  179. package/scripts/lib/roadmap_migration.rb +95 -0
  180. package/scripts/lib/roadmap_queue.rb +170 -12
  181. package/scripts/lib/roadmap_render.rb +150 -0
  182. package/scripts/lib/roadmap_savepoint.rb +64 -14
  183. package/scripts/lib/runner_absorb.rb +703 -0
  184. package/scripts/lib/runner_answer.rb +206 -0
  185. package/scripts/lib/runner_core.rb +194 -0
  186. package/scripts/lib/runner_dispatch.rb +526 -0
  187. package/scripts/lib/runner_policy.rb +191 -0
  188. package/scripts/lib/runner_proposals.rb +275 -0
  189. package/scripts/lib/runner_rewind.rb +201 -0
  190. package/scripts/lib/runner_sweep.rb +231 -0
  191. package/scripts/lib/runner_until_empty.rb +252 -0
  192. package/scripts/lib/runner_watch.rb +389 -0
  193. package/scripts/lib/savepoint.rb +141 -19
  194. package/scripts/lib/scaffold_intent.rb +6 -3
  195. package/scripts/lib/screen_paint.rb +365 -28
  196. package/scripts/lib/screens/dashboard.rb +20 -0
  197. package/scripts/lib/screens/plan.rb +18 -0
  198. package/scripts/lib/screens/roadmap.rb +15 -0
  199. package/scripts/lib/search_index.rb +55 -0
  200. package/scripts/lib/session_close.rb +30 -28
  201. package/scripts/lib/session_git.rb +67 -19
  202. package/scripts/lib/session_ledger.rb +48 -4
  203. package/scripts/lib/session_usage.rb +190 -0
  204. package/scripts/lib/sqlite.rb +22 -0
  205. package/scripts/lib/stop_gate.rb +95 -0
  206. package/scripts/lib/store_discovery.rb +7 -6
  207. package/scripts/lib/store_layout.rb +54 -0
  208. package/scripts/lib/store_provisioning.rb +2 -1
  209. package/scripts/lib/store_sync.rb +85 -0
  210. package/scripts/lib/stores_move.rb +93 -0
  211. package/scripts/lib/untouched_scaffold.rb +51 -0
  212. package/scripts/lib/verify_intent.rb +36 -8
  213. package/scripts/lib/version_number.rb +48 -0
  214. package/scripts/lib/work_graph.rb +59 -0
  215. package/scripts/lib/work_graph_validator.rb +201 -0
  216. package/scripts/lib/worktree.rb +27 -32
  217. package/scripts/lib/worktree_sweep.rb +6 -5
  218. package/scripts/link-suggest +2 -1
  219. package/scripts/meter-watch +57 -0
  220. package/scripts/migrate-to-global +1 -1
  221. package/scripts/new-intent +4 -13
  222. package/scripts/node-input +92 -0
  223. package/scripts/node-run +225 -0
  224. package/scripts/node-transition +291 -0
  225. package/scripts/outcome-report +74 -0
  226. package/scripts/plastic-lock +65 -60
  227. package/scripts/project-links +6 -21
  228. package/scripts/promote-session-item +3 -2
  229. package/scripts/read-config +53 -9
  230. package/scripts/ready-set +126 -0
  231. package/scripts/release-check +123 -0
  232. package/scripts/report-screen +177 -16
  233. package/scripts/roadmap-graph +125 -0
  234. package/scripts/roadmap-savepoint +7 -0
  235. package/scripts/rollback.rb +5 -1
  236. package/scripts/runner +581 -0
  237. package/scripts/savepoint-note +11 -9
  238. package/scripts/session-commit +2 -1
  239. package/scripts/session-usage +56 -0
  240. package/scripts/skill-lint +115 -6
  241. package/scripts/spawn-preamble +2 -2
  242. package/scripts/update.rb +31 -4
  243. package/scripts/validate-work-graph +39 -0
  244. package/scripts/verify-intent +3 -2
  245. package/scripts/write-handoff +2 -1
  246. package/templates/agents.md +7 -7
  247. package/templates/config.yml +16 -9
  248. package/templates/dashboard-screen.md +22 -0
  249. package/templates/display-fixture.md +21 -0
  250. package/templates/graph.md +16 -0
  251. package/templates/index.md +1 -1
  252. package/templates/intent-screen.md +1 -1
  253. package/templates/node-decision.md +11 -0
  254. package/templates/node-research.md +13 -0
  255. package/templates/node-verify.md +13 -0
  256. package/templates/node-work.md +22 -0
  257. package/templates/outcome.md +8 -3
  258. package/templates/project.yml +1 -1
  259. package/templates/render.css +10 -0
  260. package/templates/report-plan.md +15 -0
  261. package/templates/report-roadmap-delivered.md +10 -0
  262. package/templates/report-roadmap-plan.md +9 -0
  263. package/templates/report-roadmap-state.md +9 -0
  264. package/templates/report-state.md +1 -1
  265. package/templates/roadmap.md +13 -0
  266. package/bin/plastic.js +0 -70
  267. package/scripts/lib/bridge.rb +0 -116
  268. package/skills/agent-advisor/SKILL.md +0 -92
  269. package/skills/auto/SKILL.md +0 -296
  270. package/skills/auto/evals/evals.json +0 -255
  271. package/skills/auto/references/end-tail.md +0 -66
  272. package/skills/auto/references/human-report-contract.md +0 -78
  273. package/skills/conventions/SKILL.md +0 -29
  274. package/skills/conventions/references/completion-and-done.md +0 -43
  275. package/skills/dashboard/SKILL.md +0 -169
  276. package/skills/dashboard/evals/evals.json +0 -38
  277. package/skills/dashboard/references/classification.md +0 -22
  278. package/skills/dashboard/templates/dashboard-global.md +0 -20
  279. package/skills/dashboard/templates/dashboard-project.md +0 -19
  280. package/skills/direct/SKILL.md +0 -66
  281. package/skills/direct/references/request-signals.md +0 -59
  282. package/skills/doctor/SKILL.md +0 -299
  283. package/skills/doctor/report.md +0 -102
  284. package/skills/feedback/SKILL.md +0 -98
  285. package/skills/feedback/references/transport-and-privacy.md +0 -65
  286. package/skills/feedback/report.md +0 -36
  287. package/skills/install/SKILL.md +0 -217
  288. package/skills/intent-continuing/SKILL.md +0 -154
  289. package/skills/intent-continuing/references/board-fill.md +0 -43
  290. package/skills/intent-continuing/references/boarding-matrix.md +0 -34
  291. package/skills/intent-continuing/references/context-management.md +0 -28
  292. package/skills/intent-continuing/references/liveness-ranking.md +0 -57
  293. package/skills/intent-creating/SKILL.md +0 -164
  294. package/skills/intent-creating/evals/evals.json +0 -72
  295. package/skills/intent-creating/references/lifecycle.md +0 -81
  296. package/skills/intent-creating/references/wikilinks.md +0 -8
  297. package/skills/intent-ending/SKILL.md +0 -176
  298. package/skills/intent-ending/evals/evals.json +0 -74
  299. package/skills/intent-executing/SKILL.md +0 -170
  300. package/skills/intent-executing/evals/evals.json +0 -66
  301. package/skills/intent-executing/implementer-prompt.md +0 -42
  302. package/skills/intent-executing/spec-reviewer-prompt.md +0 -27
  303. package/skills/intent-speccing/SKILL.md +0 -130
  304. package/skills/intent-speccing/evals/evals.json +0 -126
  305. package/skills/intent-speccing/references/design-principles.md +0 -44
  306. package/skills/intent-speccing/references/per-section-fill-rules.md +0 -92
  307. package/skills/intent-speccing/references/self-verify-checklist.md +0 -37
  308. package/skills/project-creating/SKILL.md +0 -162
  309. package/skills/project-creating/references/hubs-projects.md +0 -55
  310. package/skills/project-creating/references/project-scaffolding.md +0 -97
  311. package/skills/releasing/SKILL.md +0 -337
  312. package/skills/releasing/references/deprecations.md +0 -60
  313. package/skills/releasing/references/promotion-and-tagging.md +0 -66
  314. package/skills/releasing/references/release-lines.md +0 -105
  315. package/skills/roadmap/SKILL.md +0 -64
  316. package/skills/roadmap/references/file-format.md +0 -124
  317. package/skills/roadmap/references/operations.md +0 -112
  318. package/skills/rollback/SKILL.md +0 -91
  319. package/skills/tutorial/SKILL.md +0 -65
  320. package/skills/tutorial/evals/evals.json +0 -186
  321. package/skills/uninstall/SKILL.md +0 -75
  322. package/skills/update/SKILL.md +0 -126
  323. /package/{skills/auto/references → docs/help}/agent-report-contract.md +0 -0
  324. /package/{skills/intent-executing → docs/help}/code-quality-reviewer-prompt.md +0 -0
  325. /package/{skills/conventions/references → docs/help}/lifecycle-and-savepoints.md +0 -0
  326. /package/{skills/intent-executing → docs/help}/plan-reviewer-prompt.md +0 -0
@@ -9,7 +9,7 @@ will exist with more than one intent inside it and a roadmap file describing the
9
9
 
10
10
  ## Before you start
11
11
 
12
- Run `/plastic-update` first (`$plastic-update` on Codex), so the commands below match what is
12
+ Run `plastic update` first, so the commands below match what is
13
13
  actually installed.
14
14
 
15
15
  Work in a sandbox: this whole track is a walked example. It creates a real project directory
@@ -20,11 +20,11 @@ one this tutorial keeps or ships.
20
20
 
21
21
  ### 1. Start from a founding implementation intent
22
22
 
23
- Create and board an intent the same way as track 1, stations 1 and 2: `/plastic-intent-creating`,
24
- then `/plastic-intent-continuing`. Describe something meant to grow into a small real project,
23
+ Create and board an intent the same way as track 1, stations 1 and 2: `plastic intent new`,
24
+ then `plastic continue`. Describe something meant to grow into a small real project,
25
25
  for example "build a personal todo app."
26
26
 
27
- Then type `/plastic-intent-speccing` and record a couple of real rulings on this founding
27
+ Then type `plastic intent spec` and record a couple of real rulings on this founding
28
28
  intent, for example the language or how tasks get stored. Keep it short: this intent only
29
29
  needs enough decisions for the new project to inherit, not a full design.
30
30
 
@@ -33,17 +33,21 @@ into a whole new project.
33
33
 
34
34
  ### 2. Grow it into a project
35
35
 
36
- Type `/plastic-project-creating`.
36
+ Make the project directory yourself and write its `AGENTS.md`, carrying forward at least one
37
+ decision from the founding intent. Plastic does not create the directory or fill that file;
38
+ that is ordinary agent work, done once, before the project exists. Once the directory exists,
39
+ run `plastic project new SLUG --path PATH` to register it in `projects.yml` and provision and
40
+ validate its store.
37
41
 
38
- Artifact: a new project directory, an `AGENTS.md` file carrying the founding intent's
39
- decisions, the project's own intent store, and a new entry in `projects.yml` registering it.
42
+ Artifact: a new project directory with its `AGENTS.md`, the project's own intent store, and a
43
+ new entry in `projects.yml` registering it.
40
44
 
41
45
  Checkpoint: open `AGENTS.md` and find at least one line that traces back to a decision
42
46
  recorded in the founding intent back in station 1.
43
47
 
44
48
  ### 3. Add more intents inside the project
45
49
 
46
- Type `/plastic-intent-creating` at least twice, from inside the project, describing two
50
+ Run `plastic intent new` at least twice, from inside the project, describing two
47
51
  pieces of real work, for example "add a task list model" and "add a due date field."
48
52
 
49
53
  Artifact: two or more intent directories inside the project's own store, separate from the
@@ -54,13 +58,16 @@ in the global store.
54
58
 
55
59
  ### 4. Plan a delivery batch
56
60
 
57
- Type `/plastic-roadmap`.
61
+ Copy `templates/roadmap.md` to `roadmaps/<slug>.md`, next to the project's `INDEX.md`, and fill
62
+ it by hand: a title and short meta header, a `## Goal` section in prose describing what "done"
63
+ looks like for the whole batch, a `## Batches` section (an ordered list of groups of intents;
64
+ intents inside one batch are safe to run in parallel, batches themselves run one after another),
65
+ and an append-only, dated `## Log`. `INDEX.md` stays the single source of truth for each
66
+ intent's status; the roadmap only mirrors it. List the two or more intents from station 3
67
+ across one or more batches.
58
68
 
59
- Teach the roadmap file shape exactly: a title and short meta header, a `## Goal` section in
60
- prose describing what "done" looks like for the whole batch, a `## Batches` section (an
61
- ordered list of groups of intents; intents inside one batch are safe to run in parallel,
62
- batches themselves run one after another), and an append-only, dated `## Log`. `INDEX.md`
63
- stays the single source of truth for each intent's status; the roadmap only mirrors it.
69
+ Run `plastic roadmap check <slug>` to confirm the file parses, then `plastic roadmap show
70
+ <slug>` to see it rendered as a report.
64
71
 
65
72
  Artifact: a new `roadmaps/<slug>.md` file, sitting next to the project's `INDEX.md`, listing
66
73
  the two or more intents from station 3 across one or more batches.
@@ -93,8 +100,8 @@ sections you turned into the condition above.
93
100
 
94
101
  No command run here; describe the step instead. Each delivered intent's code merges to main
95
102
  as it lands. When the batch (or a meaningful slice of it) is ready to ship, cutting a release
96
- runs through `/plastic-releasing`, which merges, bumps the version, tags, and completes the
97
- intents it collects.
103
+ is a push to `alpha`, `beta`, or `main`: the version files are bumped in that push, and CI
104
+ tags, publishes, and completes the intents it collects.
98
105
 
99
106
  Releases and any npm publish step are described here, not run: this walkthrough stays in a
100
107
  sandbox and never touches a real package registry.
@@ -108,4 +115,4 @@ This is the same What, Why, How, Exec cycle from tracks 1 and 2, repeated across
108
115
  and gathered by a roadmap. Read
109
116
  [`using-plastic-with-claude-code.md`](https://github.com/zalom/plastic/blob/main/docs/guides/using-plastic-with-claude-code.md) for roadmap-driven delivery in more depth,
110
117
  including a real worked roadmap. For the exact roadmap file format beyond what this
111
- walkthrough covers, the `plastic-roadmap` skill itself is the reference.
118
+ walkthrough covers, [`docs/help/roadmaps.md`](roadmaps.md) is the reference.
@@ -0,0 +1,4 @@
1
+ #!/bin/bash
2
+ INPUT=$(cat)
3
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
4
+ echo "$INPUT" | env -u RUBYOPT ruby --disable-gems "$SCRIPT_DIR/../scripts/hook-call-budget"
package/hooks/hooks.json CHANGED
@@ -17,6 +17,18 @@
17
17
  ]
18
18
  }
19
19
  ],
20
+ "PreToolUse": [
21
+ {
22
+ "matcher": "",
23
+ "hooks": [
24
+ {
25
+ "type": "command",
26
+ "command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook\" call-budget",
27
+ "statusMessage": ""
28
+ }
29
+ ]
30
+ }
31
+ ],
20
32
  "PreCompact": [
21
33
  {
22
34
  "matcher": "",
@@ -76,6 +88,18 @@
76
88
  }
77
89
  ]
78
90
  }
91
+ ],
92
+ "Stop": [
93
+ {
94
+ "matcher": "",
95
+ "hooks": [
96
+ {
97
+ "type": "command",
98
+ "command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook\" stop",
99
+ "statusMessage": ""
100
+ }
101
+ ]
102
+ }
79
103
  ]
80
104
  }
81
105
  }
@@ -57,8 +57,18 @@ if [ "$is_index_zero" = 1 ]; then
57
57
  *'"delta":"#'*|*'"delta": "#'*) handoff=1 ;;
58
58
  *'"delta":"▶'*|*'"delta": "▶'*) handoff=1 ;;
59
59
  *'"delta":"✔'*|*'"delta": "✔'*) handoff=1 ;;
60
- *'"delta":"▶'*|*'"delta": "▶'*) handoff=1 ;;
61
- *'"delta":"✔'*|*'"delta": "✔'*) handoff=1 ;;
60
+ esac
61
+ # 331a review fix (M12e): chunk 0 is not exempt from D5 either. The
62
+ # intent's own flagship shape -- a lead-in sentence and the opener in the
63
+ # SAME first chunk -- never starts with "#", "▶", or "✔", so the arm
64
+ # above alone never sees it. Joins it with the identical opener-anywhere
65
+ # globs used for a later chunk (M12a) rather than replacing anything:
66
+ # same reasoning as the comment at that site applies verbatim here.
67
+ case $INPUT in
68
+ *'"delta":"'*'▶'*|*'"delta": "'*'▶'*) handoff=1 ;;
69
+ *'"delta":"'*'✔'*|*'"delta": "'*'✔'*) handoff=1 ;;
70
+ *'"delta":"'*'\u25b6'*|*'"delta": "'*'\u25b6'*) handoff=1 ;;
71
+ *'"delta":"'*'\u2714'*|*'"delta": "'*'\u2714'*) handoff=1 ;;
62
72
  esac
63
73
  else
64
74
  # A later chunk: hand off when this message's directory already exists
@@ -74,8 +84,51 @@ else
74
84
  *'"delta":""'*|*'"delta": ""'*) handoff=1 ;;
75
85
  *'"delta":"\n"'*|*'"delta": "\n"'*) handoff=1 ;;
76
86
  esac
87
+ # 331a (D5): the hook engages anywhere. An opener can now fall ANYWHERE
88
+ # inside a later chunk's own delta, not only at its start (the shape
89
+ # tests just above), so these globs search the delta value rather than
90
+ # anchor to its opening quote. Still anchored to the "delta":" key itself
91
+ # (never dropped, matrix M12d) so an ordinary field elsewhere in the
92
+ # payload can never be mistaken for the delta's own text; within that,
93
+ # every shipped opener (## ▶, ## ✔, ▶ In delivery, ✔ + digit) contains a
94
+ # bare ▶ or ✔, so matching the bare glyph anywhere covers all four at
95
+ # once. Prose that merely shapes like an opener still hands off this way
96
+ # (an accepted over-match: Ruby's own grammar is the final, stricter
97
+ # arbiter and fails open on anything that is not a real one). Raw glyph
98
+ # and \u-escaped forms both count, since the encoder's choice is not ours
99
+ # to predict.
100
+ case $INPUT in
101
+ *'"delta":"'*'▶'*|*'"delta": "'*'▶'*) handoff=1 ;;
102
+ *'"delta":"'*'✔'*|*'"delta": "'*'✔'*) handoff=1 ;;
103
+ *'"delta":"'*'\u25b6'*|*'"delta": "'*'\u25b6'*) handoff=1 ;;
104
+ *'"delta":"'*'\u2714'*|*'"delta": "'*'\u2714'*) handoff=1 ;;
105
+ esac
77
106
  fi
78
107
 
79
108
  [ "$handoff" = 1 ] || exit 0
80
109
 
110
+ # 331a1 (D1): chunk 0 is about to hand off to Ruby, which takes on the
111
+ # order of 150 ms to boot before it ever writes SCREEN or NOSCREEN. Claude
112
+ # Code fires the per-chunk hook PROCESSES CONCURRENTLY (see the header
113
+ # comment above), so a later chunk landing inside that window used to find
114
+ # no message directory at all, fail this script's own cheap shape test,
115
+ # and pass through as raw Markdown - measured at 15 to 21 chunks of every
116
+ # screen, against a stream-realistic 5 ms stagger. Staking a PENDING
117
+ # marker here, the instant the handoff gate above passes, closes that
118
+ # window down to microseconds: a later chunk's own "does the directory
119
+ # exist" check (below, unchanged) now finds it almost at once, and
120
+ # MessageDisplay polls for the real decision instead of judging the
121
+ # chunk's own shape. mkdir is the one non-builtin on this whole path - it
122
+ # forks, unlike everything else in this file - but it runs ONLY here,
123
+ # after the handoff gate, so the ordinary (non-candidate) chunk that is
124
+ # the overwhelming common case still forks nothing (matrix L8). A failed
125
+ # mkdir or printf (an unwritable tmp root, a race with another process) is
126
+ # silently swallowed: it must never change this script's own exit status
127
+ # or skip the Ruby handoff below - Ruby's own polling already fails open
128
+ # (D5) when no decision ever appears.
129
+ if [ "$is_index_zero" = 1 ]; then
130
+ mkdir -p "$MSGDIR" 2>/dev/null
131
+ printf '' > "$MSGDIR/PENDING" 2>/dev/null
132
+ fi
133
+
81
134
  printf '%s' "$INPUT" | env -u RUBYOPT ruby "$SCRIPT_DIR/../scripts/hook-message-display"
@@ -1,5 +1,9 @@
1
1
  #!/bin/bash
2
- GLOBAL_INDEX="$HOME/.plastic/INDEX.md"
2
+ if [ -d "$HOME/.plastic/stores" ]; then
3
+ GLOBAL_INDEX="$HOME/.plastic/stores/global/INDEX.md"
4
+ else
5
+ GLOBAL_INDEX="$HOME/.plastic/INDEX.md"
6
+ fi
3
7
 
4
8
  if [ ! -f "$GLOBAL_INDEX" ]; then
5
9
  exit 0
package/hooks/statusline CHANGED
@@ -2,8 +2,8 @@
2
2
  # plastic-hook-version: 4.0.0
3
3
  # StatusLine hook - Plastic owns the full statusline (no chaining).
4
4
  # Renders: {model} - ctx {pct}% ({used}/{size}) - 5h {p}% - 7d {p}% - ${cost}
5
- # - claudish {n} rw / {tok} - Plastic {version}[ -> {next}] - {path}
6
- # Every segment but claudish and the Plastic version comes from the stdin payload.
5
+ # - Plastic {version}[ -> {next}] - {path}
6
+ # Every segment but the Plastic version comes from the stdin payload.
7
7
  # Pure bash (macOS 3.2 compatible). No ruby, no jq. Reads stdin once; small file reads
8
8
  # only. The stdin JSON is walked in a single awk pass (below); nothing else in this
9
9
  # script forks a second process per field, which is what keeps a render cheap.
@@ -17,7 +17,6 @@ C_OK='' # default - meter below 70%
17
17
  C_WARN=$'\033[33m' # yellow - meter at 70% and above
18
18
  C_CRIT=$'\033[38;2;231;76;60m' # red - meter at 90% and above
19
19
  C_COST=$'\033[37m' # white - session cost
20
- C_CLAUDISH=$'\033[38;2;249;140;30m' # orange - claudish rewrites
21
20
  C_VER=$'\033[37m' # white - "Plastic {version}" and update arrow
22
21
  C_NEXT=$'\033[33m' # yellow - next version
23
22
  C_PATH=$'\033[38;2;128;134;144m' # gray - path (matches dim UI text)
@@ -188,6 +187,7 @@ FIELDS=$(printf '%s' "$INPUT" | awk '
188
187
  wanted["context_window.current_usage.cache_read_input_tokens"] = 1
189
188
  wanted["cost.total_cost_usd"] = 1
190
189
  wanted["rate_limits.five_hour.used_percentage"] = 1
190
+ wanted["rate_limits.five_hour.resets_at"] = 1
191
191
  wanted["rate_limits.seven_day.used_percentage"] = 1
192
192
  }
193
193
  { buf = buf $0 " " }
@@ -210,6 +210,7 @@ CU_CC=""
210
210
  CU_CR=""
211
211
  COST_RAW=""
212
212
  M5_PCT=""
213
+ M5_RESETS=""
213
214
  M7_PCT=""
214
215
 
215
216
  while IFS=$'\t' read -r k v; do
@@ -225,6 +226,7 @@ while IFS=$'\t' read -r k v; do
225
226
  context_window.current_usage.cache_read_input_tokens) CU_CR="$v" ;;
226
227
  cost.total_cost_usd) COST_RAW="$v" ;;
227
228
  rate_limits.five_hour.used_percentage) M5_PCT="$v" ;;
229
+ rate_limits.five_hour.resets_at) M5_RESETS="$v" ;;
228
230
  rate_limits.seven_day.used_percentage) M7_PCT="$v" ;;
229
231
  esac
230
232
  done <<FIELDS_EOF
@@ -302,6 +304,31 @@ meter_seg() { # $1 = label, $2 = raw percentage
302
304
  M5=$(meter_seg "5h" "$M5_PCT")
303
305
  M7=$(meter_seg "7d" "$M7_PCT")
304
306
 
307
+ # --- Rate-limits cache for MeterWatch (graph.md D11) ---
308
+ # Written only when the payload carries a meter at all; an API-key session
309
+ # with no rate_limits section leaves the cache untouched. A present meter
310
+ # with no matching value writes null rather than dropping the key, so
311
+ # MeterWatch always sees the same three fields. Temp file in the cache
312
+ # directory, then mv, so MeterWatch never reads a half-written file.
313
+ if [ -n "$M5_PCT" ] || [ -n "$M7_PCT" ]; then
314
+ CACHE_DIR="$HOME/.plastic/.cache"
315
+ mkdir -p "$CACHE_DIR"
316
+ CACHE5=$(to_int "$M5_PCT")
317
+ CACHE7=$(to_int "$M7_PCT")
318
+ [ -z "$CACHE5" ] && CACHE5=null
319
+ [ -z "$CACHE7" ] && CACHE7=null
320
+ if [ -n "$M5_RESETS" ]; then
321
+ RESETS_JSON="\"$M5_RESETS\""
322
+ else
323
+ RESETS_JSON=null
324
+ fi
325
+ CACHE_AT=$(date -u +%Y-%m-%dT%H:%M:%SZ)
326
+ CACHE_TMP="$CACHE_DIR/.rate-limits.json.tmp.$$"
327
+ printf '{"five_hour":%s,"seven_day":%s,"resets_at":%s,"at":"%s"}\n' \
328
+ "$CACHE5" "$CACHE7" "$RESETS_JSON" "$CACHE_AT" > "$CACHE_TMP"
329
+ mv "$CACHE_TMP" "$CACHE_DIR/rate-limits.json"
330
+ fi
331
+
305
332
  # --- Session cost (stdin cost.total_cost_usd); hidden when it renders as $0.00 ---
306
333
  COST_SEG=""
307
334
  if [ -n "$COST_RAW" ]; then
@@ -309,40 +336,18 @@ if [ -n "$COST_RAW" ]; then
309
336
  [ -n "$COST_FMT" ] && [ "$COST_FMT" != "0.00" ] && COST_SEG="${C_COST}\$${COST_FMT}${RST}"
310
337
  fi
311
338
 
312
- # --- claudish rewrites for THIS session (fork ledger, optional) ---
313
- # Tab separated, one call per line; column 11 is the session id. Rows written
314
- # before that column existed have 9 or 10 fields and never match, so an old
315
- # ledger renders no segment instead of a wrong one.
316
- CL_SEG=""
317
- CL_LOG="${CLAUDISH_LOCAL_DIR:-$HOME/.claude/claudish-local}/usage.log"
318
- if [ -n "$SID" ] && [ -f "$CL_LOG" ]; then
319
- CL=$(awk -F'\t' -v sid="$SID" '
320
- NF >= 11 && $11 == sid { n++; t += $5 + $6 }
321
- END {
322
- if (n > 0) {
323
- if (t >= 1000) {
324
- s = sprintf("%.1f", t / 1000); sub(/\.0$/, "", s); printf "%d %sk", n, s
325
- } else {
326
- printf "%d %d", n, t
327
- }
328
- }
329
- }' "$CL_LOG" 2>/dev/null)
330
- [ -n "$CL" ] && CL_SEG="${C_CLAUDISH}claudish ${CL%% *} rw / ${CL#* }${RST}"
331
- fi
332
-
333
339
  # --- Assemble segments in order, joined by " . " ---
334
340
  PARTS=""
335
341
  add() { [ -z "$1" ] && return; if [ -z "$PARTS" ]; then PARTS="$1"; else PARTS="$PARTS$SEP$1"; fi; }
336
342
 
337
- # Order: identity first (model), then this session's spend (context, meters, cost,
338
- # rewrites), then the volatile-length values last (version, path) so the line does
343
+ # Order: identity first (model), then this session's spend (context, meters, cost),
344
+ # then the volatile-length values last (version, path) so the line does
339
345
  # not visually jump as they change.
340
346
  [ -n "$MODEL" ] && add "${C_MODEL}${MODEL}${RST}"
341
347
  add "$CTX_SEG"
342
348
  add "$M5"
343
349
  add "$M7"
344
350
  add "$COST_SEG"
345
- add "$CL_SEG"
346
351
  if [ -n "$VERSION" ]; then
347
352
  vseg="${C_VER}Plastic ${VERSION}${RST}"
348
353
  [ -n "$NEXT" ] && vseg="${vseg}${C_VER} "$'\342\206\222'" ${RST}${C_NEXT}${NEXT}${RST}"
package/hooks/stop ADDED
@@ -0,0 +1,5 @@
1
+ #!/bin/bash
2
+ INPUT=$(cat)
3
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
4
+ echo "$INPUT" | env -u RUBYOPT ruby "$SCRIPT_DIR/../scripts/hook-stop" "$HOME/.plastic"
5
+ exit 0
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@zalom/plastic",
3
- "version": "2.0.0-alpha.9",
3
+ "version": "2.0.2",
4
4
  "description": "Intent-driven idea development system for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
7
- "plastic": "bin/plastic.js"
7
+ "plastic": "bin/plastic"
8
8
  },
9
9
  "engines": {
10
10
  "node": ">=18.0.0"
@@ -27,13 +27,15 @@
27
27
  "license": "MIT",
28
28
  "repository": {
29
29
  "type": "git",
30
- "url": "https://github.com/zalom/plastic"
30
+ "url": "git+https://github.com/zalom/plastic.git"
31
31
  },
32
32
  "homepage": "https://github.com/zalom/plastic",
33
33
  "files": [
34
+ "assets/",
34
35
  "bin/",
35
36
  "scripts/",
36
37
  "skills/",
38
+ "docs/help/",
37
39
  "hooks/",
38
40
  "agents/",
39
41
  "templates/",
@@ -30,6 +30,7 @@
30
30
  # 2 - usage error, or promote/tick found nothing to address (no write happens)
31
31
  # 3 - promote/tick could not take an exclusive lock (filesystem without flock support)
32
32
 
33
+ require_relative "lib/store_layout"
33
34
  require_relative "lib/session_ledger"
34
35
  require_relative "lib/handoff"
35
36
 
@@ -162,7 +163,7 @@ def main(argv)
162
163
  usage_abort("verb must be one of #{VERBS.join(", ")}, got #{opts[:verb].inspect}") unless VERBS.include?(opts[:verb])
163
164
 
164
165
  plastic_home = expand(ENV.fetch("PLASTIC_HOME", "~/.plastic"))
165
- store = opts[:store] ? expand(opts[:store]) : File.join(plastic_home, "store")
166
+ store = opts[:store] ? expand(opts[:store]) : Plastic::StoreLayout.global_store(plastic_home)
166
167
  templates = opts[:templates] ? expand(opts[:templates]) : default_templates_dir
167
168
  usage_abort("templates dir not found: #{templates}") unless Dir.exist?(templates)
168
169
  opts[:templates] = templates