openclaw-scheduler 0.2.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.
Files changed (70) hide show
  1. package/AGENTS.md +302 -0
  2. package/BEST-PRACTICES.md +506 -0
  3. package/CHANGELOG.md +82 -0
  4. package/CODE_OF_CONDUCT.md +22 -0
  5. package/CONTEXT.md +26 -0
  6. package/CONTRIBUTING.md +73 -0
  7. package/IMPLEMENTATION_SPEC.md +170 -0
  8. package/INSTALL-ADDITIONAL-HOST.md +333 -0
  9. package/INSTALL-LINUX.md +419 -0
  10. package/INSTALL-WINDOWS.md +305 -0
  11. package/INSTALL.md +364 -0
  12. package/JOB-QUICK-REF.md +222 -0
  13. package/LICENSE +21 -0
  14. package/QUICK-START.md +256 -0
  15. package/README.md +2170 -0
  16. package/SECURITY.md +34 -0
  17. package/UNINSTALL.md +129 -0
  18. package/UPGRADING.md +436 -0
  19. package/agents.js +67 -0
  20. package/approval.js +107 -0
  21. package/backup.js +390 -0
  22. package/bin/openclaw-scheduler.js +138 -0
  23. package/cli.js +1083 -0
  24. package/db.js +122 -0
  25. package/dispatch/529-recovery.mjs +204 -0
  26. package/dispatch/README.md +372 -0
  27. package/dispatch/config.example.json +24 -0
  28. package/dispatch/deliver-watcher.sh +57 -0
  29. package/dispatch/hooks.mjs +171 -0
  30. package/dispatch/index.mjs +1836 -0
  31. package/dispatch/watcher.mjs +1396 -0
  32. package/dispatch-queue.js +112 -0
  33. package/dispatcher-approvals.js +96 -0
  34. package/dispatcher-delivery.js +43 -0
  35. package/dispatcher-maintenance.js +242 -0
  36. package/dispatcher-shell.js +29 -0
  37. package/dispatcher-strategies.js +1280 -0
  38. package/dispatcher-utils.js +81 -0
  39. package/dispatcher.js +855 -0
  40. package/docs/adr-schedule-ownership.md +73 -0
  41. package/docs/gateway-contract.md +904 -0
  42. package/docs/plans/2026-03-09-fix-typescript-types.md +91 -0
  43. package/docs/plans/2026-03-09-test-coverage-gaps.md +83 -0
  44. package/docs/plans/2026-03-10-dispatcher-refactor.md +801 -0
  45. package/docs/trust-architecture.md +266 -0
  46. package/gateway.js +473 -0
  47. package/idempotency.js +119 -0
  48. package/index.d.ts +864 -0
  49. package/index.js +17 -0
  50. package/jobs.js +1224 -0
  51. package/messages.js +357 -0
  52. package/migrate-consolidate.js +694 -0
  53. package/migrate.js +125 -0
  54. package/package.json +130 -0
  55. package/paths.js +79 -0
  56. package/prompt-context.js +94 -0
  57. package/retrieval.js +176 -0
  58. package/runs.js +270 -0
  59. package/scheduler-schema.js +101 -0
  60. package/schema.sql +480 -0
  61. package/scripts/dispatch-cli-utils.mjs +65 -0
  62. package/scripts/inbox-consumer.mjs +288 -0
  63. package/scripts/stuck-detector.sh +18 -0
  64. package/scripts/stuck-run-detector.mjs +333 -0
  65. package/scripts/telegram-webhook-check.mjs +238 -0
  66. package/setup.mjs +724 -0
  67. package/shell-result.js +214 -0
  68. package/task-tracker.js +300 -0
  69. package/team-adapter.js +335 -0
  70. package/v02-runtime.js +599 -0
