-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathindex.js
More file actions
96 lines (76 loc) · 3.06 KB
/
Copy pathindex.js
File metadata and controls
96 lines (76 loc) · 3.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#!/usr/bin/env node
import { cpSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
import { basename, join, resolve } from "node:path";
import { fileURLToPath } from "node:url";
const args = process.argv.slice(2);
const flags = new Set(args.filter((a) => a.startsWith("--")));
const positional = args.filter((a) => !a.startsWith("--"));
if (flags.has("--help") || flags.has("-h")) {
console.log(`
Usage: pnpm create @health-samurai/react-app <project-name> [options]
Options:
--aidbox Include @health-samurai/aidbox-client
--codegen Include FHIR type generation (scripts/generate-types.ts)
--skills Add CLAUDE.md + a postinstall that syncs the design-system skills
--help, -h Show this help message
`);
process.exit(0);
}
const targetName = positional[0];
if (!targetName) {
console.error("Usage: pnpm create @health-samurai/react-app <project-name> [options]");
process.exit(1);
}
const targetDir = resolve(targetName);
if (existsSync(targetDir)) {
console.error(`Directory "${targetName}" already exists.`);
process.exit(1);
}
const dir = fileURLToPath(new URL(".", import.meta.url));
const templateDir = join(dir, "template");
mkdirSync(targetDir, { recursive: true });
cpSync(templateDir, targetDir, { recursive: true });
if (!flags.has("--skills")) {
rmSync(join(targetDir, "CLAUDE.md"), { force: true });
}
const pkgPath = join(targetDir, "package.json");
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
pkg.name = basename(targetDir);
if (flags.has("--skills")) {
// Skills ship inside @health-samurai/react-components; sync them into
// .claude/skills/ on install so they always match the package version.
pkg.scripts = { postinstall: "hs-react-components sync-skills", ...pkg.scripts };
}
if (!flags.has("--aidbox")) {
delete pkg.dependencies["@health-samurai/aidbox-client"];
}
if (!flags.has("--codegen")) {
delete pkg.scripts["generate-types"];
delete pkg.devDependencies["@atomic-ehr/codegen"];
delete pkg.devDependencies["tsx"];
rmSync(join(targetDir, "scripts"), { recursive: true, force: true });
}
writeFileSync(pkgPath, JSON.stringify(pkg, null, "\t") + "\n");
if (flags.has("--skills")) {
const claudePath = join(targetDir, "CLAUDE.md");
let claude = readFileSync(claudePath, "utf-8");
const sections = [];
if (flags.has("--codegen")) {
sections.push("## FHIR Types\n\nGenerated via `@atomic-ehr/codegen` into `src/fhir-types/`.\n\n```bash\npnpm generate-types\n```\n\nEdit `scripts/generate-types.ts` to configure which resources to include.");
}
if (flags.has("--aidbox")) {
sections.push("## Aidbox Client\n\n`@health-samurai/aidbox-client` provides a typed FHIR client with `Result<T, E>` error handling.");
}
if (sections.length > 0) {
claude = claude.replace("## Components", sections.join("\n\n") + "\n\n## Components");
}
writeFileSync(claudePath, claude);
}
console.log(`\nCreated "${targetName}".\n`);
console.log("Next steps:\n");
console.log(` cd ${targetName}`);
console.log(" pnpm install");
if (flags.has("--codegen")) {
console.log(" pnpm generate-types");
}
console.log(" pnpm dev\n");