@nilsr0711/drydock 0.1.2 → 0.1.4
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/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/app-path-routes-manifest.json +5 -3
- package/.next/standalone/.next/build-manifest.json +2 -2
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/routes-manifest.json +12 -0
- package/.next/standalone/.next/server/app/_global-error/page.js +2 -2
- package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page.js +2 -2
- package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/adrs/page.js +2 -2
- package/.next/standalone/.next/server/app/adrs/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/adrs/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/analytics/page.js +2 -0
- package/.next/standalone/.next/server/app/analytics/page.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/analytics/page_client-reference-manifest.js +1 -0
- package/.next/standalone/.next/server/app/api/cost/export/route.js +2 -1
- package/.next/standalone/.next/server/app/api/cost/export/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/sse/dashboard/route.js +15 -2
- package/.next/standalone/.next/server/app/api/sse/dashboard/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/sse/jobs/[id]/route.js +2 -2
- package/.next/standalone/.next/server/app/api/sse/jobs/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/webhooks/[repoId]/route.js +14 -1
- package/.next/standalone/.next/server/app/api/webhooks/[repoId]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/costs/page.js +2 -2
- package/.next/standalone/.next/server/app/costs/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/costs/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/jobs/[id]/page.js +3 -5
- package/.next/standalone/.next/server/app/jobs/[id]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/jobs/[id]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/jobs/page.js +2 -0
- package/.next/standalone/.next/server/app/jobs/page.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/jobs/page_client-reference-manifest.js +1 -0
- package/.next/standalone/.next/server/app/needs-human/page.js +2 -2
- package/.next/standalone/.next/server/app/needs-human/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/needs-human/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/page.js +2 -2
- package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/prompts/page.js +2 -2
- package/.next/standalone/.next/server/app/prompts/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/prompts/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/repos/[id]/page.js +2 -2
- package/.next/standalone/.next/server/app/repos/[id]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/repos/[id]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings/page.js +2 -2
- package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app-paths-manifest.json +5 -3
- package/.next/standalone/.next/server/chunks/318.js +14 -0
- package/.next/standalone/.next/server/chunks/468.js +24 -0
- package/.next/standalone/.next/server/chunks/49.js +3 -0
- package/.next/standalone/.next/server/chunks/541.js +1 -1
- package/.next/standalone/.next/server/chunks/665.js +9 -0
- package/.next/standalone/.next/server/chunks/675.js +1 -0
- package/.next/standalone/.next/server/chunks/785.js +93 -0
- package/.next/standalone/.next/server/chunks/859.js +1 -0
- package/.next/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/static/chunks/131-754f0b3c6a7625f0.js +1 -0
- package/.next/standalone/.next/static/chunks/{750-1062dd98095cb147.js → 334-ac65cc1c43f3e786.js} +3 -3
- package/.next/standalone/.next/static/chunks/488-94313c3750ed9fec.js +1 -0
- package/.next/standalone/.next/static/chunks/626-25255b0a66c520cb.js +1 -0
- package/.next/standalone/.next/static/chunks/751-17d24a843c68c75a.js +1 -0
- package/.next/standalone/.next/static/chunks/860-5c68ffeb97288824.js +1 -0
- package/.next/standalone/.next/static/chunks/app/adrs/page-d427443f113c3575.js +1 -0
- package/.next/standalone/.next/static/chunks/app/analytics/page-4154e54399ac6fb4.js +1 -0
- package/.next/standalone/.next/static/chunks/app/costs/page-85ceb7f167a8095a.js +1 -0
- package/.next/standalone/.next/static/chunks/app/jobs/[id]/page-eb2e6d420c330df8.js +1 -0
- package/.next/standalone/.next/static/chunks/app/jobs/page-73240c8c9b0571cf.js +1 -0
- package/.next/standalone/.next/static/chunks/app/layout-717833ce6aaa45ee.js +1 -0
- package/.next/standalone/.next/static/chunks/app/needs-human/page-fd702f6eeab08820.js +1 -0
- package/.next/standalone/.next/static/chunks/app/page-43ce9934744597e6.js +1 -0
- package/.next/standalone/.next/static/chunks/app/prompts/page-ecd6816b8dd8b583.js +1 -0
- package/.next/standalone/.next/static/chunks/app/repos/[id]/page-df838c0805fce188.js +1 -0
- package/.next/standalone/.next/static/chunks/app/settings/page-3274e07b560fc8bc.js +1 -0
- package/.next/standalone/.next/static/css/1f98a1f790475168.css +3 -0
- package/.next/standalone/.next/static/eWyghWWF4zppTRQ7rmwde/_buildManifest.js +1 -0
- package/.next/standalone/drizzle/0010_one_shot_costs.sql +12 -0
- package/.next/standalone/drizzle/0021_robust_wind_dancer.sql +48 -0
- package/.next/standalone/drizzle/0022_issue_model_override.sql +2 -0
- package/.next/standalone/drizzle/meta/0021_snapshot.json +1780 -0
- package/.next/standalone/drizzle/meta/_journal.json +7 -0
- package/.next/standalone/package.json +2 -1
- package/.next/static/chunks/131-754f0b3c6a7625f0.js +1 -0
- package/.next/static/chunks/{750-1062dd98095cb147.js → 334-ac65cc1c43f3e786.js} +3 -3
- package/.next/static/chunks/488-94313c3750ed9fec.js +1 -0
- package/.next/static/chunks/626-25255b0a66c520cb.js +1 -0
- package/.next/static/chunks/751-17d24a843c68c75a.js +1 -0
- package/.next/static/chunks/860-5c68ffeb97288824.js +1 -0
- package/.next/static/chunks/app/adrs/page-d427443f113c3575.js +1 -0
- package/.next/static/chunks/app/analytics/page-4154e54399ac6fb4.js +1 -0
- package/.next/static/chunks/app/costs/page-85ceb7f167a8095a.js +1 -0
- package/.next/static/chunks/app/jobs/[id]/page-eb2e6d420c330df8.js +1 -0
- package/.next/static/chunks/app/jobs/page-73240c8c9b0571cf.js +1 -0
- package/.next/static/chunks/app/layout-717833ce6aaa45ee.js +1 -0
- package/.next/static/chunks/app/needs-human/page-fd702f6eeab08820.js +1 -0
- package/.next/static/chunks/app/page-43ce9934744597e6.js +1 -0
- package/.next/static/chunks/app/prompts/page-ecd6816b8dd8b583.js +1 -0
- package/.next/static/chunks/app/repos/[id]/page-df838c0805fce188.js +1 -0
- package/.next/static/chunks/app/settings/page-3274e07b560fc8bc.js +1 -0
- package/.next/static/css/1f98a1f790475168.css +3 -0
- package/.next/static/eWyghWWF4zppTRQ7rmwde/_buildManifest.js +1 -0
- package/README.md +12 -4
- package/bin/drydock.mjs +145 -7
- package/drizzle/0010_one_shot_costs.sql +12 -0
- package/drizzle/0021_robust_wind_dancer.sql +48 -0
- package/drizzle/0022_issue_model_override.sql +2 -0
- package/drizzle/meta/0021_snapshot.json +1780 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +2 -1
- package/.next/standalone/.next/server/chunks/185.js +0 -32
- package/.next/standalone/.next/server/chunks/235.js +0 -1
- package/.next/standalone/.next/server/chunks/309.js +0 -1
- package/.next/standalone/.next/server/chunks/350.js +0 -9
- package/.next/standalone/.next/server/chunks/39.js +0 -3
- package/.next/standalone/.next/server/chunks/447.js +0 -1
- package/.next/standalone/.next/server/chunks/507.js +0 -9
- package/.next/standalone/.next/server/chunks/579.js +0 -62
- package/.next/standalone/.next/server/chunks/710.js +0 -1
- package/.next/standalone/.next/server/chunks/777.js +0 -1
- package/.next/standalone/.next/server/chunks/9.js +0 -3
- package/.next/standalone/.next/static/ZVOWTwaHoyx4ZcNdVzldW/_buildManifest.js +0 -1
- package/.next/standalone/.next/static/chunks/66-a23941cbbf88d6cd.js +0 -1
- package/.next/standalone/.next/static/chunks/700-c294ac6d353097ec.js +0 -1
- package/.next/standalone/.next/static/chunks/app/adrs/page-e75b859d58967540.js +0 -1
- package/.next/standalone/.next/static/chunks/app/costs/page-737c89e70adff98b.js +0 -1
- package/.next/standalone/.next/static/chunks/app/jobs/[id]/page-265e757a89803698.js +0 -1
- package/.next/standalone/.next/static/chunks/app/layout-f6048a8c9f541e0d.js +0 -1
- package/.next/standalone/.next/static/chunks/app/needs-human/page-88cb4f2c3aaf76c4.js +0 -1
- package/.next/standalone/.next/static/chunks/app/page-ab315dafdd344c06.js +0 -1
- package/.next/standalone/.next/static/chunks/app/prompts/page-562338cf5f420f96.js +0 -1
- package/.next/standalone/.next/static/chunks/app/repos/[id]/page-3099a9a513358664.js +0 -1
- package/.next/standalone/.next/static/chunks/app/settings/page-b6af5304dba71aa3.js +0 -1
- package/.next/standalone/.next/static/css/64af283f7f467bc0.css +0 -3
- package/.next/static/ZVOWTwaHoyx4ZcNdVzldW/_buildManifest.js +0 -1
- package/.next/static/chunks/66-a23941cbbf88d6cd.js +0 -1
- package/.next/static/chunks/700-c294ac6d353097ec.js +0 -1
- package/.next/static/chunks/app/adrs/page-e75b859d58967540.js +0 -1
- package/.next/static/chunks/app/costs/page-737c89e70adff98b.js +0 -1
- package/.next/static/chunks/app/jobs/[id]/page-265e757a89803698.js +0 -1
- package/.next/static/chunks/app/layout-f6048a8c9f541e0d.js +0 -1
- package/.next/static/chunks/app/needs-human/page-88cb4f2c3aaf76c4.js +0 -1
- package/.next/static/chunks/app/page-ab315dafdd344c06.js +0 -1
- package/.next/static/chunks/app/prompts/page-562338cf5f420f96.js +0 -1
- package/.next/static/chunks/app/repos/[id]/page-3099a9a513358664.js +0 -1
- package/.next/static/chunks/app/settings/page-b6af5304dba71aa3.js +0 -1
- package/.next/static/css/64af283f7f467bc0.css +0 -3
- /package/.next/standalone/.next/static/{ZVOWTwaHoyx4ZcNdVzldW → eWyghWWF4zppTRQ7rmwde}/_ssgManifest.js +0 -0
- /package/.next/static/{ZVOWTwaHoyx4ZcNdVzldW → eWyghWWF4zppTRQ7rmwde}/_ssgManifest.js +0 -0
package/bin/drydock.mjs
CHANGED
|
@@ -6,13 +6,43 @@
|
|
|
6
6
|
// step or TypeScript runtime so it works straight from the published tarball.
|
|
7
7
|
|
|
8
8
|
import { spawn } from "node:child_process";
|
|
9
|
-
import { existsSync, mkdirSync, readFileSync } from "node:fs";
|
|
9
|
+
import { existsSync, mkdirSync, readFileSync, realpathSync } from "node:fs";
|
|
10
10
|
import { homedir } from "node:os";
|
|
11
11
|
import { dirname, join, resolve } from "node:path";
|
|
12
12
|
import { fileURLToPath } from "node:url";
|
|
13
13
|
|
|
14
14
|
const DEFAULT_HOST = "127.0.0.1";
|
|
15
15
|
const DEFAULT_PORT = 3737;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Returns true when the given host address binds only to the local machine.
|
|
19
|
+
* Loopback addresses (127.0.0.1, ::1, localhost) are safe because they are
|
|
20
|
+
* unreachable from the network; all other values expand the attack surface.
|
|
21
|
+
*
|
|
22
|
+
* @param {string} host
|
|
23
|
+
*/
|
|
24
|
+
export function isLoopbackHost(host) {
|
|
25
|
+
return host === "127.0.0.1" || host === "::1" || host === "localhost";
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Throws an informative Error when `host` is a non-loopback address and the
|
|
30
|
+
* operator has not set DRYDOCK_ALLOW_REMOTE=1. This is the only gate between
|
|
31
|
+
* the unauthenticated dashboard and the network.
|
|
32
|
+
*
|
|
33
|
+
* @param {string} host
|
|
34
|
+
* @param {Record<string, string | undefined>} [env]
|
|
35
|
+
*/
|
|
36
|
+
export function assertSafeHost(host, env = process.env) {
|
|
37
|
+
if (isLoopbackHost(host)) return;
|
|
38
|
+
if (env.DRYDOCK_ALLOW_REMOTE) return;
|
|
39
|
+
throw new Error(
|
|
40
|
+
`Refusing to bind to "${host}": the Drydock dashboard has no authentication and ` +
|
|
41
|
+
`would be reachable by anyone on the network.\n` +
|
|
42
|
+
`To opt in and accept this risk, set DRYDOCK_ALLOW_REMOTE=1:\n` +
|
|
43
|
+
` DRYDOCK_ALLOW_REMOTE=1 drydock --host ${host}`,
|
|
44
|
+
);
|
|
45
|
+
}
|
|
16
46
|
const PACKAGE_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
17
47
|
|
|
18
48
|
/**
|
|
@@ -129,20 +159,107 @@ export function detectInstallKind(packageRoot) {
|
|
|
129
159
|
return "local";
|
|
130
160
|
}
|
|
131
161
|
|
|
162
|
+
/** The npm package name this CLI is published under. */
|
|
163
|
+
const PACKAGE_NAME = "@nilsr0711/drydock";
|
|
164
|
+
|
|
132
165
|
/** The command that updates a global install to the latest published version. */
|
|
133
166
|
export function updateCommand() {
|
|
134
|
-
return { command: "npm", args: ["install", "--global",
|
|
167
|
+
return { command: "npm", args: ["install", "--global", `${PACKAGE_NAME}@latest`] };
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Compare two `x.y.z` versions (a leading `v` is tolerated). Returns 1 if `a` is
|
|
172
|
+
* newer, -1 if older, 0 if equal. Throws if either version is unparseable so
|
|
173
|
+
* callers can fall back rather than silently mis-ordering.
|
|
174
|
+
*/
|
|
175
|
+
export function compareVersions(a, b) {
|
|
176
|
+
const parse = (v) => {
|
|
177
|
+
const m = /^v?(\d+)\.(\d+)\.(\d+)/.exec(String(v).trim());
|
|
178
|
+
if (!m) throw new Error(`unparseable version: ${v}`);
|
|
179
|
+
return [Number(m[1]), Number(m[2]), Number(m[3])];
|
|
180
|
+
};
|
|
181
|
+
const pa = parse(a);
|
|
182
|
+
const pb = parse(b);
|
|
183
|
+
for (let i = 0; i < 3; i++) {
|
|
184
|
+
if (pa[i] > pb[i]) return 1;
|
|
185
|
+
if (pa[i] < pb[i]) return -1;
|
|
186
|
+
}
|
|
187
|
+
return 0;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Decide what `drydock update` should do given the installed version and the
|
|
192
|
+
* latest published version (which may be null/unparseable when the check fails).
|
|
193
|
+
* Degrades gracefully: when the latest version can't be determined, still
|
|
194
|
+
* attempts the install rather than blocking the user.
|
|
195
|
+
*
|
|
196
|
+
* @returns {{ action: "skip" | "install", reason: string, latestVersion?: string }}
|
|
197
|
+
*/
|
|
198
|
+
export function planUpdate(currentVersion, latestVersion) {
|
|
199
|
+
if (!latestVersion) return { action: "install", reason: "unknown-latest" };
|
|
200
|
+
let cmp;
|
|
201
|
+
try {
|
|
202
|
+
cmp = compareVersions(latestVersion, currentVersion);
|
|
203
|
+
} catch {
|
|
204
|
+
return { action: "install", reason: "unknown-latest" };
|
|
205
|
+
}
|
|
206
|
+
if (cmp <= 0) return { action: "skip", reason: "up-to-date" };
|
|
207
|
+
return { action: "install", reason: "update-available", latestVersion };
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Resolve the latest published version from the npm registry's `latest`
|
|
212
|
+
* dist-tag. Never throws: returns null on any network/HTTP/parse failure so the
|
|
213
|
+
* caller can fall back to a blind install.
|
|
214
|
+
*
|
|
215
|
+
* @param {string} pkg The (possibly scoped) package name.
|
|
216
|
+
* @param {{ fetchImpl?: typeof fetch }} [opts]
|
|
217
|
+
* @returns {Promise<string | null>}
|
|
218
|
+
*/
|
|
219
|
+
export async function resolveLatestVersion(pkg, { fetchImpl = fetch } = {}) {
|
|
220
|
+
try {
|
|
221
|
+
const url = `https://registry.npmjs.org/${encodeURIComponent(pkg)}/latest`;
|
|
222
|
+
const res = await fetchImpl(url, {
|
|
223
|
+
headers: { Accept: "application/json", "User-Agent": "drydock-update" },
|
|
224
|
+
});
|
|
225
|
+
if (!res.ok) return null;
|
|
226
|
+
const body = await res.json();
|
|
227
|
+
return typeof body?.version === "string" ? body.version : null;
|
|
228
|
+
} catch {
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
135
231
|
}
|
|
136
232
|
|
|
137
233
|
/** Run the self-update, inheriting stdio so npm's progress is visible. */
|
|
138
|
-
function runUpdate() {
|
|
234
|
+
async function runUpdate() {
|
|
235
|
+
const current = readVersion();
|
|
236
|
+
console.error(`Current version: drydock v${current}`);
|
|
237
|
+
|
|
238
|
+
const latest = await resolveLatestVersion(PACKAGE_NAME);
|
|
239
|
+
const plan = planUpdate(current, latest);
|
|
240
|
+
|
|
241
|
+
if (plan.action === "skip") {
|
|
242
|
+
console.error(`drydock is already up to date (v${current}).`);
|
|
243
|
+
process.exit(0);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if (plan.reason === "unknown-latest") {
|
|
247
|
+
console.error("Could not determine the latest version; attempting update anyway…");
|
|
248
|
+
} else {
|
|
249
|
+
console.error(`Updating drydock ${current} → ${plan.latestVersion} …`);
|
|
250
|
+
}
|
|
251
|
+
|
|
139
252
|
const { command, args } = updateCommand();
|
|
140
|
-
console.error(`Updating drydock: ${command} ${args.join(" ")}`);
|
|
141
253
|
const child = spawn(command, args, {
|
|
142
254
|
shell: process.platform === "win32",
|
|
143
255
|
stdio: "inherit",
|
|
144
256
|
});
|
|
145
|
-
child.on("exit", (code) =>
|
|
257
|
+
child.on("exit", (code) => {
|
|
258
|
+
if (code === 0 && plan.reason === "update-available") {
|
|
259
|
+
console.error(`Updated to drydock v${plan.latestVersion}.`);
|
|
260
|
+
}
|
|
261
|
+
process.exit(code ?? 0);
|
|
262
|
+
});
|
|
146
263
|
child.on("error", (err) => {
|
|
147
264
|
console.error(`Update failed: ${err.message}`);
|
|
148
265
|
process.exit(1);
|
|
@@ -183,6 +300,8 @@ async function waitForServer(url, { attempts = 100, intervalMs = 100 } = {}) {
|
|
|
183
300
|
}
|
|
184
301
|
|
|
185
302
|
async function serve({ host, port, open }) {
|
|
303
|
+
assertSafeHost(host);
|
|
304
|
+
|
|
186
305
|
const serverEntry = join(PACKAGE_ROOT, ".next", "standalone", "server.js");
|
|
187
306
|
if (!existsSync(serverEntry)) {
|
|
188
307
|
throw new Error(
|
|
@@ -244,15 +363,34 @@ async function main(argv) {
|
|
|
244
363
|
console.log(readVersion());
|
|
245
364
|
return;
|
|
246
365
|
case "update":
|
|
247
|
-
runUpdate();
|
|
366
|
+
await runUpdate();
|
|
248
367
|
return;
|
|
249
368
|
default:
|
|
250
369
|
await serve(directive);
|
|
251
370
|
}
|
|
252
371
|
}
|
|
253
372
|
|
|
373
|
+
/**
|
|
374
|
+
* Decide whether this module is the program entry point. A plain string compare
|
|
375
|
+
* against `process.argv[1]` breaks for global/npx installs, where the bin is a
|
|
376
|
+
* symlink in a bin directory and argv[1] is that link rather than the real file.
|
|
377
|
+
* Resolving the entry path through symlinks (realpath) makes the two comparable,
|
|
378
|
+
* so `drydock`, `drydock --version`, etc. actually run when installed.
|
|
379
|
+
*
|
|
380
|
+
* @param {string} modulePath Absolute path to this module (resolved import.meta.url).
|
|
381
|
+
* @param {string | undefined} entryPath The invoked entry path (process.argv[1]).
|
|
382
|
+
*/
|
|
383
|
+
export function isMainModule(modulePath, entryPath) {
|
|
384
|
+
if (!entryPath) return false;
|
|
385
|
+
try {
|
|
386
|
+
return modulePath === realpathSync(entryPath);
|
|
387
|
+
} catch {
|
|
388
|
+
return false;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
254
392
|
// Only run when executed directly, not when imported by tests.
|
|
255
|
-
if (
|
|
393
|
+
if (isMainModule(fileURLToPath(import.meta.url), process.argv[1])) {
|
|
256
394
|
main(process.argv.slice(2)).catch((err) => {
|
|
257
395
|
console.error(err instanceof Error ? err.message : String(err));
|
|
258
396
|
process.exit(1);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
CREATE TABLE `one_shot_costs` (
|
|
2
|
+
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
|
3
|
+
`repo_id` integer NOT NULL,
|
|
4
|
+
`type` text NOT NULL,
|
|
5
|
+
`cost_usd` real DEFAULT 0 NOT NULL,
|
|
6
|
+
`input_tokens` integer DEFAULT 0 NOT NULL,
|
|
7
|
+
`output_tokens` integer DEFAULT 0 NOT NULL,
|
|
8
|
+
`created_at` integer DEFAULT (unixepoch()) NOT NULL,
|
|
9
|
+
FOREIGN KEY (`repo_id`) REFERENCES `repos`(`id`) ON UPDATE no action ON DELETE cascade
|
|
10
|
+
);
|
|
11
|
+
--> statement-breakpoint
|
|
12
|
+
CREATE INDEX `one_shot_costs_repo_idx` ON `one_shot_costs` (`repo_id`);
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
PRAGMA foreign_keys=OFF;--> statement-breakpoint
|
|
2
|
+
CREATE TABLE `__new_repos` (
|
|
3
|
+
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
|
4
|
+
`path` text NOT NULL,
|
|
5
|
+
`name` text NOT NULL,
|
|
6
|
+
`default_branch` text DEFAULT 'main' NOT NULL,
|
|
7
|
+
`queue_label` text DEFAULT 'drydock:queue' NOT NULL,
|
|
8
|
+
`working_label` text DEFAULT 'drydock:working' NOT NULL,
|
|
9
|
+
`needs_human_label` text DEFAULT 'drydock:needs-human' NOT NULL,
|
|
10
|
+
`default_model` text DEFAULT 'claude-opus-4-8' NOT NULL,
|
|
11
|
+
`agent` text DEFAULT 'claude' NOT NULL,
|
|
12
|
+
`platform` text DEFAULT 'github' NOT NULL,
|
|
13
|
+
`api_base_url` text,
|
|
14
|
+
`api_token` text,
|
|
15
|
+
`daily_cost_limit_usd` real DEFAULT 10 NOT NULL,
|
|
16
|
+
`adr_gating` integer DEFAULT false NOT NULL,
|
|
17
|
+
`sequential` integer DEFAULT true NOT NULL,
|
|
18
|
+
`auto_triage_enabled` integer DEFAULT false NOT NULL,
|
|
19
|
+
`auto_process_enabled` integer DEFAULT false NOT NULL,
|
|
20
|
+
`auto_heal_ci` integer DEFAULT false NOT NULL,
|
|
21
|
+
`auto_review_feedback` integer DEFAULT false NOT NULL,
|
|
22
|
+
`auto_resolve_merge_conflicts` integer DEFAULT false NOT NULL,
|
|
23
|
+
`include_progress_replies` integer DEFAULT false NOT NULL,
|
|
24
|
+
`auto_decompose` integer DEFAULT false NOT NULL,
|
|
25
|
+
`verify_pr` integer DEFAULT false NOT NULL,
|
|
26
|
+
`auto_heal_deployments` integer DEFAULT false NOT NULL,
|
|
27
|
+
`deployment_platform` text,
|
|
28
|
+
`trusted_reviewers` text DEFAULT '[]' NOT NULL,
|
|
29
|
+
`ignored_bots` text DEFAULT '["dependabot[bot]","github-actions[bot]","codecov[bot]"]' NOT NULL,
|
|
30
|
+
`ready_labels` text DEFAULT '["ready","ready-for-agent","ready-to-work"]' NOT NULL,
|
|
31
|
+
`blocking_labels` text DEFAULT '["blocked","question","needs-human","needs-discussion","wontfix","duplicate","invalid"]' NOT NULL,
|
|
32
|
+
`auto_label_whitelist` text DEFAULT '["bug","enhancement","documentation","ready"]' NOT NULL,
|
|
33
|
+
`priority_authors` text DEFAULT '[]' NOT NULL,
|
|
34
|
+
`min_author_association` text DEFAULT 'approved' NOT NULL,
|
|
35
|
+
`max_attempts` integer DEFAULT 3 NOT NULL,
|
|
36
|
+
`max_job_minutes` integer,
|
|
37
|
+
`max_ci_wait_minutes` integer,
|
|
38
|
+
`max_job_cost_usd` real,
|
|
39
|
+
`agent_instructions` text,
|
|
40
|
+
`release_enabled` integer DEFAULT false NOT NULL,
|
|
41
|
+
`webhook_secret` text,
|
|
42
|
+
`created_at` integer DEFAULT (unixepoch()) NOT NULL
|
|
43
|
+
);
|
|
44
|
+
--> statement-breakpoint
|
|
45
|
+
INSERT INTO `__new_repos`("id", "path", "name", "default_branch", "queue_label", "working_label", "needs_human_label", "default_model", "agent", "platform", "api_base_url", "api_token", "daily_cost_limit_usd", "adr_gating", "sequential", "auto_triage_enabled", "auto_process_enabled", "auto_heal_ci", "auto_review_feedback", "auto_resolve_merge_conflicts", "include_progress_replies", "auto_decompose", "verify_pr", "auto_heal_deployments", "deployment_platform", "trusted_reviewers", "ignored_bots", "ready_labels", "blocking_labels", "auto_label_whitelist", "priority_authors", "min_author_association", "max_attempts", "max_job_minutes", "max_ci_wait_minutes", "max_job_cost_usd", "agent_instructions", "release_enabled", "webhook_secret", "created_at") SELECT "id", "path", "name", "default_branch", "queue_label", "working_label", "needs_human_label", "default_model", "agent", "platform", "api_base_url", "api_token", "daily_cost_limit_usd", "adr_gating", "sequential", "auto_triage_enabled", "auto_process_enabled", "auto_heal_ci", "auto_review_feedback", "auto_resolve_merge_conflicts", "include_progress_replies", "auto_decompose", "verify_pr", "auto_heal_deployments", "deployment_platform", "trusted_reviewers", "ignored_bots", "ready_labels", "blocking_labels", "auto_label_whitelist", "priority_authors", "min_author_association", "max_attempts", "max_job_minutes", "max_ci_wait_minutes", "max_job_cost_usd", "agent_instructions", "release_enabled", "webhook_secret", "created_at" FROM `repos`;--> statement-breakpoint
|
|
46
|
+
DROP TABLE `repos`;--> statement-breakpoint
|
|
47
|
+
ALTER TABLE `__new_repos` RENAME TO `repos`;--> statement-breakpoint
|
|
48
|
+
PRAGMA foreign_keys=ON;
|