@hasna/loops 0.3.29 → 0.3.30

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/index.js CHANGED
@@ -5253,7 +5253,7 @@ function buildScriptInventoryReport(store, opts = {}) {
5253
5253
  // package.json
5254
5254
  var package_default = {
5255
5255
  name: "@hasna/loops",
5256
- version: "0.3.29",
5256
+ version: "0.3.30",
5257
5257
  description: "Persistent local loop and workflow runner for deterministic commands and headless AI coding agents",
5258
5258
  type: "module",
5259
5259
  main: "dist/index.js",
@@ -6636,6 +6636,10 @@ function routeThrottleDryRunPreview(args) {
6636
6636
  limits: args.limits
6637
6637
  };
6638
6638
  }
6639
+ function findLoopByTaskIdempotency(store, idempotencyKey) {
6640
+ const marker = `idempotency=${idempotencyKey}`;
6641
+ return store.listLoops({ includeArchived: true, limit: 1e5 }).find((loop) => loop.description?.includes(marker));
6642
+ }
6639
6643
  async function readEventEnvelopeFromStdin() {
6640
6644
  const raw = process.env.HASNA_EVENT_JSON || await Bun.stdin.text();
6641
6645
  const event = JSON.parse(raw);
@@ -6687,7 +6691,7 @@ function routeTodosTaskEvent(event, opts) {
6687
6691
  if (!opts.dryRun) {
6688
6692
  const store2 = new Store;
6689
6693
  try {
6690
- const existingLoop = store2.findLoopByName(loopName) ?? store2.findLoopByName(legacyLoopName);
6694
+ const existingLoop = store2.findLoopByName(loopName) ?? store2.findLoopByName(legacyLoopName) ?? findLoopByTaskIdempotency(store2, idempotencyKey);
6691
6695
  if (existingLoop) {
6692
6696
  const existingWorkflow = existingLoop.target.type === "workflow" ? store2.getWorkflow(existingLoop.target.workflowId) : undefined;
6693
6697
  return {
@@ -6775,7 +6779,7 @@ function routeTodosTaskEvent(event, opts) {
6775
6779
  event: event.id
6776
6780
  }, {}) : undefined;
6777
6781
  const outcome = store.writeTransaction(() => {
6778
- const existingLoop = store.findLoopByName(loopName) ?? store.findLoopByName(legacyLoopName);
6782
+ const existingLoop = store.findLoopByName(loopName) ?? store.findLoopByName(legacyLoopName) ?? findLoopByTaskIdempotency(store, idempotencyKey);
6779
6783
  if (existingLoop) {
6780
6784
  const existingWorkflow2 = existingLoop.target.type === "workflow" ? store.getWorkflow(existingLoop.target.workflowId) : undefined;
6781
6785
  return { kind: "deduped", existingLoop, existingWorkflow: existingWorkflow2 };
@@ -4574,7 +4574,7 @@ function enableStartup(result) {
4574
4574
  // package.json
4575
4575
  var package_default = {
4576
4576
  name: "@hasna/loops",
4577
- version: "0.3.29",
4577
+ version: "0.3.30",
4578
4578
  description: "Persistent local loop and workflow runner for deterministic commands and headless AI coding agents",
4579
4579
  type: "module",
4580
4580
  main: "dist/index.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/loops",
3
- "version": "0.3.29",
3
+ "version": "0.3.30",
4
4
  "description": "Persistent local loop and workflow runner for deterministic commands and headless AI coding agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",