@hasna/loops 0.3.32 → 0.3.33

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
@@ -5254,7 +5254,7 @@ function buildScriptInventoryReport(store, opts = {}) {
5254
5254
  // package.json
5255
5255
  var package_default = {
5256
5256
  name: "@hasna/loops",
5257
- version: "0.3.32",
5257
+ version: "0.3.33",
5258
5258
  description: "Persistent local loop and workflow runner for deterministic commands and headless AI coding agents",
5259
5259
  type: "module",
5260
5260
  main: "dist/index.js",
@@ -6928,6 +6928,25 @@ function taskDrainEvent(task) {
6928
6928
  }
6929
6929
  };
6930
6930
  }
6931
+ function compactDrainResult(result) {
6932
+ const value = result.value;
6933
+ const event = objectField(value.event);
6934
+ const loop = objectField(value.loop);
6935
+ const workflow = objectField(value.workflow);
6936
+ const throttle = objectField(value.throttle);
6937
+ return {
6938
+ kind: result.kind,
6939
+ taskId: event?.subject,
6940
+ eventId: event?.id,
6941
+ idempotencyKey: stringField(value.idempotencyKey),
6942
+ reason: stringField(value.reason) ?? throttle?.reason,
6943
+ loopId: stringField(loop?.id),
6944
+ loopName: stringField(loop?.name),
6945
+ workflowId: stringField(workflow?.id),
6946
+ workflowName: stringField(workflow?.name),
6947
+ queuedAtSource: value.queuedAtSource
6948
+ };
6949
+ }
6931
6950
  function loadReadyTodosTasks(opts, scanLimit) {
6932
6951
  const todosProject = opts.todosProject ?? defaultLoopsProject();
6933
6952
  const args = ["--project", todosProject, "--json", "ready", "--limit", String(scanLimit)];
@@ -7135,7 +7154,7 @@ eventsHandle.command("todos-task").description("create a one-shot worker/verifie
7135
7154
  print(result.value, result.human);
7136
7155
  });
7137
7156
  var eventsDrain = events.command("drain").description("drain durable source queues into bounded OpenLoops workflows");