@@ -0,0 +1,91 @@
1
+ **Status: Completed**
2
+
3
+ # Fix TypeScript Type Definitions Implementation Plan
4
+
5
+ > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
6
+
7
+ **Goal:** Make index.d.ts accurately reflect every exported JS function, parameter, and return type.
8
+
9
+ **Architecture:** Single-file rewrite of index.d.ts plus expanded types-smoke.ts. No JS changes.
10
+
11
+ **Tech Stack:** TypeScript declarations, tsc --noEmit for validation.
12
+
13
+ ---
14
+
15
+ ### Task 1: Rewrite index.d.ts record interfaces
16
+
17
+ **Files:**
18
+ - Modify: `index.d.ts`
19
+
20
+ **Step 1:** Rewrite all record interfaces to include every column from schema.sql:
21
+ - `JobSpec`: add 17 missing fields (payload_scope, payload_model, payload_thinking, delivery_guarantee, job_class, preferred_session_key, job_type, watchdog_*, consecutive_errors, queued_count, run_now)
22
+ - `JobRecord`: add created_at, updated_at, last_run_at
23
+ - `RunRecord`: add started_at, finished_at, duration_ms, last_heartbeat, session_key, session_id, dispatched_at, run_timeout_ms, context_summary, replay_of, idempotency_key
24
+ - `MessageRecord`: add all 16 missing columns (team_id through owner)
25
+ - `ApprovalRecord`: add dispatch_queue_id, requested_at, resolved_at, resolved_by, notes
26
+ - `AgentRecord`: add last_seen_at, created_at
27
+ - Add new `DispatchRecord` interface with all job_dispatch_queue columns
28
+ - Fix `ShellResult` to add stdoutTruncated, stderrTruncated fields
29
+ - Add `PartialShellResult` (return type of extractShellResultFromRun)
30
+ - Type `SCHEDULER_SCHEMAS` with its actual structure
31
+
32
+ **Step 2:** Run `npm run typecheck` -- expect failure (smoke test uses old shapes)
33
+
34
+ ### Task 2: Rewrite index.d.ts function declarations
35
+
36
+ **Files:**
37
+ - Modify: `index.d.ts`
38
+
39
+ **Step 1:** Add all 26 missing function declarations:
40
+ - jobs: pruneExpiredJobs, detectCycle, getChainDepth, getDispatchBacklogCount, canEnqueueDispatch, cancelJob, hasRunningRunForPool, hasRunningRun
41
+ - messages: getTeamMessages, ackMessage, expireMessages, pruneMessages, recordMessageAttempt, listMessageReceipts
42
+ - gateway: runAgentTurn, runAgentTurnWithActivityTimeout, sendSystemEvent, invokeGatewayTool, listSessions, getAllSubAgentSessions
43
+ - approval: countPendingApprovalsForJob, getTimedOutApprovals, pruneApprovals
44
+ - runs: updateHeartbeat, getRunningRunsByPool
45
+ - paths: resolveBackupStagingDir
46
+ - dispatch-queue: listDispatchesForJob
47
+
48
+ **Step 2:** Fix 4 wrong return types:
49
+ - runJobNow: returns JobRecord & { dispatch_id, dispatch_kind } | null
50
+ - resolveApproval: returns ApprovalRecord
51
+ - deliverMessage: returns Promise<{ ok: true; parts: number; lastResponse: unknown }>
52
+ - extractShellResultFromRun: returns PartialShellResult | null
53
+
54
+ **Step 3:** Replace Record<string, unknown> params with named fields:
55
+ - sendMessage opts
56
+ - createRun opts
57
+ - finishRun opts
58
+ - normalizeShellResult params
59
+ - buildTriggeredRunContext params
60
+ - listJobs opts
61
+ - resolveSchedulerDbPath params
62
+ - resolveArtifactsDir params
63
+ - upsertAgent opts
64
+
65
+ **Step 4:** Run `npm run typecheck` -- expect failure (smoke test)
66
+
67
+ ### Task 3: Expand types-smoke.ts
68
+
69
+ **Files:**
70
+ - Modify: `types-smoke.ts`
71
+
72
+ **Step 1:** Add smoke tests exercising:
73
+ - All 26 newly typed functions (at type level, not runtime)
74
+ - Watchdog JobSpec fields
75
+ - DispatchRecord interface
76
+ - Gateway function signatures
77
+ - Message ack and team functions
78
+ - Approval timeout/prune functions
79
+ - PartialShellResult from extractShellResultFromRun
80
+ - RunRecord time fields (started_at, finished_at)
81
+
82
+ **Step 2:** Run `npm run typecheck` -- must pass
83
+
84
+ **Step 3:** Run `npm test` -- must still pass (581 tests, no JS changes)
85
+
86
+ ### Task 4: Commit
87
+
88
+ ```bash
89
+ git add index.d.ts types-smoke.ts
90
+ git commit -m "Complete TypeScript type coverage for all exported APIs"
91
+ ```
@@ -0,0 +1,83 @@
1
+ **Status: Completed**
2
+
3
+ # Test Coverage Gaps Implementation Plan
4
+
5
+ > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
6
+
7
+ **Goal:** Close 6 identified testable coverage gaps in test.js without changing any source code.
8
+
9
+ **Architecture:** Add test sections to the existing test.js using the custom assert harness. All tests use in-memory SQLite.
10
+
11
+ **Tech Stack:** Node.js ESM, better-sqlite3, custom test harness (assert/passed/failed counters).
12
+
13
+ ---
14
+
15
+ ### Task 1: Import dispatcher-utils.js and replace inline re-implementations
16
+
17
+ **Files:**
18
+ - Modify: `test.js` (imports at top, transient error section around line 1859)
19
+
20
+ **Changes:**
21
+ 1. Add import: `import { matchesSentinel, detectTransientError, adaptiveDeferralMs, buildExecutionIntentNote, getBackoffMs, sqliteNow } from './dispatcher-utils.js';`
22
+ 2. In the "Transient Error Detection" section (~line 1859), delete the inline `TRANSIENT_ERROR_PATTERNS` array, `detectTransientError` function, and `matchesSentinel` function
23
+ 3. Add new test section "Dispatcher Utils" testing:
24
+ - `adaptiveDeferralMs`: depth 0 returns baseMs, depth 11 caps at 12x, result caps at 300000
25
+ - `buildExecutionIntentNote`: returns '' for normal jobs, returns plan note for plan intent, returns read-only note for read_only, includes both when both set
26
+ - `getBackoffMs`: n=1 returns 30000, n=5 returns 3600000, n=99 caps at 3600000
27
+ - `sqliteNow`: returns valid datetime string format
28
+
29
+ ### Task 2: Test dispatch-queue claim/release/setStatus
30
+
31
+ **Files:**
32
+ - Modify: `test.js`
33
+
34
+ **Changes:**
35
+ Add new test section "Dispatch Queue Lifecycle" after existing dispatch tests:
36
+ - `claimDispatch`: create pending dispatch, claim it, verify status='claimed' and claimed_at set; claim again returns null
37
+ - `releaseDispatch`: claim a dispatch, release it, verify status='pending' and claimed_at cleared; release with new scheduledFor
38
+ - `setDispatchStatus`: set to 'done', verify processed_at set; set to 'cancelled', verify processed_at set; set to 'pending', verify processed_at unchanged
39
+
40
+ ### Task 3: Test approval timeout/prune/count
41
+
42
+ **Files:**
43
+ - Modify: `test.js`
44
+
45
+ **Changes:**
46
+ Add to existing "v5: Approval Gates" section or new section after it:
47
+ - `countPendingApprovalsForJob`: create 2 pending approvals, count returns 2; resolve one, count returns 1
48
+ - `getTimedOutApprovals`: create approval, backdate requested_at past timeout, verify it appears in results with job_name/approval_timeout_s/approval_auto
49
+ - `pruneApprovals`: create resolved approval, backdate resolved_at past retention, prune, verify deleted
50
+
51
+ ### Task 4: Test runs updateRunSession and updateContextSummary
52
+
53
+ **Files:**
54
+ - Modify: `test.js` (imports + new section)
55
+
56
+ **Changes:**
57
+ 1. Add `updateRunSession` and `updateContextSummary` to runs.js import
58
+ 2. Add tests:
59
+ - `updateRunSession`: create run, call with session key/id, verify both stored on run
60
+ - `updateContextSummary`: create run, call with object, verify JSON stored; call with string, verify stored as-is
61
+
62
+ ### Task 5: Test prompt-context.js missing branches
63
+
64
+ **Files:**
65
+ - Modify: `test.js`
66
+
67
+ **Changes:**
68
+ Add to existing "Prompt Context" section:
69
+ - Null parent run: pass `{ triggered_by_run: 'nonexistent' }` with getRunById returning undefined; verify text='', meta.parent_run_missing=true
70
+ - No trigger: pass `{}` (no triggered_by_run); verify text='', meta is empty
71
+ - Non-shell parent: pass parent run with status='ok', summary='Agent completed task', session_target='isolated' (no shell fields); verify text includes summary, no shell exit code
72
+
73
+ ### Task 6: Test migrate.js cronFromSchedule
74
+
75
+ **Files:**
76
+ - Modify: `test.js`
77
+
78
+ **Changes:**
79
+ Since `cronFromSchedule` is not exported, test it indirectly via dynamic import or extract its logic. Since we cannot modify source files, we re-implement the pure function in tests (same pattern as the original matchesSentinel approach, but documented).
80
+
81
+ Actually: `cronFromSchedule` is a local function in migrate.js, not exported. We cannot test it without modifying the source. Skip this task or note it as requiring a source change.
82
+
83
+ **Alternative:** Add a note that this gap requires exporting cronFromSchedule from migrate.js in a future change.