Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .claude/skills/sc-cli-reference/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,8 @@ cargo run --bin sc -- work --agents 3 [--name <base>] [--budget-mb <n>] -- <cmd>
bash demo/run_work_demo.sh # parallel-agents round-trip proof
cargo run --bin sc -- ws fork --agents N [--name <n>] [--identity <key>] [--author <a>] # durable multi-invocation
# (--agents default 2; --author is stored in the
# manifest, but harvest takes its own --author,
# then $SC_AUTHOR, then the OS user)
# manifest and is the harvest default; an explicit
# harvest --author wins)
# session: materializes N checkouts under
# .sc/ws/<i>/ and persists a manifest (P20).
# --name opens a further named session in
Expand Down
6 changes: 3 additions & 3 deletions crates/cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -832,8 +832,8 @@ enum WsOp {
/// on both sides (ciphertext-id fast paths need no identity at all).
#[arg(long)]
identity: Option<PathBuf>,
/// Author recorded on any landing commit (default $SC_AUTHOR, then
/// the OS username).
/// Author recorded on any landing commit (default: the author given to
/// `sc ws fork` for this session).
#[arg(long)]
author: Option<String>,
/// Attach this transcript file to each workspace's landed snapshot
Expand Down Expand Up @@ -3620,7 +3620,7 @@ fn run_ws(op: WsOp) -> Result<()> {
let outcomes = repo.ws_harvest(
session.as_deref(),
into.as_deref(),
&resolve_author(author),
author.as_deref(),
sk.as_ref(),
)?;

Expand Down
4 changes: 2 additions & 2 deletions crates/repo/src/file_dir_collision.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ fn ws_harvest_refuses_a_directory_over_an_absent_protected_file() {
let dir = s.workspaces[0].dir.clone();
assert!(!dir.join("secret").exists());
put(&dir, "secret/agent.txt", "agent\n");
let err = repo.ws_harvest(None, None, "t", None).unwrap_err();
let err = repo.ws_harvest(None, None, Some("t"), None).unwrap_err();
assert_collision(&err, "secret", "secret/agent.txt");
assert_eq!(repo.head_tip().unwrap(), Some(c1), "no ref moved");
assert!(
Expand All @@ -184,7 +184,7 @@ fn ws_harvest_refuses_a_directory_over_an_absent_protected_file() {
// The session is still open: removing the directory lets it harvest.
std::fs::remove_dir_all(dir.join("secret")).unwrap();
put(&dir, "other.txt", "ok\n");
let out = repo.ws_harvest(None, None, "t", None).unwrap();
let out = repo.ws_harvest(None, None, Some("t"), None).unwrap();
assert_eq!(out.len(), 1);
cleanup(repo, &root);
}
Expand Down
18 changes: 11 additions & 7 deletions crates/repo/src/partial_sessions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ fn harvest_lands_a_clean_merge_and_carries_the_out_of_view_subtrees() {
std::fs::write(fx.clone_root.join("src/a.txt"), SRC_LAST).unwrap();
let host_tip = clone.commit("t", "host edit").unwrap();

let outcomes = clone.ws_harvest(None, None, "t", None).unwrap();
let outcomes = clone.ws_harvest(None, None, Some("t"), None).unwrap();
let merged = match outcomes.as_slice() {
[WsHarvestOutcome::Landed { merged_tip, .. }] => *merged_tip,
other => panic!("expected a clean landing, got {other:?}"),
Expand Down Expand Up @@ -82,7 +82,7 @@ fn harvest_conflict_falls_back_to_a_branch() {
std::fs::write(fx.clone_root.join("src/a.txt"), b"uno\ntwo\nthree\n").unwrap();
let host_tip = clone.commit("t", "host edit").unwrap();

let outcomes = clone.ws_harvest(None, None, "t", None).unwrap();
let outcomes = clone.ws_harvest(None, None, Some("t"), None).unwrap();
match outcomes.as_slice() {
[WsHarvestOutcome::FallbackBranch { branch, .. }] => {
assert_eq!(branch, "work-1");
Expand Down Expand Up @@ -125,7 +125,7 @@ fn two_named_sessions_land_independently_under_the_view() {
std::fs::write(b.workspaces[0].dir.join("src/a.txt"), SRC_LAST).unwrap();

let first = match clone
.ws_harvest(Some("a"), None, "t", None)
.ws_harvest(Some("a"), None, Some("t"), None)
.unwrap()
.as_slice()
{
Expand All @@ -137,7 +137,7 @@ fn two_named_sessions_land_independently_under_the_view() {
"b is still open"
);
let merged = match clone
.ws_harvest(Some("b"), None, "t", None)
.ws_harvest(Some("b"), None, Some("t"), None)
.unwrap()
.as_slice()
{
Expand All @@ -162,7 +162,7 @@ fn harvest_of_an_untouched_workspace_is_unchanged() {
let fx = Fx::origin("ws-unchanged", |_| {});
let clone = fx.clone(false);
clone.ws_fork(None, 1, "t", None).unwrap();
let outcomes = clone.ws_harvest(None, None, "t", None).unwrap();
let outcomes = clone.ws_harvest(None, None, Some("t"), None).unwrap();
assert!(matches!(
outcomes.as_slice(),
[WsHarvestOutcome::Unchanged { .. }]
Expand Down Expand Up @@ -290,7 +290,7 @@ fn a_failing_probe_leaves_no_candidate_branch() {
Some(b1)
);

let err = clone.ws_harvest(None, None, "t", None).unwrap_err();
let err = clone.ws_harvest(None, None, Some("t"), None).unwrap_err();
eprintln!("probe error: {err:?}");
assert!(
refs::read_branch_tip(clone.layout(), "work-1")
Expand Down Expand Up @@ -349,7 +349,11 @@ fn refresh_moves_a_workspace_without_reading_the_rest() {
assert!(!dir.join("docs").exists(), "docs is outside the view");
assert!(!has(&clone, &new_docs), "and was never read or fetched");

let merged = match clone.ws_harvest(None, None, "t", None).unwrap().as_slice() {
let merged = match clone
.ws_harvest(None, None, Some("t"), None)
.unwrap()
.as_slice()
{
[WsHarvestOutcome::Landed { merged_tip, .. }] => *merged_tip,
other => panic!("expected a landing, got {other:?}"),
};
Expand Down
4 changes: 2 additions & 2 deletions crates/repo/src/partial_size.rs
Original file line number Diff line number Diff line change
Expand Up @@ -908,7 +908,7 @@ fn workspace_session_on_a_size_limited_clone_lands() {
)
.unwrap();
clone.commit("t", "host edit").unwrap();
let outcomes = clone.ws_harvest(name, None, "t", None).unwrap();
let outcomes = clone.ws_harvest(name, None, Some("t"), None).unwrap();
assert!(
matches!(outcomes.as_slice(), [WsHarvestOutcome::Landed { .. }]),
"got {outcomes:?}"
Expand Down Expand Up @@ -1097,7 +1097,7 @@ fn named_sessions_on_a_size_limited_clone() {
)
.unwrap();
for name in ["a", "b"] {
let out = clone.ws_harvest(Some(name), None, "t", None).unwrap();
let out = clone.ws_harvest(Some(name), None, Some("t"), None).unwrap();
assert!(
matches!(out.as_slice(), [WsHarvestOutcome::Landed { .. }]),
"{name}: {out:?}"
Expand Down
Loading
Loading