@cat-factory/worker 0.144.0 → 0.145.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 (35) hide show
  1. package/dist/infrastructure/container-assembly.d.ts.map +1 -1
  2. package/dist/infrastructure/container-assembly.js +2 -1
  3. package/dist/infrastructure/container-assembly.js.map +1 -1
  4. package/dist/infrastructure/container-notification-deps.d.ts +39 -0
  5. package/dist/infrastructure/container-notification-deps.d.ts.map +1 -0
  6. package/dist/infrastructure/container-notification-deps.js +144 -0
  7. package/dist/infrastructure/container-notification-deps.js.map +1 -0
  8. package/dist/infrastructure/container-per-user-deps.d.ts +18 -0
  9. package/dist/infrastructure/container-per-user-deps.d.ts.map +1 -0
  10. package/dist/infrastructure/container-per-user-deps.js +26 -0
  11. package/dist/infrastructure/container-per-user-deps.js.map +1 -0
  12. package/dist/infrastructure/container-shared-services.d.ts.map +1 -1
  13. package/dist/infrastructure/container-shared-services.js +2 -1
  14. package/dist/infrastructure/container-shared-services.js.map +1 -1
  15. package/dist/infrastructure/container.d.ts +1 -34
  16. package/dist/infrastructure/container.d.ts.map +1 -1
  17. package/dist/infrastructure/container.js +8 -127
  18. package/dist/infrastructure/container.js.map +1 -1
  19. package/dist/infrastructure/repositories/D1LlmCallMetricRepository.d.ts.map +1 -1
  20. package/dist/infrastructure/repositories/D1LlmCallMetricRepository.js +10 -1
  21. package/dist/infrastructure/repositories/D1LlmCallMetricRepository.js.map +1 -1
  22. package/dist/infrastructure/repositories/D1RiskPolicyRepository.d.ts.map +1 -1
  23. package/dist/infrastructure/repositories/D1RiskPolicyRepository.js +12 -3
  24. package/dist/infrastructure/repositories/D1RiskPolicyRepository.js.map +1 -1
  25. package/dist/infrastructure/repositories/D1TaskRepository.d.ts +1 -0
  26. package/dist/infrastructure/repositories/D1TaskRepository.d.ts.map +1 -1
  27. package/dist/infrastructure/repositories/D1TaskRepository.js +11 -0
  28. package/dist/infrastructure/repositories/D1TaskRepository.js.map +1 -1
  29. package/dist/infrastructure/repositories/D1TutorialProgressRepository.d.ts +14 -0
  30. package/dist/infrastructure/repositories/D1TutorialProgressRepository.d.ts.map +1 -0
  31. package/dist/infrastructure/repositories/D1TutorialProgressRepository.js +66 -0
  32. package/dist/infrastructure/repositories/D1TutorialProgressRepository.js.map +1 -0
  33. package/migrations/0080_role_scoped_class_rules.sql +16 -0
  34. package/migrations/0080_tutorial_progress.sql +18 -0
  35. package/package.json +18 -18
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Parse a stored JSON id array LENIENTLY: anything that is not an array of strings reads as
3
+ * empty.
4
+ *
5
+ * The row is composed by a browser, so a value that fails to parse means a client or a migration
6
+ * wrote something unexpected. Throwing here would take down the workspace snapshot this is read
7
+ * as part of, over a tutorial-progress list — the correct degradation is to forget the
8
+ * walkthroughs, which costs a re-offer, not the board.
9
+ */
10
+ function parseIds(raw) {
11
+ try {
12
+ const parsed = JSON.parse(raw);
13
+ return Array.isArray(parsed) ? parsed.filter((id) => typeof id === 'string') : [];
14
+ }
15
+ catch {
16
+ // silent-catch-ok: a malformed list degrades to "no tours remembered"; the fallback IS the
17
+ // report, and there is nothing an operator would do about one row of client-authored JSON.
18
+ return [];
19
+ }
20
+ }
21
+ /**
22
+ * The stored decision, narrowed against the closed vocabulary. An unrecognised value reads as
23
+ * "never answered", so a retired member cannot be spliced into the SPA's state as a decision it
24
+ * has no branch for.
25
+ */
26
+ function parseDecision(raw) {
27
+ return raw === 'accepted' || raw === 'declined' ? raw : null;
28
+ }
29
+ function rowToProgress(row) {
30
+ return {
31
+ decision: parseDecision(row.decision),
32
+ completedTourIds: parseIds(row.completed_tour_ids),
33
+ nudgedTourIds: parseIds(row.nudged_tour_ids),
34
+ };
35
+ }
36
+ /** D1-backed per-user tutorial progress (migration 0080). */
37
+ export class D1TutorialProgressRepository {
38
+ db;
39
+ constructor({ db }) {
40
+ this.db = db;
41
+ }
42
+ async get(userId) {
43
+ const row = await this.db
44
+ .prepare('SELECT * FROM tutorial_progress WHERE user_id = ?')
45
+ .bind(userId)
46
+ .first();
47
+ return row ? rowToProgress(row) : null;
48
+ }
49
+ async upsert(userId, progress) {
50
+ await this.db
51
+ .prepare(`INSERT INTO tutorial_progress
52
+ (user_id, decision, completed_tour_ids, nudged_tour_ids, updated_at)
53
+ VALUES (?, ?, ?, ?, ?)
54
+ ON CONFLICT(user_id) DO UPDATE SET
55
+ decision = excluded.decision,
56
+ completed_tour_ids = excluded.completed_tour_ids,
57
+ nudged_tour_ids = excluded.nudged_tour_ids,
58
+ updated_at = excluded.updated_at`)
59
+ .bind(userId, progress.decision, JSON.stringify(progress.completedTourIds), JSON.stringify(progress.nudgedTourIds), Date.now())
60
+ .run();
61
+ }
62
+ async remove(userId) {
63
+ await this.db.prepare('DELETE FROM tutorial_progress WHERE user_id = ?').bind(userId).run();
64
+ }
65
+ }
66
+ //# sourceMappingURL=D1TutorialProgressRepository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"D1TutorialProgressRepository.js","sourceRoot":"","sources":["../../../src/infrastructure/repositories/D1TutorialProgressRepository.ts"],"names":[],"mappings":"AAYA;;;;;;;;GAQG;AACH,SAAS,QAAQ,CAAC,GAAW;IAC3B,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QACvC,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,EAAgB,EAAE,CAAC,OAAO,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IACjG,CAAC;IAAC,MAAM,CAAC;QACP,2FAA2F;QAC3F,2FAA2F;QAC3F,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,aAAa,CAAC,GAAkB;IACvC,OAAO,GAAG,KAAK,UAAU,IAAI,GAAG,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAA;AAC9D,CAAC;AAED,SAAS,aAAa,CAAC,GAAwB;IAC7C,OAAO;QACL,QAAQ,EAAE,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC;QACrC,gBAAgB,EAAE,QAAQ,CAAC,GAAG,CAAC,kBAAkB,CAAC;QAClD,aAAa,EAAE,QAAQ,CAAC,GAAG,CAAC,eAAe,CAAC;KAC7C,CAAA;AACH,CAAC;AAED,6DAA6D;AAC7D,MAAM,OAAO,4BAA4B;IACtB,EAAE,CAAY;IAE/B,YAAY,EAAE,EAAE,EAAsB;QACpC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAA;IACd,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,MAAc;QACtB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,EAAE;aACtB,OAAO,CAAC,mDAAmD,CAAC;aAC5D,IAAI,CAAC,MAAM,CAAC;aACZ,KAAK,EAAuB,CAAA;QAC/B,OAAO,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACxC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,MAAc,EAAE,QAA0B;QACrD,MAAM,IAAI,CAAC,EAAE;aACV,OAAO,CACN;;;;;;;4CAOoC,CACrC;aACA,IAAI,CACH,MAAM,EACN,QAAQ,CAAC,QAAQ,EACjB,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EACzC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,EACtC,IAAI,CAAC,GAAG,EAAE,CACX;aACA,GAAG,EAAE,CAAA;IACV,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,MAAc;QACzB,MAAM,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,iDAAiD,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAA;IAC7F,CAAC;CACF"}
@@ -0,0 +1,16 @@
1
+ -- Role-scoped merge policy on the merge preset.
2
+ --
3
+ -- `class_rules_by_role` is a JSON partial map from workspace role (`admin` | `member` | `viewer`)
4
+ -- to that role's own per-change-class rule map — the same shape as `class_rules`, one tier in.
5
+ -- Composition is narrow-only in the domain (`narrowMergeClassRule`), so a role entry can only
6
+ -- make a class stricter than the base rules; it can never widen one.
7
+ --
8
+ -- `dry_run_roles` is a JSON array of the roles whose runs are forced into dry-run mode: the
9
+ -- pipeline runs in full and opens its pull request, but nothing merges.
10
+ --
11
+ -- Both are NOT NULL with empty defaults, so every existing row resolves to exactly its previous
12
+ -- behaviour — no role narrows anything, nobody is sandboxed. Mirrored on Node by the
13
+ -- `class_rules_by_role` / `dry_run_roles` text columns on the Drizzle `merge_threshold_presets`
14
+ -- table.
15
+ ALTER TABLE merge_threshold_presets ADD COLUMN class_rules_by_role TEXT NOT NULL DEFAULT '{}';
16
+ ALTER TABLE merge_threshold_presets ADD COLUMN dry_run_roles TEXT NOT NULL DEFAULT '[]';
@@ -0,0 +1,18 @@
1
+ -- Per-user in-app tutorial progress. PK is the user id, like `user_settings` (migration 0042).
2
+ --
3
+ -- Mirrors the SPA's browser-persisted store so a person's walkthrough history follows THEM rather
4
+ -- than a browser profile: without it a second machine re-asks the launch question and re-makes
5
+ -- every contextual offer. Absence of a row is the "never touched the tutorial" state, which is
6
+ -- also what "Reset progress" restores (the row is deleted, never rewritten with defaults).
7
+ --
8
+ -- The two id lists are stored as JSON arrays rather than a join table on purpose: they are
9
+ -- grow-only sets of at most a few dozen opaque tour ids, always read and written whole, and
10
+ -- nothing joins or aggregates over them. `decision` is NULL when never answered, which is a real
11
+ -- state distinct from 'declined'.
12
+ CREATE TABLE tutorial_progress (
13
+ user_id TEXT NOT NULL PRIMARY KEY,
14
+ decision TEXT,
15
+ completed_tour_ids TEXT NOT NULL DEFAULT '[]',
16
+ nudged_tour_ids TEXT NOT NULL DEFAULT '[]',
17
+ updated_at INTEGER NOT NULL
18
+ );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cat-factory/worker",
3
- "version": "0.144.0",
3
+ "version": "0.145.0",
4
4
  "description": "Reusable Cloudflare Worker library (Hono + D1) exposing the Agent Architecture Board core: the `createApp()` Hono factory, the default fetch/scheduled/queue handler, and the Durable Object + Workflow classes. Deployments (see deploy/backend) supply the wrangler.toml + config and re-export these.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -42,22 +42,22 @@
