feat: initialize registry with provider support and enhanced init flow#1
Conversation
Review complete; README change only, no new issues.
Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues. Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues. |
Greptile SummaryThis PR introduces the The registry architecture is well-designed: lazy Key changes:
Confidence Score: 4/5Safe to merge; the only consequential issue is the Implementation is clean, well-tested, and consistent. Provider tools correctly use lazy dynamic imports with friendly missing-SDK errors. The
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[runeflow init] --> B{TTY or --name provided?}
B -- No --> C[throw Error]
B -- Yes --> D[Collect name / description / provider / model]
D --> E{provider in PROVIDER_DEFAULTS?}
E -- No --> F[Silent fallback to cerebras - no warning emitted]
E -- Yes --> G[Resolve providerConfig]
F --> G
G --> H{skillFile exists and not --force?}
H -- Yes --> I[throw Error]
H -- No --> J[Write .runeflow.md]
J --> K{runtimeFile exists and not --force?}
K -- No or force --> L[Write runtime.js]
K -- Yes --> M[Skip runtime.js]
L --> N[Log success + Next steps - bypasses silent]
M --> N
P[runeflow run - tool step] --> Q[Resolve input bindings]
Q --> R{tool in runtime.tools?}
R -- No --> S[RuntimeError: tool not registered]
R -- Yes --> T{lazy import provider SDK}
T -- SDK missing --> U[Friendly install hint error]
T -- SDK present --> V[Execute tool handler]
V --> W[Validate output schema]
W --> X[Write step artifact JSON]
|
| "runeflow": ">=0.1.0" | ||
| }, | ||
| "peerDependenciesMeta": { | ||
| "@octokit/rest": { "optional": true }, | ||
| "@linear/sdk": { "optional": true }, | ||
| "@slack/web-api": { "optional": true }, | ||
| "@notionhq/client": { "optional": true } | ||
| }, |
There was a problem hiding this comment.
peerDependenciesMeta entries are silently ignored without matching peerDependencies
The four optional provider packages (@octokit/rest, @linear/sdk, @slack/web-api, @notionhq/client) are listed in peerDependenciesMeta but are absent from peerDependencies. Per the npm spec, peerDependenciesMeta only annotates packages already declared in peerDependencies — it has no effect on packages not already listed there. As written, package managers (npm, pnpm, yarn) silently ignore these entries: consumers won't receive install hints and the packages won't be treated as peers at all.
Fix: add all four to peerDependencies and keep peerDependenciesMeta to mark them optional:
| "runeflow": ">=0.1.0" | |
| }, | |
| "peerDependenciesMeta": { | |
| "@octokit/rest": { "optional": true }, | |
| "@linear/sdk": { "optional": true }, | |
| "@slack/web-api": { "optional": true }, | |
| "@notionhq/client": { "optional": true } | |
| }, | |
| "peerDependencies": { | |
| "runeflow": ">=0.1.0", | |
| "@octokit/rest": "*", | |
| "@linear/sdk": "*", | |
| "@slack/web-api": "*", | |
| "@notionhq/client": "*" | |
| }, | |
| "peerDependenciesMeta": { | |
| "@octokit/rest": { "optional": true }, | |
| "@linear/sdk": { "optional": true }, | |
| "@slack/web-api": { "optional": true }, | |
| "@notionhq/client": { "optional": true } | |
| }, |
| console.log(`\n✅ Created ${skillFile}`); | ||
| if (!runtimeExists || options.force) console.log(`✅ Created ${runtimeFile}`); | ||
| console.log(`\nNext steps:`); | ||
| console.log(` 1. npm install ${providerConfig.pkg}`); | ||
| console.log(` 2. export ${providerConfig.envKey}=your-key`); | ||
| console.log(` 3. Edit ${skillFile} to define your workflow`); | ||
| console.log(` 4. runeflow validate ./${skillFile}`); | ||
| console.log(` 5. runeflow run ./${skillFile} --input '{}' --runtime ./${runtimeFile}\n`); |
There was a problem hiding this comment.
silent option doesn't suppress the success and "Next steps" output
The log helper defined on line 95 correctly becomes a no-op when options.silent is true. However, the success messages and "Next steps" block (lines 128–135) call console.log directly, bypassing silent. For programmatic callers that pass silent: true (as the test suite does), these lines will still emit output unexpectedly. Replace console.log with log throughout this block to make the option behave consistently.
| const name = options.name ?? await ask(rl, "Skill name", "my-skill"); | ||
| const description = options.description ?? await ask(rl, "What does it do", `${name} skill`); | ||
| const providerInput = options.provider ?? await ask(rl, `Provider (${Object.keys(PROVIDER_DEFAULTS).join(", ")})`, "cerebras"); | ||
| const provider = PROVIDER_DEFAULTS[providerInput] ? providerInput : "cerebras"; |
There was a problem hiding this comment.
Unknown provider silently falls back to
cerebras without any warning
If the user provides an unrecognised provider string (e.g. a typo like "openai " with a trailing space, or a valid but unsupported provider name), the code silently falls back to "cerebras" with no user-visible feedback. The generated .runeflow.md will then contain provider: cerebras while the user expected their input. Emitting a warning before the fallback makes this visible:
| const provider = PROVIDER_DEFAULTS[providerInput] ? providerInput : "cerebras"; | |
| if (!PROVIDER_DEFAULTS[providerInput]) { | |
| log(`⚠ Unknown provider "${providerInput}", falling back to cerebras.`); | |
| } | |
| const provider = PROVIDER_DEFAULTS[providerInput] ? providerInput : "cerebras"; |
This PR introduces the initial implementation of the Runeflow registry with support for multiple providers (GitHub, Linear, Notion, Slack). Key changes include:
runeflow-registrypackage with provider modules, schemas, and toolsinitfunctionality with better setup and configuration handlingThe changes lay the foundation for a pluggable provider architecture and improve the overall initialization experience. Note: .DS_Store file should be gitignored and will be removed in a follow-up if needed.