@withmata/blueprints 0.2.0 → 0.3.1

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/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/index.ts
4
- import { intro, outro, log as log5 } from "@clack/prompts";
5
- import pc2 from "picocolors";
4
+ import { intro as intro2, outro as outro2, log as log6 } from "@clack/prompts";
5
+ import pc3 from "picocolors";
6
6
 
7
7
  // src/constants.ts
8
8
  var API_URL = process.env["WITHMATA_API_URL"] || "https://blueprints.withmata.dev";
9
- var VERSION = "0.2.0";
9
+ var VERSION = "0.3.1";
10
10
 
11
11
  // src/steps/auth.ts
12
12
  import { log } from "@clack/prompts";
@@ -27,6 +27,15 @@ var WITHMATA_DIR = join(homedir(), ".withmata");
27
27
  var BLUEPRINTS_DIR = join(WITHMATA_DIR, "blueprints");
28
28
  var CREDENTIALS_PATH = join(WITHMATA_DIR, "credentials.json");
29
29
  var CONFIG_PATH = join(WITHMATA_DIR, "config.json");
30
+ var SKILLS_SOURCE_DIR = join(BLUEPRINTS_DIR, ".claude", "skills");
31
+ var CLAUDE_SKILLS_DIR = join(homedir(), ".claude", "skills");
32
+ var OPENCODE_SKILLS_DIR = join(
33
+ homedir(),
34
+ ".config",
35
+ "opencode",
36
+ "skills"
37
+ );
38
+ var CURSOR_SKILLS_DIR = join(homedir(), ".cursor", "skills");
30
39
  var CLAUDE_COMMANDS_DIR = ".claude/commands";
31
40
  var OPENCODE_COMMANDS_DIR = ".opencode/commands";
32
41
  var CURSOR_COMMANDS_DIR = ".cursor/commands";
@@ -149,23 +158,11 @@ async function downloadBlueprints(_token) {
149
158
  recursive: true
150
159
  });
151
160
  }
