@ozzylabs/feedradar 0.1.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 (168) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +104 -0
  3. package/dist/agents/_boundary.d.ts +44 -0
  4. package/dist/agents/_boundary.d.ts.map +1 -0
  5. package/dist/agents/_boundary.js +59 -0
  6. package/dist/agents/_boundary.js.map +1 -0
  7. package/dist/agents/claude-code.d.ts +32 -0
  8. package/dist/agents/claude-code.d.ts.map +1 -0
  9. package/dist/agents/claude-code.js +256 -0
  10. package/dist/agents/claude-code.js.map +1 -0
  11. package/dist/agents/codex-cli.d.ts +31 -0
  12. package/dist/agents/codex-cli.d.ts.map +1 -0
  13. package/dist/agents/codex-cli.js +303 -0
  14. package/dist/agents/codex-cli.js.map +1 -0
  15. package/dist/agents/copilot.d.ts +29 -0
  16. package/dist/agents/copilot.d.ts.map +1 -0
  17. package/dist/agents/copilot.js +282 -0
  18. package/dist/agents/copilot.js.map +1 -0
  19. package/dist/agents/gemini-cli.d.ts +30 -0
  20. package/dist/agents/gemini-cli.d.ts.map +1 -0
  21. package/dist/agents/gemini-cli.js +316 -0
  22. package/dist/agents/gemini-cli.js.map +1 -0
  23. package/dist/agents/index.d.ts +12 -0
  24. package/dist/agents/index.d.ts.map +1 -0
  25. package/dist/agents/index.js +33 -0
  26. package/dist/agents/index.js.map +1 -0
  27. package/dist/agents/types.d.ts +103 -0
  28. package/dist/agents/types.d.ts.map +1 -0
  29. package/dist/agents/types.js +2 -0
  30. package/dist/agents/types.js.map +1 -0
  31. package/dist/claude-skills/dismiss/SKILL.md +41 -0
  32. package/dist/claude-skills/research/SKILL.md +45 -0
  33. package/dist/claude-skills/review/SKILL.md +45 -0
  34. package/dist/claude-skills/update/SKILL.md +49 -0
  35. package/dist/cli/dismiss.d.ts +28 -0
  36. package/dist/cli/dismiss.d.ts.map +1 -0
  37. package/dist/cli/dismiss.js +122 -0
  38. package/dist/cli/dismiss.js.map +1 -0
  39. package/dist/cli/index.d.ts +7 -0
  40. package/dist/cli/index.d.ts.map +1 -0
  41. package/dist/cli/index.js +64 -0
  42. package/dist/cli/index.js.map +1 -0
  43. package/dist/cli/init.d.ts +148 -0
  44. package/dist/cli/init.d.ts.map +1 -0
  45. package/dist/cli/init.js +578 -0
  46. package/dist/cli/init.js.map +1 -0
  47. package/dist/cli/research.d.ts +30 -0
  48. package/dist/cli/research.d.ts.map +1 -0
  49. package/dist/cli/research.js +313 -0
  50. package/dist/cli/research.js.map +1 -0
  51. package/dist/cli/review.d.ts +34 -0
  52. package/dist/cli/review.d.ts.map +1 -0
  53. package/dist/cli/review.js +418 -0
  54. package/dist/cli/review.js.map +1 -0
  55. package/dist/cli/source.d.ts +57 -0
  56. package/dist/cli/source.d.ts.map +1 -0
  57. package/dist/cli/source.js +511 -0
  58. package/dist/cli/source.js.map +1 -0
  59. package/dist/cli/update.d.ts +43 -0
  60. package/dist/cli/update.d.ts.map +1 -0
  61. package/dist/cli/update.js +429 -0
  62. package/dist/cli/update.js.map +1 -0
  63. package/dist/cli/watch.d.ts +22 -0
  64. package/dist/cli/watch.d.ts.map +1 -0
  65. package/dist/cli/watch.js +101 -0
  66. package/dist/cli/watch.js.map +1 -0
  67. package/dist/core/config.d.ts +60 -0
  68. package/dist/core/config.d.ts.map +1 -0
  69. package/dist/core/config.js +101 -0
  70. package/dist/core/config.js.map +1 -0
  71. package/dist/core/feeds/derive-id.d.ts +43 -0
  72. package/dist/core/feeds/derive-id.d.ts.map +1 -0
  73. package/dist/core/feeds/derive-id.js +66 -0
  74. package/dist/core/feeds/derive-id.js.map +1 -0
  75. package/dist/core/feeds/github-api.d.ts +69 -0
  76. package/dist/core/feeds/github-api.d.ts.map +1 -0
  77. package/dist/core/feeds/github-api.js +161 -0
  78. package/dist/core/feeds/github-api.js.map +1 -0
  79. package/dist/core/feeds/github-releases.d.ts +3 -0
  80. package/dist/core/feeds/github-releases.d.ts.map +1 -0
  81. package/dist/core/feeds/github-releases.js +85 -0
  82. package/dist/core/feeds/github-releases.js.map +1 -0
  83. package/dist/core/feeds/html.d.ts +10 -0
  84. package/dist/core/feeds/html.d.ts.map +1 -0
  85. package/dist/core/feeds/html.js +263 -0
  86. package/dist/core/feeds/html.js.map +1 -0
  87. package/dist/core/feeds/index.d.ts +5 -0
  88. package/dist/core/feeds/index.d.ts.map +1 -0
  89. package/dist/core/feeds/index.js +18 -0
  90. package/dist/core/feeds/index.js.map +1 -0
  91. package/dist/core/feeds/npm-registry.d.ts +36 -0
  92. package/dist/core/feeds/npm-registry.d.ts.map +1 -0
  93. package/dist/core/feeds/npm-registry.js +200 -0
  94. package/dist/core/feeds/npm-registry.js.map +1 -0
  95. package/dist/core/feeds/rss.d.ts +12 -0
  96. package/dist/core/feeds/rss.d.ts.map +1 -0
  97. package/dist/core/feeds/rss.js +222 -0
  98. package/dist/core/feeds/rss.js.map +1 -0
  99. package/dist/core/feeds/types.d.ts +45 -0
  100. package/dist/core/feeds/types.d.ts.map +1 -0
  101. package/dist/core/feeds/types.js +2 -0
  102. package/dist/core/feeds/types.js.map +1 -0
  103. package/dist/core/filter.d.ts +25 -0
  104. package/dist/core/filter.d.ts.map +1 -0
  105. package/dist/core/filter.js +123 -0
  106. package/dist/core/filter.js.map +1 -0
  107. package/dist/core/injection-detector.d.ts +57 -0
  108. package/dist/core/injection-detector.d.ts.map +1 -0
  109. package/dist/core/injection-detector.js +109 -0
  110. package/dist/core/injection-detector.js.map +1 -0
  111. package/dist/core/items.d.ts +20 -0
  112. package/dist/core/items.d.ts.map +1 -0
  113. package/dist/core/items.js +105 -0
  114. package/dist/core/items.js.map +1 -0
  115. package/dist/core/state.d.ts +12 -0
  116. package/dist/core/state.d.ts.map +1 -0
  117. package/dist/core/state.js +42 -0
  118. package/dist/core/state.js.map +1 -0
  119. package/dist/core/templates.d.ts +21 -0
  120. package/dist/core/templates.d.ts.map +1 -0
  121. package/dist/core/templates.js +52 -0
  122. package/dist/core/templates.js.map +1 -0
  123. package/dist/core/watcher.d.ts +72 -0
  124. package/dist/core/watcher.d.ts.map +1 -0
  125. package/dist/core/watcher.js +240 -0
  126. package/dist/core/watcher.js.map +1 -0
  127. package/dist/gemini-commands/dismiss.toml +2 -0
  128. package/dist/gemini-commands/research.toml +2 -0
  129. package/dist/gemini-commands/review.toml +2 -0
  130. package/dist/gemini-commands/update.toml +2 -0
  131. package/dist/index.d.ts +3 -0
  132. package/dist/index.d.ts.map +1 -0
  133. package/dist/index.js +8 -0
  134. package/dist/index.js.map +1 -0
  135. package/dist/schemas/config.d.ts +39 -0
  136. package/dist/schemas/config.d.ts.map +1 -0
  137. package/dist/schemas/config.js +23 -0
  138. package/dist/schemas/config.js.map +1 -0
  139. package/dist/schemas/index.d.ts +6 -0
  140. package/dist/schemas/index.d.ts.map +1 -0
  141. package/dist/schemas/index.js +6 -0
  142. package/dist/schemas/index.js.map +1 -0
  143. package/dist/schemas/item.d.ts +38 -0
  144. package/dist/schemas/item.d.ts.map +1 -0
  145. package/dist/schemas/item.js +34 -0
  146. package/dist/schemas/item.js.map +1 -0
  147. package/dist/schemas/research.d.ts +82 -0
  148. package/dist/schemas/research.d.ts.map +1 -0
  149. package/dist/schemas/research.js +45 -0
  150. package/dist/schemas/research.js.map +1 -0
  151. package/dist/schemas/source.d.ts +139 -0
  152. package/dist/schemas/source.d.ts.map +1 -0
  153. package/dist/schemas/source.js +127 -0
  154. package/dist/schemas/source.js.map +1 -0
  155. package/dist/schemas/state.d.ts +19 -0
  156. package/dist/schemas/state.d.ts.map +1 -0
  157. package/dist/schemas/state.js +12 -0
  158. package/dist/schemas/state.js.map +1 -0
  159. package/dist/skills/research/SKILL.md +156 -0
  160. package/dist/skills/review/SKILL.md +173 -0
  161. package/dist/skills/update/SKILL.md +200 -0
  162. package/dist/templates/agents/AGENTS.md +161 -0
  163. package/dist/templates/claude/CLAUDE.md +5 -0
  164. package/dist/templates/default.md +16 -0
  165. package/dist/templates/feedradar.md +165 -0
  166. package/dist/templates/routines/watch-daily.md +42 -0
  167. package/dist/templates/workflows/watch.yaml +70 -0
  168. package/package.json +73 -0
