Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion docs/README-python-client.md
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,7 @@ asyncio.run(main())
The `rocketride` command is installed automatically with the package.

```bash
rocketride init # Scaffold .rocketride/ in the current directory
rocketride start pipeline.json # Start a pipeline
rocketride upload *.pdf --token <token> # Upload files to a running pipeline
rocketride status --token <token> # Monitor task progress
Expand All @@ -536,7 +537,8 @@ rocketride events ALL --token <token> # Stream task events
rocketride rrext_store get_all_projects # List stored projects
```

All commands accept `--uri` and `--apikey` flags, or read from environment variables.
`rocketride init` runs entirely offline — it creates `.rocketride/docs/`, installs agent stubs (CLAUDE.md, cursor rules, etc.) for any detected coding agents, and adds `.rocketride/` to `.gitignore`. Pass `--agent <name>` to force a specific stub or `--no-agents` to skip them.
All other commands accept `--uri` and `--apikey` flags, or read from environment variables.

## Configuration

Expand Down
6 changes: 5 additions & 1 deletion packages/client-python/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,8 @@ where = ["src"]
include = ["rocketride*"]

[tool.setuptools.package-data]
rocketride = ["py.typed"]
rocketride = [
"py.typed",
"cli/templates/docs/*.md",
"cli/templates/stubs/*",
]
48 changes: 43 additions & 5 deletions packages/client-python/scripts/tasks.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@
* clean - Remove build artifacts
*/
const path = require('path');
const { execCommand, syncDir, formatSyncStats, removeDirs, removeMatching, removeDirAndParents, PROJECT_ROOT, BUILD_ROOT, DIST_ROOT, mkdir, copyFile, exists, startServer, stopServer, bracket, parallel, hasSourceChanged, saveSourceHash, setState } = require('../../../scripts/lib');
const crypto = require('crypto');
const fsp = require('fs').promises;
const { execCommand, syncDir, formatSyncStats, removeDirs, removeMatching, removeDirAndParents, PROJECT_ROOT, BUILD_ROOT, DIST_ROOT, mkdir, copyFile, exists, startServer, stopServer, bracket, parallel, fingerprint, saveSourceHash, getState, setState } = require('../../../scripts/lib');

const PACKAGE_DIR = path.join(__dirname, '..');
const SRC_DIR = path.join(PACKAGE_DIR, 'src', 'rocketride');
Expand All @@ -52,6 +54,13 @@ const DOCS_DIR = path.join(PROJECT_ROOT, 'docs');
const README_SRC = path.join(DOCS_DIR, 'README-python-client.md');
const README_DEST = path.join(BUILD_DIR, 'README.md');

// Init ships the agent docs and stubs as wheel package data;
// Source of truth lives in the repo at docs/agents/ + docs/stubs/; the build
// copies them into BUILD_DIR so they end up at the package_data path declared
const AGENT_DOCS_SRC = path.join(DOCS_DIR, 'agents');
const AGENT_STUBS_SRC = path.join(DOCS_DIR, 'stubs');
const TEMPLATES_DEST_BASE = path.join(BUILD_DIR, 'src', 'rocketride', 'cli', 'templates');

// ============================================================================
// Action Factories
// ============================================================================
Expand All @@ -65,6 +74,16 @@ function makeCopyReadmeAction() {
};
}

function makeCopyInitTemplatesAction() {
return {
run: async (ctx, task) => {
const docsStats = await syncDir(AGENT_DOCS_SRC, path.join(TEMPLATES_DEST_BASE, 'docs'), { package: true });
const stubsStats = await syncDir(AGENT_STUBS_SRC, path.join(TEMPLATES_DEST_BASE, 'stubs'), { package: true });
task.output = `docs: ${formatSyncStats(docsStats)} | stubs: ${formatSyncStats(stubsStats)}`;
},
Comment on lines +79 to +83
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Prefix the unused action context with _.

ctx is never read in this action, so the new code drifts from the repo’s JS convention for unused variables.

♻️ Proposed fix
-		run: async (ctx, task) => {
+		run: async (_ctx, task) => {

As per coding guidelines, "Unused variables must be prefixed with underscore (_)."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/client-python/scripts/tasks.js` around lines 79 - 83, The action
callback parameter `ctx` is unused and should follow the repo convention for
unused variables; rename the parameter in the `run` async function from `ctx` to
`_ctx` (i.e., change `run: async (ctx, task) => { ... }` to `run: async (_ctx,
task) => { ... }`) and ensure there are no remaining references to `ctx` in the
function body so linters pass.

};
}

function makeSyncClientPythonAction() {
return {
run: async (ctx, task) => {
Expand All @@ -88,14 +107,32 @@ function makeWheelSourceAction() {
// State key for source fingerprint
const SRC_HASH_KEY = 'client-python.srcHash';

// Inputs that affect wheel contents — keep in sync with the wheel-build steps.
// SRC_DIR is the package source; AGENT_DOCS_SRC + AGENT_STUBS_SRC are bundled
// into the wheel as `cli/templates/` package data; README_SRC is copied to
// BUILD_DIR/README.md before `python -m build` runs.
async function computeWheelInputsHash() {
const dirHashes = await Promise.all([fingerprint(SRC_DIR), fingerprint(AGENT_DOCS_SRC), fingerprint(AGENT_STUBS_SRC)]);
let readmeStat = '';
try {
const s = await fsp.stat(README_SRC);
readmeStat = `${s.size}:${s.mtimeMs}`;
} catch {
readmeStat = 'missing';
}
const combined = [...dirHashes.map((h) => h ?? 'missing'), readmeStat].join('|');
return crypto.createHash('md5').update(combined).digest('hex');
}

function makeWheelBuildAction() {
return {
run: async (ctx, task) => {
// Check if source changed
const { changed, hash } = await hasSourceChanged(SRC_DIR, SRC_HASH_KEY);
// Check if any wheel input (src, agent docs/stubs, README) changed
const hash = await computeWheelInputsHash();
const savedHash = await getState(SRC_HASH_KEY);
const outputExists = await exists(DIST_DIR);

if (!changed && outputExists) {
if (hash === savedHash && outputExists) {
task.output = 'No changes detected';
Comment thread
coderabbitai[bot] marked this conversation as resolved.
return;
}
Expand Down Expand Up @@ -223,6 +260,7 @@ module.exports = {
actions: [
// Internal actions
{ name: 'client-python:copy-readme', action: makeCopyReadmeAction },
{ name: 'client-python:copy-init-templates', action: makeCopyInitTemplatesAction },
{ name: 'client-python:sync-source', action: makeSyncClientPythonAction },
{ name: 'client-python:wheel-source', action: makeWheelSourceAction },
{ name: 'client-python:wheel-build', action: makeWheelBuildAction },
Expand All @@ -236,7 +274,7 @@ module.exports = {
name: 'client-python:build',
action: () => ({
description: 'Build Python client',
steps: ['server:build', 'client-python:sync-source', 'client-python:wheel-source', 'client-python:copy-readme', 'client-python:wheel-build', 'client-python:sync'],
steps: ['server:build', 'client-python:sync-source', 'client-python:wheel-source', 'client-python:copy-readme', 'client-python:copy-init-templates', 'client-python:wheel-build', 'client-python:sync'],
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}),
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
from .events import EventsCommand
from .list import ListCommand
from .store import StoreCommand
from .init import InitCommand

__all__ = [
'StartCommand',
Expand All @@ -52,4 +53,5 @@
'EventsCommand',
'ListCommand',
'StoreCommand',
'InitCommand',
]
Loading
Loading