7138
- eventsDrain.command("todos-task").description("drain ready todos tasks into bounded worker/verifier workflow loops").option("--todos-project <path>", "todos storage project path", defaultLoopsProject()).option("--todos-project-id <id>", "filter todos ready output to one todos project id").option("--task-list <id-or-slug>", "filter ready tasks to one task-list id, slug, or name").option("--project-path-prefix <path>", "filter ready tasks to a project/repo path prefix").option("--tags <tags>", "require all comma-separated tags before routing").option("--tag <tags>", "alias for --tags").option("--limit <n>", "maximum filtered ready-task candidates to consider", "50").option("--scan-limit <n>", "maximum raw todos ready rows to fetch before filters; defaults to 500 when filters are used").option("--max-dispatch <n>", "maximum new workflow loops to create in this drain run", "1").option("--evidence-dir <path>", "write a JSON drain report to this directory").option("--provider <provider>", "agent provider", "codewith").option("--auth-profile <profile>", "provider-native auth profile; currently supported for codewith").option("--auth-profile-pool <profiles>", "comma-separated provider-native auth profile pool").option("--worker-auth-profile <profile>", "provider-native auth profile for worker step").option("--verifier-auth-profile <profile>", "provider-native auth profile for verifier step").option("--account <profile>", "OpenAccounts profile name").option("--account-pool <profiles>", "comma-separated OpenAccounts profile pool").option("--worker-account <profile>", "OpenAccounts profile for worker step").option("--verifier-account <profile>", "OpenAccounts profile for verifier step").option("--account-tool <tool>", "OpenAccounts tool id").option("--model <model>", "provider model").option("--variant <variant>", "provider-specific model variant or reasoning effort").option("--agent <agent>", "provider-specific agent").option("--permission-mode <mode>", "provider permission mode: default, plan, auto, or bypass", "bypass").option("--sandbox <mode>", "provider sandbox").option("--project-path <path>", "fallback project/repo working directory").option("--project-group <name>", "optional project group for concurrency limits").option("--max-active <n>", "skip creating a workflow when this many active routed workflows already exist globally").option("--max-active-per-project <n>", "skip creating a workflow when this many active routed workflows already exist for the project").option("--max-active-per-project-group <n>", "skip creating a workflow when this many active routed workflows already exist for the project group").option("--worktree-mode <mode>", "worktree isolation mode: auto, required, off, or main", "auto").option("--worktree-root <path>", "base directory for OpenLoops-managed git worktrees").option("--worktree-branch-prefix <prefix>", "branch prefix for generated task worktrees", "openloops").option("--name-prefix <prefix>", "workflow/loop name prefix", "event:todos-task").option("--preflight", "check generated workflow steps before storing workflow loops").option("--dry-run", "preview selected tasks and generated workflow loops without storing anything").action((opts) => {
7157
+ eventsDrain.command("todos-task").description("drain ready todos tasks into bounded worker/verifier workflow loops").option("--todos-project <path>", "todos storage project path", defaultLoopsProject()).option("--todos-project-id <id>", "filter todos ready output to one todos project id").option("--task-list <id-or-slug>", "filter ready tasks to one task-list id, slug, or name").option("--project-path-prefix <path>", "filter ready tasks to a project/repo path prefix").option("--tags <tags>", "require all comma-separated tags before routing").option("--tag <tags>", "alias for --tags").option("--limit <n>", "maximum filtered ready-task candidates to consider", "50").option("--scan-limit <n>", "maximum raw todos ready rows to fetch before filters; defaults to 500 when filters are used").option("--max-dispatch <n>", "maximum new workflow loops to create in this drain run", "1").option("--evidence-dir <path>", "write a JSON drain report to this directory").option("--compact", "print compact JSON to stdout while preserving the full evidence file").option("--provider <provider>", "agent provider", "codewith").option("--auth-profile <profile>", "provider-native auth profile; currently supported for codewith").option("--auth-profile-pool <profiles>", "comma-separated provider-native auth profile pool").option("--worker-auth-profile <profile>", "provider-native auth profile for worker step").option("--verifier-auth-profile <profile>", "provider-native auth profile for verifier step").option("--account <profile>", "OpenAccounts profile name").option("--account-pool <profiles>", "comma-separated OpenAccounts profile pool").option("--worker-account <profile>", "OpenAccounts profile for worker step").option("--verifier-account <profile>", "OpenAccounts profile for verifier step").option("--account-tool <tool>", "OpenAccounts tool id").option("--model <model>", "provider model").option("--variant <variant>", "provider-specific model variant or reasoning effort").option("--agent <agent>", "provider-specific agent").option("--permission-mode <mode>", "provider permission mode: default, plan, auto, or bypass", "bypass").option("--sandbox <mode>", "provider sandbox").option("--project-path <path>", "fallback project/repo working directory").option("--project-group <name>", "optional project group for concurrency limits").option("--max-active <n>", "skip creating a workflow when this many active routed workflows already exist globally").option("--max-active-per-project <n>", "skip creating a workflow when this many active routed workflows already exist for the project").option("--max-active-per-project-group <n>", "skip creating a workflow when this many active routed workflows already exist for the project group").option("--worktree-mode <mode>", "worktree isolation mode: auto, required, off, or main", "auto").option("--worktree-root <path>", "base directory for OpenLoops-managed git worktrees").option("--worktree-branch-prefix <prefix>", "branch prefix for generated task worktrees", "openloops").option("--name-prefix <prefix>", "workflow/loop name prefix", "event:todos-task").option("--preflight", "check generated workflow steps before storing workflow loops").option("--dry-run", "preview selected tasks and generated workflow loops without storing anything").action((opts) => {
7139
7158
  const maxDispatch = positiveInteger(opts.maxDispatch ?? "1", "--max-dispatch") ?? 1;
7140
7159
  const todosProject = opts.todosProject ?? defaultLoopsProject();
7141
7160
  const requiredTags = splitList(opts.tags ?? opts.tag) ?? [];
@@ -7191,7 +7210,33 @@ eventsDrain.command("todos-task").description("drain ready todos tasks into boun
7191
7210
  results: results.map((result) => ({ kind: result.kind, ...result.value }))
7192
7211
  };
7193
7212
  const evidencePath = writeRouteEvidence("todos-task-drain", report, opts.evidenceDir);
7194
- print({ ...report, evidencePath }, `drained todos ready queue: considered=${report.considered} created=${report.created} deduped=${report.deduped} throttled=${report.throttled} skipped=${report.skipped}`);
7213
+ const output = opts.compact ? {
7214
+ drainedAt: report.drainedAt,
7215
+ todosProject: report.todosProject,
7216
+ todosProjectId: report.todosProjectId,
7217
+ taskList: report.taskList,
7218
+ taskListId: report.taskListId,
7219
+ projectPathPrefix: report.projectPathPrefix,
7220
+ tags: report.tags,
7221
+ limit: report.limit,
7222
+ scanLimit: report.scanLimit,
7223
+ filtersApplied: report.filtersApplied,
7224
+ scanned: report.scanned,
7225
+ candidates: report.candidates,
7226
+ filteredCandidates: report.filteredCandidates,
7227
+ scanExhausted: report.scanExhausted,
7228
+ considered: report.considered,
7229
+ created: report.created,
7230
+ deduped: report.deduped,
7231
+ throttled: report.throttled,
7232
+ skipped: report.skipped,
7233
+ maxDispatch: report.maxDispatch,
7234
+ source: report.source,
7235
+ dryRun: report.dryRun,
7236
+ evidencePath,
7237
+ results: results.map(compactDrainResult)
7238
+ } : { ...report, evidencePath };
7239
+ print(output, `drained todos ready queue: considered=${report.considered} created=${report.created} deduped=${report.deduped} throttled=${report.throttled} skipped=${report.skipped}`);
7195
7240
  });
7196
7241
  eventsHandle.command("generic").description("create a one-shot worker/verifier workflow loop for any Hasna event").option("--provider <provider>", "agent provider", "codewith").option("--auth-profile <profile>", "provider-native auth profile; currently supported for codewith").option("--auth-profile-pool <profiles>", "comma-separated provider-native auth profile pool").option("--worker-auth-profile <profile>", "provider-native auth profile for worker step").option("--verifier-auth-profile <profile>", "provider-native auth profile for verifier step").option("--account <profile>", "OpenAccounts profile name").option("--account-pool <profiles>", "comma-separated OpenAccounts profile pool").option("--worker-account <profile>", "OpenAccounts profile for worker step").option("--verifier-account <profile>", "OpenAccounts profile for verifier step").option("--account-tool <tool>", "OpenAccounts tool id").option("--model <model>", "provider model").option("--variant <variant>", "provider-specific model variant or reasoning effort").option("--agent <agent>", "provider-specific agent").option("--permission-mode <mode>", "provider permission mode: default, plan, auto, or bypass", "bypass").option("--sandbox <mode>", "provider sandbox").option("--project-path <path>", "fallback project/repo working directory").option("--project-group <name>", "optional project group for concurrency limits").option("--max-active <n>", "skip creating a workflow when this many active routed workflows already exist globally").option("--max-active-per-project <n>", "skip creating a workflow when this many active routed workflows already exist for the project").option("--max-active-per-project-group <n>", "skip creating a workflow when this many active routed workflows already exist for the project group").option("--worktree-mode <mode>", "worktree isolation mode: auto, required, off, or main", "auto").option("--worktree-root <path>", "base directory for OpenLoops-managed git worktrees").option("--worktree-branch-prefix <prefix>", "branch prefix for generated event worktrees", "openloops").option("--name-prefix <prefix>", "workflow/loop name prefix", "event:generic").option("--preflight", "check generated workflow steps before storing the workflow loop").option("--dry-run", "print the workflow and loop input without storing anything").action(async (opts) => {
7197
7242
  const event = await readEventEnvelopeFromStdin();
@@ -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.32",
4577
+ version: "0.3.33",
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.32",
3
+ "version": "0.3.33",
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",