set up npx app

This commit is contained in:
Ramnique Singh 2025-11-05 13:28:38 +05:30
parent 3645f92774
commit 776be21fbd
6 changed files with 40 additions and 59 deletions

4
apps/cli/bin/app.js Executable file
View file

@ -0,0 +1,4 @@
#!/usr/bin/env node
import { start } from '../dist/x.js';
start();

View file

@ -1,6 +1,6 @@
{
"name": "cli",
"version": "1.0.0",
"name": "@rowboatlabs/rowboatx",
"version": "0.2.0",
"main": "index.js",
"type": "module",
"scripts": {
@ -8,9 +8,16 @@
"build": "rm -rf dist && tsc",
"copilot": "npm run build && node dist/x.js"
},
"files": [
"dist",
"bin"
],
"bin": {
"rowboatx": "bin/app.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"author": "Rowboat Labs",
"license": "MIT",
"description": "",
"devDependencies": {
"@types/node": "^24.9.1",

View file

@ -2,12 +2,10 @@ import fs from "fs";
import path from "path";
import { z } from "zod";
import { McpServerConfig } from "../../entities/mcp.js";
import { ensureBaseDirs, getStoragePaths } from "../services/storage.js";
import { WorkDir } from "../../config/config.js";
export function mcpConfigPath(): string {
const base = getStoragePaths();
ensureBaseDirs(base);
return path.join(base.workDir, "mcp", "servers.json");
return path.join(WorkDir, "mcp", "servers.json");
}
export function readMcpConfig(): z.infer<typeof McpServerConfig> {

View file

@ -1,48 +1,22 @@
import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";
import { WorkDir } from "../../config/config.js";
export type DirKind = "workflows" | "agents" | "mcp";
export interface StoragePaths {
appRoot: string;
workDir: string; // .rowboat
}
const defaultPaths: StoragePaths = (() => {
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const appRoot = path.resolve(__dirname, "../../../../");
const workDir = path.join(appRoot, ".rowboat");
return { appRoot, workDir };
})();
export function getStoragePaths(): StoragePaths {
return defaultPaths;
}
export function ensureBaseDirs(base: StoragePaths = defaultPaths) {
const ensure = (p: string) => {
if (!fs.existsSync(p)) fs.mkdirSync(p, { recursive: true });
};
ensure(base.workDir);
ensure(path.join(base.workDir, "workflows"));
ensure(path.join(base.workDir, "agents"));
ensure(path.join(base.workDir, "mcp"));
}
export function dirFor(kind: DirKind, base: StoragePaths = defaultPaths): string {
export function dirFor(kind: DirKind): string {
switch (kind) {
case "workflows":
return path.join(base.workDir, "workflows");
return path.join(WorkDir, "workflows");
case "agents":
return path.join(base.workDir, "agents");
return path.join(WorkDir, "agents");
case "mcp":
return path.join(base.workDir, "mcp");
return path.join(WorkDir, "mcp");
}
}
export function listJson(kind: DirKind, base: StoragePaths = defaultPaths): string[] {
const d = dirFor(kind, base);
export function listJson(kind: DirKind): string[] {
const d = dirFor(kind);
if (!fs.existsSync(d)) return [];
return fs
.readdirSync(d)
@ -50,20 +24,20 @@ export function listJson(kind: DirKind, base: StoragePaths = defaultPaths): stri
.map((f) => f.replace(/\.json$/, ""));
}
export function readJson<T>(kind: DirKind, id: string, base: StoragePaths = defaultPaths): T | undefined {
const p = path.join(dirFor(kind, base), `${id}.json`);
export function readJson<T>(kind: DirKind, id: string): T | undefined {
const p = path.join(dirFor(kind), `${id}.json`);
if (!fs.existsSync(p)) return undefined;
const raw = fs.readFileSync(p, "utf8");
return JSON.parse(raw) as T;
}
export function writeJson(kind: DirKind, id: string, value: unknown, base: StoragePaths = defaultPaths): void {
const p = path.join(dirFor(kind, base), `${id}.json`);
export function writeJson(kind: DirKind, id: string, value: unknown): void {
const p = path.join(dirFor(kind), `${id}.json`);
fs.writeFileSync(p, JSON.stringify(value, null, 2) + "\n", "utf8");
}
export function deleteJson(kind: DirKind, id: string, base: StoragePaths = defaultPaths): boolean {
const p = path.join(dirFor(kind, base), `${id}.json`);
export function deleteJson(kind: DirKind, id: string): boolean {
const p = path.join(dirFor(kind), `${id}.json`);
if (!fs.existsSync(p)) return false;
fs.rmSync(p);
return true;

View file

@ -1,13 +1,11 @@
import path from "path";
import fs from "fs";
import { fileURLToPath } from "url";
import { McpServerConfig } from "../entities/mcp.js";
import { z } from "zod";
import { homedir } from "os";
// Resolve app root relative to compiled file location (dist/...)
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const AppRoot = path.resolve(__dirname, "../../..");
export const WorkDir = path.join(AppRoot, ".rowboat");
export const WorkDir = path.join(homedir(), ".rowboat");
function ensureDirs() {
const ensure = (p: string) => { if (!fs.existsSync(p)) fs.mkdirSync(p, { recursive: true }); };
@ -17,8 +15,9 @@ function ensureDirs() {
ensure(path.join(WorkDir, "mcp"));
}
ensureDirs();
function loadMcpServerConfig(): z.infer<typeof McpServerConfig> {
ensureDirs();
const configPath = path.join(WorkDir, "mcp", "servers.json");
if (!fs.existsSync(configPath)) return { mcpServers: [] };
const config = fs.readFileSync(configPath, "utf8");

View file

@ -1,9 +1,8 @@
import { ensureBaseDirs } from "./application/assistant/services/storage.js";
import { startCopilot } from "./application/assistant/chat.js";
ensureBaseDirs();
startCopilot().catch((err) => {
console.error("Failed to run copilot:", err);
process.exitCode = 1;
});
export const start = () => {
startCopilot().catch((err) => {
console.error("Failed to run copilot:", err);
process.exitCode = 1;
});
}