@nseng-ai/ccc 0.1.1 → 0.1.2
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/package.json +10 -10
- package/src/cmux/branch-slug.ts +15 -39
- package/src/cmux/dispatch-from-trunk.ts +106 -16
- package/src/cmux/sidebar.ts +3 -2
- package/src/cmux/slot-dispatch-plan.ts +2 -1
- package/src/ns/autobranch/checkpoint.ts +1 -1
- package/src/ns/cli-command-io.ts +2 -2
- package/src/ns/cli.ts +5 -3
- package/src/ns/land.ts +6 -1
- package/src/pi/dispatch-from-trunk.ts +7 -1
- package/src/pi/slot-dispatch-plan.ts +1 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nseng-ai/ccc",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"src"
|
|
@@ -26,15 +26,15 @@
|
|
|
26
26
|
"./pi/extension": "./src/pi/extension.ts"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@nseng-ai/branch-context": "0.1.
|
|
30
|
-
"@nseng-ai/capability-kit": "0.1.
|
|
31
|
-
"@nseng-ai/clinkr": "0.1.
|
|
32
|
-
"@nseng-ai/foundation": "0.1.
|
|
33
|
-
"@nseng-ai/flow": "0.1.
|
|
34
|
-
"@nseng-ai/
|
|
35
|
-
"@nseng-ai/objectives": "0.1.
|
|
36
|
-
"@nseng-ai/plans": "0.1.
|
|
37
|
-
"@nseng-ai/slots": "0.1.
|
|
29
|
+
"@nseng-ai/branch-context": "0.1.2",
|
|
30
|
+
"@nseng-ai/capability-kit": "0.1.2",
|
|
31
|
+
"@nseng-ai/clinkr": "0.1.2",
|
|
32
|
+
"@nseng-ai/foundation": "0.1.2",
|
|
33
|
+
"@nseng-ai/flow": "0.1.2",
|
|
34
|
+
"@nseng-ai/kernel": "0.1.2",
|
|
35
|
+
"@nseng-ai/objectives": "0.1.2",
|
|
36
|
+
"@nseng-ai/plans": "0.1.2",
|
|
37
|
+
"@nseng-ai/slots": "0.1.2",
|
|
38
38
|
"zod": "^4.4.3"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
package/src/cmux/branch-slug.ts
CHANGED
|
@@ -4,15 +4,15 @@ import {
|
|
|
4
4
|
sanitizeBranchName,
|
|
5
5
|
trimBranchSlugToLength,
|
|
6
6
|
} from "@nseng-ai/foundation/branch-slug";
|
|
7
|
+
import {
|
|
8
|
+
formatRawTextModelFailure,
|
|
9
|
+
generateRawTextWithModel,
|
|
10
|
+
} from "@nseng-ai/capability-kit/model-slug";
|
|
7
11
|
import type { TextResult } from "@nseng-ai/foundation/primitives";
|
|
8
12
|
import type { ExtensionAPI } from "@nseng-ai/capability-kit/cmux/types";
|
|
9
13
|
|
|
10
14
|
export { finalizeBranchSlug, MAX_BRANCH_SLUG_LENGTH, sanitizeBranchName, trimBranchSlugToLength };
|
|
11
15
|
|
|
12
|
-
const GPT_NANO_PROVIDER = "openai";
|
|
13
|
-
const GPT_NANO_MODEL = "gpt-5.4-nano";
|
|
14
|
-
const SLUG_PROMPT_TIMEOUT_MS = 60_000;
|
|
15
|
-
const SUMMARY_PROMPT_TIMEOUT_MS = 60_000;
|
|
16
16
|
const MAX_SLUG_INPUT_CHARS = 12_000;
|
|
17
17
|
const MAX_SUMMARY_INPUT_CHARS = 16_000;
|
|
18
18
|
|
|
@@ -31,7 +31,7 @@ export async function generateBranchSlug(
|
|
|
31
31
|
},
|
|
32
32
|
): Promise<TextResult> {
|
|
33
33
|
const prompt = buildSlugPrompt(input);
|
|
34
|
-
const result = await
|
|
34
|
+
const result = await generateRawText(pi, cwd, prompt);
|
|
35
35
|
if (!result.ok) {
|
|
36
36
|
return {
|
|
37
37
|
ok: false,
|
|
@@ -56,12 +56,7 @@ export async function summarizePlanWithGptNano(
|
|
|
56
56
|
sourceLabel?: string;
|
|
57
57
|
},
|
|
58
58
|
): Promise<TextResult> {
|
|
59
|
-
const result = await
|
|
60
|
-
pi,
|
|
61
|
-
cwd,
|
|
62
|
-
buildPlanSummaryPrompt(input),
|
|
63
|
-
SUMMARY_PROMPT_TIMEOUT_MS,
|
|
64
|
-
);
|
|
59
|
+
const result = await generateRawText(pi, cwd, buildPlanSummaryPrompt(input));
|
|
65
60
|
if (!result.ok) {
|
|
66
61
|
return { ok: false, message: `Could not summarize plan with GPT Nano: ${result.message}` };
|
|
67
62
|
}
|
|
@@ -73,39 +68,20 @@ export async function summarizePlanWithGptNano(
|
|
|
73
68
|
return { ok: true, text: summary };
|
|
74
69
|
}
|
|
75
70
|
|
|
76
|
-
async function
|
|
71
|
+
async function generateRawText(
|
|
77
72
|
pi: BranchSlugRuntime,
|
|
78
73
|
cwd: string,
|
|
79
74
|
prompt: string,
|
|
80
|
-
timeout: number,
|
|
81
75
|
): Promise<TextResult> {
|
|
82
|
-
const result = await
|
|
83
|
-
|
|
84
|
-
const details = result.stderr.trim() || result.stdout.trim();
|
|
85
|
-
return { ok: false, message: details };
|
|
86
|
-
}
|
|
87
|
-
return { ok: true, text: result.stdout.trim() };
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export function buildGptNanoTextArgs(prompt: string): string[] {
|
|
91
|
-
return [
|
|
92
|
-
"--provider",
|
|
93
|
-
GPT_NANO_PROVIDER,
|
|
94
|
-
"--model",
|
|
95
|
-
GPT_NANO_MODEL,
|
|
96
|
-
"--thinking",
|
|
97
|
-
"low",
|
|
98
|
-
"--no-session",
|
|
99
|
-
"--no-extensions",
|
|
100
|
-
"--no-skills",
|
|
101
|
-
"--no-prompt-templates",
|
|
102
|
-
"--no-context-files",
|
|
103
|
-
"--no-tools",
|
|
104
|
-
"--mode",
|
|
105
|
-
"text",
|
|
106
|
-
"--print",
|
|
76
|
+
const result = await generateRawTextWithModel({
|
|
77
|
+
cwd,
|
|
107
78
|
prompt,
|
|
108
|
-
|
|
79
|
+
exec: (command, args, options) => pi.exec(command, args, options),
|
|
80
|
+
});
|
|
81
|
+
if (!result.ok) {
|
|
82
|
+
return { ok: false, message: formatRawTextModelFailure(result.failure) };
|
|
83
|
+
}
|
|
84
|
+
return { ok: true, text: result.evidence.rawOutput.trim() };
|
|
109
85
|
}
|
|
110
86
|
|
|
111
87
|
export function buildSlugPrompt(input: {
|
|
@@ -6,11 +6,23 @@ import {
|
|
|
6
6
|
piExecApiToCommandExecApi,
|
|
7
7
|
} from "@nseng-ai/foundation/command";
|
|
8
8
|
import { firstNonEmptyLine } from "@nseng-ai/foundation/text-normalization";
|
|
9
|
+
import { isAbsolute, resolve } from "node:path";
|
|
10
|
+
|
|
9
11
|
import {
|
|
10
12
|
planLocalBranchRefreshFromWorktrees,
|
|
11
13
|
type LocalBranchRefreshPlan,
|
|
12
14
|
} from "@nseng-ai/capability-kit/git";
|
|
13
15
|
import { runGraphiteCommand } from "@nseng-ai/capability-kit/graphite/branch";
|
|
16
|
+
import {
|
|
17
|
+
createGraphiteMetadataDbAccess,
|
|
18
|
+
GRAPHITE_BRANCH_METADATA_QUERY,
|
|
19
|
+
GRAPHITE_BRANCH_METADATA_SCHEMA_QUERY,
|
|
20
|
+
graphiteMetadataDbPath,
|
|
21
|
+
hasExpectedGraphiteBranchMetadataSchema,
|
|
22
|
+
parseGraphiteBranchMetadataRows,
|
|
23
|
+
resolveGraphiteTrunkBranchFromTopology,
|
|
24
|
+
type GraphiteMetadataDbAccess,
|
|
25
|
+
} from "@nseng-ai/capability-kit/graphite/metadata";
|
|
14
26
|
import { optionalEntry } from "@nseng-ai/foundation/primitives";
|
|
15
27
|
|
|
16
28
|
import { CCC_WORKSPACE_DISPATCH_FROM_TRUNK_COMMAND_NAME } from "./command-surfaces.ts";
|
|
@@ -30,12 +42,19 @@ const GIT_TRUNK_REFRESH_TIMEOUT_MS = 2 * 60 * 1000;
|
|
|
30
42
|
const TRUNK_DISPATCH_CONTEXT_NOTE =
|
|
31
43
|
"This branch was created from refreshed Graphite trunk and is intentionally unrelated to the caller's current stack.";
|
|
32
44
|
|
|
45
|
+
interface GraphiteTrunkResolutionContext {
|
|
46
|
+
pi: Pick<ExtensionAPI, "exec">;
|
|
47
|
+
cwd: string;
|
|
48
|
+
metadataDbAccess: GraphiteMetadataDbAccess;
|
|
49
|
+
}
|
|
50
|
+
|
|
33
51
|
export async function handleCccSlotDispatchFromTrunk(options: {
|
|
34
52
|
pi: Pick<ExtensionAPI, "exec" | "getThinkingLevel">;
|
|
35
53
|
payloadOptions: ReturnType<typeof resolveDispatchPromptPayloadOptions>;
|
|
36
54
|
args: string;
|
|
37
55
|
ctx: CommandContext;
|
|
38
56
|
slotClient?: SlotClient;
|
|
57
|
+
metadataDbAccess?: GraphiteMetadataDbAccess;
|
|
39
58
|
notifyProgress: (message: string) => void;
|
|
40
59
|
}): Promise<void> {
|
|
41
60
|
const { pi, payloadOptions, args, ctx } = options;
|
|
@@ -45,13 +64,13 @@ export async function handleCccSlotDispatchFromTrunk(options: {
|
|
|
45
64
|
return;
|
|
46
65
|
}
|
|
47
66
|
|
|
48
|
-
options.notifyProgress("Resolving Graphite trunk…");
|
|
49
67
|
await ctx.waitForIdle();
|
|
50
68
|
const branch = await createTrackedBranchFromTrunkForPrompt({
|
|
51
69
|
pi,
|
|
52
70
|
cwd: ctx.cwd,
|
|
53
71
|
prompt,
|
|
54
72
|
notify: options.notifyProgress,
|
|
73
|
+
...optionalEntry("metadataDbAccess", options.metadataDbAccess),
|
|
55
74
|
});
|
|
56
75
|
if ("error" in branch) {
|
|
57
76
|
ctx.ui.notify(branch.error, "error");
|
|
@@ -75,26 +94,17 @@ export async function createTrackedBranchFromTrunkForPrompt(options: {
|
|
|
75
94
|
cwd: string;
|
|
76
95
|
prompt: string;
|
|
77
96
|
notify?: (message: string) => void;
|
|
97
|
+
metadataDbAccess?: GraphiteMetadataDbAccess;
|
|
78
98
|
}): Promise<BranchCreateResult | { error: string }> {
|
|
79
99
|
const { pi, cwd, prompt, notify } = options;
|
|
80
100
|
notify?.("Resolving Graphite trunk…");
|
|
81
|
-
const trunk = await
|
|
101
|
+
const trunk = await resolveGraphiteTrunkBranch({
|
|
102
|
+
pi,
|
|
82
103
|
cwd,
|
|
83
|
-
|
|
104
|
+
metadataDbAccess: options.metadataDbAccess ?? createGraphiteMetadataDbAccess(),
|
|
84
105
|
});
|
|
85
|
-
if (
|
|
86
|
-
|
|
87
|
-
error: formatCommandFailure(
|
|
88
|
-
"Could not resolve Graphite trunk.",
|
|
89
|
-
"gt trunk --no-interactive",
|
|
90
|
-
trunk,
|
|
91
|
-
),
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
const trunkBranch = firstNonEmptyLine(trunk.stdout);
|
|
95
|
-
if (trunkBranch === undefined) {
|
|
96
|
-
return { error: "gt trunk --no-interactive returned no branch." };
|
|
97
|
-
}
|
|
106
|
+
if ("error" in trunk) return trunk;
|
|
107
|
+
const trunkBranch = trunk.branch;
|
|
98
108
|
|
|
99
109
|
notify?.("Refreshing Graphite trunk…");
|
|
100
110
|
const refresh = await refreshLocalTrunkBranch({ pi, cwd, trunkBranch });
|
|
@@ -124,6 +134,86 @@ export async function createTrackedBranchFromTrunkForPrompt(options: {
|
|
|
124
134
|
});
|
|
125
135
|
}
|
|
126
136
|
|
|
137
|
+
async function resolveGraphiteTrunkBranch(
|
|
138
|
+
context: GraphiteTrunkResolutionContext,
|
|
139
|
+
): Promise<{ branch: string } | { error: string }> {
|
|
140
|
+
const { pi, cwd } = context;
|
|
141
|
+
const trunk = await runGraphiteCommand(execApiToCommandRunner(piExecApiToCommandExecApi(pi)), {
|
|
142
|
+
cwd,
|
|
143
|
+
args: ["trunk", "--no-interactive"],
|
|
144
|
+
});
|
|
145
|
+
if (commandSucceeded(trunk)) {
|
|
146
|
+
const trunkBranch = firstNonEmptyLine(trunk.stdout);
|
|
147
|
+
if (trunkBranch === undefined) {
|
|
148
|
+
return { error: "gt trunk --no-interactive returned no branch." };
|
|
149
|
+
}
|
|
150
|
+
return { branch: trunkBranch };
|
|
151
|
+
}
|
|
152
|
+
const trunkFailureMessage = formatCommandFailure(
|
|
153
|
+
"Could not resolve Graphite trunk.",
|
|
154
|
+
"gt trunk --no-interactive",
|
|
155
|
+
trunk,
|
|
156
|
+
);
|
|
157
|
+
if (!isDetachedHeadGraphiteTrunkFailure(trunk)) {
|
|
158
|
+
return { error: trunkFailureMessage };
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const metadataTrunk = await resolveGraphiteTrunkBranchFromMetadata(context);
|
|
162
|
+
if ("branch" in metadataTrunk) return metadataTrunk;
|
|
163
|
+
return { error: [trunkFailureMessage, metadataTrunk.error].join("\n\n") };
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function isDetachedHeadGraphiteTrunkFailure(result: { stdout: string; stderr: string }): boolean {
|
|
167
|
+
return `${result.stdout}\n${result.stderr}`.toLowerCase().includes("no current branch");
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
async function resolveGraphiteTrunkBranchFromMetadata(
|
|
171
|
+
context: GraphiteTrunkResolutionContext,
|
|
172
|
+
): Promise<{ branch: string } | { error: string }> {
|
|
173
|
+
const commonDir = await runText(context.pi, context.cwd, "git", [
|
|
174
|
+
"rev-parse",
|
|
175
|
+
"--git-common-dir",
|
|
176
|
+
]);
|
|
177
|
+
if (!commonDir.ok) {
|
|
178
|
+
return { error: `Could not inspect Graphite metadata fallback: ${commonDir.message}` };
|
|
179
|
+
}
|
|
180
|
+
const commonGitDir = commonDir.text.trim();
|
|
181
|
+
const dbPath = graphiteMetadataDbPath(
|
|
182
|
+
isAbsolute(commonGitDir) ? commonGitDir : resolve(context.cwd, commonGitDir),
|
|
183
|
+
);
|
|
184
|
+
if (!context.metadataDbAccess.exists(dbPath)) {
|
|
185
|
+
return {
|
|
186
|
+
error: `Graphite metadata fallback unavailable: metadata store not found at ${dbPath}`,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
const schemaRows = context.metadataDbAccess.queryJson(
|
|
190
|
+
dbPath,
|
|
191
|
+
GRAPHITE_BRANCH_METADATA_SCHEMA_QUERY,
|
|
192
|
+
);
|
|
193
|
+
if (!schemaRows.ok) {
|
|
194
|
+
return { error: `Graphite metadata fallback failed: ${schemaRows.error.message}` };
|
|
195
|
+
}
|
|
196
|
+
if (!hasExpectedGraphiteBranchMetadataSchema(schemaRows.value)) {
|
|
197
|
+
return { error: "Graphite metadata fallback failed: branch_metadata schema mismatch." };
|
|
198
|
+
}
|
|
199
|
+
const metadataRows = context.metadataDbAccess.queryJson(dbPath, GRAPHITE_BRANCH_METADATA_QUERY);
|
|
200
|
+
if (!metadataRows.ok) {
|
|
201
|
+
return { error: `Graphite metadata fallback failed: ${metadataRows.error.message}` };
|
|
202
|
+
}
|
|
203
|
+
const parsed = parseGraphiteBranchMetadataRows(metadataRows.value);
|
|
204
|
+
if (parsed.type === "not_array") {
|
|
205
|
+
return { error: "Graphite metadata fallback failed: branch_metadata rows were not an array." };
|
|
206
|
+
}
|
|
207
|
+
const resolution = resolveGraphiteTrunkBranchFromTopology(parsed.topology);
|
|
208
|
+
if (resolution.type === "trunk") return { branch: resolution.branch };
|
|
209
|
+
if (resolution.type === "none") {
|
|
210
|
+
return { error: "Graphite metadata fallback found no trunk marker." };
|
|
211
|
+
}
|
|
212
|
+
return {
|
|
213
|
+
error: `Graphite metadata fallback found multiple trunk markers: ${resolution.branches.join(", ")}`,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
|
|
127
217
|
async function refreshLocalTrunkBranch(options: {
|
|
128
218
|
pi: Pick<ExtensionAPI, "exec">;
|
|
129
219
|
cwd: string;
|
package/src/cmux/sidebar.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { DEFAULT_FAST_MODEL_REF, resolveModelRef } from "@nseng-ai/foundation/mo
|
|
|
2
2
|
import {
|
|
3
3
|
chooseActiveObjectiveSlug,
|
|
4
4
|
objectiveSelectionContextFromCommandContext,
|
|
5
|
+
objectiveSelectionHostFromExec,
|
|
5
6
|
type ObjectiveSelectionSpec,
|
|
6
7
|
} from "@nseng-ai/objectives/api";
|
|
7
8
|
|
|
@@ -33,7 +34,7 @@ const SIDEBAR_MODEL_ENV = "NS_CCC_SIDEBAR_MODEL";
|
|
|
33
34
|
const OBJECTIVE_SIDEBAR_SELECTION_SPEC = {
|
|
34
35
|
statusKey: PI_SIDEBAR_STATUS_KEY,
|
|
35
36
|
selectionTitle: "Select an active Objective for cmux sidebar",
|
|
36
|
-
|
|
37
|
+
selectionMode: "compact-diff-suggestion",
|
|
37
38
|
} satisfies ObjectiveSelectionSpec;
|
|
38
39
|
|
|
39
40
|
interface RestoreState {
|
|
@@ -227,7 +228,7 @@ async function resolveObjectiveSidebarSlug(
|
|
|
227
228
|
}
|
|
228
229
|
|
|
229
230
|
return chooseActiveObjectiveSlug(
|
|
230
|
-
pi,
|
|
231
|
+
objectiveSelectionHostFromExec(pi),
|
|
231
232
|
objectiveSelectionContextFromCommandContext(ctx),
|
|
232
233
|
OBJECTIVE_SIDEBAR_SELECTION_SPEC,
|
|
233
234
|
);
|
|
@@ -465,7 +465,7 @@ function formatLaunchPreview(options: {
|
|
|
465
465
|
options.launchCommand,
|
|
466
466
|
);
|
|
467
467
|
return [
|
|
468
|
-
"cmux new-surface --type terminal --workspace <caller-workspace> --pane <caller-pane> --focus
|
|
468
|
+
"cmux new-surface --type terminal --workspace <caller-workspace> --pane <caller-pane> --focus false",
|
|
469
469
|
`cmux rename-tab --title ${formatShellArg(options.branch)}`,
|
|
470
470
|
`cmux send -- ${formatShellArg(`${surfaceLaunchCommand}\n`)}`,
|
|
471
471
|
].join("\n");
|
|
@@ -517,6 +517,7 @@ async function openBranchInCmuxSurface(options: {
|
|
|
517
517
|
tabTitle,
|
|
518
518
|
command: surfaceLaunchCommand,
|
|
519
519
|
signal: undefined,
|
|
520
|
+
shouldFocus: false,
|
|
520
521
|
onStage: (stage) => setStatus(ctx, config, formatSurfaceStageStatus(stage)),
|
|
521
522
|
});
|
|
522
523
|
if (launched.type === "failed") {
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
type CommandResult,
|
|
5
5
|
type PreparedCheckpointMessage,
|
|
6
6
|
} from "@nseng-ai/capability-kit/checkpoint-flow";
|
|
7
|
-
import { createTextGenerator } from "@nseng-ai/
|
|
7
|
+
import { createTextGenerator } from "@nseng-ai/kernel/context";
|
|
8
8
|
import type { PendingWorktreeSnapshot } from "@nseng-ai/capability-kit/pending-worktree";
|
|
9
9
|
import { selectCheckpointModelRef } from "@nseng-ai/capability-kit/text-generation";
|
|
10
10
|
|
package/src/ns/cli-command-io.ts
CHANGED
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
createCliCommandIo,
|
|
3
3
|
type CliCommandIoInput,
|
|
4
4
|
type CliCommandIoOptions,
|
|
5
|
-
} from "@nseng-ai/
|
|
6
|
-
import type { NsCommandIo } from "@nseng-ai/
|
|
5
|
+
} from "@nseng-ai/kernel/command-io";
|
|
6
|
+
import type { NsCommandIo } from "@nseng-ai/kernel/sdk";
|
|
7
7
|
|
|
8
8
|
/** Minimal CLI stream/callback surface that CCC standalone commands adapt to NsCommandIo. */
|
|
9
9
|
export type CccCliCommandIoInput = CliCommandIoInput;
|
package/src/ns/cli.ts
CHANGED
|
@@ -6,7 +6,6 @@ import { ClinkrGroup, failure, negative, ok, type ClinkrExit } from "@nseng-ai/c
|
|
|
6
6
|
import { defineCli, type CliEntrypointDeps } from "@nseng-ai/foundation/cli-runtime";
|
|
7
7
|
import { NodeCommandExecApi } from "@nseng-ai/foundation/exec";
|
|
8
8
|
import type { CommandExecApi } from "@nseng-ai/foundation/command";
|
|
9
|
-
|
|
10
9
|
import {
|
|
11
10
|
commitAutobranchCheckpointMessage,
|
|
12
11
|
prepareAutobranchCheckpointMessage,
|
|
@@ -143,11 +142,12 @@ async function handleAutobranch(
|
|
|
143
142
|
): Promise<ClinkrExit<AutobranchResult>> {
|
|
144
143
|
const args: FlowAutobranchRequest = request.slug === undefined ? {} : { slug: request.slug };
|
|
145
144
|
const autobranch = ctx.autobranch ?? {};
|
|
145
|
+
const exec = (command: string, commandArgs: string[], timeout: number) =>
|
|
146
|
+
ctx.commands.exec(command, commandArgs, { cwd: ctx.cwd, timeout, env: ctx.env });
|
|
146
147
|
const result = await createFlowAutobranchCheckpointFlow({
|
|
147
148
|
cwd: ctx.cwd,
|
|
148
149
|
args,
|
|
149
|
-
exec
|
|
150
|
-
ctx.commands.exec(command, commandArgs, { cwd: ctx.cwd, timeout, env: ctx.env }),
|
|
150
|
+
exec,
|
|
151
151
|
prepareCheckpointMessage:
|
|
152
152
|
autobranch.prepareCheckpointMessage ??
|
|
153
153
|
((snapshot) => prepareAutobranchCheckpointMessage(snapshot, ctx.env)),
|
|
@@ -183,4 +183,6 @@ function renderAutobranch(result: AutobranchResult): string {
|
|
|
183
183
|
return result.summary;
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
+
export const VERSION = entry.version;
|
|
187
|
+
|
|
186
188
|
await entry.runIfMain({ isImportMetaMain: import.meta.main });
|
package/src/ns/land.ts
CHANGED
|
@@ -9,4 +9,9 @@ export type {
|
|
|
9
9
|
PrintOutput,
|
|
10
10
|
ValidPullRequestView,
|
|
11
11
|
} from "@nseng-ai/flow/api";
|
|
12
|
-
export {
|
|
12
|
+
export {
|
|
13
|
+
FLOW_LAND_PR_FIELDS,
|
|
14
|
+
parsePullRequestView,
|
|
15
|
+
registerLandCommand,
|
|
16
|
+
runLandCli,
|
|
17
|
+
} from "@nseng-ai/flow/api";
|
|
@@ -10,12 +10,17 @@ import {
|
|
|
10
10
|
type DispatchPromptPayloadOptions,
|
|
11
11
|
} from "../api/handlers.ts";
|
|
12
12
|
import type { ExtensionAPI } from "@nseng-ai/capability-kit/cmux/types";
|
|
13
|
+
import type { GraphiteMetadataDbAccess } from "@nseng-ai/capability-kit/graphite/metadata";
|
|
13
14
|
|
|
14
15
|
const COMMAND_NAME = CCC_WORKSPACE_DISPATCH_FROM_TRUNK_COMMAND_NAME;
|
|
15
16
|
|
|
17
|
+
export interface CccSlotDispatchFromTrunkOptions extends DispatchPromptPayloadOptions {
|
|
18
|
+
metadataDbAccess?: GraphiteMetadataDbAccess;
|
|
19
|
+
}
|
|
20
|
+
|
|
16
21
|
export function registerCccSlotDispatchFromTrunkCommand(
|
|
17
22
|
pi: ExtensionAPI,
|
|
18
|
-
options:
|
|
23
|
+
options: CccSlotDispatchFromTrunkOptions = {},
|
|
19
24
|
): void {
|
|
20
25
|
const payloadOptions = resolveDispatchPromptPayloadOptions(options);
|
|
21
26
|
registerCommandWithImmediateAck({
|
|
@@ -33,6 +38,7 @@ export function registerCccSlotDispatchFromTrunkCommand(
|
|
|
33
38
|
args,
|
|
34
39
|
ctx,
|
|
35
40
|
...optionalEntry("slotClient", options.slotClient),
|
|
41
|
+
...optionalEntry("metadataDbAccess", options.metadataDbAccess),
|
|
36
42
|
notifyProgress,
|
|
37
43
|
});
|
|
38
44
|
},
|
|
@@ -50,8 +50,7 @@ function registerDispatchPlanCommand(
|
|
|
50
50
|
host: pi,
|
|
51
51
|
commandName: config.commandName,
|
|
52
52
|
commandDefinition: {
|
|
53
|
-
description:
|
|
54
|
-
"Attach the latest session-saved plan to a new Graphite-tracked branch via branch-context and launch it in a new cmux workspace.",
|
|
53
|
+
description: `Attach the latest session-saved plan to a new Graphite-tracked branch via branch-context and launch it in a new cmux ${config.destination}.`,
|
|
55
54
|
argumentHint: "[--dry-run] [--help]",
|
|
56
55
|
handler: async (rawArgs, ctx) => {
|
|
57
56
|
const notifyProgress = makeCommandProgressNotifier({ host: pi, ctx });
|