@clipboard-health/groundcrew 4.37.0 → 4.38.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/clearance-allow-hosts +6 -0
- package/dist/commands/dispatcher.d.ts.map +1 -1
- package/dist/commands/dispatcher.js +7 -0
- package/dist/commands/resumeWorkspace.d.ts.map +1 -1
- package/dist/commands/resumeWorkspace.js +18 -4
- package/dist/commands/setupWorkspace.d.ts +2 -0
- package/dist/commands/setupWorkspace.d.ts.map +1 -1
- package/dist/commands/setupWorkspace.js +12 -2
- package/dist/lib/config.js +1 -1
- package/dist/lib/launchCommand.d.ts +8 -4
- package/dist/lib/launchCommand.d.ts.map +1 -1
- package/dist/lib/launchCommand.js +15 -4
- package/dist/lib/sourceCapabilities.d.ts +8 -0
- package/dist/lib/sourceCapabilities.d.ts.map +1 -1
- package/dist/lib/sourceCapabilities.js +26 -1
- package/docs/runners.md +1 -1
- package/docs/task-sources.md +5 -4
- package/package.json +1 -1
package/clearance-allow-hosts
CHANGED
|
@@ -73,6 +73,12 @@ conda.anaconda.org
|
|
|
73
73
|
registry.npmjs.org
|
|
74
74
|
www.npmjs.com
|
|
75
75
|
|
|
76
|
+
# PyPI registry + package CDN (pip / uv). pypi.org serves the Simple index;
|
|
77
|
+
# files.pythonhosted.org serves the wheel/sdist artifacts. uv's managed-Python
|
|
78
|
+
# downloads come from github.com (already allowed above).
|
|
79
|
+
files.pythonhosted.org
|
|
80
|
+
pypi.org
|
|
81
|
+
|
|
76
82
|
# Google APIs
|
|
77
83
|
developers.google.com
|
|
78
84
|
www.googleapis.com
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/commands/dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/commands/dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGvD,OAAO,EACL,KAAK,UAAU,EAGf,KAAK,KAAK,EAEX,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAGpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAWzD,UAAU,cAAc;IACtB,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,EAAE,KAAK,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,CAAC,UAAU,EAAE;QACpB,KAAK,EAAE,UAAU,CAAC;QAClB,eAAe,EAAE,SAAS,aAAa,EAAE,CAAC;QAC1C,+FAA+F;QAC/F,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;QACvD,MAAM,EAAE,OAAO,CAAC;QAChB,MAAM,CAAC,EAAE,WAAW,CAAC;QACrB;;;;WAIG;QACH,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrB;AAiCD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,UAAU,CAyOjE;AA2BD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,GAAG,MAAM,CAQrE"}
|
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
* Pure verdict logic lives in `eligibility.ts`; this module is responsible
|
|
7
7
|
* for telemetry, writeback via Board, and side-effecting setupWorkspace calls.
|
|
8
8
|
*/
|
|
9
|
+
import { sourcesFromConfig } from "../lib/buildSources.js";
|
|
9
10
|
import { dispatchableRepository, formatKnownRepositories } from "../lib/repositoryValidation.js";
|
|
11
|
+
import { sourceSupportsMarkDone } from "../lib/sourceCapabilities.js";
|
|
10
12
|
import { isGroundcrewIssue, naturalIdFromCanonical, } from "../lib/taskSource.js";
|
|
11
13
|
import { errorMessage, failMark, log, logEvent, styleWarning } from "../lib/util.js";
|
|
12
14
|
import { workspaces } from "../lib/workspaces.js";
|
|
@@ -35,6 +37,7 @@ function logMissingRepositorySkip(issue, agent, knownRepositories) {
|
|
|
35
37
|
}
|
|
36
38
|
export function createDispatcher(deps) {
|
|
37
39
|
const { config, board } = deps;
|
|
40
|
+
const rawSources = sourcesFromConfig(config);
|
|
38
41
|
function buildExhaustedSet(usage) {
|
|
39
42
|
const exhausted = new Set();
|
|
40
43
|
for (const exhaustion of classifyUsageExhaustion(config, usage)) {
|
|
@@ -71,6 +74,10 @@ export function createDispatcher(deps) {
|
|
|
71
74
|
repository: issue.repository,
|
|
72
75
|
task: taskId,
|
|
73
76
|
completionTaskId: issue.id,
|
|
77
|
+
completionMarkDoneSupported: sourceSupportsMarkDone({
|
|
78
|
+
rawSources,
|
|
79
|
+
sourceName: issue.source,
|
|
80
|
+
}),
|
|
74
81
|
agent: issue.agent,
|
|
75
82
|
details: {
|
|
76
83
|
title: issue.title,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resumeWorkspace.d.ts","sourceRoot":"","sources":["../../src/commands/resumeWorkspace.ts"],"names":[],"mappings":"AAGA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"resumeWorkspace.d.ts","sourceRoot":"","sources":["../../src/commands/resumeWorkspace.ts"],"names":[],"mappings":"AAGA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAiBnE,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;CACd;AAqJD,wBAAsB,eAAe,CACnC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,IAAI,CAAC,CA0Ff;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAGtE"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { fetchResolvedIssue } from "../lib/adapters/linear/fetch.js";
|
|
2
2
|
import { getLinearClient } from "../lib/adapters/linear/client.js";
|
|
3
|
-
import { isLinearEnabled } from "../lib/buildSources.js";
|
|
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
6
|
import { workerEnvironmentForTask } from "../lib/launchCommand.js";
|
|
7
7
|
import { readRunState, recordRunState } from "../lib/runState.js";
|
|
8
|
+
import { taskSupportsCompletionCommand } from "../lib/sourceCapabilities.js";
|
|
8
9
|
import { removeStagedPrompt, stageBuildSecrets, stagePromptText, stageWorkspaceLaunchCommand, } from "../lib/stagedLaunch.js";
|
|
9
10
|
import { taskSourceWritePathsForCompletion } from "../lib/taskSourceFilesystem.js";
|
|
10
11
|
import { naturalIdFromCanonical, toCanonicalId } from "../lib/taskSource.js";
|
|
@@ -33,6 +34,7 @@ async function fetchTaskDetails(task) {
|
|
|
33
34
|
}
|
|
34
35
|
async function contextFromLinear(config, task, worktree) {
|
|
35
36
|
const resolved = await fetchResolvedIssue({ client: getLinearClient(), config, task });
|
|
37
|
+
const completionTaskId = toCanonicalId("linear", task);
|
|
36
38
|
return {
|
|
37
39
|
task,
|
|
38
40
|
repository: resolved.repository,
|
|
@@ -40,7 +42,11 @@ async function contextFromLinear(config, task, worktree) {
|
|
|
40
42
|
worktree,
|
|
41
43
|
title: resolved.title,
|
|
42
44
|
description: resolved.description,
|
|
43
|
-
completionTaskId
|
|
45
|
+
completionTaskId,
|
|
46
|
+
completionMarkDoneSupported: taskSupportsCompletionCommand({
|
|
47
|
+
rawSources: sourcesFromConfig(config),
|
|
48
|
+
taskId: completionTaskId,
|
|
49
|
+
}),
|
|
44
50
|
resumeCount: 0,
|
|
45
51
|
};
|
|
46
52
|
}
|
|
@@ -49,6 +55,7 @@ async function contextFromState(config, task, state, worktree) {
|
|
|
49
55
|
// missing-API-key error logs noisily even though resume only needs it to
|
|
50
56
|
// enrich the prompt title/description (which falls back to the task id).
|
|
51
57
|
const details = isLinearEnabled(config) ? await fetchTaskDetails(task) : undefined;
|
|
58
|
+
const completionTaskId = state.completionTaskId ?? task;
|
|
52
59
|
return {
|
|
53
60
|
task,
|
|
54
61
|
repository: state.repository,
|
|
@@ -56,7 +63,11 @@ async function contextFromState(config, task, state, worktree) {
|
|
|
56
63
|
worktree,
|
|
57
64
|
title: details?.title ?? task.toUpperCase(),
|
|
58
65
|
description: details?.description ?? "",
|
|
59
|
-
completionTaskId
|
|
66
|
+
completionTaskId,
|
|
67
|
+
completionMarkDoneSupported: taskSupportsCompletionCommand({
|
|
68
|
+
rawSources: sourcesFromConfig(config),
|
|
69
|
+
taskId: completionTaskId,
|
|
70
|
+
}),
|
|
60
71
|
...(state.reason === undefined ? {} : { reason: state.reason }),
|
|
61
72
|
resumeCount: state.resumeCount,
|
|
62
73
|
};
|
|
@@ -159,7 +170,10 @@ export async function resumeWorkspace(config, options) {
|
|
|
159
170
|
secretsFile,
|
|
160
171
|
sandboxName,
|
|
161
172
|
workspaceKind,
|
|
162
|
-
workerEnvironment: workerEnvironmentForTask(
|
|
173
|
+
workerEnvironment: workerEnvironmentForTask({
|
|
174
|
+
taskId: context.completionTaskId,
|
|
175
|
+
markDoneSupported: context.completionMarkDoneSupported,
|
|
176
|
+
}),
|
|
163
177
|
taskSourceWritePaths,
|
|
164
178
|
}));
|
|
165
179
|
const launchCmd = stageWorkspaceLaunchCommand(stagedPrompt.directory, launchCommand);
|
|
@@ -9,6 +9,8 @@ export interface SetupWorkspaceOptions {
|
|
|
9
9
|
task: string;
|
|
10
10
|
/** Canonical source id for worker self-completion; falls back to `task`. */
|
|
11
11
|
completionTaskId?: string;
|
|
12
|
+
/** Whether the task source can apply `crew task done`; defaults to true for direct calls. */
|
|
13
|
+
completionMarkDoneSupported?: boolean;
|
|
12
14
|
repository: string;
|
|
13
15
|
agent: string;
|
|
14
16
|
details: TaskDetails;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setupWorkspace.d.ts","sourceRoot":"","sources":["../../src/commands/setupWorkspace.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"setupWorkspace.d.ts","sourceRoot":"","sources":["../../src/commands/setupWorkspace.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAyBnE,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,CA4If;AAgJD,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACjC,OAAO,CAAC,IAAI,CAAC,CAkDf"}
|
|
@@ -6,6 +6,7 @@ import { buildSources, sourcesFromConfig } from "../lib/buildSources.js";
|
|
|
6
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 { sourceSupportsMarkDone } from "../lib/sourceCapabilities.js";
|
|
9
10
|
import { stageBuildSecrets, stagePromptFromTemplate, stageWorkspaceLaunchCommand, } from "../lib/stagedLaunch.js";
|
|
10
11
|
import { taskSourceWritePathsForCompletion } from "../lib/taskSourceFilesystem.js";
|
|
11
12
|
import { naturalIdFromCanonical } from "../lib/taskSource.js";
|
|
@@ -83,6 +84,7 @@ export async function setupWorkspace(config, options, runOptions = {}) {
|
|
|
83
84
|
});
|
|
84
85
|
const secretsFile = prepareWorktreeCommand === undefined ? undefined : stageBuildSecrets(promptDir);
|
|
85
86
|
const completionTaskId = options.completionTaskId ?? task;
|
|
87
|
+
const completionMarkDoneSupported = options.completionMarkDoneSupported ?? true;
|
|
86
88
|
const taskSourceWritePaths = runner === "safehouse" || runner === "srt"
|
|
87
89
|
? taskSourceWritePathsForCompletion({
|
|
88
90
|
config,
|
|
@@ -101,7 +103,10 @@ export async function setupWorkspace(config, options, runOptions = {}) {
|
|
|
101
103
|
prepareWorktreeCommand,
|
|
102
104
|
sandboxName,
|
|
103
105
|
workspaceKind,
|
|
104
|
-
workerEnvironment: workerEnvironmentForTask(
|
|
106
|
+
workerEnvironment: workerEnvironmentForTask({
|
|
107
|
+
taskId: completionTaskId,
|
|
108
|
+
markDoneSupported: completionMarkDoneSupported,
|
|
109
|
+
}),
|
|
105
110
|
taskSourceWritePaths,
|
|
106
111
|
});
|
|
107
112
|
srtSettingsDir = stagedSrtSettingsDir;
|
|
@@ -264,9 +269,10 @@ async function rollbackWorktree(arguments_) {
|
|
|
264
269
|
}
|
|
265
270
|
export async function setupWorkspaceCli(task, options = {}) {
|
|
266
271
|
const config = await loadConfig();
|
|
272
|
+
const rawSources = sourcesFromConfig(config);
|
|
267
273
|
let sources;
|
|
268
274
|
try {
|
|
269
|
-
sources = await buildSources(
|
|
275
|
+
sources = await buildSources(rawSources, { globalConfig: config });
|
|
270
276
|
}
|
|
271
277
|
catch (error) {
|
|
272
278
|
/* v8 ignore next @preserve -- catch re-throw always receives an Error; String(error) is an unreachable fallback */
|
|
@@ -292,6 +298,10 @@ export async function setupWorkspaceCli(task, options = {}) {
|
|
|
292
298
|
await setupWorkspace(config, {
|
|
293
299
|
task: naturalId,
|
|
294
300
|
completionTaskId: resolved.id,
|
|
301
|
+
completionMarkDoneSupported: sourceSupportsMarkDone({
|
|
302
|
+
rawSources,
|
|
303
|
+
sourceName: resolved.source,
|
|
304
|
+
}),
|
|
295
305
|
repository: resolved.repository,
|
|
296
306
|
agent: resolved.agent,
|
|
297
307
|
details: {
|
package/dist/lib/config.js
CHANGED
|
@@ -108,7 +108,7 @@ const DEFAULT_PROMPT_INITIAL = [
|
|
|
108
108
|
"2. Implement the smallest sensible change that completes the task.",
|
|
109
109
|
"3. Run the repo's documented verification command. If no documented command exists, run the smallest relevant test suite you can find and fix failures you introduced before continuing.",
|
|
110
110
|
"4. Follow the task description for output. If no output instructions exist, open a PR with `Closes {{task}}` in the description. If you cannot open one, leave the branch ready and record the blocker.",
|
|
111
|
-
"5. If the requested work is complete, no PR is needed, and any dirty worktree state is expected or explicitly allowed, run the command in `GROUNDCREW_COMPLETE` to mark the task done.",
|
|
111
|
+
"5. If the requested work is complete, no PR is needed, `GROUNDCREW_COMPLETE` is set, and any dirty worktree state is expected or explicitly allowed, run the command in `GROUNDCREW_COMPLETE` to mark the task done.",
|
|
112
112
|
].join("\n");
|
|
113
113
|
const ALLOWED_PROMPT_PLACEHOLDERS = new Set([
|
|
114
114
|
"{{task}}",
|
|
@@ -37,10 +37,14 @@ export declare function isEnvironmentAssignment(token: string): boolean;
|
|
|
37
37
|
* profile; srt uses it to pick the agent's credential profile in `srtPolicy`.
|
|
38
38
|
*/
|
|
39
39
|
export declare function inferAgentCommandName(agentCmd: string): string;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
export type WorkerEnvironment = Readonly<{
|
|
41
|
+
GROUNDCREW_TASK_ID: string;
|
|
42
|
+
GROUNDCREW_COMPLETE?: string;
|
|
43
|
+
}>;
|
|
44
|
+
export declare function workerEnvironmentForTask(arguments_: {
|
|
45
|
+
taskId: string;
|
|
46
|
+
markDoneSupported: boolean;
|
|
47
|
+
}): WorkerEnvironment;
|
|
44
48
|
export interface SafehouseAgentIntegration {
|
|
45
49
|
addDirsReadOnly: readonly string[];
|
|
46
50
|
envPass: readonly string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"launchCommand.d.ts","sourceRoot":"","sources":["../../src/lib/launchCommand.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,KAAK,WAAW,EAChB,KAAK,eAAe,EACrB,MAAM,aAAa,CAAC;AAIrB,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;;;;;GASG;AACH,wBAAgB,6BAA6B,CAAC,OAAO,GAAE,MAAwB,GAAG,MAAM,CAcvF;AAID;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,MAAwB,GAAG,MAAM,CAgB3E;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAAG,MAAM,CAMvF;AAsMD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CA8B9D;
|
|
1
|
+
{"version":3,"file":"launchCommand.d.ts","sourceRoot":"","sources":["../../src/lib/launchCommand.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,KAAK,WAAW,EAChB,KAAK,eAAe,EACrB,MAAM,aAAa,CAAC;AAIrB,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;;;;;GASG;AACH,wBAAgB,6BAA6B,CAAC,OAAO,GAAE,MAAwB,GAAG,MAAM,CAcvF;AAID;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,MAAwB,GAAG,MAAM,CAgB3E;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAAG,MAAM,CAMvF;AAsMD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CA8B9D;AAMD,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IACvC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC,CAAC;AAEH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,OAAO,CAAC;CAC5B,GAAG,iBAAiB,CAMpB;AA8BD,MAAM,WAAW,yBAAyB;IACxC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED,UAAU,sBAAsB;IAC9B,UAAU,EAAE,eAAe,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5C;;;;OAIG;IACH,MAAM,EAAE,WAAW,CAAC;IACpB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5C;;;OAGG;IACH,oBAAoB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC;;;;;;;OAOG;IACH,oBAAoB,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IACnE;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IACjD;;;OAGG;IACH,qBAAqB,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IACtD;;;;;OAKG;IACH,yBAAyB,CAAC,EAAE,yBAAyB,GAAG,SAAS,CAAC;IAClE;;;OAGG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;CACnD;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,sBAAsB,GAAG,MAAM,CAkC7E"}
|
|
@@ -248,20 +248,31 @@ export function inferAgentCommandName(agentCmd) {
|
|
|
248
248
|
return commandName;
|
|
249
249
|
}
|
|
250
250
|
const WORKER_ENVIRONMENT_NAMES = ["GROUNDCREW_TASK_ID", "GROUNDCREW_COMPLETE"];
|
|
251
|
-
export function workerEnvironmentForTask(
|
|
251
|
+
export function workerEnvironmentForTask(arguments_) {
|
|
252
|
+
const { taskId, markDoneSupported } = arguments_;
|
|
252
253
|
return {
|
|
253
254
|
GROUNDCREW_TASK_ID: taskId,
|
|
254
|
-
GROUNDCREW_COMPLETE: `crew task done ${taskId}
|
|
255
|
+
...(markDoneSupported ? { GROUNDCREW_COMPLETE: `crew task done ${taskId}` } : {}),
|
|
255
256
|
};
|
|
256
257
|
}
|
|
257
258
|
function workerEnvironmentNames(workerEnvironment) {
|
|
258
|
-
|
|
259
|
+
if (workerEnvironment === undefined) {
|
|
260
|
+
return [];
|
|
261
|
+
}
|
|
262
|
+
return WORKER_ENVIRONMENT_NAMES.filter((name) => workerEnvironment[name] !== undefined);
|
|
259
263
|
}
|
|
260
264
|
function workerEnvironmentExports(workerEnvironment) {
|
|
261
265
|
if (workerEnvironment === undefined) {
|
|
262
266
|
return [];
|
|
263
267
|
}
|
|
264
|
-
|
|
268
|
+
const exports = [];
|
|
269
|
+
for (const name of WORKER_ENVIRONMENT_NAMES) {
|
|
270
|
+
const value = workerEnvironment[name];
|
|
271
|
+
if (value !== undefined) {
|
|
272
|
+
exports.push(`export ${name}=${shellSingleQuote(value)}`);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return exports;
|
|
265
276
|
}
|
|
266
277
|
function envPassFlag(names) {
|
|
267
278
|
const uniqueNames = [...new Set(names)];
|
|
@@ -14,5 +14,13 @@ export interface SourceSummary {
|
|
|
14
14
|
capabilities: SourceCapabilities;
|
|
15
15
|
}
|
|
16
16
|
export declare function summarizeSource(raw: unknown): SourceSummary;
|
|
17
|
+
export declare function sourceSupportsMarkDone(arguments_: {
|
|
18
|
+
rawSources: readonly unknown[];
|
|
19
|
+
sourceName: string;
|
|
20
|
+
}): boolean;
|
|
21
|
+
export declare function taskSupportsCompletionCommand(arguments_: {
|
|
22
|
+
rawSources: readonly unknown[];
|
|
23
|
+
taskId: string;
|
|
24
|
+
}): boolean;
|
|
17
25
|
export {};
|
|
18
26
|
//# sourceMappingURL=sourceCapabilities.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sourceCapabilities.d.ts","sourceRoot":"","sources":["../../src/lib/sourceCapabilities.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sourceCapabilities.d.ts","sourceRoot":"","sources":["../../src/lib/sourceCapabilities.ts"],"names":[],"mappings":"AAIA,UAAU,kBAAkB;IAC1B,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;IACxB,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,kBAAkB,CAAC;CAClC;AAqDD,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,aAAa,CAiB3D;AAED,wBAAgB,sBAAsB,CAAC,UAAU,EAAE;IACjD,UAAU,EAAE,SAAS,OAAO,EAAE,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CASV;AAED,wBAAgB,6BAA6B,CAAC,UAAU,EAAE;IACxD,UAAU,EAAE,SAAS,OAAO,EAAE,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAcV"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { shellAdapterConfigSchema } from "./adapters/shell/schema.js";
|
|
3
|
-
import { kindShape } from "./buildSources.js";
|
|
4
3
|
const nameShape = z.looseObject({ name: z.string().optional() });
|
|
4
|
+
const kindShape = z.object({ kind: z.string() });
|
|
5
5
|
const LINEAR_CAPABILITIES = {
|
|
6
6
|
verify: true,
|
|
7
7
|
listTasks: true,
|
|
@@ -65,3 +65,28 @@ export function summarizeSource(raw) {
|
|
|
65
65
|
}
|
|
66
66
|
return { name: sourceName, kind, capabilities };
|
|
67
67
|
}
|
|
68
|
+
export function sourceSupportsMarkDone(arguments_) {
|
|
69
|
+
const { rawSources, sourceName } = arguments_;
|
|
70
|
+
for (const rawSource of rawSources) {
|
|
71
|
+
const source = summarizeSource(rawSource);
|
|
72
|
+
if (source.name === sourceName) {
|
|
73
|
+
return source.capabilities.markDone;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
export function taskSupportsCompletionCommand(arguments_) {
|
|
79
|
+
const { rawSources, taskId } = arguments_;
|
|
80
|
+
const colonIndex = taskId.indexOf(":");
|
|
81
|
+
if (colonIndex === -1) {
|
|
82
|
+
const [singleSource] = rawSources;
|
|
83
|
+
if (rawSources.length === 1 && singleSource !== undefined) {
|
|
84
|
+
return summarizeSource(singleSource).capabilities.markDone;
|
|
85
|
+
}
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
return sourceSupportsMarkDone({
|
|
89
|
+
rawSources,
|
|
90
|
+
sourceName: taskId.slice(0, colonIndex),
|
|
91
|
+
});
|
|
92
|
+
}
|
package/docs/runners.md
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
Only applies when `local.runner` resolves to `safehouse`. Groundcrew starts `clearance` on `http://127.0.0.1:19999` and runs the agent through the bundled `safehouse-clearance` wrapper. Groundcrew automatically points clearance at its shipped starter allowlist, so a fresh install does not need a `CLEARANCE_ALLOW_HOSTS_FILES` export.
|
|
17
17
|
|
|
18
|
-
Groundcrew ships that starter file at `$(npm root -g)/@clipboard-health/groundcrew/clearance-allow-hosts`, covering model APIs, Linear, Notion, Slack, Datadog, GitHub, npm, and common dev tooling.
|
|
18
|
+
Groundcrew ships that starter file at `$(npm root -g)/@clipboard-health/groundcrew/clearance-allow-hosts`, covering model APIs, Linear, Notion, Slack, Datadog, GitHub, npm, PyPI, and common dev tooling.
|
|
19
19
|
|
|
20
20
|
To add ad hoc hosts for one run, use `CLEARANCE_ALLOW_HOSTS`:
|
|
21
21
|
|
package/docs/task-sources.md
CHANGED
|
@@ -40,10 +40,11 @@ completed no-PR work. If omitted, groundcrew treats done advancement as
|
|
|
40
40
|
unsupported and leaves the task for the source's own integration to close out.
|
|
41
41
|
`${id}`, `${canonicalId}`, and `${name}` placeholders are shell-quoted before substitution.
|
|
42
42
|
|
|
43
|
-
Workers receive `GROUNDCREW_TASK_ID`
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
43
|
+
Workers receive `GROUNDCREW_TASK_ID` in their launch environment. They receive
|
|
44
|
+
`GROUNDCREW_COMPLETE` only when the source supports done writeback. The default
|
|
45
|
+
prompt tells them to run `GROUNDCREW_COMPLETE` only when it is set, the
|
|
46
|
+
requested work is complete, no PR is needed, and any dirty worktree state is
|
|
47
|
+
expected or explicitly allowed.
|
|
47
48
|
|
|
48
49
|
```json
|
|
49
50
|
[
|
package/package.json
CHANGED