@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,578 @@
1
+ import { access, copyFile, mkdir, writeFile } from "node:fs/promises";
2
+ import { dirname, join, resolve } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ /**
5
+ * Resolve the directory holding the bundled skill assets (`dist/skills/`).
6
+ *
7
+ * The compiled CLI lives at `dist/cli/init.js`, so the bundled skills sit at
8
+ * `../skills` relative to this module. During tests we may be running from
9
+ * source (`src/cli/init.ts`), so we also fall back to `src/skills/` if the
10
+ * compiled location does not exist.
11
+ */
12
+ async function resolveSkillsRoot() {
13
+ const here = dirname(fileURLToPath(import.meta.url));
14
+ // Compiled layout: dist/cli/init.js -> dist/skills
15
+ const compiled = resolve(here, "../skills");
16
+ if (await pathExists(compiled)) {
17
+ return compiled;
18
+ }
19
+ // Source layout fallback: src/cli/init.ts -> src/skills (used by tests run on .ts).
20
+ const source = resolve(here, "../skills");
21
+ return source;
22
+ }
23
+ /** Same resolution strategy as `resolveSkillsRoot`, but for `src|dist/templates`. */
24
+ async function resolveTemplatesRoot() {
25
+ const here = dirname(fileURLToPath(import.meta.url));
26
+ const compiled = resolve(here, "../templates");
27
+ if (await pathExists(compiled)) {
28
+ return compiled;
29
+ }
30
+ return resolve(here, "../templates");
31
+ }
32
+ /**
33
+ * Resolve the directory holding the bundled Claude Code slash-command
34
+ * wrappers (`dist/claude-skills/`).
35
+ *
36
+ * These are distinct from the engine SKILLs at `dist/skills/`. The engine
37
+ * SKILLs land at `<cwd>/.agents/skills/<name>/SKILL.md` and are read by the
38
+ * agent adapter when the CLI spawns claude/codex/gemini/copilot. The Claude
39
+ * discovery skills land at `<cwd>/.claude/skills/<name>/SKILL.md` so that
40
+ * Claude Code, when opened in the workspace, surfaces `/research` /
41
+ * `/review` / `/update` / `/dismiss` as invocable slash commands. The
42
+ * discovery skills are thin wrappers — they shell out to the `radar`
43
+ * CLI rather than duplicating the engine procedure.
44
+ *
45
+ * See ADR-0007 (revised 2026-05-17) for the policy and `docs/design/
46
+ * skill-design.md` for the SSoT vs discovery layering rationale.
47
+ */
48
+ async function resolveClaudeSkillsRoot() {
49
+ const here = dirname(fileURLToPath(import.meta.url));
50
+ const compiled = resolve(here, "../claude-skills");
51
+ if (await pathExists(compiled)) {
52
+ return compiled;
53
+ }
54
+ return resolve(here, "../claude-skills");
55
+ }
56
+ /**
57
+ * Resolve the directory holding the bundled Gemini CLI slash command TOMLs
58
+ * (`dist/gemini-commands/`).
59
+ *
60
+ * These are distinct from the engine SKILLs at `dist/skills/` and the Claude
61
+ * Code discovery wrappers at `dist/claude-skills/`. Gemini CLI surfaces slash
62
+ * commands from `.gemini/commands/<name>.toml` (TOML format with `prompt` and
63
+ * `description` keys). The bundled TOMLs are thin wrappers — they tell Gemini
64
+ * to shell out to the `radar` CLI with `{{args}}` interpolation; the
65
+ * canonical procedure stays in the engine SKILLs (SSoT) under
66
+ * `.agents/skills/`.
67
+ *
68
+ * See ADR-0007 (revised 2026-05-17 c) for the five-layer init bundle and the
69
+ * cross-agent slash-command parity rationale.
70
+ */
71
+ async function resolveGeminiCommandsRoot() {
72
+ const here = dirname(fileURLToPath(import.meta.url));
73
+ const compiled = resolve(here, "../gemini-commands");
74
+ if (await pathExists(compiled)) {
75
+ return compiled;
76
+ }
77
+ return resolve(here, "../gemini-commands");
78
+ }
79
+ async function pathExists(p) {
80
+ try {
81
+ await access(p);
82
+ return true;
83
+ }
84
+ catch {
85
+ return false;
86
+ }
87
+ }
88
+ const WORKSPACE_DIRS = ["sources", "state", "items", "research", "templates"];
89
+ /**
90
+ * Data directories that receive a `.gitkeep` placeholder so the empty
91
+ * directory survives an initial `git add .` commit.
92
+ *
93
+ * AGENTS.md's "データ管理ポリシー" recommends committing `sources/` / `items/`
94
+ * / `state/` / `research/` to git (state preservation for scheduled runs,
95
+ * audit trail for research history). Git does not track empty directories,
96
+ * so without a placeholder, a user who runs `init` and then `git add .`
97
+ * loses the directory layout entirely.
98
+ *
99
+ * `templates/` is intentionally excluded — the bundled `default.md` ships
100
+ * via a separate `init` codepath (see ADR-0007 follow-up) and serves as
101
+ * its own placeholder.
102
+ */
103
+ const GITKEEP_DIRS = ["sources", "items", "state", "research"];
104
+ /**
105
+ * Engine SKILLs (SSoT): canonical procedure documents that the agent adapter
106
+ * reads when the CLI spawns claude/codex/gemini/copilot. They land at
107
+ * `<cwd>/.agents/skills/<name>/SKILL.md`.
108
+ */
109
+ const BUNDLED_SKILLS = ["research", "review", "update"];
110
+ /**
111
+ * Claude Code discovery SKILLs: thin slash-command wrappers that surface
112
+ * `/research` / `/review` / `/update` / `/dismiss` inside Claude Code
113
+ * interactive sessions opened in the workspace. They land at
114
+ * `<cwd>/.claude/skills/<name>/SKILL.md` and delegate to the `radar`
115
+ * CLI; they do not duplicate the engine procedure.
116
+ *
117
+ * Note `dismiss` is here but NOT in `BUNDLED_SKILLS` — the dismiss command
118
+ * does not invoke an agent (no LLM call), so there is no engine SKILL for
119
+ * it. The slash-command wrapper is purely a UX affordance for Claude Code
120
+ * users (vs typing `radar dismiss` in a terminal).
121
+ *
122
+ * See ADR-0007 (revised 2026-05-17) for the SSoT vs discovery split.
123
+ */
124
+ const CLAUDE_DISCOVERY_SKILLS = ["research", "review", "update", "dismiss"];
125
+ /**
126
+ * Gemini CLI slash commands: thin TOML wrappers that surface `/research` /
127
+ * `/review` / `/update` / `/dismiss` inside Gemini CLI interactive sessions
128
+ * opened in the workspace. They land at `<cwd>/.gemini/commands/<name>.toml`
129
+ * and delegate to the `radar` CLI via `{{args}}` interpolation; they
130
+ * do not duplicate the engine procedure.
131
+ *
132
+ * Note `dismiss` is here but NOT in `BUNDLED_SKILLS` — the dismiss command
133
+ * does not invoke an agent (no LLM call), so there is no engine SKILL for
134
+ * it. The TOML is purely a UX affordance for Gemini CLI users.
135
+ *
136
+ * See ADR-0007 (revised 2026-05-17 c) for the five-layer init bundle and the
137
+ * cross-agent slash-command parity rationale (#78).
138
+ */
139
+ const GEMINI_COMMANDS = ["research", "review", "update", "dismiss"];
140
+ /**
141
+ * Schedule scaffolds that `init` may emit on opt-in flags.
142
+ *
143
+ * - `src`: bundled template path under `<templatesRoot>/`
144
+ * - `dest`: where the file lands in the user's workspace
145
+ *
146
+ * See ADR-0004 for the policy: `radar` does not run schedules
147
+ * itself; these scaffolds wire it into Claude Routines / GitHub Actions.
148
+ */
149
+ const SCHEDULE_SCAFFOLDS = {
150
+ routines: {
151
+ src: "routines/watch-daily.md",
152
+ dest: ["claude", "routines", "watch-daily.md"],
153
+ },
154
+ actions: {
155
+ src: "workflows/watch.yaml",
156
+ dest: [".github", "workflows", "watch.yaml"],
157
+ },
158
+ };
159
+ /**
160
+ * Bundled agent-agnostic instructions file emitted by default at the
161
+ * workspace root. Codex CLI / Gemini CLI / GitHub Copilot CLI auto-read
162
+ * `AGENTS.md` from project root; Claude Code does not, but the standard
163
+ * pattern is `CLAUDE.md` → `@AGENTS.md` include.
164
+ *
165
+ * See ADR-0007 (revised 2026-05-17 b) for the four-layer init bundle.
166
+ */
167
+ const AGENTS_MD_SCAFFOLD = {
168
+ src: "agents/AGENTS.md",
169
+ dest: ["AGENTS.md"],
170
+ };
171
+ /**
172
+ * Bundled minimal Claude Code workspace instructions emitted by default at
173
+ * the workspace root. The template re-exports `AGENTS.md` via the
174
+ * `@AGENTS.md` import directive so that the SSoT for cross-agent
175
+ * instructions stays in `AGENTS.md` while Claude Code (which does NOT
176
+ * auto-read `AGENTS.md`) still gets the workspace context the moment a
177
+ * user opens an interactive session.
178
+ *
179
+ * When `--no-agents-md` is also passed, the `@AGENTS.md` import would
180
+ * dangle, so `init` auto-skips this scaffold (emit a warning).
181
+ *
182
+ * See ADR-0007 (revised 2026-05-17 b) for the multi-layer init bundle.
183
+ */
184
+ const CLAUDE_MD_SCAFFOLD = {
185
+ src: "claude/CLAUDE.md",
186
+ dest: ["CLAUDE.md"],
187
+ };
188
+ /**
189
+ * Bundled starter Markdown template emitted by default into
190
+ * `<cwd>/templates/default.md`. The body mirrors the engine `research`
191
+ * SKILL's fallback structure (要約 / 詳細 / 出典) so editing it has an
192
+ * immediately predictable effect on generated reports.
193
+ *
194
+ * Note the template stores the **body only** — no frontmatter. The
195
+ * research engine SKILL constructs `ResearchFrontmatter` itself per
196
+ * ADR-0003 and appends the templateBody as the report body. Including
197
+ * frontmatter here would conflict with that contract.
198
+ *
199
+ * See ADR-0007 (revised 2026-05-17) for the init bundle layering and
200
+ * `src/skills/research/SKILL.md` §3 for the template body contract.
201
+ */
202
+ const DEFAULT_TEMPLATE_SCAFFOLD = {
203
+ src: "default.md",
204
+ dest: ["templates", "default.md"],
205
+ };
206
+ /**
207
+ * Bundled human-facing workspace guide emitted by default at the workspace
208
+ * root. Distinct from `AGENTS.md` / `CLAUDE.md`, which are AI-agent-facing
209
+ * instruction files auto-read by the respective CLIs. `FEEDRADAR.md`
210
+ * is for the human who ran `init` and needs to learn what they can do in
211
+ * this workspace — with skills-based / natural-language agent invocation
212
+ * as the primary path and CLI direct invocation as the secondary
213
+ * (scheduler / CI) path.
214
+ *
215
+ * Named `FEEDRADAR.md` (not `README.md`) so it does not collide with
216
+ * a workspace that already has its own README, and so its purpose is
217
+ * obvious from the filename. Same warning+skip + `--force` overwrite
218
+ * policy as all other bundled files.
219
+ */
220
+ const FEEDRADAR_MD_SCAFFOLD = {
221
+ src: "feedradar.md",
222
+ dest: ["FEEDRADAR.md"],
223
+ };
224
+ /**
225
+ * Initialize the current directory as a FeedRadar workspace.
226
+ *
227
+ * Creates the canonical workspace directories and copies bundled SKILL.md
228
+ * files into `.agents/skills/<name>/SKILL.md`. Existing files are protected
229
+ * unless `force` is true.
230
+ *
231
+ * Claude Code discoverability (ADR-0007, revised 2026-05-17 via #75): in
232
+ * addition to the engine SKILLs at `.agents/skills/`, `init` also writes
233
+ * thin slash-command wrappers to `.claude/skills/` so that Claude Code,
234
+ * when opened interactively in the workspace, surfaces `/research` /
235
+ * `/review` / `/update` / `/dismiss`. The wrappers delegate to the
236
+ * `radar` CLI rather than duplicating the engine procedure (the
237
+ * engine SKILL at `.agents/skills/<name>/SKILL.md` remains the SSoT).
238
+ * Existing files are protected, so workspaces that already manage
239
+ * `.claude/skills/` via the `@ozzylabs/skills` Renovate preset won't be
240
+ * surprised; alternatively use `--no-claude-skills` to skip the discovery
241
+ * layer entirely.
242
+ *
243
+ * Multi-agent context (ADR-0007, revised 2026-05-17 b via #77): `init`
244
+ * also writes an agent-agnostic `AGENTS.md` at the workspace root. Codex
245
+ * CLI, Gemini CLI, and GitHub Copilot CLI auto-read this file when opened
246
+ * interactively in the workspace, giving those agents context about
247
+ * available commands, typical workflow, and docs pointers without any
248
+ * extra setup. Opt out via `--no-agents-md` (workspaces that already have
249
+ * their own AGENTS.md).
250
+ *
251
+ * Gemini CLI slash commands (ADR-0007, revised 2026-05-17 c via #78):
252
+ * `init` writes Gemini CLI's native slash command TOMLs at
253
+ * `<cwd>/.gemini/commands/{research,review,update,dismiss}.toml`. These
254
+ * thin wrappers shell out to the `radar` CLI through Gemini's
255
+ * `{{args}}` interpolation, surfacing `/research` etc. inside Gemini CLI
256
+ * interactive sessions. Opt out via `--no-gemini-commands` (engine SKILLs
257
+ * remain in place via the dual-mode "Invocation modes" fallback). This
258
+ * closes the slash-command UX gap for Gemini CLI (Codex CLI is covered by
259
+ * the engine SKILL dual-mode procedure itself).
260
+ */
261
+ export async function initWorkspace(options) {
262
+ const { cwd, force } = options;
263
+ const warn = options.warn ?? ((m) => console.warn(m));
264
+ const info = options.info ?? ((m) => console.log(m));
265
+ const createdDirs = [];
266
+ const copiedFiles = [];
267
+ const skippedFiles = [];
268
+ for (const dir of WORKSPACE_DIRS) {
269
+ const abs = join(cwd, dir);
270
+ await mkdir(abs, { recursive: true });
271
+ createdDirs.push(dir);
272
+ }
273
+ // Place a `.gitkeep` in each data directory so an empty workspace survives
274
+ // the user's first `git add .`. AGENTS.md's "データ管理ポリシー" recommends
275
+ // committing these directories (state preservation across scheduled runs,
276
+ // audit trail), which is impossible without a tracked placeholder file.
277
+ //
278
+ // Always create when missing, regardless of `--force` — a 0-byte placeholder
279
+ // has no user content worth protecting. Existing `.gitkeep` files (or any
280
+ // other content the user may have placed at that path) are left untouched
281
+ // to avoid surprising overwrites.
282
+ for (const dir of GITKEEP_DIRS) {
283
+ const gitkeepPath = join(cwd, dir, ".gitkeep");
284
+ if (await pathExists(gitkeepPath)) {
285
+ continue;
286
+ }
287
+ await writeFile(gitkeepPath, "", "utf8");
288
+ copiedFiles.push(`${dir}/.gitkeep`);
289
+ }
290
+ const skillsRoot = options.skillsRoot ?? (await resolveSkillsRoot());
291
+ for (const skill of BUNDLED_SKILLS) {
292
+ const src = join(skillsRoot, skill, "SKILL.md");
293
+ const destDir = join(cwd, ".agents", "skills", skill);
294
+ const dest = join(destDir, "SKILL.md");
295
+ await mkdir(destDir, { recursive: true });
296
+ if (!(await pathExists(src))) {
297
+ warn(`init: bundled skill not found, skipped: ${src}`);
298
+ skippedFiles.push(`.agents/skills/${skill}/SKILL.md`);
299
+ continue;
300
+ }
301
+ if ((await pathExists(dest)) && !force) {
302
+ warn(`init: skipped existing file (use --force to overwrite): .agents/skills/${skill}/SKILL.md`);
303
+ skippedFiles.push(`.agents/skills/${skill}/SKILL.md`);
304
+ continue;
305
+ }
306
+ await copyFile(src, dest);
307
+ copiedFiles.push(`.agents/skills/${skill}/SKILL.md`);
308
+ }
309
+ if (!options.noClaudeSkills) {
310
+ const claudeSkillsRoot = options.claudeSkillsRoot ?? (await resolveClaudeSkillsRoot());
311
+ for (const skill of CLAUDE_DISCOVERY_SKILLS) {
312
+ const src = join(claudeSkillsRoot, skill, "SKILL.md");
313
+ const destDir = join(cwd, ".claude", "skills", skill);
314
+ const dest = join(destDir, "SKILL.md");
315
+ await mkdir(destDir, { recursive: true });
316
+ if (!(await pathExists(src))) {
317
+ warn(`init: bundled claude discovery skill not found, skipped: ${src}`);
318
+ skippedFiles.push(`.claude/skills/${skill}/SKILL.md`);
319
+ continue;
320
+ }
321
+ if ((await pathExists(dest)) && !force) {
322
+ warn(`init: skipped existing file (use --force to overwrite): .claude/skills/${skill}/SKILL.md`);
323
+ skippedFiles.push(`.claude/skills/${skill}/SKILL.md`);
324
+ continue;
325
+ }
326
+ await copyFile(src, dest);
327
+ copiedFiles.push(`.claude/skills/${skill}/SKILL.md`);
328
+ }
329
+ }
330
+ if (!options.noGeminiCommands) {
331
+ const geminiCommandsRoot = options.geminiCommandsRoot ?? (await resolveGeminiCommandsRoot());
332
+ for (const command of GEMINI_COMMANDS) {
333
+ const src = join(geminiCommandsRoot, `${command}.toml`);
334
+ const destDir = join(cwd, ".gemini", "commands");
335
+ const dest = join(destDir, `${command}.toml`);
336
+ await mkdir(destDir, { recursive: true });
337
+ if (!(await pathExists(src))) {
338
+ warn(`init: bundled gemini command not found, skipped: ${src}`);
339
+ skippedFiles.push(`.gemini/commands/${command}.toml`);
340
+ continue;
341
+ }
342
+ if ((await pathExists(dest)) && !force) {
343
+ warn(`init: skipped existing file (use --force to overwrite): .gemini/commands/${command}.toml`);
344
+ skippedFiles.push(`.gemini/commands/${command}.toml`);
345
+ continue;
346
+ }
347
+ await copyFile(src, dest);
348
+ copiedFiles.push(`.gemini/commands/${command}.toml`);
349
+ }
350
+ }
351
+ if (!options.noAgentsMd) {
352
+ await emitScaffold({
353
+ cwd,
354
+ force,
355
+ templatesRoot: options.templatesRoot,
356
+ scaffold: AGENTS_MD_SCAFFOLD,
357
+ copiedFiles,
358
+ skippedFiles,
359
+ warn,
360
+ });
361
+ }
362
+ // CLAUDE.md is auto-skipped when AGENTS.md is also skipped, because the
363
+ // bundled CLAUDE.md template re-exports AGENTS.md via `@AGENTS.md` and
364
+ // that import would otherwise dangle. Users who want CLAUDE.md without
365
+ // AGENTS.md should manage CLAUDE.md themselves.
366
+ if (!options.noClaudeMd) {
367
+ if (options.noAgentsMd) {
368
+ warn("init: skipped CLAUDE.md because --no-agents-md was passed (the bundled CLAUDE.md imports @AGENTS.md and would dangle)");
369
+ skippedFiles.push("CLAUDE.md");
370
+ }
371
+ else {
372
+ await emitScaffold({
373
+ cwd,
374
+ force,
375
+ templatesRoot: options.templatesRoot,
376
+ scaffold: CLAUDE_MD_SCAFFOLD,
377
+ copiedFiles,
378
+ skippedFiles,
379
+ warn,
380
+ });
381
+ }
382
+ }
383
+ if (!options.noTemplates) {
384
+ await emitScaffold({
385
+ cwd,
386
+ force,
387
+ templatesRoot: options.templatesRoot,
388
+ scaffold: DEFAULT_TEMPLATE_SCAFFOLD,
389
+ copiedFiles,
390
+ skippedFiles,
391
+ warn,
392
+ });
393
+ }
394
+ if (!options.noFeedradarMd) {
395
+ await emitScaffold({
396
+ cwd,
397
+ force,
398
+ templatesRoot: options.templatesRoot,
399
+ scaffold: FEEDRADAR_MD_SCAFFOLD,
400
+ copiedFiles,
401
+ skippedFiles,
402
+ warn,
403
+ });
404
+ }
405
+ if (options.withRoutines) {
406
+ await emitScaffold({
407
+ cwd,
408
+ force,
409
+ templatesRoot: options.templatesRoot,
410
+ scaffold: SCHEDULE_SCAFFOLDS.routines,
411
+ copiedFiles,
412
+ skippedFiles,
413
+ warn,
414
+ });
415
+ }
416
+ if (options.withActions) {
417
+ await emitScaffold({
418
+ cwd,
419
+ force,
420
+ templatesRoot: options.templatesRoot,
421
+ scaffold: SCHEDULE_SCAFFOLDS.actions,
422
+ copiedFiles,
423
+ skippedFiles,
424
+ warn,
425
+ });
426
+ }
427
+ info(`init: workspace ready at ${cwd}`);
428
+ info(`init: directories created: ${createdDirs.join(", ")}`);
429
+ if (copiedFiles.length > 0) {
430
+ info(`init: skills copied: ${copiedFiles.join(", ")}`);
431
+ }
432
+ if (skippedFiles.length > 0) {
433
+ info(`init: files skipped: ${skippedFiles.join(", ")}`);
434
+ }
435
+ // Next-step hint: FEEDRADAR.md is the canonical entry point for the
436
+ // human who just ran init. Point them at it (when present) so they don't
437
+ // have to hunt for usage docs. Skip the hint when the file wasn't written
438
+ // (workspace owner chose --no-feedradar-md or pre-existing protected).
439
+ if (copiedFiles.includes("FEEDRADAR.md")) {
440
+ info("init: next steps — read FEEDRADAR.md for natural-language and slash usage.");
441
+ }
442
+ return { createdDirs, copiedFiles, skippedFiles };
443
+ }
444
+ /**
445
+ * Copy one bundled schedule scaffold into `cwd`. Existing files are protected
446
+ * unless `force` is true (mirrors the bundled-skills path).
447
+ */
448
+ async function emitScaffold(args) {
449
+ const { cwd, force, scaffold, copiedFiles, skippedFiles, warn } = args;
450
+ const templatesRoot = args.templatesRoot ?? (await resolveTemplatesRoot());
451
+ const src = join(templatesRoot, scaffold.src);
452
+ const dest = join(cwd, ...scaffold.dest);
453
+ const relDest = scaffold.dest.join("/");
454
+ if (!(await pathExists(src))) {
455
+ warn(`init: bundled template not found, skipped: ${src}`);
456
+ skippedFiles.push(relDest);
457
+ return;
458
+ }
459
+ await mkdir(dirname(dest), { recursive: true });
460
+ if ((await pathExists(dest)) && !force) {
461
+ warn(`init: skipped existing file (use --force to overwrite): ${relDest}`);
462
+ skippedFiles.push(relDest);
463
+ return;
464
+ }
465
+ await copyFile(src, dest);
466
+ copiedFiles.push(relDest);
467
+ }
468
+ function parseArgs(args) {
469
+ let force = false;
470
+ let withRoutines = false;
471
+ let withActions = false;
472
+ let noClaudeSkills = false;
473
+ let noGeminiCommands = false;
474
+ let noAgentsMd = false;
475
+ let noClaudeMd = false;
476
+ let noTemplates = false;
477
+ let noFeedradarMd = false;
478
+ let help = false;
479
+ for (const arg of args) {
480
+ if (arg === "--force" || arg === "-f") {
481
+ force = true;
482
+ }
483
+ else if (arg === "--with-routines") {
484
+ withRoutines = true;
485
+ }
486
+ else if (arg === "--with-actions") {
487
+ withActions = true;
488
+ }
489
+ else if (arg === "--no-claude-skills") {
490
+ noClaudeSkills = true;
491
+ }
492
+ else if (arg === "--no-gemini-commands") {
493
+ noGeminiCommands = true;
494
+ }
495
+ else if (arg === "--no-agents-md") {
496
+ noAgentsMd = true;
497
+ }
498
+ else if (arg === "--no-claude-md") {
499
+ noClaudeMd = true;
500
+ }
501
+ else if (arg === "--no-templates") {
502
+ noTemplates = true;
503
+ }
504
+ else if (arg === "--no-feedradar-md") {
505
+ noFeedradarMd = true;
506
+ }
507
+ else if (arg === "-h" || arg === "--help") {
508
+ help = true;
509
+ }
510
+ }
511
+ return {
512
+ force,
513
+ withRoutines,
514
+ withActions,
515
+ noClaudeSkills,
516
+ noGeminiCommands,
517
+ noAgentsMd,
518
+ noClaudeMd,
519
+ noTemplates,
520
+ noFeedradarMd,
521
+ help,
522
+ };
523
+ }
524
+ export const initCommand = {
525
+ name: "init",
526
+ summary: "Initialize a workspace (sources/items/state/research/templates)",
527
+ run: async (args) => {
528
+ const { force, withRoutines, withActions, noClaudeSkills, noGeminiCommands, noAgentsMd, noClaudeMd, noTemplates, noFeedradarMd, help, } = parseArgs(args);
529
+ if (help) {
530
+ console.log("Usage: radar init [--force] [--with-routines] [--with-actions]");
531
+ console.log(" [--no-claude-skills] [--no-gemini-commands]");
532
+ console.log(" [--no-agents-md] [--no-claude-md] [--no-templates]");
533
+ console.log(" [--no-feedradar-md]");
534
+ console.log("");
535
+ console.log("Creates the workspace directories and copies bundled skills:");
536
+ console.log(" - Engine SKILLs (SSoT): .agents/skills/{research,review,update}/SKILL.md");
537
+ console.log(" - Claude Code slash-command wrappers: .claude/skills/{research,review,update,dismiss}/SKILL.md");
538
+ console.log(" - Gemini CLI slash commands: .gemini/commands/{research,review,update,dismiss}.toml");
539
+ console.log(" - Agent-agnostic instructions: AGENTS.md (auto-read by Codex / Gemini / Copilot)");
540
+ console.log(" - Claude Code workspace instructions: CLAUDE.md (imports @AGENTS.md so Claude reads it)");
541
+ console.log(" - Starter report template: templates/default.md (editable; mirrors research SKILL fallback)");
542
+ console.log(" - Human-facing workspace guide: FEEDRADAR.md (natural-language / slash usage)");
543
+ console.log("");
544
+ console.log("Options:");
545
+ console.log(" --force Overwrite existing files");
546
+ console.log(" --with-routines Generate claude/routines/watch-daily.md (Claude Routines scaffold)");
547
+ console.log(" --with-actions Generate .github/workflows/watch.yaml (GitHub Actions cron scaffold)");
548
+ console.log(" --no-claude-skills Skip writing slash-command wrappers to .claude/skills/");
549
+ console.log(" (useful if @ozzylabs/skills Renovate preset manages that directory)");
550
+ console.log(" --no-gemini-commands Skip writing Gemini CLI slash commands to .gemini/commands/");
551
+ console.log(" (engine SKILLs still serve interactive Gemini via dual-mode)");
552
+ console.log(" --no-agents-md Skip writing AGENTS.md at the workspace root");
553
+ console.log(" (useful if the workspace already has its own AGENTS.md;");
554
+ console.log(" implies --no-claude-md since the bundled CLAUDE.md imports @AGENTS.md)");
555
+ console.log(" --no-claude-md Skip writing CLAUDE.md at the workspace root");
556
+ console.log(" (useful if the workspace already has its own CLAUDE.md)");
557
+ console.log(" --no-templates Skip writing templates/default.md starter template");
558
+ console.log(" (research engine SKILL falls back to its built-in structure)");
559
+ console.log(" --no-feedradar-md Skip writing FEEDRADAR.md at the workspace root");
560
+ console.log(" (useful if the workspace already has its own user-facing docs)");
561
+ return 0;
562
+ }
563
+ await initWorkspace({
564
+ cwd: process.cwd(),
565
+ force,
566
+ withRoutines,
567
+ withActions,
568
+ noClaudeSkills,
569
+ noGeminiCommands,
570
+ noAgentsMd,
571
+ noClaudeMd,
572
+ noTemplates,
573
+ noFeedradarMd,
574
+ });
575
+ return 0;
576
+ },
577
+ };
578
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { Command } from "./index.js";
2
+ /** Sinks for the research command's user-facing output. Tests inject capturing sinks. */
3
+ export interface ResearchIO {
4
+ log?: (message: string) => void;
5
+ warn?: (message: string) => void;
6
+ error?: (message: string) => void;
7
+ }
8
+ export interface ResearchCommandOptions {
9
+ cwd?: string;
10
+ io?: ResearchIO;
11
+ }
12
+ /**
13
+ * Implementation of `radar research <item-id>`.
14
+ *
15
+ * High-level flow (Phase 1):
16
+ * 1. Parse + validate args (agent defaults to `claude-code`, template to `default`).
17
+ * 2. Locate `items/<sourceId>/<item-id>.yaml` and parse it.
18
+ * 3. Load `templates/<template-id>.md` (empty body when default is absent).
19
+ * 4. Compute `research/<YYYYMMDD>_<slug>_v1.md`; refuse to overwrite an
20
+ * existing file (re-runs go through `update` per ADR-0003).
21
+ * 5. Invoke the registered agent adapter; the agent writes the report.
22
+ * 6. Validate the report's frontmatter against `ResearchFrontmatterSchema`.
23
+ * 7. Transition the item: `status` → `researched` and persist.
24
+ *
25
+ * Any step from 4 onward that fails surfaces a non-zero exit code with a
26
+ * targeted message so the user can debug without re-reading the source.
27
+ */
28
+ export declare function runResearch(args: string[], options?: ResearchCommandOptions): Promise<number>;
29
+ export declare const researchCommand: Command;
30
+ //# sourceMappingURL=research.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"research.d.ts","sourceRoot":"","sources":["../../src/cli/research.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,yFAAyF;AACzF,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,sBAAsB;IACrC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,UAAU,CAAC;CACjB;AA+GD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,MAAM,CAAC,CA+LjB;AAED,eAAO,MAAM,eAAe,EAAE,OAI7B,CAAC"}