@outcomeeng/spx 0.1.7 → 0.1.8

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/cli.js CHANGED
@@ -817,6 +817,42 @@ async function resolveSessionConfig(options = {}) {
817
817
  };
818
818
  }
819
819
 
820
+ // src/session/batch.ts
821
+ var BatchError = class extends Error {
822
+ results;
823
+ constructor(results) {
824
+ const failures = results.filter((r) => !r.ok);
825
+ const successes = results.filter((r) => r.ok);
826
+ super(
827
+ `${failures.length} of ${results.length} operations failed. ${successes.length} succeeded.`
828
+ );
829
+ this.name = "BatchError";
830
+ this.results = results;
831
+ }
832
+ };
833
+ async function processBatch(ids, handler) {
834
+ const results = [];
835
+ for (const id of ids) {
836
+ try {
837
+ const output2 = await handler(id);
838
+ results.push({ id, ok: true, message: output2 });
839
+ } catch (error) {
840
+ const message = error instanceof Error ? error.message : String(error);
841
+ results.push({ id, ok: false, message });
842
+ }
843
+ }
844
+ const output = results.map((r) => r.ok ? r.message : `Error (${r.id}): ${r.message}`).join("\n\n");
845
+ const hasFailures = results.some((r) => !r.ok);
846
+ if (hasFailures) {
847
+ const err = new BatchError(results);
848
+ err.message = `${err.message}
849
+
850
+ ${output}`;
851
+ throw err;
852
+ }
853
+ return output;
854
+ }
855
+
820
856
  // src/session/errors.ts
