exponential-cli 1.11.2 → 1.13.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/README.md +25 -0
- package/dist/index.js +442 -58
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
-
import { Command as
|
|
4
|
+
import { Command as Command23 } from "commander";
|
|
5
5
|
|
|
6
6
|
// src/commands/auth.ts
|
|
7
7
|
import { Command } from "commander";
|
|
@@ -899,6 +899,17 @@ ${chalk3[getFeatureStatusColor(feature.status)](`[${feature.status}]`)} ${chalk3
|
|
|
899
899
|
if (feature.priority != null) {
|
|
900
900
|
console.log(` ${chalk3.magenta("Priority:")} ${feature.priority}`);
|
|
901
901
|
}
|
|
902
|
+
if (feature.goal) {
|
|
903
|
+
console.log(` ${chalk3.blue("Objective:")} ${feature.goal.title} ${chalk3.gray(`(${feature.goal.id})`)}`);
|
|
904
|
+
}
|
|
905
|
+
if (feature.keyResultLinks?.length) {
|
|
906
|
+
console.log(` ${chalk3.blue("Key results:")}`);
|
|
907
|
+
for (const link of feature.keyResultLinks) {
|
|
908
|
+
const kr = link.keyResult;
|
|
909
|
+
const progress = kr.currentValue != null && kr.targetValue != null ? `${kr.currentValue}/${kr.targetValue}${kr.unit && kr.unit !== "custom" ? ` ${kr.unit}` : ""}, ` : "";
|
|
910
|
+
console.log(` \xB7 ${kr.title} ${chalk3.gray(`(${progress}${kr.period}, ${kr.id})`)}`);
|
|
911
|
+
}
|
|
912
|
+
}
|
|
902
913
|
if (feature._count?.tickets != null) {
|
|
903
914
|
console.log(` ${chalk3.cyan("Tickets:")} ${feature._count.tickets}`);
|
|
904
915
|
}
|
|
@@ -923,9 +934,26 @@ Features (${features.length} total)`));
|
|
|
923
934
|
const ticketCount = f._count?.tickets != null ? chalk3.gray(` \u2014 ${f._count.tickets} tickets`) : "";
|
|
924
935
|
console.log(` ${statusBadge} ${chalk3.bold(f.name)}${ticketCount}`);
|
|
925
936
|
console.log(chalk3.gray(` ID: ${f.id}`));
|
|
937
|
+
if (f.keyResultLinks?.length) {
|
|
938
|
+
const titles = f.keyResultLinks.map((l) => l.keyResult.title).join("; ");
|
|
939
|
+
console.log(chalk3.gray(` KRs: ${titles}`));
|
|
940
|
+
}
|
|
926
941
|
}
|
|
927
942
|
console.log();
|
|
928
943
|
}
|
|
944
|
+
function summarizeFeatureKeyResult(link) {
|
|
945
|
+
const kr = link.keyResult;
|
|
946
|
+
return {
|
|
947
|
+
keyResultId: kr.id,
|
|
948
|
+
title: kr.title,
|
|
949
|
+
period: kr.period,
|
|
950
|
+
goalId: kr.goalId,
|
|
951
|
+
status: kr.status ?? null,
|
|
952
|
+
currentValue: kr.currentValue ?? null,
|
|
953
|
+
targetValue: kr.targetValue ?? null,
|
|
954
|
+
unit: kr.unit ?? null
|
|
955
|
+
};
|
|
956
|
+
}
|
|
929
957
|
function transformFeature(feature) {
|
|
930
958
|
return {
|
|
931
959
|
id: feature.id,
|
|
@@ -938,6 +966,12 @@ function transformFeature(feature) {
|
|
|
938
966
|
priority: feature.priority,
|
|
939
967
|
goalId: feature.goalId,
|
|
940
968
|
goal: feature.goal ?? null,
|
|
969
|
+
// Flattened out of the join row (ADR-0050): callers building a per-feature
|
|
970
|
+
// "which key results does this move" column want the key results, not the
|
|
971
|
+
// edge rows. `goal` above is the coarser Objective alignment and is a
|
|
972
|
+
// different question - the two are allowed to disagree, so both ride along.
|
|
973
|
+
// Progress values are present on `features get` and absent on `list`.
|
|
974
|
+
keyResults: feature.keyResultLinks?.map(summarizeFeatureKeyResult) ?? null,
|
|
941
975
|
counts: feature._count ?? null,
|
|
942
976
|
createdAt: new Date(feature.createdAt).toISOString(),
|
|
943
977
|
updatedAt: new Date(feature.updatedAt).toISOString()
|
|
@@ -1324,6 +1358,157 @@ Pages (${pages.length} total)`));
|
|
|
1324
1358
|
}
|
|
1325
1359
|
console.log();
|
|
1326
1360
|
}
|
|
1361
|
+
function meetingWhen(meeting) {
|
|
1362
|
+
return new Date(meeting.meetingDate ?? meeting.createdAt);
|
|
1363
|
+
}
|
|
1364
|
+
function renderMeetingSummary(summary) {
|
|
1365
|
+
if (!summary.trimStart().startsWith("{")) return summary;
|
|
1366
|
+
try {
|
|
1367
|
+
const parsed = JSON.parse(summary);
|
|
1368
|
+
if (parsed && typeof parsed === "object") {
|
|
1369
|
+
const obj = parsed;
|
|
1370
|
+
const parts = [obj.overview, obj.detailed_breakdown].filter(
|
|
1371
|
+
(v) => typeof v === "string" && v.length > 0
|
|
1372
|
+
);
|
|
1373
|
+
if (parts.length > 0) return parts.join("\n\n");
|
|
1374
|
+
}
|
|
1375
|
+
} catch {
|
|
1376
|
+
}
|
|
1377
|
+
return summary;
|
|
1378
|
+
}
|
|
1379
|
+
function transformMeeting(m) {
|
|
1380
|
+
return {
|
|
1381
|
+
id: m.id,
|
|
1382
|
+
sessionId: m.sessionId,
|
|
1383
|
+
title: m.title,
|
|
1384
|
+
description: m.description,
|
|
1385
|
+
notes: m.notes,
|
|
1386
|
+
summary: m.summary,
|
|
1387
|
+
transcription: m.transcription,
|
|
1388
|
+
meetingDate: m.meetingDate,
|
|
1389
|
+
createdAt: m.createdAt,
|
|
1390
|
+
updatedAt: m.updatedAt,
|
|
1391
|
+
userId: m.userId,
|
|
1392
|
+
projectId: m.projectId,
|
|
1393
|
+
workspaceId: m.workspaceId,
|
|
1394
|
+
archivedAt: m.archivedAt,
|
|
1395
|
+
durationSeconds: m.durationSeconds ?? null,
|
|
1396
|
+
participantCount: m.participantCount ?? null,
|
|
1397
|
+
videoUrl: m.videoUrl ?? null,
|
|
1398
|
+
project: m.project ?? null,
|
|
1399
|
+
workspace: m.workspace ?? null,
|
|
1400
|
+
sourceIntegration: m.sourceIntegration ?? null,
|
|
1401
|
+
participants: m.participants ?? [],
|
|
1402
|
+
actions: m.actions ?? []
|
|
1403
|
+
};
|
|
1404
|
+
}
|
|
1405
|
+
function transformMeetingListRow(m) {
|
|
1406
|
+
const { notes, summary, transcription, ...rest } = transformMeeting(m);
|
|
1407
|
+
return {
|
|
1408
|
+
...rest,
|
|
1409
|
+
hasNotes: Boolean(notes),
|
|
1410
|
+
hasSummary: Boolean(summary),
|
|
1411
|
+
hasTranscript: Boolean(transcription)
|
|
1412
|
+
};
|
|
1413
|
+
}
|
|
1414
|
+
function outputMeetingJson(meeting) {
|
|
1415
|
+
console.log(JSON.stringify(transformMeeting(meeting), null, 2));
|
|
1416
|
+
}
|
|
1417
|
+
function outputMeetingPretty(meeting, options = {}) {
|
|
1418
|
+
console.log(chalk3.gray("\u2500".repeat(50)));
|
|
1419
|
+
console.log(`
|
|
1420
|
+
${chalk3.bold(meeting.title ?? "Untitled meeting")}`);
|
|
1421
|
+
console.log(chalk3.gray(` ID: ${meeting.id}`));
|
|
1422
|
+
console.log(` ${chalk3.gray("Date:")} ${meetingWhen(meeting).toLocaleString()}`);
|
|
1423
|
+
if (meeting.workspace) {
|
|
1424
|
+
console.log(` ${chalk3.gray("Workspace:")} ${meeting.workspace.name}`);
|
|
1425
|
+
}
|
|
1426
|
+
if (meeting.project) {
|
|
1427
|
+
console.log(` ${chalk3.gray("Project:")} ${meeting.project.name}`);
|
|
1428
|
+
}
|
|
1429
|
+
if (meeting.sourceIntegration) {
|
|
1430
|
+
console.log(` ${chalk3.gray("Source:")} ${meeting.sourceIntegration.provider}`);
|
|
1431
|
+
}
|
|
1432
|
+
if (meeting.durationSeconds) {
|
|
1433
|
+
console.log(` ${chalk3.gray("Duration:")} ${Math.round(meeting.durationSeconds / 60)} min`);
|
|
1434
|
+
}
|
|
1435
|
+
if (meeting.archivedAt) {
|
|
1436
|
+
console.log(` ${chalk3.yellow("Archived")}`);
|
|
1437
|
+
}
|
|
1438
|
+
if (meeting.participants && meeting.participants.length > 0) {
|
|
1439
|
+
const people = meeting.participants.map((p) => p.name ?? p.email).join(", ");
|
|
1440
|
+
console.log(` ${chalk3.gray("Participants:")} ${people}`);
|
|
1441
|
+
}
|
|
1442
|
+
if (meeting.description) {
|
|
1443
|
+
console.log(`
|
|
1444
|
+
${meeting.description}`);
|
|
1445
|
+
}
|
|
1446
|
+
if (meeting.summary) {
|
|
1447
|
+
console.log(`
|
|
1448
|
+
${chalk3.bold("Summary")}`);
|
|
1449
|
+
console.log(renderMeetingSummary(meeting.summary));
|
|
1450
|
+
}
|
|
1451
|
+
if (meeting.notes) {
|
|
1452
|
+
console.log(`
|
|
1453
|
+
${chalk3.bold("Notes")}`);
|
|
1454
|
+
console.log(meeting.notes);
|
|
1455
|
+
} else {
|
|
1456
|
+
console.log(chalk3.gray("\nNo notes yet."));
|
|
1457
|
+
}
|
|
1458
|
+
if (options.transcript) {
|
|
1459
|
+
if (meeting.transcription) {
|
|
1460
|
+
console.log(`
|
|
1461
|
+
${chalk3.bold("Transcript")}`);
|
|
1462
|
+
console.log(meeting.transcription);
|
|
1463
|
+
} else {
|
|
1464
|
+
console.log(chalk3.gray("\nNo transcript."));
|
|
1465
|
+
}
|
|
1466
|
+
} else if (meeting.transcription) {
|
|
1467
|
+
console.log(chalk3.gray("\n(transcript available \u2014 pass --transcript to print it)"));
|
|
1468
|
+
}
|
|
1469
|
+
console.log();
|
|
1470
|
+
}
|
|
1471
|
+
function outputMeetingsJson(meetings) {
|
|
1472
|
+
console.log(
|
|
1473
|
+
JSON.stringify(
|
|
1474
|
+
{ meetings: meetings.map(transformMeetingListRow), total: meetings.length },
|
|
1475
|
+
null,
|
|
1476
|
+
2
|
|
1477
|
+
)
|
|
1478
|
+
);
|
|
1479
|
+
}
|
|
1480
|
+
function outputMeetingsPretty(meetings) {
|
|
1481
|
+
if (meetings.length === 0) {
|
|
1482
|
+
console.log(chalk3.gray("No meetings found."));
|
|
1483
|
+
return;
|
|
1484
|
+
}
|
|
1485
|
+
console.log(chalk3.bold(`
|
|
1486
|
+
Meetings (${meetings.length} total)`));
|
|
1487
|
+
console.log(chalk3.gray("\u2500".repeat(50)));
|
|
1488
|
+
for (const m of meetings) {
|
|
1489
|
+
const flags = [
|
|
1490
|
+
m.notes ? "notes" : null,
|
|
1491
|
+
m.summary ? "summary" : null,
|
|
1492
|
+
m.transcription ? "transcript" : null
|
|
1493
|
+
].filter(Boolean);
|
|
1494
|
+
const archived = m.archivedAt ? chalk3.yellow(" [archived]") : "";
|
|
1495
|
+
console.log(
|
|
1496
|
+
` ${chalk3.bold(m.title ?? "Untitled meeting")}${archived} ${chalk3.gray(
|
|
1497
|
+
meetingWhen(m).toLocaleDateString()
|
|
1498
|
+
)}`
|
|
1499
|
+
);
|
|
1500
|
+
console.log(chalk3.gray(` ID: ${m.id}`));
|
|
1501
|
+
const context = [
|
|
1502
|
+
m.project ? `Project: ${m.project.name}` : null,
|
|
1503
|
+
m.participantCount ? `${m.participantCount} participants` : null,
|
|
1504
|
+
flags.length > 0 ? flags.join(", ") : null
|
|
1505
|
+
].filter(Boolean);
|
|
1506
|
+
if (context.length > 0) {
|
|
1507
|
+
console.log(chalk3.gray(` ${context.join(" \xB7 ")}`));
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
console.log();
|
|
1511
|
+
}
|
|
1327
1512
|
function outputRequirementJson(requirement) {
|
|
1328
1513
|
console.log(JSON.stringify(requirement, null, 2));
|
|
1329
1514
|
}
|
|
@@ -3770,8 +3955,211 @@ function createLabelsCommand() {
|
|
|
3770
3955
|
return labels;
|
|
3771
3956
|
}
|
|
3772
3957
|
|
|
3773
|
-
// src/commands/
|
|
3958
|
+
// src/commands/meetings.ts
|
|
3774
3959
|
import { Command as Command13 } from "commander";
|
|
3960
|
+
import chalk6 from "chalk";
|
|
3961
|
+
|
|
3962
|
+
// src/utils/input.ts
|
|
3963
|
+
import { readFileSync } from "fs";
|
|
3964
|
+
var stdinConsumed = false;
|
|
3965
|
+
function readText(inline, file) {
|
|
3966
|
+
if (inline !== void 0) return inline;
|
|
3967
|
+
if (file === void 0) return void 0;
|
|
3968
|
+
if (file === "-") {
|
|
3969
|
+
if (stdinConsumed) {
|
|
3970
|
+
throw new Error('stdin ("-") can only back one option per invocation.');
|
|
3971
|
+
}
|
|
3972
|
+
stdinConsumed = true;
|
|
3973
|
+
return readFileSync(0, "utf-8");
|
|
3974
|
+
}
|
|
3975
|
+
return readFileSync(file, "utf-8");
|
|
3976
|
+
}
|
|
3977
|
+
function parseDate2(value) {
|
|
3978
|
+
if (value === void 0 || value === "") return void 0;
|
|
3979
|
+
const date = /^\d{4}-\d{2}-\d{2}$/.test(value) ? /* @__PURE__ */ new Date(`${value}T00:00:00`) : new Date(value);
|
|
3980
|
+
if (Number.isNaN(date.getTime())) {
|
|
3981
|
+
throw new Error(
|
|
3982
|
+
`Invalid date: "${value}". Use ISO format, e.g. 2026-08-25 or 2026-08-25T14:00.`
|
|
3983
|
+
);
|
|
3984
|
+
}
|
|
3985
|
+
return date;
|
|
3986
|
+
}
|
|
3987
|
+
|
|
3988
|
+
// src/commands/meetings.ts
|
|
3989
|
+
function createMeetingsCommand() {
|
|
3990
|
+
const meetings = new Command13("meetings").description(
|
|
3991
|
+
"Manage meetings and their notes (recorded, imported, or manually created)"
|
|
3992
|
+
);
|
|
3993
|
+
meetings.command("list").description(
|
|
3994
|
+
'List meetings you can see (owned, attended, or shared via project/workspace). JSON rows carry hasNotes/hasSummary/hasTranscript flags instead of the bodies \u2014 use "get" for content.'
|
|
3995
|
+
).option("--workspace <slug|id>", "Restrict to one workspace").option("--mine", "Only meetings you own or attended").option("--archived", "Include archived meetings").action(
|
|
3996
|
+
async (options, cmd) => {
|
|
3997
|
+
const globalOpts = cmd.optsWithGlobals();
|
|
3998
|
+
const useJson = shouldUseJson(globalOpts.json, globalOpts.pretty);
|
|
3999
|
+
try {
|
|
4000
|
+
const client = getClient();
|
|
4001
|
+
const workspaceId = options.workspace ? await resolveWorkspaceId(client, options.workspace) : void 0;
|
|
4002
|
+
const list = await client.meetings.list({
|
|
4003
|
+
workspaceId,
|
|
4004
|
+
includeArchived: options.archived,
|
|
4005
|
+
meetingType: options.mine ? "mine" : void 0
|
|
4006
|
+
});
|
|
4007
|
+
if (useJson) outputMeetingsJson(list);
|
|
4008
|
+
else outputMeetingsPretty(list);
|
|
4009
|
+
} catch (error) {
|
|
4010
|
+
handleError(error, useJson);
|
|
4011
|
+
}
|
|
4012
|
+
}
|
|
4013
|
+
);
|
|
4014
|
+
meetings.command("get <id>").description("Get a meeting: details, summary, and notes").option("--transcript", "Also print the raw transcript (pretty mode; JSON always includes it)").action(
|
|
4015
|
+
async (id, options, cmd) => {
|
|
4016
|
+
const globalOpts = cmd.optsWithGlobals();
|
|
4017
|
+
const useJson = shouldUseJson(globalOpts.json, globalOpts.pretty);
|
|
4018
|
+
try {
|
|
4019
|
+
const client = getClient();
|
|
4020
|
+
const meeting = await client.meetings.get(id);
|
|
4021
|
+
if (useJson) outputMeetingJson(meeting);
|
|
4022
|
+
else outputMeetingPretty(meeting, { transcript: options.transcript });
|
|
4023
|
+
} catch (error) {
|
|
4024
|
+
handleError(error, useJson);
|
|
4025
|
+
}
|
|
4026
|
+
}
|
|
4027
|
+
);
|
|
4028
|
+
meetings.command("create").description(
|
|
4029
|
+
"Create a meeting manually. Transcript: --transcript text, --transcript-file <path>, or --transcript-file - for stdin."
|
|
4030
|
+
).requiredOption("-t, --title <title>", "Meeting title").option("--transcript <text>", "Transcript text (required by the API)").option("--transcript-file <path>", 'Read the transcript from a file ("-" = stdin)').option("--notes <markdown>", "Meeting notes").option("--notes-file <path>", 'Read the notes from a file ("-" = stdin)').option("--description <text>", "Short description").option("--date <iso>", "When the meeting occurred (e.g. 2026-08-25T14:00; a bare date is local midnight)").option("--project <id>", "Link to a project (the meeting inherits its workspace)").option("--workspace <slug|id>", "Workspace (omit for a personal meeting)").action(
|
|
4031
|
+
async (options, cmd) => {
|
|
4032
|
+
const globalOpts = cmd.optsWithGlobals();
|
|
4033
|
+
const useJson = shouldUseJson(globalOpts.json, globalOpts.pretty);
|
|
4034
|
+
try {
|
|
4035
|
+
const client = getClient();
|
|
4036
|
+
const transcription = readText(options.transcript, options.transcriptFile);
|
|
4037
|
+
if (transcription === void 0) {
|
|
4038
|
+
throw new Error(
|
|
4039
|
+
"A transcript is required: pass --transcript <text> or --transcript-file <path|->."
|
|
4040
|
+
);
|
|
4041
|
+
}
|
|
4042
|
+
if (transcription.trim() === "") {
|
|
4043
|
+
throw new Error("The transcript is empty. The API requires a non-empty transcript.");
|
|
4044
|
+
}
|
|
4045
|
+
const workspaceId = options.workspace ? await resolveWorkspaceId(client, options.workspace) : void 0;
|
|
4046
|
+
const meeting = await client.meetings.create({
|
|
4047
|
+
title: options.title,
|
|
4048
|
+
transcription,
|
|
4049
|
+
notes: readText(options.notes, options.notesFile),
|
|
4050
|
+
description: options.description,
|
|
4051
|
+
meetingDate: parseDate2(options.date),
|
|
4052
|
+
projectId: options.project,
|
|
4053
|
+
workspaceId
|
|
4054
|
+
});
|
|
4055
|
+
if (useJson) outputMeetingJson(meeting);
|
|
4056
|
+
else {
|
|
4057
|
+
console.log("\n\u2713 Meeting created");
|
|
4058
|
+
outputMeetingPretty(meeting);
|
|
4059
|
+
}
|
|
4060
|
+
} catch (error) {
|
|
4061
|
+
handleError(error, useJson);
|
|
4062
|
+
}
|
|
4063
|
+
}
|
|
4064
|
+
);
|
|
4065
|
+
meetings.command("update").description(
|
|
4066
|
+
"Update a meeting; only the fields you pass are written. Title and other fields are two API calls \u2014 on a mid-flight failure the title may already be saved."
|
|
4067
|
+
).requiredOption("--id <id>", "Meeting CUID").option("-t, --title <title>", "New title").option("--notes <markdown>", "Replace the meeting notes").option("--notes-file <path>", 'Read the new notes from a file ("-" = stdin)').option("--summary <text>", "Replace the summary").option("--description <text>", "Replace the description").option("--date <iso>", "When the meeting occurred").action(
|
|
4068
|
+
async (options, cmd) => {
|
|
4069
|
+
const globalOpts = cmd.optsWithGlobals();
|
|
4070
|
+
const useJson = shouldUseJson(globalOpts.json, globalOpts.pretty);
|
|
4071
|
+
try {
|
|
4072
|
+
const notes2 = readText(options.notes, options.notesFile);
|
|
4073
|
+
if (options.title === void 0 && notes2 === void 0 && options.summary === void 0 && options.description === void 0 && options.date === void 0) {
|
|
4074
|
+
throw new Error(
|
|
4075
|
+
"Nothing to update. Pass at least one of --title, --notes, --notes-file, --summary, --description, --date."
|
|
4076
|
+
);
|
|
4077
|
+
}
|
|
4078
|
+
const client = getClient();
|
|
4079
|
+
const meeting = await client.meetings.update({
|
|
4080
|
+
id: options.id,
|
|
4081
|
+
title: options.title,
|
|
4082
|
+
notes: notes2,
|
|
4083
|
+
summary: options.summary,
|
|
4084
|
+
description: options.description,
|
|
4085
|
+
meetingDate: parseDate2(options.date)
|
|
4086
|
+
});
|
|
4087
|
+
if (useJson) outputMeetingJson(meeting);
|
|
4088
|
+
else {
|
|
4089
|
+
console.log("\n\u2713 Meeting updated");
|
|
4090
|
+
outputMeetingPretty(meeting);
|
|
4091
|
+
}
|
|
4092
|
+
} catch (error) {
|
|
4093
|
+
handleError(error, useJson);
|
|
4094
|
+
}
|
|
4095
|
+
}
|
|
4096
|
+
);
|
|
4097
|
+
const notes = new Command13("notes").description(
|
|
4098
|
+
"Read and write a meeting's notes"
|
|
4099
|
+
);
|
|
4100
|
+
notes.command("get <id>").description(
|
|
4101
|
+
"Print the meeting notes as raw Markdown (safe to redirect to a file); pass --json for a {id, notes} envelope"
|
|
4102
|
+
).action(async (id, _options, cmd) => {
|
|
4103
|
+
const globalOpts = cmd.optsWithGlobals();
|
|
4104
|
+
try {
|
|
4105
|
+
const client = getClient();
|
|
4106
|
+
const body = await client.meetings.getNotes(id);
|
|
4107
|
+
if (globalOpts.json) {
|
|
4108
|
+
console.log(JSON.stringify({ id, notes: body }, null, 2));
|
|
4109
|
+
} else if (body !== null) {
|
|
4110
|
+
process.stdout.write(body.endsWith("\n") ? body : `${body}
|
|
4111
|
+
`);
|
|
4112
|
+
} else if (process.stdout.isTTY) {
|
|
4113
|
+
console.log(chalk6.gray("No notes yet."));
|
|
4114
|
+
}
|
|
4115
|
+
} catch (error) {
|
|
4116
|
+
handleError(error, shouldUseJson(globalOpts.json, globalOpts.pretty));
|
|
4117
|
+
}
|
|
4118
|
+
});
|
|
4119
|
+
notes.command("set <id> [notes]").description("Replace the meeting notes. Body: inline, --file <path>, or --file - for stdin.").option("--file <path>", 'Read the notes from a file ("-" = stdin)').action(
|
|
4120
|
+
async (id, inline, options, cmd) => {
|
|
4121
|
+
const globalOpts = cmd.optsWithGlobals();
|
|
4122
|
+
const useJson = shouldUseJson(globalOpts.json, globalOpts.pretty);
|
|
4123
|
+
try {
|
|
4124
|
+
const body = readText(inline, options.file);
|
|
4125
|
+
if (body === void 0) {
|
|
4126
|
+
throw new Error("Pass the notes inline or via --file <path|->.");
|
|
4127
|
+
}
|
|
4128
|
+
const client = getClient();
|
|
4129
|
+
const meeting = await client.meetings.setNotes(id, body);
|
|
4130
|
+
if (useJson) outputMeetingJson(meeting);
|
|
4131
|
+
else console.log("\u2713 Notes saved");
|
|
4132
|
+
} catch (error) {
|
|
4133
|
+
handleError(error, useJson);
|
|
4134
|
+
}
|
|
4135
|
+
}
|
|
4136
|
+
);
|
|
4137
|
+
notes.command("append <id> [notes]").description(
|
|
4138
|
+
"Append a block to the meeting notes (separated by a blank line). Read-modify-write: concurrent appends can lose one side."
|
|
4139
|
+
).option("--file <path>", 'Read the block from a file ("-" = stdin)').action(
|
|
4140
|
+
async (id, inline, options, cmd) => {
|
|
4141
|
+
const globalOpts = cmd.optsWithGlobals();
|
|
4142
|
+
const useJson = shouldUseJson(globalOpts.json, globalOpts.pretty);
|
|
4143
|
+
try {
|
|
4144
|
+
const body = readText(inline, options.file);
|
|
4145
|
+
if (body === void 0) {
|
|
4146
|
+
throw new Error("Pass the notes inline or via --file <path|->.");
|
|
4147
|
+
}
|
|
4148
|
+
const client = getClient();
|
|
4149
|
+
const meeting = await client.meetings.appendNotes(id, body);
|
|
4150
|
+
if (useJson) outputMeetingJson(meeting);
|
|
4151
|
+
else console.log("\u2713 Notes appended");
|
|
4152
|
+
} catch (error) {
|
|
4153
|
+
handleError(error, useJson);
|
|
4154
|
+
}
|
|
4155
|
+
}
|
|
4156
|
+
);
|
|
4157
|
+
meetings.addCommand(notes);
|
|
4158
|
+
return meetings;
|
|
4159
|
+
}
|
|
4160
|
+
|
|
4161
|
+
// src/commands/organizations.ts
|
|
4162
|
+
import { Command as Command14 } from "commander";
|
|
3775
4163
|
var VALID_SIZES = [
|
|
3776
4164
|
"1-10",
|
|
3777
4165
|
"11-50",
|
|
@@ -3781,7 +4169,7 @@ var VALID_SIZES = [
|
|
|
3781
4169
|
"1000+"
|
|
3782
4170
|
];
|
|
3783
4171
|
function createOrganizationsCommand() {
|
|
3784
|
-
const organizations = new
|
|
4172
|
+
const organizations = new Command14("organizations").alias("orgs").description("Manage CRM organizations");
|
|
3785
4173
|
organizations.command("list").description("List organizations").requiredOption("--workspace <id>", "Workspace ID").option("--search <query>", "Search by name or description").option("--industry <industry>", "Filter by industry").option("--limit <n>", "Max results to return", parseInt).option("--cursor <cursor>", "Pagination cursor").action(async (options, cmd) => {
|
|
3786
4174
|
const globalOpts = cmd.optsWithGlobals();
|
|
3787
4175
|
const useJson = shouldUseJson(globalOpts.json, globalOpts.pretty);
|
|
@@ -3849,13 +4237,12 @@ function createOrganizationsCommand() {
|
|
|
3849
4237
|
}
|
|
3850
4238
|
|
|
3851
4239
|
// src/commands/pages.ts
|
|
3852
|
-
import {
|
|
3853
|
-
import { Command as Command15 } from "commander";
|
|
4240
|
+
import { Command as Command16 } from "commander";
|
|
3854
4241
|
|
|
3855
4242
|
// src/commands/pageComments.ts
|
|
3856
|
-
import { Command as
|
|
4243
|
+
import { Command as Command15 } from "commander";
|
|
3857
4244
|
function createPageCommentsCommand() {
|
|
3858
|
-
const comment = new
|
|
4245
|
+
const comment = new Command15("comment").description(
|
|
3859
4246
|
"Read and post comments on a page. Mention teammates with --mention."
|
|
3860
4247
|
);
|
|
3861
4248
|
comment.command("list").description("List comments on a page").requiredOption("--page <id>", "Page ID").action(async (options, cmd) => {
|
|
@@ -3949,14 +4336,8 @@ function createPageCommentsCommand() {
|
|
|
3949
4336
|
}
|
|
3950
4337
|
|
|
3951
4338
|
// src/commands/pages.ts
|
|
3952
|
-
function readBody(body, bodyFile) {
|
|
3953
|
-
if (body !== void 0) return body;
|
|
3954
|
-
if (bodyFile === void 0) return void 0;
|
|
3955
|
-
if (bodyFile === "-") return readFileSync(0, "utf-8");
|
|
3956
|
-
return readFileSync(bodyFile, "utf-8");
|
|
3957
|
-
}
|
|
3958
4339
|
function createPagesCommand() {
|
|
3959
|
-
const pages = new
|
|
4340
|
+
const pages = new Command16("pages").description(
|
|
3960
4341
|
'Manage Knowledge pages (PRDs, research, technical specs). Link one to a feature with "features link-page".'
|
|
3961
4342
|
);
|
|
3962
4343
|
pages.command("list").description("List pages in a workspace").option("--workspace <slug|id>", "Workspace (defaults to the configured default)").option("--search <text>", "Filter by title/content").action(
|
|
@@ -3999,7 +4380,7 @@ function createPagesCommand() {
|
|
|
3999
4380
|
const page = await client.pages.create({
|
|
4000
4381
|
workspaceId,
|
|
4001
4382
|
title: options.title,
|
|
4002
|
-
body:
|
|
4383
|
+
body: readText(options.body, options.bodyFile)
|
|
4003
4384
|
});
|
|
4004
4385
|
if (useJson) outputPageJson(page);
|
|
4005
4386
|
else {
|
|
@@ -4022,7 +4403,7 @@ function createPagesCommand() {
|
|
|
4022
4403
|
const page = await client.pages.update({
|
|
4023
4404
|
id: options.id,
|
|
4024
4405
|
title: options.title,
|
|
4025
|
-
body:
|
|
4406
|
+
body: readText(options.body, options.bodyFile)
|
|
4026
4407
|
});
|
|
4027
4408
|
if (useJson) outputPageJson(page);
|
|
4028
4409
|
else {
|
|
@@ -4039,9 +4420,9 @@ function createPagesCommand() {
|
|
|
4039
4420
|
}
|
|
4040
4421
|
|
|
4041
4422
|
// src/commands/products.ts
|
|
4042
|
-
import { Command as
|
|
4423
|
+
import { Command as Command17 } from "commander";
|
|
4043
4424
|
function createProductsCommand() {
|
|
4044
|
-
const products = new
|
|
4425
|
+
const products = new Command17("products").description(
|
|
4045
4426
|
"Manage products. A workspace contains products; a product holds features and tickets."
|
|
4046
4427
|
);
|
|
4047
4428
|
products.command("list").description("List products in a workspace").option("--workspace <slug|id>", "Workspace slug or CUID (defaults to configured workspace)").action(async (options, cmd) => {
|
|
@@ -4104,7 +4485,7 @@ function createProductsCommand() {
|
|
|
4104
4485
|
}
|
|
4105
4486
|
|
|
4106
4487
|
// src/commands/projects.ts
|
|
4107
|
-
import { Command as
|
|
4488
|
+
import { Command as Command18 } from "commander";
|
|
4108
4489
|
var PROJECT_STATUSES = [
|
|
4109
4490
|
"ACTIVE",
|
|
4110
4491
|
"ON_HOLD",
|
|
@@ -4131,7 +4512,7 @@ function validateProjectPriority(value) {
|
|
|
4131
4512
|
return value;
|
|
4132
4513
|
}
|
|
4133
4514
|
function createProjectsCommand() {
|
|
4134
|
-
const projects = new
|
|
4515
|
+
const projects = new Command18("projects").description("Manage projects");
|
|
4135
4516
|
projects.command("list").description("List all projects").option("--workspace <slug|id>", "Workspace slug or CUID").option("--include-actions", "Include actions in output").action(async (options, cmd) => {
|
|
4136
4517
|
const globalOpts = cmd.optsWithGlobals();
|
|
4137
4518
|
const useJson = shouldUseJson(globalOpts.json, globalOpts.pretty);
|
|
@@ -4250,8 +4631,8 @@ Re-run with --force to delete it anyway.`
|
|
|
4250
4631
|
}
|
|
4251
4632
|
|
|
4252
4633
|
// src/commands/search.ts
|
|
4253
|
-
import { Command as
|
|
4254
|
-
import
|
|
4634
|
+
import { Command as Command19 } from "commander";
|
|
4635
|
+
import chalk7 from "chalk";
|
|
4255
4636
|
var TYPE_LABELS = {
|
|
4256
4637
|
workspace: "Workspaces",
|
|
4257
4638
|
project: "Projects",
|
|
@@ -4269,7 +4650,7 @@ var TYPE_LABELS = {
|
|
|
4269
4650
|
product: "Products"
|
|
4270
4651
|
};
|
|
4271
4652
|
function createSearchCommand() {
|
|
4272
|
-
const search = new
|
|
4653
|
+
const search = new Command19("search").description(
|
|
4273
4654
|
"Global search across projects, actions, goals, workspaces and more \u2014 same coverage as the app's Cmd+K palette"
|
|
4274
4655
|
).argument("<query>", "Text to search for").option("-w, --workspace <slug>", "Restrict results to one workspace (slug or ID)").option("-l, --limit <n>", "Max results per entity type (1-25, default 10)").action(async (query, options, cmd) => {
|
|
4275
4656
|
const globalOpts = cmd.optsWithGlobals();
|
|
@@ -4283,10 +4664,10 @@ function createSearchCommand() {
|
|
|
4283
4664
|
(w) => w.slug === options.workspace || w.id === options.workspace
|
|
4284
4665
|
);
|
|
4285
4666
|
if (!match) {
|
|
4286
|
-
console.error(
|
|
4287
|
-
console.log(
|
|
4667
|
+
console.error(chalk7.red(`Workspace "${options.workspace}" not found.`));
|
|
4668
|
+
console.log(chalk7.gray("Available workspaces:"));
|
|
4288
4669
|
workspaces.forEach((w) => {
|
|
4289
|
-
console.log(
|
|
4670
|
+
console.log(chalk7.gray(` - ${w.slug} (${w.name})`));
|
|
4290
4671
|
});
|
|
4291
4672
|
process.exit(1);
|
|
4292
4673
|
}
|
|
@@ -4299,7 +4680,7 @@ function createSearchCommand() {
|
|
|
4299
4680
|
return;
|
|
4300
4681
|
}
|
|
4301
4682
|
if (result.results.length === 0) {
|
|
4302
|
-
console.log(
|
|
4683
|
+
console.log(chalk7.gray(`No matches for "${result.query}".`));
|
|
4303
4684
|
return;
|
|
4304
4685
|
}
|
|
4305
4686
|
const byType = /* @__PURE__ */ new Map();
|
|
@@ -4309,14 +4690,14 @@ function createSearchCommand() {
|
|
|
4309
4690
|
byType.set(r.type, bucket);
|
|
4310
4691
|
}
|
|
4311
4692
|
for (const [type, rows] of byType) {
|
|
4312
|
-
console.log(
|
|
4693
|
+
console.log(chalk7.bold(`
|
|
4313
4694
|
${TYPE_LABELS[type] ?? type}`));
|
|
4314
4695
|
for (const row of rows) {
|
|
4315
|
-
const parts = [
|
|
4316
|
-
if (row.subtitle) parts.push(
|
|
4317
|
-
if (row.workspace) parts.push(
|
|
4318
|
-
console.log(` ${parts.join(
|
|
4319
|
-
console.log(
|
|
4696
|
+
const parts = [chalk7.white(row.title)];
|
|
4697
|
+
if (row.subtitle) parts.push(chalk7.gray(row.subtitle));
|
|
4698
|
+
if (row.workspace) parts.push(chalk7.cyan(`@${row.workspace.slug}`));
|
|
4699
|
+
console.log(` ${parts.join(chalk7.gray(" \xB7 "))}`);
|
|
4700
|
+
console.log(chalk7.gray(` ${row.id}${row.url ? ` ${row.url}` : ""}`));
|
|
4320
4701
|
}
|
|
4321
4702
|
}
|
|
4322
4703
|
console.log();
|
|
@@ -4328,7 +4709,7 @@ ${TYPE_LABELS[type] ?? type}`));
|
|
|
4328
4709
|
}
|
|
4329
4710
|
|
|
4330
4711
|
// src/commands/tickets.ts
|
|
4331
|
-
import { Command as
|
|
4712
|
+
import { Command as Command20 } from "commander";
|
|
4332
4713
|
function collectRepeatable(value, previous) {
|
|
4333
4714
|
return [...previous, value];
|
|
4334
4715
|
}
|
|
@@ -4371,7 +4752,7 @@ function validateTicketType(value) {
|
|
|
4371
4752
|
return value;
|
|
4372
4753
|
}
|
|
4373
4754
|
function createTicketsCommand() {
|
|
4374
|
-
const tickets = new
|
|
4755
|
+
const tickets = new Command20("tickets").description(
|
|
4375
4756
|
"Manage product backlog tickets. Tickets live under a product, link to features/epics, depend on each other, and can be implemented via actions."
|
|
4376
4757
|
);
|
|
4377
4758
|
tickets.command("list").description(
|
|
@@ -4484,7 +4865,7 @@ function createTicketsCommand() {
|
|
|
4484
4865
|
handleError(error, useJson);
|
|
4485
4866
|
}
|
|
4486
4867
|
});
|
|
4487
|
-
tickets.command("create").description("Create a new ticket in a product").requiredOption("--product <slug|id>", "Product slug or CUID").requiredOption("-t, --title <title>", "Ticket title").option("-b, --body <text>", "Body (markdown supported)").option("--type <type>", `Ticket type: ${TICKET_TYPES.join(", ")}`).option("--status <status>", `Initial status: ${TICKET_STATUSES.join(", ")}`).option("--priority <n>", "Priority 0-4 (lower = higher)", parseInt).option("--points <n>", "Story points", parseFloat).option("--feature <id>", "Feature CUID to attach to").option("--scope <id>", "Feature scope CUID to attach to (requires --feature)").option("--epic <id>", "Epic CUID to attach to").option("--assignee <id>", "Assignee user ID").option("--branch <name>", "Branch name").option("--pr <url>", "Pull request URL").option("--workspace <slug|id>", "Workspace (required when --product is a slug)").option(
|
|
4868
|
+
tickets.command("create").description("Create a new ticket in a product").requiredOption("--product <slug|id>", "Product slug or CUID").requiredOption("-t, --title <title>", "Ticket title").option("-b, --body <text>", "Body (markdown supported)").option("--type <type>", `Ticket type: ${TICKET_TYPES.join(", ")}`).option("--status <status>", `Initial status: ${TICKET_STATUSES.join(", ")}`).option("--priority <n>", "Priority 0-4 (lower = higher)", parseInt).option("--points <n>", "Story points", parseFloat).option("--feature <id>", "Feature CUID to attach to").option("--scope <id>", "Feature scope CUID to attach to (requires --feature)").option("--epic <id>", "Epic CUID to attach to").option("--cycle <id>", "Cycle CUID to assign to").option("--assignee <id>", "Assignee user ID").option("--branch <name>", "Branch name").option("--pr <url>", "Pull request URL").option("--workspace <slug|id>", "Workspace (required when --product is a slug)").option(
|
|
4488
4869
|
"--label <slug-or-id>",
|
|
4489
4870
|
"Label to attach (repeatable)",
|
|
4490
4871
|
collectRepeatable,
|
|
@@ -4514,6 +4895,7 @@ function createTicketsCommand() {
|
|
|
4514
4895
|
featureId: options.feature,
|
|
4515
4896
|
scopeId: options.scope,
|
|
4516
4897
|
epicId: options.epic,
|
|
4898
|
+
cycleId: options.cycle,
|
|
4517
4899
|
assigneeId: options.assignee,
|
|
4518
4900
|
branchName: options.branch,
|
|
4519
4901
|
prUrl: options.pr
|
|
@@ -4536,7 +4918,7 @@ function createTicketsCommand() {
|
|
|
4536
4918
|
}
|
|
4537
4919
|
}
|
|
4538
4920
|
);
|
|
4539
|
-
tickets.command("update").description("Update an existing ticket").requiredOption("--id <id>", "Ticket CUID").option("-t, --title <title>", "New title").option("-b, --body <text>", "New body").option("--type <type>", `Type: ${TICKET_TYPES.join(", ")}`).option("--status <status>", `Status: ${TICKET_STATUSES.join(", ")}`).option("--priority <n>", 'Priority 0-4 (or "null" to clear)').option("--points <n>", 'Story points (or "null" to clear)').option("--feature <id>", 'Feature CUID (or "null" to detach)').option("--epic <id>", 'Epic CUID (or "null" to detach)').option("--assignee <id>", 'Assignee user ID (or "null" to unassign)').option("--branch <name>", 'Branch name (or "null")').option("--pr <url>", 'PR URL (or "null")').option(
|
|
4921
|
+
tickets.command("update").description("Update an existing ticket").requiredOption("--id <id>", "Ticket CUID").option("-t, --title <title>", "New title").option("-b, --body <text>", "New body").option("--type <type>", `Type: ${TICKET_TYPES.join(", ")}`).option("--status <status>", `Status: ${TICKET_STATUSES.join(", ")}`).option("--priority <n>", 'Priority 0-4 (or "null" to clear)').option("--points <n>", 'Story points (or "null" to clear)').option("--feature <id>", 'Feature CUID (or "null" to detach)').option("--epic <id>", 'Epic CUID (or "null" to detach)').option("--cycle <id>", 'Cycle CUID (or "null" to detach)').option("--assignee <id>", 'Assignee user ID (or "null" to unassign)').option("--branch <name>", 'Branch name (or "null")').option("--pr <url>", 'PR URL (or "null")').option(
|
|
4540
4922
|
"--add-label <slug-or-id>",
|
|
4541
4923
|
"Label to attach to this ticket (repeatable)",
|
|
4542
4924
|
collectRepeatable,
|
|
@@ -4583,6 +4965,7 @@ function createTicketsCommand() {
|
|
|
4583
4965
|
points: parseNullableFloat(options.points),
|
|
4584
4966
|
featureId: parseNullableString(options.feature),
|
|
4585
4967
|
epicId: parseNullableString(options.epic),
|
|
4968
|
+
cycleId: parseNullableString(options.cycle),
|
|
4586
4969
|
assigneeId: parseNullableString(options.assignee),
|
|
4587
4970
|
branchName: parseNullableString(options.branch),
|
|
4588
4971
|
prUrl: parseNullableString(options.pr)
|
|
@@ -4695,7 +5078,7 @@ function createTicketsCommand() {
|
|
|
4695
5078
|
handleError(error, useJson);
|
|
4696
5079
|
}
|
|
4697
5080
|
});
|
|
4698
|
-
const comment = new
|
|
5081
|
+
const comment = new Command20("comment").description("Manage comments on a ticket");
|
|
4699
5082
|
comment.command("list").description("List comments on a ticket").requiredOption("--id <id>", "Ticket CUID").action(async (options, cmd) => {
|
|
4700
5083
|
const globalOpts = cmd.optsWithGlobals();
|
|
4701
5084
|
const useJson = shouldUseJson(globalOpts.json, globalOpts.pretty);
|
|
@@ -4787,10 +5170,10 @@ function createTicketsCommand() {
|
|
|
4787
5170
|
}
|
|
4788
5171
|
|
|
4789
5172
|
// src/commands/workspaces.ts
|
|
4790
|
-
import { Command as
|
|
4791
|
-
import
|
|
5173
|
+
import { Command as Command21 } from "commander";
|
|
5174
|
+
import chalk8 from "chalk";
|
|
4792
5175
|
function createWorkspacesCommand() {
|
|
4793
|
-
const workspaces = new
|
|
5176
|
+
const workspaces = new Command21("workspaces").description("Manage workspaces");
|
|
4794
5177
|
workspaces.command("list").description("List all workspaces").action(async (_options, cmd) => {
|
|
4795
5178
|
const globalOpts = cmd.optsWithGlobals();
|
|
4796
5179
|
const useJson = shouldUseJson(globalOpts.json, globalOpts.pretty);
|
|
@@ -4803,7 +5186,7 @@ function createWorkspacesCommand() {
|
|
|
4803
5186
|
const config = getConfig();
|
|
4804
5187
|
outputWorkspacesPretty(workspaces2);
|
|
4805
5188
|
if (config.defaultWorkspaceSlug) {
|
|
4806
|
-
console.log(
|
|
5189
|
+
console.log(chalk8.gray(`Default workspace: ${config.defaultWorkspaceSlug}`));
|
|
4807
5190
|
}
|
|
4808
5191
|
}
|
|
4809
5192
|
} catch (error) {
|
|
@@ -4816,10 +5199,10 @@ function createWorkspacesCommand() {
|
|
|
4816
5199
|
const workspaces2 = await client.workspaces.list();
|
|
4817
5200
|
const workspace = workspaces2.find((w) => w.slug === slug);
|
|
4818
5201
|
if (!workspace) {
|
|
4819
|
-
console.error(
|
|
4820
|
-
console.log(
|
|
5202
|
+
console.error(chalk8.red(`Workspace with slug "${slug}" not found.`));
|
|
5203
|
+
console.log(chalk8.gray("Available workspaces:"));
|
|
4821
5204
|
workspaces2.forEach((w) => {
|
|
4822
|
-
console.log(
|
|
5205
|
+
console.log(chalk8.gray(` - ${w.slug} (${w.name})`));
|
|
4823
5206
|
});
|
|
4824
5207
|
process.exit(1);
|
|
4825
5208
|
}
|
|
@@ -4827,7 +5210,7 @@ function createWorkspacesCommand() {
|
|
|
4827
5210
|
defaultWorkspaceId: workspace.id,
|
|
4828
5211
|
defaultWorkspaceSlug: workspace.slug
|
|
4829
5212
|
});
|
|
4830
|
-
console.log(
|
|
5213
|
+
console.log(chalk8.green(`Default workspace set to: ${workspace.name} (${workspace.slug})`));
|
|
4831
5214
|
} catch (error) {
|
|
4832
5215
|
handleError(error);
|
|
4833
5216
|
}
|
|
@@ -4855,20 +5238,20 @@ function createWorkspacesCommand() {
|
|
|
4855
5238
|
return;
|
|
4856
5239
|
}
|
|
4857
5240
|
if (members.length === 0) {
|
|
4858
|
-
console.log(
|
|
5241
|
+
console.log(chalk8.gray("No members found."));
|
|
4859
5242
|
return;
|
|
4860
5243
|
}
|
|
4861
|
-
console.log(
|
|
5244
|
+
console.log(chalk8.bold(`
|
|
4862
5245
|
Members (${members.length})
|
|
4863
5246
|
`));
|
|
4864
5247
|
for (const m of members) {
|
|
4865
5248
|
const label = m.name ?? m.email ?? m.id;
|
|
4866
|
-
const via = m.source === "team" ?
|
|
5249
|
+
const via = m.source === "team" ? chalk8.gray(
|
|
4867
5250
|
` via team${m.teams.length ? `: ${m.teams.map((t) => t.name).join(", ")}` : ""}` + (m.teamRole ? ` [team ${m.teamRole}]` : "")
|
|
4868
5251
|
) : "";
|
|
4869
|
-
console.log(`${
|
|
4870
|
-
if (m.email) console.log(
|
|
4871
|
-
console.log(
|
|
5252
|
+
console.log(`${chalk8.bold(label)} ${chalk8.gray(`(${m.role})`)}${via}`);
|
|
5253
|
+
if (m.email) console.log(chalk8.gray(` ${m.email}`));
|
|
5254
|
+
console.log(chalk8.gray(` mention: ${m.mentionSyntax}`));
|
|
4872
5255
|
console.log();
|
|
4873
5256
|
}
|
|
4874
5257
|
} catch (error) {
|
|
@@ -4880,7 +5263,7 @@ Members (${members.length})
|
|
|
4880
5263
|
}
|
|
4881
5264
|
|
|
4882
5265
|
// src/commands/goals.ts
|
|
4883
|
-
import { Command as
|
|
5266
|
+
import { Command as Command22 } from "commander";
|
|
4884
5267
|
var GOAL_STATUSES = [
|
|
4885
5268
|
"planned",
|
|
4886
5269
|
"active",
|
|
@@ -4992,7 +5375,7 @@ function validateKeyResultUnit(value) {
|
|
|
4992
5375
|
return value;
|
|
4993
5376
|
}
|
|
4994
5377
|
function createKeyResultsCommand() {
|
|
4995
|
-
const kr = new
|
|
5378
|
+
const kr = new Command22("kr").description(
|
|
4996
5379
|
"Key results on an objective. Ids are CUIDs; --goal takes the objective's integer id."
|
|
4997
5380
|
);
|
|
4998
5381
|
kr.command("list").description("List key results").option("--goal <id>", "Objective ID (a number)").option("-w, --workspace <slug|id>", "Workspace (workspace-wide: every member's KRs)").option("--period <period>", "Period, e.g. Q3-2026").option("--status <status>", `Filter by status: ${KEY_RESULT_STATUSES.join(", ")}`).option("--mine", "Narrow a workspace list to key results you own").action(
|
|
@@ -5195,7 +5578,7 @@ function createKeyResultsCommand() {
|
|
|
5195
5578
|
return kr;
|
|
5196
5579
|
}
|
|
5197
5580
|
function createGoalCommentsCommand() {
|
|
5198
|
-
const comment = new
|
|
5581
|
+
const comment = new Command22("comment").description(
|
|
5199
5582
|
"Read and post comments on a goal. Mention teammates with --mention."
|
|
5200
5583
|
);
|
|
5201
5584
|
comment.command("list").description("List comments on a goal").requiredOption("--goal <id>", "Goal ID (a number)").action(async (options, cmd) => {
|
|
@@ -5290,7 +5673,7 @@ function createGoalCommentsCommand() {
|
|
|
5290
5673
|
return comment;
|
|
5291
5674
|
}
|
|
5292
5675
|
function createGoalsCommand() {
|
|
5293
|
-
const goals = new
|
|
5676
|
+
const goals = new Command22("goals").description(
|
|
5294
5677
|
"Manage goals (objectives) and their key results. Objectives have integer ids; key results are CUIDs."
|
|
5295
5678
|
);
|
|
5296
5679
|
goals.command("list").description(
|
|
@@ -5556,7 +5939,7 @@ Re-run with --with-key-results to go ahead, or move them with \`goals kr update
|
|
|
5556
5939
|
return goals;
|
|
5557
5940
|
}
|
|
5558
5941
|
function createOkrsCommand() {
|
|
5559
|
-
const okrs = new
|
|
5942
|
+
const okrs = new Command22("okrs").description(
|
|
5560
5943
|
"OKRs \u2014 objectives with their key results nested. Manage the parts with `goals` and `goals kr`."
|
|
5561
5944
|
);
|
|
5562
5945
|
okrs.command("list").description(
|
|
@@ -5640,7 +6023,7 @@ import { fileURLToPath } from "url";
|
|
|
5640
6023
|
var PKG_VERSION = JSON.parse(
|
|
5641
6024
|
readFileSync2(join(dirname(fileURLToPath(import.meta.url)), "..", "package.json"), "utf-8")
|
|
5642
6025
|
).version;
|
|
5643
|
-
var program = new
|
|
6026
|
+
var program = new Command23();
|
|
5644
6027
|
program.name("exponential").description(
|
|
5645
6028
|
[
|
|
5646
6029
|
"CLI to interact with Exponential productivity app.",
|
|
@@ -5657,6 +6040,7 @@ program.addCommand(createDealsCommand());
|
|
|
5657
6040
|
program.addCommand(createEpicsCommand());
|
|
5658
6041
|
program.addCommand(createFeaturesCommand());
|
|
5659
6042
|
program.addCommand(createLabelsCommand());
|
|
6043
|
+
program.addCommand(createMeetingsCommand());
|
|
5660
6044
|
program.addCommand(createOrganizationsCommand());
|
|
5661
6045
|
program.addCommand(createPagesCommand());
|
|
5662
6046
|
program.addCommand(createProductsCommand());
|