@zalom/plastic 2.0.0-alpha.27 → 2.0.0-alpha.28
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 +13 -139
- package/README.md +337 -133
- package/agents/plastic-enforcer.md +9 -10
- package/agents/plastic-executor.md +1 -1
- package/bin/crap +4 -0
- package/bin/lib/context_budget.rb +35 -1
- package/bin/lib/skill_census.rb +839 -0
- package/bin/plastic +6 -0
- package/bin/plastic-skill-census +114 -0
- package/bin/verify-change +345 -0
- package/deprecations.yml +1 -1
- package/{skills/agent-advisor/references → docs/help}/advisor-protocol.md +4 -7
- package/{skills/auto/references → docs/help}/agent-architecture.md +7 -7
- package/{skills/conventions/references → docs/help}/completion-and-done.md +1 -1
- package/{skills/auto/references → docs/help}/human-report-contract.md +17 -19
- package/{skills/conventions/references → docs/help}/roadmaps.md +2 -2
- package/{skills/tutorial/references → docs/help}/track-1-guided.md +8 -8
- package/{skills/tutorial/references → docs/help}/track-2-auto.md +5 -5
- package/{skills/tutorial/references → docs/help}/track-3-projects-and-roadmaps.md +24 -17
- package/package.json +3 -2
- package/scripts/append-ledger +2 -1
- package/scripts/dashboard.rb +10 -9
- package/scripts/day-summary +2 -1
- package/scripts/doctor.rb +48 -42
- package/scripts/end-intent +2 -8
- package/scripts/file-session-intent +2 -1
- package/scripts/hook-capture +4 -3
- package/scripts/hook-close +2 -1
- package/scripts/hook-record +3 -2
- package/scripts/hook-savepoint +3 -2
- package/scripts/hook-session-start +5 -4
- package/scripts/hook-stop +2 -1
- package/scripts/insight-append +1 -2
- package/scripts/install.rb +3 -1
- package/scripts/lib/active_delivery.rb +1 -1
- package/scripts/lib/arm.rb +2 -1
- package/scripts/lib/backup.rb +63 -0
- package/scripts/lib/cli/command.rb +85 -0
- package/scripts/lib/cli/commands/auto.rb +18 -0
- package/scripts/lib/cli/commands/auto_brief.rb +44 -0
- package/scripts/lib/cli/commands/auto_lock.rb +60 -0
- package/scripts/lib/cli/commands/auto_report.rb +50 -0
- package/scripts/lib/cli/commands/auto_take.rb +25 -0
- package/scripts/lib/cli/commands/backup.rb +43 -0
- package/scripts/lib/cli/commands/checkout.rb +25 -0
- package/scripts/lib/cli/commands/continue.rb +66 -0
- package/scripts/lib/cli/commands/doctor.rb +20 -0
- package/scripts/lib/cli/commands/feedback.rb +40 -0
- package/scripts/lib/cli/commands/help.rb +69 -0
- package/scripts/lib/cli/commands/hook.rb +32 -0
- package/scripts/lib/cli/commands/index.rb +23 -0
- package/scripts/lib/cli/commands/install.rb +21 -0
- package/scripts/lib/cli/commands/installer_verb.rb +37 -0
- package/scripts/lib/cli/commands/intent.rb +19 -0
- package/scripts/lib/cli/commands/intent_answer.rb +37 -0
- package/scripts/lib/cli/commands/intent_command.rb +53 -0
- package/scripts/lib/cli/commands/intent_end.rb +61 -0
- package/scripts/lib/cli/commands/intent_new.rb +62 -0
- package/scripts/lib/cli/commands/intent_note.rb +43 -0
- package/scripts/lib/cli/commands/intent_rule.rb +36 -0
- package/scripts/lib/cli/commands/intent_show.rb +25 -0
- package/scripts/lib/cli/commands/intent_spec.rb +44 -0
- package/scripts/lib/cli/commands/intent_step.rb +43 -0
- package/scripts/lib/cli/commands/intent_verify.rb +26 -0
- package/scripts/lib/cli/commands/migrate.rb +16 -0
- package/scripts/lib/cli/commands/migrate_stores.rb +31 -0
- package/scripts/lib/cli/commands/next.rb +49 -0
- package/scripts/lib/cli/commands/project.rb +19 -0
- package/scripts/lib/cli/commands/project_links.rb +42 -0
- package/scripts/lib/cli/commands/project_list.rb +20 -0
- package/scripts/lib/cli/commands/project_new.rb +72 -0
- package/scripts/lib/cli/commands/query.rb +31 -0
- package/scripts/lib/cli/commands/render.rb +25 -0
- package/scripts/lib/cli/commands/roadmap.rb +19 -0
- package/scripts/lib/cli/commands/roadmap_check.rb +44 -0
- package/scripts/lib/cli/commands/roadmap_log.rb +54 -0
- package/scripts/lib/cli/commands/roadmap_next.rb +34 -0
- package/scripts/lib/cli/commands/roadmap_show.rb +45 -0
- package/scripts/lib/cli/commands/rollback.rb +20 -0
- package/scripts/lib/cli/commands/search.rb +60 -0
- package/scripts/lib/cli/commands/session.rb +18 -0
- package/scripts/lib/cli/commands/session_commit.rb +42 -0
- package/scripts/lib/cli/commands/session_handoff.rb +34 -0
- package/scripts/lib/cli/commands/session_summary.rb +35 -0
- package/scripts/lib/cli/commands/status.rb +68 -0
- package/scripts/lib/cli/commands/subcommand_list.rb +36 -0
- package/scripts/lib/cli/commands/sync.rb +46 -0
- package/scripts/lib/cli/commands/uninstall.rb +20 -0
- package/scripts/lib/cli/commands/update.rb +20 -0
- package/scripts/lib/cli/commands/version.rb +53 -0
- package/scripts/lib/cli/frontier.rb +84 -0
- package/scripts/lib/cli/legacy.rb +50 -0
- package/scripts/lib/cli/output.rb +102 -0
- package/scripts/lib/cli/scope.rb +127 -0
- package/scripts/lib/cli/table.rb +64 -0
- package/scripts/lib/cli.rb +94 -0
- package/scripts/lib/compact_instructions.rb +8 -0
- package/scripts/lib/day_summary.rb +4 -3
- package/scripts/lib/doctor_core.rb +7 -32
- package/scripts/lib/doctor_session_ledger.rb +2 -1
- package/scripts/lib/feedback_report.rb +1 -1
- package/scripts/lib/graph_measure_models.rb +3 -1
- package/scripts/lib/index_entry.rb +9 -0
- package/scripts/lib/installer_core.rb +73 -19
- package/scripts/lib/intent_screen.rb +3 -3
- package/scripts/lib/lock.rb +2 -2
- package/scripts/lib/node_input.rb +3 -2
- package/scripts/lib/preflight.rb +2 -4
- package/scripts/lib/project_config.rb +2 -1
- package/scripts/lib/project_validator.rb +3 -2
- package/scripts/lib/qmd_sync.rb +8 -7
- package/scripts/lib/reference_archive.rb +45 -0
- package/scripts/lib/release_guard.rb +2 -0
- package/scripts/lib/report_screen.rb +4 -3
- package/scripts/lib/rlm/corpus.rb +13 -0
- package/scripts/lib/rlm/probe.rb +29 -0
- package/scripts/lib/rlm/query.rb +22 -0
- package/scripts/lib/roadmap_queue.rb +2 -2
- package/scripts/lib/roadmap_savepoint.rb +1 -1
- package/scripts/lib/runner_absorb.rb +3 -2
- package/scripts/lib/search_index.rb +55 -0
- package/scripts/lib/session_git.rb +4 -3
- package/scripts/lib/sqlite.rb +22 -0
- package/scripts/lib/store_discovery.rb +7 -6
- package/scripts/lib/store_layout.rb +54 -0
- package/scripts/lib/store_provisioning.rb +2 -1
- package/scripts/lib/store_sync.rb +85 -0
- package/scripts/lib/stores_move.rb +93 -0
- package/scripts/lib/verify_intent.rb +2 -7
- package/scripts/lib/version_number.rb +48 -0
- package/scripts/lib/work_graph.rb +59 -0
- package/scripts/lib/worktree.rb +3 -8
- package/scripts/lib/worktree_sweep.rb +3 -2
- package/scripts/link-suggest +2 -1
- package/scripts/migrate-to-global +1 -1
- package/scripts/new-intent +3 -12
- package/scripts/plastic-lock +3 -2
- package/scripts/promote-session-item +3 -2
- package/scripts/release-check +10 -5
- package/scripts/report-screen +1 -1
- package/scripts/session-commit +2 -1
- package/scripts/spawn-preamble +2 -2
- package/scripts/update.rb +25 -4
- package/scripts/write-handoff +2 -1
- package/templates/agents.md +6 -6
- package/templates/render.css +10 -0
- package/bin/plastic.js +0 -70
- package/skills/agent-advisor/SKILL.md +0 -84
- package/skills/auto/SKILL.md +0 -297
- package/skills/auto/evals/evals.json +0 -255
- package/skills/auto/references/end-tail.md +0 -64
- package/skills/conventions/SKILL.md +0 -29
- package/skills/dashboard/SKILL.md +0 -180
- package/skills/dashboard/evals/evals.json +0 -38
- package/skills/dashboard/references/classification.md +0 -22
- package/skills/dashboard/templates/dashboard-global.md +0 -20
- package/skills/dashboard/templates/dashboard-project.md +0 -19
- package/skills/direct/SKILL.md +0 -66
- package/skills/direct/references/request-signals.md +0 -59
- package/skills/doctor/SKILL.md +0 -305
- package/skills/doctor/report.md +0 -102
- package/skills/feedback/SKILL.md +0 -98
- package/skills/feedback/references/transport-and-privacy.md +0 -65
- package/skills/feedback/report.md +0 -36
- package/skills/install/SKILL.md +0 -215
- package/skills/intent-continuing/SKILL.md +0 -156
- package/skills/intent-continuing/references/board-fill.md +0 -52
- package/skills/intent-continuing/references/boarding-matrix.md +0 -35
- package/skills/intent-continuing/references/context-management.md +0 -28
- package/skills/intent-continuing/references/liveness-ranking.md +0 -57
- package/skills/intent-creating/SKILL.md +0 -89
- package/skills/intent-creating/evals/evals.json +0 -72
- package/skills/intent-creating/references/lifecycle.md +0 -81
- package/skills/intent-creating/references/wikilinks.md +0 -8
- package/skills/intent-ending/SKILL.md +0 -182
- package/skills/intent-ending/evals/evals.json +0 -74
- package/skills/intent-executing/SKILL.md +0 -87
- package/skills/intent-executing/evals/evals.json +0 -66
- package/skills/intent-executing/implementer-prompt.md +0 -47
- package/skills/intent-executing/spec-reviewer-prompt.md +0 -27
- package/skills/intent-speccing/SKILL.md +0 -136
- package/skills/intent-speccing/evals/evals.json +0 -126
- package/skills/intent-speccing/references/design-principles.md +0 -44
- package/skills/intent-speccing/references/per-section-fill-rules.md +0 -92
- package/skills/intent-speccing/references/self-verify-checklist.md +0 -37
- package/skills/project-creating/SKILL.md +0 -162
- package/skills/project-creating/references/hubs-projects.md +0 -55
- package/skills/project-creating/references/project-scaffolding.md +0 -97
- package/skills/releasing/SKILL.md +0 -376
- package/skills/releasing/references/deprecations.md +0 -60
- package/skills/releasing/references/promotion-and-tagging.md +0 -70
- package/skills/releasing/references/release-lines.md +0 -105
- package/skills/roadmap/SKILL.md +0 -90
- package/skills/roadmap/references/file-format.md +0 -134
- package/skills/roadmap/references/operations.md +0 -112
- package/skills/rollback/SKILL.md +0 -91
- package/skills/tutorial/SKILL.md +0 -66
- package/skills/tutorial/evals/evals.json +0 -186
- package/skills/uninstall/SKILL.md +0 -75
- package/skills/update/SKILL.md +0 -126
- /package/{skills/auto/references → docs/help}/agent-report-contract.md +0 -0
- /package/{skills/intent-executing → docs/help}/code-quality-reviewer-prompt.md +0 -0
- /package/{skills/conventions/references → docs/help}/knowledge-graph.md +0 -0
- /package/{skills/conventions/references → docs/help}/lifecycle-and-savepoints.md +0 -0
- /package/{skills/conventions/references → docs/help}/locks-and-worktrees.md +0 -0
- /package/{skills/conventions/references → docs/help}/maintenance-and-revisions.md +0 -0
- /package/{skills/intent-executing → docs/help}/plan-reviewer-prompt.md +0 -0
|
@@ -9,7 +9,7 @@ end to end: a piece of work moved through What, Why, How, and Exec, with a finis
|
|
|
9
9
|
|
|
10
10
|
## Before you start
|
|
11
11
|
|
|
12
|
-
Run
|
|
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 track always creates a global-store intent; the throwaway repo below
|
|
@@ -22,7 +22,7 @@ directory instead (see station 6). Either way, nothing in this track touches a r
|
|
|
22
22
|
|
|
23
23
|
### 1. Create the intent
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
Run `plastic intent new` and describe the work in plain words, for example "add a
|
|
26
26
|
short Usage section to this project's README."
|
|
27
27
|
|
|
28
28
|
Artifact: a new intent directory, `{id}--slug.md`, plus the sentinel placeholder lifecycle
|
|
@@ -35,7 +35,7 @@ tool, never written by hand.
|
|
|
35
35
|
|
|
36
36
|
### 2. Board the intent
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
Run `plastic continue` and name the intent.
|
|
39
39
|
|
|
40
40
|
Artifact: a delivery lock (a `delivery.lock` file in the intent directory) naming this
|
|
41
41
|
session as the one owner, and a line in `savepoint.md` recording the stage. The agent then
|
|
@@ -46,13 +46,13 @@ sessions from editing the same intent at the same time.
|
|
|
46
46
|
|
|
47
47
|
### 3. Why, rulings one at a time
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
Run `plastic intent spec` (say "grill me" for a harder, interview-style pass over
|
|
50
50
|
the same ground). It asks conversational prose questions, one at a
|
|
51
51
|
time, never a multiple-choice menu, and answers them one at a time in return.
|
|
52
52
|
|
|
53
53
|
Artifact: `## Context` and `### Decisions` in the intent file fill in as each answer lands, and
|
|
54
54
|
each ruling also lands as its own `## Insights` entry the moment it is made, never batched for
|
|
55
|
-
later. This station's product is the enriched Why; it hands off to
|
|
55
|
+
later. This station's product is the enriched Why; it hands off to `plastic intent spec`
|
|
56
56
|
next, it does not write `spec.md` itself.
|
|
57
57
|
|
|
58
58
|
Checkpoint: after two or three answers, look at the intent file. Every ruling given out loud
|
|
@@ -60,7 +60,7 @@ is already sitting in `### Decisions` and in `## Insights`, in writing.
|
|
|
60
60
|
|
|
61
61
|
### 4. How, write the graph
|
|
62
62
|
|
|
63
|
-
Ask the same conversation (
|
|
63
|
+
Ask the same conversation (`plastic intent spec`) to turn the rulings into the graph.
|
|
64
64
|
|
|
65
65
|
Artifact: `graph.md` (nodes, edges, dispatch policy) and one `nodes/N.md` file per node this
|
|
66
66
|
small delivery needs. A delivery this size is one node; many independent tasks instead get
|
|
@@ -70,7 +70,7 @@ Checkpoint: open `graph.md` and point at the one node this worked example needs.
|
|
|
70
70
|
|
|
71
71
|
### 5. Exec, drive the runner loop
|
|
72
72
|
|
|
73
|
-
|
|
73
|
+
Run `plastic intent step`.
|
|
74
74
|
|
|
75
75
|
Teach the loop: `ruby scripts/runner step <intent_dir>` computes which nodes are ready and
|
|
76
76
|
prints a spawn block to dispatch, `ruby scripts/runner status <intent_dir>` reads the
|
|
@@ -87,7 +87,7 @@ moving to station 6.
|
|
|
87
87
|
|
|
88
88
|
### 6. End
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
Run `plastic intent end`.
|
|
91
91
|
|
|
92
92
|
Artifact: a real `outcome.md` (Summary, Delivered, Verification, Follow-ups) generated by
|
|
93
93
|
`scripts/outcome-report` from `graph.md` and the ledger, the intent moved from `## Active`
|
|
@@ -9,7 +9,7 @@ agent end to end, and pausing and resuming that delivery will feel familiar.
|
|
|
9
9
|
|
|
10
10
|
## Before you start
|
|
11
11
|
|
|
12
|
-
Run
|
|
12
|
+
Run `plastic update` first, so the commands below match what is
|
|
13
13
|
actually installed.
|
|
14
14
|
|
|
15
15
|
Work in a sandbox: a throwaway git repository, or a global-store intent. Nothing in this
|
|
@@ -19,8 +19,8 @@ track touches a real project.
|
|
|
19
19
|
|
|
20
20
|
### 1. Board a small intent and choose auto
|
|
21
21
|
|
|
22
|
-
Start from an active intent (create one first with
|
|
23
|
-
exists, the same way as track 1 station 1).
|
|
22
|
+
Start from an active intent (create one first with `plastic intent new` if none
|
|
23
|
+
exists, the same way as track 1 station 1). Run `plastic auto take ID`.
|
|
24
24
|
|
|
25
25
|
Artifact: the delivery lock arms, and the agent announces it is taking over the intent for
|
|
26
26
|
autonomous delivery.
|
|
@@ -45,7 +45,7 @@ can review how it checked, not just what it found.
|
|
|
45
45
|
The user keeps two things: the rulings made along the way, and the review points, moments
|
|
46
46
|
auto is built to pause for, such as confirming a project path or stopping before a
|
|
47
47
|
destructive action with no safe way back. When auto tells you to run a command yourself
|
|
48
|
-
("run
|
|
48
|
+
("run plastic intent spec"), that is an instruction for you to type; it is a different
|
|
49
49
|
thing from the prompts auto hands to its own dispatched subagents, and the two are never
|
|
50
50
|
mixed up in what it tells you.
|
|
51
51
|
|
|
@@ -74,7 +74,7 @@ line.
|
|
|
74
74
|
|
|
75
75
|
### 5. Continue and where-was-I after time away
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
Run `plastic continue`.
|
|
78
78
|
|
|
79
79
|
Artifact: the current state, presented and then the session stops. If a specific intent is
|
|
80
80
|
named, the agent reads its stage and savepoint and resumes exactly there, rather than
|
|
@@ -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
|
|
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:
|
|
24
|
-
then
|
|
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
|
|
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
|
-
|
|
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
|
|
39
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
60
|
-
|
|
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
|
-
|
|
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,
|
|
118
|
+
walkthrough covers, [`docs/help/roadmaps.md`](roadmaps.md) is the reference.
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zalom/plastic",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.28",
|
|
4
4
|
"description": "Intent-driven idea development system for AI coding agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"plastic": "bin/plastic
|
|
7
|
+
"plastic": "bin/plastic"
|
|
8
8
|
},
|
|
9
9
|
"engines": {
|
|
10
10
|
"node": ">=18.0.0"
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
"bin/",
|
|
35
35
|
"scripts/",
|
|
36
36
|
"skills/",
|
|
37
|
+
"docs/help/",
|
|
37
38
|
"hooks/",
|
|
38
39
|
"agents/",
|
|
39
40
|
"templates/",
|
package/scripts/append-ledger
CHANGED
|
@@ -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]) :
|
|
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
|
package/scripts/dashboard.rb
CHANGED
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
#
|
|
22
22
|
# Read-only. Never modifies files.
|
|
23
23
|
|
|
24
|
+
require_relative "lib/store_layout"
|
|
24
25
|
require "json"
|
|
25
26
|
require "yaml"
|
|
26
27
|
require "date"
|
|
@@ -143,13 +144,13 @@ def completion_dates(index_path)
|
|
|
143
144
|
end
|
|
144
145
|
|
|
145
146
|
# All stores: global + every registered project. -> [{scope, store, index}]
|
|
146
|
-
def stores
|
|
147
|
+
def stores(home = PLASTIC_HOME)
|
|
147
148
|
list = []
|
|
148
|
-
global =
|
|
149
|
-
list << { scope: "global", store: global, index: File.join(
|
|
150
|
-
projects_root =
|
|
149
|
+
global = Plastic::StoreLayout.global_store(home)
|
|
150
|
+
list << { scope: "global", store: global, index: File.join(Plastic::StoreLayout.global_root(home), "INDEX.md") } if File.directory?(global)
|
|
151
|
+
projects_root = Plastic::StoreLayout.projects_root(home)
|
|
151
152
|
if File.directory?(projects_root)
|
|
152
|
-
|
|
153
|
+
Plastic::StoreLayout.project_slugs(home).each do |proj|
|
|
153
154
|
store = File.join(projects_root, proj, "store")
|
|
154
155
|
next unless File.directory?(store)
|
|
155
156
|
list << { scope: "project:#{proj}", store: store, index: File.join(projects_root, proj, "INDEX.md") }
|
|
@@ -592,7 +593,7 @@ def render_continue(records)
|
|
|
592
593
|
out.concat(matrix(open, scope_tag: true))
|
|
593
594
|
out << ""
|
|
594
595
|
out << LEGEND
|
|
595
|
-
out << "ask for the <slug> project board · plastic
|
|
596
|
+
out << "ask for the <slug> project board · plastic auto take ID (works the dispatchable queue)"
|
|
596
597
|
out.join("\n") + "\n"
|
|
597
598
|
end
|
|
598
599
|
|
|
@@ -855,7 +856,7 @@ end
|
|
|
855
856
|
def short_description(scope)
|
|
856
857
|
return "" unless scope.start_with?("project:")
|
|
857
858
|
slug = scope.sub("project:", "")
|
|
858
|
-
agents = File.join(PLASTIC_HOME,
|
|
859
|
+
agents = File.join(Plastic::StoreLayout.project_root(PLASTIC_HOME, slug), "AGENTS.md")
|
|
859
860
|
if File.exist?(agents)
|
|
860
861
|
File.readlines(agents).each do |l|
|
|
861
862
|
t = l.strip
|
|
@@ -1022,7 +1023,7 @@ end
|
|
|
1022
1023
|
# directly under PLASTIC_HOME, with no intervening "store" segment.
|
|
1023
1024
|
def screen_tier_root(plastic_home, scope)
|
|
1024
1025
|
return plastic_home if scope == "global"
|
|
1025
|
-
|
|
1026
|
+
Plastic::StoreLayout.project_root(plastic_home, screen_scope_slug(scope))
|
|
1026
1027
|
end
|
|
1027
1028
|
|
|
1028
1029
|
# "global" spans every store (the same aggregate render_continue and --json's
|
|
@@ -1085,7 +1086,7 @@ end
|
|
|
1085
1086
|
# PLASTIC_HOME/store tmp root, and `session: nil` (A6) so the calling
|
|
1086
1087
|
# session's own live heartbeat counts rather than being excluded as "self".
|
|
1087
1088
|
def screen_sessions_count(plastic_home, now:)
|
|
1088
|
-
store =
|
|
1089
|
+
store = Plastic::StoreLayout.global_store(plastic_home)
|
|
1089
1090
|
DaySummary.active_sessions(store, nil, now: now, ttl: DaySummary::HEARTBEAT_TTL).size
|
|
1090
1091
|
end
|
|
1091
1092
|
|
package/scripts/day-summary
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
#
|
|
15
15
|
# Exit codes: 0 done; 2 usage error.
|
|
16
16
|
|
|
17
|
+
require_relative "lib/store_layout"
|
|
17
18
|
require_relative "lib/session_ledger"
|
|
18
19
|
require_relative "lib/day_summary"
|
|
19
20
|
|
|
@@ -43,7 +44,7 @@ end
|
|
|
43
44
|
|
|
44
45
|
opts = parse_args(ARGV)
|
|
45
46
|
home = opts[:home] ? expand(opts[:home]) : expand(ENV.fetch("PLASTIC_HOME", "~/.plastic"))
|
|
46
|
-
store = opts[:store] ? expand(opts[:store]) :
|
|
47
|
+
store = opts[:store] ? expand(opts[:store]) : Plastic::StoreLayout.global_store(home)
|
|
47
48
|
day = opts[:day] || SessionLedger.day_id
|
|
48
49
|
usage_abort("--day must be eight digits parsing as a real date, got #{day.inspect}") unless SessionLedger.valid_day_id?(day)
|
|
49
50
|
session = SessionLedger.short_session_id(opts[:session], ENV["CLAUDE_CODE_SESSION_ID"])
|
package/scripts/doctor.rb
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
# Exit codes: 0 (all pass), 1 (warnings only), 2 (failures present)
|
|
10
10
|
# Read-only — never modifies files.
|
|
11
11
|
|
|
12
|
+
require_relative "lib/store_layout"
|
|
12
13
|
require "date"
|
|
13
14
|
require "open3"
|
|
14
15
|
require "timeout"
|
|
@@ -40,6 +41,7 @@ require_relative "lib/preflight"
|
|
|
40
41
|
require_relative "lib/ruby_probe"
|
|
41
42
|
require_relative "lib/doctor_session_ledger"
|
|
42
43
|
require_relative "lib/intent_screen"
|
|
44
|
+
require_relative "lib/store_sync"
|
|
43
45
|
|
|
44
46
|
# Diagnostic engine, instantiable with an injected store/agent map so tests can
|
|
45
47
|
# run it hermetically (no eval, no global-constant rewriting).
|
|
@@ -216,7 +218,7 @@ class Doctor
|
|
|
216
218
|
def check_global_store
|
|
217
219
|
checks = []
|
|
218
220
|
|
|
219
|
-
index_path = File.join(plastic_home, "INDEX.md")
|
|
221
|
+
index_path = File.join(Plastic::StoreLayout.global_root(plastic_home), "INDEX.md")
|
|
220
222
|
|
|
221
223
|
# index_exists
|
|
222
224
|
if File.exist?(index_path)
|
|
@@ -252,7 +254,7 @@ class Doctor
|
|
|
252
254
|
end
|
|
253
255
|
|
|
254
256
|
# orphaned_intents — directories in store/ not referenced in INDEX.md
|
|
255
|
-
store_dir =
|
|
257
|
+
store_dir = Plastic::StoreLayout.global_store(plastic_home)
|
|
256
258
|
if File.directory?(store_dir)
|
|
257
259
|
intent_dirs = store_intent_dirs(store_dir)
|
|
258
260
|
orphans = intent_dirs.reject { |d| content.include?("store/#{d}") }
|
|
@@ -278,7 +280,7 @@ class Doctor
|
|
|
278
280
|
store_paths = content.scan(%r{store/\S+}).map { |ref| ref.gsub(/[)\]>].*/, "").chomp("/") }.uniq
|
|
279
281
|
|
|
280
282
|
ghosts = store_paths.select do |ref|
|
|
281
|
-
full_path = File.join(plastic_home, ref)
|
|
283
|
+
full_path = File.join(Plastic::StoreLayout.global_root(plastic_home), ref)
|
|
282
284
|
!File.exist?(full_path) && !File.directory?(full_path)
|
|
283
285
|
end
|
|
284
286
|
|
|
@@ -330,7 +332,7 @@ class Doctor
|
|
|
330
332
|
category: "core_files", name: name, status: "warn",
|
|
331
333
|
message: "#{config[:name]}'s agent-side VERSION file not found at #{tilde(agent_version_path)}",
|
|
332
334
|
fixable: true,
|
|
333
|
-
fix_hint: "Re-sync the stale harness: npx @zalom/plastic@latest install --reinstall <flag>, or plastic
|
|
335
|
+
fix_hint: "Re-sync the stale harness: npx @zalom/plastic@latest install --reinstall <flag>, or `plastic rollback` to a prior version"
|
|
334
336
|
)
|
|
335
337
|
else
|
|
336
338
|
agent_version = File.read(agent_version_path).strip
|
|
@@ -348,7 +350,7 @@ class Doctor
|
|
|
348
350
|
"#{tilde(agent_version_path)}: #{agent_version}",
|
|
349
351
|
],
|
|
350
352
|
fixable: true,
|
|
351
|
-
fix_hint: "Re-sync the stale harness: npx @zalom/plastic@latest install --reinstall <flag>, or plastic
|
|
353
|
+
fix_hint: "Re-sync the stale harness: npx @zalom/plastic@latest install --reinstall <flag>, or `plastic rollback` to a prior version"
|
|
352
354
|
)
|
|
353
355
|
end
|
|
354
356
|
end
|
|
@@ -613,7 +615,7 @@ class Doctor
|
|
|
613
615
|
fixable: true,
|
|
614
616
|
fix_hint: "Relocate each unsanctioned section into the " \
|
|
615
617
|
"intent's revisions.md via move-and-record (a missing required section is restored " \
|
|
616
|
-
"or reprojected instead); see plastic
|
|
618
|
+
"or reprojected instead); see `plastic help maintenance-and-revisions`"
|
|
617
619
|
)
|
|
618
620
|
end
|
|
619
621
|
|
|
@@ -644,7 +646,7 @@ class Doctor
|
|
|
644
646
|
# unpromoted_rules (intent 341, G8, C37): an Insights entry tagged
|
|
645
647
|
# `rule:` (via `insight-append --rule`) is a promise the rule will make
|
|
646
648
|
# it into project doctrine. Advisory only.
|
|
647
|
-
checks.concat(unpromoted_rules_checks(intent_dirs
|
|
649
|
+
checks.concat(unpromoted_rules_checks(intent_dirs))
|
|
648
650
|
|
|
649
651
|
# cross_store_resolution — RESOLVES (not just shape-checks) every cross-store
|
|
650
652
|
# `store:id` ref against the FULL store family via the relocation map
|
|
@@ -705,14 +707,14 @@ class Doctor
|
|
|
705
707
|
if scopes.nil? || scopes.include?("global")
|
|
706
708
|
stores << {
|
|
707
709
|
scope: "global",
|
|
708
|
-
index: File.join(plastic_home, "INDEX.md"),
|
|
709
|
-
store_dir:
|
|
710
|
+
index: File.join(Plastic::StoreLayout.global_root(plastic_home), "INDEX.md"),
|
|
711
|
+
store_dir: Plastic::StoreLayout.global_store(plastic_home),
|
|
710
712
|
}
|
|
711
713
|
end
|
|
712
714
|
|
|
713
|
-
projects_root =
|
|
715
|
+
projects_root = Plastic::StoreLayout.projects_root(plastic_home)
|
|
714
716
|
if File.directory?(projects_root)
|
|
715
|
-
|
|
717
|
+
Plastic::StoreLayout.project_slugs(plastic_home).each do |project|
|
|
716
718
|
scope = "project:#{project}"
|
|
717
719
|
next unless scopes.nil? || scopes.include?(scope)
|
|
718
720
|
|
|
@@ -1228,7 +1230,7 @@ end
|
|
|
1228
1230
|
"project-links --intent <id> --apply` over running project-links directly: it detects " \
|
|
1229
1231
|
"(never acquires) the target's delivery lock, requires a clean store working tree, and " \
|
|
1230
1232
|
"commits the scoped change plus its revisions.md receipt as one merged operation " \
|
|
1231
|
-
"(plastic
|
|
1233
|
+
"(`plastic help maintenance-and-revisions`)."
|
|
1232
1234
|
)
|
|
1233
1235
|
end
|
|
1234
1236
|
|
|
@@ -1692,7 +1694,7 @@ end
|
|
|
1692
1694
|
"Every sources/chain id resolves to a real intent (I4)",
|
|
1693
1695
|
"Record the dangling sources/chain edge as a " \
|
|
1694
1696
|
"broken-source/broken-chain move-and-record entry in the intent's revisions.md (see " \
|
|
1695
|
-
"plastic
|
|
1697
|
+
"`plastic help maintenance-and-revisions`), or restore the missing intent"
|
|
1696
1698
|
)
|
|
1697
1699
|
checks
|
|
1698
1700
|
end
|
|
@@ -1865,31 +1867,25 @@ end
|
|
|
1865
1867
|
#
|
|
1866
1868
|
# `insight-append --rule` tags an entry "... - rule: <text>". A tag is a
|
|
1867
1869
|
# promise the rule will make it into project doctrine; until the exact
|
|
1868
|
-
# rule text shows up in some
|
|
1869
|
-
#
|
|
1870
|
-
#
|
|
1871
|
-
#
|
|
1872
|
-
#
|
|
1873
|
-
#
|
|
1870
|
+
# rule text shows up in some docs/help/*.md chapter, it is only visible to
|
|
1871
|
+
# a session that happens to read this one intent file, and the next
|
|
1872
|
+
# session repeats the mistake the rule names. Advisory only (warn, never
|
|
1873
|
+
# fail): a freshly tagged rule is not yet promoted by design, and nothing
|
|
1874
|
+
# here can auto-promote it (that is an editorial call, not a mechanical
|
|
1875
|
+
# one).
|
|
1874
1876
|
RULE_ENTRY_RE = /—\s*rule:\s*(.+?)\s*\z/.freeze
|
|
1875
1877
|
|
|
1876
|
-
def unpromoted_rules_checks(intent_dirs, package_root: PACKAGE_ROOT
|
|
1877
|
-
#
|
|
1878
|
-
# (~/.plastic
|
|
1879
|
-
#
|
|
1880
|
-
#
|
|
1881
|
-
#
|
|
1882
|
-
|
|
1883
|
-
if home
|
|
1884
|
-
chapter_dirs << File.join(home, ".claude", "skills", "plastic-conventions", "references")
|
|
1885
|
-
chapter_dirs << File.join(home, ".agents", "skills", "plastic-conventions", "references")
|
|
1886
|
-
end
|
|
1887
|
-
chapter_dirs << File.join(package_root, "skills", "conventions", "references")
|
|
1878
|
+
def unpromoted_rules_checks(intent_dirs, package_root: PACKAGE_ROOT)
|
|
1879
|
+
# docs/help installs straight under PACKAGE_ROOT for every harness alike
|
|
1880
|
+
# (~/.plastic/docs/help once installed, repo docs/help in a checkout), so
|
|
1881
|
+
# a single path covers both the repo and the installed layout; unlike
|
|
1882
|
+
# the old skills-based chapters, help topics are no longer agent-home
|
|
1883
|
+
# specific, so this needs no `home:` split.
|
|
1884
|
+
chapter_dir = File.join(package_root, "docs", "help")
|
|
1888
1885
|
|
|
1889
|
-
chapters_text =
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
.join("\n\n")
|
|
1886
|
+
chapters_text = Dir.glob(File.join(chapter_dir, "*.md"))
|
|
1887
|
+
.map { |f| File.read(f) }
|
|
1888
|
+
.join("\n\n")
|
|
1893
1889
|
|
|
1894
1890
|
unpromoted = []
|
|
1895
1891
|
intent_dirs.each do |d|
|
|
@@ -1917,7 +1913,7 @@ end
|
|
|
1917
1913
|
category: "conventions", name: "unpromoted_rules", status: "warn",
|
|
1918
1914
|
message: "#{unpromoted.size} tagged rule(s) not yet carried by any conventions chapter",
|
|
1919
1915
|
details: unpromoted, fixable: false,
|
|
1920
|
-
fix_hint: "Promote the rule into the right
|
|
1916
|
+
fix_hint: "Promote the rule into the right docs/help/*.md chapter, " \
|
|
1921
1917
|
"or drop the tag if the finding does not belong in doctrine"
|
|
1922
1918
|
)]
|
|
1923
1919
|
end
|
|
@@ -1934,8 +1930,7 @@ end
|
|
|
1934
1930
|
# skill directory under agent_dir/skills that has NO corresponding entry in the
|
|
1935
1931
|
# current install manifest is a stray (e.g. a leftover old-name copy the
|
|
1936
1932
|
# install/update prune should have removed, or one it never saw because the
|
|
1937
|
-
# manifest predates it).
|
|
1938
|
-
# least one skill exists). Defers to the manifest check when the manifest itself
|
|
1933
|
+
# manifest predates it). Defers to the manifest check when the manifest itself
|
|
1939
1934
|
# is missing or malformed, so the two checks never double-report the same gap.
|
|
1940
1935
|
|
|
1941
1936
|
# Auto-mode role agents install as <dir>/agents/plastic-*.md. Pass if at least
|
|
@@ -2301,7 +2296,7 @@ end
|
|
|
2301
2296
|
# project can be checked in isolation (used by `--store <slug>`).
|
|
2302
2297
|
def check_project_store(slug, project_info)
|
|
2303
2298
|
checks = []
|
|
2304
|
-
project_dir =
|
|
2299
|
+
project_dir = Plastic::StoreLayout.project_root(plastic_home, slug)
|
|
2305
2300
|
|
|
2306
2301
|
# project_dir_exists
|
|
2307
2302
|
if File.directory?(project_dir)
|
|
@@ -2351,7 +2346,7 @@ end
|
|
|
2351
2346
|
end
|
|
2352
2347
|
|
|
2353
2348
|
# project_yml_exists
|
|
2354
|
-
project_yml_path = File.join(plastic_home,
|
|
2349
|
+
project_yml_path = File.join(Plastic::StoreLayout.project_root(plastic_home, slug), "project.yml")
|
|
2355
2350
|
project_yml_data = nil
|
|
2356
2351
|
|
|
2357
2352
|
if File.exist?(project_yml_path)
|
|
@@ -2398,7 +2393,7 @@ end
|
|
|
2398
2393
|
return checks unless parent_id
|
|
2399
2394
|
|
|
2400
2395
|
# Find the intent directory for the parent ID
|
|
2401
|
-
store_dir =
|
|
2396
|
+
store_dir = Plastic::StoreLayout.global_store(plastic_home)
|
|
2402
2397
|
parent_dir = nil
|
|
2403
2398
|
if File.directory?(store_dir)
|
|
2404
2399
|
parent_dir = Dir.children(store_dir).find { |d| d.start_with?("#{parent_id}--") }
|
|
@@ -2555,7 +2550,7 @@ end
|
|
|
2555
2550
|
# A config-asks warn in that tier would flip every post-update doctor to
|
|
2556
2551
|
# "fail" on an otherwise healthy install until the question is answered,
|
|
2557
2552
|
# re-noising the post-update surface intent 126 deliberately quieted. The
|
|
2558
|
-
# recoverable-later path for a pending question is a full
|
|
2553
|
+
# recoverable-later path for a pending question is a full `plastic doctor`
|
|
2559
2554
|
# run, the declared maintenance front door; the moment-it-happens path is
|
|
2560
2555
|
# update.rb#announce_pending_config_asks, which already runs on every hop.
|
|
2561
2556
|
#
|
|
@@ -3019,6 +3014,16 @@ end
|
|
|
3019
3014
|
end
|
|
3020
3015
|
end
|
|
3021
3016
|
|
|
3017
|
+
def check_graph_links
|
|
3018
|
+
return [] unless File.exist?(Plastic::WorkGraph.path(plastic_home))
|
|
3019
|
+
|
|
3020
|
+
orphans = Plastic::StoreSync.orphans(plastic_home)
|
|
3021
|
+
return [check(category: "graph_links", name: "graph_links", status: "pass", message: "every stored file belongs to an intent in work_graph.db")] if orphans.empty?
|
|
3022
|
+
|
|
3023
|
+
[check(category: "graph_links", name: "graph_links", status: "warn", details: orphans, fixable: false,
|
|
3024
|
+
message: "#{orphans.size} intent id(s) hold files and have no row in work_graph.db")]
|
|
3025
|
+
end
|
|
3026
|
+
|
|
3022
3027
|
# --- Run all checks ---
|
|
3023
3028
|
|
|
3024
3029
|
def run_checks(agent_key)
|
|
@@ -3037,6 +3042,7 @@ end
|
|
|
3037
3042
|
all_checks += check_session_ledger(scopes: ["global"])
|
|
3038
3043
|
all_checks += check_skill_lint
|
|
3039
3044
|
all_checks += check_install_integrity
|
|
3045
|
+
all_checks += check_graph_links
|
|
3040
3046
|
all_checks += check_display_registration(agent_key)
|
|
3041
3047
|
all_checks += check_display_paints(agent_key)
|
|
3042
3048
|
all_checks += check_display_not_defeated(agent_key)
|
package/scripts/end-intent
CHANGED
|
@@ -68,6 +68,7 @@
|
|
|
68
68
|
# 7 hollow delivered report refused (317a D7) - intent 308's one deliberate
|
|
69
69
|
# exception to report-and-proceed; --allow-hollow-report overrides.
|
|
70
70
|
|
|
71
|
+
require_relative "lib/store_layout"
|
|
71
72
|
require "fileutils"
|
|
72
73
|
require "date"
|
|
73
74
|
require "open3"
|
|
@@ -170,14 +171,7 @@ end
|
|
|
170
171
|
# "projects" (the StoreDiscovery convention, scripts/lib/store_discovery.rb), never by
|
|
171
172
|
# hardcoding ".plastic" as a name.
|
|
172
173
|
def resolve_plastic_home_and_scope(store)
|
|
173
|
-
|
|
174
|
-
grandparent = File.dirname(parent)
|
|
175
|
-
if File.basename(grandparent) == "projects"
|
|
176
|
-
slug = File.basename(parent)
|
|
177
|
-
[File.dirname(grandparent), "project:#{slug}"]
|
|
178
|
-
else
|
|
179
|
-
[parent, "global"]
|
|
180
|
-
end
|
|
174
|
+
Plastic::StoreLayout.home_and_scope(store)
|
|
181
175
|
end
|
|
182
176
|
|
|
183
177
|
# --- outcome generation, before the backfill (intent 339, G6, spec D10) -----
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
# and on any filing error (reported on stderr; the next boot tries again), 2 on
|
|
15
15
|
# a usage error.
|
|
16
16
|
|
|
17
|
+
require_relative "lib/store_layout"
|
|
17
18
|
require_relative "lib/session_ledger"
|
|
18
19
|
require_relative "lib/session_backfill"
|
|
19
20
|
|
|
@@ -48,7 +49,7 @@ if opts[:carry_to] && !SessionLedger.valid_day_id?(opts[:carry_to])
|
|
|
48
49
|
usage_abort("--carry-to must be a real calendar date, YYYYMMDD")
|
|
49
50
|
end
|
|
50
51
|
|
|
51
|
-
store = opts[:store] ||
|
|
52
|
+
store = opts[:store] || Plastic::StoreLayout.global_store(File.expand_path(ENV.fetch("PLASTIC_HOME", "~/.plastic")))
|
|
52
53
|
templates = opts[:templates] || File.expand_path("../templates", __dir__)
|
|
53
54
|
|
|
54
55
|
begin
|
package/scripts/hook-capture
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
# runs in its own rescue and the hook always exits 0 (spec D2). Intent 345
|
|
10
10
|
# (D7, 323) removed the per-prompt Future-intent hint step entirely.
|
|
11
11
|
|
|
12
|
+
require_relative "lib/store_layout"
|
|
12
13
|
require "json"
|
|
13
14
|
require "open3"
|
|
14
15
|
require "time"
|
|
@@ -38,7 +39,7 @@ cwd = payload["cwd"].to_s
|
|
|
38
39
|
cwd = Dir.pwd if cwd.empty?
|
|
39
40
|
|
|
40
41
|
plastic_home = File.expand_path(ENV["PLASTIC_HOME"] || "~/.plastic")
|
|
41
|
-
store =
|
|
42
|
+
store = Plastic::StoreLayout.global_store(plastic_home)
|
|
42
43
|
templates = File.expand_path("../templates", __dir__)
|
|
43
44
|
sid = SessionLedger.short_session_id(nil, session_id)
|
|
44
45
|
today = SessionLedger.day_id
|
|
@@ -108,7 +109,7 @@ begin
|
|
|
108
109
|
cockpit, _err, status = Open3.capture3({ "RUBYOPT" => nil }, "ruby", dashboard, "continue")
|
|
109
110
|
if status.success? && !cockpit.strip.empty?
|
|
110
111
|
context_parts << (cockpit.rstrip +
|
|
111
|
-
"\n\
|
|
112
|
+
"\n\nRun `plastic continue` to resume: " \
|
|
112
113
|
"if active intents exist, read their state and resume; otherwise surface the " \
|
|
113
114
|
"most-valuable next work and any stale or triage intents from the board above.")
|
|
114
115
|
|
|
@@ -135,7 +136,7 @@ begin
|
|
|
135
136
|
auto_triggers = ["take it from here", "deliver this", "/plastic-auto", "auto mode"].freeze
|
|
136
137
|
triggered = auto_triggers.any? { |p| message_lower.include?(p) } || message_lower.match?(/\bauto\b/)
|
|
137
138
|
if triggered
|
|
138
|
-
context_parts << "Auto-mode request detected.
|
|
139
|
+
context_parts << "Auto-mode request detected. Run `plastic auto take ID` to deliver the " \
|
|
139
140
|
"active intent autonomously - it takes the intent under a lock and a worktree " \
|
|
140
141
|
"and points this session at it."
|
|
141
142
|
end
|
package/scripts/hook-close
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
#
|
|
9
9
|
# Usage: hook-close <plastic_home> (stdin: the hook JSON)
|
|
10
10
|
|
|
11
|
+
require_relative "lib/store_layout"
|
|
11
12
|
require "json"
|
|
12
13
|
require_relative "lib/session_ledger"
|
|
13
14
|
require_relative "lib/session_close"
|
|
@@ -23,7 +24,7 @@ payload =
|
|
|
23
24
|
{}
|
|
24
25
|
end
|
|
25
26
|
|
|
26
|
-
store =
|
|
27
|
+
store = Plastic::StoreLayout.global_store(File.expand_path(plastic_home))
|
|
27
28
|
filer = File.expand_path("file-session-intent", __dir__)
|
|
28
29
|
templates = File.expand_path("../templates", __dir__)
|
|
29
30
|
begin
|