@zalom/plastic 2.0.0-alpha.2 → 2.0.0-alpha.20
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/agents/plastic-enforcer.md +3 -1
- package/agents/plastic-executor.md +9 -3
- package/hooks/hooks.json +12 -0
- package/hooks/message-display +134 -0
- package/hooks/statusline +4 -27
- package/package.json +2 -2
- package/scripts/agent-report +8 -2
- package/scripts/dashboard.rb +297 -18
- package/scripts/doctor.rb +652 -5
- package/scripts/end-intent +219 -0
- package/scripts/hook-capture +25 -113
- package/scripts/hook-message-display +81 -0
- package/scripts/hook-record +12 -4
- package/scripts/hook-session-start +23 -1
- package/scripts/index-projection +74 -0
- package/scripts/intent-screen +77 -0
- package/scripts/lib/action_graph_shim.rb +277 -0
- package/scripts/lib/arm.rb +26 -1
- package/scripts/lib/atomic_write.rb +31 -0
- package/scripts/lib/core_integrity.rb +71 -0
- package/scripts/lib/dashboard_screen.rb +40 -0
- package/scripts/lib/day_summary.rb +7 -2
- package/scripts/lib/doctor_core.rb +101 -5
- package/scripts/lib/doctor_session_ledger.rb +52 -0
- package/scripts/lib/graph_edges.rb +121 -0
- package/scripts/lib/graph_file.rb +246 -0
- package/scripts/lib/graph_tree.rb +98 -0
- package/scripts/lib/guarded_append.rb +155 -0
- package/scripts/lib/hook_registry.rb +14 -0
- package/scripts/lib/hook_replay.rb +211 -0
- package/scripts/lib/index_projection.rb +201 -0
- package/scripts/lib/installer_core.rb +131 -4
- package/scripts/lib/intent_screen.rb +309 -0
- package/scripts/lib/intent_screen_ansi.rb +262 -0
- package/scripts/lib/message_display.rb +586 -0
- package/scripts/lib/node_file.rb +214 -0
- package/scripts/lib/node_ids.rb +99 -0
- package/scripts/lib/node_ledger.rb +377 -0
- package/scripts/lib/node_packet.rb +886 -0
- package/scripts/lib/node_return.rb +199 -0
- package/scripts/lib/node_worktree.rb +337 -0
- package/scripts/lib/outcome_report.rb +440 -0
- package/scripts/lib/packet_wrapper.rb +132 -0
- package/scripts/lib/ready_set.rb +462 -0
- package/scripts/lib/release_guard.rb +16 -0
- package/scripts/lib/report_screen.rb +1967 -0
- package/scripts/lib/roadmap_graph.rb +210 -0
- package/scripts/lib/roadmap_migration.rb +95 -0
- package/scripts/lib/roadmap_queue.rb +155 -5
- package/scripts/lib/roadmap_render.rb +150 -0
- package/scripts/lib/roadmap_savepoint.rb +62 -12
- package/scripts/lib/runner_absorb.rb +620 -0
- package/scripts/lib/runner_answer.rb +206 -0
- package/scripts/lib/runner_core.rb +194 -0
- package/scripts/lib/runner_dispatch.rb +482 -0
- package/scripts/lib/runner_policy.rb +142 -0
- package/scripts/lib/runner_proposals.rb +254 -0
- package/scripts/lib/runner_rewind.rb +201 -0
- package/scripts/lib/runner_sweep.rb +231 -0
- package/scripts/lib/savepoint.rb +149 -12
- package/scripts/lib/screen_paint.rb +555 -0
- package/scripts/lib/screens/dashboard.rb +20 -0
- package/scripts/lib/screens/plan.rb +18 -0
- package/scripts/lib/screens/roadmap.rb +15 -0
- package/scripts/lib/session_git.rb +49 -18
- package/scripts/lib/session_ledger.rb +128 -0
- package/scripts/lib/verify_intent.rb +33 -0
- package/scripts/lib/work_graph_validator.rb +201 -0
- package/scripts/node-packet +92 -0
- package/scripts/node-transition +291 -0
- package/scripts/outcome-report +74 -0
- package/scripts/plastic-lock +8 -1
- package/scripts/ready-set +126 -0
- package/scripts/release-check +118 -0
- package/scripts/report-screen +281 -0
- package/scripts/roadmap-graph +119 -0
- package/scripts/roadmap-savepoint +7 -0
- package/scripts/runner +392 -0
- package/scripts/savepoint-note +69 -0
- package/scripts/spawn-preamble +9 -2
- package/scripts/validate-work-graph +39 -0
- package/scripts/verify-intent +2 -1
- package/skills/auto/SKILL.md +24 -17
- package/skills/auto/references/human-report-contract.md +136 -54
- package/skills/conventions/references/locks-and-worktrees.md +12 -0
- package/skills/dashboard/SKILL.md +13 -2
- package/skills/dashboard/templates/dashboard-global.md +1 -1
- package/skills/dashboard/templates/dashboard-project.md +2 -2
- package/skills/doctor/SKILL.md +10 -4
- package/skills/intent-continuing/SKILL.md +51 -41
- package/skills/intent-continuing/references/board-fill.md +9 -0
- package/skills/intent-continuing/references/boarding-matrix.md +6 -5
- package/skills/intent-continuing/references/context-management.md +1 -1
- package/skills/intent-ending/SKILL.md +36 -16
- package/skills/intent-executing/SKILL.md +17 -5
- package/skills/intent-executing/implementer-prompt.md +6 -1
- package/skills/intent-speccing/SKILL.md +7 -4
- package/skills/releasing/SKILL.md +39 -0
- package/skills/releasing/references/promotion-and-tagging.md +10 -6
- package/skills/releasing/references/release-lines.md +1 -1
- package/skills/roadmap/SKILL.md +26 -0
- package/skills/roadmap/references/file-format.md +10 -0
- package/templates/dashboard-screen.md +22 -0
- package/templates/display-fixture.md +21 -0
- package/templates/graph.md +16 -0
- package/templates/intent-screen.md +17 -0
- package/templates/node-decision.md +11 -0
- package/templates/node-research.md +11 -0
- package/templates/node-verify.md +13 -0
- package/templates/node-work.md +22 -0
- package/templates/outcome.md +19 -1
- package/templates/report-plan.md +15 -0
- package/templates/report-roadmap-delivered.md +10 -0
- package/templates/report-roadmap-plan.md +9 -0
- package/templates/report-roadmap-state.md +9 -0
- package/templates/report-state.md +11 -0
- package/templates/roadmap.md +13 -0
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
require "time"
|
|
5
5
|
require "fileutils"
|
|
6
|
+
require_relative "guarded_append"
|
|
6
7
|
|
|
7
8
|
# RoadmapSavepoint - the roadmap's machine counterpart to its human `## Log` (intent 134).
|
|
8
9
|
#
|
|
@@ -66,6 +67,25 @@ module RoadmapSavepoint
|
|
|
66
67
|
File.read(ledger_path).each_line.filter_map { |line| parse_pair(line) }
|
|
67
68
|
end
|
|
68
69
|
|
|
70
|
+
# Public (intent 331c): a roadmap's own ledger, parsed into `[Time, event, detail]` triples in
|
|
71
|
+
# file order - so a screen reader never re-derives the "<iso> <event> <detail>" line shape.
|
|
72
|
+
# `roadmap_path` is the roadmap `.md` file, never the `.savepoint.md` sibling directly (mirrors
|
|
73
|
+
# `ledger_path_for`'s own convention). No paired ledger file -> `[]`, never an invented event.
|
|
74
|
+
def ledger_entries(roadmap_path)
|
|
75
|
+
ledger_path = ledger_path_for(roadmap_path)
|
|
76
|
+
return [] unless File.exist?(ledger_path)
|
|
77
|
+
|
|
78
|
+
File.readlines(ledger_path).filter_map do |line|
|
|
79
|
+
parts = line.strip.split(/\s{2,}/, 3)
|
|
80
|
+
next nil unless parts.length == 3
|
|
81
|
+
begin
|
|
82
|
+
[Time.iso8601(parts[0]), parts[1], parts[2]]
|
|
83
|
+
rescue ArgumentError
|
|
84
|
+
nil
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
69
89
|
def parse_pair(line)
|
|
70
90
|
parts = line.strip.split(/\s{2,}/)
|
|
71
91
|
parts.length >= 3 ? [parts[1], parts[2]] : nil
|
|
@@ -76,17 +96,37 @@ module RoadmapSavepoint
|
|
|
76
96
|
# recorded (no-op). Creates the paired ledger file (and its directory) lazily. Raises
|
|
77
97
|
# ArgumentError when `event` is outside the controlled vocabulary. Returns true when a line
|
|
78
98
|
# was written, false on a dedup no-op.
|
|
79
|
-
|
|
99
|
+
#
|
|
100
|
+
# Intent 335 (spec D14): the dedup check moves INSIDE one GuardedAppend hold, which makes
|
|
101
|
+
# "is this pair already recorded" and "append it" atomic against a second writer without
|
|
102
|
+
# changing what this method returns. `strict: false` keeps this ledger's existing
|
|
103
|
+
# flock-less-filesystem fallback exactly as it was before the guard existed (spec D12a): a
|
|
104
|
+
# single O_APPEND write still lands whole there, so this ledger never refuses on such a
|
|
105
|
+
# filesystem, unlike a strict transition append elsewhere in 335. `guard:` is the sole thing
|
|
106
|
+
# this module takes from 335 (spec D14: "RoadmapSavepoint takes GuardedAppend and nothing else");
|
|
107
|
+
# `flock:`/`sleeper:` pass straight through as GuardedAppend test seams, never read from an
|
|
108
|
+
# environment variable. The directory is created BEFORE the guard is called (spec D12b): the
|
|
109
|
+
# guard's own File.open would raise Errno::ENOENT on a missing parent, which must propagate as
|
|
110
|
+
# itself rather than be mistaken for lock contention.
|
|
111
|
+
def append(roadmap_path, event, detail, now: Time.now, guard: GuardedAppend, **guard_opts)
|
|
80
112
|
unless EVENTS.include?(event)
|
|
81
113
|
raise ArgumentError, "event must be one of #{EVENTS.join(', ')}, got #{event.inspect}"
|
|
82
114
|
end
|
|
83
115
|
|
|
84
116
|
ledger_path = ledger_path_for(roadmap_path)
|
|
85
|
-
return false if recorded_pairs(ledger_path).include?([event, detail])
|
|
86
|
-
|
|
87
117
|
FileUtils.mkdir_p(File.dirname(ledger_path))
|
|
88
|
-
|
|
89
|
-
|
|
118
|
+
|
|
119
|
+
pair = [event, detail]
|
|
120
|
+
written = false
|
|
121
|
+
guard.call(ledger_path, strict: false, **guard_opts) do |content|
|
|
122
|
+
if content.each_line.filter_map { |line| parse_pair(line) }.include?(pair)
|
|
123
|
+
nil
|
|
124
|
+
else
|
|
125
|
+
written = true
|
|
126
|
+
format_line(now, event, detail)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
written
|
|
90
130
|
end
|
|
91
131
|
|
|
92
132
|
def format_line(time, event, detail)
|
|
@@ -141,11 +181,13 @@ module RoadmapSavepoint
|
|
|
141
181
|
end
|
|
142
182
|
private_class_method :parse_log_time
|
|
143
183
|
|
|
184
|
+
# Public (intent 331c): the Log table on a roadmap's `delivered` screen classifies every
|
|
185
|
+
# `## Log` line through this same keyword vocabulary, so a screen reader never grows a second
|
|
186
|
+
# copy of KEYWORD_TABLE.
|
|
144
187
|
def classify_event(text)
|
|
145
188
|
hit = KEYWORD_TABLE.find { |regex, _event| text =~ regex }
|
|
146
189
|
hit && hit[1]
|
|
147
190
|
end
|
|
148
|
-
private_class_method :classify_event
|
|
149
191
|
|
|
150
192
|
WAVE_ENTRY = /\A-\s*\[([ xX])\]\s+(\S+)\s+.+—\s*(\S+)\s*\z/.freeze
|
|
151
193
|
|
|
@@ -217,13 +259,21 @@ module RoadmapSavepoint
|
|
|
217
259
|
# already calling `ledger_path_for`), so this is the smaller diff than a new shared module.
|
|
218
260
|
# Raises MissingGroupingHeading, naming the offending path, when neither heading is present.
|
|
219
261
|
def grouping_section_body(text, path: nil)
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
262
|
+
heading = grouping_heading(text)
|
|
263
|
+
unless heading
|
|
264
|
+
raise MissingGroupingHeading,
|
|
265
|
+
"#{path || '(unknown roadmap file)'}: found neither '## Batches' (canonical) nor " \
|
|
266
|
+
"'## Waves' (legacy) grouping heading"
|
|
223
267
|
end
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
268
|
+
text.match(/^##\s+#{Regexp.escape(heading)}\s*$(.*?)(?=^##\s|\z)/m)[1]
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
# Public (intent 331c): "Batches" or "Waves", whichever grouping heading `text` carries - the
|
|
272
|
+
# one owner of that label so a screen's own field row (and its entries table's column header)
|
|
273
|
+
# never hand-picks between them a second way. nil when neither heading is present (mirrors
|
|
274
|
+
# grouping_section_body's own detection, one call site cheaper than two).
|
|
275
|
+
def grouping_heading(text)
|
|
276
|
+
GROUPING_HEADINGS.find { |heading| text.match?(/^##\s+#{Regexp.escape(heading)}\s*$/) }
|
|
227
277
|
end
|
|
228
278
|
|
|
229
279
|
# Stable dedup on the `(event, detail)` pair, keeping the first occurrence in the given
|