@@ -0,0 +1,39 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Schema for `radar.config.yaml`, the workspace-level configuration file
4
+ * placed at the workspace root (next to `sources/`, `items/`, etc.).
5
+ *
6
+ * Fields are intentionally minimal in Phase 2; the config is designed to grow
7
+ * one field at a time as new defaults are needed (per [#25] Phase 2 epic).
8
+ *
9
+ * - `defaultResearchAgent`: agent used when `radar research` is run
10
+ * without an explicit `--agent`. Falls through to the hard-coded default
11
+ * (`claude-code`) when unset.
12
+ * - `defaultReviewAgent`: same idea for `radar review`.
13
+ *
14
+ * Out-of-scope (tracked separately):
15
+ * - default agent for `update` (Phase 5)
16
+ * - agent-specific knobs (timeout / API key / etc.)
17
+ */
18
+ export declare const RadarConfigSchema: z.ZodObject<{
19
+ defaultResearchAgent: z.ZodOptional<z.ZodEnum<{
20
+ "claude-code": "claude-code";
21
+ "codex-cli": "codex-cli";
22
+ "gemini-cli": "gemini-cli";
23
+ copilot: "copilot";
24
+ }>>;
25
+ defaultReviewAgent: z.ZodOptional<z.ZodEnum<{
26
+ "claude-code": "claude-code";
27
+ "codex-cli": "codex-cli";
28
+ "gemini-cli": "gemini-cli";
29
+ copilot: "copilot";
30
+ }>>;
31
+ }, z.core.$strip>;
32
+ export type RadarConfig = z.infer<typeof RadarConfigSchema>;
33
+ /**
34
+ * The set of commands for which a default agent can be configured. New
35
+ * commands are added here (rather than to a free-form `string`) so that the
36
+ * resolver below stays exhaustive and TypeScript flags missing branches.
37
+ */
38
+ export type ConfigurableCommand = "research" | "review";
39
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/schemas/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;iBAG5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG,QAAQ,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { z } from "zod";
2
+ import { AgentIdSchema } from "./research.js";
3
+ /**
4
+ * Schema for `radar.config.yaml`, the workspace-level configuration file
5
+ * placed at the workspace root (next to `sources/`, `items/`, etc.).
6
+ *
7
+ * Fields are intentionally minimal in Phase 2; the config is designed to grow
8
+ * one field at a time as new defaults are needed (per [#25] Phase 2 epic).
9
+ *
10
+ * - `defaultResearchAgent`: agent used when `radar research` is run
11
+ * without an explicit `--agent`. Falls through to the hard-coded default
12
+ * (`claude-code`) when unset.
13
+ * - `defaultReviewAgent`: same idea for `radar review`.
14
+ *
15
+ * Out-of-scope (tracked separately):
16
+ * - default agent for `update` (Phase 5)
17
+ * - agent-specific knobs (timeout / API key / etc.)
18
+ */
19
+ export const RadarConfigSchema = z.object({
20
+ defaultResearchAgent: AgentIdSchema.optional(),
21
+ defaultReviewAgent: AgentIdSchema.optional(),
22
+ });
23
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/schemas/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,oBAAoB,EAAE,aAAa,CAAC,QAAQ,EAAE;IAC9C,kBAAkB,EAAE,aAAa,CAAC,QAAQ,EAAE;CAC7C,CAAC,CAAC"}
@@ -0,0 +1,6 @@
1
+ export * from "./config.js";
2
+ export * from "./item.js";
3
+ export * from "./research.js";
4
+ export * from "./source.js";
5
+ export * from "./state.js";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
@@ -0,0 +1,6 @@
1
+ export * from "./config.js";
2
+ export * from "./item.js";
3
+ export * from "./research.js";
4
+ export * from "./source.js";
5
+ export * from "./state.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Item status state machine (ADR-0008).
4
+ *
5
+ * detected ──► (dismissed | researched) ──► reviewed
6
+ *
7
+ * - `detected`: watch run emitted the item after filter
8
+ * - `dismissed`: user decided not to research (terminal)
9
+ * - `researched`: research report written
10
+ * - `reviewed`: research report reviewed (terminal happy path)
11
+ */
12
+ export declare const ItemStatusSchema: z.ZodEnum<{
13
+ detected: "detected";
14
+ dismissed: "dismissed";
15
+ researched: "researched";
16
+ reviewed: "reviewed";
17
+ }>;
18
+ export type ItemStatus = z.infer<typeof ItemStatusSchema>;
19
+ export declare const ItemSchema: z.ZodObject<{
20
+ id: z.ZodString;
21
+ sourceId: z.ZodString;
22
+ title: z.ZodString;
23
+ url: z.ZodString;
24
+ publishedAt: z.ZodOptional<z.ZodString>;
25
+ fetchedAt: z.ZodString;
26
+ summary: z.ZodOptional<z.ZodString>;
27
+ raw: z.ZodOptional<z.ZodUnknown>;
28
+ matchedKeywords: z.ZodDefault<z.ZodArray<z.ZodString>>;
29
+ status: z.ZodDefault<z.ZodEnum<{
30
+ detected: "detected";
31
+ dismissed: "dismissed";
32
+ researched: "researched";
33
+ reviewed: "reviewed";
34
+ }>>;
35
+ injectionFlags: z.ZodDefault<z.ZodArray<z.ZodString>>;
36
+ }, z.core.$strip>;
37
+ export type Item = z.infer<typeof ItemSchema>;
38
+ //# sourceMappingURL=item.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"item.d.ts","sourceRoot":"","sources":["../../src/schemas/item.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB;;;;;EAA8D,CAAC;AAC5F,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;iBAoBrB,CAAC;AACH,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Item status state machine (ADR-0008).
4
+ *
5
+ * detected ──► (dismissed | researched) ──► reviewed
6
+ *
7
+ * - `detected`: watch run emitted the item after filter
8
+ * - `dismissed`: user decided not to research (terminal)
9
+ * - `researched`: research report written
10
+ * - `reviewed`: research report reviewed (terminal happy path)
11
+ */
12
+ export const ItemStatusSchema = z.enum(["detected", "dismissed", "researched", "reviewed"]);
13
+ export const ItemSchema = z.object({
14
+ id: z.string().min(1),
15
+ sourceId: z.string().min(1),
16
+ title: z.string(),
17
+ url: z.string().url(),
18
+ publishedAt: z.string().datetime().optional(),
19
+ fetchedAt: z.string().datetime(),
20
+ summary: z.string().optional(),
21
+ raw: z.unknown().optional(),
22
+ matchedKeywords: z.array(z.string()).default([]),
23
+ status: ItemStatusSchema.default("detected"),
24
+ /**
25
+ * Prompt-injection pattern labels that fired when the watcher scanned
26
+ * `title` / `summary` / `raw` (ADR-0009 M1a — Adopt). Audit-only: a
27
+ * non-empty value does NOT change `status`, sanitize content, or block
28
+ * downstream commands. Existing items written before this field landed
29
+ * default to `[]` thanks to the schema default, so load-side compat is
30
+ * automatic.
31
+ */
32
+ injectionFlags: z.array(z.string()).default([]),
33
+ });
34
+ //# sourceMappingURL=item.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"item.js","sourceRoot":"","sources":["../../src/schemas/item.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC;AAG5F,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACrB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IACrB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC7C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9B,GAAG,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAC3B,eAAe,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAChD,MAAM,EAAE,gBAAgB,CAAC,OAAO,CAAC,UAAU,CAAC;IAC5C;;;;;;;OAOG;IACH,cAAc,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CAChD,CAAC,CAAC"}
@@ -0,0 +1,82 @@
1
+ import { z } from "zod";
2
+ export declare const AgentIdSchema: z.ZodEnum<{
3
+ "claude-code": "claude-code";
4
+ "codex-cli": "codex-cli";
5
+ "gemini-cli": "gemini-cli";
6
+ copilot: "copilot";
7
+ }>;
8
+ export type AgentId = z.infer<typeof AgentIdSchema>;
9
+ /**
10
+ * Frontmatter persisted on disk in `research/<id>.md`.
11
+ *
12
+ * `outputPath` is intentionally **omitted** here: the path is encoded in the
13
+ * filename itself, so storing it in the frontmatter would be redundant and
14
+ * invite drift between the two. Anything that needs the path can construct it
15
+ * from `id` (filename) or read it from the file system. This split keeps the
16
+ * persisted artifact ADR-0003-compliant while letting in-memory orchestration
17
+ * carry the resolved path through `Research`.
18
+ *
19
+ * Phase 1 contract: `reviewedAt` / `reviewedBy` are **always written as
20
+ * `null`** by the `research` command. They become non-null when Phase 2's
21
+ * `review` command stamps the file. See ADR-0003.
22
+ *
23
+ * Phase 5 contract: `supersedes` records the lineage between research file
24
+ * versions. v1 files write `null`; v(N+1) files write the previous version's
25
+ * `id` (filename without the `.md` extension). The field is `null`-defaulted
26
+ * so existing v1 frontmatter generated before Phase 5 (which omits the field
27
+ * entirely) parses without violating the schema. See ADR-0003.
28
+ */
29
+ export declare const ResearchFrontmatterSchema: z.ZodObject<{
30
+ id: z.ZodString;
31
+ itemIds: z.ZodArray<z.ZodString>;
32
+ agent: z.ZodEnum<{
33
+ "claude-code": "claude-code";
34
+ "codex-cli": "codex-cli";
35
+ "gemini-cli": "gemini-cli";
36
+ copilot: "copilot";
37
+ }>;
38
+ templateId: z.ZodString;
39
+ createdAt: z.ZodString;
40
+ updatedAt: z.ZodNullable<z.ZodString>;
41
+ reviewedAt: z.ZodNullable<z.ZodString>;
42
+ reviewedBy: z.ZodNullable<z.ZodEnum<{
43
+ "claude-code": "claude-code";
44
+ "codex-cli": "codex-cli";
45
+ "gemini-cli": "gemini-cli";
46
+ copilot: "copilot";
47
+ }>>;
48
+ supersedes: z.ZodDefault<z.ZodNullable<z.ZodString>>;
49
+ }, z.core.$strip>;
50
+ export type ResearchFrontmatter = z.infer<typeof ResearchFrontmatterSchema>;
51
+ /**
52
+ * In-memory Research record used by the orchestration layer.
53
+ *
54
+ * Extends `ResearchFrontmatter` with `outputPath`, which the CLI needs to
55
+ * pass through to the agent adapter (so the agent knows where to write) and
56
+ * back to the caller (so the CLI can verify the file after the adapter
57
+ * returns). Persisted frontmatter intentionally drops this field.
58
+ */
59
+ export declare const ResearchSchema: z.ZodObject<{
60
+ id: z.ZodString;
61
+ itemIds: z.ZodArray<z.ZodString>;
62
+ agent: z.ZodEnum<{
63
+ "claude-code": "claude-code";
64
+ "codex-cli": "codex-cli";
65
+ "gemini-cli": "gemini-cli";
66
+ copilot: "copilot";
67
+ }>;
68
+ templateId: z.ZodString;
69
+ createdAt: z.ZodString;
70
+ updatedAt: z.ZodNullable<z.ZodString>;
71
+ reviewedAt: z.ZodNullable<z.ZodString>;
72
+ reviewedBy: z.ZodNullable<z.ZodEnum<{
73
+ "claude-code": "claude-code";
74
+ "codex-cli": "codex-cli";
75
+ "gemini-cli": "gemini-cli";
76
+ copilot: "copilot";
77
+ }>>;
78
+ supersedes: z.ZodDefault<z.ZodNullable<z.ZodString>>;
79
+ outputPath: z.ZodString;
80
+ }, z.core.$strip>;
81
+ export type Research = z.infer<typeof ResearchSchema>;
82
+ //# sourceMappingURL=research.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"research.d.ts","sourceRoot":"","sources":["../../src/schemas/research.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,aAAa;;;;;EAAgE,CAAC;AAC3F,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;iBAUpC,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;iBAEzB,CAAC;AACH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC"}
@@ -0,0 +1,45 @@
1
+ import { z } from "zod";
2
+ export const AgentIdSchema = z.enum(["claude-code", "codex-cli", "gemini-cli", "copilot"]);
3
+ /**
4
+ * Frontmatter persisted on disk in `research/<id>.md`.
5
+ *
6
+ * `outputPath` is intentionally **omitted** here: the path is encoded in the
7
+ * filename itself, so storing it in the frontmatter would be redundant and
8
+ * invite drift between the two. Anything that needs the path can construct it
9
+ * from `id` (filename) or read it from the file system. This split keeps the
10
+ * persisted artifact ADR-0003-compliant while letting in-memory orchestration
11
+ * carry the resolved path through `Research`.
12
+ *
13
+ * Phase 1 contract: `reviewedAt` / `reviewedBy` are **always written as
14
+ * `null`** by the `research` command. They become non-null when Phase 2's
15
+ * `review` command stamps the file. See ADR-0003.
16
+ *
17
+ * Phase 5 contract: `supersedes` records the lineage between research file
18
+ * versions. v1 files write `null`; v(N+1) files write the previous version's
19
+ * `id` (filename without the `.md` extension). The field is `null`-defaulted
20
+ * so existing v1 frontmatter generated before Phase 5 (which omits the field
21
+ * entirely) parses without violating the schema. See ADR-0003.
22
+ */
23
+ export const ResearchFrontmatterSchema = z.object({
24
+ id: z.string().min(1),
25
+ itemIds: z.array(z.string().min(1)).min(1),
26
+ agent: AgentIdSchema,
27
+ templateId: z.string().min(1),
28
+ createdAt: z.string().datetime(),
29
+ updatedAt: z.string().datetime().nullable(),
30
+ reviewedAt: z.string().datetime().nullable(),
31
+ reviewedBy: AgentIdSchema.nullable(),
32
+ supersedes: z.string().min(1).nullable().default(null),
33
+ });
34
+ /**
35
+ * In-memory Research record used by the orchestration layer.
36
+ *
37
+ * Extends `ResearchFrontmatter` with `outputPath`, which the CLI needs to
38
+ * pass through to the agent adapter (so the agent knows where to write) and
39
+ * back to the caller (so the CLI can verify the file after the adapter
40
+ * returns). Persisted frontmatter intentionally drops this field.
41
+ */
42
+ export const ResearchSchema = ResearchFrontmatterSchema.extend({
43
+ outputPath: z.string().min(1),
44
+ });
45
+ //# sourceMappingURL=research.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"research.js","sourceRoot":"","sources":["../../src/schemas/research.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC,CAAC;AAG3F;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACrB,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1C,KAAK,EAAE,aAAa;IACpB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC3C,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC5C,UAAU,EAAE,aAAa,CAAC,QAAQ,EAAE;IACpC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;CACvD,CAAC,CAAC;AAGH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,yBAAyB,CAAC,MAAM,CAAC;IAC7D,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CAC9B,CAAC,CAAC"}
@@ -0,0 +1,139 @@
1
+ import { z } from "zod";
2
+ export declare const SourceKindSchema: z.ZodEnum<{
3
+ rss: "rss";
4
+ html: "html";
5
+ "github-releases": "github-releases";
6
+ "npm-registry": "npm-registry";
7
+ }>;
8
+ export type SourceKind = z.infer<typeof SourceKindSchema>;
9
+ /**
10
+ * Match modes for keyword evaluation (ADR-0006).
11
+ *
12
+ * - `word`: whole-word match (`\b<kw>\b`). Default; safest for casual blog feeds.
13
+ * - `substring`: simple substring match. Use for partial-token monitoring.
14
+ * - `regex`: keyword is compiled as a JavaScript RegExp. Invalid patterns throw.
15
+ * Beware ReDoS; users own pattern complexity.
16
+ */
17
+ export declare const MatchModeSchema: z.ZodEnum<{
18
+ word: "word";
19
+ substring: "substring";
20
+ regex: "regex";
21
+ }>;
22
+ export type MatchMode = z.infer<typeof MatchModeSchema>;
23
+ /** Item fields a filter may inspect (ADR-0006). Adapters silently skip fields they cannot supply. */
24
+ export declare const MatchFieldSchema: z.ZodEnum<{
25
+ title: "title";
26
+ summary: "summary";
27
+ body: "body";
28
+ tags: "tags";
29
+ }>;
30
+ export type MatchField = z.infer<typeof MatchFieldSchema>;
31
+ /**
32
+ * Trust level for a Source (ADR-0009 M4).
33
+ *
34
+ * Tags whether the content returned by this source's adapter should be treated
35
+ * as agent-controllable. The default is `"untrusted"` so omitting the field
36
+ * (the only state existing source YAMLs are in) preserves the current
37
+ * defense-in-depth posture: every external feed is treated as adversarial
38
+ * until the user explicitly opts in.
39
+ *
40
+ * This issue only adds the field. Downstream policy branches (regex detection
41
+ * sensitivity, boundary marker strength, prompt builder behavior) land in a
42
+ * separate sub-issue so the schema change is reviewable in isolation.
43
+ */
44
+ export declare const TrustLevelSchema: z.ZodEnum<{
45
+ trusted: "trusted";
46
+ untrusted: "untrusted";
47
+ }>;
48
+ export type TrustLevel = z.infer<typeof TrustLevelSchema>;
49
+ export declare const SourceFiltersSchema: z.ZodObject<{
50
+ keywords: z.ZodDefault<z.ZodArray<z.ZodString>>;
51
+ excludeKeywords: z.ZodDefault<z.ZodArray<z.ZodString>>;
52
+ matchMode: z.ZodDefault<z.ZodEnum<{
53
+ word: "word";
54
+ substring: "substring";
55
+ regex: "regex";
56
+ }>>;
57
+ matchFields: z.ZodDefault<z.ZodArray<z.ZodEnum<{
58
+ title: "title";
59
+ summary: "summary";
60
+ body: "body";
61
+ tags: "tags";
62
+ }>>>;
63
+ caseSensitive: z.ZodDefault<z.ZodBoolean>;
64
+ }, z.core.$strip>;
65
+ export type SourceFilters = z.infer<typeof SourceFiltersSchema>;
66
+ /**
67
+ * CSS selector ruleset for `kind: html` sources.
68
+ *
69
+ * HTML scraping cannot rely on a standard envelope the way RSS/Atom does, so
70
+ * each site declares the selectors needed to locate items and extract fields.
71
+ * The adapter walks every element matched by `item`, then applies the
72
+ * remaining selectors relative to that element.
73
+ *
74
+ * - `item` and `title` are required: without an item boundary or a title we
75
+ * cannot derive a stable id or produce a meaningful `Item`.
76
+ * - `link` is required because `Item.url` is the only field every downstream
77
+ * consumer (research / review / dedup) depends on.
78
+ * - `summary` / `publishedAt` / `body` / `tags` are optional; missing fields
79
+ * simply drop out of the normalized item (mirrors RSS adapter behavior).
80
+ * - `publishedAt` is parsed via `new Date(text)`; the adapter prefers a
81
+ * `datetime` / `content` attribute when the matched element exposes one
82
+ * (e.g. `<time datetime="…">`), falling back to text content.
83
+ *
84
+ * See `docs/design/source-html.md` for the parser choice rationale and the
85
+ * selector contract in full.
86
+ */
87
+ export declare const SourceSelectorsSchema: z.ZodObject<{
88
+ item: z.ZodString;
89
+ title: z.ZodString;
90
+ link: z.ZodString;
91
+ summary: z.ZodOptional<z.ZodString>;
92
+ publishedAt: z.ZodOptional<z.ZodString>;
93
+ body: z.ZodOptional<z.ZodString>;
94
+ tags: z.ZodOptional<z.ZodString>;
95
+ }, z.core.$strip>;
96
+ export type SourceSelectors = z.infer<typeof SourceSelectorsSchema>;
97
+ export declare const SourceSchema: z.ZodObject<{
98
+ id: z.ZodString;
99
+ kind: z.ZodEnum<{
100
+ rss: "rss";
101
+ html: "html";
102
+ "github-releases": "github-releases";
103
+ "npm-registry": "npm-registry";
104
+ }>;
105
+ url: z.ZodString;
106
+ name: z.ZodOptional<z.ZodString>;
107
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
108
+ filters: z.ZodDefault<z.ZodObject<{
109
+ keywords: z.ZodDefault<z.ZodArray<z.ZodString>>;
110
+ excludeKeywords: z.ZodDefault<z.ZodArray<z.ZodString>>;
111
+ matchMode: z.ZodDefault<z.ZodEnum<{
112
+ word: "word";
113
+ substring: "substring";
114
+ regex: "regex";
115
+ }>>;
116
+ matchFields: z.ZodDefault<z.ZodArray<z.ZodEnum<{
117
+ title: "title";
118
+ summary: "summary";
119
+ body: "body";
120
+ tags: "tags";
121
+ }>>>;
122
+ caseSensitive: z.ZodDefault<z.ZodBoolean>;
123
+ }, z.core.$strip>>;
124
+ selectors: z.ZodOptional<z.ZodObject<{
125
+ item: z.ZodString;
126
+ title: z.ZodString;
127
+ link: z.ZodString;
128
+ summary: z.ZodOptional<z.ZodString>;
129
+ publishedAt: z.ZodOptional<z.ZodString>;
130
+ body: z.ZodOptional<z.ZodString>;
131
+ tags: z.ZodOptional<z.ZodString>;
132
+ }, z.core.$strip>>;
133
+ trustLevel: z.ZodDefault<z.ZodEnum<{
134
+ trusted: "trusted";
135
+ untrusted: "untrusted";
136
+ }>>;
137
+ }, z.core.$strip>;
138
+ export type Source = z.infer<typeof SourceSchema>;
139
+ //# sourceMappingURL=source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../../src/schemas/source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,gBAAgB;;;;;EAA6D,CAAC;AAC3F,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe;;;;EAAyC,CAAC;AACtE,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,qGAAqG;AACrG,eAAO,MAAM,gBAAgB;;;;;EAA+C,CAAC;AAC7E,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,gBAAgB;;;EAAmC,CAAC;AACjE,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;iBAM9B,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;iBAQhC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAoBpE,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA2CrB,CAAC;AACL,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC"}
@@ -0,0 +1,127 @@
1
+ import { z } from "zod";
2
+ export const SourceKindSchema = z.enum(["rss", "html", "github-releases", "npm-registry"]);
3
+ /**
4
+ * Match modes for keyword evaluation (ADR-0006).
5
+ *
6
+ * - `word`: whole-word match (`\b<kw>\b`). Default; safest for casual blog feeds.
7
+ * - `substring`: simple substring match. Use for partial-token monitoring.
8
+ * - `regex`: keyword is compiled as a JavaScript RegExp. Invalid patterns throw.
9
+ * Beware ReDoS; users own pattern complexity.
10
+ */
11
+ export const MatchModeSchema = z.enum(["word", "substring", "regex"]);
12
+ /** Item fields a filter may inspect (ADR-0006). Adapters silently skip fields they cannot supply. */
13
+ export const MatchFieldSchema = z.enum(["title", "summary", "body", "tags"]);
14
+ /**
15
+ * Trust level for a Source (ADR-0009 M4).
16
+ *
17
+ * Tags whether the content returned by this source's adapter should be treated
18
+ * as agent-controllable. The default is `"untrusted"` so omitting the field
19
+ * (the only state existing source YAMLs are in) preserves the current
20
+ * defense-in-depth posture: every external feed is treated as adversarial
21
+ * until the user explicitly opts in.
22
+ *
23
+ * This issue only adds the field. Downstream policy branches (regex detection
24
+ * sensitivity, boundary marker strength, prompt builder behavior) land in a
25
+ * separate sub-issue so the schema change is reviewable in isolation.
26
+ */
27
+ export const TrustLevelSchema = z.enum(["trusted", "untrusted"]);
28
+ export const SourceFiltersSchema = z.object({
29
+ keywords: z.array(z.string()).default([]),
30
+ excludeKeywords: z.array(z.string()).default([]),
31
+ matchMode: MatchModeSchema.default("word"),
32
+ matchFields: z.array(MatchFieldSchema).default(["title", "summary"]),
33
+ caseSensitive: z.boolean().default(false),
34
+ });
35
+ /**
36
+ * CSS selector ruleset for `kind: html` sources.
37
+ *
38
+ * HTML scraping cannot rely on a standard envelope the way RSS/Atom does, so
39
+ * each site declares the selectors needed to locate items and extract fields.
40
+ * The adapter walks every element matched by `item`, then applies the
41
+ * remaining selectors relative to that element.
42
+ *
43
+ * - `item` and `title` are required: without an item boundary or a title we
44
+ * cannot derive a stable id or produce a meaningful `Item`.
45
+ * - `link` is required because `Item.url` is the only field every downstream
46
+ * consumer (research / review / dedup) depends on.
47
+ * - `summary` / `publishedAt` / `body` / `tags` are optional; missing fields
48
+ * simply drop out of the normalized item (mirrors RSS adapter behavior).
49
+ * - `publishedAt` is parsed via `new Date(text)`; the adapter prefers a
50
+ * `datetime` / `content` attribute when the matched element exposes one
51
+ * (e.g. `<time datetime="…">`), falling back to text content.
52
+ *
53
+ * See `docs/design/source-html.md` for the parser choice rationale and the
54
+ * selector contract in full.
55
+ */
56
+ export const SourceSelectorsSchema = z.object({
57
+ item: z.string().min(1),
58
+ title: z.string().min(1),
59
+ link: z.string().min(1),
60
+ summary: z.string().optional(),
61
+ publishedAt: z.string().optional(),
62
+ body: z.string().optional(),
63
+ tags: z.string().optional(),
64
+ });
65
+ /**
66
+ * Validate `Source.url` per kind.
67
+ *
68
+ * Every kind except `npm-registry` requires a fully-qualified `http(s)` URL.
69
+ * The npm adapter accepts both the bare-package form (`@scope/pkg` or `pkg`)
70
+ * and the `https://www.npmjs.com/package/<pkg>` URL — see ADR-0002 — so we
71
+ * only enforce non-empty for that kind and let the adapter
72
+ * (`extractPackageName()`) canonicalize.
73
+ */
74
+ function isValidHttpUrl(value) {
75
+ try {
76
+ const parsed = new URL(value);
77
+ return parsed.protocol === "http:" || parsed.protocol === "https:";
78
+ }
79
+ catch {
80
+ return false;
81
+ }
82
+ }
83
+ export const SourceSchema = z
84
+ .object({
85
+ id: z.string().min(1),
86
+ kind: SourceKindSchema,
87
+ url: z.string().min(1),
88
+ name: z.string().optional(),
89
+ tags: z.array(z.string()).default([]),
90
+ // Default `filters` to a fully-populated object so a source missing the
91
+ // entire `filters` block still parses. Zod 4's `.default()` takes the
92
+ // post-parse output (all required fields), so we cannot pass `{}`.
93
+ filters: SourceFiltersSchema.default({
94
+ keywords: [],
95
+ excludeKeywords: [],
96
+ matchMode: "word",
97
+ matchFields: ["title", "summary"],
98
+ caseSensitive: false,
99
+ }),
100
+ // `selectors` is required for `kind: html` and ignored for the other
101
+ // kinds. We model it as optional at the field level and enforce the
102
+ // "required when html" rule via a refinement so the same Source type
103
+ // serializes cleanly for both cases.
104
+ selectors: SourceSelectorsSchema.optional(),
105
+ // `trustLevel` defaults to `"untrusted"` so existing source YAMLs (which
106
+ // omit the field entirely) keep their current treatment. Per ADR-0009 M4
107
+ // this is schema-only; policy branches that read `trustLevel` arrive in a
108
+ // separate sub-issue.
109
+ trustLevel: TrustLevelSchema.default("untrusted"),
110
+ })
111
+ .superRefine((value, ctx) => {
112
+ if (value.kind !== "npm-registry" && !isValidHttpUrl(value.url)) {
113
+ ctx.addIssue({
114
+ code: "custom",
115
+ path: ["url"],
116
+ message: "Invalid url",
117
+ });
118
+ }
119
+ if (value.kind === "html" && value.selectors === undefined) {
120
+ ctx.addIssue({
121
+ code: "custom",
122
+ path: ["selectors"],
123
+ message: "selectors is required when kind is 'html'",
124
+ });
125
+ }
126
+ });
127
+ //# sourceMappingURL=source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source.js","sourceRoot":"","sources":["../../src/schemas/source.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { z } from "zod";
2
+ export declare const SourceStateSchema: z.ZodObject<{
3
+ sourceId: z.ZodString;
4
+ lastFetchedAt: z.ZodOptional<z.ZodString>;
5
+ lastEtag: z.ZodOptional<z.ZodString>;
6
+ lastSeenIds: z.ZodDefault<z.ZodArray<z.ZodString>>;
7
+ }, z.core.$strip>;
8
+ export type SourceState = z.infer<typeof SourceStateSchema>;
9
+ export declare const StateFileSchema: z.ZodObject<{
10
+ version: z.ZodLiteral<1>;
11
+ sources: z.ZodDefault<z.ZodArray<z.ZodObject<{
12
+ sourceId: z.ZodString;
13
+ lastFetchedAt: z.ZodOptional<z.ZodString>;
14
+ lastEtag: z.ZodOptional<z.ZodString>;
15
+ lastSeenIds: z.ZodDefault<z.ZodArray<z.ZodString>>;
16
+ }, z.core.$strip>>>;
17
+ }, z.core.$strip>;
18
+ export type StateFile = z.infer<typeof StateFileSchema>;
19
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/schemas/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,iBAAiB;;;;;iBAK5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,eAAO,MAAM,eAAe;;;;;;;;iBAG1B,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { z } from "zod";
2
+ export const SourceStateSchema = z.object({
3
+ sourceId: z.string().min(1),
4
+ lastFetchedAt: z.string().datetime().optional(),
5
+ lastEtag: z.string().optional(),
6
+ lastSeenIds: z.array(z.string()).default([]),
7
+ });
8
+ export const StateFileSchema = z.object({
9
+ version: z.literal(1),
10
+ sources: z.array(SourceStateSchema).default([]),
11
+ });
12
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/schemas/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3B,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC/C,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CAC7C,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IACrB,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CAChD,CAAC,CAAC"}