@clipboard-health/groundcrew 4.46.6 → 4.47.1
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/openWorkspace.d.ts.map +1 -1
- package/dist/commands/openWorkspace.js +6 -0
- package/dist/commands/resumeWorkspace.d.ts.map +1 -1
- package/dist/commands/resumeWorkspace.js +6 -1
- package/dist/commands/setupWorkspace.d.ts.map +1 -1
- package/dist/commands/setupWorkspace.js +6 -1
- package/dist/lib/adapters/linear/client.d.ts.map +1 -1
- package/dist/lib/adapters/linear/client.js +1 -0
- package/dist/lib/seedLaunchWorkspaceTrust.d.ts +9 -0
- package/dist/lib/seedLaunchWorkspaceTrust.d.ts.map +1 -0
- package/dist/lib/seedLaunchWorkspaceTrust.js +17 -0
- package/dist/lib/worktrees.d.ts +7 -0
- package/dist/lib/worktrees.d.ts.map +1 -1
- package/dist/lib/worktrees.js +43 -3
- package/docs/troubleshooting.md +14 -0
- package/package.json +4 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openWorkspace.d.ts","sourceRoot":"","sources":["../../src/commands/openWorkspace.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"openWorkspace.d.ts","sourceRoot":"","sources":["../../src/commands/openWorkspace.ts"],"names":[],"mappings":"AAKA,OAAO,EAAiC,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAetF,UAAU,gBAAgB;IACxB,IAAI,EAAE,IAAI,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,UAAU,WAAW;IACnB,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,gBAAgB,GAAG,WAAW,CAAC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AA6JD,wBAAsB,aAAa,CACjC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,IAAI,CAAC,CA6Gf;AA4ID,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,oBAAoB,CAE3E;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAIpE"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { existsSync, readFileSync, rmSync } from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { composeAgentLaunch, openAgentWorkspace, prepareAgentLaunch } from "../lib/agentLaunch.js";
|
|
4
|
+
import { inferAgentCommandName } from "../lib/launchCommand.js";
|
|
4
5
|
import { loadConfig, repositoryBaseDir } from "../lib/config.js";
|
|
5
6
|
import { resolvePullRequest } from "../lib/pullRequests.js";
|
|
6
7
|
import { resolvePrepareWorktreeCommand } from "../lib/repositoryHooks.js";
|
|
7
8
|
import { recordRunState, readRunState } from "../lib/runState.js";
|
|
9
|
+
import { seedLaunchWorkspaceTrust } from "../lib/seedLaunchWorkspaceTrust.js";
|
|
8
10
|
import { stageBuildSecrets, stagePromptText, stageWorkspaceLaunchCommand, } from "../lib/stagedLaunch.js";
|
|
9
11
|
import { normalizePlainTaskId } from "../lib/taskId.js";
|
|
10
12
|
import { debug, errorMessage, log, okMark } from "../lib/util.js";
|
|
@@ -159,6 +161,10 @@ export async function openWorkspace(config, options) {
|
|
|
159
161
|
defaultHooks: config.defaults.hooks,
|
|
160
162
|
});
|
|
161
163
|
const secretsFile = prepareWorktreeCommand === undefined ? undefined : stageBuildSecrets(stagedPrompt.directory);
|
|
164
|
+
seedLaunchWorkspaceTrust({
|
|
165
|
+
agentCommandName: inferAgentCommandName(definition.cmd),
|
|
166
|
+
launchDir,
|
|
167
|
+
});
|
|
162
168
|
let launchCommand;
|
|
163
169
|
({ launchCommand, srtSettingsDir } = composeAgentLaunch({
|
|
164
170
|
runner,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resumeWorkspace.d.ts","sourceRoot":"","sources":["../../src/commands/resumeWorkspace.ts"],"names":[],"mappings":"AAGA,OAAO,EAAoC,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"resumeWorkspace.d.ts","sourceRoot":"","sources":["../../src/commands/resumeWorkspace.ts"],"names":[],"mappings":"AAGA,OAAO,EAAoC,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAsBzF,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAyKD,wBAAsB,eAAe,CACnC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAwGf;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAGtE"}
|
|
@@ -3,8 +3,9 @@ import { getLinearClient } from "../lib/adapters/linear/client.js";
|
|
|
3
3
|
import { isLinearEnabled, sourcesFromConfig } from "../lib/buildSources.js";
|
|
4
4
|
import { loadConfig } from "../lib/config.js";
|
|
5
5
|
import { composeAgentLaunch, openAgentWorkspace, prepareAgentLaunch } from "../lib/agentLaunch.js";
|
|
6
|
-
import { withResumeArgs, workerEnvironmentForTask } from "../lib/launchCommand.js";
|
|
6
|
+
import { inferAgentCommandName, withResumeArgs, workerEnvironmentForTask, } from "../lib/launchCommand.js";
|
|
7
7
|
import { readRunState, recordRunState } from "../lib/runState.js";
|
|
8
|
+
import { seedLaunchWorkspaceTrust } from "../lib/seedLaunchWorkspaceTrust.js";
|
|
8
9
|
import { taskSupportsCompletionCommand } from "../lib/sourceCapabilities.js";
|
|
9
10
|
import { removeStagedPrompt, stageBuildSecrets, stagePromptText, stageWorkspaceLaunchCommand, } from "../lib/stagedLaunch.js";
|
|
10
11
|
import { taskSourceWritePathsForCompletion } from "../lib/taskSourceFilesystem.js";
|
|
@@ -183,6 +184,10 @@ export async function resumeWorkspace(config, options) {
|
|
|
183
184
|
workingDir: launchDir,
|
|
184
185
|
})
|
|
185
186
|
: undefined;
|
|
187
|
+
seedLaunchWorkspaceTrust({
|
|
188
|
+
agentCommandName: inferAgentCommandName(launchDefinition.cmd),
|
|
189
|
+
launchDir,
|
|
190
|
+
});
|
|
186
191
|
({ launchCommand, srtSettingsDir } = composeAgentLaunch({
|
|
187
192
|
runner,
|
|
188
193
|
networkEgress,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setupWorkspace.d.ts","sourceRoot":"","sources":["../../src/commands/setupWorkspace.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"setupWorkspace.d.ts","sourceRoot":"","sources":["../../src/commands/setupWorkspace.ts"],"names":[],"mappings":"AAEA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AA0BnE,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,6FAA6F;IAC7F,2BAA2B,CAAC,EAAE,OAAO,CAAC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAuBD,wBAAsB,cAAc,CAClC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,qBAAqB,EAC9B,UAAU,GAAE,wBAA6B,GACxC,OAAO,CAAC,IAAI,CAAC,CAqJf;AA8MD,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACjC,OAAO,CAAC,IAAI,CAAC,CAkDf"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { rmSync } from "node:fs";
|
|
2
2
|
import { loadConfig } from "../lib/config.js";
|
|
3
3
|
import { composeAgentLaunch, openAgentWorkspace, prepareAgentLaunch } from "../lib/agentLaunch.js";
|
|
4
|
+
import { inferAgentCommandName, workerEnvironmentForTask } from "../lib/launchCommand.js";
|
|
4
5
|
import { createBoard } from "../lib/board.js";
|
|
5
6
|
import { buildSources, sourcesFromConfig } from "../lib/buildSources.js";
|
|
6
|
-
import { workerEnvironmentForTask } from "../lib/launchCommand.js";
|
|
7
7
|
import { resolvePrepareWorktreeCommand } from "../lib/repositoryHooks.js";
|
|
8
8
|
import { recordRunState } from "../lib/runState.js";
|
|
9
|
+
import { seedLaunchWorkspaceTrust } from "../lib/seedLaunchWorkspaceTrust.js";
|
|
9
10
|
import { sourceSupportsMarkDone } from "../lib/sourceCapabilities.js";
|
|
10
11
|
import { stageBuildSecrets, stagePromptFromTemplate, stageWorkspaceLaunchCommand, } from "../lib/stagedLaunch.js";
|
|
11
12
|
import { taskSourceWritePathsForCompletion } from "../lib/taskSourceFilesystem.js";
|
|
@@ -103,6 +104,10 @@ export async function setupWorkspace(config, options, runOptions = {}) {
|
|
|
103
104
|
workingDir: launchDir,
|
|
104
105
|
})
|
|
105
106
|
: undefined;
|
|
107
|
+
seedLaunchWorkspaceTrust({
|
|
108
|
+
agentCommandName: inferAgentCommandName(definition.cmd),
|
|
109
|
+
launchDir,
|
|
110
|
+
});
|
|
106
111
|
const { launchCommand, srtSettingsDir: stagedSrtSettingsDir } = composeAgentLaunch({
|
|
107
112
|
runner,
|
|
108
113
|
networkEgress,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/linear/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI3C,QAAA,MAAM,sBAAsB,YAAI,2BAA2B,EAAE,gBAAgB,CAAU,CAAC;AAExF,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzE,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,kBAAkB,CAAC;CAC5B;AAED,wBAAgB,mBAAmB,IAAI,oBAAoB,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../src/lib/adapters/linear/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI3C,QAAA,MAAM,sBAAsB,YAAI,2BAA2B,EAAE,gBAAgB,CAAU,CAAC;AAExF,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzE,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,kBAAkB,CAAC;CAC5B;AAED,wBAAgB,mBAAmB,IAAI,oBAAoB,GAAG,SAAS,CActE;AAED,wBAAgB,eAAe,IAAI,YAAY,CAQ9C;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,YAAY,GAAG,MAAM,YAAY,CAMhF"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Record agent workspace trust for a launch directory. Fail-open: logs on
|
|
3
|
+
* error and returns so agent launch can continue.
|
|
4
|
+
*/
|
|
5
|
+
export declare function seedLaunchWorkspaceTrust(input: {
|
|
6
|
+
agentCommandName: string;
|
|
7
|
+
launchDir: string;
|
|
8
|
+
}): void;
|
|
9
|
+
//# sourceMappingURL=seedLaunchWorkspaceTrust.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seedLaunchWorkspaceTrust.d.ts","sourceRoot":"","sources":["../../src/lib/seedLaunchWorkspaceTrust.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAC9C,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,IAAI,CASP"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { agentTrustDir } from "agent-trust";
|
|
2
|
+
import { writeError } from "./util.js";
|
|
3
|
+
const GROUNDCREW_TRUST_METHOD = "groundcrew-auto-trust";
|
|
4
|
+
/**
|
|
5
|
+
* Record agent workspace trust for a launch directory. Fail-open: logs on
|
|
6
|
+
* error and returns so agent launch can continue.
|
|
7
|
+
*/
|
|
8
|
+
export function seedLaunchWorkspaceTrust(input) {
|
|
9
|
+
const result = agentTrustDir({
|
|
10
|
+
agent: input.agentCommandName,
|
|
11
|
+
dirPath: input.launchDir,
|
|
12
|
+
trustMethod: GROUNDCREW_TRUST_METHOD,
|
|
13
|
+
});
|
|
14
|
+
if (!result.ok) {
|
|
15
|
+
writeError(`groundcrew: ${result.error}`);
|
|
16
|
+
}
|
|
17
|
+
}
|
package/dist/lib/worktrees.d.ts
CHANGED
|
@@ -58,6 +58,13 @@ export type WorktreeDirtiness = {
|
|
|
58
58
|
} | {
|
|
59
59
|
kind: "unknown";
|
|
60
60
|
};
|
|
61
|
+
export declare function isRecoverableRemovalError(error: unknown): boolean;
|
|
62
|
+
export interface ForceRemoveDirectoryOptions {
|
|
63
|
+
attempts?: number;
|
|
64
|
+
delayMs?: number;
|
|
65
|
+
remove?: (target: string) => void;
|
|
66
|
+
}
|
|
67
|
+
export declare function forceRemoveDirectory(targetDir: string, options?: ForceRemoveDirectoryOptions): Promise<void>;
|
|
61
68
|
declare function list(config: ResolvedConfig): WorktreeEntry[];
|
|
62
69
|
declare function findByTask(config: ResolvedConfig, task: string): WorktreeEntry[];
|
|
63
70
|
export interface PredictedWorktreeEntry {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worktrees.d.ts","sourceRoot":"","sources":["../../src/lib/worktrees.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;
|
|
1
|
+
{"version":3,"file":"worktrees.d.ts","sourceRoot":"","sources":["../../src/lib/worktrees.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/worktrees.js
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
import { existsSync, readdirSync, rmSync, statSync } from "node:fs";
|
|
12
12
|
import { userInfo } from "node:os";
|
|
13
13
|
import path from "node:path";
|
|
14
|
+
import { setTimeout as sleep } from "node:timers/promises";
|
|
14
15
|
import { applySubstitutions } from "./adapters/shell/invoke.js";
|
|
15
16
|
import { runCommandAsync } from "./commandRunner.js";
|
|
16
17
|
import { repositoryBaseDir, worktreeBaseDir, } from "./config.js";
|
|
@@ -384,7 +385,7 @@ async function removeWorktree(config, entry, options) {
|
|
|
384
385
|
if (registration !== "orphan") {
|
|
385
386
|
throw error;
|
|
386
387
|
}
|
|
387
|
-
removeOrphanWorktreeDirectory(config, entry);
|
|
388
|
+
await removeOrphanWorktreeDirectory(config, entry);
|
|
388
389
|
}
|
|
389
390
|
else {
|
|
390
391
|
const dirtiness = await throwIfWorktreeDirty(entry, options.signal, error);
|
|
@@ -533,7 +534,46 @@ function isInsideDirectory(parentDir, childDir) {
|
|
|
533
534
|
!childRelativePath.startsWith("..") &&
|
|
534
535
|
!path.isAbsolute(childRelativePath));
|
|
535
536
|
}
|
|
536
|
-
|
|
537
|
+
// APFS reports ENOTEMPTY (and occasionally EBUSY/EPERM) from a recursive rmdir
|
|
538
|
+
// when directory-entry caches lag behind the unlinks that just emptied it. This
|
|
539
|
+
// bites large trees like node_modules, where `rmSync` bails partway through even
|
|
540
|
+
// though a plain `rm -rf` succeeds. Retrying the removal lets the caches settle
|
|
541
|
+
// and drains the remaining entries.
|
|
542
|
+
const RECOVERABLE_REMOVAL_ERROR_CODES = new Set([
|
|
543
|
+
"ENOTEMPTY",
|
|
544
|
+
"EBUSY",
|
|
545
|
+
"EPERM",
|
|
546
|
+
"EMFILE",
|
|
547
|
+
"ENFILE",
|
|
548
|
+
]);
|
|
549
|
+
export function isRecoverableRemovalError(error) {
|
|
550
|
+
return (error instanceof Error &&
|
|
551
|
+
"code" in error &&
|
|
552
|
+
typeof error.code === "string" &&
|
|
553
|
+
RECOVERABLE_REMOVAL_ERROR_CODES.has(error.code));
|
|
554
|
+
}
|
|
555
|
+
export async function forceRemoveDirectory(targetDir, options = {}) {
|
|
556
|
+
const attempts = options.attempts ?? 8;
|
|
557
|
+
const delayMs = options.delayMs ?? 100;
|
|
558
|
+
const removeDirectory = options.remove ??
|
|
559
|
+
((target) => {
|
|
560
|
+
rmSync(target, { recursive: true, force: true });
|
|
561
|
+
});
|
|
562
|
+
for (let attempt = 1;; attempt += 1) {
|
|
563
|
+
try {
|
|
564
|
+
removeDirectory(targetDir);
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
catch (error) {
|
|
568
|
+
if (attempt >= attempts || !isRecoverableRemovalError(error)) {
|
|
569
|
+
throw error;
|
|
570
|
+
}
|
|
571
|
+
// oxlint-disable-next-line no-await-in-loop -- retries are intentionally serial with a settle delay between attempts.
|
|
572
|
+
await sleep(delayMs);
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
async function removeOrphanWorktreeDirectory(config, entry) {
|
|
537
577
|
const worktreeRoot = path.resolve(worktreeBaseDir(config));
|
|
538
578
|
const expectedDir = expectedHostWorktreeDir(config, entry);
|
|
539
579
|
const targetDir = path.resolve(entry.dir);
|
|
@@ -541,7 +581,7 @@ function removeOrphanWorktreeDirectory(config, entry) {
|
|
|
541
581
|
throw new Error(`Refusing to force-delete ${entry.dir}: expected groundcrew worktree path ${expectedDir}.`);
|
|
542
582
|
}
|
|
543
583
|
debug(`Removing orphaned worktree directory ${entry.dir} (--force)...`);
|
|
544
|
-
|
|
584
|
+
await forceRemoveDirectory(targetDir);
|
|
545
585
|
}
|
|
546
586
|
function list(config) {
|
|
547
587
|
return listWorktrees(config);
|
package/docs/troubleshooting.md
CHANGED
|
@@ -52,6 +52,20 @@ If the task intentionally has no PR, mark it complete with `crew task done <task
|
|
|
52
52
|
|
|
53
53
|
Groundcrew creates isolated per-task worktrees for unattended runs, so the shipped `claude` command is `claude --permission-mode auto` to let Claude proceed without stopping for clarifying questions while keeping its built-in safety prompts intact. Override `agents.definitions.claude.cmd` for `bypassPermissions` if you need to suppress tool-permission prompts entirely, or for a stricter mode.
|
|
54
54
|
|
|
55
|
+
## Workspace Trust Is Seeded Automatically
|
|
56
|
+
|
|
57
|
+
Groundcrew provisions each worktree and records workspace trust for `claude`, `codex`, and `cursor-agent` before the agent starts (via [`agent-trust`](https://www.npmjs.com/package/agent-trust)), so unattended launches do not stall on first-run trust dialogs. There is no config toggle: if groundcrew created the worktree, trust is recorded in the agent's local store (`~/.claude.json` for Claude, `~/.codex/config.toml` for Codex, `~/.cursor/projects/<slug>/.workspace-trusted` for Cursor) for the worktree launch directory. Cursor markers use `trustMethod: "groundcrew-auto-trust"` for auditability. This applies only to groundcrew-provisioned worktrees at launch time; it does not trust arbitrary paths you open manually. Permission mode (`claude --permission-mode auto`) and Codex approval bypass (`--dangerously-bypass-approvals-and-sandbox`) are separate from workspace trust.
|
|
58
|
+
|
|
59
|
+
Inspect or clean trust entries with the published CLI:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npm i -g agent-trust
|
|
63
|
+
agent-trust list
|
|
64
|
+
agent-trust list --missing
|
|
65
|
+
agent-trust remove --trust-method groundcrew-auto-trust --all --agent cursor
|
|
66
|
+
agent-trust prune
|
|
67
|
+
```
|
|
68
|
+
|
|
55
69
|
## Doctor's Command Introspection Is Shallow
|
|
56
70
|
|
|
57
71
|
Doctor reports the resolved local runner and whether its prerequisites are met, then tokenizes agent `cmd` and checks the first two non-flag tokens against PATH. Boolean flags without values, env-var assignments (`FOO=1`), shell pipelines, and subshells are not parsed. When `local.runner` is `"none"`, doctor surfaces a single WARNING line.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clipboard-health/groundcrew",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.47.1",
|
|
4
4
|
"description": "Linear-driven orchestrator that launches AI coding agents in git worktrees, with workspace lifecycle and usage tracking.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
|
@@ -73,6 +73,7 @@
|
|
|
73
73
|
"@anthropic-ai/sandbox-runtime": "0.0.63",
|
|
74
74
|
"@clipboard-health/clearance": "1.4.4",
|
|
75
75
|
"@linear/sdk": "88.0.0",
|
|
76
|
+
"agent-trust": "1.0.0",
|
|
76
77
|
"cosmiconfig": "9.0.2",
|
|
77
78
|
"tslib": "2.8.1",
|
|
78
79
|
"zod": "4.4.3"
|
|
@@ -83,8 +84,8 @@
|
|
|
83
84
|
"@nx/js": "22.7.6",
|
|
84
85
|
"@tsconfig/node24": "24.0.4",
|
|
85
86
|
"@tsconfig/strictest": "2.0.8",
|
|
86
|
-
"@types/node": "25.9.
|
|
87
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
87
|
+
"@types/node": "25.9.5",
|
|
88
|
+
"@typescript/native-preview": "7.0.0-dev.20260707.2",
|
|
88
89
|
"@vitest/coverage-v8": "4.1.9",
|
|
89
90
|
"cspell": "10.0.1",
|
|
90
91
|
"dependency-cruiser": "18.0.0",
|