@hasna/todos 0.11.58 → 0.11.60

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.
Files changed (41) hide show
  1. package/README.md +66 -2
  2. package/dist/cli/commands/mcp-hooks-commands.d.ts.map +1 -1
  3. package/dist/cli/commands/task-commands.d.ts.map +1 -1
  4. package/dist/cli/index.js +1518 -197
  5. package/dist/contracts.d.ts.map +1 -1
  6. package/dist/contracts.js +600 -14
  7. package/dist/db/findings.d.ts +108 -0
  8. package/dist/db/findings.d.ts.map +1 -0
  9. package/dist/db/migrations.d.ts.map +1 -1
  10. package/dist/db/schema.d.ts.map +1 -1
  11. package/dist/db/task-crud.d.ts +3 -1
  12. package/dist/db/task-crud.d.ts.map +1 -1
  13. package/dist/db/task-runs.d.ts +56 -0
  14. package/dist/db/task-runs.d.ts.map +1 -1
  15. package/dist/db/tasks.d.ts +2 -2
  16. package/dist/db/tasks.d.ts.map +1 -1
  17. package/dist/index.d.ts +5 -3
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +968 -15
  20. package/dist/json-contracts.d.ts.map +1 -1
  21. package/dist/lib/access-profiles.d.ts.map +1 -1
  22. package/dist/lib/event-hooks.d.ts +1 -1
  23. package/dist/lib/event-hooks.d.ts.map +1 -1
  24. package/dist/lib/shared-events.d.ts +1 -1
  25. package/dist/lib/shared-events.d.ts.map +1 -1
  26. package/dist/mcp/index.js +1082 -27
  27. package/dist/mcp/token-utils.d.ts.map +1 -1
  28. package/dist/mcp/tools/task-crud.d.ts.map +1 -1
  29. package/dist/mcp/tools/task-resources.d.ts.map +1 -1
  30. package/dist/mcp.js +12 -1
  31. package/dist/registry.js +600 -14
  32. package/dist/release-provenance.json +3 -3
  33. package/dist/server/index.js +1082 -27
  34. package/dist/server/routes.d.ts +1 -0
  35. package/dist/server/routes.d.ts.map +1 -1
  36. package/dist/server/serve.d.ts +2 -0
  37. package/dist/server/serve.d.ts.map +1 -1
  38. package/dist/storage.js +473 -11
  39. package/dist/types/index.d.ts +11 -0
  40. package/dist/types/index.d.ts.map +1 -1
  41. package/package.json +2 -2
package/README.md CHANGED
@@ -33,6 +33,20 @@ todos manual
33
33
  todos manual --json
