@ozzylabs/feedradar 0.1.4 → 0.1.5

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 (117) hide show
  1. package/README.ja.md +12 -6
  2. package/README.md +10 -5
  3. package/dist/agents/claude-code.d.ts +12 -1
  4. package/dist/agents/claude-code.d.ts.map +1 -1
  5. package/dist/agents/claude-code.js +9 -5
  6. package/dist/agents/claude-code.js.map +1 -1
  7. package/dist/agents/codex-cli.d.ts +7 -1
  8. package/dist/agents/codex-cli.d.ts.map +1 -1
  9. package/dist/agents/codex-cli.js +9 -5
  10. package/dist/agents/codex-cli.js.map +1 -1
  11. package/dist/agents/copilot.d.ts +7 -1
  12. package/dist/agents/copilot.d.ts.map +1 -1
  13. package/dist/agents/copilot.js +9 -5
  14. package/dist/agents/copilot.js.map +1 -1
  15. package/dist/agents/gemini-cli.d.ts +7 -1
  16. package/dist/agents/gemini-cli.d.ts.map +1 -1
  17. package/dist/agents/gemini-cli.js +9 -5
  18. package/dist/agents/gemini-cli.js.map +1 -1
  19. package/dist/agents/index.d.ts +1 -1
  20. package/dist/agents/index.d.ts.map +1 -1
  21. package/dist/agents/types.d.ts +33 -0
  22. package/dist/agents/types.d.ts.map +1 -1
  23. package/dist/cli/_progress.d.ts +138 -0
  24. package/dist/cli/_progress.d.ts.map +1 -0
  25. package/dist/cli/_progress.js +176 -0
  26. package/dist/cli/_progress.js.map +1 -0
  27. package/dist/cli/index.d.ts.map +1 -1
  28. package/dist/cli/index.js +2 -0
  29. package/dist/cli/index.js.map +1 -1
  30. package/dist/cli/research.d.ts +18 -20
  31. package/dist/cli/research.d.ts.map +1 -1
  32. package/dist/cli/research.js +318 -203
  33. package/dist/cli/research.js.map +1 -1
  34. package/dist/cli/review.d.ts +7 -0
  35. package/dist/cli/review.d.ts.map +1 -1
  36. package/dist/cli/review.js +46 -1
  37. package/dist/cli/review.js.map +1 -1
  38. package/dist/cli/source.d.ts +23 -2
  39. package/dist/cli/source.d.ts.map +1 -1
  40. package/dist/cli/source.js +425 -7
  41. package/dist/cli/source.js.map +1 -1
  42. package/dist/cli/update.d.ts +7 -0
  43. package/dist/cli/update.d.ts.map +1 -1
  44. package/dist/cli/update.js +41 -1
  45. package/dist/cli/update.js.map +1 -1
  46. package/dist/cli/watch.d.ts.map +1 -1
  47. package/dist/cli/watch.js +65 -3
  48. package/dist/cli/watch.js.map +1 -1
  49. package/dist/cli/workflow/generate-combined.d.ts +100 -0
  50. package/dist/cli/workflow/generate-combined.d.ts.map +1 -0
  51. package/dist/cli/workflow/generate-combined.js +387 -0
  52. package/dist/cli/workflow/generate-combined.js.map +1 -0
  53. package/dist/cli/workflow/generate-watch.d.ts +142 -0
  54. package/dist/cli/workflow/generate-watch.d.ts.map +1 -0
  55. package/dist/cli/workflow/generate-watch.js +338 -0
  56. package/dist/cli/workflow/generate-watch.js.map +1 -0
  57. package/dist/cli/workflow.d.ts +29 -0
  58. package/dist/cli/workflow.d.ts.map +1 -0
  59. package/dist/cli/workflow.js +66 -0
  60. package/dist/cli/workflow.js.map +1 -0
  61. package/dist/core/feeds/_fetch.d.ts +10 -0
  62. package/dist/core/feeds/_fetch.d.ts.map +1 -1
  63. package/dist/core/feeds/_fetch.js +182 -0
  64. package/dist/core/feeds/_fetch.js.map +1 -1
  65. package/dist/core/feeds/_jsonpath.d.ts +57 -0
  66. package/dist/core/feeds/_jsonpath.d.ts.map +1 -0
  67. package/dist/core/feeds/_jsonpath.js +207 -0
  68. package/dist/core/feeds/_jsonpath.js.map +1 -0
  69. package/dist/core/feeds/html-js.d.ts +8 -0
  70. package/dist/core/feeds/html-js.d.ts.map +1 -1
  71. package/dist/core/feeds/html-js.js +47 -1
  72. package/dist/core/feeds/html-js.js.map +1 -1
  73. package/dist/core/feeds/index.d.ts +1 -1
  74. package/dist/core/feeds/index.d.ts.map +1 -1
  75. package/dist/core/feeds/index.js +4 -0
  76. package/dist/core/feeds/index.js.map +1 -1
  77. package/dist/core/feeds/json-api.d.ts +3 -0
  78. package/dist/core/feeds/json-api.d.ts.map +1 -0
  79. package/dist/core/feeds/json-api.js +723 -0
  80. package/dist/core/feeds/json-api.js.map +1 -0
  81. package/dist/core/feeds/json-feed.d.ts +11 -0
  82. package/dist/core/feeds/json-feed.d.ts.map +1 -0
  83. package/dist/core/feeds/json-feed.js +242 -0
  84. package/dist/core/feeds/json-feed.js.map +1 -0
  85. package/dist/core/feeds/types.d.ts +123 -0
  86. package/dist/core/feeds/types.d.ts.map +1 -1
  87. package/dist/core/progress.d.ts +101 -0
  88. package/dist/core/progress.d.ts.map +1 -0
  89. package/dist/core/progress.js +212 -0
  90. package/dist/core/progress.js.map +1 -0
  91. package/dist/core/recipes.d.ts +138 -0
  92. package/dist/core/recipes.d.ts.map +1 -0
  93. package/dist/core/recipes.js +238 -0
  94. package/dist/core/recipes.js.map +1 -0
  95. package/dist/core/watcher.d.ts +61 -1
  96. package/dist/core/watcher.d.ts.map +1 -1
  97. package/dist/core/watcher.js +99 -2
  98. package/dist/core/watcher.js.map +1 -1
  99. package/dist/recipes/aws-whats-new.yaml +61 -0
  100. package/dist/recipes/dev-to.yaml +40 -0
  101. package/dist/schemas/index.d.ts +1 -0
  102. package/dist/schemas/index.d.ts.map +1 -1
  103. package/dist/schemas/index.js +1 -0
  104. package/dist/schemas/index.js.map +1 -1
  105. package/dist/schemas/recipe.d.ts +115 -0
  106. package/dist/schemas/recipe.d.ts.map +1 -0
  107. package/dist/schemas/recipe.js +54 -0
  108. package/dist/schemas/recipe.js.map +1 -0
  109. package/dist/schemas/source.d.ts +130 -0
  110. package/dist/schemas/source.d.ts.map +1 -1
  111. package/dist/schemas/source.js +130 -0
  112. package/dist/schemas/source.js.map +1 -1
  113. package/dist/templates/agents/AGENTS.md +31 -3
  114. package/dist/templates/feedradar.md +23 -8
  115. package/dist/templates/workflows/combined.template.yaml.tmpl +110 -0
  116. package/dist/templates/workflows/watch.template.yaml.tmpl +103 -0
  117. package/package.json +1 -2