152
- const claudeCommandsSource = join3(sourcePath, ".claude", "commands");
153
- if (existsSync3(claudeCommandsSource)) {
154
- const target = join3(BLUEPRINTS_DIR, ".claude", "commands");
155
- mkdirSync2(target, { recursive: true });
156
- cpSync(claudeCommandsSource, target, { recursive: true });
157
- }
158
- const opencodeCommandsSource = join3(sourcePath, ".opencode", "commands");
159
- if (existsSync3(opencodeCommandsSource)) {
160
- const target = join3(BLUEPRINTS_DIR, ".opencode", "commands");
161
- mkdirSync2(target, { recursive: true });
162
- cpSync(opencodeCommandsSource, target, { recursive: true });
163
- }
164
- const cursorCommandsSource = join3(sourcePath, ".cursor", "commands");
165
- if (existsSync3(cursorCommandsSource)) {
166
- const target = join3(BLUEPRINTS_DIR, ".cursor", "commands");
161
+ const skillsSource = join3(sourcePath, ".claude", "skills");
162
+ if (existsSync3(skillsSource)) {
163
+ const target = join3(BLUEPRINTS_DIR, ".claude", "skills");
167
164
  mkdirSync2(target, { recursive: true });
168
- cpSync(cursorCommandsSource, target, { recursive: true });
165
+ cpSync(skillsSource, target, { recursive: true });
169
166
  }
170
167
  const engineeringSource = join3(sourcePath, "ENGINEERING.md");
171
168
  if (existsSync3(engineeringSource)) {
@@ -226,188 +223,129 @@ import {
226
223
  existsSync as existsSync4,
227
224
  mkdirSync as mkdirSync3,
228
225
  symlinkSync,
229
- readFileSync as readFileSync2,
230
- appendFileSync,
231
- writeFileSync as writeFileSync2,
232
226
  lstatSync,
233
227
  unlinkSync as unlinkSync2,
234
228
  renameSync,
235
229
  readdirSync as readdirSync2,
236
- cpSync as cpSync2
230
+ readlinkSync
237
231
  } from "fs";
238
232
  import { join as join4, resolve as resolve2 } from "path";
239
233
  import { spinner as spinner2, log as log3 } from "@clack/prompts";
240
- async function linkToProject(tools) {
241
- let commandsLinked = 0;
242
- const rulesFilesUpdated = [];
243
- const targetDir = process.cwd();
234
+ async function installSkillsGlobally(tools) {
235
+ let skillsInstalled = 0;
244
236
  for (const tool of tools) {
245
237
  if (tool === "claude-code") {
246
- const result = linkCommands(
247
- join4(BLUEPRINTS_DIR, CLAUDE_COMMANDS_DIR),
248
- join4(targetDir, CLAUDE_COMMANDS_DIR),
238
+ skillsInstalled += installSkills(
239
+ SKILLS_SOURCE_DIR,
240
+ CLAUDE_SKILLS_DIR,
249
241
  "Claude Code"
250
242
  );
251
- commandsLinked += result;
252
- if (updateRulesFile(targetDir, "CLAUDE.md")) {
253
- rulesFilesUpdated.push("CLAUDE.md");
254
- }
255
243
  }
256
244
  if (tool === "opencode") {
257
- const result = linkCommands(
258
- join4(BLUEPRINTS_DIR, OPENCODE_COMMANDS_DIR),
259
- join4(targetDir, OPENCODE_COMMANDS_DIR),
245
+ skillsInstalled += installSkills(
246
+ SKILLS_SOURCE_DIR,
247
+ OPENCODE_SKILLS_DIR,
260
248
  "OpenCode"
261
249
  );
262
- commandsLinked += result;
263
- if (updateRulesFile(targetDir, "AGENTS.md")) {
264
- if (!rulesFilesUpdated.includes("AGENTS.md")) {
265
- rulesFilesUpdated.push("AGENTS.md");
266
- }
267
- }
268
250
  }
269
251
  if (tool === "cursor") {
270
- const result = linkCommands(
271
- join4(BLUEPRINTS_DIR, CURSOR_COMMANDS_DIR),
272
- join4(targetDir, CURSOR_COMMANDS_DIR),
252
+ skillsInstalled += installSkills(
253
+ SKILLS_SOURCE_DIR,
254
+ CURSOR_SKILLS_DIR,
273
255
  "Cursor"
274
256
  );
275
- commandsLinked += result;
276
- if (updateRulesFile(targetDir, "AGENTS.md")) {
277
- if (!rulesFilesUpdated.includes("AGENTS.md")) {
278
- rulesFilesUpdated.push("AGENTS.md");
279
- }
280
- }
281
257
  }
282
258
  }
283
- const engineeringCopied = copyEngineering(targetDir);
284
- return { commandsLinked, rulesFilesUpdated, engineeringCopied };
259
+ const legacyCommandsCleaned = cleanupLegacyCommands(process.cwd());
260
+ return { skillsInstalled, legacyCommandsCleaned };
285
261
  }
286
- function linkCommands(sourceDir, targetDir, toolLabel) {
262
+ function installSkills(sourceDir, globalTargetDir, toolLabel) {
287
263
  const s = spinner2();
288
- s.start(`Linking commands for ${toolLabel}...`);
289
- mkdirSync3(targetDir, { recursive: true });
290
- let count = 0;
264
+ s.start(`Installing skills for ${toolLabel}...`);
265
+ mkdirSync3(globalTargetDir, { recursive: true });
291
266
  if (!existsSync4(sourceDir)) {
292
- s.stop(`No commands found for ${toolLabel}`);
267
+ s.stop(`No skills found for ${toolLabel}`);
293
268
  return 0;
294
269
  }
295
- for (const file of readdirSync2(sourceDir)) {
296
- if (!file.endsWith(".md")) continue;
297
- const source = resolve2(sourceDir, file);
298
- const target = join4(targetDir, file);
299
- if (existsSync4(target)) {
270
+ let count = 0;
271
+ for (const entry of readdirSync2(sourceDir, { withFileTypes: true })) {
272
+ if (!entry.isDirectory()) continue;
273
+ const source = resolve2(sourceDir, entry.name);
274
+ const target = join4(globalTargetDir, entry.name);
275
+ if (existsSync4(target) || lstatExists(target)) {
300
276
  if (lstatSync(target).isSymbolicLink()) {
301
277
  unlinkSync2(target);
302
278
  } else {
303
- renameSync(target, `${target}.bak`);
279
+ const backup = `${target}.bak`;
280
+ if (existsSync4(backup)) {
281
+ unlinkSync2(backup);
282
+ }
283
+ renameSync(target, backup);
304
284
  }
305
285
  }
306
286
  symlinkSync(source, target);
307
287
  count++;
308
288
  }
309
- s.stop(`${count} commands linked for ${toolLabel}`);
289
+ s.stop(`${count} skills installed for ${toolLabel}`);
310
290
  return count;
311
291
  }
312
- var MARKER_START = "# --- withmata-blueprints ---";
313
- var MARKER_END = "# --- /withmata-blueprints ---";
314
- function buildRulesBlock() {
315
- return `
316
- ${MARKER_START}
317
- ## Blueprint System (withmata.dev)
318
-
319
- You have access to production-ready blueprints for scaffolding project infrastructure. Blueprints encode battle-tested patterns and configurations that save hours of setup. They work in both monorepo and single-repo projects.
320
-
321
- ### Commands
322
-
323
- \`/new-project\`, \`/discover\`, \`/scaffold-foundation\`, \`/scaffold-auth\`, \`/scaffold-db\`, \`/audit\`
324
-
325
- ### Available Blueprints
326
-
327
- | Blueprint | Tier | What it does | Dependencies | Command |
328
- |-----------|------|-------------|--------------|---------|
329
- | Product Discovery | Discovery | Structured session producing product thesis, user archetypes, and competitive analysis. No code. | None | \`/discover\` |
330
- | Monorepo Foundation | Foundation | Turborepo + pnpm monorepo with Next.js, Biome, TypeScript strict, Tailwind v4. | None | \`/scaffold-foundation\` |
331
- | Database | Feature | Drizzle ORM + PostgreSQL: schema groups, migrations, seed scripts. | None | \`/scaffold-db\` |
332
- | Authentication | Feature | Better Auth + Drizzle + PostgreSQL: social login, email/password, organizations, role-based permissions. | Database | \`/scaffold-auth\` |
333
-
334
- ### When to Recommend
335
-
336
- Suggest a blueprint when you observe these signals. Be helpful, not pushy \u2014 mention it once, then follow the user's lead.
337
-
338
- **\`/discover\`** \u2014 User describes a new product idea, asks "what should I build", is unsure about scope or target users, is non-technical or building their first product, or project has no product documentation.
339
-
340
- **\`/scaffold-foundation\`** \u2014 User wants to set up a monorepo, mentions Turborepo or project structure, or project has no \`turbo.json\` / \`pnpm-workspace.yaml\`. Best after discovery. Skip for single-repo apps.
341
-
342
- **\`/scaffold-db\`** \u2014 User mentions database, Drizzle, PostgreSQL, schemas, migrations, or needs a structured db layer. Or is writing raw SQL or using an ORM without organized schemas.
343
-
344
- **\`/scaffold-auth\`** \u2014 User mentions login, signup, users, accounts, teams, organizations, permissions, or authentication. Or is implementing auth from scratch. Recommend \`/scaffold-db\` first if not already installed.
345
-
346
- **\`/audit\`** \u2014 User asks "what should I do next?", wants to understand their project's state, or has hand-rolled infrastructure that a blueprint could improve.
347
-
348
- ### Lifecycle & Dependencies
349
-
350
- Discovery \u2192 Foundation \u2192 Features is the recommended flow, but blueprints can be applied at any stage.
351
-
352
- - **New project, no code:** Start with \`/discover\` (especially for non-technical users) or \`/scaffold-foundation\` (for monorepos)
353
- - **Single-repo project:** Skip foundation \u2014 go directly to feature blueprints (\`/scaffold-db\`, \`/scaffold-auth\`)
354
- - **Has monorepo, missing features:** Suggest specific feature blueprints
355
- - **Existing project:** Feature blueprints adapt to existing structures \u2014 no foundation required
356
- - **Dependencies:** \`/scaffold-auth\` works best after \`/scaffold-db\` (auth builds on db patterns). Install dependencies first.
357
-
358
- ### Important
359
-
360
- - Read \`.project-context.md\` first \u2014 it tracks what is already set up. Do not recommend blueprints already recorded there.
361
- - Read the full BLUEPRINT.md before scaffolding. Follow ENGINEERING.md for coding conventions.
362
- - Only recommend blueprints listed above. Other blueprints are in development and not yet available.
363
- - Blueprints location: \`${BLUEPRINTS_DIR}\`
364
- ${MARKER_END}
365
- `;
366
- }
367
- function updateRulesFile(targetDir, filename) {
368
- const filepath = join4(targetDir, filename);
369
- const block = buildRulesBlock();
370
- if (existsSync4(filepath)) {
371
- const content = readFileSync2(filepath, "utf-8");
372
- if (content.includes(MARKER_START)) {
373
- const startIdx = content.indexOf(MARKER_START);
374
- const endIdx = content.indexOf(MARKER_END);
375
- if (endIdx === -1) {
376
- appendFileSync(filepath, block);
377
- } else {
378
- const before = content.slice(0, startIdx);
379
- const after = content.slice(endIdx + MARKER_END.length);
380
- writeFileSync2(filepath, before + block.trimStart() + after);
292
+ function cleanupLegacyCommands(targetDir) {
293
+ let cleaned = 0;
294
+ const legacyDirs = [
295
+ join4(targetDir, CLAUDE_COMMANDS_DIR),
296
+ join4(targetDir, OPENCODE_COMMANDS_DIR),
297
+ join4(targetDir, CURSOR_COMMANDS_DIR)
298
+ ];
299
+ for (const dir of legacyDirs) {
300
+ if (!existsSync4(dir)) continue;
301
+ let dirEmpty = true;
302
+ for (const file of readdirSync2(dir)) {
303
+ const filePath = join4(dir, file);
304
+ if (lstatSync(filePath).isSymbolicLink()) {
305
+ try {
306
+ const linkTarget = readlinkSync(filePath);
307
+ if (linkTarget.includes(BLUEPRINTS_DIR)) {
308
+ unlinkSync2(filePath);
309
+ cleaned++;
310
+ continue;
311
+ }
312
+ } catch {
313
+ unlinkSync2(filePath);
314
+ cleaned++;
315
+ continue;
316
+ }
317
+ }
318
+ dirEmpty = false;
319
+ }
320
+ if (dirEmpty && readdirSync2(dir).length === 0) {
321
+ try {
322
+ readdirSync2(dir);
323
+ if (readdirSync2(dir).length === 0) {
324
+ unlinkSync2(dir);
325
+ }
326
+ } catch {
381
327
  }
382
- log3.success(`Updated ${filename} (refreshed blueprint catalog)`);
383
- return true;
384
328
  }
385
- appendFileSync(filepath, block);
386
- } else {
387
- writeFileSync2(filepath, block.trimStart());
388
329
  }
389
- log3.success(`Updated ${filename}`);
390
- return true;
330
+ if (cleaned > 0) {
331
+ log3.info(`Cleaned up ${cleaned} legacy command symlink(s)`);
332
+ }
333
+ return cleaned;
391
334
  }
392
- function copyEngineering(targetDir) {
393
- const source = join4(BLUEPRINTS_DIR, "ENGINEERING.md");
394
- const target = join4(targetDir, "ENGINEERING.md");
395
- if (!existsSync4(source)) return false;
396
- if (existsSync4(target)) {
397
- const sourceContent = readFileSync2(source, "utf-8");
398
- const targetContent = readFileSync2(target, "utf-8");
399
- if (sourceContent === targetContent) return false;
335
+ function lstatExists(path) {
336
+ try {
337
+ lstatSync(path);
338
+ return true;
339
+ } catch {
340
+ return false;
400
341
  }
401
- cpSync2(source, target);
402
- log3.success("Copied ENGINEERING.md");
403
- return true;
404
342
  }
405
343
 
406
344
  // src/steps/summary.ts
407
345
  import { log as log4, note } from "@clack/prompts";
408
346
  import pc from "picocolors";
409
- function showSummary({ linked, tools, blueprintCount }) {
410
- const commands = [
347
+ function showSummary({ installed, tools, blueprintCount }) {
348
+ const skills = [
411
349
  `${pc.cyan("/new-project")} Start a new project`,
412
350
  `${pc.cyan("/scaffold-auth")} Add auth to this project`,
413
351
  `${pc.cyan("/scaffold-db")} Set up database package`,
@@ -415,38 +353,144 @@ function showSummary({ linked, tools, blueprintCount }) {
415
353
  `${pc.cyan("/discover")} Run product discovery`,
416
354
  `${pc.cyan("/audit")} Run a project health check`
417
355
  ].join("\n");
418
- note(commands, "Available commands");
356
+ note(skills, "Available skills (global)");
419
357
  const toolNameMap = {
420
358
  "claude-code": "Claude Code",
421
359
  opencode: "OpenCode",
422
360
  cursor: "Cursor"
423
361
  };
424
- const toolNames = tools.map((t) => toolNameMap[t]).join(" or ");
425
- log4.info(`Open ${pc.bold(toolNames)} in this directory to use them.`);
426
- log4.info(pc.dim(`Manage your account at https://withmata.dev/dashboard`));
362
+ const toolNames = tools.map((t) => toolNameMap[t]).join(", ");
363
+ log4.info(
364
+ `${pc.bold(String(installed.skillsInstalled))} skills installed globally for ${toolNames}.`
365
+ );
366
+ log4.info("These skills work in any project \u2014 no per-project setup needed.");
367
+ if (installed.legacyCommandsCleaned > 0) {
368
+ log4.info(
369
+ pc.dim(
370
+ `Cleaned up ${installed.legacyCommandsCleaned} legacy command symlink(s).`
371
+ )
372
+ );
373
+ }
374
+ }
375
+
376
+ // src/steps/uninstall.ts
377
+ import {
378
+ existsSync as existsSync5,
379
+ readdirSync as readdirSync3,
380
+ lstatSync as lstatSync2,
381
+ readlinkSync as readlinkSync2,
382
+ unlinkSync as unlinkSync3,
383
+ rmSync as rmSync2
384
+ } from "fs";
385
+ import { join as join5 } from "path";
386
+ import { intro, outro, confirm, log as log5, spinner as spinner3 } from "@clack/prompts";
387
+ import pc2 from "picocolors";
388
+ var SKILL_DIRS = [CLAUDE_SKILLS_DIR, OPENCODE_SKILLS_DIR, CURSOR_SKILLS_DIR];
389
+ async function runUninstall() {
390
+ intro(
391
+ `${pc2.bgCyan(pc2.black(" @withmata/blueprints "))} ${pc2.dim(`v${VERSION}`)} ${pc2.yellow("uninstall")}`
392
+ );
393
+ const s = spinner3();
394
+ s.start("Scanning for withmata skill symlinks...");
395
+ let symlinksRemoved = 0;
396
+ for (const dir of SKILL_DIRS) {
397
+ if (!existsSync5(dir)) continue;
398
+ for (const entry of readdirSync3(dir)) {
399
+ const fullPath = join5(dir, entry);
400
+ try {
401
+ if (!lstatSync2(fullPath).isSymbolicLink()) continue;
402
+ const target = readlinkSync2(fullPath);
403
+ if (target.startsWith(BLUEPRINTS_DIR)) {
404
+ unlinkSync3(fullPath);
405
+ symlinksRemoved++;
406
+ }
407
+ } catch {
408
+ }
409
+ }
410
+ }
411
+ s.stop(
412
+ symlinksRemoved > 0 ? `Removed ${symlinksRemoved} skill symlink(s)` : "No withmata symlinks found"
413
+ );
414
+ let blueprintsRemoved = false;
415
+ if (existsSync5(BLUEPRINTS_DIR)) {
416
+ rmSync2(BLUEPRINTS_DIR, { recursive: true, force: true });
417
+ blueprintsRemoved = true;
418
+ log5.success("Removed cached blueprints (~/.withmata/blueprints/)");
419
+ }
420
+ let configRemoved = false;
421
+ if (existsSync5(WITHMATA_DIR)) {
422
+ const removeAll = await confirm({
423
+ message: "Also remove credentials and config (~/.withmata/)?",
424
+ initialValue: false
425
+ });
426
+ if (removeAll === true) {
427
+ rmSync2(WITHMATA_DIR, { recursive: true, force: true });
428
+ configRemoved = true;
429
+ log5.success("Removed ~/.withmata/");
430
+ }
431
+ }
432
+ if (!symlinksRemoved && !blueprintsRemoved && !configRemoved) {
433
+ outro("Nothing to clean up \u2014 already uninstalled.");
434
+ } else {
435
+ const parts = [];
436
+ if (symlinksRemoved > 0) parts.push(`${symlinksRemoved} symlink(s)`);
437
+ if (blueprintsRemoved) parts.push("cached blueprints");
438
+ if (configRemoved) parts.push("credentials & config");
439
+ outro(`Uninstalled: ${parts.join(", ")}`);
440
+ }
427
441
  }
428
442
 
429
443
  // src/index.ts
444
+ var HELP = `
445
+ Usage: @withmata/blueprints [command]
446
+
447
+ Commands:
448
+ install Install blueprints and skills (default)
449
+ uninstall Remove skills, symlinks, and cached data
450
+
451
+ Options:
452
+ -h, --help Show this help message
453
+ -v, --version Show version number
454
+ `.trim();
430
455
  async function main() {
431
- intro(`${pc2.bgCyan(pc2.black(" @withmata/blueprints "))} ${pc2.dim(`v${VERSION}`)}`);
456
+ const arg = process.argv[2];
457
+ if (arg === "--version" || arg === "-v") {
458
+ console.log(VERSION);
459
+ return;
460
+ }
461
+ if (arg === "--help" || arg === "-h") {
462
+ console.log(HELP);
463
+ return;
464
+ }
465
+ if (arg === "uninstall") {
466
+ await runUninstall();
467
+ return;
468
+ }
469
+ if (arg && arg !== "install") {
470
+ console.log(`Unknown command: ${arg}
471
+ `);
472
+ console.log(HELP);
473
+ process.exit(1);
474
+ }
475
+ intro2(`${pc3.bgCyan(pc3.black(" @withmata/blueprints "))} ${pc3.dim(`v${VERSION}`)}`);
432
476
  const user = await checkAuth();
433
477
  if (user) {
434
- log5.success(`Logged in as ${user.email} (${user.tier} plan)`);
478
+ log6.success(`Logged in as ${user.email} (${user.tier} plan)`);
435
479
  } else {
436
- log5.info("Running in local mode");
480
+ log6.info("Running in local mode");
437
481
  }
438
482
  const tools = await detectAndSelectTools(process.cwd());
439
483
  const blueprints = await downloadBlueprints(user?.token);
440
- const linked = await linkToProject(tools);
484
+ const installed = await installSkillsGlobally(tools);
441
485
  showSummary({
442
- linked,
486
+ installed,
443
487
  tools,
444
488
  blueprintCount: blueprints.total
445
489
  });
446
- outro("Setup complete!");
490
+ outro2("Setup complete!");
447
491
  }
448
492
  main().catch((err) => {
449
- log5.error(
493
+ log6.error(
450
494
  err instanceof Error ? err.message : "An unexpected error occurred"
451
495
  );
452
496
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@withmata/blueprints",
3
- "version": "0.2.0",
3
+ "version": "0.3.1",
4
4
  "description": "Set up AI-powered project blueprints for Claude Code, OpenCode, and Cursor",
5
5
  "type": "module",
6
6
  "bin": {
@@ -9,17 +9,16 @@
9
9
  "files": [
10
10
  "dist",
11
11
  "blueprints",
12
- ".claude/commands",
13
- ".opencode/commands",
14
- ".cursor/commands",
12
+ ".claude/skills",
15
13
  "ENGINEERING.md"
16
14
  ],
17
15
  "scripts": {
18
16
  "build": "tsup",
19
17
  "dev": "tsup --watch",
20
18
  "typecheck": "tsc --noEmit",
21
- "copy-blueprints": "node scripts/copy-blueprints.mjs",
22
- "prepublishOnly": "node scripts/copy-blueprints.mjs && tsup"
19
+ "copy-blueprints": "bun scripts/copy-blueprints.mjs",
20
+ "prepublishOnly": "bun scripts/copy-blueprints.mjs && tsup",
21
+ "release": "bun scripts/release.ts"
23
22
  },
24
23
  "dependencies": {
25
24
  "@clack/prompts": "^0.11.0",
@@ -38,7 +37,7 @@
38
37
  },
39
38
  "repository": {
40
39
  "type": "git",
41
- "url": "https://github.com/With-Mata/my-blueprints.git",
40
+ "url": "git+https://github.com/With-Mata/my-blueprints.git",
42
41
  "directory": "cli"
43
42
  },
44
43
  "keywords": [