@khangal.j/fireside-cli 0.0.5 → 0.0.6

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.
Files changed (2) hide show
  1. package/dist/index.js +147 -17
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -708,6 +708,71 @@ function serializeTaskHandoff(taskEntry, taskHandoff) {
708
708
  }
709
709
  };
710
710
  }
711
+ function shortId(id) {
712
+ return id.slice(0, 8);
713
+ }
714
+ function leanAssignees(assignees) {
715
+ return assignees.map(
716
+ (member) => member.username ? `@${member.username}` : member.email
717
+ );
718
+ }
719
+ function serializeTaskRow(taskEntry) {
720
+ const assignees = leanAssignees(taskEntry.task.assignees);
721
+ return {
722
+ id: shortId(taskEntry.task.id),
723
+ title: taskEntry.task.title,
724
+ project: taskEntry.project.title,
725
+ board: taskEntry.board.title,
726
+ column: taskEntry.column.title,
727
+ role: taskEntry.column.role,
728
+ position: taskEntry.task.position,
729
+ ...taskEntry.task.dueDate ? { dueDate: taskEntry.task.dueDate } : {},
730
+ ...assignees.length ? { assignees } : {},
731
+ ...taskEntry.task.description ? { hasDescription: true } : {}
732
+ };
733
+ }
734
+ function serializeAssignedRow(task) {
735
+ const assignees = leanAssignees(task.assignees);
736
+ return {
737
+ id: shortId(task.id),
738
+ title: task.title,
739
+ project: task.projectTitle,
740
+ board: task.boardTitle,
741
+ column: task.columnTitle,
742
+ ...task.dueDate ? { dueDate: task.dueDate } : {},
743
+ ...assignees.length ? { assignees } : {},
744
+ ...task.description ? { hasDescription: true } : {}
745
+ };
746
+ }
747
+ function leanHandoff(handoff) {
748
+ const handle = (user) => user.username ? `@${user.username}` : user.email;
749
+ return {
750
+ id: handoff.id,
751
+ status: handoff.status,
752
+ summary: handoff.summary,
753
+ from: handle(handoff.fromUser),
754
+ to: handle(handoff.toUser),
755
+ next: handle(handoff.nextAssigneeUser),
756
+ contextMarkdown: handoff.contextMarkdown,
757
+ createdAt: handoff.createdAt
758
+ };
759
+ }
760
+ function serializeTaskFull(taskEntry, contextRevision, taskHandoff) {
761
+ return {
762
+ id: taskEntry.task.id,
763
+ title: taskEntry.task.title,
764
+ project: taskEntry.project.title,
765
+ board: taskEntry.board.title,
766
+ column: taskEntry.column.title,
767
+ role: taskEntry.column.role,
768
+ position: taskEntry.task.position,
769
+ dueDate: taskEntry.task.dueDate,
770
+ assignees: leanAssignees(taskEntry.task.assignees),
771
+ description: taskEntry.task.description,
772
+ ...contextRevision !== void 0 ? { contextRevision } : {},
773
+ ...taskHandoff !== void 0 ? { handoff: taskHandoff ? leanHandoff(taskHandoff) : null } : {}
774
+ };
775
+ }
711
776
  function printTaskSummary(taskEntry) {
712
777
  console.log(formatHeading(taskEntry.task.title, taskEntry.task.id));
713
778
  console.log(
@@ -873,13 +938,25 @@ async function loadProjectBoardsResults(baseUrl, accessToken, projectSelector) {
873
938
  );
874
939
  }
875
940
  async function resolveTaskEntry(baseUrl, accessToken, taskId, projectSelector) {
876
- const taskEntries = flattenTaskEntries(
941
+ const allEntries = flattenTaskEntries(
877
942
  await loadProjectBoardsResults(baseUrl, accessToken, projectSelector)
878
- ).filter((taskEntry) => taskEntry.task.id === taskId);
879
- if (!taskEntries.length) {
943
+ );
944
+ const trimmed = taskId.trim();
945
+ let matches = allEntries.filter((taskEntry) => taskEntry.task.id === trimmed);
946
+ if (!matches.length && trimmed.length >= 4) {
947
+ matches = allEntries.filter(
948
+ (taskEntry) => taskEntry.task.id.startsWith(trimmed)
949
+ );
950
+ }
951
+ if (!matches.length) {
880
952
  throw new Error(`Task ${taskId} was not found.`);
881
953
  }
882
- return taskEntries[0];
954
+ if (matches.length > 1) {
955
+ throw new Error(
956
+ `Task id "${taskId}" is ambiguous (${matches.length} matches). Use more characters or the full id.`
957
+ );
958
+ }
959
+ return matches[0];
883
960
  }
884
961
  function parseTargetPosition(value) {
885
962
  if (value === void 0) {
@@ -1015,7 +1092,7 @@ function printAssignedTasks(tasks, projectFilter) {
1015
1092
  }
1016
1093
  }
1017
1094
  var program = new import_commander.Command();
1018
- program.name("fireside").description("Fireside CLI").version("0.0.2").configureOutput({
1095
+ program.name("fireside").description("Fireside CLI").version("0.0.6").configureOutput({
1019
1096
  outputError: (message, write) => write(import_picocolors.default.red(message))
1020
1097
  }).showHelpAfterError();
1021
1098
  addBaseUrlOption(
@@ -1084,7 +1161,7 @@ addBaseUrlOption(
1084
1161
  })
1085
1162
  );
1086
1163
  addBaseUrlOption(
1087
- program.command("my-stuff").description("List tasks currently assigned to you").option("--json", "Print assigned tasks as JSON").option("-p, --project <project>", "Filter by project id or title").action(
1164
+ program.command("my-stuff").description("List tasks currently assigned to you").option("--json", "Print assigned tasks as compact JSON").option("--raw", "With --json, print the full unabridged shape (larger)").option("-p, --project <project>", "Filter by project id or title").action(
1088
1165
  async (options) => {
1089
1166
  const state = await requireAuthState();
1090
1167
  const configState = await loadConfigState();
@@ -1095,7 +1172,11 @@ addBaseUrlOption(
1095
1172
  options.project
1096
1173
  );
1097
1174
  if (options.json) {
1098
- console.log(JSON.stringify(filteredTasks, null, 2));
1175
+ if (options.raw) {
1176
+ console.log(JSON.stringify(filteredTasks, null, 2));
1177
+ } else {
1178
+ console.log(JSON.stringify(filteredTasks.map(serializeAssignedRow)));
1179
+ }
1099
1180
  return;
1100
1181
  }
1101
1182
  printAssignedTasks(filteredTasks, options.project);
@@ -1116,7 +1197,7 @@ addBaseUrlOption(
1116
1197
  );
1117
1198
  var tasksCommand = program.command("tasks").description("Interact with tasks");
1118
1199
  addBaseUrlOption(
1119
- tasksCommand.command("list").description("List accessible tasks").option("--json", "Print tasks as JSON").option("-p, --project <project>", "Filter by project id or title").option("--board <board>", "Filter by board id or title").option("--column <column>", "Filter by column id or title").action(
1200
+ tasksCommand.command("list").description("List accessible tasks").option("--json", "Print tasks as compact JSON").option("--raw", "With --json, print the full unabridged shape (larger)").option("-p, --project <project>", "Filter by project id or title").option("--board <board>", "Filter by board id or title").option("--column <column>", "Filter by column id or title").action(
1120
1201
  async (options) => {
1121
1202
  const { accessToken, baseUrl } = await loadCliContext(options.baseUrl);
1122
1203
  let taskEntries = flattenTaskEntries(
@@ -1133,13 +1214,21 @@ addBaseUrlOption(
1133
1214
  );
1134
1215
  }
1135
1216
  if (options.json) {
1136
- console.log(
1137
- JSON.stringify(
1138
- taskEntries.map((taskEntry) => serializeTaskEntry(taskEntry)),
1139
- null,
1140
- 2
1141
- )
1142
- );
1217
+ if (options.raw) {
1218
+ console.log(
1219
+ JSON.stringify(
1220
+ taskEntries.map((taskEntry) => serializeTaskEntry(taskEntry)),
1221
+ null,
1222
+ 2
1223
+ )
1224
+ );
1225
+ } else {
1226
+ console.log(
1227
+ JSON.stringify(
1228
+ taskEntries.map((taskEntry) => serializeTaskRow(taskEntry))
1229
+ )
1230
+ );
1231
+ }
1143
1232
  return;
1144
1233
  }
1145
1234
  if (!taskEntries.length) {
@@ -1153,7 +1242,48 @@ addBaseUrlOption(
1153
1242
  )
1154
1243
  );
1155
1244
  addBaseUrlOption(
1156
- tasksCommand.command("get <taskId>").description("Show a task by id").option("--json", "Print the task as JSON").option("-p, --project <project>", "Limit lookup to a project id or title").option("--context", "Load the latest saved task context").option("--handoff", "Load the active handoff context").action(
1245
+ tasksCommand.command("columns").description("List a board's columns (id, role, title) without tasks").option("--json", "Print columns as JSON").option("-p, --project <project>", "Filter by project id or title").option("--board <board>", "Board id or title").action(
1246
+ async (options) => {
1247
+ const { accessToken, baseUrl } = await loadCliContext(options.baseUrl);
1248
+ const [projectBoardsResult] = await loadProjectBoardsResults(
1249
+ baseUrl,
1250
+ accessToken,
1251
+ options.project
1252
+ );
1253
+ if (!projectBoardsResult) {
1254
+ printWarning("No project found.");
1255
+ return;
1256
+ }
1257
+ const board = resolveBoard(
1258
+ projectBoardsResult.boardsData.boards,
1259
+ options.board
1260
+ );
1261
+ const columns = [...board.columns].sort(
1262
+ (left, right) => left.position - right.position
1263
+ );
1264
+ if (options.json) {
1265
+ console.log(
1266
+ JSON.stringify(
1267
+ columns.map((column) => ({
1268
+ id: column.id,
1269
+ role: column.role,
1270
+ title: column.title
1271
+ }))
1272
+ )
1273
+ );
1274
+ return;
1275
+ }
1276
+ console.log(
1277
+ formatHeading(`${projectBoardsResult.project.title} / ${board.title}`)
1278
+ );
1279
+ for (const column of columns) {
1280
+ console.log(` ${import_picocolors.default.dim(column.role.padEnd(8))} ${column.title}`);
1281
+ }
1282
+ }
1283
+ )
1284
+ );
1285
+ addBaseUrlOption(
1286
+ tasksCommand.command("get <taskId>").description("Show a task by id (accepts a short id prefix)").option("--json", "Print the task as JSON").option("--raw", "With --json, print the full unabridged shape (larger)").option("-p, --project <project>", "Limit lookup to a project id or title").option("--context", "Load the latest saved task context").option("--handoff", "Load the active handoff context").action(
1157
1287
  async (taskId, options) => {
1158
1288
  const { accessToken, baseUrl } = await loadCliContext(options.baseUrl);
1159
1289
  const taskEntry = await resolveTaskEntry(
@@ -1179,7 +1309,7 @@ addBaseUrlOption(
1179
1309
  if (options.json) {
1180
1310
  console.log(
1181
1311
  JSON.stringify(
1182
- serializeTaskEntry(taskEntry, contextRevision, taskHandoff),
1312
+ options.raw ? serializeTaskEntry(taskEntry, contextRevision, taskHandoff) : serializeTaskFull(taskEntry, contextRevision, taskHandoff),
1183
1313
  null,
1184
1314
  2
1185
1315
  )
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@khangal.j/fireside-cli",
3
- "version": "0.0.5",
3
+ "version": "0.0.6",
4
4
  "description": "Fireside CLI",
5
5
  "license": "MIT",
6
6
  "private": false,