opencara 0.101.0 → 0.102.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.
- package/dist/bin.js +97 -3
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -492,7 +492,7 @@ var AgentCallParser = class {
|
|
|
492
492
|
};
|
|
493
493
|
|
|
494
494
|
// src/commands/run.ts
|
|
495
|
-
var PKG_VERSION = "0.
|
|
495
|
+
var PKG_VERSION = "0.102.0";
|
|
496
496
|
var LOG_FLUSH_MS = 800;
|
|
497
497
|
var MAX_CHUNK_SIZE = 4 * 1024;
|
|
498
498
|
async function run(opts = {}) {
|
|
@@ -688,6 +688,97 @@ async function logout() {
|
|
|
688
688
|
console.log("Removed local credentials.");
|
|
689
689
|
}
|
|
690
690
|
|
|
691
|
+
// src/commands/internal.ts
|
|
692
|
+
import { execFileSync } from "node:child_process";
|
|
693
|
+
import { mkdtempSync, rmSync, existsSync as existsSync2, realpathSync } from "node:fs";
|
|
694
|
+
import { tmpdir } from "node:os";
|
|
695
|
+
import { join as join2, sep } from "node:path";
|
|
696
|
+
async function internal(argv) {
|
|
697
|
+
const sub = argv[0];
|
|
698
|
+
const rest = argv.slice(1);
|
|
699
|
+
if (sub === "worktree") {
|
|
700
|
+
const op = rest[0];
|
|
701
|
+
const opArgs = rest.slice(1);
|
|
702
|
+
if (op === "create") return worktreeCreate(opArgs);
|
|
703
|
+
if (op === "remove") return worktreeRemove(opArgs);
|
|
704
|
+
fail(`unknown worktree op: ${op ?? "(none)"}`);
|
|
705
|
+
}
|
|
706
|
+
fail(`unknown internal subcommand: ${sub ?? "(none)"}`);
|
|
707
|
+
}
|
|
708
|
+
function worktreeCreate(args) {
|
|
709
|
+
const repo = pickFlag(args, "--repo");
|
|
710
|
+
const branch = pickFlag(args, "--branch");
|
|
711
|
+
const fromRaw = pickFlag(args, "--from-branch") ?? "";
|
|
712
|
+
const fromBranch = fromRaw.length > 0 ? fromRaw : null;
|
|
713
|
+
if (!repo || !branch) {
|
|
714
|
+
fail("worktree create requires --repo OWNER/NAME and --branch <name>");
|
|
715
|
+
}
|
|
716
|
+
if (!/^[\w.-]+\/[\w.-]+$/.test(repo)) {
|
|
717
|
+
fail(`invalid --repo '${repo}' (expected OWNER/NAME)`);
|
|
718
|
+
}
|
|
719
|
+
const token = process.env["GH_TOKEN"];
|
|
720
|
+
if (!token) {
|
|
721
|
+
fail("worktree create needs GH_TOKEN in env (the orchestrator injects this per run)");
|
|
722
|
+
}
|
|
723
|
+
if (!/^[\w-]+$/.test(token)) {
|
|
724
|
+
fail("GH_TOKEN contains unexpected characters; refusing to use");
|
|
725
|
+
}
|
|
726
|
+
const dir = mkdtempSync(join2(tmpdir(), "opencara-wt-"));
|
|
727
|
+
const HELPER_SNIPPET = '!f() { echo username=x-access-token; echo "password=$GH_TOKEN"; }; f';
|
|
728
|
+
const cleanUrl = `https://github.com/${repo}.git`;
|
|
729
|
+
const cloneArgs = ["-c", `credential.helper=${HELPER_SNIPPET}`, "clone", "--depth=1"];
|
|
730
|
+
if (fromBranch) {
|
|
731
|
+
cloneArgs.push("--branch", fromBranch);
|
|
732
|
+
}
|
|
733
|
+
cloneArgs.push(cleanUrl, ".");
|
|
734
|
+
try {
|
|
735
|
+
git(dir, cloneArgs);
|
|
736
|
+
git(dir, ["checkout", "-b", branch]);
|
|
737
|
+
git(dir, ["config", "credential.helper", HELPER_SNIPPET]);
|
|
738
|
+
} catch (err) {
|
|
739
|
+
try {
|
|
740
|
+
rmSync(dir, { recursive: true, force: true });
|
|
741
|
+
} catch {
|
|
742
|
+
}
|
|
743
|
+
throw err;
|
|
744
|
+
}
|
|
745
|
+
process.stdout.write(`${JSON.stringify({ workdir: dir, branch })}
|
|
746
|
+
`);
|
|
747
|
+
}
|
|
748
|
+
function worktreeRemove(args) {
|
|
749
|
+
const workdir = pickFlag(args, "--workdir");
|
|
750
|
+
if (!workdir) {
|
|
751
|
+
fail("worktree remove requires --workdir <path>");
|
|
752
|
+
}
|
|
753
|
+
if (!existsSync2(workdir)) {
|
|
754
|
+
return;
|
|
755
|
+
}
|
|
756
|
+
const tmp = realpathSync(tmpdir());
|
|
757
|
+
let resolved;
|
|
758
|
+
try {
|
|
759
|
+
resolved = realpathSync(workdir);
|
|
760
|
+
} catch (err) {
|
|
761
|
+
if (err.code === "ENOENT") return;
|
|
762
|
+
fail(`worktree remove: cannot resolve ${workdir}: ${err.message}`);
|
|
763
|
+
}
|
|
764
|
+
if (resolved !== tmp && !resolved.startsWith(tmp + sep)) {
|
|
765
|
+
fail(`worktree remove: refuses to remove ${resolved} (not under ${tmp})`);
|
|
766
|
+
}
|
|
767
|
+
rmSync(resolved, { recursive: true, force: true });
|
|
768
|
+
}
|
|
769
|
+
function git(cwd, args) {
|
|
770
|
+
execFileSync("git", args, { cwd, stdio: ["ignore", "ignore", "inherit"] });
|
|
771
|
+
}
|
|
772
|
+
function pickFlag(argv, name) {
|
|
773
|
+
const i = argv.indexOf(name);
|
|
774
|
+
if (i === -1) return void 0;
|
|
775
|
+
return argv[i + 1];
|
|
776
|
+
}
|
|
777
|
+
function fail(msg) {
|
|
778
|
+
console.error(msg);
|
|
779
|
+
process.exit(1);
|
|
780
|
+
}
|
|
781
|
+
|
|
691
782
|
// src/bin.ts
|
|
692
783
|
async function main() {
|
|
693
784
|
const argv = process.argv.slice(2);
|
|
@@ -701,6 +792,9 @@ async function main() {
|
|
|
701
792
|
case "logout":
|
|
702
793
|
await logout();
|
|
703
794
|
return;
|
|
795
|
+
case "internal":
|
|
796
|
+
await internal(argv.slice(1));
|
|
797
|
+
return;
|
|
704
798
|
case "--help":
|
|
705
799
|
case "-h":
|
|
706
800
|
printHelp();
|
|
@@ -714,10 +808,10 @@ async function main() {
|
|
|
714
808
|
}
|
|
715
809
|
await run({
|
|
716
810
|
forcePair: argv.includes("--force-pair"),
|
|
717
|
-
url:
|
|
811
|
+
url: pickFlag2(argv, "--url")
|
|
718
812
|
});
|
|
719
813
|
}
|
|
720
|
-
function
|
|
814
|
+
function pickFlag2(argv, name) {
|
|
721
815
|
const i = argv.indexOf(name);
|
|
722
816
|
if (i === -1) return void 0;
|
|
723
817
|
return argv[i + 1];
|