Skip to content

feat: initialize registry with provider support and enhanced init flow#1

Merged
paritoshmmmec merged 5 commits into
mainfrom
feat/wave2-registry-init-force
Apr 7, 2026
Merged

feat: initialize registry with provider support and enhanced init flow#1
paritoshmmmec merged 5 commits into
mainfrom
feat/wave2-registry-init-force

Conversation

@paritoshmmmec

Copy link
Copy Markdown
Owner

This PR introduces the initial implementation of the Runeflow registry with support for multiple providers (GitHub, Linear, Notion, Slack). Key changes include:

  • Registry Package: New runeflow-registry package with provider modules, schemas, and tools
  • Provider Integration: Full implementations for GitHub, Linear, Notion, and Slack with dedicated schemas and tooling
  • Enhanced Init Flow: Improved init functionality with better setup and configuration handling
  • CLI Updates: Updates to CLI to support new registry functionality
  • Runtime Improvements: Minor updates to runtime with expanded test coverage
  • Comprehensive Tests: Added new tests for CLI and runtime functionality

The 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.

@ghost

ghost commented Apr 7, 2026

Copy link
Copy Markdown

Rooviewer Clock   Follow task

Review complete; README change only, no new issues.

  • --force flag is ignored unless given a value; presence should set force=true for init/run.
Previous reviews

Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues.

Previous reviews

Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues.

Comment thread src/cli.js Outdated
@greptile-apps

greptile-apps Bot commented Apr 7, 2026

Copy link
Copy Markdown

Greptile Summary

This PR introduces the runeflow-registry package with provider integrations for GitHub, Linear, Notion, and Slack, alongside an enhanced init flow (runeflow init), a --force flag for run, and expanded test coverage.

The registry architecture is well-designed: lazy import() calls for provider SDKs mean consumers only pay the cost of what they use, the consistent schemas + tools split per provider is clean and extensible, and friendly error messages when an SDK is missing are a good DX touch. The new runInit is straightforward and the tests cover the important paths (non-interactive init, --force overwrite, resume from halted run).

Key changes:

  • New runeflow-registry package with four providers (GitHub, Linear, Notion, Slack), each with schema definitions and lazy-loaded tool implementations
  • runeflow init command for scaffolding new skill files and runtime.js interactively or non-interactively
  • --force flag on runeflow run to bypass cached steps
  • peerDependenciesMeta entries in packages/runeflow-registry/package.json lack matching peerDependencies entries — package managers will silently ignore them; this should be fixed before publishing to npm
  • Minor: silent option in init.js doesn't suppress the success/next-steps output block; unknown provider falls back to cerebras without warning the user
  • .DS_Store macOS metadata file is committed; .gitignore should be updated

Confidence Score: 4/5

Safe to merge; the only consequential issue is the peerDependenciesMeta packaging bug which should be fixed before npm publish but does not affect runtime behavior

Implementation is clean, well-tested, and consistent. Provider tools correctly use lazy dynamic imports with friendly missing-SDK errors. The peerDependencies metadata issue affects install-time discoverability but not runtime execution. Two P2 init.js style issues and .DS_Store are non-blocking.

packages/runeflow-registry/package.json needs the peerDependencies section corrected before npm publish; src/init.js has two minor UX issues worth addressing

Important Files Changed

Filename Overview
packages/runeflow-registry/package.json New registry package manifest — peerDependenciesMeta entries for provider SDKs lack matching peerDependencies entries, making them silently ineffective (P1)
packages/runeflow-registry/index.js Clean top-level re-export barrel for all four providers; correct
packages/runeflow-registry/providers/github/tools.js GitHub tool implementations via lazy @octokit/rest import with friendly missing-SDK error; correct pattern
packages/runeflow-registry/providers/github/schemas.js Well-formed JSON-Schema descriptors for all five GitHub tools
packages/runeflow-registry/providers/linear/tools.js Linear tool implementations using @linear/sdk; correct lazy-load pattern
packages/runeflow-registry/providers/notion/tools.js Notion tool implementations using @notionhq/client; correct
packages/runeflow-registry/providers/slack/tools.js Slack tool implementations using @slack/web-api; correct
src/init.js New runeflow init command — two minor P2 issues: silent option inconsistency and silent provider fallback without warning; otherwise well-structured
src/cli.js Updated CLI surface adds init command and --force flag; clean
src/runtime.js Runtime execution engine with --force and resume support; no regressions
test/cli.test.js Comprehensive new CLI tests covering init, resume, force overwrite, and legacy fallback paths
.DS_Store macOS metadata binary — should not be committed; .gitignore needs a .DS_Store entry

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]
Loading

Comments Outside Diff (1)

  1. .gitignore, line 7 (link)

    P2 .DS_Store committed and not covered by .gitignore

    The macOS metadata file .DS_Store was introduced in this PR and the .gitignore does not currently exclude it. The PR description acknowledges this with a planned follow-up, but adding the entry here is a one-line fix that prevents the file from being re-committed by any macOS contributor in the future:

Reviews (1): Last reviewed commit: "docs: update roadmap — reflect shipped i..." | Re-trigger Greptile

Comment on lines +17 to +24
"runeflow": ">=0.1.0"
},
"peerDependenciesMeta": {
"@octokit/rest": { "optional": true },
"@linear/sdk": { "optional": true },
"@slack/web-api": { "optional": true },
"@notionhq/client": { "optional": true }
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 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:

Suggested change
"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 }
},

Comment thread src/init.js
Comment on lines +128 to +135
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`);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 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.

Comment thread src/init.js
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";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 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:

Suggested change
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";

@paritoshmmmec paritoshmmmec merged commit 49bfd16 into main Apr 7, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant