@zalom/plastic 1.0.0-alpha.2 → 1.0.0-alpha.21
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 +128 -473
- package/README.md +90 -58
- package/agents/future-intent-researcher.md +1 -1
- package/agents/intent-curator.md +1 -1
- package/bin/plastic.js +57 -0
- package/bin/test +28 -0
- package/deprecations.yml +7 -6
- package/hooks/auto-arm +5 -0
- package/hooks/bash-gate +3 -0
- package/hooks/check-update +12 -8
- package/hooks/code-gate +10 -0
- package/hooks/hooks.json +25 -4
- package/hooks/statusline +50 -10
- package/package.json +2 -2
- package/scripts/dashboard.rb +480 -0
- package/scripts/doctor.rb +973 -0
- package/scripts/hook-auto-arm +52 -0
- package/scripts/hook-bash-gate +53 -0
- package/scripts/hook-code-gate +39 -0
- package/scripts/hook-continue +15 -114
- package/scripts/hook-gate-check +19 -4
- package/scripts/hook-session-start +76 -31
- package/scripts/install.rb +91 -480
- package/scripts/lib/bridge.rb +255 -0
- package/scripts/lib/installer_core.rb +760 -0
- package/scripts/migrate-to-global +1 -1
- package/scripts/select-update-target +93 -0
- package/scripts/uninstall.rb +53 -0
- package/scripts/update.rb +142 -0
- package/scripts/versions.rb +141 -0
- package/skills/_active-intent-gate.md +26 -0
- package/skills/auto/SKILL.md +62 -9
- package/skills/auto/evals/evals.json +92 -0
- package/skills/auto/references/agent-architecture.md +60 -0
- package/skills/brainstorming/SKILL.md +143 -0
- package/skills/brainstorming-grill-me/SKILL.md +5 -5
- package/skills/continuing/SKILL.md +102 -77
- package/skills/continuing/evals/evals.json +136 -0
- package/skills/continuing/references/context-management.md +32 -0
- package/skills/creating-intent/SKILL.md +16 -1
- package/skills/creating-intent/references/lifecycle.md +74 -0
- package/skills/creating-intent/references/wikilinks.md +8 -0
- package/skills/creating-project/SKILL.md +8 -4
- package/skills/creating-project/references/hubs-projects.md +55 -0
- package/skills/dashboard/SKILL.md +92 -0
- package/skills/doctor/SKILL.md +116 -0
- package/skills/doctor/references/gates-stuck-detection.md +38 -0
- package/skills/doctor/report.md +96 -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 +3 -3
- package/skills/install/SKILL.md +56 -8
- package/skills/intent-curator/SKILL.md +3 -3
- package/skills/linking-intents/SKILL.md +5 -1
- package/skills/linking-intents/references/zettelkasten.md +33 -0
- package/skills/managing-index/SKILL.md +5 -1
- package/skills/releasing/SKILL.md +119 -18
- package/skills/releasing/references/deprecations.md +44 -0
- package/skills/research/SKILL.md +114 -0
- 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 -36
- 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 +183 -0
- package/templates/agents.md +16 -0
- package/templates/outcome.md +13 -0
- package/templates/project.yml +5 -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,119 @@
|
|
|
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
|
-
| `intent-curator` | Maintains INDEX.md health, suggests links |
|
|
84
|
-
| `future-intent-researcher` | Researches parked future intents |
|
|
115
|
+
All conventions live in `AGENTS.md`, distributed to `~/.plastic/AGENTS.md`
|
|
116
|
+
during installation. Run `plastic-doctor` to check installation health.
|
|
85
117
|
|
|
86
118
|
## License
|
|
87
119
|
|
package/agents/intent-curator.md
CHANGED
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
|
@@ -12,12 +12,13 @@
|
|
|
12
12
|
# link: optional URL to migration guide
|
|
13
13
|
|
|
14
14
|
deprecations:
|
|
15
|
-
- id: cc-plugin-to-
|
|
16
|
-
severity:
|
|
17
|
-
summary: "Plastic
|
|
15
|
+
- id: cc-plugin-to-hyphen-skills
|
|
16
|
+
severity: warning
|
|
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/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,10 @@
|
|
|
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
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
10
|
+
ruby "$SCRIPT_DIR/../scripts/hook-code-gate" "$FILE_PATH"
|
package/hooks/hooks.json
CHANGED
|
@@ -29,6 +29,28 @@
|
|
|
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": "Bash",
|
|
45
|
+
"hooks": [
|
|
46
|
+
{
|
|
47
|
+
"type": "command",
|
|
48
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook\" bash-gate",
|
|
49
|
+
"statusMessage": "Checking lifecycle gate..."
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
}
|
|
53
|
+
],
|
|
32
54
|
"PostToolUse": [
|
|
33
55
|
{
|
|
34
56
|
"matcher": "Write|Edit",
|
|
@@ -61,15 +83,14 @@
|
|
|
61
83
|
"statusMessage": "Checking future intents..."
|
|
62
84
|
}
|
|
63
85
|
]
|
|
64
|
-
}
|
|
65
|
-
],
|
|
66
|
-
"statusLine": [
|
|
86
|
+
},
|
|
67
87
|
{
|
|
68
88
|
"matcher": "",
|
|
69
89
|
"hooks": [
|
|
70
90
|
{
|
|
71
91
|
"type": "command",
|
|
72
|
-
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/
|
|
92
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/auto-arm\"",
|
|
93
|
+
"statusMessage": "Checking auto mode..."
|
|
73
94
|
}
|
|
74
95
|
]
|
|
75
96
|
}
|
package/hooks/statusline
CHANGED
|
@@ -1,16 +1,56 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
# plastic-hook-version:
|
|
3
|
-
# StatusLine hook —
|
|
2
|
+
# plastic-hook-version: 2.0.0
|
|
3
|
+
# StatusLine hook — chains user's original statusline, adds Plastic info
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
INPUT=$(cat)
|
|
6
|
+
|
|
7
|
+
# --- Chain original statusline ---
|
|
8
|
+
ORIGINAL_CONFIG="$HOME/.plastic/.cache/original-statusline.json"
|
|
9
|
+
ORIGINAL_OUTPUT=""
|
|
10
|
+
if [ -f "$ORIGINAL_CONFIG" ]; then
|
|
11
|
+
ORIGINAL_CMD=$(grep -o '"command":"[^"]*"' "$ORIGINAL_CONFIG" 2>/dev/null | head -1 | cut -d'"' -f4)
|
|
12
|
+
if [ -z "$ORIGINAL_CMD" ]; then
|
|
13
|
+
ORIGINAL_CMD=$(grep -o '"command": "[^"]*"' "$ORIGINAL_CONFIG" 2>/dev/null | head -1 | sed 's/.*"command": "//;s/".*//')
|
|
14
|
+
fi
|
|
15
|
+
if [ -n "$ORIGINAL_CMD" ] && [ -x "$ORIGINAL_CMD" ]; then
|
|
16
|
+
ORIGINAL_OUTPUT=$(echo "$INPUT" | "$ORIGINAL_CMD" 2>/dev/null)
|
|
17
|
+
fi
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
# --- Plastic status ---
|
|
21
|
+
PLASTIC_PARTS=""
|
|
6
22
|
|
|
7
|
-
|
|
8
|
-
|
|
23
|
+
# Active intent from INDEX.md
|
|
24
|
+
INDEX="$HOME/.plastic/INDEX.md"
|
|
25
|
+
if [ -f "$INDEX" ]; then
|
|
26
|
+
ACTIVE=$(sed -n '/^## Active$/,/^## /{/^- \[/p;}' "$INDEX" | head -1)
|
|
27
|
+
if [ -n "$ACTIVE" ]; then
|
|
28
|
+
INTENT=$(echo "$ACTIVE" | sed 's/^- \[\([^]]*\)\].*/\1/')
|
|
29
|
+
PLASTIC_PARTS="plastic: ${INTENT}"
|
|
30
|
+
fi
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
# Update notification
|
|
34
|
+
CACHE_FILE="$HOME/.plastic/.cache/update-check.json"
|
|
35
|
+
if [ -f "$CACHE_FILE" ]; then
|
|
36
|
+
UPDATE_AVAILABLE=$(grep -o '"updateAvailable":true' "$CACHE_FILE" 2>/dev/null)
|
|
37
|
+
if [ -n "$UPDATE_AVAILABLE" ]; then
|
|
38
|
+
LATEST=$(grep -o '"latest":"[^"]*"' "$CACHE_FILE" 2>/dev/null | head -1 | cut -d'"' -f4)
|
|
39
|
+
CURRENT=$(grep -o '"current":"[^"]*"' "$CACHE_FILE" 2>/dev/null | head -1 | cut -d'"' -f4)
|
|
40
|
+
UPDATE_MSG="plastic update: $CURRENT -> $LATEST"
|
|
41
|
+
if [ -n "$PLASTIC_PARTS" ]; then
|
|
42
|
+
PLASTIC_PARTS="$PLASTIC_PARTS | $UPDATE_MSG"
|
|
43
|
+
else
|
|
44
|
+
PLASTIC_PARTS="$UPDATE_MSG"
|
|
45
|
+
fi
|
|
46
|
+
fi
|
|
9
47
|
fi
|
|
10
48
|
|
|
11
|
-
|
|
12
|
-
if [ -n "$
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
echo "
|
|
49
|
+
# --- Combine output ---
|
|
50
|
+
if [ -n "$ORIGINAL_OUTPUT" ] && [ -n "$PLASTIC_PARTS" ]; then
|
|
51
|
+
echo "$ORIGINAL_OUTPUT | $PLASTIC_PARTS"
|
|
52
|
+
elif [ -n "$ORIGINAL_OUTPUT" ]; then
|
|
53
|
+
echo "$ORIGINAL_OUTPUT"
|
|
54
|
+
elif [ -n "$PLASTIC_PARTS" ]; then
|
|
55
|
+
echo "$PLASTIC_PARTS"
|
|
16
56
|
fi
|
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.21",
|
|
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"
|