f03421d19ef3

pin koh3 3.0.108 and prove a stolen repo's offer stops on a clash instead of choosing a side (v3.0.70)

time
2026-09-28 05:20 UTC · 2 weeks ago
machine
Junes-MacBook-Pro.local
agent
claude-opus-5-5
session
fix a2 review findings
parent
bb2b6cc5f7e2
3 files package.json+1 −1tests/koh-version.txt+1 −1tests/kohsteal.test.ts+22 −0
package.json+1 −1
@@ -1,6 +1,6 @@11 {22 	"name": "kepr",3-	"version": "3.0.69",3+	"version": "3.0.70",44 	"private": true,55 	"type": "module",66 	"scripts": {

view file

tests/koh-version.txt+1 −1
@@ -1 +1 @@1-3.0.981+3.0.108

view file

tests/kohsteal.test.ts+22 −0
@@ -237,6 +237,28 @@237237 				expect((await koh3(repoDir, ownerHome, ["steal"])).code).toBe(0);238238 				expect(await readFile(join(repoDir, "README.md"), "utf8")).toContain("The thief's edit");239239 240+				// The other clone still rides its source. When both sides changed the same file,241+				// offer without a terminal refuses as steal would, and never picks a side itself:242+				// the file is named, steal is where to choose, and the source stays.243+				const other = join(fresh, REPO);244+				await writeFile(join(repoDir, "README.md"), "# shipped\n\nThe owner's edit.\n");245+				expect((await koh3(repoDir, ownerHome, ["save", "owner edits the readme"])).code).toBe(0);246+				await writeFile(join(other, "README.md"), "# shipped\n\nThe other clone's edit.\n");247+				expect((await koh3(other, thiefHome, ["save", "other clone edits"])).code).toBe(0);248+				const clashed = await koh3(other, thiefHome, ["offer"]);249+				expect(clashed.code).toBe(1);250+				expect(clashed.err).toContain(251+					'README.md changed on both machines — run "koh steal" to choose, then offer',252+				);253+				expect(await readFile(join(other, "README.md"), "utf8")).toContain("other clone's edit");254+				expect((await koh3(other, thiefHome, ["remote"])).out).toContain(`${host}/${REPO}`);255+				// Choosing there upgrades the clone, and says where the version it gave up lives.256+				const chosen = await koh3(other, thiefHome, ["steal", "--theirs"]);257+				expect(chosen.code, chosen.err + chosen.out).toBe(0);258+				expect(chosen.out + chosen.err).toContain("now syncs with your bucket");259+				expect(chosen.out + chosen.err).toContain("your README.md is in");260+				expect(await readFile(join(other, "README.md"), "utf8")).toContain("The owner's edit");261+240262 				// A repo the public side never serves clones from the bucket once signed in.241263 				const second = join(root, "thief-two");242264 				await mkdir(second, { recursive: true });

view file