mcptask-rails-runner 0.3.48 → 0.3.50
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +72 -0
- data/lib/mcptask_rails_runner/binary.rb +44 -11
- data/lib/mcptask_rails_runner/palette.rb +50 -19
- data/lib/mcptask_rails_runner/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a8ed1f78b740e6c06359d6542e3076565af06ab29b8e819af2dc96e4147d2e63
|
|
4
|
+
data.tar.gz: d516cff029479cd79757e5bb13c104836e7f4f2a03795ff4f6a4baf2450274c7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 77c3f2e609f5fe842cf432595ec6339fb788a22bc6724a847c6fb7b5532e60ba5730dafb95b16ec8d49fa06265cb6bfd1e1101f52b73659383fc45f344939800
|
|
7
|
+
data.tar.gz: e6985e3d9a02f888c0e2955ef78d3db100c3fa9f0238796730d78491fcc9f0c5f72f913fb82a6431dce6547fa1d93f090faf813bf9029bdf07a39d1c2267cfd0
|
data/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,78 @@ release notes for the same tag.
|
|
|
9
9
|
|
|
10
10
|
Nothing yet.
|
|
11
11
|
|
|
12
|
+
## 0.3.50
|
|
13
|
+
|
|
14
|
+
Full binary notes in
|
|
15
|
+
[mcptask-releases v0.3.50](https://github.com/jchsoft/mcptask-releases/releases/tag/v0.3.50).
|
|
16
|
+
|
|
17
|
+
**Upgrading takes two commands.** `mcptask_runner update --self` replaces the binary; then a bare `mcptask_runner update` in every project on the host, because the bundled `.claude/` assets changed (skills/mcptask-read/SKILL.md). Run it while no runner is working that checkout. A runner idling in a wait keeps the old binary until its next task or a restart (`launchctl kill SIGTERM`, wait for the job to stop, then `kickstart` on macOS), so restart it.
|
|
18
|
+
|
|
19
|
+
**The gem's own line in `rake mcptask_runner:install` / `:update` now takes the shape of init's screen** (Story 14828). It is the first line of that screen, so it speaks the same line kinds, glyphs and codes as the Go binary's output after it:
|
|
20
|
+
|
|
21
|
+
- `✓ mcptask_runner 0.3.50 installed into ~/.mcptask/bin` (green), with `(was 0.3.49)` when it replaced an older one, or `✓ mcptask_runner 0.3.49 is already current` when the installed copy already held this version. The old `installed ... (replacing 0.3.49)` with the same version on both sides said nothing.
|
|
22
|
+
- `! ...` for a warning the run goes on after (`MCPTASK_RUNNER_BIN` is set, a newer binary is kept): orange `\e[38;5;208m` when `TERM` contains `256color` or `COLORTERM` is set, else yellow. These were yellow with no glyph.
|
|
23
|
+
- `✗ ...` (red) with the step to take when the binary is missing from the gem or the copy fails; the error is still raised after the line.
|
|
24
|
+
- The `[mcptask_runner]` prefix is gone, and the home directory is shown as `~`.
|
|
25
|
+
- Colour only on a terminal, never with `NO_COLOR` non-empty; `MCPTASK_RUNNER_COLOR` keeps its meaning. With colour off the text is plain, glyphs included.
|
|
26
|
+
- Task names and argument forms are unchanged, and so is how the binary is exec'd.
|
|
27
|
+
|
|
28
|
+
Binary changes carried by this version:
|
|
29
|
+
|
|
30
|
+
- Re-check now: the card checks a host problem at once
|
|
31
|
+
- Each token variable gets its own export file
|
|
32
|
+
- A runner may now sit retrying instead of ending its day
|
|
33
|
+
- `init` says whose role is missing, and where
|
|
34
|
+
- The `mcptask-read` skill downloads attachments with the signed link only
|
|
35
|
+
- `init` speaks in colour on a terminal
|
|
36
|
+
- `init` runs in four sections, each with one green line
|
|
37
|
+
- `update` speaks the same line kinds as `init`
|
|
38
|
+
- The install has a bad day of its own
|
|
39
|
+
- Every warning and refusal of `init` is a named exception, orange or red, with its step
|
|
40
|
+
- An interrupted `init` continues at its last unanswered question
|
|
41
|
+
- `init` on an installed project sums it up and asks one question
|
|
42
|
+
- A kill never empties a file
|
|
43
|
+
- `init` is tested through a real terminal
|
|
44
|
+
- What `init` says before it has a screen is painted too
|
|
45
|
+
- The scheduled job runs on the days you choose, and `--force` repairs an old one
|
|
46
|
+
- The card carries the scheduled job's plan
|
|
47
|
+
|
|
48
|
+
## 0.3.49
|
|
49
|
+
|
|
50
|
+
Full binary notes in
|
|
51
|
+
[mcptask-releases v0.3.49](https://github.com/jchsoft/mcptask-releases/releases/tag/v0.3.49).
|
|
52
|
+
|
|
53
|
+
**Upgrading takes two commands.** `mcptask_runner update --self` replaces the binary; then a bare `mcptask_runner update` in every project on the host, because the bundled `.claude/` assets changed (helpers/check_test_lock, skills/test-runner/SKILL.md). Run it while no runner is working that checkout. A runner idling in a wait keeps the old binary until its next task or a restart (`launchctl kill SIGTERM`, wait for the job to stop, then `kickstart` on macOS), so restart it.
|
|
54
|
+
|
|
55
|
+
No wrapper changes.
|
|
56
|
+
|
|
57
|
+
Binary changes carried by this version:
|
|
58
|
+
|
|
59
|
+
- `init` asks which project this is
|
|
60
|
+
- `init` switches the job on
|
|
61
|
+
- The install's task logs its progress without a refusal
|
|
62
|
+
- `init` stops asking what it can find out
|
|
63
|
+
- `init` keeps its details in a log
|
|
64
|
+
- A CLI that exits 127 is reported as not found
|
|
65
|
+
- A bug report attaches only the current run's record
|
|
66
|
+
- The story sweep rides out a dropped connection
|
|
67
|
+
- `pr merge` carries a tree-identical head's statuses to the merge commit
|
|
68
|
+
- `init` recognises an Xcode project
|
|
69
|
+
- Two reports stop blaming the child for what happened outside it
|
|
70
|
+
- An mcptask.online outage no longer ends the day
|
|
71
|
+
- A triage that cannot reach its tools is waited out
|
|
72
|
+
- A panic in a background goroutine is reported like a loop panic
|
|
73
|
+
- The daily loop keeps working when a bug report is refused
|
|
74
|
+
- An urgent bug on a dirty branch waits for a person instead of ending the run
|
|
75
|
+
- A usage limit that outlasts the runner's waits no longer ends the day
|
|
76
|
+
- A report no longer lists a settings file the project never had
|
|
77
|
+
- One host refusal is one bug piece a day
|
|
78
|
+
- Git credentials origin refuses are waited out, not filed
|
|
79
|
+
- A refused task waits for a person, and the child no longer looks for a way in
|
|
80
|
+
- A step only a person can take becomes that person's task
|
|
81
|
+
- A Stop from the card during a Story's merge pauses the runner, not ends it
|
|
82
|
+
- The banner says where the runner's own failures go; a refused card is said in the log
|
|
83
|
+
|
|
12
84
|
## 0.3.48
|
|
13
85
|
|
|
14
86
|
Full binary notes in
|
|
@@ -85,38 +85,71 @@ module McptaskRailsRunner
|
|
|
85
85
|
# Newest wins, and says so. A host with several projects has several gem
|
|
86
86
|
# versions and one installed binary, so a project pinning an older gem must
|
|
87
87
|
# not quietly drag the machine's runner backwards.
|
|
88
|
+
#
|
|
89
|
+
# What it prints is the first line of init's screen, in init's line kinds:
|
|
90
|
+
# done (green check), a warning the run goes on after (orange bang), or a
|
|
91
|
+
# refusal with the step to take (red cross), after which the error is still
|
|
92
|
+
# raised — the line is for the person, the exception is for the report.
|
|
88
93
|
def install!(install_dir: INSTALL_DIR, gem_root: GEM_ROOT, out: $stdout)
|
|
89
94
|
paint = Palette.for(out)
|
|
90
95
|
|
|
91
96
|
override = ENV["MCPTASK_RUNNER_BIN"]
|
|
92
97
|
unless override.nil? || override.empty?
|
|
93
|
-
out.puts paint.
|
|
98
|
+
out.puts paint.warning("MCPTASK_RUNNER_BIN is set — running #{override} " \
|
|
94
99
|
"and leaving #{installed_path(install_dir: install_dir)} alone.")
|
|
95
100
|
return override
|
|
96
101
|
end
|
|
97
102
|
|
|
98
|
-
source =
|
|
103
|
+
source = bundled_source(gem_root, out, paint)
|
|
99
104
|
target = installed_path(install_dir: install_dir)
|
|
100
105
|
|
|
101
106
|
existing = installed_version(target)
|
|
102
107
|
if existing && existing > Gem::Version.new(VERSION)
|
|
103
|
-
out.puts paint.
|
|
108
|
+
out.puts paint.warning("#{display_path(target)} already holds #{existing}, which is newer than " \
|
|
104
109
|
"this gem's #{VERSION} — keeping it. Delete that file to install this " \
|
|
105
110
|
"gem's binary instead.")
|
|
106
111
|
return target
|
|
107
112
|
end
|
|
108
113
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
# install, or the same version laid down again. Yellow when a binary the
|
|
112
|
-
# host was running has just been replaced, which is the one line of this
|
|
113
|
-
# command worth stopping on.
|
|
114
|
-
line = "[mcptask_runner] installed mcptask_runner #{VERSION} into #{target}" \
|
|
115
|
-
"#{existing ? " (replacing #{existing})" : ''}."
|
|
116
|
-
out.puts(existing && existing < Gem::Version.new(VERSION) ? paint.changed(line) : paint.ok(line))
|
|
114
|
+
copy_or_refuse(source, target, out, paint)
|
|
115
|
+
out.puts paint.done(installed_line(existing, install_dir))
|
|
117
116
|
target
|
|
118
117
|
end
|
|
119
118
|
|
|
119
|
+
# The bundled binary, or the red line that says what to do about its absence
|
|
120
|
+
# and then the error itself.
|
|
121
|
+
def bundled_source(gem_root, out, paint)
|
|
122
|
+
bundled_path(gem_root: gem_root)
|
|
123
|
+
rescue Error
|
|
124
|
+
out.puts paint.refusal("mcptask_runner binary missing from this gem — run `bundle install` again, or " \
|
|
125
|
+
"set MCPTASK_RUNNER_BIN to a binary from https://github.com/jchsoft/mcptask-releases.")
|
|
126
|
+
raise
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def copy_or_refuse(source, target, out, paint)
|
|
130
|
+
copy(source, target)
|
|
131
|
+
rescue SystemCallError => e
|
|
132
|
+
out.puts paint.refusal("could not copy mcptask_runner into #{display_path(File.dirname(target))} " \
|
|
133
|
+
"(#{e.message}) — make that directory writable, then run this task again.")
|
|
134
|
+
raise
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# "installed" is what happened; "is already current" is what it was worth
|
|
138
|
+
# saying when the installed copy already held this version, which "replacing
|
|
139
|
+
# 0.3.49" with 0.3.49 never did.
|
|
140
|
+
def installed_line(existing, install_dir)
|
|
141
|
+
return "mcptask_runner #{VERSION} is already current" if existing == Gem::Version.new(VERSION)
|
|
142
|
+
|
|
143
|
+
line = "mcptask_runner #{VERSION} installed into #{display_path(install_dir)}"
|
|
144
|
+
existing ? "#{line} (was #{existing})" : line
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# The home directory as ~, the way a person types it.
|
|
148
|
+
def display_path(path)
|
|
149
|
+
home = Dir.home
|
|
150
|
+
path == home || path.start_with?("#{home}#{File::SEPARATOR}") ? path.sub(home, "~") : path
|
|
151
|
+
end
|
|
152
|
+
|
|
120
153
|
# Replaces the current process, so the binary's exit code and signal
|
|
121
154
|
# handling reach the caller (rake) unchanged.
|
|
122
155
|
def exec!(*args)
|
|
@@ -1,23 +1,33 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module McptaskRailsRunner
|
|
4
|
-
# Colour for the lines this gem prints before it hands the process
|
|
4
|
+
# Colour and shape for the lines this gem prints before it hands the process
|
|
5
|
+
# over.
|
|
5
6
|
#
|
|
6
|
-
# `rake mcptask_runner:
|
|
7
|
-
# everything after it
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
7
|
+
# `rake mcptask_runner:install` opens with Binary.install!'s line, and
|
|
8
|
+
# everything after it is the Go binary's init screen. That screen has a fixed
|
|
9
|
+
# set of line kinds (Story 14828): a green check for what is done, an orange
|
|
10
|
+
# bang for an exception the run goes on after, a red cross plus the step to
|
|
11
|
+
# take for one that stops it. This gem's own line is the first line of that
|
|
12
|
+
# screen, so it speaks the same kinds, in the same glyphs and codes.
|
|
12
13
|
#
|
|
13
|
-
# The rules here are copied from internal/
|
|
14
|
-
#
|
|
15
|
-
# terminal and nowhere else". Two halves of one
|
|
16
|
-
# what NO_COLOR means would be a puzzle, not a
|
|
14
|
+
# The rules here are copied from internal/ansi/ansi.go and
|
|
15
|
+
# internal/install/color.go in the Go repo rather than invented — same
|
|
16
|
+
# colours, same levers, same "a terminal and nowhere else". Two halves of one
|
|
17
|
+
# command that disagreed about what NO_COLOR means would be a puzzle, not a
|
|
18
|
+
# feature.
|
|
17
19
|
class Palette
|
|
18
20
|
RESET = "\e[0m"
|
|
21
|
+
BOLD = "\e[1m"
|
|
22
|
+
DIM = "\e[2m"
|
|
23
|
+
RED = "\e[31m"
|
|
19
24
|
GREEN = "\e[32m"
|
|
20
25
|
YELLOW = "\e[33m"
|
|
26
|
+
ORANGE = "\e[38;5;208m"
|
|
27
|
+
|
|
28
|
+
DONE_GLYPH = "✓"
|
|
29
|
+
WARNING_GLYPH = "!"
|
|
30
|
+
REFUSAL_GLYPH = "✗"
|
|
21
31
|
|
|
22
32
|
# Values of MCPTASK_RUNNER_COLOR that settle the question, either way.
|
|
23
33
|
FORCE_ON = %w[1 true always force].freeze
|
|
@@ -33,7 +43,14 @@ module McptaskRailsRunner
|
|
|
33
43
|
|
|
34
44
|
# for decides how one stream should be written to.
|
|
35
45
|
def self.for(out, env: ENV)
|
|
36
|
-
new(enabled: enabled?(out, env))
|
|
46
|
+
new(enabled: enabled?(out, env), orange: orange?(env))
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Orange is a 256-colour code. A terminal that does not say it has them gets
|
|
50
|
+
# the yellow every terminal has, rather than a code it may render as
|
|
51
|
+
# something else.
|
|
52
|
+
def self.orange?(env)
|
|
53
|
+
env["TERM"].to_s.include?("256color") || !env["COLORTERM"].to_s.empty?
|
|
37
54
|
end
|
|
38
55
|
|
|
39
56
|
# MCPTASK_RUNNER_COLOR is asked first and wins both ways, because it is the
|
|
@@ -51,22 +68,36 @@ module McptaskRailsRunner
|
|
|
51
68
|
Gem.win_platform? ? WINDOWS_ANSI_HINTS.any? { |name| !env[name].to_s.empty? } : true
|
|
52
69
|
end
|
|
53
70
|
|
|
54
|
-
def initialize(enabled:)
|
|
71
|
+
def initialize(enabled:, orange: false)
|
|
55
72
|
@enabled = enabled
|
|
73
|
+
@orange = orange
|
|
56
74
|
end
|
|
57
75
|
|
|
58
76
|
def enabled?
|
|
59
77
|
@enabled
|
|
60
78
|
end
|
|
61
79
|
|
|
62
|
-
#
|
|
63
|
-
def
|
|
64
|
-
wrap(GREEN, text)
|
|
80
|
+
# done — this happened, or is already the state you wanted.
|
|
81
|
+
def done(text)
|
|
82
|
+
wrap(GREEN, "#{DONE_GLYPH} #{text}")
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# warning — something is not as expected, and the run goes on.
|
|
86
|
+
def warning(text)
|
|
87
|
+
wrap(@orange ? ORANGE : YELLOW, "#{WARNING_GLYPH} #{text}")
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# refusal — the run has stopped; the text carries the step to take.
|
|
91
|
+
def refusal(text)
|
|
92
|
+
wrap(RED, "#{REFUSAL_GLYPH} #{text}")
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def bold(text)
|
|
96
|
+
wrap(BOLD, text)
|
|
65
97
|
end
|
|
66
98
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
wrap(YELLOW, text)
|
|
99
|
+
def dim(text)
|
|
100
|
+
wrap(DIM, text)
|
|
70
101
|
end
|
|
71
102
|
|
|
72
103
|
private
|
|
@@ -10,5 +10,5 @@ module McptaskRailsRunner
|
|
|
10
10
|
# Binary::INSTALL_DIR. So the pin is per project and per foreground rake
|
|
11
11
|
# invocation; the installed copy is per machine, and the newest binary any of
|
|
12
12
|
# those projects offers is the one that stays.
|
|
13
|
-
VERSION = "0.3.
|
|
13
|
+
VERSION = "0.3.50"
|
|
14
14
|
end
|