@keystrokehq/cli 0.0.4 → 0.0.6

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Keystroke
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -7,8 +7,7 @@ const InitOptionsSchema = z.object({
7
7
  path: z.string().optional().describe("Directory to initialize (default: current directory)"),
8
8
  name: z.string().optional().describe("Project name (skips prompt; default: directory basename)"),
9
9
  description: z.string().optional().describe("Project description for the API (skips prompt when creating a new project)"),
10
- scaffold: z.boolean().default(true).describe("Scaffold project files (package.json, vitest.config.ts, etc.)"),
11
- install: z.boolean().default(true).describe("Run package manager install after scaffolding (when scaffold is enabled)")
10
+ scaffold: z.boolean().default(true).describe("Scaffold project files (package.json, vitest.config.ts, etc.)")
12
11
  });
13
12
  const INIT_OPTIONS_CONFIG = {
14
13
  path: {
@@ -26,10 +25,6 @@ const INIT_OPTIONS_CONFIG = {
26
25
  scaffold: {
27
26
  flag: "--no-scaffold",
28
27
  description: "Skip scaffolding project files (package.json, vitest.config.ts, etc.)"
29
- },
30
- install: {
31
- flag: "--no-install",
32
- description: "Skip running package manager install after scaffolding"
33
28
  }
34
29
  };
35
30
  function createInitCommand() {
@@ -38,7 +33,7 @@ function createInitCommand() {
38
33
  description: "Initialize a Keystroke project (creates keystroke.config.ts)",
39
34
  schema: InitOptionsSchema,
40
35
  optionsConfig: INIT_OPTIONS_CONFIG,
41
- loadHandler: async () => (await import("./init.handler-HRdgViGH.mjs")).handleInit
36
+ loadHandler: async () => (await import("./init.handler-Cs5YXM5Z.mjs")).handleInit
42
37
  });
43
38
  }
44
39
  //#endregion
@@ -4,36 +4,20 @@ import { C as CliExitError, t as ui } from "./keystroke.mjs";
4
4
  import { d as trackProject } from "./dist-BF6r1hfv.mjs";
5
5
  import { a as writeProjectConfig, i as readProjectConfig, r as getProjectConfigPath } from "./project-config-opj6DsPF.mjs";
6
6
  import { i as requireClient } from "./context-D-YKFNxL.mjs";
7
- import { t as syncKeystrokeAgentSkills } from "./sync-keystroke-agent-skills-CY9h25_5.mjs";
7
+ import { t as syncKeystrokeAgentSkills } from "./sync-keystroke-agent-skills-CBMQ4fh_.mjs";
8
8
  import { createRequire } from "node:module";
9
- import { accessSync, readFileSync } from "node:fs";
9
+ import { readFileSync } from "node:fs";
10
10
  import { access, mkdir, readFile, writeFile } from "node:fs/promises";
11
11
  import * as path$1 from "node:path";
12
12
  import path from "node:path";
13
13
  import { cancel, isCancel, text } from "@clack/prompts";
14
14
  import { fileURLToPath } from "node:url";
15
- import { spawn } from "node:child_process";
16
- //#region src/lib/keystroke-local-registry-npmrc.ts
17
- /**
18
- * Default local registry for consumer projects (Verdaccio default port).
19
- * Override with `KEYSTROKE_LOCAL_NPM_REGISTRY` when publishing or documenting for authors.
20
- */
21
- function getKeystrokeLocalNpmRegistryUrl() {
22
- const raw = process.env.KEYSTROKE_LOCAL_NPM_REGISTRY?.trim();
23
- if (!raw) return "http://localhost:4873/";
24
- return `${raw.replace(/\/+$/, "")}/`;
25
- }
26
- /**
27
- * `.npmrc` line so installs resolve `@keystroke/*` from the local registry (Verdaccio).
28
- */
29
- function createKeystrokeLocalRegistryNpmrcContent() {
30
- return `@keystroke:registry=${getKeystrokeLocalNpmRegistryUrl()}\n`;
31
- }
32
- /** When the CLI cannot resolve `@keystrokehq/core` on disk (e.g. unusual installs). */
15
+ //#region src/lib/keystroke-scaffold-version-ranges.ts
16
+ /** When the CLI cannot resolve `@keystrokehq/core` on disk (e.g. bundled installs). */
33
17
  const FALLBACK_WORKFLOW_CORE_VERSION_RANGE = "^0.0.1";
34
18
  /**
35
19
  * Semver range for scaffold `package.json` — uses the version of `@keystrokehq/core`
36
- * installed next to this CLI (same as the Keystroke toolchain the author runs).
20
+ * installed next to this CLI when available.
37
21
  */
38
22
  function workflowCoreScaffoldVersionRange() {
39
23
  try {
@@ -43,19 +27,6 @@ function workflowCoreScaffoldVersionRange() {
43
27
  } catch {}
44
28
  return FALLBACK_WORKFLOW_CORE_VERSION_RANGE;
45
29
  }
46
- /** When the CLI cannot resolve `@keystroke/skills` on disk. */
47
- const FALLBACK_SKILLS_VERSION_RANGE = "^0.0.1";
48
- /**
49
- * Semver range for scaffold `package.json` devDependency `@keystroke/skills` (published to local Verdaccio).
50
- */
51
- function keystrokeSkillsScaffoldVersionRange() {
52
- try {
53
- const raw = readFileSync(createRequire(import.meta.url).resolve("@keystroke/skills/package.json"), "utf-8");
54
- const version = JSON.parse(raw).version?.trim();
55
- if (version) return `^${version}`;
56
- } catch {}
57
- return FALLBACK_SKILLS_VERSION_RANGE;
58
- }
59
30
  //#endregion
60
31
  //#region src/commands/init/agents-md.ts
61
32
  const AGENTS_FILENAME = "AGENTS.md";
@@ -76,7 +47,7 @@ function resolveCliPackageSkillsBlurbPath() {
76
47
  function resolveBundledKeystrokeAgentsBlurbPath() {
77
48
  const require = createRequire(import.meta.url);
78
49
  try {
79
- const skillsPackageJsonPath = require.resolve("@keystroke/skills/package.json");
50
+ const skillsPackageJsonPath = require.resolve("@keystrokehq/skills/package.json");
80
51
  return path$1.join(path$1.dirname(skillsPackageJsonPath), AGENTS_BLURB_PACKAGE_PATH);
81
52
  } catch {}
82
53
  try {
@@ -237,9 +208,6 @@ describe('hello workflow', () => {
237
208
  //#region src/commands/init/templates/package-json.ts
238
209
  /**
239
210
  * Template for generating a package.json for a new Keystroke project.
240
- *
241
- * `@keystrokehq/core` uses a semver range; installs resolve via `.npmrc` → local Verdaccio
242
- * (see `pnpm publish:local` from the Keystroke monorepo).
243
211
  */
244
212
  function createPackageJsonContent(projectName, options) {
245
213
  return JSON.stringify({
@@ -256,7 +224,6 @@ function createPackageJsonContent(projectName, options) {
256
224
  zod: "^4.3.6"
257
225
  },
258
226
  devDependencies: {
259
- "@keystroke/skills": options.skillsVersionRange,
260
227
  "@biomejs/biome": "2.4.13",
261
228
  vitest: "^4.0.18",
262
229
  typescript: "^5.9.3"
@@ -359,40 +326,22 @@ async function promptProjectDescription(options) {
359
326
  const t = typeof answer === "string" ? answer.trim() : "";
360
327
  return t.length > 0 ? t : void 0;
361
328
  }
362
- async function ensureScaffoldPackageJson(targetDir, projectName, ranges) {
329
+ async function ensureScaffoldPackageJson(targetDir, projectName, workflowCoreRange) {
363
330
  const pkgPath = path.join(targetDir, "package.json");
364
331
  try {
365
332
  const raw = await readFile(pkgPath, "utf-8");
366
333
  const pkg = JSON.parse(raw);
367
334
  pkg.dependencies = pkg.dependencies ?? {};
368
- pkg.dependencies["@keystrokehq/core"] = ranges.workflowCore;
335
+ pkg.dependencies["@keystrokehq/core"] = workflowCoreRange;
369
336
  pkg.dependencies.zod = pkg.dependencies.zod ?? "^4.3.6";
370
337
  pkg.devDependencies = pkg.devDependencies ?? {};
371
- pkg.devDependencies["@keystroke/skills"] = ranges.skills;
372
338
  pkg.devDependencies.vitest = pkg.devDependencies.vitest ?? "^4.0.18";
373
339
  pkg.devDependencies.typescript = pkg.devDependencies.typescript ?? "^5.9.3";
374
340
  if (!pkg.name) pkg.name = projectName;
375
341
  await writeFile(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`, "utf-8");
376
342
  return "updated";
377
343
  } catch {
378
- await writeFile(pkgPath, `${createPackageJsonContent(projectName, {
379
- workflowCoreVersionRange: ranges.workflowCore,
380
- skillsVersionRange: ranges.skills
381
- })}\n`, "utf-8");
382
- return "created";
383
- }
384
- }
385
- /** Ensure `.npmrc` sends `@keystroke/*` to the local Verdaccio registry. */
386
- async function ensureKeystrokeLocalRegistryNpmrc(targetDir) {
387
- const npmrcPath = path.join(targetDir, ".npmrc");
388
- const line = createKeystrokeLocalRegistryNpmrcContent().trimEnd();
389
- try {
390
- const existing = await readFile(npmrcPath, "utf-8");
391
- if (existing.split(/\r?\n/).some((l) => l.trim().startsWith("@keystroke:registry="))) return "skipped";
392
- await writeFile(npmrcPath, existing.trimEnd().length > 0 ? `${existing.trimEnd()}\n${line}\n` : `${line}\n`, "utf-8");
393
- return "updated";
394
- } catch {
395
- await writeFile(npmrcPath, createKeystrokeLocalRegistryNpmrcContent(), "utf-8");
344
+ await writeFile(pkgPath, `${createPackageJsonContent(projectName, { workflowCoreVersionRange: workflowCoreRange })}\n`, "utf-8");
396
345
  return "created";
397
346
  }
398
347
  }
@@ -447,7 +396,7 @@ async function handleInit(options, ctx) {
447
396
  const agentsAction = await ensureAgentsMarkdown(targetDir, await loadKeystrokeAgentsBlurb());
448
397
  if (agentsAction === "created") ui.success("Created AGENTS.md with Keystroke project guidance.");
449
398
  else if (agentsAction === "updated") ui.success("Updated AGENTS.md with Keystroke project guidance.");
450
- if (options.scaffold) await scaffoldProject(targetDir, projectName, workflowCoreScaffoldVersionRange(), keystrokeSkillsScaffoldVersionRange(), options.install);
399
+ if (options.scaffold) await scaffoldProject(targetDir, projectName, workflowCoreScaffoldVersionRange());
451
400
  }
452
401
  /** Write a file only if it does not already exist. Returns true if written. */
453
402
  async function writeIfMissing(filePath, content) {
@@ -459,54 +408,15 @@ async function writeIfMissing(filePath, content) {
459
408
  return true;
460
409
  }
461
410
  }
462
- /**
463
- * Detect package manager from lockfiles. New projects (no lockfile) default to **pnpm** so `keystroke init`
464
- * matches the Keystroke monorepo toolchain.
465
- */
466
- function detectPackageManager(targetDir) {
467
- try {
468
- accessSync(path.join(targetDir, "pnpm-lock.yaml"));
469
- return "pnpm";
470
- } catch {}
471
- try {
472
- accessSync(path.join(targetDir, "yarn.lock"));
473
- return "yarn";
474
- } catch {}
475
- try {
476
- accessSync(path.join(targetDir, "package-lock.json"));
477
- return "npm";
478
- } catch {}
479
- return "pnpm";
480
- }
481
- /** Run install in targetDir. Returns true if succeeded. */
482
- function runInstall(targetDir) {
483
- const pm = detectPackageManager(targetDir);
484
- const [cmd, ...args] = pm === "pnpm" ? ["pnpm", "install"] : pm === "yarn" ? ["yarn", "install"] : ["npm", "install"];
485
- return new Promise((resolve) => {
486
- spawn(cmd, args, {
487
- cwd: targetDir,
488
- stdio: "inherit",
489
- shell: true
490
- }).on("close", (code) => resolve(code === 0));
491
- });
492
- }
493
411
  async function trySyncAgentSkillsAfterScaffold(targetDir) {
494
412
  const syncResult = await syncKeystrokeAgentSkills(targetDir);
495
413
  if (syncResult.ok) ui.success(`Synced ${syncResult.copied.length} skill(s) to .cursor/skills and .claude/skills: ${syncResult.copied.join(", ")}`);
496
- else if (syncResult.reason === "not_installed") ui.hint("After install completes, run `keystroke skills sync` to copy @keystroke/skills for Cursor / Claude Code.");
497
- else ui.warn(`@keystroke/skills is installed at ${syncResult.packageRoot} but no skill directories with SKILL.md were found.`);
414
+ else if (syncResult.reason === "not_installed") ui.hint("After install completes, run `keystroke skills sync` to copy @keystrokehq/skills for Cursor / Claude Code.");
415
+ else ui.warn(`@keystrokehq/skills is installed at ${syncResult.packageRoot} but no skill directories with SKILL.md were found.`);
498
416
  }
499
- async function scaffoldProject(targetDir, projectName, workflowCoreVersionRange, skillsVersionRange, runInstallAfterScaffold) {
500
- const pkgAction = await ensureScaffoldPackageJson(targetDir, projectName, {
501
- workflowCore: workflowCoreVersionRange,
502
- skills: skillsVersionRange
503
- });
504
- ui.success(pkgAction === "created" ? `Created package.json (@keystrokehq/core ${workflowCoreVersionRange}, @keystroke/skills ${skillsVersionRange})` : `Updated package.json (Keystroke deps → core ${workflowCoreVersionRange}, skills ${skillsVersionRange})`);
505
- const registryUrl = getKeystrokeLocalNpmRegistryUrl();
506
- const npmrcAction = await ensureKeystrokeLocalRegistryNpmrc(targetDir);
507
- if (npmrcAction === "created") ui.success(`Created .npmrc (@keystroke → local registry ${registryUrl.trim()})`);
508
- else if (npmrcAction === "updated") ui.success("Updated .npmrc with @keystroke registry line");
509
- ui.hint("Before install: run Verdaccio (e.g. pnpm dlx verdaccio), then from the Keystroke repo: pnpm publish:local");
417
+ async function scaffoldProject(targetDir, projectName, workflowCoreVersionRange) {
418
+ const pkgAction = await ensureScaffoldPackageJson(targetDir, projectName, workflowCoreVersionRange);
419
+ ui.success(pkgAction === "created" ? `Created package.json (@keystrokehq/core ${workflowCoreVersionRange})` : `Updated package.json (Keystroke deps -> core ${workflowCoreVersionRange})`);
510
420
  const files = [
511
421
  {
512
422
  rel: "vitest.config.ts",
@@ -557,29 +467,8 @@ async function scaffoldProject(targetDir, projectName, workflowCoreVersionRange,
557
467
  }
558
468
  if (created.length > 0) ui.success(`Scaffolded ${created.length} file(s): ${created.join(", ")}`);
559
469
  else ui.hint("Scaffold files already exist — skipped (package.json was still updated).");
560
- if (runInstallAfterScaffold) {
561
- const pkgJsonPath = path.join(targetDir, "package.json");
562
- try {
563
- await access(pkgJsonPath);
564
- } catch {
565
- return;
566
- }
567
- ui.hint("Running install...");
568
- const ok = await runInstall(targetDir);
569
- const pm = detectPackageManager(targetDir);
570
- const testCmd = pm === "pnpm" ? "pnpm test" : pm === "yarn" ? "yarn test" : "npm test";
571
- if (ok) {
572
- ui.success("Dependencies installed.");
573
- await trySyncAgentSkillsAfterScaffold(targetDir);
574
- ui.hint(`Run \`${testCmd}\` to run tests.`);
575
- } else {
576
- ui.warn("Install failed. Run your package manager install manually.");
577
- await trySyncAgentSkillsAfterScaffold(targetDir);
578
- }
579
- } else {
580
- ui.hint("Run `pnpm install`, then `pnpm test` to run tests (or use your lockfile’s package manager).");
581
- await trySyncAgentSkillsAfterScaffold(targetDir);
582
- }
470
+ ui.hint("Run `pnpm install` to install dependencies, then `pnpm test` to run tests (or use your lockfile's package manager).");
471
+ await trySyncAgentSkillsAfterScaffold(targetDir);
583
472
  }
584
473
  //#endregion
585
474
  export { handleInit };
File without changes
@@ -9,7 +9,7 @@ import * as path$1 from "node:path";
9
9
  import { z } from "zod";
10
10
  import { log } from "@clack/prompts";
11
11
  //#region package.json
12
- var version = "0.0.4";
12
+ var version = "0.0.6";
13
13
  //#endregion
14
14
  //#region src/command-registry.ts
15
15
  const ROOT_OPTIONS_WITH_VALUES = new Set([
@@ -54,7 +54,7 @@ const lazyCommandDefinitions = [
54
54
  },
55
55
  {
56
56
  name: "init",
57
- loadCommand: async () => (await import("./init-CWFlBuxT.mjs")).createInitCommand()
57
+ loadCommand: async () => (await import("./init-BXwx0QA4.mjs")).createInitCommand()
58
58
  },
59
59
  {
60
60
  name: "integrations",
@@ -82,7 +82,7 @@ const lazyCommandDefinitions = [
82
82
  },
83
83
  {
84
84
  name: "skills",
85
- loadCommand: async () => (await import("./skills.command-mMs4o12N.mjs")).createSkillsCommand()
85
+ loadCommand: async () => (await import("./skills.command-C2NXqc5h.mjs")).createSkillsCommand()
86
86
  },
87
87
  {
88
88
  name: "sync",
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { C as CliExitError, t as ui } from "./keystroke.mjs";
4
4
  import { i as writeJson, r as isJsonMode } from "./output-q4KljAhu.mjs";
5
- import { t as syncKeystrokeAgentSkills } from "./sync-keystroke-agent-skills-CY9h25_5.mjs";
5
+ import { t as syncKeystrokeAgentSkills } from "./sync-keystroke-agent-skills-CBMQ4fh_.mjs";
6
6
  import path from "node:path";
7
7
  //#region src/commands/skills/skills-sync.handler.ts
8
8
  async function handleSkillsSync(options, _ctx) {
@@ -27,8 +27,8 @@ async function handleSkillsSync(options, _ctx) {
27
27
  ui.success(`Synced ${result.copied.length} skill(s) to .cursor/skills and .claude/skills: ${result.copied.join(", ")}`);
28
28
  return;
29
29
  }
30
- if (result.reason === "not_installed") throw new CliExitError("Could not resolve @keystroke/skills. Add it to devDependencies, run install, then run `keystroke skills sync`.", { exitCode: 1 });
31
- ui.warn(`@keystroke/skills is installed at ${result.packageRoot} but no skill directories with SKILL.md were found.`);
30
+ if (result.reason === "not_installed") throw new CliExitError("Could not resolve @keystrokehq/skills from this project or the installed CLI. Reinstall the CLI or add @keystrokehq/skills to devDependencies, run install, then run `keystroke skills sync`.", { exitCode: 1 });
31
+ ui.warn(`@keystrokehq/skills is installed at ${result.packageRoot} but no skill directories with SKILL.md were found.`);
32
32
  }
33
33
  //#endregion
34
34
  export { handleSkillsSync };
@@ -15,16 +15,16 @@ const SKILLS_OPTIONS_CONFIG = {
15
15
  function createSkillsCommand() {
16
16
  const cmd = createTypedCommand({
17
17
  name: "skills",
18
- description: "Sync Keystroke agent skills (SKILL.md) from @keystroke/skills",
18
+ description: "Sync Keystroke agent skills (SKILL.md) from @keystrokehq/skills",
19
19
  schema: SkillsCommandOptionsSchema,
20
20
  optionsConfig: SKILLS_OPTIONS_CONFIG,
21
- loadHandler: async () => (await import("./skills.handler-JauTJV1C.mjs")).handleSkillsParent,
21
+ loadHandler: async () => (await import("./skills.handler-BTUhxO37.mjs")).handleSkillsParent,
22
22
  subcommands: [createTypedCommand({
23
23
  name: "sync",
24
- description: "Copy installed @keystroke/skills into .cursor/skills and .claude/skills",
24
+ description: "Copy installed @keystrokehq/skills into .cursor/skills and .claude/skills",
25
25
  schema: SkillsCommandOptionsSchema,
26
26
  optionsConfig: SKILLS_OPTIONS_CONFIG,
27
- loadHandler: async () => (await import("./skills-sync.handler-IB73kEeA.mjs")).handleSkillsSync
27
+ loadHandler: async () => (await import("./skills-sync.handler-CwwnzDiO.mjs")).handleSkillsSync
28
28
  })]
29
29
  });
30
30
  cmd.enablePositionalOptions();
@@ -3,7 +3,7 @@
3
3
  import { t as ui } from "./keystroke.mjs";
4
4
  //#region src/commands/skills/skills.handler.ts
5
5
  async function handleSkillsParent(_options, _ctx) {
6
- ui.hint("Run `keystroke skills sync` to copy @keystroke/skills into .cursor/skills and .claude/skills.");
6
+ ui.hint("Run `keystroke skills sync` to copy @keystrokehq/skills into .cursor/skills and .claude/skills.");
7
7
  }
8
8
  //#endregion
9
9
  export { handleSkillsParent };
@@ -1,21 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ import { createRequire } from "node:module";
3
4
  import { access, cp, mkdir, readdir } from "node:fs/promises";
4
5
  import path from "node:path";
5
6
  //#region src/lib/sync-keystroke-agent-skills.ts
6
7
  /**
7
- * Resolve the installed `@keystroke/skills` package root for a consumer project.
8
- *
9
- * Only checks `projectDir/node_modules/@keystroke/skills` (pnpm symlinks that path; npm/yarn lay out
10
- * the same). We intentionally do not walk ancestor directories — that avoids resolving a
11
- * unrelated workspace copy when TMPDIR or the project lives inside another repo.
8
+ * Resolve the `@keystrokehq/skills` package root from the CLI's own node_modules.
9
+ * Skills are distributed with the CLI release, so no npm install is needed.
12
10
  */
13
- async function resolveKeystrokeSkillsPackageRoot(projectDir) {
14
- const root = path.resolve(projectDir);
15
- const marker = path.join(root, "node_modules", "@keystroke", "skills", "package.json");
11
+ async function resolveKeystrokeSkillsPackageRoot() {
16
12
  try {
17
- await access(marker);
18
- return path.dirname(marker);
13
+ const require = createRequire(import.meta.url);
14
+ return path.dirname(require.resolve("@keystrokehq/skills/package.json"));
19
15
  } catch {
20
16
  return null;
21
17
  }
@@ -34,11 +30,11 @@ async function listKeystrokeSkillDirectoryNames(skillsPackageRoot) {
34
30
  return names.sort();
35
31
  }
36
32
  /**
37
- * Copy each skill directory from `node_modules/@keystroke/skills/*` into
33
+ * Copy each skill directory from the resolved `@keystrokehq/skills` package into
38
34
  * `.cursor/skills` and `.claude/skills` under `projectDir`.
39
35
  */
40
36
  async function syncKeystrokeAgentSkills(projectDir) {
41
- const packageRoot = await resolveKeystrokeSkillsPackageRoot(projectDir);
37
+ const packageRoot = await resolveKeystrokeSkillsPackageRoot();
42
38
  if (!packageRoot) return {
43
39
  ok: false,
44
40
  reason: "not_installed"
File without changes
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@keystrokehq/cli",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "private": false,
5
5
  "description": "Command-line interface for creating, managing, and deploying Keystroke automations.",
6
6
  "type": "module",
@@ -22,46 +22,34 @@
22
22
  "dist",
23
23
  "README.md"
24
24
  ],
25
- "scripts": {
26
- "dev:cli": "pnpm run build && node bin/keystroke.mjs",
27
- "typecheck": "tsgo --build",
28
- "build": "tsdown",
29
- "check:command-imports": "node scripts/check-command-imports.mjs",
30
- "dev:install-pack": "pnpm run build && node scripts/install-dev-pack.mjs",
31
- "smoke:pack": "pnpm run build && node scripts/smoke-pack.mjs",
32
- "lint": "biome check --write .",
33
- "test:unit": "vitest run --passWithNoTests --project unit",
34
- "test:int": "vitest run --passWithNoTests --project int",
35
- "prepublishOnly": "pnpm run build && pnpm run test:unit"
36
- },
37
25
  "dependencies": {
38
26
  "@clack/prompts": "^1.2.0",
39
27
  "cli-table3": "^0.6.5",
40
28
  "commander": "^14.0.3",
41
- "dayjs": "catalog:",
42
- "dotenv": "catalog:",
29
+ "dayjs": "^1.11.20",
30
+ "dotenv": "^17.4.2",
43
31
  "ky": "^1.14.3",
44
32
  "oxc-parser": "^0.128.0",
45
33
  "rolldown": "1.0.0-rc.17",
46
34
  "tsx": "^4.21.0",
47
- "zod": "catalog:"
35
+ "zod": "^4.3.6",
36
+ "@keystrokehq/skills": "0.0.1"
48
37
  },
49
38
  "devDependencies": {
50
- "@keystroke/env-utils": "workspace:*",
51
- "@keystroke/local-memory": "workspace:*",
52
- "@keystroke/project-config": "workspace:*",
53
- "@keystroke/shared-types": "workspace:*",
54
- "@keystroke/skills": "workspace:*",
55
- "@keystroke/test-utils": "workspace:*",
56
- "@keystroke/typescript-config": "workspace:*",
57
- "@keystroke/utils": "workspace:*",
58
- "@keystroke/workflow-builder": "workspace:*",
59
- "@keystrokehq/core": "workspace:*",
60
- "@keystroke/workflow-deploy": "workspace:*",
61
- "@keystroke/workflow-sdk": "workspace:*",
62
- "tsdown": "catalog:",
63
- "typescript": "catalog:",
64
- "vitest": "catalog:"
39
+ "tsdown": "0.21.10",
40
+ "typescript": "^5.9.3",
41
+ "vitest": "^4.1.5",
42
+ "@keystroke/env-utils": "0.0.0",
43
+ "@keystroke/local-memory": "0.0.0",
44
+ "@keystroke/shared-types": "0.0.1",
45
+ "@keystroke/test-utils": "0.0.0",
46
+ "@keystroke/typescript-config": "0.0.0",
47
+ "@keystroke/utils": "0.0.0",
48
+ "@keystroke/workflow-builder": "0.0.2",
49
+ "@keystrokehq/core": "0.0.3",
50
+ "@keystroke/workflow-deploy": "0.0.1",
51
+ "@keystroke/workflow-sdk": "0.0.0",
52
+ "@keystroke/project-config": "0.0.1"
65
53
  },
66
54
  "keywords": [
67
55
  "automation",
@@ -82,5 +70,16 @@
82
70
  "publishConfig": {
83
71
  "access": "public",
84
72
  "registry": "https://registry.npmjs.org/"
73
+ },
74
+ "scripts": {
75
+ "dev:cli": "pnpm run build && node bin/keystroke.mjs",
76
+ "typecheck": "tsgo --build",
77
+ "build": "tsdown",
78
+ "check:command-imports": "node scripts/check-command-imports.mjs",
79
+ "dev:install-pack": "pnpm run build && node scripts/install-dev-pack.mjs",
80
+ "smoke:pack": "pnpm run build && node scripts/smoke-pack.mjs",
81
+ "lint": "biome check --write .",
82
+ "test:unit": "vitest run --passWithNoTests --project unit",
83
+ "test:int": "vitest run --passWithNoTests --project int"
85
84
  }
86
- }
85
+ }