@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.
- package/README.ja.md +12 -6
- package/README.md +10 -5
- package/dist/agents/claude-code.d.ts +12 -1
- package/dist/agents/claude-code.d.ts.map +1 -1
- package/dist/agents/claude-code.js +9 -5
- package/dist/agents/claude-code.js.map +1 -1
- package/dist/agents/codex-cli.d.ts +7 -1
- package/dist/agents/codex-cli.d.ts.map +1 -1
- package/dist/agents/codex-cli.js +9 -5
- package/dist/agents/codex-cli.js.map +1 -1
- package/dist/agents/copilot.d.ts +7 -1
- package/dist/agents/copilot.d.ts.map +1 -1
- package/dist/agents/copilot.js +9 -5
- package/dist/agents/copilot.js.map +1 -1
- package/dist/agents/gemini-cli.d.ts +7 -1
- package/dist/agents/gemini-cli.d.ts.map +1 -1
- package/dist/agents/gemini-cli.js +9 -5
- package/dist/agents/gemini-cli.js.map +1 -1
- package/dist/agents/index.d.ts +1 -1
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/types.d.ts +33 -0
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/cli/_progress.d.ts +138 -0
- package/dist/cli/_progress.d.ts.map +1 -0
- package/dist/cli/_progress.js +176 -0
- package/dist/cli/_progress.js.map +1 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/research.d.ts +18 -20
- package/dist/cli/research.d.ts.map +1 -1
- package/dist/cli/research.js +318 -203
- package/dist/cli/research.js.map +1 -1
- package/dist/cli/review.d.ts +7 -0
- package/dist/cli/review.d.ts.map +1 -1
- package/dist/cli/review.js +46 -1
- package/dist/cli/review.js.map +1 -1
- package/dist/cli/source.d.ts +23 -2
- package/dist/cli/source.d.ts.map +1 -1
- package/dist/cli/source.js +425 -7
- package/dist/cli/source.js.map +1 -1
- package/dist/cli/update.d.ts +7 -0
- package/dist/cli/update.d.ts.map +1 -1
- package/dist/cli/update.js +41 -1
- package/dist/cli/update.js.map +1 -1
- package/dist/cli/watch.d.ts.map +1 -1
- package/dist/cli/watch.js +65 -3
- package/dist/cli/watch.js.map +1 -1
- package/dist/cli/workflow/generate-combined.d.ts +100 -0
- package/dist/cli/workflow/generate-combined.d.ts.map +1 -0
- package/dist/cli/workflow/generate-combined.js +387 -0
- package/dist/cli/workflow/generate-combined.js.map +1 -0
- package/dist/cli/workflow/generate-watch.d.ts +142 -0
- package/dist/cli/workflow/generate-watch.d.ts.map +1 -0
- package/dist/cli/workflow/generate-watch.js +338 -0
- package/dist/cli/workflow/generate-watch.js.map +1 -0
- package/dist/cli/workflow.d.ts +29 -0
- package/dist/cli/workflow.d.ts.map +1 -0
- package/dist/cli/workflow.js +66 -0
- package/dist/cli/workflow.js.map +1 -0
- package/dist/core/feeds/_fetch.d.ts +10 -0
- package/dist/core/feeds/_fetch.d.ts.map +1 -1
- package/dist/core/feeds/_fetch.js +182 -0
- package/dist/core/feeds/_fetch.js.map +1 -1
- package/dist/core/feeds/_jsonpath.d.ts +57 -0
- package/dist/core/feeds/_jsonpath.d.ts.map +1 -0
- package/dist/core/feeds/_jsonpath.js +207 -0
- package/dist/core/feeds/_jsonpath.js.map +1 -0
- package/dist/core/feeds/html-js.d.ts +8 -0
- package/dist/core/feeds/html-js.d.ts.map +1 -1
- package/dist/core/feeds/html-js.js +47 -1
- package/dist/core/feeds/html-js.js.map +1 -1
- package/dist/core/feeds/index.d.ts +1 -1
- package/dist/core/feeds/index.d.ts.map +1 -1
- package/dist/core/feeds/index.js +4 -0
- package/dist/core/feeds/index.js.map +1 -1
- package/dist/core/feeds/json-api.d.ts +3 -0
- package/dist/core/feeds/json-api.d.ts.map +1 -0
- package/dist/core/feeds/json-api.js +723 -0
- package/dist/core/feeds/json-api.js.map +1 -0
- package/dist/core/feeds/json-feed.d.ts +11 -0
- package/dist/core/feeds/json-feed.d.ts.map +1 -0
- package/dist/core/feeds/json-feed.js +242 -0
- package/dist/core/feeds/json-feed.js.map +1 -0
- package/dist/core/feeds/types.d.ts +123 -0
- package/dist/core/feeds/types.d.ts.map +1 -1
- package/dist/core/progress.d.ts +101 -0
- package/dist/core/progress.d.ts.map +1 -0
- package/dist/core/progress.js +212 -0
- package/dist/core/progress.js.map +1 -0
- package/dist/core/recipes.d.ts +138 -0
- package/dist/core/recipes.d.ts.map +1 -0
- package/dist/core/recipes.js +238 -0
- package/dist/core/recipes.js.map +1 -0
- package/dist/core/watcher.d.ts +61 -1
- package/dist/core/watcher.d.ts.map +1 -1
- package/dist/core/watcher.js +99 -2
- package/dist/core/watcher.js.map +1 -1
- package/dist/recipes/aws-whats-new.yaml +61 -0
- package/dist/recipes/dev-to.yaml +40 -0
- package/dist/schemas/index.d.ts +1 -0
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/schemas/index.js +1 -0
- package/dist/schemas/index.js.map +1 -1
- package/dist/schemas/recipe.d.ts +115 -0
- package/dist/schemas/recipe.d.ts.map +1 -0
- package/dist/schemas/recipe.js +54 -0
- package/dist/schemas/recipe.js.map +1 -0
- package/dist/schemas/source.d.ts +130 -0
- package/dist/schemas/source.d.ts.map +1 -1
- package/dist/schemas/source.js +130 -0
- package/dist/schemas/source.js.map +1 -1
- package/dist/templates/agents/AGENTS.md +31 -3
- package/dist/templates/feedradar.md +23 -8
- package/dist/templates/workflows/combined.template.yaml.tmpl +110 -0
- package/dist/templates/workflows/watch.template.yaml.tmpl +103 -0
- 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;
|
|
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"}
|