@zalom/plastic 1.0.0-alpha.18 → 1.0.0-alpha.19
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 +48 -6
- package/bin/plastic.js +57 -0
- package/bin/test +28 -0
- package/hooks/bash-gate +3 -0
- package/hooks/hooks.json +10 -0
- package/package.json +2 -2
- package/scripts/doctor.rb +741 -729
- package/scripts/hook-bash-gate +53 -0
- package/scripts/hook-session-start +42 -34
- package/scripts/install.rb +90 -695
- package/scripts/lib/bridge.rb +103 -0
- package/scripts/lib/installer_core.rb +760 -0
- package/scripts/uninstall.rb +53 -0
- package/scripts/update.rb +142 -0
- package/scripts/versions.rb +141 -0
- package/skills/brainstorming/SKILL.md +1 -1
- package/skills/executing-plan/SKILL.md +2 -2
- package/skills/install/SKILL.md +5 -5
- package/skills/uninstall/SKILL.md +2 -2
- package/skills/update/SKILL.md +35 -91
- package/skills/versions/SKILL.md +65 -0
- package/templates/outcome.md +13 -0
- package/templates/spec.md +25 -0
- package/bin/install.js +0 -29
package/README.md
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
> Install: `npx @zalom/plastic@alpha --claude`
|
|
5
5
|
|
|
6
6
|
Intent-driven idea development system for AI coding agents. Named after
|
|
7
|
-
**neuroplasticity
|
|
7
|
+
**neuroplasticity**: adaptive, malleable, dynamic, resilient.
|
|
8
8
|
|
|
9
|
-
Plastic thinks in **intents**, not tasks. An intent is a desire
|
|
9
|
+
Plastic thinks in **intents**, not tasks. An intent is a desire, something
|
|
10
10
|
you want to accomplish, explore, or understand. Intents are atomic thoughts
|
|
11
11
|
that get developed through two nested processes.
|
|
12
12
|
|
|
@@ -20,18 +20,53 @@ This loop runs continuously across sessions.
|
|
|
20
20
|
from motivation through specification, planning, to delivery. Intents produce
|
|
21
21
|
artifacts: `spec.md`, `plan.md`, `checklist.md`, `outcome.md`.
|
|
22
22
|
|
|
23
|
+
## How Plastic Works
|
|
24
|
+
|
|
25
|
+
Plastic is a **thinking system**, a blueprint for taking a desire from intent to
|
|
26
|
+
delivery. It splits the work in two:
|
|
27
|
+
|
|
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.
|
|
33
|
+
|
|
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.
|
|
40
|
+
|
|
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.
|
|
45
|
+
|
|
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.
|
|
51
|
+
|
|
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.
|
|
57
|
+
|
|
23
58
|
## Install
|
|
24
59
|
|
|
25
60
|
Plastic requires Ruby (pre-installed on macOS/Linux) and Node.js 18+.
|
|
26
61
|
|
|
27
62
|
```bash
|
|
28
|
-
# Alpha (current
|
|
63
|
+
# Alpha (current, active development)
|
|
29
64
|
npx @zalom/plastic@alpha --claude
|
|
30
65
|
|
|
31
|
-
# Beta (when available
|
|
66
|
+
# Beta (when available, API-stable, bug hunting)
|
|
32
67
|
npx @zalom/plastic@beta --claude
|
|
33
68
|
|
|
34
|
-
# Stable (when available
|
|
69
|
+
# Stable (when available, general use)
|
|
35
70
|
npx @zalom/plastic --claude
|
|
36
71
|
```
|
|
37
72
|
|
|
@@ -42,7 +77,7 @@ Bun users can substitute `bunx` for `npx` (e.g. `bunx @zalom/plastic@alpha --cla
|
|
|
42
77
|
Bun is never required.
|
|
43
78
|
|
|
44
79
|
Skills install as flat, hyphen-namespaced personal skills (`plastic-doctor`,
|
|
45
|
-
`plastic-auto`,
|
|
80
|
+
`plastic-auto`, and so on). Invoke them with a hyphen. Plastic is **not** a Claude Code
|
|
46
81
|
plugin; re-running the installer auto-removes any legacy plugin registration.
|
|
47
82
|
|
|
48
83
|
### Updating
|
|
@@ -68,6 +103,13 @@ After installation, run `/clear` to load Plastic conventions, then:
|
|
|
68
103
|
|
|
69
104
|
Or say "auto" to let the agent handle the full lifecycle autonomously.
|
|
70
105
|
|
|
106
|
+
## Documentation
|
|
107
|
+
|
|
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.
|
|
112
|
+
|
|
71
113
|
## Conventions
|
|
72
114
|
|
|
73
115
|
All conventions live in `AGENTS.md`, distributed to `~/.plastic/AGENTS.md`
|
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/hooks/bash-gate
ADDED
package/hooks/hooks.json
CHANGED
|
@@ -39,6 +39,16 @@
|
|
|
39
39
|
"statusMessage": "Checking lifecycle gate..."
|
|
40
40
|
}
|
|
41
41
|
]
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"matcher": "Bash",
|
|
45
|
+
"hooks": [
|
|
46
|
+
{
|
|
47
|
+
"type": "command",
|
|
48
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook\" bash-gate",
|
|
49
|
+
"statusMessage": "Checking lifecycle gate..."
|
|
50
|
+
}
|
|
51
|
+
]
|
|
42
52
|
}
|
|
43
53
|
],
|
|
44
54
|
"PostToolUse": [
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zalom/plastic",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.19",
|
|
4
4
|
"description": "Intent-driven idea development system for AI coding agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"plastic": "bin/
|
|
7
|
+
"plastic": "bin/plastic.js"
|
|
8
8
|
},
|
|
9
9
|
"engines": {
|
|
10
10
|
"node": ">=18.0.0"
|