create-claudify 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,76 @@
1
+ # create-claudify
2
+
3
+ Scaffold a production-grade Claude Code systems architecture into any project.
4
+
5
+ Turn Claude Code from a chatbot into an autonomous operating system with memory, hooks, commands, agents, and skills.
6
+
7
+ ## Quick Start
8
+
9
+ ```bash
10
+ npx create-claudify
11
+ ```
12
+
13
+ Answer the prompts. That's it.
14
+
15
+ ## What You Get
16
+
17
+ ```
18
+ your-project/
19
+ ├── CLAUDE.md # Project instructions — Claude reads this first
20
+ ├── CLAUDE.local.md # Personal overrides (gitignored)
21
+ ├── SETUP.md # Getting started guide
22
+ ├── .mcp.json # MCP server config
23
+ └── .claude/
24
+ ├── settings.json # Permissions + hooks
25
+ ├── memory.md # Living session state
26
+ ├── knowledge-base.md # Institutional memory
27
+ ├── knowledge-nominations.md # Candidate learnings pipeline
28
+ ├── command-index.md # Command registry
29
+ ├── commands/ # /start, /sync, /clear, /wrap-up, /audit
30
+ ├── agents/ # auditor + reviewer
31
+ ├── agent-memory/ # Persistent agent knowledge
32
+ ├── skills/ # research, deploy, monitor, data-export, content
33
+ ├── hooks/ # quality-gate, context-monitor, audit-logger
34
+ └── logs/ # Audit trail
35
+ ```
36
+
37
+ ## Features
38
+
39
+ Choose what to include during setup:
40
+
41
+ | System | What it does |
42
+ |---|---|
43
+ | **Memory** | 4-layer architecture: global, project, personal, dynamic. Claude remembers across sessions. |
44
+ | **Commands** | Daily workflow rituals: `/start`, `/sync`, `/clear`, `/wrap-up`, `/audit`. |
45
+ | **Hooks** | Deterministic enforcement: block bad writes, monitor context usage, log all tool calls. |
46
+ | **Agents** | Specialist subagents: auditor (quality gate) + reviewer (read-only QA). |
47
+ | **Skills** | Domain knowledge loaded on demand: research, deploy, monitor, data-export, content. |
48
+ | **MCP** | Pre-configured MCP servers: context7 (live docs) + memory (knowledge graph). |
49
+
50
+ ## Update
51
+
52
+ When we release new templates, commands, or improvements:
53
+
54
+ ```bash
55
+ npx create-claudify update
56
+ ```
57
+
58
+ This updates system files (hooks, commands, agents, skills) without touching your custom content (CLAUDE.md, memory.md, knowledge-base.md, settings.json).
59
+
60
+ ## How It Works
61
+
62
+ 1. **CLAUDE.md** is the routing file — Claude reads it first, follows links to everything else
63
+ 2. **Memory system** gives Claude session state + institutional knowledge
64
+ 3. **Hooks** enforce rules deterministically (no relying on instructions alone)
65
+ 4. **Commands** are repeatable procedures triggered by name
66
+ 5. **Agents** are specialist subprocesses with their own memory
67
+ 6. **Skills** are domain knowledge loaded only when needed
68
+
69
+ ## Requirements
70
+
71
+ - Node.js 18+
72
+ - [Claude Code](https://docs.anthropic.com/en/docs/claude-code) installed
73
+
74
+ ## License
75
+
76
+ MIT
package/dist/index.js ADDED
@@ -0,0 +1,558 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/index.ts
4
+ import * as p2 from "@clack/prompts";
5
+ import pc2 from "picocolors";
6
+ import { basename, resolve } from "path";
7
+
8
+ // src/commands/init.ts
9
+ import { mkdir, writeFile, readFile, chmod } from "fs/promises";
10
+ import { existsSync } from "fs";
11
+ import { join, dirname } from "path";
12
+ import { fileURLToPath } from "url";
13
+
14
+ // src/utils/template.ts
15
+ function processTemplate(content, variables) {
16
+ return content.replace(/\{\{([A-Z_]+)\}\}/g, (match, key) => {
17
+ return variables[key] ?? match;
18
+ });
19
+ }
20
+
21
+ // src/commands/init.ts
22
+ var FEATURE_MAP = {
23
+ memory: [
24
+ ".claude/memory.md",
25
+ ".claude/knowledge-base.md",
26
+ ".claude/knowledge-nominations.md"
27
+ ],
28
+ commands: [
29
+ ".claude/commands/start.md",
30
+ ".claude/commands/sync.md",
31
+ ".claude/commands/clear.md",
32
+ ".claude/commands/wrap-up.md",
33
+ ".claude/commands/audit.md",
34
+ ".claude/command-index.md"
35
+ ],
36
+ hooks: [
37
+ ".claude/hooks/quality-gate.sh",
38
+ ".claude/hooks/context-monitor.sh",
39
+ ".claude/hooks/audit-logger.sh"
40
+ ],
41
+ agents: [
42
+ ".claude/agents/auditor.md",
43
+ ".claude/agents/reviewer.md",
44
+ ".claude/agent-memory/auditor.md"
45
+ ],
46
+ skills: [
47
+ ".claude/skills/research/SKILL.md",
48
+ ".claude/skills/deploy/SKILL.md",
49
+ ".claude/skills/monitor/SKILL.md",
50
+ ".claude/skills/data-export/SKILL.md",
51
+ ".claude/skills/content/SKILL.md"
52
+ ],
53
+ mcp: [
54
+ ".mcp.json"
55
+ ]
56
+ };
57
+ var CORE_FILES = [
58
+ "CLAUDE.md",
59
+ "CLAUDE.local.md",
60
+ "SETUP.md",
61
+ ".claude/settings.json",
62
+ ".claude/logs/.gitkeep"
63
+ ];
64
+ async function scaffoldProject(options) {
65
+ const cwd = process.cwd();
66
+ const templatesDir = getTemplatesDir();
67
+ const variables = buildVariables(options);
68
+ const filesToCreate = [...CORE_FILES];
69
+ for (const feature of options.features) {
70
+ const files = FEATURE_MAP[feature];
71
+ if (files) {
72
+ filesToCreate.push(...files);
73
+ }
74
+ }
75
+ let created = 0;
76
+ let skipped = 0;
77
+ const createdFiles = [];
78
+ for (const relPath of filesToCreate) {
79
+ const targetPath = join(cwd, relPath);
80
+ const templatePath = join(templatesDir, relPath);
81
+ if (options.merge && existsSync(targetPath)) {
82
+ skipped++;
83
+ continue;
84
+ }
85
+ await mkdir(dirname(targetPath), { recursive: true });
86
+ let content;
87
+ try {
88
+ content = await readFile(templatePath, "utf-8");
89
+ } catch {
90
+ continue;
91
+ }
92
+ content = processTemplate(content, variables);
93
+ content = stripUnselectedSections(content, options.features);
94
+ if (relPath === ".claude/settings.json" && !options.features.includes("hooks")) {
95
+ content = stripHooksFromSettings(content);
96
+ }
97
+ await writeFile(targetPath, content, "utf-8");
98
+ created++;
99
+ createdFiles.push(relPath);
100
+ if (relPath.endsWith(".sh")) {
101
+ await chmod(targetPath, 493);
102
+ }
103
+ }
104
+ await appendGitignore(cwd);
105
+ return { created, skipped, files: createdFiles };
106
+ }
107
+ function getTemplatesDir() {
108
+ const __filename = fileURLToPath(import.meta.url);
109
+ const __dirname = dirname(__filename);
110
+ const candidates = [
111
+ join(__dirname, "..", "..", "templates"),
112
+ join(__dirname, "..", "templates")
113
+ ];
114
+ for (const candidate of candidates) {
115
+ if (existsSync(candidate)) return candidate;
116
+ }
117
+ return candidates[0];
118
+ }
119
+ function buildVariables(options) {
120
+ const now = /* @__PURE__ */ new Date();
121
+ const lineCount = "~90";
122
+ return {
123
+ PROJECT_NAME: options.name,
124
+ PROJECT_DESCRIPTION: options.description,
125
+ TECH_STACK: options.techStack,
126
+ BUILD_COMMAND: options.buildCommand,
127
+ TEST_COMMAND: options.testCommand,
128
+ LINT_COMMAND: options.lintCommand,
129
+ CODE_CONVENTIONS: options.conventions || "No specific conventions configured. Add your team's standards here.",
130
+ LINE_COUNT: lineCount,
131
+ DATE: now.toISOString().split("T")[0],
132
+ YEAR: String(now.getFullYear())
133
+ };
134
+ }
135
+ function stripUnselectedSections(content, features) {
136
+ const allFeatures = ["memory", "commands", "hooks", "agents", "skills", "mcp"];
137
+ for (const feature of allFeatures) {
138
+ const regex = new RegExp(`\\{\\{#if ${feature}\\}\\}([\\s\\S]*?)\\{\\{/if\\}\\}`, "g");
139
+ if (features.includes(feature)) {
140
+ content = content.replace(regex, "$1");
141
+ } else {
142
+ content = content.replace(regex, "");
143
+ }
144
+ }
145
+ return content;
146
+ }
147
+ function stripHooksFromSettings(content) {
148
+ try {
149
+ const settings = JSON.parse(content);
150
+ delete settings.hooks;
151
+ return JSON.stringify(settings, null, 2) + "\n";
152
+ } catch {
153
+ return content;
154
+ }
155
+ }
156
+ async function appendGitignore(cwd) {
157
+ const gitignorePath = join(cwd, ".gitignore");
158
+ const entries = [
159
+ "",
160
+ "# Claudify \u2014 personal & runtime files",
161
+ "CLAUDE.local.md",
162
+ ".claude/logs/",
163
+ ".claude/agent-memory/",
164
+ ".claude/hooks/__counter"
165
+ ];
166
+ const block = entries.join("\n") + "\n";
167
+ if (existsSync(gitignorePath)) {
168
+ const existing = await readFile(gitignorePath, "utf-8");
169
+ if (existing.includes("# Claudify")) return;
170
+ await writeFile(gitignorePath, existing + "\n" + block, "utf-8");
171
+ } else {
172
+ await writeFile(gitignorePath, block, "utf-8");
173
+ }
174
+ }
175
+
176
+ // src/commands/update.ts
177
+ import * as p from "@clack/prompts";
178
+ import pc from "picocolors";
179
+ import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2, chmod as chmod2 } from "fs/promises";
180
+ import { existsSync as existsSync2 } from "fs";
181
+ import { join as join3, dirname as dirname3 } from "path";
182
+ import { fileURLToPath as fileURLToPath3 } from "url";
183
+
184
+ // src/utils/version.ts
185
+ import { readFileSync } from "fs";
186
+ import { join as join2, dirname as dirname2 } from "path";
187
+ import { fileURLToPath as fileURLToPath2 } from "url";
188
+ var cachedVersion = null;
189
+ function getVersion() {
190
+ if (cachedVersion) return cachedVersion;
191
+ try {
192
+ const __filename = fileURLToPath2(import.meta.url);
193
+ const __dirname = dirname2(__filename);
194
+ const candidates = [
195
+ join2(__dirname, "..", "package.json"),
196
+ join2(__dirname, "..", "..", "package.json")
197
+ ];
198
+ for (const candidate of candidates) {
199
+ try {
200
+ const pkg = JSON.parse(readFileSync(candidate, "utf-8"));
201
+ if (pkg.version && pkg.name === "create-claudify") {
202
+ cachedVersion = pkg.version;
203
+ return pkg.version;
204
+ }
205
+ } catch {
206
+ continue;
207
+ }
208
+ }
209
+ } catch {
210
+ }
211
+ cachedVersion = "0.0.0";
212
+ return "0.0.0";
213
+ }
214
+
215
+ // src/commands/update.ts
216
+ async function updateProject() {
217
+ const cwd = process.cwd();
218
+ if (!existsSync2(join3(cwd, ".claude"))) {
219
+ p.log.error("No .claude/ directory found. Run `npx create-claudify` first to set up your project.");
220
+ process.exit(1);
221
+ }
222
+ p.log.info(`Checking for updates...`);
223
+ const templatesDir = getTemplatesDir2();
224
+ const UPDATABLE_FILES = [
225
+ // Hooks — always safe to update (deterministic scripts)
226
+ ".claude/hooks/quality-gate.sh",
227
+ ".claude/hooks/context-monitor.sh",
228
+ ".claude/hooks/audit-logger.sh",
229
+ // Command procedures — safe to update
230
+ ".claude/commands/start.md",
231
+ ".claude/commands/sync.md",
232
+ ".claude/commands/clear.md",
233
+ ".claude/commands/wrap-up.md",
234
+ ".claude/commands/audit.md",
235
+ ".claude/command-index.md",
236
+ // Agent definitions — safe to update
237
+ ".claude/agents/auditor.md",
238
+ ".claude/agents/reviewer.md",
239
+ // Skills — safe to update
240
+ ".claude/skills/research/SKILL.md",
241
+ ".claude/skills/deploy/SKILL.md",
242
+ ".claude/skills/monitor/SKILL.md",
243
+ ".claude/skills/data-export/SKILL.md",
244
+ ".claude/skills/content/SKILL.md",
245
+ // Setup guide
246
+ "SETUP.md"
247
+ ];
248
+ const updates = [];
249
+ const unchanged = [];
250
+ for (const relPath of UPDATABLE_FILES) {
251
+ const templatePath = join3(templatesDir, relPath);
252
+ const targetPath = join3(cwd, relPath);
253
+ if (!existsSync2(templatePath)) continue;
254
+ if (!existsSync2(targetPath)) continue;
255
+ const templateContent = await readFile2(templatePath, "utf-8");
256
+ const currentContent = await readFile2(targetPath, "utf-8");
257
+ if (templateContent !== currentContent) {
258
+ updates.push(relPath);
259
+ } else {
260
+ unchanged.push(relPath);
261
+ }
262
+ }
263
+ const ALL_TEMPLATE_FILES = await getTemplateFileList(templatesDir);
264
+ const newFiles = [];
265
+ for (const relPath of ALL_TEMPLATE_FILES) {
266
+ const targetPath = join3(cwd, relPath);
267
+ if (!existsSync2(targetPath)) {
268
+ newFiles.push(relPath);
269
+ }
270
+ }
271
+ if (updates.length === 0 && newFiles.length === 0) {
272
+ p.log.success("Everything is up to date!");
273
+ p.outro(`${pc.dim("v" + getVersion())}`);
274
+ return;
275
+ }
276
+ if (updates.length > 0) {
277
+ p.note(
278
+ updates.map((f) => `${pc.yellow("~")} ${f}`).join("\n"),
279
+ `${updates.length} file${updates.length === 1 ? "" : "s"} to update`
280
+ );
281
+ }
282
+ if (newFiles.length > 0) {
283
+ p.note(
284
+ newFiles.map((f) => `${pc.green("+")} ${f}`).join("\n"),
285
+ `${newFiles.length} new file${newFiles.length === 1 ? "" : "s"} available`
286
+ );
287
+ }
288
+ const confirmed = await p.confirm({
289
+ message: "Apply updates?",
290
+ initialValue: true
291
+ });
292
+ if (p.isCancel(confirmed) || !confirmed) {
293
+ p.cancel("Update cancelled.");
294
+ process.exit(0);
295
+ }
296
+ const s = p.spinner();
297
+ s.start("Applying updates...");
298
+ let count = 0;
299
+ for (const relPath of updates) {
300
+ const templatePath = join3(templatesDir, relPath);
301
+ const targetPath = join3(cwd, relPath);
302
+ const content = await readFile2(templatePath, "utf-8");
303
+ await writeFile2(targetPath, content, "utf-8");
304
+ if (relPath.endsWith(".sh")) {
305
+ await chmod2(targetPath, 493);
306
+ }
307
+ count++;
308
+ }
309
+ for (const relPath of newFiles) {
310
+ const templatePath = join3(templatesDir, relPath);
311
+ const targetPath = join3(cwd, relPath);
312
+ await mkdir2(dirname3(targetPath), { recursive: true });
313
+ const content = await readFile2(templatePath, "utf-8");
314
+ await writeFile2(targetPath, content, "utf-8");
315
+ if (relPath.endsWith(".sh")) {
316
+ await chmod2(targetPath, 493);
317
+ }
318
+ count++;
319
+ }
320
+ s.stop(`Updated ${count} file${count === 1 ? "" : "s"}.`);
321
+ p.note(
322
+ [
323
+ `${pc.dim("Updated files do not contain your custom variables.")}`,
324
+ `${pc.dim("Your CLAUDE.md, memory.md, and settings.json are untouched.")}`
325
+ ].join("\n"),
326
+ "Note"
327
+ );
328
+ p.outro(pc.green("Update complete."));
329
+ }
330
+ function getTemplatesDir2() {
331
+ const __filename = fileURLToPath3(import.meta.url);
332
+ const __dirname = dirname3(__filename);
333
+ const candidates = [
334
+ join3(__dirname, "..", "..", "templates"),
335
+ join3(__dirname, "..", "templates")
336
+ ];
337
+ for (const candidate of candidates) {
338
+ if (existsSync2(candidate)) return candidate;
339
+ }
340
+ return candidates[0];
341
+ }
342
+ async function getTemplateFileList(dir, base = "") {
343
+ const { readdir: readdir2, stat: stat2 } = await import("fs/promises");
344
+ const files = [];
345
+ const entries = await readdir2(dir);
346
+ for (const entry of entries) {
347
+ const fullPath = join3(dir, entry);
348
+ const relPath = base ? join3(base, entry) : entry;
349
+ const s = await stat2(fullPath);
350
+ if (s.isDirectory()) {
351
+ files.push(...await getTemplateFileList(fullPath, relPath));
352
+ } else {
353
+ files.push(relPath);
354
+ }
355
+ }
356
+ return files;
357
+ }
358
+
359
+ // src/index.ts
360
+ var args = process.argv.slice(2);
361
+ var command = args[0];
362
+ async function main() {
363
+ console.log();
364
+ p2.intro(`${pc2.bgCyan(pc2.black(" create-claudify "))} ${pc2.dim(`v${getVersion()}`)}`);
365
+ if (command === "update") {
366
+ await updateProject();
367
+ return;
368
+ }
369
+ if (command === "--version" || command === "-v") {
370
+ console.log(getVersion());
371
+ process.exit(0);
372
+ }
373
+ if (command === "--help" || command === "-h") {
374
+ printHelp();
375
+ process.exit(0);
376
+ }
377
+ await runInit();
378
+ }
379
+ async function runInit() {
380
+ const { existsSync: existsSync3 } = await import("fs");
381
+ const hasExisting = existsSync3(".claude");
382
+ if (hasExisting) {
383
+ const shouldContinue = await p2.confirm({
384
+ message: "Existing .claude/ directory detected. Claudify will merge without overwriting your files. Continue?",
385
+ initialValue: true
386
+ });
387
+ if (p2.isCancel(shouldContinue) || !shouldContinue) {
388
+ p2.cancel("Setup cancelled.");
389
+ process.exit(0);
390
+ }
391
+ }
392
+ const project = await p2.group(
393
+ {
394
+ name: () => p2.text({
395
+ message: "Project name",
396
+ placeholder: getDirectoryName(),
397
+ defaultValue: getDirectoryName(),
398
+ validate: (v) => {
399
+ if (!v.trim()) return "Project name is required";
400
+ }
401
+ }),
402
+ description: () => p2.text({
403
+ message: "What does this project do? (one sentence)",
404
+ placeholder: "A SaaS platform for...",
405
+ validate: (v) => {
406
+ if (!v.trim()) return "A brief description helps Claude understand context";
407
+ }
408
+ }),
409
+ techStack: () => p2.text({
410
+ message: "Tech stack",
411
+ placeholder: "Next.js, TypeScript, Prisma, PostgreSQL",
412
+ validate: (v) => {
413
+ if (!v.trim()) return "Tech stack helps Claude write correct code";
414
+ }
415
+ }),
416
+ buildCommand: () => p2.text({
417
+ message: "Build command",
418
+ placeholder: "npm run build",
419
+ defaultValue: "npm run build"
420
+ }),
421
+ testCommand: () => p2.text({
422
+ message: "Test command",
423
+ placeholder: "npm test",
424
+ defaultValue: "npm test"
425
+ }),
426
+ lintCommand: () => p2.text({
427
+ message: "Lint command",
428
+ placeholder: "npm run lint",
429
+ defaultValue: "npm run lint"
430
+ })
431
+ },
432
+ {
433
+ onCancel: () => {
434
+ p2.cancel("Setup cancelled.");
435
+ process.exit(0);
436
+ }
437
+ }
438
+ );
439
+ const features = await p2.multiselect({
440
+ message: "What systems do you want to include?",
441
+ required: true,
442
+ options: [
443
+ {
444
+ value: "memory",
445
+ label: "Memory system",
446
+ hint: "memory.md + knowledge-base.md \u2014 session state & institutional memory"
447
+ },
448
+ {
449
+ value: "commands",
450
+ label: "Commands",
451
+ hint: "/start, /sync, /clear, /wrap-up, /audit \u2014 daily workflow rituals"
452
+ },
453
+ {
454
+ value: "hooks",
455
+ label: "Hooks",
456
+ hint: "quality gate, context monitor, audit logger \u2014 deterministic enforcement"
457
+ },
458
+ {
459
+ value: "agents",
460
+ label: "Agents",
461
+ hint: "auditor + reviewer \u2014 specialist subagents with persistent memory"
462
+ },
463
+ {
464
+ value: "skills",
465
+ label: "Skills",
466
+ hint: "research, deploy, monitor, data-export, content \u2014 domain knowledge"
467
+ },
468
+ {
469
+ value: "mcp",
470
+ label: "MCP config",
471
+ hint: ".mcp.json with context7 + memory servers pre-configured"
472
+ }
473
+ ],
474
+ initialValues: ["memory", "commands", "hooks", "agents", "skills", "mcp"]
475
+ });
476
+ if (p2.isCancel(features)) {
477
+ p2.cancel("Setup cancelled.");
478
+ process.exit(0);
479
+ }
480
+ const conventions = await p2.text({
481
+ message: "Code conventions (optional \u2014 press Enter to skip)",
482
+ placeholder: "e.g. Use functional components, prefer const, no default exports...",
483
+ defaultValue: ""
484
+ });
485
+ if (p2.isCancel(conventions)) {
486
+ p2.cancel("Setup cancelled.");
487
+ process.exit(0);
488
+ }
489
+ p2.note(
490
+ [
491
+ `${pc2.cyan("Project:")} ${project.name}`,
492
+ `${pc2.cyan("Stack:")} ${project.techStack}`,
493
+ `${pc2.cyan("Features:")} ${features.join(", ")}`,
494
+ `${pc2.cyan("Build:")} ${project.buildCommand}`,
495
+ `${pc2.cyan("Test:")} ${project.testCommand}`
496
+ ].join("\n"),
497
+ "Configuration"
498
+ );
499
+ const confirmed = await p2.confirm({
500
+ message: "Create your Claude Code operating system?",
501
+ initialValue: true
502
+ });
503
+ if (p2.isCancel(confirmed) || !confirmed) {
504
+ p2.cancel("Setup cancelled.");
505
+ process.exit(0);
506
+ }
507
+ const s = p2.spinner();
508
+ s.start("Creating your Claude Code operating system...");
509
+ try {
510
+ const result = await scaffoldProject({
511
+ name: project.name,
512
+ description: project.description,
513
+ techStack: project.techStack,
514
+ buildCommand: project.buildCommand,
515
+ testCommand: project.testCommand,
516
+ lintCommand: project.lintCommand,
517
+ conventions,
518
+ features,
519
+ merge: hasExisting
520
+ });
521
+ s.stop(`Done! ${result.created} files created${result.skipped > 0 ? `, ${result.skipped} skipped (already exist)` : ""}.`);
522
+ p2.note(
523
+ [
524
+ `${pc2.green("1.")} Open this project in Claude Code`,
525
+ `${pc2.green("2.")} Run ${pc2.cyan("/start")} to begin your first session`,
526
+ `${pc2.green("3.")} Read ${pc2.dim("SETUP.md")} for the full guide`,
527
+ "",
528
+ `${pc2.dim("Update later:")} npx create-claudify update`
529
+ ].join("\n"),
530
+ "Next steps"
531
+ );
532
+ p2.outro(`${pc2.green("Your Claude Code operating system is ready.")} ${pc2.dim("\u2014 claudify.dev")}`);
533
+ } catch (err) {
534
+ s.stop("Failed.");
535
+ p2.log.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
536
+ process.exit(1);
537
+ }
538
+ }
539
+ function getDirectoryName() {
540
+ return basename(resolve("."));
541
+ }
542
+ function printHelp() {
543
+ console.log(`
544
+ ${pc2.bold("create-claudify")} \u2014 Claude Code Systems Architecture
545
+
546
+ ${pc2.cyan("Usage:")}
547
+ npx create-claudify Scaffold a new project
548
+ npx create-claudify update Update to latest templates
549
+
550
+ ${pc2.cyan("Options:")}
551
+ -v, --version Show version
552
+ -h, --help Show this help
553
+ `);
554
+ }
555
+ main().catch((err) => {
556
+ console.error(err);
557
+ process.exit(1);
558
+ });
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "create-claudify",
3
+ "version": "1.0.0",
4
+ "description": "Scaffold a production-grade Claude Code systems architecture into any project",
5
+ "type": "module",
6
+ "bin": {
7
+ "create-claudify": "./dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist",
11
+ "templates"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsup",
15
+ "dev": "tsup --watch",
16
+ "typecheck": "tsc --noEmit"
17
+ },
18
+ "keywords": [
19
+ "claude",
20
+ "claude-code",
21
+ "ai",
22
+ "llm",
23
+ "scaffolding",
24
+ "cli",
25
+ "developer-tools",
26
+ "systems-architecture"
27
+ ],
28
+ "author": "HYAD <hello@hyad.co.uk>",
29
+ "license": "MIT",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "https://github.com/byldpartners/claudify.git",
33
+ "directory": "cli"
34
+ },
35
+ "homepage": "https://claudify.dev",
36
+ "engines": {
37
+ "node": ">=18.0.0"
38
+ },
39
+ "dependencies": {
40
+ "@clack/prompts": "^0.9.1",
41
+ "picocolors": "^1.1.1"
42
+ },
43
+ "devDependencies": {
44
+ "tsup": "^8.4.0",
45
+ "typescript": "^5.7.0"
46
+ }
47
+ }
@@ -0,0 +1,16 @@
1
+ # Auditor Memory
2
+
3
+ Persistent knowledge for the auditor agent. Survives across sessions.
4
+ Read at startup, write learnings after each audit.
5
+
6
+ ## Known Patterns
7
+
8
+ - [Patterns you've seen repeatedly — e.g., "imports often miss newly created files"]
9
+
10
+ ## Common Failures
11
+
12
+ - [Failure modes you've caught — helps prioritize what to check first]
13
+
14
+ ## Audit History
15
+
16
+ - [MMDDYY] Audited [scope]: [result summary]