@hasna/loops 0.3.42 → 0.3.43

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
@@ -5716,7 +5716,7 @@ function buildScriptInventoryReport(store, opts = {}) {
5716
5716
  // package.json
5717
5717
  var package_default = {
5718
5718
  name: "@hasna/loops",
5719
- version: "0.3.42",
5719
+ version: "0.3.43",
5720
5720
  description: "Persistent local loop and workflow runner for deterministic commands and headless AI coding agents",
5721
5721
  type: "module",
5722
5722
  main: "dist/index.js",
@@ -7329,6 +7329,31 @@ function generatedRouteSandboxPreflight(workflow) {
7329
7329
  }
7330
7330
  return checks;
7331
7331
  }
7332
+ function generatedRouteWorkflowSignature(workflow) {
7333
+ return JSON.stringify({
7334
+ version: workflow.version ?? 1,
7335
+ goal: workflow.goal ?? null,
7336
+ steps: workflow.steps
7337
+ });
7338
+ }
7339
+ function canReuseGeneratedRouteWorkflow(existing, generated) {
7340
+ if (generatedRouteWorkflowSignature(existing) !== generatedRouteWorkflowSignature(generated))
7341
+ return false;
7342
+ try {
7343
+ generatedRouteSandboxPreflight(existing);
7344
+ return true;
7345
+ } catch {
7346
+ return false;
7347
+ }
7348
+ }
7349
+ function routeWorkflowForStorage(store, workflowBody) {
7350
+ const existingWorkflow = store.findWorkflowByName(workflowBody.name);
7351
+ if (existingWorkflow && canReuseGeneratedRouteWorkflow(existingWorkflow, workflowBody))
7352
+ return existingWorkflow;
7353
+ if (existingWorkflow)
7354
+ store.archiveWorkflow(existingWorkflow.id);
7355
+ return store.createWorkflow(workflowBody);
7356
+ }
7332
7357
  function routeThrottleLimitsFromOpts(opts) {
7333
7358
  return {
7334
7359
  maxActive: positiveInteger(opts.maxActive, "--max-active"),
@@ -7578,8 +7603,7 @@ function routeTodosTaskEvent(event, opts) {
7578
7603
  }
7579
7604
  const store = new Store;
7580
7605
  try {
7581
- const existingWorkflowForPreflight = store.findWorkflowByName(workflowBody.name);
7582
- const workflowPreflightSpec = existingWorkflowForPreflight ?? workflowSpecForPreflight(workflowBody, "event-preflight");
7606
+ const workflowPreflightSpec = workflowSpecForPreflight(workflowBody, "event-preflight");
7583
7607
  generatedRouteSandboxPreflight(workflowPreflightSpec);
7584
7608
  const preflight = opts.preflight ? preflightStoredWorkflow(workflowPreflightSpec, {
7585
7609
  name: workflowBody.name,
@@ -7591,8 +7615,8 @@ function routeTodosTaskEvent(event, opts) {
7591
7615
  const existingItem = store.findWorkflowWorkItem("todos-task", idempotencyKey);
7592
7616
  if (existingItem?.loopId && ["admitted", "running", "succeeded"].includes(existingItem.status)) {
7593
7617
  const existingLoop = store.getLoop(existingItem.loopId);
7594
- const existingWorkflow2 = existingItem.workflowId ? store.getWorkflow(existingItem.workflowId) : undefined;
7595
- return { kind: "deduped", existingItem, existingLoop, existingWorkflow: existingWorkflow2, invocation };
7618
+ const existingWorkflow = existingItem.workflowId ? store.getWorkflow(existingItem.workflowId) : undefined;
7619
+ return { kind: "deduped", existingItem, existingLoop, existingWorkflow, invocation };
7596
7620
  }
7597
7621
  const throttle = hasThrottleLimits(throttleLimits) ? routeThrottleDecision(store, { projectPath: routeProjectPath, projectGroup, limits: throttleLimits }) : undefined;
7598
7622
  const workItem = store.upsertWorkflowWorkItem({
@@ -7603,8 +7627,7 @@ function routeTodosTaskEvent(event, opts) {
7603
7627
  });
7604
7628
  if (throttle && !throttle.allowed)
7605
7629
  return { kind: "throttled", invocation, workItem, throttle };
7606
- const existingWorkflow = store.findWorkflowByName(workflowBody.name);
7607
- const workflow = existingWorkflow ?? store.createWorkflow(workflowBody);
7630
+ const workflow = routeWorkflowForStorage(store, workflowBody);
7608
7631
  const loop = store.createLoop({
7609
7632
  ...loopInput,
7610
7633
  target: {
@@ -7790,8 +7813,7 @@ function routeGenericEvent(event, opts) {
7790
7813
  }
7791
7814
  const store = new Store;
7792
7815
  try {
7793
- const existingWorkflowForPreflight = store.findWorkflowByName(workflowBody.name);
7794
- const workflowPreflightSpec = existingWorkflowForPreflight ?? workflowSpecForPreflight(workflowBody, "event-preflight");
7816
+ const workflowPreflightSpec = workflowSpecForPreflight(workflowBody, "event-preflight");
7795
7817
  generatedRouteSandboxPreflight(workflowPreflightSpec);
7796
7818
  const preflight = opts.preflight ? preflightStoredWorkflow(workflowPreflightSpec, {
7797
7819
  name: workflowBody.name,
@@ -7803,8 +7825,8 @@ function routeGenericEvent(event, opts) {
7803
7825
  const existingItem = store.findWorkflowWorkItem("generic-event", idempotencyKey);
7804
7826
  if (existingItem?.loopId && ["admitted", "running", "succeeded"].includes(existingItem.status)) {
7805
7827
  const existingLoop = store.getLoop(existingItem.loopId);
7806
- const existingWorkflow2 = existingItem.workflowId ? store.getWorkflow(existingItem.workflowId) : undefined;
7807
- return { kind: "deduped", existingItem, existingLoop, existingWorkflow: existingWorkflow2, invocation };
7828
+ const existingWorkflow = existingItem.workflowId ? store.getWorkflow(existingItem.workflowId) : undefined;
7829
+ return { kind: "deduped", existingItem, existingLoop, existingWorkflow, invocation };
7808
7830
  }
7809
7831
  const throttle = hasThrottleLimits(throttleLimits) ? routeThrottleDecision(store, { projectPath: routeProjectPath, projectGroup, limits: throttleLimits }) : undefined;
7810
7832
  const workItem = store.upsertWorkflowWorkItem({
@@ -7815,8 +7837,7 @@ function routeGenericEvent(event, opts) {
7815
7837
  });
7816
7838
  if (throttle && !throttle.allowed)
7817
7839
  return { kind: "throttled", invocation, workItem, throttle };
7818
- const existingWorkflow = store.findWorkflowByName(workflowBody.name);
7819
- const workflow = existingWorkflow ?? store.createWorkflow(workflowBody);
7840
+ const workflow = routeWorkflowForStorage(store, workflowBody);
7820
7841
  const loop = store.createLoop({
7821
7842
  ...loopInput,
7822
7843
  target: {
@@ -8605,8 +8626,7 @@ eventsHandle.command("generic").description("create a one-shot worker/verifier w
8605
8626
  }
8606
8627
  const store = new Store;
8607
8628
  try {
8608
- const existingWorkflowForPreflight = store.findWorkflowByName(workflowBody.name);
8609
- const workflowPreflightSpec = existingWorkflowForPreflight ?? workflowSpecForPreflight(workflowBody, "event-preflight");
8629
+ const workflowPreflightSpec = workflowSpecForPreflight(workflowBody, "event-preflight");
8610
8630
  generatedRouteSandboxPreflight(workflowPreflightSpec);
8611
8631
  const preflight = opts.preflight ? preflightStoredWorkflow(workflowPreflightSpec, {
8612
8632
  name: workflowBody.name,
@@ -8618,8 +8638,8 @@ eventsHandle.command("generic").description("create a one-shot worker/verifier w
8618
8638
  const existingItem = store.findWorkflowWorkItem("generic-event", idempotencyKey);
8619
8639
  if (existingItem?.loopId && ["admitted", "running", "succeeded"].includes(existingItem.status)) {
8620
8640
  const existingLoop = store.getLoop(existingItem.loopId);
8621
- const existingWorkflow2 = existingItem.workflowId ? store.getWorkflow(existingItem.workflowId) : undefined;
8622
- return { kind: "deduped", existingItem, existingLoop, existingWorkflow: existingWorkflow2, invocation };
8641
+ const existingWorkflow = existingItem.workflowId ? store.getWorkflow(existingItem.workflowId) : undefined;
8642
+ return { kind: "deduped", existingItem, existingLoop, existingWorkflow, invocation };
8623
8643
  }
8624
8644
  const throttle = hasThrottleLimits(throttleLimits) ? routeThrottleDecision(store, { projectPath: routeProjectPath, projectGroup, limits: throttleLimits }) : undefined;
8625
8645
  const workItem = store.upsertWorkflowWorkItem({
@@ -8630,8 +8650,7 @@ eventsHandle.command("generic").description("create a one-shot worker/verifier w
8630
8650
  });
8631
8651
  if (throttle && !throttle.allowed)
8632
8652
  return { kind: "throttled", invocation, workItem, throttle };
8633
- const existingWorkflow = store.findWorkflowByName(workflowBody.name);
8634
- const workflow = existingWorkflow ?? store.createWorkflow(workflowBody);
8653
+ const workflow = routeWorkflowForStorage(store, workflowBody);
8635
8654
  const loop = store.createLoop({
8636
8655
  ...loopInput,
8637
8656
  target: {
@@ -5030,7 +5030,7 @@ function enableStartup(result) {
5030
5030
  // package.json
5031
5031
  var package_default = {
5032
5032
  name: "@hasna/loops",
5033
- version: "0.3.42",
5033
+ version: "0.3.43",
5034
5034
  description: "Persistent local loop and workflow runner for deterministic commands and headless AI coding agents",
5035
5035
  type: "module",
5036
5036
  main: "dist/index.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/loops",
3
- "version": "0.3.42",
3
+ "version": "0.3.43",
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",