821
857
  var SessionError = class extends Error {
822
858
  constructor(message) {
@@ -908,14 +944,17 @@ async function resolveArchivePaths(sessionId, config) {
908
944
  }
909
945
  throw new SessionNotFoundError(sessionId);
910
946
  }
911
- async function archiveCommand(options) {
912
- const { config } = await resolveSessionConfig({ sessionsDir: options.sessionsDir });
913
- const { source, target } = await resolveArchivePaths(options.sessionId, config);
947
+ async function archiveSingle(sessionId, config) {
948
+ const { source, target } = await resolveArchivePaths(sessionId, config);
914
949
  await mkdir(dirname2(target), { recursive: true });
915
950
  await rename(source, target);
916
- return `Archived session: ${options.sessionId}
951
+ return `Archived session: ${sessionId}
917
952
  Archive location: ${target}`;
918
953
  }
954
+ async function archiveCommand(options) {
955
+ const { config } = await resolveSessionConfig({ sessionsDir: options.sessionsDir });
956
+ return processBatch(options.sessionIds, (id) => archiveSingle(id, config));
957
+ }
919
958
 
920
959
  // src/commands/session/delete.ts
921
960
  import { stat as stat2, unlink } from "fs/promises";
@@ -1108,13 +1147,16 @@ async function findExistingPaths(paths) {
1108
1147
  }
1109
1148
  return existing;
1110
1149
  }
1111
- async function deleteCommand(options) {
1112
- const { config } = await resolveSessionConfig({ sessionsDir: options.sessionsDir });
1113
- const paths = resolveSessionPaths(options.sessionId, config);
1150
+ async function deleteSingle(sessionId, config) {
1151
+ const paths = resolveSessionPaths(sessionId, config);
1114
1152
  const existingPaths = await findExistingPaths(paths);
1115
- const pathToDelete = resolveDeletePath(options.sessionId, existingPaths);
1153
+ const pathToDelete = resolveDeletePath(sessionId, existingPaths);
1116
1154
  await unlink(pathToDelete);
1117
- return `Deleted session: ${options.sessionId}`;
1155
+ return `Deleted session: ${sessionId}`;
1156
+ }
1157
+ async function deleteCommand(options) {
1158
+ const { config } = await resolveSessionConfig({ sessionsDir: options.sessionsDir });
1159
+ return processBatch(options.sessionIds, (id) => deleteSingle(id, config));
1118
1160
  }
1119
1161
 
1120
1162
  // src/commands/session/handoff.ts
@@ -1511,16 +1553,19 @@ async function findExistingPath(paths, _config) {
1511
1553
  }
1512
1554
  return null;
1513
1555
  }
1514
- async function showCommand(options) {
1515
- const { config } = await resolveSessionConfig({ sessionsDir: options.sessionsDir });
1516
- const paths = resolveSessionPaths(options.sessionId, config);
1556
+ async function showSingle(sessionId, config) {
1557
+ const paths = resolveSessionPaths(sessionId, config);
1517
1558
  const found = await findExistingPath(paths, config);
1518
1559
  if (!found) {
1519
- throw new SessionNotFoundError(options.sessionId);
1560
+ throw new SessionNotFoundError(sessionId);
1520
1561
  }
1521
1562
  const content = await readFile4(found.path, "utf-8");
1522
1563
  return formatShowOutput(content, { status: found.status });
1523
1564
  }
1565
+ async function showCommand(options) {
1566
+ const { config } = await resolveSessionConfig({ sessionsDir: options.sessionsDir });
1567
+ return processBatch(options.sessionIds, (id) => showSingle(id, config));
1568
+ }
1524
1569
 
1525
1570
  // src/domains/session/help.ts
1526
1571
  var SESSION_FORMAT_HELP = `
@@ -1539,7 +1584,8 @@ Workflow:
1539
1584
  1. handoff - Create session (todo)
1540
1585
  2. pickup - Claim session (todo -> doing)
1541
1586
  3. release - Return session (doing -> todo)
1542
- 4. delete - Remove session
1587
+ 4. archive - Move session to archive
1588
+ 5. delete - Remove session permanently
1543
1589
  `;
1544
1590
  var HANDOFF_FRONTMATTER_HELP = `
1545
1591
  Usage:
@@ -1627,10 +1673,10 @@ function registerSessionCommands(sessionCmd) {
1627
1673
  handleError(error);
1628
1674
  }
1629
1675
  });
1630
- sessionCmd.command("show <id>").description("Show session content").option("--sessions-dir <path>", "Custom sessions directory").action(async (id, options) => {
1676
+ sessionCmd.command("show <id...>").description("Show session content").option("--sessions-dir <path>", "Custom sessions directory").action(async (ids, options) => {
1631
1677
  try {
1632
1678
  const output = await showCommand({
1633
- sessionId: id,
1679
+ sessionIds: ids,
1634
1680
  sessionsDir: options.sessionsDir
1635
1681
  });
1636
1682
  console.log(output);
@@ -1677,10 +1723,10 @@ function registerSessionCommands(sessionCmd) {
1677
1723
  handleError(error);
1678
1724
  }
1679
1725
  });
1680
- sessionCmd.command("delete <id>").description("Delete a session").option("--sessions-dir <path>", "Custom sessions directory").action(async (id, options) => {
1726
+ sessionCmd.command("delete <id...>").description("Delete one or more sessions").option("--sessions-dir <path>", "Custom sessions directory").action(async (ids, options) => {
1681
1727
  try {
1682
1728
  const output = await deleteCommand({
1683
- sessionId: id,
1729
+ sessionIds: ids,
1684
1730
  sessionsDir: options.sessionsDir
1685
1731
  });
1686
1732
  console.log(output);
@@ -1705,10 +1751,10 @@ function registerSessionCommands(sessionCmd) {
1705
1751
  handleError(error);
1706
1752
  }
1707
1753
  });
1708
- sessionCmd.command("archive <id>").description("Move a session to the archive directory").option("--sessions-dir <path>", "Custom sessions directory").action(async (id, options) => {
1754
+ sessionCmd.command("archive <id...>").description("Move one or more sessions to the archive directory").option("--sessions-dir <path>", "Custom sessions directory").action(async (ids, options) => {
1709
1755
  try {
1710
1756
  const output = await archiveCommand({
1711
- sessionId: id,
1757
+ sessionIds: ids,
1712
1758
  sessionsDir: options.sessionsDir
1713
1759
  });
1714
1760
  console.log(output);