Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ node_modules
dist
build
packages/cli-js/templates
packages/cli-js/core
npm-debug.log

# python
Expand Down
5 changes: 2 additions & 3 deletions packages/cli-js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,19 @@
"publishConfig": {
"access": "public"
},
"files": ["dist", "templates", "README.md"],
"files": ["dist", "templates", "core", "README.md"],
"bin": {
"planforge": "dist/index.js"
},
"scripts": {
"check:templates": "node scripts/check-templates.js",
"build": "pnpm run check:templates && tsc && node scripts/copy-templates.js",
"build": "pnpm run check:templates && tsc && node scripts/copy-templates.js && node scripts/copy-core.js",
"dev": "tsc --watch",
"planforge": "node dist/index.js",
"install:global": "pnpm run build && npm install -g .",
"prepublishOnly": "pnpm run build"
},
"dependencies": {
"@planforge/core": "file:../core",
"@daun_jung/korean-romanizer": "^1.0.1",
"commander": "^12.0.0",
"fs-extra": "^11.2.0"
Expand Down
8 changes: 0 additions & 8 deletions packages/cli-js/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions packages/cli-js/scripts/copy-core.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* Copy @planforge/core content (prompts, models.json) into packages/cli-js/core so the published npm package contains them.
* Run from packages/cli-js (e.g. node scripts/copy-core.js).
*/
import { cpSync, mkdirSync, existsSync } from "fs";
import { resolve, dirname } from "path";
import { fileURLToPath } from "url";

const __dirname = dirname(fileURLToPath(import.meta.url));
const repoRoot = resolve(__dirname, "..", "..", "..");
const corePkg = resolve(repoRoot, "packages", "core");
const dest = resolve(__dirname, "..", "core");
const promptsSrc = resolve(corePkg, "prompts");
const modelsSrc = resolve(corePkg, "models.json");

if (!existsSync(promptsSrc) || !existsSync(modelsSrc)) {
console.error("copy-core: packages/core/prompts or models.json not found");
process.exit(1);
}
mkdirSync(dest, { recursive: true });
cpSync(promptsSrc, resolve(dest, "prompts"), { recursive: true });
cpSync(modelsSrc, resolve(dest, "models.json"));
console.log("copy-core: copied core to", dest);
2 changes: 1 addition & 1 deletion packages/cli-js/src/commands/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export function loadModelsCatalog(): ModelsCatalog {
const filePath = existsSync(path) ? path : existsSync(fallback) ? fallback : null;
if (!filePath) {
throw new Error(
`models.json not found. Tried: ${path} and ${fallback}. Check @planforge/core package or run from repo root.`
`models.json not found. Tried: ${path} and ${fallback}. Run pnpm run build in cli-js or reinstall planforge.`
);
}
return fs.readJsonSync(filePath) as ModelsCatalog;
Expand Down
21 changes: 11 additions & 10 deletions packages/cli-js/src/utils/paths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@
import { existsSync } from "fs";
import { resolve, dirname } from "path";
import { fileURLToPath } from "url";
import { createRequire } from "module";

const __dirname = dirname(fileURLToPath(import.meta.url));
const require = createRequire(import.meta.url);

/**
* Find project root by walking up from cwd until we find planforge.json or .cursor/plans or .cursor/contexts.
Expand Down Expand Up @@ -71,19 +69,22 @@ export function getTemplatesRoot(): string {
}

/**
* Resolve prompts directory from @planforge/core package (for planner/implementer system prompts).
* Resolve core root (prompts, models.json). Always uses the bundled copy at package root; no @planforge/core dependency.
*/
function getCoreRoot(): string {
return resolve(__dirname, "..", "..", "core");
}

/**
* Resolve prompts directory (planner/implementer system prompts). Uses bundled core from build.
*/
export function getPromptsDir(): string {
const corePackageJson = require.resolve("@planforge/core/package.json");
const coreRoot = dirname(corePackageJson);
return resolve(coreRoot, "prompts");
return resolve(getCoreRoot(), "prompts");
}

/**
* Resolve models.json path from @planforge/core package (for planforge model command).
* Resolve models.json path (planforge model command). Uses bundled core from build.
*/
export function getModelsJsonPath(): string {
const corePackageJson = require.resolve("@planforge/core/package.json");
const coreRoot = dirname(corePackageJson);
return resolve(coreRoot, "models.json");
return resolve(getCoreRoot(), "models.json");
}
Loading