@go-to-k/cdkd 0.228.0 → 0.229.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 CHANGED
@@ -589,14 +589,17 @@ cdkd events MyStack # list runs, newest first
589
589
  cdkd events MyStack --run <runId> # one run's full event stream
590
590
  cdkd events MyStack --format json # machine-readable (AI-agent hand-off)
591
591
  cdkd events prune MyStack --all # purge event history (reclaim S3 space)
592
+ cdkd destroy MyStack --purge-events # destroy + purge events in one command
592
593
  ```
593
594
 
594
595
  Events are persisted as JSONL under a `deployments/` key family separate
595
596
  from `state.json` (no state schema bump), so a destroyed stack's failure
596
597
  history stays readable. Recording is best-effort and never blocks the
597
598
  run; events carry error + metadata only (never resource properties). The
598
- store self-bounds to the last 20 runs, and `cdkd events prune` purges old
599
- history on demand (`--keep N` / `--older-than <dur>` / `--all`). See
599
+ store self-bounds to the last 20 runs, `cdkd events prune` purges old
600
+ history on demand (`--keep N` / `--older-than <dur>` / `--all`), and
601
+ `cdkd destroy --purge-events` deletes a stack's history right after a clean
602
+ destroy so the bucket returns fully empty. See
600
603
  **[docs/deployment-events.md](docs/deployment-events.md)** for the full
601
604
  reference.
602
605
 
package/dist/cli.js CHANGED
@@ -1556,7 +1556,7 @@ const FLUSH_INTERVAL_MS = 2e3;
1556
1556
  const FLUSH_EVENT_THRESHOLD = 50;
1557
1557
  /** Build-time cdkd version, with a dev fallback for non-built contexts. */
1558
1558
  function getCdkdVersion() {
1559
- return "0.228.0";
1559
+ return "0.229.0";
1560
1560
  }
1561
1561
  /**
1562
1562
  * Generate a time-sortable unique run id, e.g.
@@ -39418,6 +39418,37 @@ function orderConsumersBeforeProducers(stackNames, consumerToProducers) {
39418
39418
  return ordered;
39419
39419
  }
39420
39420
  /**
39421
+ * Issue [#885] — apply `cdkd destroy --purge-events` for one stack.
39422
+ *
39423
+ * Purges the stack's deployment-event history (the post-mortem `deployments/`
39424
+ * store cdkd keeps by default) ONLY after a clean, non-interrupted destroy, so
39425
+ * the state bucket returns fully empty. Deliberately skipped on a failed /
39426
+ * interrupted destroy — those events ARE the post-mortem the user wants on the
39427
+ * retry — and a no-op when `--purge-events` was not passed.
39428
+ *
39429
+ * MUST be called AFTER the run's `eventRecorder.finalize()` (which writes this
39430
+ * run's own events + index): purging first would just be re-created by the
39431
+ * finalize. Best-effort — a purge failure warns but never fails the
39432
+ * already-successful destroy (the resources are gone regardless). The
39433
+ * equivalent for an already-destroyed stack is `cdkd events prune <stack> --all`.
39434
+ *
39435
+ * Returns the prune result when a purge ran, or `null` when it was skipped
39436
+ * (flag off / failed / interrupted) or the purge itself errored. Extracted
39437
+ * from the destroy loop so the gating is unit-testable without the full
39438
+ * synth / AWS-client harness.
39439
+ */
39440
+ async function purgeEventsAfterDestroy(reader, stackName, region, opts, logger) {
39441
+ if (opts.purgeEvents !== true || opts.runResult !== "SUCCEEDED" || opts.interrupted) return null;
39442
+ try {
39443
+ const purge = await reader.pruneRuns(stackName, region, { all: true });
39444
+ if (purge.deletedRunIds.length > 0 || purge.indexDeleted) logger.info(` Purged deployment-event history for ${stackName} (${region}).`);
39445
+ return purge;
39446
+ } catch (purgeError) {
39447
+ logger.warn(` Failed to purge deployment-event history for ${stackName}: ${purgeError instanceof Error ? purgeError.message : String(purgeError)}`);
39448
+ return null;
39449
+ }
39450
+ }
39451
+ /**
39421
39452
  * Destroy command implementation
39422
39453
  */
39423
39454
  async function destroyCommand(stackArgs, options) {
@@ -39645,6 +39676,11 @@ async function destroyCommand(stackArgs, options) {
39645
39676
  } finally {
39646
39677
  await eventRecorder.finalize(destroyRunResult);
39647
39678
  }
39679
+ await purgeEventsAfterDestroy(new DeploymentEventsReader(stateBackend), stackName, stackTargetRegion, {
39680
+ purgeEvents: options.purgeEvents,
39681
+ runResult: destroyRunResult,
39682
+ interrupted
39683
+ }, logger);
39648
39684
  if (interrupted) break;
39649
39685
  }
39650
39686
  if (totalErrors > 0) throw new PartialFailureError(`Destroy completed with ${totalErrors} resource error(s). State preserved — inspect 'cdkd state show <stack>' and re-run 'cdkd destroy' to retry.`);
@@ -39657,7 +39693,7 @@ async function destroyCommand(stackArgs, options) {
39657
39693
  * Create destroy command
39658
39694
  */
39659
39695
  function createDestroyCommand() {
39660
- const cmd = new Command("destroy").description("Destroy all resources in the stack").argument("[stacks...]", "Stack name(s) to destroy. Accepts physical CloudFormation names (e.g. 'MyStage-Api') or CDK display paths (e.g. 'MyStage/Api'). Supports wildcards (e.g. 'MyStage/*').").option("--all", "Destroy all stacks", false).action(withErrorHandling(destroyCommand));
39696
+ const cmd = new Command("destroy").description("Destroy all resources in the stack").argument("[stacks...]", "Stack name(s) to destroy. Accepts physical CloudFormation names (e.g. 'MyStage-Api') or CDK display paths (e.g. 'MyStage/Api'). Supports wildcards (e.g. 'MyStage/*').").option("--all", "Destroy all stacks", false).option("--purge-events", "After a clean destroy, also delete the stack's deployment-event history (issue #808 store) so the state bucket returns fully empty. By default events survive destroy as post-mortem context. Skipped when the destroy fails or is interrupted (those events aid the retry). Equivalent for an already-destroyed stack: 'cdkd events prune <stack> --all'.", false).action(withErrorHandling(destroyCommand));
39661
39697
  [
39662
39698
  ...commonOptions,
39663
39699
  ...appOptions,
@@ -54952,7 +54988,7 @@ function reorderArgs(argv) {
54952
54988
  async function main() {
54953
54989
  installPipeCloseHandler();
54954
54990
  const program = new Command();
54955
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.228.0");
54991
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.229.0");
54956
54992
  program.addCommand(createBootstrapCommand());
54957
54993
  program.addCommand(createSynthCommand());
54958
54994
  program.addCommand(createListCommand());