@snappedly-tools/shipyard 0.7.0-staging.36082887921 → 0.7.0-staging.36121841659
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/README.md +7 -3
- package/dist/main.js +133 -13
- package/dist/main.js.map +1 -1
- package/dist/templates/parallel-planner/main.mts +11 -7
- package/dist/templates/parallel-planner/setup.sh +1 -0
- package/dist/templates/parallel-planner-with-review/main.mts +11 -7
- package/dist/templates/parallel-planner-with-review/setup.sh +1 -0
- package/dist/templates/sequential-reviewer/main.mts +7 -3
- package/dist/templates/sequential-reviewer/setup.sh +1 -0
- package/dist/templates/shared/setup.sh +1 -0
- package/dist/templates/simple-loop/main.mts +7 -3
- package/dist/templates/simple-loop/setup.sh +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -41,7 +41,11 @@ npx shipyard init
|
|
|
41
41
|
|
|
42
42
|
During `shipyard init`, choose your agent, **Docker**, the template you want, and install the optional
|
|
43
43
|
[repository runner](docs/content/docs/repository-runner.mdx). Follow
|
|
44
|
-
the authentication prompts.
|
|
44
|
+
the authentication prompts. Init offers to commit and push the generated
|
|
45
|
+
Shipyard setup to the current branch. The offer stages `.shipyard/` and, when
|
|
46
|
+
installed, `.github/workflows/shipyard-wake.yml`. It leaves `.shipyard/.env`
|
|
47
|
+
untracked. Non-interactive init skips the offer; pass `--commit-setup true` to
|
|
48
|
+
commit and push the generated files.
|
|
45
49
|
|
|
46
50
|
On a local Mac, the repository runner automatically wakes Shipyard when you label an issue.
|
|
47
51
|
It runs as long as its terminal stays open.
|
|
@@ -60,8 +64,8 @@ conflict resolution, and integration. The review-enabled planner also uses
|
|
|
60
64
|
strong for ticket and final specification reviews. See
|
|
61
65
|
[agent setup](docs/content/docs/agents.mdx).
|
|
62
66
|
|
|
63
|
-
|
|
64
|
-
`.shipyard/.env`
|
|
67
|
+
If you decline the commit, commit `.shipyard/` before running Shipyard. Docker
|
|
68
|
+
sandboxes read setup files from Git history. Keep `.shipyard/.env` untracked.
|
|
65
69
|
|
|
66
70
|
```sh
|
|
67
71
|
npx shipyard run
|
package/dist/main.js
CHANGED
|
@@ -271,8 +271,7 @@ var ISSUE_TRACKER_REGISTRY = [
|
|
|
271
271
|
# Required repository permissions: Contents, Issues, and Pull requests (Read and write); Metadata (Read)
|
|
272
272
|
# Or leave blank and run: GH_TOKEN="$(gh auth token)" npx shipyard run
|
|
273
273
|
GH_TOKEN=
|
|
274
|
-
|
|
275
|
-
GH_REPO=`
|
|
274
|
+
`
|
|
276
275
|
}
|
|
277
276
|
];
|
|
278
277
|
var listIssueTrackers = () => ISSUE_TRACKER_REGISTRY;
|
|
@@ -358,8 +357,8 @@ var rewriteMainTs = (configDir, agent, model, modelExplicit, sandboxProvider, ma
|
|
|
358
357
|
}
|
|
359
358
|
if (agent.name === "codex" && codexAuth === "chatgpt") {
|
|
360
359
|
content = content.replace(
|
|
361
|
-
|
|
362
|
-
`
|
|
360
|
+
"const sandboxAuthOptions = {};",
|
|
361
|
+
`const sandboxAuthOptions = ${CODEX_CHATGPT_AUTH_OPTIONS};`
|
|
363
362
|
);
|
|
364
363
|
}
|
|
365
364
|
content = content.replace(/\bdocker\b/g, sandboxProvider.name);
|
|
@@ -1293,12 +1292,57 @@ var initializeRepositoryRunner = async (options) => {
|
|
|
1293
1292
|
}
|
|
1294
1293
|
};
|
|
1295
1294
|
var repositoryRunnerNextSteps = () => [
|
|
1296
|
-
`
|
|
1295
|
+
`Ensure ${REPOSITORY_RUNNER_WORKFLOW_PATH} is committed and pushed to the repository's default branch`,
|
|
1297
1296
|
`Keep the foreground controller open with \`npx ${CLI_NAME} runner start\``,
|
|
1298
1297
|
`Inspect it from another terminal with \`npx ${CLI_NAME} runner status\``,
|
|
1299
1298
|
`Stop it with \`npx ${CLI_NAME} runner stop\``,
|
|
1300
1299
|
`Unregister and delete its protected files with \`npx ${CLI_NAME} runner remove\``
|
|
1301
1300
|
];
|
|
1301
|
+
var errorText = (error) => {
|
|
1302
|
+
if (error !== null && typeof error === "object" && "stderr" in error) {
|
|
1303
|
+
const stderr = error.stderr;
|
|
1304
|
+
if (typeof stderr === "string" || Buffer.isBuffer(stderr)) {
|
|
1305
|
+
const text = stderr.toString().trim();
|
|
1306
|
+
if (text) return text;
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
return error instanceof Error ? error.message : String(error);
|
|
1310
|
+
};
|
|
1311
|
+
var commitAndPushInitSetup = (repoDir) => {
|
|
1312
|
+
const branch = execFileSync("git", ["branch", "--show-current"], {
|
|
1313
|
+
cwd: repoDir,
|
|
1314
|
+
encoding: "utf8"
|
|
1315
|
+
}).trim();
|
|
1316
|
+
if (!branch) {
|
|
1317
|
+
throw new Error("Cannot push the Shipyard setup from a detached HEAD.");
|
|
1318
|
+
}
|
|
1319
|
+
const paths = [CONFIG_DIR];
|
|
1320
|
+
if (existsSync(join(repoDir, REPOSITORY_RUNNER_WORKFLOW_PATH))) {
|
|
1321
|
+
paths.push(REPOSITORY_RUNNER_WORKFLOW_PATH);
|
|
1322
|
+
}
|
|
1323
|
+
execFileSync("git", ["add", "--", ...paths], {
|
|
1324
|
+
cwd: repoDir,
|
|
1325
|
+
stdio: "ignore"
|
|
1326
|
+
});
|
|
1327
|
+
execFileSync(
|
|
1328
|
+
"git",
|
|
1329
|
+
["commit", "--only", "-m", "Add Shipyard setup", "--", ...paths],
|
|
1330
|
+
{ cwd: repoDir, stdio: "pipe" }
|
|
1331
|
+
);
|
|
1332
|
+
const commit = execFileSync("git", ["rev-parse", "--short", "HEAD"], {
|
|
1333
|
+
cwd: repoDir,
|
|
1334
|
+
encoding: "utf8"
|
|
1335
|
+
}).trim();
|
|
1336
|
+
try {
|
|
1337
|
+
execFileSync("git", ["push", "origin", `HEAD:refs/heads/${branch}`], {
|
|
1338
|
+
cwd: repoDir,
|
|
1339
|
+
stdio: "pipe"
|
|
1340
|
+
});
|
|
1341
|
+
return { branch, commit };
|
|
1342
|
+
} catch (error) {
|
|
1343
|
+
return { branch, commit, pushError: errorText(error) };
|
|
1344
|
+
}
|
|
1345
|
+
};
|
|
1302
1346
|
var execFileAsync2 = promisify(execFile);
|
|
1303
1347
|
var CONTROLLER_STATE = ".shipyard-state.json";
|
|
1304
1348
|
var LAST_FAILURE = ".shipyard-last-failure.json";
|
|
@@ -2367,7 +2411,7 @@ var runnerCommand = Command.make(
|
|
|
2367
2411
|
purgeRunnerCommand
|
|
2368
2412
|
])
|
|
2369
2413
|
);
|
|
2370
|
-
var VERSION = "0.7.0-staging.
|
|
2414
|
+
var VERSION = "0.7.0-staging.36121841659" ;
|
|
2371
2415
|
|
|
2372
2416
|
// src/cli.ts
|
|
2373
2417
|
var imageNameOption = Options.text("image-name").pipe(
|
|
@@ -2588,6 +2632,11 @@ var installRunnerOption = Options.choice("install-runner", [
|
|
|
2588
2632
|
),
|
|
2589
2633
|
Options.optional
|
|
2590
2634
|
);
|
|
2635
|
+
var commitSetupOption = Options.choice("commit-setup", ["true", "false"]).pipe(
|
|
2636
|
+
Options.withDescription(
|
|
2637
|
+
"Whether to commit and push .shipyard/ and the optional runner workflow"
|
|
2638
|
+
)
|
|
2639
|
+
).pipe(Options.optional);
|
|
2591
2640
|
var choiceToTriBool = (opt) => opt._tag === "Some" ? Option.some(opt.value === "true") : Option.none();
|
|
2592
2641
|
var initCommand = Command.make(
|
|
2593
2642
|
"init",
|
|
@@ -2601,7 +2650,8 @@ var initCommand = Command.make(
|
|
|
2601
2650
|
issueTracker: issueTrackerOption,
|
|
2602
2651
|
buildImage: buildImageOption,
|
|
2603
2652
|
installTemplateDeps: installTemplateDepsOption,
|
|
2604
|
-
installRunner: installRunnerOption
|
|
2653
|
+
installRunner: installRunnerOption,
|
|
2654
|
+
commitSetup: commitSetupOption
|
|
2605
2655
|
},
|
|
2606
2656
|
({
|
|
2607
2657
|
imageName: imageNameFlag,
|
|
@@ -2613,7 +2663,8 @@ var initCommand = Command.make(
|
|
|
2613
2663
|
issueTracker: issueTrackerFlag,
|
|
2614
2664
|
buildImage: buildImageFlag,
|
|
2615
2665
|
installTemplateDeps: installTemplateDepsFlag,
|
|
2616
|
-
installRunner: installRunnerFlag
|
|
2666
|
+
installRunner: installRunnerFlag,
|
|
2667
|
+
commitSetup: commitSetupFlag
|
|
2617
2668
|
}) => Effect.gen(function* () {
|
|
2618
2669
|
const d = yield* Display;
|
|
2619
2670
|
const cwd = process.cwd();
|
|
@@ -2657,6 +2708,7 @@ var initCommand = Command.make(
|
|
|
2657
2708
|
installTemplateDepsFlag
|
|
2658
2709
|
);
|
|
2659
2710
|
const installRunnerChoice = choiceToTriBool(installRunnerFlag);
|
|
2711
|
+
const commitSetupChoice = choiceToTriBool(commitSetupFlag);
|
|
2660
2712
|
const isInteractive = process.stdin.isTTY === true;
|
|
2661
2713
|
const failIfNonInteractive = (flag) => Effect.fail(
|
|
2662
2714
|
new InitError({
|
|
@@ -2966,15 +3018,12 @@ var initCommand = Command.make(
|
|
|
2966
3018
|
message: `Repository-runner setup failed: ${error instanceof Error ? error.message : String(error)}`
|
|
2967
3019
|
})
|
|
2968
3020
|
});
|
|
2969
|
-
|
|
3021
|
+
const runnerInstalled = runnerInit.status === "installed";
|
|
3022
|
+
if (runnerInstalled) {
|
|
2970
3023
|
yield* d.status(
|
|
2971
3024
|
`Installed ${runnerInit.result.name} for ${runnerInit.result.repository}.`,
|
|
2972
3025
|
"success"
|
|
2973
3026
|
);
|
|
2974
|
-
yield* d.text("Repository runner next steps:");
|
|
2975
|
-
for (const [index, line] of repositoryRunnerNextSteps().entries()) {
|
|
2976
|
-
yield* d.text(styleText("dim", `${index + 1}. ${line}`));
|
|
2977
|
-
}
|
|
2978
3027
|
} else if (runnerInit.status === "failed") {
|
|
2979
3028
|
yield* d.status(
|
|
2980
3029
|
`Shipyard scaffolding is ready, but repository runner installation failed: ${runnerInit.message}`,
|
|
@@ -2985,6 +3034,77 @@ var initCommand = Command.make(
|
|
|
2985
3034
|
"warn"
|
|
2986
3035
|
);
|
|
2987
3036
|
}
|
|
3037
|
+
let shouldCommitSetup = commitSetupChoice._tag === "Some" && commitSetupChoice.value;
|
|
3038
|
+
if (commitSetupChoice._tag === "None" && isInteractive) {
|
|
3039
|
+
const confirmed = yield* Effect.promise(
|
|
3040
|
+
() => clack2.confirm({
|
|
3041
|
+
message: "Commit .shipyard/ and the optional runner workflow, then push this branch to origin? Sandboxes need the setup committed. The push also sends any local commits not already on origin.",
|
|
3042
|
+
initialValue: true
|
|
3043
|
+
})
|
|
3044
|
+
);
|
|
3045
|
+
if (clack2.isCancel(confirmed)) {
|
|
3046
|
+
yield* Effect.fail(
|
|
3047
|
+
new InitError({ message: "Shipyard setup commit cancelled." })
|
|
3048
|
+
);
|
|
3049
|
+
}
|
|
3050
|
+
shouldCommitSetup = confirmed === true;
|
|
3051
|
+
}
|
|
3052
|
+
if (shouldCommitSetup) {
|
|
3053
|
+
const publishResult = yield* Effect.sync(() => {
|
|
3054
|
+
try {
|
|
3055
|
+
return {
|
|
3056
|
+
status: "committed",
|
|
3057
|
+
result: commitAndPushInitSetup(cwd)
|
|
3058
|
+
};
|
|
3059
|
+
} catch (error) {
|
|
3060
|
+
return {
|
|
3061
|
+
status: "failed",
|
|
3062
|
+
message: error instanceof Error ? error.message : String(error)
|
|
3063
|
+
};
|
|
3064
|
+
}
|
|
3065
|
+
});
|
|
3066
|
+
if (publishResult.status === "failed") {
|
|
3067
|
+
yield* d.status(
|
|
3068
|
+
`Could not commit the Shipyard setup: ${publishResult.message}`,
|
|
3069
|
+
"warn"
|
|
3070
|
+
);
|
|
3071
|
+
yield* d.status(
|
|
3072
|
+
`Commit \`${CONFIG_DIR}/\` before running Shipyard.`,
|
|
3073
|
+
"warn"
|
|
3074
|
+
);
|
|
3075
|
+
} else if (publishResult.result.pushError) {
|
|
3076
|
+
yield* d.status(
|
|
3077
|
+
`Committed ${publishResult.result.commit}, but could not push to origin/${publishResult.result.branch}: ${publishResult.result.pushError}`,
|
|
3078
|
+
"warn"
|
|
3079
|
+
);
|
|
3080
|
+
yield* d.status(
|
|
3081
|
+
`Push it later with \`git push origin ${publishResult.result.branch}\`.`,
|
|
3082
|
+
"warn"
|
|
3083
|
+
);
|
|
3084
|
+
} else {
|
|
3085
|
+
yield* d.status(
|
|
3086
|
+
`Committed ${publishResult.result.commit} and pushed origin/${publishResult.result.branch}.`,
|
|
3087
|
+
"success"
|
|
3088
|
+
);
|
|
3089
|
+
}
|
|
3090
|
+
} else {
|
|
3091
|
+
yield* d.status(
|
|
3092
|
+
`Commit \`${CONFIG_DIR}/\` before running Shipyard. Sandboxes do not receive uncommitted setup files.`,
|
|
3093
|
+
"warn"
|
|
3094
|
+
);
|
|
3095
|
+
if (runnerInstalled) {
|
|
3096
|
+
yield* d.status(
|
|
3097
|
+
"Push the runner wake workflow to the repository's default branch before starting the runner.",
|
|
3098
|
+
"warn"
|
|
3099
|
+
);
|
|
3100
|
+
}
|
|
3101
|
+
}
|
|
3102
|
+
if (runnerInstalled) {
|
|
3103
|
+
yield* d.text("Repository runner next steps:");
|
|
3104
|
+
for (const [index, line] of repositoryRunnerNextSteps().entries()) {
|
|
3105
|
+
yield* d.text(styleText("dim", `${index + 1}. ${line}`));
|
|
3106
|
+
}
|
|
3107
|
+
}
|
|
2988
3108
|
yield* d.status("Init complete!", "success");
|
|
2989
3109
|
const nextSteps = getNextStepsLines();
|
|
2990
3110
|
for (const [i, line] of nextSteps.entries()) {
|