34
34
  ```
35
35
 
36
+ Deterministic loops can upsert a task by stable fingerprint without creating
37
+ duplicates. The fingerprint is stored as `metadata.fingerprint`, and later
38
+ upserts shallow-merge metadata so expectation fields can be refreshed safely:
39
+
40
+ ```bash
41
+ todos --json task upsert \
42
+ --fingerprint "loop:expectation:key" \
43
+ --title "Expectation failed" \
44
+ --metadata-json '{"expectation_id":"exp-1"}' \
45
+ --evidence-paths "logs/loop.txt" \
46
+ --expected '{"status":"ok"}' \
47
+ --observed '{"status":"failed"}'
48
+ ```
49
+
36
50
  ## Terminal Dashboard
37
51
 
38
52
  `todos dashboard` launches a local Ink TUI with keyboard tabs for overview,
@@ -398,7 +412,14 @@ polling:
398
412
  todos webhooks add loops \
399
413
  --id openloops-task-created \
400
414
  --transport command \
415
+ --source todos \
401
416
  --type task.created \
417
+ --metadata 'project_path=/home/hasna/workspace/hasna/opensource/*' \
418
+ --metadata-json 'route_enabled=true' \
419
+ --metadata-json 'automation.no_auto!=true' \
420
+ --metadata-json 'automation.manual_required!=true' \
421
+ --metadata-json 'automation.requires_approval!=true' \
422
+ --metadata-json 'automation.approval_required!=true' \
402
423
  --arg=events \
403
424
  --arg=handle \
404
425
  --arg=todos-task \
@@ -418,8 +439,27 @@ When a task is created, `@hasna/events` sends the event JSON on stdin and in
418
439
  `HASNA_EVENT_JSON`. OpenLoops uses that event to create a deduped one-shot
419
440
  worker/verifier workflow for the task. The event data includes task identity,
420
441
  title, description, project/list ids, working directory, tags, metadata, status,
421
- priority, and timestamps. Local event hooks remain available for local-only
422
- JSONL/socket/script integrations.
442
+ priority, approval state, and timestamps. Event metadata includes routing-safe
443
+ project/list/path fields, `route_enabled` when the task metadata opts in, and an
444
+ `automation` object containing only boolean routing gates such as `no_auto`,
445
+ `manual_required`, `requires_approval`, and `approval_required`.
446
+
447
+ Production task-created routes should fail closed:
448
+
449
+ - Require one explicit opt-in, either task metadata `route_enabled=true` or an
450
+ approved routing tag such as `auto:route`.
451
+ - Add negative automation predicates so `no_auto`, manual, and approval-gated
452
+ tasks do not invoke the route.
453
+ - Scope by project path, task list, tags, or repo metadata before invoking
454
+ OpenLoops.
455
+ - Avoid overlapping opt-in channels for the same task family unless the target
456
+ handler is idempotent. `loops events handle todos-task` dedupes by task id and
457
+ event type, but a narrower subscription still avoids wasted invocations.
458
+
459
+ For tag opt-in, use a second route with the same deny predicates and
460
+ `--data 'tags=auto:route'` instead of `--metadata-json 'route_enabled=true'`.
461
+ Tasks without one of those opt-ins are intentionally no-route. Local event hooks
462
+ remain available for local-only JSONL/socket/script integrations.
423
463
 
424
464
  ## Local Terminal Notifications
425
465
 
@@ -781,6 +821,30 @@ metadata, redaction status, retention metadata, and metadata-only fallback when
781
821
  the original path is unavailable. Use `--no-store` to record only artifact
782
822
  metadata.
783
823
 
824
+ Loops that need bounded, idempotent JSON can use the transaction commands
825
+ instead of scripting around comments and run lookup:
826
+
827
+ ```bash
828
+ todos runs begin <task-id> --key nightly:parser:42 --agent codex --title "Nightly parser loop"
829
+ RUN_ID=$(todos runs begin <task-id> --key nightly:parser:42 --agent codex --title "Nightly parser loop" --apply | jq -r .run.id)
830
+ todos findings upsert --task <task-id> --run "$RUN_ID" --fingerprint parser-timeout --title "Parser timeout" --severity high --source nightly-parser --artifact logs/parser-loop.txt --apply
831
+ todos findings resolve-missing --task <task-id> --source nightly-parser --fingerprints parser-timeout --run "$RUN_ID"
832
+ todos findings resolve-missing --task <task-id> --source nightly-parser --fingerprints parser-timeout --run "$RUN_ID" --apply
833
+ todos runs finish "$RUN_ID" --status completed --summary "nightly loop complete"
834
+ ```
835
+
836
+ `runs begin` is dry-run by default and only creates a run when `--apply` is
837
+ provided. Reusing the same `--key`, `--loop-run-id`, or `--loop-id` returns the
838
+ existing compact run summary instead of creating duplicates. `runs finish` is
839
+ idempotent for already-finished runs and can resolve a run by `--key --task`.
840
+ Finding upserts are deduped by task and fingerprint, redacted before storage,
841
+ and expose only artifact paths/references by default. `findings upsert` and
842
+ `findings resolve-missing` are dry-run by default; add `--apply` to mutate local
843
+ state. MCP clients use `begin_task_run_transaction`, `finish_task_run`,
844
+ `upsert_task_finding`, `list_task_findings`, and
845
+ `resolve_missing_task_findings`; these compact loop tools are included in the
846
+ default `TODOS_PROFILE=minimal` surface.
847
+
784
848
  ## Local Time Tracking
785
849
 
786
850
  Manual time logs and focus sessions stay in the local SQLite database and roll
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-hooks-commands.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/mcp-hooks-commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwMzC,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,QAghCxD"}
1
+ {"version":3,"file":"mcp-hooks-commands.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/mcp-hooks-commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwMzC,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,QA6oCxD"}
@@ -1 +1 @@
1
- {"version":3,"file":"task-commands.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/task-commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuEzC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,QA0wBpD"}
1
+ {"version":3,"file":"task-commands.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/task-commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA0HzC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,QAo1BpD"}