@groundtrack/hooks 0.1.11 → 0.1.12
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.
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { resolve } from "node:path";
|
|
1
|
+
import { basename, resolve } from "node:path";
|
|
2
2
|
import * as prompts from "@clack/prompts";
|
|
3
|
-
import {
|
|
4
|
-
import { environment } from "../setup/agents.js";
|
|
3
|
+
import { isSessionImportAgent, SESSION_IMPORT_AGENTS } from "../agents.js";
|
|
4
|
+
import { discoverAgents, environment, savedAgents, } from "../setup/agents.js";
|
|
5
5
|
import { CANONICAL_IMPORT_MAX_BYTES } from "./canonical.js";
|
|
6
6
|
import { uploadAgentSession } from "./client.js";
|
|
7
7
|
import { discoverSessions, normalizeRepositoryUrl, repositoryIdentity } from "./discovery.js";
|
|
@@ -17,7 +17,7 @@ export const IMPORT_USAGE = `Usage:
|
|
|
17
17
|
[--visibility private|organization] [--dry-run] [--yes] [--json]
|
|
18
18
|
|
|
19
19
|
Import options:
|
|
20
|
-
--agent VALUE ${importAgentDescription}
|
|
20
|
+
--agent VALUE ${importAgentDescription}; omit in a terminal to choose
|
|
21
21
|
--repo PATH Import sessions for this Git repository (default: current repository)
|
|
22
22
|
--all-repos Import sessions associated with any Git repository
|
|
23
23
|
--include-unscoped With --all-repos, also import sessions outside a Git repository
|
|
@@ -58,7 +58,7 @@ export function parseImportArguments(argv) {
|
|
|
58
58
|
};
|
|
59
59
|
let repoDir;
|
|
60
60
|
let homeDir;
|
|
61
|
-
let agent =
|
|
61
|
+
let agent = null;
|
|
62
62
|
let allRepositories = false;
|
|
63
63
|
let includeUnscoped = false;
|
|
64
64
|
let includeSubagents = false;
|
|
@@ -197,14 +197,8 @@ function sessionDateRange(sessions) {
|
|
|
197
197
|
}
|
|
198
198
|
: null;
|
|
199
199
|
}
|
|
200
|
-
|
|
201
|
-
const
|
|
202
|
-
if (args.help) {
|
|
203
|
-
process.stdout.write(IMPORT_USAGE);
|
|
204
|
-
return;
|
|
205
|
-
}
|
|
206
|
-
const context = environment({ repoDir: args.repoDir, homeDir: args.homeDir });
|
|
207
|
-
const format = sessionImportFormat(args.agent);
|
|
200
|
+
async function runAgentImport(args, agent, context, interactive) {
|
|
201
|
+
const format = sessionImportFormat(agent);
|
|
208
202
|
const home = resolve(context.env[format.homeEnvironmentVariable] ||
|
|
209
203
|
resolve(context.homeDir, format.defaultHomeDirectory));
|
|
210
204
|
const repository = args.allRepositories ? undefined : repositoryIdentity(context.repoDir);
|
|
@@ -259,7 +253,7 @@ export async function runImportCli(argv) {
|
|
|
259
253
|
}
|
|
260
254
|
const scope = args.allRepositories ? "all repositories" : repository.root;
|
|
261
255
|
const plan = {
|
|
262
|
-
agent
|
|
256
|
+
agent,
|
|
263
257
|
scope,
|
|
264
258
|
selected: prepared.length,
|
|
265
259
|
alreadyImported: prepared.filter((item) => item.alreadyImported).length,
|
|
@@ -284,9 +278,8 @@ export async function runImportCli(argv) {
|
|
|
284
278
|
});
|
|
285
279
|
if (preparationErrors.length)
|
|
286
280
|
process.exitCode = 1;
|
|
287
|
-
return;
|
|
281
|
+
return true;
|
|
288
282
|
}
|
|
289
|
-
const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY && !args.json);
|
|
290
283
|
if (!args.json)
|
|
291
284
|
printPlan({
|
|
292
285
|
displayName: format.displayName,
|
|
@@ -307,7 +300,7 @@ export async function runImportCli(argv) {
|
|
|
307
300
|
});
|
|
308
301
|
if (prompts.isCancel(approved) || !approved) {
|
|
309
302
|
prompts.cancel("Nothing uploaded.");
|
|
310
|
-
return;
|
|
303
|
+
return false;
|
|
311
304
|
}
|
|
312
305
|
}
|
|
313
306
|
let imported = 0;
|
|
@@ -358,8 +351,53 @@ export async function runImportCli(argv) {
|
|
|
358
351
|
process.stdout.write(`Imported ${imported}; duplicates ${duplicate}; skipped ${result.skipped}; failed ${failures.length}.\n${result.sessionsUrl}\n`);
|
|
359
352
|
if (failures.length)
|
|
360
353
|
process.exitCode = 1;
|
|
354
|
+
return true;
|
|
361
355
|
}
|
|
362
356
|
finally {
|
|
363
357
|
discovery.cleanup?.();
|
|
364
358
|
}
|
|
365
359
|
}
|
|
360
|
+
async function chooseImportAgents(args, context, interactive) {
|
|
361
|
+
if (args.agent)
|
|
362
|
+
return [args.agent];
|
|
363
|
+
if (!interactive)
|
|
364
|
+
throw new Error("Choose an agent with --agent, or run groundtrack import in an interactive terminal to choose from a list.");
|
|
365
|
+
const discovered = discoverAgents(context);
|
|
366
|
+
const saved = savedAgents(context)?.filter(isSessionImportAgent) ?? null;
|
|
367
|
+
prompts.intro(`Import coding-agent sessions · ${basename(context.repoDir)}`);
|
|
368
|
+
const selection = await prompts.multiselect({
|
|
369
|
+
message: "Which coding agents do you want to import from?",
|
|
370
|
+
options: SESSION_IMPORT_AGENTS.map((agent) => {
|
|
371
|
+
const state = discovered.find((candidate) => candidate.id === agent.id);
|
|
372
|
+
return {
|
|
373
|
+
value: agent.id,
|
|
374
|
+
label: agent.name,
|
|
375
|
+
hint: state.configured ? "configured" : state.detected ? "detected" : "not detected",
|
|
376
|
+
};
|
|
377
|
+
}),
|
|
378
|
+
initialValues: saved ??
|
|
379
|
+
discovered
|
|
380
|
+
.filter((agent) => agent.detected && isSessionImportAgent(agent.id))
|
|
381
|
+
.map((agent) => agent.id),
|
|
382
|
+
required: false,
|
|
383
|
+
});
|
|
384
|
+
if (prompts.isCancel(selection) || selection.length === 0) {
|
|
385
|
+
prompts.cancel("No agents selected. Nothing imported.");
|
|
386
|
+
return [];
|
|
387
|
+
}
|
|
388
|
+
return selection;
|
|
389
|
+
}
|
|
390
|
+
export async function runImportCli(argv) {
|
|
391
|
+
const args = parseImportArguments(argv);
|
|
392
|
+
if (args.help) {
|
|
393
|
+
process.stdout.write(IMPORT_USAGE);
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
const context = environment({ repoDir: args.repoDir, homeDir: args.homeDir });
|
|
397
|
+
const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY && !args.json);
|
|
398
|
+
const agents = await chooseImportAgents(args, context, interactive);
|
|
399
|
+
for (const agent of agents) {
|
|
400
|
+
if (!(await runAgentImport(args, agent, context, interactive)))
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
}
|