@snappedly-tools/shipyard 0.5.0 → 0.6.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/README.md +56 -8
- package/dist/index.js +27 -9
- package/dist/index.js.map +1 -1
- package/dist/main.js +51 -15
- package/dist/main.js.map +1 -1
- package/dist/templates/parallel-planner/block-scope.sh +160 -0
- package/dist/templates/parallel-planner/conflict-prompt.md +22 -0
- package/dist/templates/parallel-planner/handoff.sh +175 -0
- package/dist/templates/parallel-planner/implement-prompt.md +10 -56
- package/dist/templates/parallel-planner/main.mts +434 -188
- package/dist/templates/parallel-planner/merge-prompt.md +9 -21
- package/dist/templates/parallel-planner/plan-prompt.md +5 -31
- package/dist/templates/parallel-planner/select-issues.mjs +788 -0
- package/dist/templates/parallel-planner/setup.sh +51 -0
- package/dist/templates/parallel-planner/spec-wave-prompt.md +16 -0
- package/dist/templates/parallel-planner/template.json +1 -1
- package/dist/templates/parallel-planner/triage-prompt.md +5 -0
- package/dist/templates/parallel-planner/verify-triage.sh +19 -0
- package/dist/templates/parallel-planner-with-review/block-scope.sh +160 -0
- package/dist/templates/parallel-planner-with-review/conflict-prompt.md +22 -0
- package/dist/templates/parallel-planner-with-review/handoff.sh +175 -0
- package/dist/templates/parallel-planner-with-review/implement-prompt.md +10 -56
- package/dist/templates/parallel-planner-with-review/main.mts +473 -205
- package/dist/templates/parallel-planner-with-review/merge-prompt.md +9 -21
- package/dist/templates/parallel-planner-with-review/plan-prompt.md +5 -31
- package/dist/templates/parallel-planner-with-review/review-prompt.md +11 -49
- package/dist/templates/parallel-planner-with-review/select-issues.mjs +788 -0
- package/dist/templates/parallel-planner-with-review/setup.sh +51 -0
- package/dist/templates/parallel-planner-with-review/spec-wave-prompt.md +16 -0
- package/dist/templates/parallel-planner-with-review/template.json +1 -1
- package/dist/templates/parallel-planner-with-review/triage-prompt.md +5 -0
- package/dist/templates/parallel-planner-with-review/verify-triage.sh +19 -0
- package/dist/templates/sequential-reviewer/block-scope.sh +160 -0
- package/dist/templates/sequential-reviewer/handoff.sh +175 -0
- package/dist/templates/sequential-reviewer/implement-prompt.md +12 -46
- package/dist/templates/sequential-reviewer/main.mts +199 -103
- package/dist/templates/sequential-reviewer/review-prompt.md +11 -49
- package/dist/templates/sequential-reviewer/select-issues.mjs +788 -0
- package/dist/templates/sequential-reviewer/setup.sh +51 -0
- package/dist/templates/sequential-reviewer/template.json +1 -1
- package/dist/templates/sequential-reviewer/triage-prompt.md +5 -0
- package/dist/templates/sequential-reviewer/verify-triage.sh +19 -0
- package/dist/templates/shared/block-scope.sh +160 -0
- package/dist/templates/shared/handoff.sh +175 -0
- package/dist/templates/shared/select-issues.mjs +788 -0
- package/dist/templates/shared/setup.sh +51 -0
- package/dist/templates/shared/triage-prompt.md +5 -0
- package/dist/templates/shared/verify-triage.sh +19 -0
- package/dist/templates/simple-loop/block-scope.sh +160 -0
- package/dist/templates/simple-loop/handoff.sh +175 -0
- package/dist/templates/simple-loop/main.mts +190 -45
- package/dist/templates/simple-loop/prompt.md +12 -46
- package/dist/templates/simple-loop/select-issues.mjs +788 -0
- package/dist/templates/simple-loop/setup.sh +51 -0
- package/dist/templates/simple-loop/template.json +1 -1
- package/dist/templates/simple-loop/triage-prompt.md +5 -0
- package/dist/templates/simple-loop/verify-triage.sh +19 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -29,6 +29,9 @@ plane around the agent:
|
|
|
29
29
|
|
|
30
30
|
## Install and run
|
|
31
31
|
|
|
32
|
+
Before running Shipyard, install the [Snappedly skills](https://github.com/snappedly/skills)
|
|
33
|
+
and run `setup-snapedly-skills` in the target repository.
|
|
34
|
+
|
|
32
35
|
Requirements: Node.js 20.18.1+, Git, Docker, and credentials for your chosen
|
|
33
36
|
agent. Run these commands in the repository Shipyard should change:
|
|
34
37
|
|
|
@@ -61,13 +64,13 @@ the [agent guide](docs/content/docs/agents.mdx) for authentication details.
|
|
|
61
64
|
|
|
62
65
|
## Pick the workflow you need
|
|
63
66
|
|
|
64
|
-
| Template | Best for | Built-in flow
|
|
65
|
-
| ------------------------------ | --------------------- |
|
|
66
|
-
| `blank` | One custom task | One agent run
|
|
67
|
-
| `simple-loop` | A small issue backlog | Implement issues sequentially
|
|
68
|
-
| `sequential-reviewer` | Safer issue delivery | Implement → review
|
|
69
|
-
| `parallel-planner` | Independent issues | Plan
|
|
70
|
-
| `parallel-planner-with-review` | Maximum autonomy | Plan → implement and review in parallel →
|
|
67
|
+
| Template | Best for | Built-in flow |
|
|
68
|
+
| ------------------------------ | --------------------- | --------------------------------------------- |
|
|
69
|
+
| `blank` | One custom task | One agent run |
|
|
70
|
+
| `simple-loop` | A small issue backlog | Implement issues sequentially → review PRs |
|
|
71
|
+
| `sequential-reviewer` | Safer issue delivery | Implement → review → review PR |
|
|
72
|
+
| `parallel-planner` | Independent issues | Plan → implement in parallel → review PRs |
|
|
73
|
+
| `parallel-planner-with-review` | Maximum autonomy | Plan → implement and review in parallel → PRs |
|
|
71
74
|
|
|
72
75
|
All templates are generated TypeScript. Adjust prompts, models, iteration
|
|
73
76
|
limits, branch strategy, hooks, and checks in `.shipyard/main.ts` or
|
|
@@ -80,12 +83,57 @@ Shipyard controller ready for GitHub Issues. Label an issue `shipyard`; the
|
|
|
80
83
|
controller wakes, drains a finite batch of eligible work, coalesces duplicate
|
|
81
84
|
wake-ups, and stops when it makes no progress. Restarting it recovers work
|
|
82
85
|
labelled while the host was offline.
|
|
86
|
+
GitHub-backed `shipyard init` provisions `shipyard`, `shipyard:blocked`,
|
|
87
|
+
`shipyard:pending`, `shipyard:complete`, and `shipyard:outstanding-tasks` in the repository.
|
|
88
|
+
It also provisions the `bug`, `enhancement`, and five triage state labels.
|
|
89
|
+
For a connected repository, init reports an error if any label cannot be created.
|
|
90
|
+
|
|
91
|
+
The bundled issue workflows install Snappedly skills and the candidate's
|
|
92
|
+
dependencies in Docker. When Shipyard takes an activated ticket, it runs
|
|
93
|
+
`/triage` first and checks the current GitHub labels. Implementation requires
|
|
94
|
+
both `shipyard` and `ready-for-agent`, with no conflicting triage state. Other
|
|
95
|
+
triage outcomes follow the normal blocked flow: Shipyard adds
|
|
96
|
+
`shipyard:blocked`, removes `shipyard`, and records the reason on the ticket.
|
|
97
|
+
A standalone ready issue then runs through `/implement`. Activating
|
|
98
|
+
a planning spec or a linked executable child resolves the parent and only
|
|
99
|
+
linked tickets labelled `shipyard` into one `/implement-spec` scope. The sequential
|
|
100
|
+
templates deliver selected tickets on one branch; the parallel templates assign
|
|
101
|
+
ready tickets to `/implement` workers, integrate dependency waves, resolve ticket
|
|
102
|
+
merge conflicts on the spec branch, and review the integrated change. One
|
|
103
|
+
non-draft PR per spec awaits human merge. Later selected tickets update that PR.
|
|
104
|
+
Shipyard also recognizes a ticket added to an open verified spec PR's `Source
|
|
105
|
+
issues:` line as belonging to that spec, even without a GitHub sub-issue or
|
|
106
|
+
`## Parent` link. Conflicting links block the selected ticket for correction.
|
|
107
|
+
Selected tickets receive `shipyard:pending` while Shipyard works on them.
|
|
108
|
+
Successful handoff replaces it with `shipyard:complete` and removes `shipyard`.
|
|
109
|
+
The parent spec and PR show `shipyard:blocked` if an unfinished child is blocked,
|
|
110
|
+
`shipyard:outstanding-tasks` if children remain, or `shipyard:complete` when all
|
|
111
|
+
linked tickets are complete. Spec labels report child state; they never prevent
|
|
112
|
+
a reactivated child from running. The issues remain open under the target
|
|
113
|
+
repository's closure policy.
|
|
114
|
+
With no labelled tickets yet, Shipyard marks the parent outstanding and waits
|
|
115
|
+
to create the PR until a ticket is selected.
|
|
116
|
+
If an attempted issue cannot be completed, Shipyard comments with the reason,
|
|
117
|
+
marks the attempted tickets `shipyard:blocked`, clears `shipyard:pending`, and
|
|
118
|
+
removes `shipyard` from the scope. The parent spec and any existing PR show
|
|
119
|
+
`shipyard:blocked` while an unfinished child remains blocked. It does not
|
|
120
|
+
publish a new PR for failed work. Resolve the problem, remove
|
|
121
|
+
`shipyard:blocked` from a ticket, then add `shipyard` to retry that ticket;
|
|
122
|
+
the parent spec's status label needs no manual change. Missing or ambiguous
|
|
123
|
+
relationships block the affected selected issue and record the reason. If GitHub cannot confirm whether a
|
|
124
|
+
PR became ready, Shipyard leaves the issue active for reconciliation. The GitHub token
|
|
125
|
+
needs Contents, Issues, and Pull requests read/write permission plus Metadata
|
|
126
|
+
read permission. Keep the Mac and foreground controller running for wake-ups.
|
|
127
|
+
If GitHub rejects a failure comment, Shipyard keeps a local pending report for
|
|
128
|
+
replay. A fresh `shipyard` activation on an unblocked ticket supersedes that
|
|
129
|
+
report. Spec and PR status label failures are logged without stopping ticket
|
|
130
|
+
work; retained activation lets the next invocation recalculate their labels.
|
|
83
131
|
|
|
84
132
|
Accept runner installation during `init`, or install it later:
|
|
85
133
|
|
|
86
134
|
```sh
|
|
87
135
|
npx shipyard runner install
|
|
88
|
-
git add .github/workflows/shipyard-wake.yml
|
|
136
|
+
git add .shipyard .github/workflows/shipyard-wake.yml
|
|
89
137
|
git commit -m "Add Shipyard wake workflow"
|
|
90
138
|
git push
|
|
91
139
|
npx shipyard runner start
|
package/dist/index.js
CHANGED
|
@@ -1596,6 +1596,15 @@ var interactive = async (options) => {
|
|
|
1596
1596
|
}
|
|
1597
1597
|
return result3;
|
|
1598
1598
|
};
|
|
1599
|
+
var runRequiredSandboxHook = (sandbox, command, cwd, sudo) => Effect.flatMap(
|
|
1600
|
+
sandbox.exec(command, { cwd, sudo }),
|
|
1601
|
+
(result3) => result3.exitCode === 0 ? Effect.succeed(result3) : Effect.fail(
|
|
1602
|
+
new Error(
|
|
1603
|
+
`Sandbox setup failed (exit ${result3.exitCode}): ${command}
|
|
1604
|
+
${result3.stderr}`
|
|
1605
|
+
)
|
|
1606
|
+
)
|
|
1607
|
+
);
|
|
1599
1608
|
var buildSandboxHandle = (ctx, close) => {
|
|
1600
1609
|
const {
|
|
1601
1610
|
branch,
|
|
@@ -2004,10 +2013,12 @@ var createSandboxFromWorktree = async (options) => {
|
|
|
2004
2013
|
`git config --global --add safe.directory ${shellQuote(sandboxRepoDir)}`
|
|
2005
2014
|
);
|
|
2006
2015
|
const sandboxEffects = (sandboxOnReady ?? []).map(
|
|
2007
|
-
(hook) =>
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2016
|
+
(hook) => runRequiredSandboxHook(
|
|
2017
|
+
sandbox,
|
|
2018
|
+
hook.command,
|
|
2019
|
+
sandboxRepoDir,
|
|
2020
|
+
hook.sudo
|
|
2021
|
+
)
|
|
2011
2022
|
);
|
|
2012
2023
|
const allEffects = [...sandboxEffects];
|
|
2013
2024
|
if (hostOnReady?.length) {
|
|
@@ -2016,7 +2027,12 @@ var createSandboxFromWorktree = async (options) => {
|
|
|
2016
2027
|
yield* Effect.all(allEffects, {
|
|
2017
2028
|
concurrency: "unbounded"
|
|
2018
2029
|
});
|
|
2019
|
-
})
|
|
2030
|
+
}).pipe(
|
|
2031
|
+
Effect.onError(
|
|
2032
|
+
() => providerHandle ? Effect.promise(() => providerHandle.close().catch(() => {
|
|
2033
|
+
})) : Effect.void
|
|
2034
|
+
)
|
|
2035
|
+
)
|
|
2020
2036
|
);
|
|
2021
2037
|
}
|
|
2022
2038
|
const applyToHost = isIsolated && providerHandle ? () => syncOut(worktreePath, providerHandle) : () => Effect.void;
|
|
@@ -2133,10 +2149,12 @@ var createSandbox = async (options) => {
|
|
|
2133
2149
|
`git config --global --add safe.directory ${shellQuote(sandboxRepoDir2)}`
|
|
2134
2150
|
);
|
|
2135
2151
|
const sandboxEffects = (sandboxOnReady ?? []).map(
|
|
2136
|
-
(hook) =>
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2152
|
+
(hook) => runRequiredSandboxHook(
|
|
2153
|
+
sandbox2,
|
|
2154
|
+
hook.command,
|
|
2155
|
+
sandboxRepoDir2,
|
|
2156
|
+
hook.sudo
|
|
2157
|
+
)
|
|
2140
2158
|
);
|
|
2141
2159
|
const allEffects = [...sandboxEffects];
|
|
2142
2160
|
if (hostOnReady?.length) {
|