@clipboard-health/groundcrew 1.12.2 → 1.12.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/dist/commands/remoteSetup.d.ts +3 -0
- package/dist/commands/remoteSetup.d.ts.map +1 -1
- package/dist/commands/remoteSetup.js +45 -24
- package/dist/commands/setupRepos.d.ts.map +1 -1
- package/dist/commands/setupRepos.js +3 -2
- package/dist/lib/spriteRemoteRunnerProvider.d.ts +3 -0
- package/dist/lib/spriteRemoteRunnerProvider.d.ts.map +1 -1
- package/dist/lib/spriteRemoteRunnerProvider.js +6 -6
- package/package.json +4 -4
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type RemoteRunnerConfig } from "../lib/config.ts";
|
|
1
2
|
export interface McpServer {
|
|
2
3
|
name: string;
|
|
3
4
|
url: string;
|
|
@@ -23,6 +24,8 @@ export interface RemoteBootstrapOptions {
|
|
|
23
24
|
owner: string;
|
|
24
25
|
baseBranch: string;
|
|
25
26
|
gitRemote?: string;
|
|
27
|
+
repoRoot?: string;
|
|
28
|
+
remoteConfig?: RemoteRunnerConfig;
|
|
26
29
|
secretNames: string[];
|
|
27
30
|
shouldRequireSelectedSecrets: boolean;
|
|
28
31
|
shouldUseSecrets: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remoteSetup.d.ts","sourceRoot":"","sources":["../../src/commands/remoteSetup.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"remoteSetup.d.ts","sourceRoot":"","sources":["../../src/commands/remoteSetup.ts"],"names":[],"mappings":"AAKA,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,kBAAkB,CAAC;AAkB1B,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;IACtB,wBAAwB,EAAE,OAAO,CAAC;IAClC,uBAAuB,EAAE,OAAO,CAAC;IACjC,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,wBAAwB,EAAE,OAAO,CAAC;IAClC,qBAAqB,EAAE,OAAO,CAAC;IAC/B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,SAAS,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,4BAA4B,EAAE,OAAO,CAAC;IACtC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAiBD,MAAM,WAAW,qBAAqB;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,sBAAsB;IACrC,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AA02BD,wBAAsB,yBAAyB,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsC9F;AAUD,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAItF;AAED,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAGrF;AAED,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAItF;AAED,wBAAsB,2BAA2B,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAGhG;AAYD,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgClF;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA2B7D"}
|
|
@@ -2,9 +2,9 @@ import { existsSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
|
2
2
|
import { homedir, tmpdir } from "node:os";
|
|
3
3
|
import { join, resolve } from "node:path";
|
|
4
4
|
import { setTimeout as sleep } from "node:timers/promises";
|
|
5
|
-
import {
|
|
5
|
+
import { DEFAULT_REMOTE_SETUP_COMMAND, loadConfig, } from "../lib/config.js";
|
|
6
6
|
import { shellSingleQuote } from "../lib/shell.js";
|
|
7
|
-
import { getRemoteRunnerProvider, remoteConfigWithRunnerName, } from "../lib/spriteRemoteRunnerProvider.js";
|
|
7
|
+
import { getRemoteRunnerProvider, remotePathJoin, remoteConfigWithRunnerName, remoteRepositoryDirectoryName, remoteRepositorySlug, } from "../lib/spriteRemoteRunnerProvider.js";
|
|
8
8
|
import { log, readEnvironmentVariable, writeOutput } from "../lib/util.js";
|
|
9
9
|
const KNOWN_MCP_SERVER_URLS = {
|
|
10
10
|
linear: "https://mcp.linear.app/mcp",
|
|
@@ -13,8 +13,8 @@ const KNOWN_MCP_SERVER_URLS = {
|
|
|
13
13
|
};
|
|
14
14
|
const DEFAULT_CHECKPOINT_COMMENT = "groundcrew remote runner baseline: selected agent auth, git identity, and MCP config";
|
|
15
15
|
const CLAUDE_SUBSCRIPTION_LOGIN_FLAG = ["--claude", "ai"].join("");
|
|
16
|
-
const DEFAULT_REPOSITORY_OWNER = "ClipboardHealth";
|
|
17
16
|
const DEFAULT_GIT_REMOTE = "origin";
|
|
17
|
+
const BOOTSTRAP_SECRET_FLAGS_CONFLICT_MESSAGE = "--secret and --no-secrets are mutually exclusive. Use --secret to forward selected build secrets or --no-secrets to disable secret forwarding.";
|
|
18
18
|
const DATADOG_PUP_VERSION = "0.63.0";
|
|
19
19
|
const DATADOG_OAUTH_CALLBACK_PORT = 8000;
|
|
20
20
|
const DATADOG_AUTH_STATUS_RETRY_ATTEMPTS = 5;
|
|
@@ -53,9 +53,9 @@ function usage() {
|
|
|
53
53
|
"Bootstrap options:",
|
|
54
54
|
" --branch <branch> Checkout/create a ticket branch before installing deps",
|
|
55
55
|
" --base <branch> Base branch used when creating a missing branch (default: git.defaultBranch)",
|
|
56
|
-
" --owner <owner> GitHub owner for bare repo names (default:
|
|
56
|
+
" --owner <owner> GitHub owner for bare repo names (default: remote.owner)",
|
|
57
57
|
" --secret <env-name> Forward one required build secret; repeat for multiple",
|
|
58
|
-
" --no-secrets Do not forward
|
|
58
|
+
" --no-secrets Do not forward configured build secrets even if present",
|
|
59
59
|
"",
|
|
60
60
|
"Bootstrap example:",
|
|
61
61
|
" crew remote bootstrap crew-claude-1 core-utils --branch rocky-team-123",
|
|
@@ -232,7 +232,7 @@ function parseBootstrapArguments(argv) {
|
|
|
232
232
|
throw new Error(usage());
|
|
233
233
|
}
|
|
234
234
|
validateRepository(repository);
|
|
235
|
-
let owner
|
|
235
|
+
let owner;
|
|
236
236
|
let baseBranch;
|
|
237
237
|
let branchName;
|
|
238
238
|
let shouldUseSecrets = true;
|
|
@@ -259,6 +259,9 @@ function parseBootstrapArguments(argv) {
|
|
|
259
259
|
continue;
|
|
260
260
|
}
|
|
261
261
|
if (argument === "--secret") {
|
|
262
|
+
if (!shouldUseSecrets) {
|
|
263
|
+
throw new Error(BOOTSTRAP_SECRET_FLAGS_CONFLICT_MESSAGE);
|
|
264
|
+
}
|
|
262
265
|
const secretName = requireValue(argv, index, "--secret");
|
|
263
266
|
validateSecretName(secretName);
|
|
264
267
|
selectedSecretNames.push(secretName);
|
|
@@ -267,6 +270,9 @@ function parseBootstrapArguments(argv) {
|
|
|
267
270
|
continue;
|
|
268
271
|
}
|
|
269
272
|
if (argument === "--no-secrets") {
|
|
273
|
+
if (selectedSecretNames.length > 0 || shouldRequireSelectedSecrets) {
|
|
274
|
+
throw new Error(BOOTSTRAP_SECRET_FLAGS_CONFLICT_MESSAGE);
|
|
275
|
+
}
|
|
270
276
|
shouldUseSecrets = false;
|
|
271
277
|
continue;
|
|
272
278
|
}
|
|
@@ -275,10 +281,10 @@ function parseBootstrapArguments(argv) {
|
|
|
275
281
|
return {
|
|
276
282
|
runnerName,
|
|
277
283
|
repository,
|
|
278
|
-
owner,
|
|
279
|
-
secretNames: selectedSecretNames.length > 0 ? selectedSecretNames : [...BUILD_SECRET_NAMES],
|
|
280
284
|
shouldRequireSelectedSecrets,
|
|
281
285
|
shouldUseSecrets,
|
|
286
|
+
...(owner === undefined ? {} : { owner }),
|
|
287
|
+
...(selectedSecretNames.length > 0 ? { secretNames: selectedSecretNames } : {}),
|
|
282
288
|
...(baseBranch === undefined ? {} : { baseBranch }),
|
|
283
289
|
...(branchName === undefined ? {} : { branchName }),
|
|
284
290
|
};
|
|
@@ -620,20 +626,22 @@ async function checkpoint(arguments_) {
|
|
|
620
626
|
}
|
|
621
627
|
await provider.checkpoint(config, options.checkpointComment);
|
|
622
628
|
}
|
|
623
|
-
function
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
629
|
+
function validateRemoteBootstrapOptions(options) {
|
|
630
|
+
validateRepository(options.repository);
|
|
631
|
+
validateRepositoryOwner(options.owner);
|
|
632
|
+
validateGitRef(options.baseBranch, "base branch");
|
|
633
|
+
validateGitRef(options.gitRemote, "git remote");
|
|
634
|
+
if (options.branchName !== undefined) {
|
|
635
|
+
validateGitRef(options.branchName, "branch");
|
|
636
|
+
}
|
|
637
|
+
for (const name of options.secretNames) {
|
|
638
|
+
validateSecretName(name);
|
|
639
|
+
}
|
|
633
640
|
}
|
|
634
641
|
function remoteBootstrapCommand(options) {
|
|
635
|
-
const slug =
|
|
636
|
-
const directoryName =
|
|
642
|
+
const slug = remoteRepositorySlug(options.owner, options.repository);
|
|
643
|
+
const directoryName = remoteRepositoryDirectoryName(options.owner, options.repository);
|
|
644
|
+
const repoDir = remotePathJoin(options.repoRoot, directoryName);
|
|
637
645
|
const baseRef = `${options.gitRemote}/${options.baseBranch}`;
|
|
638
646
|
const unsetSecretsLine = options.secretNames.length === 0 ? ":" : `unset ${options.secretNames.join(" ")}`;
|
|
639
647
|
const checkoutLines = options.branchName === undefined
|
|
@@ -649,9 +657,10 @@ function remoteBootstrapCommand(options) {
|
|
|
649
657
|
"set -euo pipefail",
|
|
650
658
|
`cleanup() { rm -f ${shellSingleQuote(REMOTE_SECRETS_FILE)}; ${unsetSecretsLine}; }`,
|
|
651
659
|
"trap cleanup EXIT",
|
|
660
|
+
`repo_root=${shellSingleQuote(options.repoRoot)}`,
|
|
661
|
+
`repo_dir=${shellSingleQuote(repoDir)}`,
|
|
652
662
|
`git_remote=${shellSingleQuote(options.gitRemote)}`,
|
|
653
|
-
'mkdir -p "$
|
|
654
|
-
`repo_dir="$HOME/dev/${directoryName}"`,
|
|
663
|
+
'mkdir -p "$repo_root"',
|
|
655
664
|
'if [ ! -d "$repo_dir/.git" ]; then',
|
|
656
665
|
` gh repo clone ${shellSingleQuote(slug)} "$repo_dir"`,
|
|
657
666
|
"fi",
|
|
@@ -668,10 +677,19 @@ function remoteBootstrapCommand(options) {
|
|
|
668
677
|
}
|
|
669
678
|
async function resolveBootstrapOptions(options) {
|
|
670
679
|
const config = await loadConfig();
|
|
680
|
+
const remoteConfig = {
|
|
681
|
+
...config.remote,
|
|
682
|
+
runnerName: options.runnerName,
|
|
683
|
+
secretNames: [...config.remote.secretNames],
|
|
684
|
+
};
|
|
671
685
|
return {
|
|
672
686
|
...options,
|
|
687
|
+
owner: options.owner ?? remoteConfig.owner,
|
|
673
688
|
baseBranch: options.baseBranch ?? config.git.defaultBranch,
|
|
674
689
|
gitRemote: config.git.remote,
|
|
690
|
+
repoRoot: remoteConfig.repoRoot,
|
|
691
|
+
remoteConfig,
|
|
692
|
+
secretNames: options.secretNames ?? [...remoteConfig.secretNames],
|
|
675
693
|
};
|
|
676
694
|
}
|
|
677
695
|
function noSecretCleanup() {
|
|
@@ -709,11 +727,14 @@ function stageBuildSecrets(options) {
|
|
|
709
727
|
};
|
|
710
728
|
}
|
|
711
729
|
export async function bootstrapRemoteRepository(options) {
|
|
730
|
+
const config = options.remoteConfig ?? remoteConfigWithRunnerName(options.runnerName);
|
|
712
731
|
const bootstrapOptions = {
|
|
713
732
|
...options,
|
|
714
733
|
gitRemote: options.gitRemote ?? DEFAULT_GIT_REMOTE,
|
|
734
|
+
repoRoot: options.repoRoot ?? config.repoRoot,
|
|
735
|
+
remoteConfig: config,
|
|
715
736
|
};
|
|
716
|
-
|
|
737
|
+
validateRemoteBootstrapOptions(bootstrapOptions);
|
|
717
738
|
const provider = providerFor(config);
|
|
718
739
|
if (!(await provider.runnerExists(config))) {
|
|
719
740
|
throw new Error(`Remote runner ${options.runnerName} does not exist. Run crew remote setup first.`);
|
|
@@ -726,7 +747,7 @@ export async function bootstrapRemoteRepository(options) {
|
|
|
726
747
|
const files = stagedSecrets.filePath === undefined
|
|
727
748
|
? []
|
|
728
749
|
: [{ localPath: stagedSecrets.filePath, remotePath: REMOTE_SECRETS_FILE }];
|
|
729
|
-
log(`Bootstrapping ${
|
|
750
|
+
log(`Bootstrapping ${remoteRepositorySlug(bootstrapOptions.owner, bootstrapOptions.repository)} in ${options.runnerName}`);
|
|
730
751
|
await provider.runCommand({
|
|
731
752
|
config,
|
|
732
753
|
files,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setupRepos.d.ts","sourceRoot":"","sources":["../../src/commands/setupRepos.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAInE,MAAM,WAAW,iBAAiB;IAChC,gDAAgD;IAChD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,oBAAoB,GAAG,gBAAgB,CAAC;AAEvF,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,kBAAkB,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,kDAAkD;IAClD,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,oDAAoD;IACpD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,4CAA4C;IAC5C,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,wEAAwE;IACxE,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,wCAAwC;IACxC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,KAAK,CAAA;KAAE,EAAE,CAAC;IACzC,mEAAmE;IACnE,SAAS,EAAE,OAAO,CAAC;CACpB;AA6JD,wBAAsB,UAAU,CAC9B,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,gBAAgB,CAAC,
|
|
1
|
+
{"version":3,"file":"setupRepos.d.ts","sourceRoot":"","sources":["../../src/commands/setupRepos.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAInE,MAAM,WAAW,iBAAiB;IAChC,gDAAgD;IAChD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,oBAAoB,GAAG,gBAAgB,CAAC;AAEvF,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,kBAAkB,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,kDAAkD;IAClD,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,oDAAoD;IACpD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,4CAA4C;IAC5C,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,wEAAwE;IACxE,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,wCAAwC;IACxC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,KAAK,CAAA;KAAE,EAAE,CAAC;IACzC,mEAAmE;IACnE,SAAS,EAAE,OAAO,CAAC;CACpB;AA6JD,wBAAsB,UAAU,CAC9B,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,gBAAgB,CAAC,CA0D3B;AAwBD,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAajE"}
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* entries are skipped with a hint, because they have no canonical URL
|
|
6
6
|
* we can guess at without involving the user's gh login. Idempotent.
|
|
7
7
|
*/
|
|
8
|
-
import { opendirSync, statSync } from "node:fs";
|
|
9
|
-
import { isAbsolute, relative, resolve } from "node:path";
|
|
8
|
+
import { mkdirSync, opendirSync, statSync } from "node:fs";
|
|
9
|
+
import { dirname, isAbsolute, relative, resolve } from "node:path";
|
|
10
10
|
import { runCommandAsync } from "../lib/commandRunner.js";
|
|
11
11
|
import { loadConfig } from "../lib/config.js";
|
|
12
12
|
import { which } from "../lib/host.js";
|
|
@@ -173,6 +173,7 @@ export async function setupRepos(config, options) {
|
|
|
173
173
|
const target = resolve(projectDir, entry);
|
|
174
174
|
log(`[clone] ${entry} → ${target}`);
|
|
175
175
|
try {
|
|
176
|
+
mkdirSync(dirname(target), { recursive: true });
|
|
176
177
|
// oxlint-disable-next-line no-await-in-loop -- see comment above
|
|
177
178
|
await runCommandAsync("gh", ["repo", "clone", entry, target], {
|
|
178
179
|
stdio: "inherit",
|
|
@@ -66,6 +66,9 @@ export interface RemoteRunnerProvider {
|
|
|
66
66
|
createWorktree(arguments_: RemoteWorktreeCreateArguments): Promise<RemoteWorktreeLocation>;
|
|
67
67
|
removeWorktree(arguments_: RemoteWorktreeRemoveArguments): Promise<void>;
|
|
68
68
|
}
|
|
69
|
+
export declare function remotePathJoin(root: string, leaf: string): string;
|
|
70
|
+
export declare function remoteRepositorySlug(owner: string, repository: string): string;
|
|
71
|
+
export declare function remoteRepositoryDirectoryName(owner: string, repository: string): string;
|
|
69
72
|
export declare const spriteRemoteRunnerProvider: RemoteRunnerProvider;
|
|
70
73
|
export declare function remoteConfigWithRunnerName(runnerName: string): RemoteRunnerConfig;
|
|
71
74
|
export declare function getRemoteRunnerProvider(provider: RemoteRunnerProviderName): RemoteRunnerProvider;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spriteRemoteRunnerProvider.d.ts","sourceRoot":"","sources":["../../src/lib/spriteRemoteRunnerProvider.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"spriteRemoteRunnerProvider.d.ts","sourceRoot":"","sources":["../../src/lib/spriteRemoteRunnerProvider.ts"],"names":[],"mappings":"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"}
|
|
@@ -82,18 +82,18 @@ function buildSpriteTtyCommand(arguments_) {
|
|
|
82
82
|
...arguments_.remoteArguments.map(shellSingleQuote),
|
|
83
83
|
].join(" ");
|
|
84
84
|
}
|
|
85
|
-
function remotePathJoin(root, leaf) {
|
|
85
|
+
export function remotePathJoin(root, leaf) {
|
|
86
86
|
let end = root.length;
|
|
87
87
|
while (end > 0 && root[end - 1] === "/") {
|
|
88
88
|
end -= 1;
|
|
89
89
|
}
|
|
90
90
|
return `${root.slice(0, end)}/${leaf}`;
|
|
91
91
|
}
|
|
92
|
-
function
|
|
92
|
+
export function remoteRepositorySlug(owner, repository) {
|
|
93
93
|
return repository.includes("/") ? repository : `${owner}/${repository}`;
|
|
94
94
|
}
|
|
95
|
-
function
|
|
96
|
-
const slug =
|
|
95
|
+
export function remoteRepositoryDirectoryName(owner, repository) {
|
|
96
|
+
const slug = remoteRepositorySlug(owner, repository);
|
|
97
97
|
const normalizedSlug = slug.endsWith(".git") ? slug.slice(0, -4) : slug;
|
|
98
98
|
return normalizedSlug.replaceAll("/", "--");
|
|
99
99
|
}
|
|
@@ -104,7 +104,7 @@ function worktreeTicketComponent(ticket) {
|
|
|
104
104
|
return ticket;
|
|
105
105
|
}
|
|
106
106
|
function spriteCreateWorktreeCommand(arguments_) {
|
|
107
|
-
const slug =
|
|
107
|
+
const slug = remoteRepositorySlug(arguments_.owner, arguments_.repository);
|
|
108
108
|
const branchRemoteRef = `refs/remotes/${arguments_.gitRemote}/${arguments_.branchName}`;
|
|
109
109
|
const branchRef = `${arguments_.gitRemote}/${arguments_.branchName}`;
|
|
110
110
|
const baseRef = `${arguments_.gitRemote}/${arguments_.baseBranch}`;
|
|
@@ -317,7 +317,7 @@ export const spriteRemoteRunnerProvider = {
|
|
|
317
317
|
},
|
|
318
318
|
async createWorktree(arguments_) {
|
|
319
319
|
const { config, repository, ticket, branchName, baseBranch, gitRemote, signal } = arguments_;
|
|
320
|
-
const remoteRepositoryName =
|
|
320
|
+
const remoteRepositoryName = remoteRepositoryDirectoryName(config.owner, repository);
|
|
321
321
|
const remoteRepoDir = remotePathJoin(config.repoRoot, remoteRepositoryName);
|
|
322
322
|
const remoteWorktreeDir = remotePathJoin(config.worktreeRoot, `${remoteRepositoryName}-${worktreeTicketComponent(ticket)}`);
|
|
323
323
|
await runCommandAsync("sprite", [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clipboard-health/groundcrew",
|
|
3
|
-
"version": "1.12.
|
|
3
|
+
"version": "1.12.4",
|
|
4
4
|
"description": "Linear-driven orchestrator that launches AI coding agents in git worktrees, with workspace lifecycle, remote runners, and usage tracking.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
},
|
|
73
73
|
"devDependencies": {
|
|
74
74
|
"@clipboard-health/ai-rules": "2.18.4",
|
|
75
|
-
"@clipboard-health/oxlint-config": "1.
|
|
75
|
+
"@clipboard-health/oxlint-config": "1.9.4",
|
|
76
76
|
"@nx/js": "22.7.1",
|
|
77
77
|
"@tsconfig/node24": "24.0.4",
|
|
78
78
|
"@tsconfig/strictest": "2.0.8",
|
|
@@ -88,8 +88,8 @@
|
|
|
88
88
|
"markdownlint-cli2": "0.22.1",
|
|
89
89
|
"nx": "22.7.1",
|
|
90
90
|
"oxfmt": "0.47.0",
|
|
91
|
-
"oxlint": "1.
|
|
92
|
-
"oxlint-tsgolint": "0.
|
|
91
|
+
"oxlint": "1.64.0",
|
|
92
|
+
"oxlint-tsgolint": "0.22.1",
|
|
93
93
|
"syncpack": "15.0.0",
|
|
94
94
|
"vite": "8.0.10",
|
|
95
95
|
"vitest": "4.1.5"
|