@@ -0,0 +1,338 @@
1
+ import { access, mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { dirname, isAbsolute, join, normalize, relative, resolve } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ /**
5
+ * Agents supported by `--agent`. The literal list mirrors ADR-0014 D5's
6
+ * auth-policy table: each agent maps to a single repo secret name and the
7
+ * generator writes that name into the rendered workflow's `env:` block.
8
+ *
9
+ * `copilot` is included for completeness, but uses the auto-provisioned
10
+ * `GITHUB_TOKEN` rather than a user-managed secret — see `agentEnvKey` below.
11
+ */
12
+ export const SUPPORTED_AGENTS = ["claude-code", "codex-cli", "gemini-cli", "copilot"];
13
+ /**
14
+ * Resolve the directory holding the bundled workflow templates.
15
+ *
16
+ * Mirrors `resolveTemplatesRoot` in `src/cli/init.ts`: the compiled CLI
17
+ * lives at `dist/cli/workflow/generate-watch.js`, so the bundled templates
18
+ * sit at `../../templates` relative to this module. During tests we may be
19
+ * running from source (`src/cli/workflow/generate-watch.ts`), in which case
20
+ * the same relative path lands at `src/templates/`.
21
+ */
22
+ async function resolveTemplatesRoot() {
23
+ const here = dirname(fileURLToPath(import.meta.url));
24
+ // Compiled: dist/cli/workflow/generate-watch.js -> dist/templates
25
+ // Source: src/cli/workflow/generate-watch.ts -> src/templates
26
+ const candidate = resolve(here, "..", "..", "templates");
27
+ return candidate;
28
+ }
29
+ async function pathExists(p) {
30
+ try {
31
+ await access(p);
32
+ return true;
33
+ }
34
+ catch {
35
+ return false;
36
+ }
37
+ }
38
+ /**
39
+ * Map an agent identifier to its required workflow secret name (ADR-0014 D5).
40
+ *
41
+ * The generator writes the result into the rendered workflow as both the
42
+ * `env:` key and the `${{ secrets.<NAME> }}` reference, so the user only
43
+ * needs to register a single secret named after the table below.
44
+ *
45
+ * `copilot` uses the auto-provisioned `GITHUB_TOKEN`; no user action needed.
46
+ * The completion message still surfaces this so the user can confirm
47
+ * `permissions: contents: write` is enough (which it is — Copilot CLI rides
48
+ * the `GITHUB_TOKEN` granted to the job).
49
+ */
50
+ export function agentEnvKey(agent) {
51
+ switch (agent) {
52
+ case "claude-code":
53
+ return "ANTHROPIC_API_KEY";
54
+ case "codex-cli":
55
+ return "OPENAI_API_KEY";
56
+ case "gemini-cli":
57
+ return "GEMINI_API_KEY";
58
+ case "copilot":
59
+ return "GITHUB_TOKEN";
60
+ }
61
+ }
62
+ /**
63
+ * Validate a 5-field POSIX cron expression.
64
+ *
65
+ * GitHub Actions accepts the standard 5-field crontab format (minute, hour,
66
+ * day-of-month, month, day-of-week). We do not aim for byte-perfect parity
67
+ * with the upstream cron parser (e.g. `@daily` aliases) — those are
68
+ * actively documented as unsupported by GitHub Actions, so rejecting them
69
+ * here protects the user from generating a workflow that silently never
70
+ * fires.
71
+ *
72
+ * The validator accepts each field as one of:
73
+ * - `*`
74
+ * - `<n>` or `<n>-<m>` (with optional `/<step>`)
75
+ * - `<a>,<b>,...` (comma list, each token validated independently)
76
+ * - star slash step (every N units, e.g. `0 *_/6 * * *` reading the
77
+ * underscore as a placeholder for the slash that would close this comment)
78
+ *
79
+ * Range bounds (e.g. month 1-12) are NOT enforced here; GitHub Actions
80
+ * rejects out-of-range expressions on workflow load. Keeping our check
81
+ * structural keeps the dep surface zero (no cron-parser library) without
82
+ * generating workflows that pass our check but fail GitHub's.
83
+ */
84
+ export function isValidCron(expr) {
85
+ const trimmed = expr.trim();
86
+ if (trimmed.length === 0)
87
+ return false;
88
+ const fields = trimmed.split(/\s+/);
89
+ if (fields.length !== 5)
90
+ return false;
91
+ // Structural per-field check: accepts *, n, n-m, with optional /step.
92
+ // Each comma-separated token must independently satisfy the per-token
93
+ // grammar; an empty token (e.g. trailing comma) fails.
94
+ const tokenPattern = /^(?:\*|\d+(?:-\d+)?)(?:\/\d+)?$/;
95
+ for (const field of fields) {
96
+ if (field.length === 0)
97
+ return false;
98
+ const tokens = field.split(",");
99
+ for (const token of tokens) {
100
+ if (token.length === 0)
101
+ return false;
102
+ if (!tokenPattern.test(token))
103
+ return false;
104
+ }
105
+ }
106
+ return true;
107
+ }
108
+ /**
109
+ * Validate that the requested `--output` path lands under
110
+ * `.github/workflows/` relative to the workspace root.
111
+ *
112
+ * Two attack/footgun classes are blocked:
113
+ *
114
+ * 1. **Traversal:** `../../etc/passwd` or `.github/workflows/../../foo`
115
+ * — `..` segments anywhere in the relative path push the file out of
116
+ * the allowed directory.
117
+ * 2. **Absolute paths:** `/etc/foo` — the workflow is meant to live in
118
+ * the workspace; an absolute path is almost certainly user error or
119
+ * malicious input.
120
+ *
121
+ * The check operates on the relative form of the resolved path so that
122
+ * `cwd` differences (test temp dirs vs `process.cwd()`) do not affect the
123
+ * verdict. We also require the file to end with `.yaml` or `.yml` so the
124
+ * GitHub Actions loader picks it up.
125
+ */
126
+ export function isSafeWorkflowPath(outputPath, cwd) {
127
+ if (isAbsolute(outputPath)) {
128
+ // Allow absolute paths only if they're inside the workspace's
129
+ // .github/workflows/ directory. This keeps the test seam (mkdtemp
130
+ // workdirs are absolute) usable while still rejecting paths that
131
+ // escape the workspace.
132
+ const allowedDir = resolve(cwd, ".github", "workflows");
133
+ const resolved = resolve(outputPath);
134
+ const rel = relative(allowedDir, resolved);
135
+ if (rel.startsWith("..") || isAbsolute(rel))
136
+ return false;
137
+ return /\.(ya?ml)$/i.test(resolved);
138
+ }
139
+ // Reject any `..` segment in the relative path (after normalize, a
140
+ // traversal that escapes the prefix surfaces as `..` at the start).
141
+ const normalized = normalize(outputPath);
142
+ if (normalized.split(/[\\/]/).includes(".."))
143
+ return false;
144
+ // Must start with `.github/workflows/`.
145
+ const required = `${join(".github", "workflows")}/`;
146
+ // Normalize separator (Windows users may pass backslashes via tests).
147
+ const unixified = normalized.replace(/\\/g, "/");
148
+ if (!unixified.startsWith(required.replace(/\\/g, "/")))
149
+ return false;
150
+ return /\.(ya?ml)$/i.test(unixified);
151
+ }
152
+ /**
153
+ * Render the bundled template by substituting `{{cron}}` / `{{output}}` /
154
+ * `{{agentEnvKey}}` placeholders with the user-supplied values.
155
+ *
156
+ * Substitution is intentionally a literal `replace`, not a templating
157
+ * engine: the placeholders are simple tokens, and we don't want to expand
158
+ * arbitrary GitHub Actions expressions (`${{ ... }}`) that already live in
159
+ * the template body.
160
+ *
161
+ * Exported for unit testing — tests can drive the renderer in isolation
162
+ * without touching the file system.
163
+ */
164
+ export function renderWatchTemplate(template, values) {
165
+ return template
166
+ .replace(/\{\{cron\}\}/g, values.cron)
167
+ .replace(/\{\{agentEnvKey\}\}/g, values.agentEnvKey);
168
+ }
169
+ /**
170
+ * Core implementation of `radar workflow generate watch`.
171
+ *
172
+ * Validates the cron + output path, renders the template with the
173
+ * agent-appropriate secret name, and writes the result. The completion
174
+ * stdout lines (printed via `io.log`) tell the user exactly which secrets
175
+ * to register so they don't have to hunt through ADR-0014 D5 by hand.
176
+ */
177
+ export async function generateWatch(options) {
178
+ const { cwd, cron, output, agent, force } = options;
179
+ const log = options.io?.log ?? ((m) => console.log(m));
180
+ const warn = options.io?.warn ?? ((m) => console.warn(m));
181
+ if (!isValidCron(cron)) {
182
+ throw new Error(`invalid --cron expression '${cron}' (expected 5-field POSIX cron, e.g. "0 0 * * *")`);
183
+ }
184
+ if (!isSafeWorkflowPath(output, cwd)) {
185
+ throw new Error(`invalid --output '${output}' (must be a relative path under .github/workflows/ ending in .yaml or .yml)`);
186
+ }
187
+ const templatesRoot = options.templatesRoot ?? (await resolveTemplatesRoot());
188
+ // The bundled template is stored with a `.yaml.tmpl` extension so that
189
+ // repo-wide yamlfmt (`lefthook-base.yaml` -> `pre-commit.yaml`) does not
190
+ // run on it. yamlfmt parses `{{agentEnvKey}}` as a flow-style YAML mapping
191
+ // key and rewrites it into syntactically valid but semantically broken
192
+ // YAML, destroying the placeholder. `.tmpl` keeps the file out of the
193
+ // **/*.{yaml,yml} glob while still being browseable on GitHub.
194
+ const templatePath = join(templatesRoot, "workflows", "watch.template.yaml.tmpl");
195
+ if (!(await pathExists(templatePath))) {
196
+ throw new Error(`bundled template not found: ${templatePath}`);
197
+ }
198
+ const template = await readFile(templatePath, "utf8");
199
+ const envKey = agentEnvKey(agent);
200
+ const rendered = renderWatchTemplate(template, { cron, agentEnvKey: envKey });
201
+ const destAbs = isAbsolute(output) ? output : join(cwd, output);
202
+ const destRel = isAbsolute(output) ? relative(cwd, output) : output;
203
+ if ((await pathExists(destAbs)) && !force) {
204
+ throw new Error(`output file already exists: ${destRel} (use --force to overwrite)`);
205
+ }
206
+ if ((await pathExists(destAbs)) && force) {
207
+ warn(`workflow generate watch: overwriting existing file ${destRel}`);
208
+ }
209
+ await mkdir(dirname(destAbs), { recursive: true });
210
+ await writeFile(destAbs, rendered, "utf8");
211
+ log(`workflow generate watch: wrote ${destRel}`);
212
+ log(`workflow generate watch: cron='${cron}', agent='${agent}'`);
213
+ log("");
214
+ log("Required GitHub Actions secrets (Settings → Secrets and variables → Actions):");
215
+ if (agent === "copilot") {
216
+ // Copilot CLI rides the auto-provisioned GITHUB_TOKEN — no user action
217
+ // beyond confirming the workflow's `permissions: contents: write`.
218
+ log(" GITHUB_TOKEN — auto-provisioned by GitHub Actions (no manual setup needed)");
219
+ }
220
+ else {
221
+ log(` ${envKey} — required for the '${agent}' agent (ADR-0014 D5)`);
222
+ log(" GITHUB_TOKEN — auto-provisioned by GitHub Actions (no manual setup needed)");
223
+ }
224
+ return { outputPath: destRel, requiredSecret: envKey };
225
+ }
226
+ /**
227
+ * Parse `workflow generate watch` flags.
228
+ *
229
+ * Throws on flags that require a value but receive none, unknown flags, or
230
+ * unsupported `--agent` choices. Returning a structured object keeps `run`
231
+ * free of argument-parsing branches.
232
+ */
233
+ export function parseGenerateWatchArgs(args) {
234
+ let cron = "0 0 * * *";
235
+ let output = join(".github", "workflows", "feedradar-watch.yaml");
236
+ let agent = "claude-code";
237
+ let force = false;
238
+ let help = false;
239
+ for (let i = 0; i < args.length; i++) {
240
+ const a = args[i];
241
+ if (a === "-h" || a === "--help") {
242
+ help = true;
243
+ continue;
244
+ }
245
+ if (a === "--cron") {
246
+ const value = args[++i];
247
+ if (value === undefined)
248
+ throw new Error(`option ${a} requires a value`);
249
+ cron = value;
250
+ continue;
251
+ }
252
+ if (a === "--output") {
253
+ const value = args[++i];
254
+ if (value === undefined)
255
+ throw new Error(`option ${a} requires a value`);
256
+ output = value;
257
+ continue;
258
+ }
259
+ if (a === "--agent") {
260
+ const value = args[++i];
261
+ if (value === undefined)
262
+ throw new Error(`option ${a} requires a value`);
263
+ if (!SUPPORTED_AGENTS.includes(value)) {
264
+ throw new Error(`option --agent expects one of: ${SUPPORTED_AGENTS.join(" | ")}, got '${value}'`);
265
+ }
266
+ agent = value;
267
+ continue;
268
+ }
269
+ if (a === "--force" || a === "-f") {
270
+ force = true;
271
+ continue;
272
+ }
273
+ if (a?.startsWith("--") || a?.startsWith("-")) {
274
+ throw new Error(`unknown option: ${a}`);
275
+ }
276
+ throw new Error(`unexpected positional argument: ${a}`);
277
+ }
278
+ return { cron, output, agent, force, help };
279
+ }
280
+ export function printGenerateWatchHelp(log) {
281
+ log("Usage: radar workflow generate watch [options]");
282
+ log("");
283
+ log("Generates a GitHub Actions workflow that runs `radar watch run` on a cron schedule.");
284
+ log("The generated workflow includes git pull --rebase retry logic to mitigate push");
285
+ log("conflicts with other concurrent workflows (ADR-0014 D4).");
286
+ log("");
287
+ log("Options:");
288
+ log(' --cron <expression> 5-field cron expression (default: "0 0 * * *")');
289
+ log(" --output <path> Output file under .github/workflows/");
290
+ log(" (default: .github/workflows/feedradar-watch.yaml)");
291
+ log(" --agent <name> claude-code | codex-cli | gemini-cli | copilot (default: claude-code)");
292
+ log(" Determines which secret name the workflow references.");
293
+ log(" --force, -f Overwrite existing output file");
294
+ log("");
295
+ log("Required secrets (Settings → Secrets and variables → Actions):");
296
+ log(" ANTHROPIC_API_KEY when --agent claude-code (default)");
297
+ log(" OPENAI_API_KEY when --agent codex-cli");
298
+ log(" GEMINI_API_KEY when --agent gemini-cli");
299
+ log(" GITHUB_TOKEN auto-provisioned for --agent copilot (no setup needed)");
300
+ }
301
+ /**
302
+ * Entry point invoked by `runWorkflow` (in `src/cli/workflow.ts`) when the
303
+ * user types `radar workflow generate watch`. Translates parsed flags into
304
+ * `generateWatch` arguments and surfaces validation errors with the
305
+ * `workflow generate watch:` prefix to match the rest of the CLI.
306
+ */
307
+ export async function runGenerateWatch(args, io = {}, cwd = process.cwd()) {
308
+ const log = io.log ?? ((m) => console.log(m));
309
+ const error = io.error ?? ((m) => console.error(m));
310
+ let parsed;
311
+ try {
312
+ parsed = parseGenerateWatchArgs(args);
313
+ }
314
+ catch (e) {
315
+ error(`workflow generate watch: ${e instanceof Error ? e.message : String(e)}`);
316
+ return 2;
317
+ }
318
+ if (parsed.help) {
319
+ printGenerateWatchHelp(log);
320
+ return 0;
321
+ }
322
+ try {
323
+ await generateWatch({
324
+ cwd,
325
+ cron: parsed.cron,
326
+ output: parsed.output,
327
+ agent: parsed.agent,
328
+ force: parsed.force,
329
+ io,
330
+ });
331
+ return 0;
332
+ }
333
+ catch (e) {
334
+ error(`workflow generate watch: ${e instanceof Error ? e.message : String(e)}`);
335
+ return 1;
336
+ }
337
+ }
338
+ //# sourceMappingURL=generate-watch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-watch.js","sourceRoot":"","sources":["../../../src/cli/workflow/generate-watch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import type { Command } from "./index.js";
2
+ /**
3
+ * Sinks for the `workflow` command family's user-facing output. Each `<type>`
4
+ * subcommand receives an `IO` object so tests can capture lines without
5
+ * spawning the full CLI; the real CLI binds these to `console.*`.
6
+ */
7
+ export interface WorkflowIO {
8
+ log?: (message: string) => void;
9
+ warn?: (message: string) => void;
10
+ error?: (message: string) => void;
11
+ }
12
+ export interface WorkflowCommandOptions {
13
+ /** Workspace root (defaults to `process.cwd()` for the real CLI). */
14
+ cwd?: string;
15
+ io?: WorkflowIO;
16
+ }
17
+ /**
18
+ * Dispatcher for `radar workflow <subcommand>`.
19
+ *
20
+ * Today the supported subcommands are `generate watch` (#188) and
21
+ * `generate combined` (this issue, #189). Additional `<type>` values
22
+ * (`research` / `review` per #191) will land as new branches in the
23
+ * `generate` switch without changing the surface.
24
+ *
25
+ * See ADR-0014 (workflow generate sub-command) for the full design rationale.
26
+ */
27
+ export declare function runWorkflow(args: string[], options?: WorkflowCommandOptions): Promise<number>;
28
+ export declare const workflowCommand: Command;
29
+ //# sourceMappingURL=workflow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../../src/cli/workflow.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAI1C;;;;GAIG;AACH,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,qEAAqE;IACrE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,UAAU,CAAC;CACjB;AAsBD;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,MAAM,CAAC,CAiCjB;AAED,eAAO,MAAM,eAAe,EAAE,OAI7B,CAAC"}
@@ -0,0 +1,66 @@
1
+ import { runGenerateCombined } from "./workflow/generate-combined.js";
2
+ import { runGenerateWatch } from "./workflow/generate-watch.js";
3
+ function printWorkflowHelp(log) {
4
+ log("Usage: radar workflow <subcommand> [...]");
5
+ log("");
6
+ log("Subcommands:");
7
+ log(" generate <type> Generate a GitHub Actions workflow YAML");
8
+ log(" Types: watch | combined (more types in future sub-issues)");
9
+ log("");
10
+ log("Run `radar workflow generate <type> --help` for type-specific options.");
11
+ }
12
+ function printGenerateHelp(log) {
13
+ log("Usage: radar workflow generate <type> [options]");
14
+ log("");
15
+ log("Types:");
16
+ log(" watch Periodic `radar watch run` (cron + state commit with rebase retry)");
17
+ log(" combined Periodic `radar watch run` -> auto research --batch with hard cap (ADR-0014)");
18
+ log("");
19
+ log("Run `radar workflow generate <type> --help` for type-specific options.");
20
+ }
21
+ /**
22
+ * Dispatcher for `radar workflow <subcommand>`.
23
+ *
24
+ * Today the supported subcommands are `generate watch` (#188) and
25
+ * `generate combined` (this issue, #189). Additional `<type>` values
26
+ * (`research` / `review` per #191) will land as new branches in the
27
+ * `generate` switch without changing the surface.
28
+ *
29
+ * See ADR-0014 (workflow generate sub-command) for the full design rationale.
30
+ */
31
+ export async function runWorkflow(args, options = {}) {
32
+ const cwd = options.cwd ?? process.cwd();
33
+ const log = options.io?.log ?? ((m) => console.log(m));
34
+ const error = options.io?.error ?? ((m) => console.error(m));
35
+ const [sub, ...rest] = args;
36
+ if (!sub || sub === "-h" || sub === "--help" || sub === "help") {
37
+ printWorkflowHelp(log);
38
+ return sub ? 0 : 2;
39
+ }
40
+ if (sub !== "generate") {
41
+ error(`workflow: unknown subcommand '${sub}'`);
42
+ printWorkflowHelp(error);
43
+ return 2;
44
+ }
45
+ const [type, ...typeArgs] = rest;
46
+ if (!type || type === "-h" || type === "--help" || type === "help") {
47
+ printGenerateHelp(log);
48
+ return type ? 0 : 2;
49
+ }
50
+ switch (type) {
51
+ case "watch":
52
+ return runGenerateWatch(typeArgs, options.io ?? {}, cwd);
53
+ case "combined":
54
+ return runGenerateCombined(typeArgs, options.io ?? {}, cwd);
55
+ default:
56
+ error(`workflow generate: unknown type '${type}'`);
57
+ printGenerateHelp(error);
58
+ return 2;
59
+ }
60
+ }
61
+ export const workflowCommand = {
62
+ name: "workflow",
63
+ summary: "Generate GitHub Actions workflows (generate <type>)",
64
+ run: (args) => runWorkflow(args),
65
+ };
66
+ //# sourceMappingURL=workflow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow.js","sourceRoot":"","sources":["../../src/cli/workflow.ts"],"names":[],"mappings":"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"}
@@ -58,6 +58,16 @@ export interface FetchWithRetryOptions {
58
58
  /** Override env for `RADAR_FETCH_*` parsing. Defaults to `process.env`. */
59
59
  env?: NodeJS.ProcessEnv;
60
60
  }
61
+ /**
62
+ * Validate a fetch URL against the SSRF host blocklist (ADR-0009 §D5b).
63
+ *
64
+ * Throws a `TypeError` with a user-friendly message when the URL is
65
+ * rejected. Returns nothing on success.
66
+ *
67
+ * Exported so adapters / tests can trigger the check independently of
68
+ * `fetchWithRetry` (e.g. validate a recipe URL at config-load time).
69
+ */
70
+ export declare function validateFetchUrl(url: string | URL, env?: NodeJS.ProcessEnv): void;
61
71
  /**
62
72
  * Build a `FetchConfig` from env vars + explicit overrides.
63
73
  *
@@ -1 +1 @@
1
- {"version":3,"file":"_fetch.d.ts","sourceRoot":"","sources":["../../../src/core/feeds/_fetch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,mDAAmD;AACnD,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAE/C,2DAA2D;AAC3D,eAAO,MAAM,qBAAqB,IAAI,CAAC;AAEvC,kFAAkF;AAClF,eAAO,MAAM,6BAA6B,MAAM,CAAC;AAEjD,sDAAsD;AACtD,eAAO,MAAM,4BAA4B,IAAI,CAAC;AAE9C;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,qEAAqE;AACrE,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mFAAmF;IACnF,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;OAGG;IACH,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,2EAA2E;IAC3E,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAUD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,qBAA0B,GAAG,WAAW,CAYnF;AAuDD,8EAA8E;AAC9E,KAAK,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;AAEpD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,cAAc,CAClC,SAAS,EAAE,SAAS,EACpB,GAAG,EAAE,MAAM,GAAG,GAAG,EACjB,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAO,EACrE,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,aAAa,CAAC,CA8CxB"}
1
+ {"version":3,"file":"_fetch.d.ts","sourceRoot":"","sources":["../../../src/core/feeds/_fetch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,mDAAmD;AACnD,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAE/C,2DAA2D;AAC3D,eAAO,MAAM,qBAAqB,IAAI,CAAC;AAEvC,kFAAkF;AAClF,eAAO,MAAM,6BAA6B,MAAM,CAAC;AAEjD,sDAAsD;AACtD,eAAO,MAAM,4BAA4B,IAAI,CAAC;AAE9C;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,qEAAqE;AACrE,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mFAAmF;IACnF,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;OAGG;IACH,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,2EAA2E;IAC3E,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAuID;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,IAAI,CA+C9F;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,qBAA0B,GAAG,WAAW,CAYnF;AAuDD,8EAA8E;AAC9E,KAAK,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;AAEpD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,cAAc,CAClC,SAAS,EAAE,SAAS,EACpB,GAAG,EAAE,MAAM,GAAG,GAAG,EACjB,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAO,EACrE,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,aAAa,CAAC,CAmDxB"}