@zalom/plastic 2.0.0-alpha.26 → 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 +12 -12
- package/agents/plastic-executor.md +2 -1
- package/agents/plastic-node-research.md +4 -2
- package/agents/plastic-node-verify.md +1 -0
- package/agents/plastic-node-work.md +1 -0
- package/agents/{plastic-advisor.md → plastic-primary-advisor.md} +6 -8
- package/agents/{plastic-faux-advisor.md → plastic-secondary-advisor.md} +9 -12
- 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/config_asks.yml +4 -4
- package/deprecations.yml +1 -1
- package/{skills/agent-advisor/references → docs/help}/advisor-protocol.md +19 -24
- 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 +57 -49
- 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 +7 -5
- package/scripts/lib/action_graph_shim.rb +3 -1
- package/scripts/lib/active_delivery.rb +1 -1
- package/scripts/lib/agent_models.rb +44 -26
- 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/codex_adapter.rb +5 -4
- 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 +4 -2
- package/scripts/lib/index_entry.rb +9 -0
- package/scripts/lib/installer_core.rb +175 -56
- package/scripts/lib/intent_screen.rb +3 -3
- package/scripts/lib/lock.rb +2 -2
- package/scripts/lib/node_file.rb +22 -2
- package/scripts/lib/node_input.rb +11 -6
- package/scripts/lib/node_return.rb +8 -3
- 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 +59 -2
- package/scripts/lib/runner_dispatch.rb +12 -8
- package/scripts/lib/runner_policy.rb +28 -10
- 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/node-run +2 -1
- package/scripts/plastic-lock +3 -2
- package/scripts/promote-session-item +3 -2
- package/scripts/read-config +44 -6
- 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/config.yml +13 -6
- package/templates/node-research.md +4 -2
- package/templates/render.css +10 -0
- package/bin/plastic.js +0 -70
- package/skills/agent-advisor/SKILL.md +0 -92
- 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 -217
- 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
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Plastic::CLI::TABLE (intent 363) - the whole command line in one frozen hash:
|
|
4
|
+
# a command name mapped to the file that holds it, the class inside
|
|
5
|
+
# Plastic::CLI::Commands, and the one line `plastic help` prints beside it.
|
|
6
|
+
#
|
|
7
|
+
# Adding a command is one row here plus one file. `plastic help` reads this
|
|
8
|
+
# hash and loads nothing, so listing the commands costs no command file.
|
|
9
|
+
# test/cli/table_test.rb walks every row, so a half-wired command cannot ship.
|
|
10
|
+
module Plastic
|
|
11
|
+
class CLI
|
|
12
|
+
TABLE = {
|
|
13
|
+
"auto brief" => ["commands/auto_brief", "AutoBrief", "Print an intent's spawn preamble, and the advisor shapes for --role advisor"],
|
|
14
|
+
"auto lock" => ["commands/auto_lock", "AutoLock", "Inspect, repair, or release an intent's delivery lock"],
|
|
15
|
+
"auto report" => ["commands/auto_report", "AutoReport", "Print an intent's completion report, then the review-by-risk rules"],
|
|
16
|
+
"auto take" => ["commands/auto_take", "AutoTake", "Arm an intent's delivery lock for this session"],
|
|
17
|
+
"auto" => ["commands/auto", "Auto", "List the auto subcommands"],
|
|
18
|
+
"backup" => ["commands/backup", "Backup", "Write one archive of the three databases and the config"],
|
|
19
|
+
"checkout" => ["commands/checkout", "Checkout", "Restore missing store files from the databases"],
|
|
20
|
+
"continue" => ["commands/continue", "Continue", "Show where one project stands and what runs next"],
|
|
21
|
+
"doctor" => ["commands/doctor", "Doctor", "Diagnose Plastic installation health"],
|
|
22
|
+
"feedback" => ["commands/feedback", "Feedback", "File a feedback report, body on standard input"],
|
|
23
|
+
"help" => ["commands/help", "Help", "List the commands and help topics, or show one usage"],
|
|
24
|
+
"hook" => ["commands/hook", "Hook", "Run one harness hook event through its launcher"],
|
|
25
|
+
"index" => ["commands/index", "Index", "Rebuild the search index from every markdown file in the stores"],
|
|
26
|
+
"install" => ["commands/install", "Install", "Install Plastic into this machine's agents"],
|
|
27
|
+
"intent" => ["commands/intent", "Intent", "List the intent subcommands"],
|
|
28
|
+
"intent answer" => ["commands/intent_answer", "IntentAnswer", "Answer an intent's needs_decision node"],
|
|
29
|
+
"intent end" => ["commands/intent_end", "IntentEnd", "Close an intent as delivered or abandoned"],
|
|
30
|
+
"intent new" => ["commands/intent_new", "IntentNew", "Create a new intent"],
|
|
31
|
+
"intent note" => ["commands/intent_note", "IntentNote", "Append a savepoint note to an intent"],
|
|
32
|
+
"intent rule" => ["commands/intent_rule", "IntentRule", "Record a ruling in an intent's Insights"],
|
|
33
|
+
"intent show" => ["commands/intent_show", "IntentShow", "Print an intent's state screen"],
|
|
34
|
+
"intent spec" => ["commands/intent_spec", "IntentSpec", "Print an intent's state screen, then the speccing rules"],
|
|
35
|
+
"intent step" => ["commands/intent_step", "IntentStep", "Run the next ready step of an intent's graph"],
|
|
36
|
+
"intent verify" => ["commands/intent_verify", "IntentVerify", "Run an intent's merge-gate checks"],
|
|
37
|
+
"migrate" => ["commands/migrate", "Migrate", "List the migrate subcommands"],
|
|
38
|
+
"migrate stores" => ["commands/migrate_stores", "MigrateStores", "Move the stores under stores/, behind a full copy of the home"],
|
|
39
|
+
"next" => ["commands/next", "Next", "Print the next action in one line"],
|
|
40
|
+
"project" => ["commands/project", "Project", "List the project subcommands"],
|
|
41
|
+
"project links" => ["commands/project_links", "ProjectLinks", "Project every store's Links sections from frontmatter"],
|
|
42
|
+
"project list" => ["commands/project_list", "ProjectList", "List every store this machine holds"],
|
|
43
|
+
"project new" => ["commands/project_new", "ProjectNew", "Register, provision and validate a new project"],
|
|
44
|
+
"query" => ["commands/query", "Query", "Run one read-only SQL statement on the index"],
|
|
45
|
+
"render" => ["commands/render", "Render", "Print one markdown file as an HTML page"],
|
|
46
|
+
"roadmap" => ["commands/roadmap", "Roadmap", "List the roadmap subcommands"],
|
|
47
|
+
"roadmap check" => ["commands/roadmap_check", "RoadmapCheck", "Check a roadmap's graph for cycles and dangling ids"],
|
|
48
|
+
"roadmap log" => ["commands/roadmap_log", "RoadmapLog", "Append a savepoint line to a roadmap's ledger"],
|
|
49
|
+
"roadmap next" => ["commands/roadmap_next", "RoadmapNext", "Name the roadmap most worth continuing"],
|
|
50
|
+
"roadmap show" => ["commands/roadmap_show", "RoadmapShow", "Print a roadmap's state screen"],
|
|
51
|
+
"rollback" => ["commands/rollback", "Rollback", "Move to a Plastic version this machine has run before"],
|
|
52
|
+
"search" => ["commands/search", "Search", "Find text in the stores, ranked, with one excerpt each"],
|
|
53
|
+
"session commit" => ["commands/session_commit", "SessionCommit", "Commit one verified checklist item"],
|
|
54
|
+
"session handoff" => ["commands/session_handoff", "SessionHandoff", "Write this session's hand-off into the day ledger"],
|
|
55
|
+
"session summary" => ["commands/session_summary", "SessionSummary", "Print the day ledger's open items and recent activity"],
|
|
56
|
+
"session" => ["commands/session", "Session", "List the session subcommands"],
|
|
57
|
+
"status" => ["commands/status", "Status", "Show active work in every store"],
|
|
58
|
+
"sync" => ["commands/sync", "Sync", "Bring the store files and the three databases level"],
|
|
59
|
+
"uninstall" => ["commands/uninstall", "Uninstall", "Remove Plastic from this machine's agents"],
|
|
60
|
+
"update" => ["commands/update", "Update", "Move Plastic to the next version on its channel"],
|
|
61
|
+
"version" => ["commands/version", "Version", "Print the installed Plastic version"]
|
|
62
|
+
}.freeze
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "did_you_mean"
|
|
5
|
+
require_relative "cli/table"
|
|
6
|
+
require_relative "cli/command"
|
|
7
|
+
require_relative "cli/output"
|
|
8
|
+
|
|
9
|
+
# Plastic::CLI (intent 363) - the dispatcher behind bin/plastic. It reads the
|
|
10
|
+
# command table, matches the longest command name the arguments begin with,
|
|
11
|
+
# requires that one file, and calls it. Nothing else is loaded, which is what
|
|
12
|
+
# keeps a call at about 20 milliseconds with RubyGems off.
|
|
13
|
+
#
|
|
14
|
+
# No arguments, or --help, print the command list. --version prints the
|
|
15
|
+
# version. A command's own --help prints that command's usage line, read from
|
|
16
|
+
# the class without building it. An unknown name exits 2 and names the closest
|
|
17
|
+
# command, so a typo never becomes a stack trace.
|
|
18
|
+
module Plastic
|
|
19
|
+
class CLI
|
|
20
|
+
FLAGS = {"--version" => "version", "-v" => "version",
|
|
21
|
+
"--help" => "help", "-h" => "help"}.freeze
|
|
22
|
+
|
|
23
|
+
def self.call(...)
|
|
24
|
+
new(...).call
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def initialize(argv, out: $stdout, err: $stderr, env: ENV, home: Dir.home,
|
|
28
|
+
directory: Dir.pwd, table: TABLE)
|
|
29
|
+
@argv = argv.dup
|
|
30
|
+
@out = out
|
|
31
|
+
@err = err
|
|
32
|
+
@env = env
|
|
33
|
+
@home = home
|
|
34
|
+
@directory = directory
|
|
35
|
+
@table = table
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def call
|
|
39
|
+
matched = match(expanded)
|
|
40
|
+
return unknown(expanded.first) unless matched
|
|
41
|
+
|
|
42
|
+
name, rest = matched
|
|
43
|
+
return usage(name, rest) if help?(rest)
|
|
44
|
+
|
|
45
|
+
command(name).call(rest, out: @out, err: @err, env: @env, home: @home,
|
|
46
|
+
directory: @directory)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def match(argv)
|
|
50
|
+
[2, 1].each do |width|
|
|
51
|
+
name = argv.first(width).join(" ")
|
|
52
|
+
return [name, argv.drop(width)] if @table.key?(name)
|
|
53
|
+
end
|
|
54
|
+
nil
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
def expanded
|
|
60
|
+
return ["help"] if @argv.empty?
|
|
61
|
+
|
|
62
|
+
[FLAGS.fetch(@argv.first, @argv.first)] + @argv.drop(1)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def help?(rest)
|
|
66
|
+
rest.any? { |argument| FLAGS[argument] == "help" }
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def usage(name, rest)
|
|
70
|
+
Output.new(out: @out, err: @err)
|
|
71
|
+
.row("usage", command(name)::USAGE_LINE)
|
|
72
|
+
.flush(json: rest.include?("--json"))
|
|
73
|
+
Command::OK
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def command(name)
|
|
77
|
+
file, const, = @table.fetch(name)
|
|
78
|
+
require_relative "cli/#{file}"
|
|
79
|
+
Commands.const_get(const)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def unknown(name)
|
|
83
|
+
suggestions = closest(name)
|
|
84
|
+
@err.puts "plastic: no command named #{name.inspect}"
|
|
85
|
+
@err.puts "Closest: #{suggestions.join(", ")}" unless suggestions.empty?
|
|
86
|
+
@err.puts "Run `plastic help` for the command list."
|
|
87
|
+
Command::USAGE
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def closest(name)
|
|
91
|
+
DidYouMean::SpellChecker.new(dictionary: @table.keys).correct(name)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -70,15 +70,16 @@ module CodexAdapter
|
|
|
70
70
|
# worktree, never `~/.plastic`), `--output-last-message` at the path the
|
|
71
71
|
# caller names, and a bare `-` so the prompt is read from stdin (row 6.9) -
|
|
72
72
|
# the node input itself never rides in this array.
|
|
73
|
-
def build_argv(kind:, worktree:, output_last_message:)
|
|
74
|
-
[
|
|
73
|
+
def build_argv(kind:, worktree:, output_last_message:, model: nil, effort: nil)
|
|
74
|
+
argv = [
|
|
75
75
|
"codex", "exec",
|
|
76
76
|
"-C", worktree.to_s,
|
|
77
77
|
"--sandbox", sandbox_mode(kind),
|
|
78
78
|
*add_dir_args(kind: kind, worktree: worktree),
|
|
79
|
-
"--output-last-message", output_last_message.to_s,
|
|
80
|
-
"-",
|
|
81
79
|
]
|
|
80
|
+
argv += ["--model", model.to_s] unless model.to_s.strip.empty?
|
|
81
|
+
argv += ["--config", %(model_reasoning_effort="#{effort}")] unless effort.to_s.strip.empty?
|
|
82
|
+
argv + ["--output-last-message", output_last_message.to_s, "-"]
|
|
82
83
|
end
|
|
83
84
|
|
|
84
85
|
# matrix row 6.23: the wall-clock bound comes from the KIND's own lease
|
|
@@ -28,7 +28,15 @@ module CompactInstructions
|
|
|
28
28
|
# as stale, so the block states the shipped numbers and names the two keys as the
|
|
29
29
|
# override instead. It names the hand-off in words and never by path, so it reads
|
|
30
30
|
# correctly whether or not the hand-off writer is installed.
|
|
31
|
+
# The `@` line is a Claude Code import: the harness reads the named file into the
|
|
32
|
+
# session. It is the whole of ruling D43, that PLASTIC.md is the only instruction text
|
|
33
|
+
# Plastic carries. It names the installed copy under the Plastic home, because a bare
|
|
34
|
+
# `@PLASTIC.md` would resolve against ~/.claude, where no such file exists.
|
|
31
35
|
BODY = <<~MD.freeze
|
|
36
|
+
Plastic runs from one command, `plastic`. Its instructions are one page, imported here:
|
|
37
|
+
|
|
38
|
+
@~/.plastic/PLASTIC.md
|
|
39
|
+
|
|
32
40
|
Plastic watches this session's context. When the harness reports how much of the
|
|
33
41
|
window is used:
|
|
34
42
|
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
# heartbeat. Never the raw ledger (296 D36). No environment reads; every
|
|
9
9
|
# path is injected.
|
|
10
10
|
|
|
11
|
+
require_relative "store_layout"
|
|
11
12
|
require "time"
|
|
12
13
|
require_relative "session_ledger"
|
|
13
14
|
require_relative "handoff"
|
|
@@ -82,10 +83,10 @@ module DaySummary
|
|
|
82
83
|
# The global store plus every projects/<slug>/store, each with its INDEX
|
|
83
84
|
# one level up, the way doctor enumerates them.
|
|
84
85
|
def stores(home)
|
|
85
|
-
list = [[File.join(home, "INDEX.md"),
|
|
86
|
-
projects_root =
|
|
86
|
+
list = [[File.join(Plastic::StoreLayout.global_root(home), "INDEX.md"), Plastic::StoreLayout.global_store(home)]]
|
|
87
|
+
projects_root = Plastic::StoreLayout.projects_root(home)
|
|
87
88
|
if File.directory?(projects_root)
|
|
88
|
-
|
|
89
|
+
Plastic::StoreLayout.project_slugs(home).each do |slug|
|
|
89
90
|
list << [File.join(projects_root, slug, "INDEX.md"), File.join(projects_root, slug, "store")]
|
|
90
91
|
end
|
|
91
92
|
end
|
|
@@ -8,12 +8,13 @@
|
|
|
8
8
|
# the store, conventions, intent and CLI halves, so Doctor stays one class with
|
|
9
9
|
# one public surface and one definition of which checks are core (intent 36a).
|
|
10
10
|
|
|
11
|
+
require_relative "store_layout"
|
|
11
12
|
require "json"
|
|
12
13
|
require "yaml"
|
|
13
14
|
require "time"
|
|
14
15
|
require "digest"
|
|
15
|
-
require "rubygems"
|
|
16
16
|
|
|
17
|
+
require_relative "version_number"
|
|
17
18
|
require_relative "hook_registry"
|
|
18
19
|
require_relative "compact_instructions"
|
|
19
20
|
|
|
@@ -301,7 +302,7 @@ class Doctor
|
|
|
301
302
|
return checks
|
|
302
303
|
end
|
|
303
304
|
|
|
304
|
-
index_path = File.join(plastic_home, "INDEX.md")
|
|
305
|
+
index_path = File.join(Plastic::StoreLayout.global_root(plastic_home), "INDEX.md")
|
|
305
306
|
if File.exist?(index_path)
|
|
306
307
|
checks << check(
|
|
307
308
|
category: "global_store", name: "global_index_reachable", status: "pass",
|
|
@@ -517,9 +518,6 @@ class Doctor
|
|
|
517
518
|
checks << hooks_entries_owned_check(settings)
|
|
518
519
|
end
|
|
519
520
|
|
|
520
|
-
# skills_exist — flat, hyphen-namespaced personal skills (plastic-<name>/)
|
|
521
|
-
checks << flat_skills_check(agent_dir, "--claude")
|
|
522
|
-
|
|
523
521
|
# stray_skills — installed plastic-* skill dir with no manifest entry (a leftover,
|
|
524
522
|
# e.g. an old-name copy after a rename; intent 158a AC15)
|
|
525
523
|
checks << stray_skills_check(agent_dir, "--claude", File.join(agent_dir, "plastic", "manifest.json"))
|
|
@@ -630,24 +628,6 @@ class Doctor
|
|
|
630
628
|
)
|
|
631
629
|
end
|
|
632
630
|
|
|
633
|
-
def flat_skills_check(agent_dir, installer_flag)
|
|
634
|
-
skills_root = File.join(agent_dir, "skills")
|
|
635
|
-
found = Dir.glob(File.join(skills_root, "plastic-*", "SKILL.md"))
|
|
636
|
-
|
|
637
|
-
if !found.empty?
|
|
638
|
-
check(
|
|
639
|
-
category: "agent_registration", name: "skills_exist", status: "pass",
|
|
640
|
-
message: "#{found.size} plastic-* skill(s) installed in #{tilde(skills_root)}"
|
|
641
|
-
)
|
|
642
|
-
else
|
|
643
|
-
check(
|
|
644
|
-
category: "agent_registration", name: "skills_exist", status: "fail",
|
|
645
|
-
message: "No plastic-* skills found in #{tilde(skills_root)}",
|
|
646
|
-
fixable: true, fix_hint: "Re-run the Plastic installer: npx @zalom/plastic@latest #{installer_flag}"
|
|
647
|
-
)
|
|
648
|
-
end
|
|
649
|
-
end
|
|
650
|
-
|
|
651
631
|
# Manifest-diff stray-skill check (intent 158a), extended (intent 276) to
|
|
652
632
|
# never vanish on a missing manifest and to name the reserved-prefix rule.
|
|
653
633
|
def stray_skills_check(agent_dir, installer_flag, manifest_path)
|
|
@@ -707,9 +687,6 @@ class Doctor
|
|
|
707
687
|
def check_flat_skills_and_stray(agent_key, agent_dir)
|
|
708
688
|
checks = []
|
|
709
689
|
|
|
710
|
-
# For codex/hermes: just check skills exist (no settings.json hooks)
|
|
711
|
-
checks << flat_skills_check(agent_dir, "--#{agent_key}")
|
|
712
|
-
|
|
713
690
|
# stray_skills — installed plastic-* skill dir with no manifest entry (a leftover,
|
|
714
691
|
# e.g. an old-name copy after a rename; intent 158a AC15)
|
|
715
692
|
checks << stray_skills_check(agent_dir, "--#{agent_key}", File.join(agent_dir, "plastic", "manifest.json"))
|
|
@@ -1061,9 +1038,7 @@ class Doctor
|
|
|
1061
1038
|
end
|
|
1062
1039
|
|
|
1063
1040
|
def safe_version(str)
|
|
1064
|
-
|
|
1065
|
-
rescue ArgumentError
|
|
1066
|
-
nil
|
|
1041
|
+
VersionNumber.parse(str)
|
|
1067
1042
|
end
|
|
1068
1043
|
|
|
1069
1044
|
def check_core_files(agent_key, include_drift: true)
|
|
@@ -1167,7 +1142,7 @@ class Doctor
|
|
|
1167
1142
|
"#{tilde(agent_version_path)}: #{agent_version}",
|
|
1168
1143
|
],
|
|
1169
1144
|
fixable: true,
|
|
1170
|
-
fix_hint: "Re-sync the stale harness: npx @zalom/plastic@latest install --reinstall <flag>, or plastic
|
|
1145
|
+
fix_hint: "Re-sync the stale harness: npx @zalom/plastic@latest install --reinstall <flag>, or `plastic rollback` to a prior version"
|
|
1171
1146
|
)
|
|
1172
1147
|
end
|
|
1173
1148
|
else
|
|
@@ -1175,7 +1150,7 @@ class Doctor
|
|
|
1175
1150
|
category: "core_files", name: "version_match", status: "warn",
|
|
1176
1151
|
message: "Agent-side VERSION file not found at #{tilde(agent_version_path)}",
|
|
1177
1152
|
fixable: true,
|
|
1178
|
-
fix_hint: "Re-sync the stale harness: npx @zalom/plastic@latest install --reinstall <flag>, or plastic
|
|
1153
|
+
fix_hint: "Re-sync the stale harness: npx @zalom/plastic@latest install --reinstall <flag>, or `plastic rollback` to a prior version"
|
|
1179
1154
|
)
|
|
1180
1155
|
end
|
|
1181
1156
|
end
|
|
@@ -1280,7 +1255,7 @@ class Doctor
|
|
|
1280
1255
|
|
|
1281
1256
|
DISPLAY_HOOK_FIX_HINT = "Re-run the Plastic installer to repair the hook registration: " \
|
|
1282
1257
|
"npx @zalom/plastic@<channel> install --reinstall --claude " \
|
|
1283
|
-
"(plastic
|
|
1258
|
+
"(plastic install --reinstall)".freeze
|
|
1284
1259
|
|
|
1285
1260
|
# display_hook_registered (intent 331e, D1, category "display"): the Claude
|
|
1286
1261
|
# settings carry the plastic-message-display command, on-disk, executable.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# encoding: UTF-8
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
+
require_relative "store_layout"
|
|
4
5
|
require "time"
|
|
5
6
|
require_relative "session_ledger"
|
|
6
7
|
|
|
@@ -38,7 +39,7 @@ module DoctorSessionLedger
|
|
|
38
39
|
def check_session_ledger(scopes: nil, now: Time.now)
|
|
39
40
|
return [] unless scopes.nil? || scopes.include?("global")
|
|
40
41
|
|
|
41
|
-
store_dir =
|
|
42
|
+
store_dir = Plastic::StoreLayout.global_store(plastic_home)
|
|
42
43
|
orphans = orphaned_session_dirs(store_dir, now)
|
|
43
44
|
shape = day_ledger_shape_problems(store_dir)
|
|
44
45
|
|
|
@@ -18,7 +18,7 @@ require "fileutils"
|
|
|
18
18
|
# Trust model: this class never sends anything anywhere. `compose` returns a
|
|
19
19
|
# Result carrying a local file path and a browser URL; only the human, in
|
|
20
20
|
# their own authenticated browser, submits it. There is no send method here
|
|
21
|
-
# and there must never be one (see
|
|
21
|
+
# and there must never be one (see SECURITY.md).
|
|
22
22
|
class FeedbackReport
|
|
23
23
|
GITHUB_REPO = "zalom/plastic"
|
|
24
24
|
CAP_BYTES = 7500
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# encoding: UTF-8
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
+
require_relative "store_layout"
|
|
4
5
|
require "json"
|
|
5
6
|
require "tmpdir"
|
|
6
7
|
require_relative "node_ledger"
|
|
@@ -24,7 +25,7 @@ require_relative "agent_models"
|
|
|
24
25
|
# through `RunnerPolicy.model_for(kind, config:)`, the one place that maps a
|
|
25
26
|
# node's kind to the role the runner actually dispatched it against - never
|
|
26
27
|
# a hand-rolled kind-to-role table, and never `AgentModels::TIER_DEFAULTS`
|
|
27
|
-
# directly, which carries no `plastic-advisor` entry at all (that agent is a
|
|
28
|
+
# directly, which carries no `plastic-primary-advisor` entry at all (that agent is a
|
|
28
29
|
# consultation agent, never auto-dispatched). Adds no second parser:
|
|
29
30
|
# `NodeLedger` owns the transition-line format, `NodeFile` owns the kind
|
|
30
31
|
# envelope and the `KIND_PREFIX` fallback, `RunnerPolicy`/`AgentModels` own
|
|
@@ -112,7 +113,8 @@ module GraphMeasureModels
|
|
|
112
113
|
# purpose - two different silences over the same store, agreeing with
|
|
113
114
|
# each other only by accident.
|
|
114
115
|
def project_config_path(store_dir)
|
|
115
|
-
|
|
116
|
+
home, slug = Plastic::StoreLayout.locate(store_dir.to_s)
|
|
117
|
+
File.join((slug == Plastic::StoreLayout::GLOBAL) ? home : File.dirname(store_dir.to_s), "config.yml")
|
|
116
118
|
end
|
|
117
119
|
|
|
118
120
|
# --- rendering ---------------------------------------------------------------
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
# plain hyphen as the id/title separator on READ; every WRITE still emits the
|
|
11
11
|
# real em dash (D10). The separator is built from the codepoint, not a
|
|
12
12
|
# literal byte, so this file stays em-dash free.
|
|
13
|
+
require_relative "atomic_write"
|
|
14
|
+
|
|
13
15
|
module IndexEntry
|
|
14
16
|
module_function
|
|
15
17
|
|
|
@@ -22,6 +24,13 @@ module IndexEntry
|
|
|
22
24
|
line.to_s.match(ENTRY_RE)
|
|
23
25
|
end
|
|
24
26
|
|
|
27
|
+
def add_active(index_path, dir_name:, title:)
|
|
28
|
+
id = dir_name.split("--").first
|
|
29
|
+
line = "- [#{id} #{EM_DASH} #{title}](store/#{dir_name}/#{dir_name}.md)\n"
|
|
30
|
+
text = File.read(index_path, encoding: "UTF-8")
|
|
31
|
+
AtomicWrite.write(index_path, text.sub(/^## Active\n/) { |heading| heading + line })
|
|
32
|
+
end
|
|
33
|
+
|
|
25
34
|
# True iff the intent is Active in its store's INDEX.md, which lives at the
|
|
26
35
|
# PARENT of the store/ dir. Non-raising: any failure (missing or unreadable
|
|
27
36
|
# INDEX, bad arg) returns false. `index_active_ids` is a pure-data test
|