poe-code 4.0.49 → 4.0.50

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/index.js CHANGED
@@ -76430,7 +76430,7 @@ function toPlanKind(value, filePath) {
76430
76430
  }
76431
76431
  throw new Error(`${filePath}: unsupported frontmatter kind ${JSON.stringify(value)}`);
76432
76432
  }
76433
- function classifyPlanKind(content, filePath) {
76433
+ function classifyPlanKind(content, filePath, archived = false) {
76434
76434
  if (isYamlPlanFile(filePath)) {
76435
76435
  parsePlan(content);
76436
76436
  return "pipeline";
@@ -76439,13 +76439,24 @@ function classifyPlanKind(content, filePath) {
76439
76439
  if (data === void 0) {
76440
76440
  return "plan";
76441
76441
  }
76442
- return data.kind === void 0 ? "plan" : toPlanKind(data.kind, filePath);
76442
+ if (data.kind === void 0) return "plan";
76443
+ if (archived && data.kind === "archived-pipeline-plan") return "plan";
76444
+ if (archived) {
76445
+ try {
76446
+ return toPlanKind(data.kind, filePath);
76447
+ } catch {
76448
+ return "plan";
76449
+ }
76450
+ }
76451
+ return toPlanKind(data.kind, filePath);
76443
76452
  }
76444
76453
  function readPlanReadiness(content, filePath) {
76445
76454
  const value = splitFrontmatter2(content, filePath).data?.readiness;
76446
76455
  if (value === void 0 || value === "draft") return "draft";
76447
76456
  if (value === "ready") return value;
76448
- throw new Error(`${filePath}: invalid readiness ${JSON.stringify(value)}; expected "draft" or "ready"`);
76457
+ throw new Error(
76458
+ `${filePath}: invalid readiness ${JSON.stringify(value)}; expected "draft" or "ready"`
76459
+ );
76449
76460
  }
76450
76461
  async function discoverSharedPlans(options) {
76451
76462
  const displayDir = await resolveSharedPlanDirectory(options);
@@ -76462,6 +76473,14 @@ async function discoverSharedPlans(options) {
76462
76473
  if (canonicalDir !== path89.resolve(absoluteDir)) {
76463
76474
  throw new Error(`Plan directory must not be a symbolic link: ${displayDir}`);
76464
76475
  }
76476
+ if (options.archived === true) {
76477
+ return discoverPlanDirectoryEntries({
76478
+ ...options,
76479
+ absoluteDir: path89.join(absoluteDir, "archive"),
76480
+ displayDir: path89.join(displayDir, "archive"),
76481
+ savedForLaterDirectory: false
76482
+ });
76483
+ }
76465
76484
  const activePlans = await discoverPlanDirectoryEntries({
76466
76485
  ...options,
76467
76486
  absoluteDir,
@@ -76502,7 +76521,9 @@ async function discoverPlanDirectoryEntries(options) {
76502
76521
  continue;
76503
76522
  }
76504
76523
  if (canonicalPath !== path89.resolve(absolutePath)) {
76505
- throw new Error(`Plan file must not be a symbolic link: ${path89.join(options.displayDir, name)}`);
76524
+ throw new Error(
76525
+ `Plan file must not be a symbolic link: ${path89.join(options.displayDir, name)}`
76526
+ );
76506
76527
  }
76507
76528
  const stat36 = await options.fs.stat(absolutePath).catch((error3) => {
76508
76529
  if (isNotFound4(error3)) {
@@ -76518,18 +76539,31 @@ async function discoverPlanDirectoryEntries(options) {
76518
76539
  }
76519
76540
  const displayPath = path89.join(options.displayDir, name);
76520
76541
  const content = await options.fs.readFile(absolutePath, "utf8");
76521
- const kind = classifyPlanKind(content, displayPath);
76542
+ let kind = classifyPlanKind(content, displayPath, options.archived);
76543
+ const savedForLater = options.savedForLaterDirectory ? readSavedForLaterMetadata(content, displayPath) ?? {} : readSavedForLaterMetadata(content, displayPath);
76544
+ let metadata;
76545
+ try {
76546
+ metadata = await readPlanMetadata({
76547
+ kind,
76548
+ absolutePath,
76549
+ path: displayPath,
76550
+ fs: options.fs,
76551
+ content
76552
+ });
76553
+ } catch (error3) {
76554
+ if (!options.archived || kind === "plan") throw error3;
76555
+ kind = "plan";
76556
+ metadata = await readPlanMetadata({
76557
+ kind,
76558
+ absolutePath,
76559
+ path: displayPath,
76560
+ fs: options.fs,
76561
+ content
76562
+ });
76563
+ }
76522
76564
  if (options.kind && kind !== options.kind) {
76523
76565
  continue;
76524
76566
  }
76525
- const savedForLater = options.savedForLaterDirectory ? readSavedForLaterMetadata(content, displayPath) ?? {} : readSavedForLaterMetadata(content, displayPath);
76526
- const metadata = await readPlanMetadata({
76527
- kind,
76528
- absolutePath,
76529
- path: displayPath,
76530
- fs: options.fs,
76531
- content
76532
- });
76533
76567
  plans.push({
76534
76568
  path: displayPath,
76535
76569
  absolutePath,
@@ -76668,6 +76702,25 @@ async function archiveSelectedPlan(entry, fs31) {
76668
76702
  }
76669
76703
  return archivedPath;
76670
76704
  }
76705
+ async function unarchivePlan(entry, fs31) {
76706
+ rejectPlanMetaDocument(entry.absolutePath, "unarchive");
76707
+ const archiveDir = path90.dirname(entry.absolutePath);
76708
+ if (path90.basename(archiveDir) !== "archive") {
76709
+ throw new Error(`Plan is not archived: ${entry.absolutePath}`);
76710
+ }
76711
+ await rejectSymbolicLink2(archiveDir, fs31, "unarchive plan through");
76712
+ const destinationPath = path90.join(path90.dirname(archiveDir), path90.basename(entry.absolutePath));
76713
+ try {
76714
+ await fs31.readFile(destinationPath, "utf8");
76715
+ throw new Error(`Unarchive destination already exists: ${destinationPath}`);
76716
+ } catch (error3) {
76717
+ if (!hasErrorCode3(error3, "ENOENT")) {
76718
+ throw error3;
76719
+ }
76720
+ }
76721
+ await fs31.rename(entry.absolutePath, destinationPath);
76722
+ return destinationPath;
76723
+ }
76671
76724
  async function savePlanForLater(entry, fs31, options = {}) {
76672
76725
  const reason = entry.savedForLater?.reason?.trim() || options.reason?.trim();
76673
76726
  if (!reason) {
@@ -76813,14 +76866,14 @@ function buildPlanExplorerConfig(options) {
76813
76866
  const loadDetailMarkdown = options.loadDetailMarkdown ?? loadPlanPreviewMarkdown;
76814
76867
  const promptSaveReason = options.promptSaveReason;
76815
76868
  let plans = options.plans;
76816
- let rows = toRows(plans);
76869
+ let rows = toRows(plans, options.archived);
76817
76870
  let entryByRowId = toEntryMap(plans);
76818
76871
  let preserveOrderOnNextRefresh = false;
76819
76872
  async function refresh() {
76820
76873
  const refreshedPlans = await options.onRefresh();
76821
76874
  plans = preserveOrderOnNextRefresh ? preservePlanOrder(plans, refreshedPlans) : refreshedPlans;
76822
76875
  preserveOrderOnNextRefresh = false;
76823
- rows = toRows(plans);
76876
+ rows = toRows(plans, options.archived);
76824
76877
  entryByRowId = toEntryMap(plans);
76825
76878
  }
76826
76879
  const actions = [
@@ -76953,43 +77006,45 @@ function buildPlanExplorerConfig(options) {
76953
77006
  }
76954
77007
  ],
76955
77008
  refresh,
76956
- actions,
76957
- reorder: {
76958
- onReorder: async (orderedIds, ctx) => {
76959
- if (ctx === void 0) {
76960
- throw new Error("Plan reorder context is required");
76961
- }
76962
- const orderedEntries = orderedIds.map((id) => getEntry(entryByRowId, id));
76963
- const movedIndex = orderedIds.indexOf(ctx.movedId);
76964
- const originalIndex = createRowIds(plans).indexOf(ctx.movedId);
76965
- if (movedIndex < 0 || originalIndex < 0) {
76966
- throw new Error(`Plan row is no longer available: ${ctx.movedId}`);
76967
- }
76968
- const moved = orderedEntries[movedIndex];
76969
- const swapTarget = orderedEntries[originalIndex];
76970
- if (swapTarget === void 0 || swapTarget.readiness !== moved.readiness) {
76971
- throw new Error("Plans can only be reordered within the same readiness group");
76972
- }
76973
- if (isSavedForLaterEntry(swapTarget) !== isSavedForLaterEntry(moved)) {
76974
- throw new Error("Active and saved-for-later plans cannot be reordered together");
76975
- }
76976
- const previousCandidate = orderedEntries[movedIndex - 1];
76977
- const nextCandidate = orderedEntries[movedIndex + 1];
76978
- const previous = sameOrderingGroup(previousCandidate, moved) ? previousCandidate : void 0;
76979
- const next = sameOrderingGroup(nextCandidate, moved) ? nextCandidate : void 0;
76980
- const [movedStat, previousStat, nextStat] = await Promise.all([
76981
- options.fs.stat(moved.absolutePath),
76982
- previous === void 0 ? void 0 : options.fs.stat(previous.absolutePath),
76983
- next === void 0 ? void 0 : options.fs.stat(next.absolutePath)
76984
- ]);
76985
- const updatedAt = resolveMovedTimestamp(previousStat?.mtimeMs, nextStat?.mtimeMs);
76986
- await options.fs.utimes(
76987
- moved.absolutePath,
76988
- new Date(movedStat.atimeMs ?? movedStat.mtimeMs),
76989
- new Date(updatedAt)
76990
- );
76991
- await ctx.refresh();
76992
- ctx.toast(`Reordered ${path91.basename(moved.path)}`, "info");
77009
+ actions: options.archived ? actions.filter((action) => action.id === "edit" || action.id === "delete") : actions,
77010
+ ...options.archived ? {} : {
77011
+ reorder: {
77012
+ onReorder: async (orderedIds, ctx) => {
77013
+ if (ctx === void 0) {
77014
+ throw new Error("Plan reorder context is required");
77015
+ }
77016
+ const orderedEntries = orderedIds.map((id) => getEntry(entryByRowId, id));
77017
+ const movedIndex = orderedIds.indexOf(ctx.movedId);
77018
+ const originalIndex = createRowIds(plans).indexOf(ctx.movedId);
77019
+ if (movedIndex < 0 || originalIndex < 0) {
77020
+ throw new Error(`Plan row is no longer available: ${ctx.movedId}`);
77021
+ }
77022
+ const moved = orderedEntries[movedIndex];
77023
+ const swapTarget = orderedEntries[originalIndex];
77024
+ if (swapTarget === void 0 || swapTarget.readiness !== moved.readiness) {
77025
+ throw new Error("Plans can only be reordered within the same readiness group");
77026
+ }
77027
+ if (isSavedForLaterEntry(swapTarget) !== isSavedForLaterEntry(moved)) {
77028
+ throw new Error("Active and saved-for-later plans cannot be reordered together");
77029
+ }
77030
+ const previousCandidate = orderedEntries[movedIndex - 1];
77031
+ const nextCandidate = orderedEntries[movedIndex + 1];
77032
+ const previous = sameOrderingGroup(previousCandidate, moved) ? previousCandidate : void 0;
77033
+ const next = sameOrderingGroup(nextCandidate, moved) ? nextCandidate : void 0;
77034
+ const [movedStat, previousStat, nextStat] = await Promise.all([
77035
+ options.fs.stat(moved.absolutePath),
77036
+ previous === void 0 ? void 0 : options.fs.stat(previous.absolutePath),
77037
+ next === void 0 ? void 0 : options.fs.stat(next.absolutePath)
77038
+ ]);
77039
+ const updatedAt = resolveMovedTimestamp(previousStat?.mtimeMs, nextStat?.mtimeMs);
77040
+ await options.fs.utimes(
77041
+ moved.absolutePath,
77042
+ new Date(movedStat.atimeMs ?? movedStat.mtimeMs),
77043
+ new Date(updatedAt)
77044
+ );
77045
+ await ctx.refresh();
77046
+ ctx.toast(`Reordered ${path91.basename(moved.path)}`, "info");
77047
+ }
76993
77048
  }
76994
77049
  },
76995
77050
  multiSelect: false,
@@ -77034,14 +77089,14 @@ function abbreviateHome(filePath, homeDir) {
77034
77089
  }
77035
77090
  return `~${path91.sep}${relative8}`;
77036
77091
  }
77037
- function toRows(plans) {
77092
+ function toRows(plans, archived = false) {
77038
77093
  const rowIds = createRowIds(plans);
77039
77094
  return plans.map((entry, index) => ({
77040
77095
  id: rowIds[index],
77041
77096
  title: formatPlanReadinessLabel(path91.basename(entry.path), entry.readiness),
77042
77097
  subtitle: formatSubtitle(entry),
77043
77098
  badge: { text: entry.typeLabel },
77044
- group: isSavedForLaterEntry(entry) ? "Saved for later" : "Active"
77099
+ group: archived ? "Archived" : isSavedForLaterEntry(entry) ? "Saved for later" : "Active"
77045
77100
  }));
77046
77101
  }
77047
77102
  function formatSubtitle(entry) {
@@ -77109,6 +77164,7 @@ async function runPlanBrowser(options) {
77109
77164
  projectConfigPath: options.projectConfigPath,
77110
77165
  fs: options.fs,
77111
77166
  kind: options.kind,
77167
+ archived: options.archived,
77112
77168
  variables: options.variables
77113
77169
  });
77114
77170
  const plans = await discover();
@@ -77128,6 +77184,7 @@ async function runPlanBrowser(options) {
77128
77184
  }
77129
77185
  const config2 = buildPlanExplorerConfig({
77130
77186
  plans,
77187
+ archived: options.archived,
77131
77188
  fs: options.fs,
77132
77189
  variables: options.variables ?? process.env,
77133
77190
  homeDir: options.homeDir,
@@ -77840,7 +77897,8 @@ function resolvePlanCommandOptions(command) {
77840
77897
  const parentOptions = command.parent?.opts() ?? {};
77841
77898
  return {
77842
77899
  kind: localOptions.kind ?? parentOptions.kind,
77843
- output: localOptions.output ?? parentOptions.output
77900
+ output: localOptions.output ?? parentOptions.output,
77901
+ archived: localOptions.archived ?? parentOptions.archived
77844
77902
  };
77845
77903
  }
77846
77904
  function resolveOutputOption(value) {
@@ -77870,7 +77928,7 @@ function resolveKind(value) {
77870
77928
  }
77871
77929
  throw new ValidationError(`Invalid --kind value "${value}". Expected ${VALID_KINDS.join(", ")}.`);
77872
77930
  }
77873
- function createPlanBrowserOptions(container, kind) {
77931
+ function createPlanBrowserOptions(container, kind, archived = false) {
77874
77932
  return {
77875
77933
  cwd: container.env.cwd,
77876
77934
  homeDir: container.env.homeDir,
@@ -77878,6 +77936,7 @@ function createPlanBrowserOptions(container, kind) {
77878
77936
  projectConfigPath: container.env.projectConfigPath,
77879
77937
  fs: container.fs,
77880
77938
  kind,
77939
+ archived,
77881
77940
  variables: container.env.variables
77882
77941
  };
77883
77942
  }
@@ -77972,7 +78031,7 @@ function formatMarkdownReadSectionOutput(result, format) {
77972
78031
  }
77973
78032
  return result.markdown.trimEnd();
77974
78033
  }
77975
- async function discoverPlans2(container, kind) {
78034
+ async function discoverPlans2(container, kind, archived = false) {
77976
78035
  return discoverAllPlans({
77977
78036
  cwd: container.env.cwd,
77978
78037
  homeDir: container.env.homeDir,
@@ -77980,6 +78039,7 @@ async function discoverPlans2(container, kind) {
77980
78039
  projectConfigPath: container.env.projectConfigPath,
77981
78040
  fs: container.fs,
77982
78041
  kind,
78042
+ archived,
77983
78043
  variables: container.env.variables
77984
78044
  });
77985
78045
  }
@@ -77987,7 +78047,7 @@ async function requirePlanBrowsingPrompt(options) {
77987
78047
  if (!options.assumeYes && process.stdin.isTTY === true) {
77988
78048
  return;
77989
78049
  }
77990
- const plans = await discoverPlans2(options.container, options.kind);
78050
+ const plans = await discoverPlans2(options.container, options.kind, options.archived);
77991
78051
  if (plans.length === 0) {
77992
78052
  return;
77993
78053
  }
@@ -78116,7 +78176,11 @@ async function executePlanAction(options) {
78116
78176
  if (format === "terminal") {
78117
78177
  intro(`plan ${options.action}`);
78118
78178
  }
78119
- const plans = await discoverPlans2(options.container, resolveKind(options.kind));
78179
+ const plans = await discoverPlans2(
78180
+ options.container,
78181
+ resolveKind(options.kind),
78182
+ options.action === "unarchive"
78183
+ );
78120
78184
  const plan = await resolveSelectedPlan({
78121
78185
  container: options.container,
78122
78186
  plans,
@@ -78169,7 +78233,7 @@ async function executePlanAction(options) {
78169
78233
  `plan ${options.action} requires --yes when running without an interactive TTY.`
78170
78234
  );
78171
78235
  const confirmed = await confirmOrCancel({
78172
- message: options.action === "archive" ? `Archive ${path93.basename(plan.path)}?` : `Permanently delete ${path93.basename(plan.path)}?`,
78236
+ message: options.action === "archive" ? `Archive ${path93.basename(plan.path)}?` : options.action === "unarchive" ? `Unarchive ${path93.basename(plan.path)}?` : `Permanently delete ${path93.basename(plan.path)}?`,
78173
78237
  initialValue: false
78174
78238
  });
78175
78239
  if (!confirmed) {
@@ -78187,6 +78251,17 @@ async function executePlanAction(options) {
78187
78251
  );
78188
78252
  return;
78189
78253
  }
78254
+ if (options.action === "unarchive") {
78255
+ const restoredPath = await unarchivePlan(
78256
+ plan,
78257
+ options.container.fs
78258
+ );
78259
+ writeOutput(
78260
+ format,
78261
+ format === "json" ? JSON.stringify({ action: "unarchive", path: plan.path, restoredPath }, null, 2) : `Unarchived ${plan.path}`
78262
+ );
78263
+ return;
78264
+ }
78190
78265
  await deletePlan(plan, options.container.fs);
78191
78266
  writeOutput(
78192
78267
  format,
@@ -78197,7 +78272,7 @@ function registerPlanCommand(program, container) {
78197
78272
  const plan = program.command("plan").alias("plans").description("Browse and manage plans.").usage("[options] [command]").allowExcessArguments().option(
78198
78273
  "--kind <kind>",
78199
78274
  "Filter by plan kind: plan, pipeline, experiment, ralph, superintendent, or superintendent-base"
78200
- ).action(async function() {
78275
+ ).option("--archived", "Browse archived plans instead of active plans").action(async function() {
78201
78276
  if (this.args.length > 0) {
78202
78277
  const candidates = plan.commands.flatMap((command) => [
78203
78278
  command.name(),
@@ -78215,19 +78290,24 @@ function registerPlanCommand(program, container) {
78215
78290
  const opts = this.opts();
78216
78291
  const flags = resolveCommandFlags(program);
78217
78292
  const kind = resolveKind(opts.kind);
78218
- await requirePlanBrowsingPrompt({ container, kind, assumeYes: flags.assumeYes });
78293
+ await requirePlanBrowsingPrompt({
78294
+ container,
78295
+ kind,
78296
+ assumeYes: flags.assumeYes,
78297
+ archived: opts.archived
78298
+ });
78219
78299
  intro("plan");
78220
- await runPlanBrowser(createPlanBrowserOptions(container, kind));
78300
+ await runPlanBrowser(createPlanBrowserOptions(container, kind, opts.archived));
78221
78301
  });
78222
78302
  plan.command("browse").description("Browse plans in the interactive explorer, or render one plan when given a path.").argument("[path]", "Plan path to render instead of opening the explorer").option(
78223
78303
  "--kind <kind>",
78224
78304
  "Filter by plan kind: plan, pipeline, experiment, ralph, superintendent, or superintendent-base"
78225
- ).action(async function(pathArg) {
78305
+ ).option("--archived", "Browse archived plans instead of active plans").action(async function(pathArg) {
78226
78306
  const opts = resolvePlanCommandOptions(this);
78227
78307
  const flags = resolveCommandFlags(program);
78228
78308
  const kind = resolveKind(opts.kind);
78229
78309
  if ((pathArg?.trim() ?? "").length > 0) {
78230
- const plans = await discoverPlans2(container, kind);
78310
+ const plans = await discoverPlans2(container, kind, opts.archived);
78231
78311
  const selected = await resolveSelectedPlan({
78232
78312
  container,
78233
78313
  plans,
@@ -78239,9 +78319,14 @@ function registerPlanCommand(program, container) {
78239
78319
  writeOutput("terminal", renderMarkdown(markdown).trimEnd());
78240
78320
  return;
78241
78321
  }
78242
- await requirePlanBrowsingPrompt({ container, kind, assumeYes: flags.assumeYes });
78322
+ await requirePlanBrowsingPrompt({
78323
+ container,
78324
+ kind,
78325
+ assumeYes: flags.assumeYes,
78326
+ archived: opts.archived
78327
+ });
78243
78328
  intro("plan browser");
78244
- await runPlanBrowser(createPlanBrowserOptions(container, kind));
78329
+ await runPlanBrowser(createPlanBrowserOptions(container, kind, opts.archived));
78245
78330
  });
78246
78331
  plan.command("list").description("List plans across all plan systems.").option(
78247
78332
  "--kind <kind>",
@@ -78365,6 +78450,18 @@ function registerPlanCommand(program, container) {
78365
78450
  ...resolvePlanCommandOptions(this)
78366
78451
  });
78367
78452
  });
78453
+ plan.command("unarchive").description("Move an archived plan back into the active plan directory.").argument("[path]", "Archived plan path").option(
78454
+ "--kind <kind>",
78455
+ "Filter by plan kind: plan, pipeline, experiment, ralph, superintendent, or superintendent-base"
78456
+ ).option("--output <format>", "Output format: terminal, md, or json").action(async function(pathArg) {
78457
+ await executePlanAction({
78458
+ program,
78459
+ container,
78460
+ action: "unarchive",
78461
+ pathArg,
78462
+ ...resolvePlanCommandOptions(this)
78463
+ });
78464
+ });
78368
78465
  plan.command("delete").description("Delete a plan file.").argument("[path]", "Plan path").option(
78369
78466
  "--kind <kind>",
78370
78467
  "Filter by plan kind: plan, pipeline, experiment, ralph, superintendent, or superintendent-base"
@@ -152722,7 +152819,7 @@ var init_package2 = __esm({
152722
152819
  "package.json"() {
152723
152820
  package_default2 = {
152724
152821
  name: "poe-code",
152725
- version: "4.0.49",
152822
+ version: "4.0.50",
152726
152823
  description: "CLI tool to configure Poe API for developer workflows.",
152727
152824
  license: "MIT",
152728
152825
  type: "module",