carson 4.2.1 → 4.3.0
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/RELEASE.md +23 -0
- data/VERSION +1 -1
- data/lib/carson/config.rb +6 -1
- data/lib/carson/courier.rb +52 -8
- data/lib/carson/runtime/deliver.rb +1 -0
- data/lib/carson/warehouse/vault.rb +76 -0
- data/lib/carson/warehouse.rb +45 -0
- data/lib/cli.rb +85 -6
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5d25d50d20c3cc3244b3ab246ca7f5b661e097146993fee1cc5b8dd66f978938
|
|
4
|
+
data.tar.gz: 1d2f6a26fc79dc62688c409557f2b74328f593f2e582af17c4a6fa020bb1b75b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 234de9b2d4bad297af4b7bf24bd396629690bde5925fa743d9438316dcbb146f88e444b0aed61a72c022de32e34ba09aeedfb078afc4711973437eb5a38e6279
|
|
7
|
+
data.tar.gz: 2d3438c23a8146367289413e28d756eee5cb303c58c5820273f471482a83f351d0fc379a3db01a6edbbcdd5f13afbce508b8f999344d0e295dfb6fd74c816f88
|
data/RELEASE.md
CHANGED
|
@@ -7,6 +7,29 @@ Release-note scope rule:
|
|
|
7
7
|
|
|
8
8
|
## Unreleased
|
|
9
9
|
|
|
10
|
+
## 4.3.0
|
|
11
|
+
|
|
12
|
+
### New
|
|
13
|
+
|
|
14
|
+
- **Local-centred workstyle** — Carson now supports two workstyles. Local-centred (the new default) merges parcels directly into the local vault (main) and pushes to the remote as backup. No PR, no CI gate, no waiting. Remote-centred remains available for projects that need Bureau oversight. Set `workstyle: remote` in `.carson.yml` to use the old behaviour.
|
|
15
|
+
- **`Warehouse::Vault` concern** — the vault is local main, where accepted parcels live. `warehouse.accept!( parcel )` merges a branch into main via fast-forward. If the branch has diverged, the agent must rebase first.
|
|
16
|
+
- **`warehouse.prepare!( parcel, message: )`** — the delivery prep phase: pack, fetch latest standard, check freshness, auto-rebase if behind. No compliance gate in local workstyle — agents handle linting and testing themselves.
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- **Courier is workstyle-aware** — `courier.deliver( parcel )` uses different gestures per workstyle. Local: push main to backup vault. Remote: the existing Bureau trip (unchanged). One verb, two gestures. The Courier doesn't know if it's doing "backup" or "primary" — it just delivers.
|
|
21
|
+
- **CLI orchestrates local delivery** — `carson deliver` in local workstyle follows the checkin/checkout pattern: CLI builds Warehouse + Courier, orchestrates `prepare!` → `accept!` → `courier.deliver`. No Runtime in the local path.
|
|
22
|
+
|
|
23
|
+
### UX
|
|
24
|
+
|
|
25
|
+
- `carson deliver` output (local workstyle): `⧓ <branch> merged into main.` / `⧓ Pushed to remote.`
|
|
26
|
+
- On failure: clear recovery instructions (`Rebase onto main and deliver again.`)
|
|
27
|
+
- On backup failure: `⧓ Backup failed.` with recovery.
|
|
28
|
+
|
|
29
|
+
### Why
|
|
30
|
+
|
|
31
|
+
The 2026-03-24 retrospective clarified that for a solo developer with agents, the remote-centred machinery (PR → CI → Bureau polling → merge) added latency, cost, and complexity without serving a need. The vault (local main) is the source of truth. GitHub is the backup vault. The Courier's job is simpler and faster.
|
|
32
|
+
|
|
10
33
|
## 4.2.1
|
|
11
34
|
|
|
12
35
|
### Fixed
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
4.
|
|
1
|
+
4.3.0
|
data/lib/carson/config.rb
CHANGED
|
@@ -33,7 +33,8 @@ module Carson
|
|
|
33
33
|
:govern_repos, :govern_merge_method,
|
|
34
34
|
:govern_agent_provider, :govern_state_path,
|
|
35
35
|
:govern_check_wait,
|
|
36
|
-
:poll_interval_at_bureau
|
|
36
|
+
:poll_interval_at_bureau,
|
|
37
|
+
:workstyle
|
|
37
38
|
|
|
38
39
|
def self.load( repo_root: )
|
|
39
40
|
base_data = default_data
|
|
@@ -85,6 +86,7 @@ module Carson
|
|
|
85
86
|
"deliver" => {
|
|
86
87
|
"poll_interval_at_bureau" => 30
|
|
87
88
|
},
|
|
89
|
+
"workstyle" => "local",
|
|
88
90
|
"govern" => {
|
|
89
91
|
"repos" => [],
|
|
90
92
|
"merge" => {
|
|
@@ -247,6 +249,9 @@ module Carson
|
|
|
247
249
|
deliver_hash = fetch_hash( hash: data, key: "deliver" )
|
|
248
250
|
@poll_interval_at_bureau = fetch_non_negative_integer( hash: deliver_hash, key: "poll_interval_at_bureau" )
|
|
249
251
|
|
|
252
|
+
workstyle_raw = data.fetch( "workstyle", "local" ).to_s.downcase
|
|
253
|
+
@workstyle = [ "local", "remote" ].include?( workstyle_raw ) ? workstyle_raw.to_sym : :local
|
|
254
|
+
|
|
250
255
|
govern_hash = fetch_hash( hash: data, key: "govern" )
|
|
251
256
|
@govern_repos = fetch_optional_string_array( hash: govern_hash, key: "repos" ).map { |path| safe_expand_path( path ) }
|
|
252
257
|
govern_merge_hash = fetch_hash( hash: govern_hash, key: "merge" )
|
data/lib/carson/courier.rb
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# Carson Co.
|
|
2
|
+
require "open3"
|
|
3
|
+
|
|
2
4
|
module Carson
|
|
3
|
-
# The delivery
|
|
5
|
+
# The delivery worker — waits at the gate, picks up parcels, delivers them.
|
|
4
6
|
#
|
|
5
7
|
# The courier is a Carson employee assigned to a warehouse. They pick up
|
|
6
8
|
# a parcel, ask the warehouse to ship it, file a waybill, and wait at
|
|
@@ -59,11 +61,14 @@ module Carson
|
|
|
59
61
|
# answer, the courier reports "filed" — the parcel is still at the bureau
|
|
60
62
|
# and the shelf stays sealed.
|
|
61
63
|
#
|
|
62
|
-
# ==
|
|
64
|
+
# == Workstyle
|
|
65
|
+
#
|
|
66
|
+
# The courier's gesture depends on the workstyle:
|
|
67
|
+
# - :local — push main to backup vault (simple, no PR, no waiting)
|
|
68
|
+
# - :remote — ship → waybill → bureau → acceptance (complex Bureau trip)
|
|
63
69
|
#
|
|
64
|
-
#
|
|
65
|
-
#
|
|
66
|
-
# The destination mode should be injectable, not baked in.
|
|
70
|
+
# The courier doesn't know whether it's doing "backup" or "primary" —
|
|
71
|
+
# it just delivers to wherever the workstyle dictates.
|
|
67
72
|
class Courier
|
|
68
73
|
# Exit codes — shared contract between Carson employees and the CLI.
|
|
69
74
|
OK = 0
|
|
@@ -75,17 +80,21 @@ module Carson
|
|
|
75
80
|
# The courier checks the bureau up to 6 times before leaving.
|
|
76
81
|
MAX_CHECKS_AT_BUREAU = 6
|
|
77
82
|
|
|
78
|
-
def initialize( warehouse, ledger: nil, merge_method: "rebase", poll_interval_at_bureau: 30, output: $stdout )
|
|
83
|
+
def initialize( warehouse, workstyle: :local, ledger: nil, merge_method: "rebase", poll_interval_at_bureau: 30, output: $stdout )
|
|
79
84
|
@warehouse = warehouse
|
|
85
|
+
@workstyle = workstyle
|
|
80
86
|
@ledger = ledger
|
|
81
87
|
@merge_method = merge_method
|
|
82
88
|
@poll_interval_at_bureau = poll_interval_at_bureau
|
|
83
89
|
@output = output
|
|
84
90
|
end
|
|
85
91
|
|
|
86
|
-
# Deliver a parcel
|
|
87
|
-
#
|
|
92
|
+
# Deliver a parcel.
|
|
93
|
+
# Local gesture: push main to backup vault.
|
|
94
|
+
# Remote gesture: ship to Bureau, file waybill, poll, register.
|
|
88
95
|
def deliver( parcel, title: nil, body_file: nil, commit_message: nil )
|
|
96
|
+
return deliver_locally( parcel ) if @workstyle == :local
|
|
97
|
+
|
|
89
98
|
result = {
|
|
90
99
|
command: "deliver",
|
|
91
100
|
label: parcel.label,
|
|
@@ -246,6 +255,41 @@ module Carson
|
|
|
246
255
|
result[ :diagnostic ] = waybill.ci_diagnostic
|
|
247
256
|
end
|
|
248
257
|
|
|
258
|
+
# Local gesture: push main to the backup vault.
|
|
259
|
+
# The parcel is already in the vault (accepted by the Warehouse).
|
|
260
|
+
# The courier's job is to push the vault state to the remote backup.
|
|
261
|
+
def deliver_locally( parcel )
|
|
262
|
+
result = {
|
|
263
|
+
command: "deliver",
|
|
264
|
+
label: parcel.label,
|
|
265
|
+
remote_main: "#{@warehouse.bureau_address}/#{@warehouse.main_label}"
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
remote = @warehouse.bureau_address
|
|
269
|
+
main = @warehouse.main_label
|
|
270
|
+
root = @warehouse.main_worktree_root
|
|
271
|
+
|
|
272
|
+
# --no-verify bypasses the pre-push hook that blocks direct pushes
|
|
273
|
+
# to main in governed repos. This IS Carson's delivery — the vault
|
|
274
|
+
# accepted the parcel, now the courier backs it up.
|
|
275
|
+
_, stderr, status = Open3.capture3(
|
|
276
|
+
"git", "-C", root, "push", "--no-verify", remote, main
|
|
277
|
+
)
|
|
278
|
+
|
|
279
|
+
if status.success?
|
|
280
|
+
result[ :exit ] = OK
|
|
281
|
+
result[ :outcome ] = "delivered"
|
|
282
|
+
result[ :synced ] = true
|
|
283
|
+
else
|
|
284
|
+
result[ :exit ] = OK
|
|
285
|
+
result[ :outcome ] = "delivered"
|
|
286
|
+
result[ :synced ] = false
|
|
287
|
+
result[ :backup_error ] = stderr.strip
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
result
|
|
291
|
+
end
|
|
292
|
+
|
|
249
293
|
# Is the waybill blocked by something that won't resolve by waiting?
|
|
250
294
|
# CI failure, merge conflict, policy block — the courier should take
|
|
251
295
|
# the parcel back immediately.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# The warehouse's vault concern.
|
|
2
|
+
# The vault is local main — where accepted parcels live.
|
|
3
|
+
# In local-centred workstyle, the vault is the source of truth.
|
|
4
|
+
# In remote-centred workstyle, the vault is the backup (receives
|
|
5
|
+
# the standard from the bureau's registry after acceptance).
|
|
6
|
+
require "open3"
|
|
7
|
+
|
|
8
|
+
module Carson
|
|
9
|
+
class Warehouse
|
|
10
|
+
module Vault
|
|
11
|
+
|
|
12
|
+
# Accept a parcel into the vault.
|
|
13
|
+
# Fast-forwards local main to include the parcel's branch.
|
|
14
|
+
# Runs from the main worktree root where main is checked out.
|
|
15
|
+
#
|
|
16
|
+
# Precondition: the parcel's branch must be a fast-forward of main.
|
|
17
|
+
# If not, the agent must rebase first.
|
|
18
|
+
#
|
|
19
|
+
# Returns a result hash:
|
|
20
|
+
# { status: "ok", branch: ..., head: ... }
|
|
21
|
+
# { status: "block", error: ..., recovery: ... }
|
|
22
|
+
# { status: "error", error: ..., recovery: ... }
|
|
23
|
+
def accept!( parcel )
|
|
24
|
+
root = main_worktree_root
|
|
25
|
+
|
|
26
|
+
# Verify main is checked out in the main worktree.
|
|
27
|
+
unless main_checked_out_at?( root )
|
|
28
|
+
return {
|
|
29
|
+
status: "error",
|
|
30
|
+
error: "#{@main_label} is not checked out in the main worktree.",
|
|
31
|
+
recovery: "Check the main worktree state at #{root}."
|
|
32
|
+
}
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Fast-forward main to include the parcel's branch.
|
|
36
|
+
_, stderr, status = Open3.capture3(
|
|
37
|
+
"git", "-C", root, "merge", "--ff-only", parcel.label
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
return vault_accepted( parcel, root ) if status.success?
|
|
41
|
+
|
|
42
|
+
vault_blocked( parcel, stderr )
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
# Check whether main is the checked-out branch at a given path.
|
|
48
|
+
def main_checked_out_at?( root )
|
|
49
|
+
head_ref, _, status = Open3.capture3(
|
|
50
|
+
"git", "-C", root, "rev-parse", "--abbrev-ref", "HEAD"
|
|
51
|
+
)
|
|
52
|
+
status.success? && head_ref.strip == @main_label
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Build the success result after vault acceptance.
|
|
56
|
+
def vault_accepted( parcel, root )
|
|
57
|
+
new_head, = Open3.capture3( "git", "-C", root, "rev-parse", "HEAD" )
|
|
58
|
+
{
|
|
59
|
+
status: "ok",
|
|
60
|
+
branch: parcel.label,
|
|
61
|
+
head: new_head.strip
|
|
62
|
+
}
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Build the blocked/error result when vault acceptance fails.
|
|
66
|
+
def vault_blocked( parcel, stderr )
|
|
67
|
+
{
|
|
68
|
+
status: "block",
|
|
69
|
+
error: "#{parcel.label} cannot be fast-forwarded into #{@main_label}.",
|
|
70
|
+
recovery: "Rebase onto #{@main_label} and deliver again."
|
|
71
|
+
}
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
data/lib/carson/warehouse.rb
CHANGED
|
@@ -6,6 +6,7 @@ require "fileutils"
|
|
|
6
6
|
require "open3"
|
|
7
7
|
|
|
8
8
|
require_relative "warehouse/workbench"
|
|
9
|
+
require_relative "warehouse/vault"
|
|
9
10
|
require_relative "warehouse/seal"
|
|
10
11
|
require_relative "warehouse/bureau"
|
|
11
12
|
|
|
@@ -16,6 +17,7 @@ module Carson
|
|
|
16
17
|
# managing workbenches, and sweeping up.
|
|
17
18
|
class Warehouse
|
|
18
19
|
include Workbench
|
|
20
|
+
include Vault
|
|
19
21
|
include Seal
|
|
20
22
|
include Bureau
|
|
21
23
|
|
|
@@ -140,6 +142,49 @@ module Carson
|
|
|
140
142
|
end
|
|
141
143
|
end
|
|
142
144
|
|
|
145
|
+
# --- Delivery prep ---
|
|
146
|
+
|
|
147
|
+
# Prepare a parcel for delivery.
|
|
148
|
+
# Orchestrates the prep phase: pack, fetch, standard check, auto-rebase.
|
|
149
|
+
# Returns { status: "ok" } or { status: "block"/"error", error:, recovery: }.
|
|
150
|
+
def prepare!( parcel, message: nil )
|
|
151
|
+
registry = "#{bureau_address}/#{main_label}"
|
|
152
|
+
|
|
153
|
+
# Pack if the agent provided a commit message.
|
|
154
|
+
if message
|
|
155
|
+
unless pack!( message: message )
|
|
156
|
+
return { status: "error", error: "Nothing to commit.", recovery: "Stage changes first." }
|
|
157
|
+
end
|
|
158
|
+
# Update the parcel's head after packing.
|
|
159
|
+
parcel = Parcel.new( label: parcel.label, head: current_head )
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# Fetch the latest standard.
|
|
163
|
+
unless fetch_latest
|
|
164
|
+
return {
|
|
165
|
+
status: "block",
|
|
166
|
+
error: "Cannot fetch latest standard.",
|
|
167
|
+
recovery: "Check network and remote config, then deliver again."
|
|
168
|
+
}
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# Check if the parcel is based on the latest standard.
|
|
172
|
+
unless based_on_latest_standard?( parcel, registry: registry )
|
|
173
|
+
# Auto-rebase onto the latest standard.
|
|
174
|
+
unless rebase_on_latest_standard!( registry: registry )
|
|
175
|
+
return {
|
|
176
|
+
status: "block",
|
|
177
|
+
error: "#{parcel.label} conflicts with #{@main_label}.",
|
|
178
|
+
recovery: "Rebase onto #{@main_label}, resolve conflicts, deliver again."
|
|
179
|
+
}
|
|
180
|
+
end
|
|
181
|
+
# Update the parcel's head after rebase.
|
|
182
|
+
parcel = Parcel.new( label: parcel.label, head: current_head )
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
{ status: "ok", parcel: parcel }
|
|
186
|
+
end
|
|
187
|
+
|
|
143
188
|
# --- Inventory ---
|
|
144
189
|
|
|
145
190
|
# All labels (branch names).
|
data/lib/cli.rb
CHANGED
|
@@ -1023,12 +1023,16 @@ module Carson
|
|
|
1023
1023
|
when "template:apply"
|
|
1024
1024
|
runtime.template_apply!( push_prep: parsed.fetch( :push_prep, false ) )
|
|
1025
1025
|
when "deliver"
|
|
1026
|
-
runtime.
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1026
|
+
if runtime.config.workstyle == :local
|
|
1027
|
+
dispatch_deliver_locally( parsed: parsed, runtime: runtime )
|
|
1028
|
+
else
|
|
1029
|
+
runtime.deliver!(
|
|
1030
|
+
title: parsed.fetch( :title, nil ),
|
|
1031
|
+
body_file: parsed.fetch( :body_file, nil ),
|
|
1032
|
+
commit_message: parsed.fetch( :commit_message, nil ),
|
|
1033
|
+
json_output: parsed.fetch( :json, false )
|
|
1034
|
+
)
|
|
1035
|
+
end
|
|
1032
1036
|
when "recover"
|
|
1033
1037
|
runtime.recover!(
|
|
1034
1038
|
check_name: parsed.fetch( :check_name ),
|
|
@@ -1081,6 +1085,81 @@ module Carson
|
|
|
1081
1085
|
report_workbench( result: result, json: parsed.fetch( :json, false ), output: runtime.output )
|
|
1082
1086
|
end
|
|
1083
1087
|
|
|
1088
|
+
# --- Local-centred delivery ---
|
|
1089
|
+
# CLI orchestrates: prepare → accept → courier.deliver.
|
|
1090
|
+
# No Runtime — follows the checkin/checkout pattern.
|
|
1091
|
+
|
|
1092
|
+
def self.dispatch_deliver_locally( parsed:, runtime: )
|
|
1093
|
+
# The warehouse must be at the current worktree (where the agent works),
|
|
1094
|
+
# not the main worktree root. The agent's branch and head live here.
|
|
1095
|
+
warehouse = Warehouse.new(
|
|
1096
|
+
path: runtime.send( :work_dir ),
|
|
1097
|
+
main_label: runtime.config.main_branch,
|
|
1098
|
+
bureau_address: runtime.config.git_remote
|
|
1099
|
+
)
|
|
1100
|
+
parcel = Parcel.new( label: warehouse.current_label, head: warehouse.current_head )
|
|
1101
|
+
message = parsed.fetch( :commit_message, nil )
|
|
1102
|
+
json = parsed.fetch( :json, false )
|
|
1103
|
+
output = runtime.output
|
|
1104
|
+
|
|
1105
|
+
# Step 1: Prepare.
|
|
1106
|
+
prep = warehouse.prepare!( parcel, message: message )
|
|
1107
|
+
unless prep[ :status ] == "ok"
|
|
1108
|
+
prep[ :command ] = "deliver"
|
|
1109
|
+
return report_deliver( result: prep, json: json, output: output )
|
|
1110
|
+
end
|
|
1111
|
+
|
|
1112
|
+
# Update parcel if prepare rebased or packed.
|
|
1113
|
+
parcel = prep[ :parcel ] || parcel
|
|
1114
|
+
|
|
1115
|
+
# Step 2: Accept into vault.
|
|
1116
|
+
accept = warehouse.accept!( parcel )
|
|
1117
|
+
accept[ :command ] = "deliver"
|
|
1118
|
+
unless accept[ :status ] == "ok"
|
|
1119
|
+
return report_deliver( result: accept, json: json, output: output )
|
|
1120
|
+
end
|
|
1121
|
+
|
|
1122
|
+
# Step 3: Courier delivers backup.
|
|
1123
|
+
courier = Courier.new( warehouse, workstyle: :local, output: output )
|
|
1124
|
+
backup = courier.deliver( parcel )
|
|
1125
|
+
|
|
1126
|
+
# Combine results.
|
|
1127
|
+
result = accept.merge( backup.slice( :outcome, :synced, :backup_error ) )
|
|
1128
|
+
result[ :command ] = "deliver"
|
|
1129
|
+
result[ :outcome ] ||= "delivered"
|
|
1130
|
+
report_deliver( result: result, json: json, output: output )
|
|
1131
|
+
end
|
|
1132
|
+
|
|
1133
|
+
# Render a local delivery result.
|
|
1134
|
+
def self.report_deliver( result:, json:, output: )
|
|
1135
|
+
status = result[ :status ]
|
|
1136
|
+
exit_code = case status
|
|
1137
|
+
when "ok" then Runtime::EXIT_OK
|
|
1138
|
+
when "block" then Runtime::EXIT_BLOCK
|
|
1139
|
+
else Runtime::EXIT_ERROR
|
|
1140
|
+
end
|
|
1141
|
+
|
|
1142
|
+
if json
|
|
1143
|
+
output.puts JSON.pretty_generate( result )
|
|
1144
|
+
else
|
|
1145
|
+
case status
|
|
1146
|
+
when "ok"
|
|
1147
|
+
output.puts "#{BADGE} #{result[ :branch ]} merged into main."
|
|
1148
|
+
if result[ :synced ]
|
|
1149
|
+
output.puts "#{BADGE} Pushed to #{result.fetch( :remote_main, "remote" )}."
|
|
1150
|
+
elsif result[ :backup_error ]
|
|
1151
|
+
output.puts "#{BADGE} Backup failed."
|
|
1152
|
+
output.puts " \u2192 git push"
|
|
1153
|
+
end
|
|
1154
|
+
when "block", "error"
|
|
1155
|
+
output.puts "#{BADGE} #{result[ :error ]}"
|
|
1156
|
+
output.puts " \u2192 #{result[ :recovery ]}" if result[ :recovery ]
|
|
1157
|
+
end
|
|
1158
|
+
end
|
|
1159
|
+
|
|
1160
|
+
exit_code
|
|
1161
|
+
end
|
|
1162
|
+
|
|
1084
1163
|
# Build a Warehouse rooted at the main worktree.
|
|
1085
1164
|
# Uses runtime's resolved root and config for remote/branch names.
|
|
1086
1165
|
def self.build_warehouse( runtime: )
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: carson
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.
|
|
4
|
+
version: 4.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Hailei Wang
|
|
@@ -84,6 +84,7 @@ files:
|
|
|
84
84
|
- lib/carson/warehouse.rb
|
|
85
85
|
- lib/carson/warehouse/bureau.rb
|
|
86
86
|
- lib/carson/warehouse/seal.rb
|
|
87
|
+
- lib/carson/warehouse/vault.rb
|
|
87
88
|
- lib/carson/warehouse/workbench.rb
|
|
88
89
|
- lib/carson/waybill.rb
|
|
89
90
|
- lib/carson/worktree.rb
|