42
42
  "pino": "^10.3.1",
43
43
  "valibot": "^1.4.2",
44
44
  "workers-ai-provider": "^4.0.0",
45
- "@cat-factory/agents": "0.107.0",
46
- "@cat-factory/caching": "0.14.0",
47
- "@cat-factory/consensus": "0.14.0",
48
- "@cat-factory/contracts": "0.222.0",
49
- "@cat-factory/eks": "0.1.210",
50
- "@cat-factory/gates": "0.8.56",
51
- "@cat-factory/integrations": "0.121.2",
52
- "@cat-factory/kernel": "0.224.0",
53
- "@cat-factory/observability-langfuse": "0.9.53",
54
- "@cat-factory/observability-otel": "0.7.1",
55
- "@cat-factory/orchestration": "0.193.0",
56
- "@cat-factory/provider-cloudflare": "0.7.362",
57
- "@cat-factory/prompt-fragments": "0.15.47",
58
- "@cat-factory/gitlab": "0.15.15",
59
- "@cat-factory/spend": "0.13.12",
60
- "@cat-factory/server": "0.205.0"
45
+ "@cat-factory/caching": "0.14.2",
46
+ "@cat-factory/consensus": "0.14.2",
47
+ "@cat-factory/contracts": "0.224.0",
48
+ "@cat-factory/eks": "0.1.212",
49
+ "@cat-factory/gates": "0.8.58",
50
+ "@cat-factory/gitlab": "0.15.17",
51
+ "@cat-factory/integrations": "0.122.1",
52
+ "@cat-factory/observability-otel": "0.8.0",
53
+ "@cat-factory/kernel": "0.226.0",
54
+ "@cat-factory/orchestration": "0.195.0",
55
+ "@cat-factory/prompt-fragments": "0.15.49",
56
+ "@cat-factory/provider-cloudflare": "0.7.364",
57
+ "@cat-factory/server": "0.207.0",
58
+ "@cat-factory/spend": "0.14.0",
59
+ "@cat-factory/observability-langfuse": "0.9.55",
60
+ "@cat-factory/agents": "0.108.0"
61
61
  },
62
62
  "devDependencies": {
63
63
  "@cloudflare/vitest-pool-workers": "^0.20.1",
@@ -65,7 +65,7 @@
65
65
  "typescript": "7.0.2",
66
66
  "vitest": "^4.1.10",
67
67
  "wrangler": "^4.118.0",
68
- "@cat-factory/conformance": "0.21.1"
68
+ "@cat-factory/conformance": "0.22.0"
69
69
  },
70
70
  "scripts": {
71
71
  "build": "tsc -b tsconfig.build.json",