@lesscap/baton-cli 0.2.3 → 0.2.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/baton.mjs +128 -5
- package/package.json +1 -1
package/dist/baton.mjs
CHANGED
|
@@ -550,6 +550,7 @@ var requirementClient = (baseUrl) => {
|
|
|
550
550
|
listByProject: (projectId) => request(u(`/projects/${projectId}/requirements`), { method: "GET" }),
|
|
551
551
|
get: (id) => request(u(`/requirements/${id}`), { method: "GET" }),
|
|
552
552
|
getByCode: (projectId, code) => fetchItemByCode(baseUrl, projectId, code, "requirement"),
|
|
553
|
+
update: (id, patch2) => request(u(`/requirements/${id}`), { method: "PATCH", body: patch2 }),
|
|
553
554
|
setStatus: (id, status) => request(u(`/requirements/${id}`), { method: "PATCH", body: { status } }),
|
|
554
555
|
remove: (id) => request(u(`/requirements/${id}`), { method: "DELETE" })
|
|
555
556
|
};
|
|
@@ -622,6 +623,7 @@ var taskClient = (baseUrl) => {
|
|
|
622
623
|
listByRequirement: (requirementId) => request(u(`/requirements/${requirementId}/tasks`), { method: "GET" }),
|
|
623
624
|
get: (id) => request(u(`/tasks/${id}`), { method: "GET" }),
|
|
624
625
|
getByCode: (projectId, code) => fetchItemByCode(baseUrl, projectId, code, "task"),
|
|
626
|
+
update: (id, patch2) => request(u(`/tasks/${id}`), { method: "PATCH", body: patch2 }),
|
|
625
627
|
setStatus: (id, status) => request(u(`/tasks/${id}`), { method: "PATCH", body: { status } }),
|
|
626
628
|
remove: (id) => request(u(`/tasks/${id}`), { method: "DELETE" }),
|
|
627
629
|
listComments: (id) => request(u(`/tasks/${id}/comments`), { method: "GET" }),
|
|
@@ -781,6 +783,12 @@ var resolveWorkspaceId = (args) => {
|
|
|
781
783
|
"no workspace in scope. pass --workspace <id> or run `baton init` in this directory."
|
|
782
784
|
);
|
|
783
785
|
};
|
|
786
|
+
var parseIssueUrl = (url) => {
|
|
787
|
+
const m = url.match(/^https:\/\/github\.com\/[^/]+\/[^/]+\/issues\/(\d+)/);
|
|
788
|
+
if (!m)
|
|
789
|
+
throw new Error(`expected a GitHub issue url (https://github.com/o/r/issues/N), got "${url}"`);
|
|
790
|
+
return { source: "github", number: Number(m[1]), url: url.split(/[?#]/)[0] };
|
|
791
|
+
};
|
|
784
792
|
var splitCsv = (s) => s ? s.split(",").map((x) => x.trim()).filter(Boolean) : void 0;
|
|
785
793
|
|
|
786
794
|
// src/commands/init.ts
|
|
@@ -940,6 +948,7 @@ var project = defineCommand({
|
|
|
940
948
|
|
|
941
949
|
// src/commands/requirement.ts
|
|
942
950
|
var createRequirement = (c, input, json) => c.requirements.create(input).then((r) => renderOne(r, fmtRequirement, json));
|
|
951
|
+
var updateRequirement = (c, id, patch2, json) => c.requirements.update(id, patch2).then((r) => renderOne(r, fmtRequirement, json));
|
|
943
952
|
var listRequirements = (c, projectId, json) => c.requirements.listByProject(projectId).then((rs) => renderList(rs, fmtRequirement, json));
|
|
944
953
|
var getRequirement = (c, id, json) => c.requirements.get(id).then((r) => renderOne(r, fmtRequirement, json));
|
|
945
954
|
var setRequirementStatus = (c, id, status, json) => c.requirements.setStatus(id, status).then((r) => renderOne(r, fmtRequirement, json));
|
|
@@ -955,6 +964,7 @@ var requirement = defineCommand({
|
|
|
955
964
|
project: { type: "string", description: "project id (overrides .baton.json)" },
|
|
956
965
|
desc: { type: "string", description: "description" },
|
|
957
966
|
body: { type: "string", description: "requirement body (markdown)" },
|
|
967
|
+
github: { type: "string", description: "link a GitHub issue url (light association)" },
|
|
958
968
|
...common
|
|
959
969
|
},
|
|
960
970
|
run: async ({ args }) => {
|
|
@@ -965,13 +975,69 @@ var requirement = defineCommand({
|
|
|
965
975
|
projectId: resolveProjectId(args),
|
|
966
976
|
title: args.title,
|
|
967
977
|
description: args.desc,
|
|
968
|
-
body: args.body
|
|
978
|
+
body: args.body,
|
|
979
|
+
external: args.github ? parseIssueUrl(args.github) : void 0
|
|
969
980
|
},
|
|
970
981
|
Boolean(args.json)
|
|
971
982
|
)
|
|
972
983
|
);
|
|
973
984
|
}
|
|
974
985
|
}),
|
|
986
|
+
update: defineCommand({
|
|
987
|
+
meta: { name: "update", description: "update a requirement title / body" },
|
|
988
|
+
args: {
|
|
989
|
+
code: { type: "positional", required: true, description: "requirement code (R-N)" },
|
|
990
|
+
title: { type: "string", description: "new title" },
|
|
991
|
+
body: { type: "string", description: "new body (markdown)" },
|
|
992
|
+
project: { type: "string", description: "project id (overrides .baton.json)" },
|
|
993
|
+
...common
|
|
994
|
+
},
|
|
995
|
+
run: async ({ args }) => {
|
|
996
|
+
const patch2 = {
|
|
997
|
+
...args.title !== void 0 ? { title: args.title } : {},
|
|
998
|
+
...args.body !== void 0 ? { body: args.body } : {}
|
|
999
|
+
};
|
|
1000
|
+
if (Object.keys(patch2).length === 0) throw new Error("pass --title and/or --body");
|
|
1001
|
+
const c = clientFor(args);
|
|
1002
|
+
const id = await resolveByCode(c, resolveProjectId(args), args.code);
|
|
1003
|
+
console.log(await updateRequirement(c, id, patch2, Boolean(args.json)));
|
|
1004
|
+
}
|
|
1005
|
+
}),
|
|
1006
|
+
link: defineCommand({
|
|
1007
|
+
meta: { name: "link", description: "link a requirement to a GitHub issue url" },
|
|
1008
|
+
args: {
|
|
1009
|
+
code: { type: "positional", required: true, description: "requirement code (R-N)" },
|
|
1010
|
+
// Named `issue` (not `url`) — `url` would collide with the common --url flag.
|
|
1011
|
+
issue: { type: "positional", required: true, description: "GitHub issue url" },
|
|
1012
|
+
project: { type: "string", description: "project id (overrides .baton.json)" },
|
|
1013
|
+
...common
|
|
1014
|
+
},
|
|
1015
|
+
run: async ({ args }) => {
|
|
1016
|
+
const c = clientFor(args);
|
|
1017
|
+
const id = await resolveByCode(c, resolveProjectId(args), args.code);
|
|
1018
|
+
console.log(
|
|
1019
|
+
await updateRequirement(
|
|
1020
|
+
c,
|
|
1021
|
+
id,
|
|
1022
|
+
{ external: parseIssueUrl(args.issue) },
|
|
1023
|
+
Boolean(args.json)
|
|
1024
|
+
)
|
|
1025
|
+
);
|
|
1026
|
+
}
|
|
1027
|
+
}),
|
|
1028
|
+
unlink: defineCommand({
|
|
1029
|
+
meta: { name: "unlink", description: "clear a requirement\u2019s GitHub issue association" },
|
|
1030
|
+
args: {
|
|
1031
|
+
code: { type: "positional", required: true, description: "requirement code (R-N)" },
|
|
1032
|
+
project: { type: "string", description: "project id (overrides .baton.json)" },
|
|
1033
|
+
...common
|
|
1034
|
+
},
|
|
1035
|
+
run: async ({ args }) => {
|
|
1036
|
+
const c = clientFor(args);
|
|
1037
|
+
const id = await resolveByCode(c, resolveProjectId(args), args.code);
|
|
1038
|
+
console.log(await updateRequirement(c, id, { external: null }, Boolean(args.json)));
|
|
1039
|
+
}
|
|
1040
|
+
}),
|
|
975
1041
|
ls: defineCommand({
|
|
976
1042
|
meta: { name: "ls", description: "list requirements in a project" },
|
|
977
1043
|
args: {
|
|
@@ -2222,6 +2288,7 @@ var session = defineCommand({
|
|
|
2222
2288
|
|
|
2223
2289
|
// src/commands/task.ts
|
|
2224
2290
|
var createTask = (c, input, json) => c.tasks.create(input).then((t) => renderOne(t, fmtTask, json));
|
|
2291
|
+
var updateTask = (c, id, patch2, json) => c.tasks.update(id, patch2).then((t) => renderOne(t, fmtTask, json));
|
|
2225
2292
|
var listTasks = (c, requirementId, json) => c.tasks.listByRequirement(requirementId).then((ts) => renderList(ts, fmtTask, json));
|
|
2226
2293
|
var getTask = (c, id, json) => c.tasks.get(id).then((t) => renderOne(t, fmtTask, json));
|
|
2227
2294
|
var setTaskStatus = (c, id, status, json) => c.tasks.setStatus(id, status).then((t) => renderOne(t, fmtTask, json));
|
|
@@ -2241,6 +2308,7 @@ var task = defineCommand({
|
|
|
2241
2308
|
project: { type: "string", description: "project id (overrides .baton.json)" },
|
|
2242
2309
|
body: { type: "string", description: "task body (markdown)" },
|
|
2243
2310
|
deps: { type: "string", description: "comma-separated dependency task codes (T-N,T-N)" },
|
|
2311
|
+
github: { type: "string", description: "link a GitHub issue url (light association)" },
|
|
2244
2312
|
...common
|
|
2245
2313
|
},
|
|
2246
2314
|
run: async ({ args }) => {
|
|
@@ -2258,13 +2326,64 @@ var task = defineCommand({
|
|
|
2258
2326
|
requirementId,
|
|
2259
2327
|
title: args.title,
|
|
2260
2328
|
body: args.body,
|
|
2261
|
-
dependsOn: dependsOn.length ? dependsOn : void 0
|
|
2329
|
+
dependsOn: dependsOn.length ? dependsOn : void 0,
|
|
2330
|
+
external: args.github ? parseIssueUrl(args.github) : void 0
|
|
2262
2331
|
},
|
|
2263
2332
|
Boolean(args.json)
|
|
2264
2333
|
)
|
|
2265
2334
|
);
|
|
2266
2335
|
}
|
|
2267
2336
|
}),
|
|
2337
|
+
update: defineCommand({
|
|
2338
|
+
meta: { name: "update", description: "update a task title / body" },
|
|
2339
|
+
args: {
|
|
2340
|
+
code: { type: "positional", required: true, description: "task code (T-N)" },
|
|
2341
|
+
title: { type: "string", description: "new title" },
|
|
2342
|
+
body: { type: "string", description: "new body (markdown)" },
|
|
2343
|
+
project: { type: "string", description: "project id (overrides .baton.json)" },
|
|
2344
|
+
...common
|
|
2345
|
+
},
|
|
2346
|
+
run: async ({ args }) => {
|
|
2347
|
+
const patch2 = {
|
|
2348
|
+
...args.title !== void 0 ? { title: args.title } : {},
|
|
2349
|
+
...args.body !== void 0 ? { body: args.body } : {}
|
|
2350
|
+
};
|
|
2351
|
+
if (Object.keys(patch2).length === 0) throw new Error("pass --title and/or --body");
|
|
2352
|
+
const c = clientFor(args);
|
|
2353
|
+
const id = await resolveTaskByCode(c, resolveProjectId(args), args.code);
|
|
2354
|
+
console.log(await updateTask(c, id, patch2, Boolean(args.json)));
|
|
2355
|
+
}
|
|
2356
|
+
}),
|
|
2357
|
+
link: defineCommand({
|
|
2358
|
+
meta: { name: "link", description: "link a task to a GitHub issue url" },
|
|
2359
|
+
args: {
|
|
2360
|
+
code: { type: "positional", required: true, description: "task code (T-N)" },
|
|
2361
|
+
// Named `issue` (not `url`) — `url` would collide with the common --url flag.
|
|
2362
|
+
issue: { type: "positional", required: true, description: "GitHub issue url" },
|
|
2363
|
+
project: { type: "string", description: "project id (overrides .baton.json)" },
|
|
2364
|
+
...common
|
|
2365
|
+
},
|
|
2366
|
+
run: async ({ args }) => {
|
|
2367
|
+
const c = clientFor(args);
|
|
2368
|
+
const id = await resolveTaskByCode(c, resolveProjectId(args), args.code);
|
|
2369
|
+
console.log(
|
|
2370
|
+
await updateTask(c, id, { external: parseIssueUrl(args.issue) }, Boolean(args.json))
|
|
2371
|
+
);
|
|
2372
|
+
}
|
|
2373
|
+
}),
|
|
2374
|
+
unlink: defineCommand({
|
|
2375
|
+
meta: { name: "unlink", description: "clear a task\u2019s GitHub issue association" },
|
|
2376
|
+
args: {
|
|
2377
|
+
code: { type: "positional", required: true, description: "task code (T-N)" },
|
|
2378
|
+
project: { type: "string", description: "project id (overrides .baton.json)" },
|
|
2379
|
+
...common
|
|
2380
|
+
},
|
|
2381
|
+
run: async ({ args }) => {
|
|
2382
|
+
const c = clientFor(args);
|
|
2383
|
+
const id = await resolveTaskByCode(c, resolveProjectId(args), args.code);
|
|
2384
|
+
console.log(await updateTask(c, id, { external: null }, Boolean(args.json)));
|
|
2385
|
+
}
|
|
2386
|
+
}),
|
|
2268
2387
|
ls: defineCommand({
|
|
2269
2388
|
meta: { name: "ls", description: "list tasks in a requirement" },
|
|
2270
2389
|
args: {
|
|
@@ -2294,7 +2413,7 @@ var task = defineCommand({
|
|
|
2294
2413
|
"set-status": defineCommand({
|
|
2295
2414
|
meta: {
|
|
2296
2415
|
name: "set-status",
|
|
2297
|
-
description: "set task status (todo|in_progress|done|failed|cancelled)"
|
|
2416
|
+
description: "set task status (todo|in_progress|blocked|done|failed|cancelled)"
|
|
2298
2417
|
},
|
|
2299
2418
|
args: {
|
|
2300
2419
|
code: { type: "positional", required: true, description: "task code (T-N)" },
|
|
@@ -2372,7 +2491,7 @@ import { query as query2 } from "@anthropic-ai/claude-agent-sdk";
|
|
|
2372
2491
|
// src/session/runner/title.ts
|
|
2373
2492
|
var clip = (s, max) => s.length > max ? s.slice(0, max) : s;
|
|
2374
2493
|
var isDeclined = (title) => title.replace(/[^a-z]/gi, "").toUpperCase() === "NONE";
|
|
2375
|
-
var sanitizeTitle = (raw) => raw.replace(/[\r\n]+/g, " ").replace(/["'
|
|
2494
|
+
var sanitizeTitle = (raw) => raw.replace(/[\r\n]+/g, " ").replace(/[*_`~#>]/g, "").replace(/["']/g, "").replace(/^\s*(?:title|session|标题)\s*[::-]\s*/i, "").replace(/^\s*(?:[-*•]|\d+[.)、])\s+/, "").replace(/\s+/g, " ").trim().slice(0, 30).replace(/[\s。.,,、;;::!!??.]+$/, "").trim();
|
|
2376
2495
|
var TITLE_TIMEOUT_MS = 3e4;
|
|
2377
2496
|
var generateTitle = async (input) => {
|
|
2378
2497
|
const { worktreePath, userText, assistantText, queryFn } = input;
|
|
@@ -2381,7 +2500,8 @@ var generateTitle = async (input) => {
|
|
|
2381
2500
|
`User: ${clip(userText, 800)}`,
|
|
2382
2501
|
assistantText ? `Assistant: ${clip(assistantText, 800)}` : ""
|
|
2383
2502
|
].filter(Boolean).join("\n");
|
|
2384
|
-
const prompt = `Reply with ONLY a
|
|
2503
|
+
const prompt = `Reply with ONLY a short title for this session: a noun phrase like a filename \u2014 at most 6 words or ~12 Chinese characters. It must NOT be a sentence, no punctuation, no markdown, no quotes, and never an opener like "\u597D\u7684"/"\u6536\u5230"/"I'll". If it is too thin or generic to title meaningfully, reply with exactly NONE.
|
|
2504
|
+
|
|
2385
2505
|
${exchange}`;
|
|
2386
2506
|
const exe = claudeExecutable();
|
|
2387
2507
|
const abort = new AbortController();
|
|
@@ -2392,6 +2512,9 @@ ${exchange}`;
|
|
|
2392
2512
|
prompt,
|
|
2393
2513
|
options: {
|
|
2394
2514
|
cwd: worktreePath,
|
|
2515
|
+
// Don't load the worktree's CLAUDE.md / project settings — they steer the
|
|
2516
|
+
// model into verbose summaries instead of a terse title.
|
|
2517
|
+
settingSources: [],
|
|
2395
2518
|
permissionMode: "bypassPermissions",
|
|
2396
2519
|
allowedTools: [],
|
|
2397
2520
|
includePartialMessages: false,
|