@orderful/droid 0.30.1 → 0.31.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/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # @orderful/droid
2
2
 
3
+ ## 0.31.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#182](https://github.com/Orderful/droid/pull/182) [`0742b3f`](https://github.com/Orderful/droid/commit/0742b3f891f0ce8f1c4a29c06cf75d19347145ef) Thanks [@frytyler](https://github.com/frytyler)! - Add Cursor as a first-class platform option
8
+ - Add `Platform.Cursor` enum value
9
+ - Skills use unified `~/.claude/skills/` path (Cursor reads this via Agent Skills standard)
10
+ - Agents install to `~/.cursor/agents/`
11
+ - Commands install to `~/.cursor/commands/` (may not work - Cursor discovers commands differently)
12
+ - Setup wizard detects Cursor via `~/.cursor` directory
13
+ - TUI displays Cursor as platform option
14
+
15
+ Note: Cursor requires nightly channel for full Agent Skills support.
16
+
17
+ ### Patch Changes
18
+
19
+ - [#184](https://github.com/Orderful/droid/pull/184) [`57596e6`](https://github.com/Orderful/droid/commit/57596e6ffea0d5d6a84a87f40d907e34eaa5f9b7) Thanks [@frytyler](https://github.com/frytyler)! - Fix TUI Tool Explorer displaying commands as `/[object Object]`
20
+
21
+ The ToolExplorer component was treating command includes as strings but they're now objects with `name` and `is_alias` properties.
22
+
3
23
  ## 0.30.1
4
24
 
5
25
  ### Patch Changes
package/dist/bin/droid.js CHANGED
@@ -213,6 +213,14 @@ var PLATFORM_PATHS = {
213
213
  commands: join2(homedir2(), ".config", "opencode", "command"),
214
214
  agents: join2(homedir2(), ".config", "opencode", "agent"),
215
215
  config: join2(homedir2(), ".config", "opencode", "AGENTS.md")
216
+ },
217
+ ["cursor" /* Cursor */]: {
218
+ skills: UNIFIED_SKILLS_PATH,
219
+ // Cursor doesn't have a documented global commands path - commands are discovered from projects
220
+ // We use this path as a placeholder; commands may not work the same as Claude Code/OpenCode
221
+ commands: join2(homedir2(), ".cursor", "commands"),
222
+ agents: join2(homedir2(), ".cursor", "agents"),
223
+ config: join2(homedir2(), ".cursor", "rules")
216
224
  }
217
225
  };
218
226
  function getSkillsPath(platform) {
@@ -577,7 +585,7 @@ function createPlatformSyncMigration(version2) {
577
585
  const bundledTools = getBundledTools();
578
586
  let configChanged = false;
579
587
  const originalPlatform = config.platform;
580
- for (const platformKey of ["claude-code" /* ClaudeCode */, "opencode" /* OpenCode */]) {
588
+ for (const platformKey of ["claude-code" /* ClaudeCode */, "opencode" /* OpenCode */, "cursor" /* Cursor */]) {
581
589
  const skillsPath = getSkillsPath(platformKey);
582
590
  if (!existsSync4(skillsPath)) continue;
583
591
  config.platform = platformKey;
@@ -617,7 +625,7 @@ function createConfigSkillNameMigration(version2) {
617
625
  const config = loadConfig();
618
626
  let configChanged = false;
619
627
  const originalPlatform = config.platform;
620
- for (const platformKey of ["claude-code" /* ClaudeCode */, "opencode" /* OpenCode */]) {
628
+ for (const platformKey of ["claude-code" /* ClaudeCode */, "opencode" /* OpenCode */, "cursor" /* Cursor */]) {
621
629
  if (!config.platforms[platformKey]) continue;
622
630
  config.platform = platformKey;
623
631
  const trackedTools = getPlatformTools(config);
@@ -1416,6 +1424,10 @@ function detectPlatform() {
1416
1424
  return "claude-code" /* ClaudeCode */;
1417
1425
  } catch {
1418
1426
  }
1427
+ const cursorDir = join8(homedir4(), ".cursor");
1428
+ if (existsSync6(cursorDir)) {
1429
+ return "cursor" /* Cursor */;
1430
+ }
1419
1431
  try {
1420
1432
  execSync2("opencode --version", { stdio: "ignore" });
1421
1433
  return "opencode" /* OpenCode */;
@@ -1476,6 +1488,17 @@ function configurePlatformPermissions(platform) {
1476
1488
  }
1477
1489
  return { added: [], alreadyPresent: true };
1478
1490
  }
1491
+ if (platform === "cursor" /* Cursor */) {
1492
+ const cursorDir = join8(homedir4(), ".cursor");
1493
+ if (!existsSync6(cursorDir)) {
1494
+ mkdirSync5(cursorDir, { recursive: true });
1495
+ }
1496
+ const agentsDir = join8(cursorDir, "agents");
1497
+ if (!existsSync6(agentsDir)) {
1498
+ mkdirSync5(agentsDir, { recursive: true });
1499
+ }
1500
+ return { added: [], alreadyPresent: true };
1501
+ }
1479
1502
  return { added: [], alreadyPresent: true };
1480
1503
  }
1481
1504
  function getOutputOptions() {
@@ -1527,6 +1550,7 @@ async function setupCommand() {
1527
1550
  message: "Which platform are you using?",
1528
1551
  choices: [
1529
1552
  { name: "Claude Code", value: "claude-code" /* ClaudeCode */ },
1553
+ { name: "Cursor", value: "cursor" /* Cursor */ },
1530
1554
  { name: "OpenCode", value: "opencode" /* OpenCode */ }
1531
1555
  ],
1532
1556
  default: detectedPlatform || "claude-code" /* ClaudeCode */
@@ -1576,6 +1600,9 @@ async function setupCommand() {
1576
1600
  }
1577
1601
  } else if (answers.platform === "opencode" /* OpenCode */) {
1578
1602
  console.log(chalk2.gray(" Skills installed to ~/.claude/skills/ (works with Claude Code, OpenCode, and Cursor)"));
1603
+ } else if (answers.platform === "cursor" /* Cursor */) {
1604
+ console.log(chalk2.gray(" Skills installed to ~/.claude/skills/ (Cursor reads from this location)"));
1605
+ console.log(chalk2.gray(" Note: Cursor requires nightly channel for Agent Skills support"));
1579
1606
  }
1580
1607
  console.log(chalk2.gray("\nRun `droid skills` to browse and install skills."));
1581
1608
  }
@@ -2211,7 +2238,7 @@ function SettingsDetails({
2211
2238
  /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", marginTop: 1, children: [
2212
2239
  /* @__PURE__ */ jsxs5(Text5, { children: [
2213
2240
  /* @__PURE__ */ jsx5(Text5, { color: colors.textDim, children: "Platform: " }),
2214
- /* @__PURE__ */ jsx5(Text5, { color: colors.text, children: config.platform === "claude-code" /* ClaudeCode */ ? "Claude Code" : "OpenCode" })
2241
+ /* @__PURE__ */ jsx5(Text5, { color: colors.text, children: config.platform === "claude-code" /* ClaudeCode */ ? "Claude Code" : config.platform === "cursor" /* Cursor */ ? "Cursor" : "OpenCode" })
2215
2242
  ] }),
2216
2243
  /* @__PURE__ */ jsxs5(Text5, { children: [
2217
2244
  /* @__PURE__ */ jsx5(Text5, { color: colors.textDim, children: "Your @mention: " }),
@@ -2505,6 +2532,7 @@ import { useState as useState3 } from "react";
2505
2532
  import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
2506
2533
  var platformOptions = [
2507
2534
  { label: "Claude Code", value: "claude-code" /* ClaudeCode */ },
2535
+ { label: "Cursor", value: "cursor" /* Cursor */ },
2508
2536
  { label: "OpenCode", value: "opencode" /* OpenCode */ }
2509
2537
  ];
2510
2538
  function SetupScreen({ onComplete, onSkip, initialConfig }) {
@@ -2683,7 +2711,7 @@ function SetupScreen({ onComplete, onSkip, initialConfig }) {
2683
2711
  /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", marginTop: 1, children: [
2684
2712
  /* @__PURE__ */ jsxs8(Text8, { children: [
2685
2713
  /* @__PURE__ */ jsx8(Text8, { color: colors.textDim, children: "Platform: " }),
2686
- /* @__PURE__ */ jsx8(Text8, { color: colors.text, children: platform === "claude-code" /* ClaudeCode */ ? "Claude Code" : "OpenCode" })
2714
+ /* @__PURE__ */ jsx8(Text8, { color: colors.text, children: platform === "claude-code" /* ClaudeCode */ ? "Claude Code" : platform === "cursor" /* Cursor */ ? "Cursor" : "OpenCode" })
2687
2715
  ] }),
2688
2716
  /* @__PURE__ */ jsxs8(Text8, { children: [
2689
2717
  /* @__PURE__ */ jsx8(Text8, { color: colors.textDim, children: "Your @mention: " }),
@@ -2843,10 +2871,11 @@ function ToolExplorer({ tool, onViewSource, onClose }) {
2843
2871
  });
2844
2872
  }
2845
2873
  for (const cmd of tool.includes.commands) {
2874
+ const cmdName = typeof cmd === "string" ? cmd : cmd.name;
2846
2875
  result.push({
2847
2876
  type: "command",
2848
- name: `/${cmd}`,
2849
- path: join9(toolDir, tool.name, "commands", `${cmd}.md`)
2877
+ name: `/${cmdName}`,
2878
+ path: join9(toolDir, tool.name, "commands", `${cmdName}.md`)
2850
2879
  });
2851
2880
  }
2852
2881
  for (const agent of tool.includes.agents) {
@@ -3628,7 +3657,7 @@ function App() {
3628
3657
  getVersion()
3629
3658
  ] })
3630
3659
  ] }) }),
3631
- /* @__PURE__ */ jsx13(Box12, { paddingX: 1, children: /* @__PURE__ */ jsx13(Text13, { color: colors.textDim, children: loadConfig().platform === "claude-code" /* ClaudeCode */ ? "Claude Code" : "OpenCode" }) }),
3660
+ /* @__PURE__ */ jsx13(Box12, { paddingX: 1, children: /* @__PURE__ */ jsx13(Text13, { color: colors.textDim, children: loadConfig().platform === "claude-code" /* ClaudeCode */ ? "Claude Code" : loadConfig().platform === "cursor" /* Cursor */ ? "Cursor" : "OpenCode" }) }),
3632
3661
  /* @__PURE__ */ jsx13(Box12, { paddingX: 1, marginTop: 1, children: /* @__PURE__ */ jsx13(TabBar, { tabs, activeTab }) }),
3633
3662
  /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", marginTop: 1, children: [
3634
3663
  activeTab === "tools" && /* @__PURE__ */ jsxs12(Fragment2, { children: [
@@ -1 +1 @@
1
- {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,QAAQ,EAA0D,MAAM,cAAc,CAAC;AA6ChG;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,QAAQ,GAAG;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,cAAc,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAiE7H;AAyBD,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAwGlD"}
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,QAAQ,EAA0D,MAAM,cAAc,CAAC;AAoDhG;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,QAAQ,GAAG;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,cAAc,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAmF7H;AAyBD,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CA4GlD"}
@@ -1 +1 @@
1
- {"version":3,"file":"SetupScreen.d.ts","sourceRoot":"","sources":["../../../../src/commands/tui/views/SetupScreen.tsx"],"names":[],"mappings":"AAKA,OAAO,EAA2B,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAI/E,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,aAAa,CAAC,EAAE,WAAW,CAAC;CAC7B;AAOD,wBAAgB,WAAW,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,EAAE,gBAAgB,2CA6NlF"}
1
+ {"version":3,"file":"SetupScreen.d.ts","sourceRoot":"","sources":["../../../../src/commands/tui/views/SetupScreen.tsx"],"names":[],"mappings":"AAKA,OAAO,EAA2B,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAI/E,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,aAAa,CAAC,EAAE,WAAW,CAAC;CAC7B;AAQD,wBAAgB,WAAW,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,EAAE,gBAAgB,2CA6NlF"}
@@ -1 +1 @@
1
- {"version":3,"file":"ToolExplorer.d.ts","sourceRoot":"","sources":["../../../../src/commands/tui/views/ToolExplorer.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAUvD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,YAAY,CAAC;IACnB,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACvD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wBAAgB,YAAY,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE,iBAAiB,2CAwK9E"}
1
+ {"version":3,"file":"ToolExplorer.d.ts","sourceRoot":"","sources":["../../../../src/commands/tui/views/ToolExplorer.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAUvD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,YAAY,CAAC;IACnB,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACvD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wBAAgB,YAAY,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE,iBAAiB,2CAyK9E"}
@@ -1 +1 @@
1
- {"version":3,"file":"tui.d.ts","sourceRoot":"","sources":["../../src/commands/tui.tsx"],"names":[],"mappings":"AAkiBA,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAiBhD"}
1
+ {"version":3,"file":"tui.d.ts","sourceRoot":"","sources":["../../src/commands/tui.tsx"],"names":[],"mappings":"AAoiBA,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAiBhD"}
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@
2
2
  var Platform = /* @__PURE__ */ ((Platform2) => {
3
3
  Platform2["ClaudeCode"] = "claude-code";
4
4
  Platform2["OpenCode"] = "opencode";
5
+ Platform2["Cursor"] = "cursor";
5
6
  return Platform2;
6
7
  })(Platform || {});
7
8
  var AIToolValue = Platform;
@@ -221,6 +222,14 @@ var PLATFORM_PATHS = {
221
222
  commands: join2(homedir2(), ".config", "opencode", "command"),
222
223
  agents: join2(homedir2(), ".config", "opencode", "agent"),
223
224
  config: join2(homedir2(), ".config", "opencode", "AGENTS.md")
225
+ },
226
+ ["cursor" /* Cursor */]: {
227
+ skills: UNIFIED_SKILLS_PATH,
228
+ // Cursor doesn't have a documented global commands path - commands are discovered from projects
229
+ // We use this path as a placeholder; commands may not work the same as Claude Code/OpenCode
230
+ commands: join2(homedir2(), ".cursor", "commands"),
231
+ agents: join2(homedir2(), ".cursor", "agents"),
232
+ config: join2(homedir2(), ".cursor", "rules")
224
233
  }
225
234
  };
226
235
  function getSkillsPath(platform) {
@@ -550,7 +559,7 @@ function createPlatformSyncMigration(version) {
550
559
  const bundledTools = getBundledTools();
551
560
  let configChanged = false;
552
561
  const originalPlatform = config.platform;
553
- for (const platformKey of ["claude-code" /* ClaudeCode */, "opencode" /* OpenCode */]) {
562
+ for (const platformKey of ["claude-code" /* ClaudeCode */, "opencode" /* OpenCode */, "cursor" /* Cursor */]) {
554
563
  const skillsPath = getSkillsPath(platformKey);
555
564
  if (!existsSync4(skillsPath)) continue;
556
565
  config.platform = platformKey;
@@ -590,7 +599,7 @@ function createConfigSkillNameMigration(version) {
590
599
  const config = loadConfig();
591
600
  let configChanged = false;
592
601
  const originalPlatform = config.platform;
593
- for (const platformKey of ["claude-code" /* ClaudeCode */, "opencode" /* OpenCode */]) {
602
+ for (const platformKey of ["claude-code" /* ClaudeCode */, "opencode" /* OpenCode */, "cursor" /* Cursor */]) {
594
603
  if (!config.platforms[platformKey]) continue;
595
604
  config.platform = platformKey;
596
605
  const trackedTools = getPlatformTools(config);
@@ -19,6 +19,12 @@ export declare const PLATFORM_PATHS: {
19
19
  readonly agents: string;
20
20
  readonly config: string;
21
21
  };
22
+ readonly cursor: {
23
+ readonly skills: string;
24
+ readonly commands: string;
25
+ readonly agents: string;
26
+ readonly config: string;
27
+ };
22
28
  };
23
29
  export type PlatformPaths = typeof PLATFORM_PATHS[Platform];
24
30
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"platforms.d.ts","sourceRoot":"","sources":["../../src/lib/platforms.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAQnC;;;;;;GAMG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;CAajB,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,OAAO,cAAc,CAAC,QAAQ,CAAC,CAAC;AAE5D;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,GAAG,aAAa,CAElE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAExD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAE1D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAExD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAExD"}
1
+ {"version":3,"file":"platforms.d.ts","sourceRoot":"","sources":["../../src/lib/platforms.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAQnC;;;;;;GAMG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;CAqBjB,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,OAAO,cAAc,CAAC,QAAQ,CAAC,CAAC;AAE5D;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,GAAG,aAAa,CAElE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAExD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAE1D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAExD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAExD"}
@@ -1,6 +1,7 @@
1
1
  export declare enum Platform {
2
2
  ClaudeCode = "claude-code",
3
- OpenCode = "opencode"
3
+ OpenCode = "opencode",
4
+ Cursor = "cursor"
4
5
  }
5
6
  declare const AIToolValue: typeof Platform;
6
7
  export { AIToolValue as AITool };
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA,oBAAY,QAAQ;IAClB,UAAU,gBAAgB;IAC1B,QAAQ,aAAa;CACtB;AAID,QAAA,MAAM,WAAW,iBAAW,CAAC;AAC7B,OAAO,EAAE,WAAW,IAAI,MAAM,EAAE,CAAC;AACjC,MAAM,MAAM,MAAM,GAAG,QAAQ,CAAC;AAE9B;;;GAGG;AACH,wBAAgB,QAAQ,IAAI,MAAM,CAEjC;AAGD,oBAAY,aAAa;IACvB,QAAQ,aAAa;IACrB,MAAM,WAAW;CAClB;AAGD,MAAM,MAAM,gBAAgB,GAAG,aAAa,GAAG,MAAM,CAAC;AAEtD,oBAAY,WAAW;IACrB,MAAM,WAAW;IACjB,IAAI,SAAS;IACb,KAAK,UAAU;CAChB;AAED,oBAAY,gBAAgB;IAC1B,MAAM,WAAW;IACjB,OAAO,YAAY;IACnB,MAAM,WAAW;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,QAAQ,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,gBAAgB,CAAC;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC1C,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B,UAAU,CAAC,EAAE;QACX,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAE/B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;KAC5D,CAAC;CACH;AAGD,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,QAAQ,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,gBAAgB,CAAC;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CACxC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,WAAW,GAClB,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAEhC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,GACpC,IAAI,CAKN;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAE7C,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAC;IAG1B,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,gBAAgB,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;CAC1C;AAED;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,EAAE,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACjD;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,QAAQ,EAAE,YAAY,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CAC9C"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orderful/droid",
3
- "version": "0.30.1",
3
+ "version": "0.31.0",
4
4
  "description": "AI workflow toolkit for sharing skills, commands, and agents across the team",
5
5
  "type": "module",
6
6
  "bin": {
@@ -21,6 +21,7 @@ const DROID_PERMISSIONS = [
21
21
 
22
22
  /**
23
23
  * Detect which platform is installed
24
+ * Priority: Claude Code > Cursor > OpenCode (Claude Code is most common)
24
25
  */
25
26
  function detectPlatform(): Platform | null {
26
27
  try {
@@ -30,6 +31,12 @@ function detectPlatform(): Platform | null {
30
31
  // Claude Code not found
31
32
  }
32
33
 
34
+ // Check for Cursor - it's an app, check if .cursor directory exists
35
+ const cursorDir = join(homedir(), '.cursor');
36
+ if (existsSync(cursorDir)) {
37
+ return Platform.Cursor;
38
+ }
39
+
33
40
  try {
34
41
  execSync('opencode --version', { stdio: 'ignore' });
35
42
  return Platform.OpenCode;
@@ -118,6 +125,24 @@ export function configurePlatformPermissions(platform: Platform): { added: strin
118
125
  return { added: [], alreadyPresent: true };
119
126
  }
120
127
 
128
+ if (platform === Platform.Cursor) {
129
+ // Skills are installed to ~/.claude/skills/ (unified location)
130
+ // Cursor reads from this location via Agent Skills standard compatibility
131
+ // Ensure .cursor directory exists for agents
132
+ const cursorDir = join(homedir(), '.cursor');
133
+ if (!existsSync(cursorDir)) {
134
+ mkdirSync(cursorDir, { recursive: true });
135
+ }
136
+
137
+ // Ensure agents directory exists
138
+ const agentsDir = join(cursorDir, 'agents');
139
+ if (!existsSync(agentsDir)) {
140
+ mkdirSync(agentsDir, { recursive: true });
141
+ }
142
+
143
+ return { added: [], alreadyPresent: true };
144
+ }
145
+
121
146
  return { added: [], alreadyPresent: true };
122
147
  }
123
148
 
@@ -190,6 +215,7 @@ export async function setupCommand(): Promise<void> {
190
215
  message: 'Which platform are you using?',
191
216
  choices: [
192
217
  { name: 'Claude Code', value: Platform.ClaudeCode },
218
+ { name: 'Cursor', value: Platform.Cursor },
193
219
  { name: 'OpenCode', value: Platform.OpenCode },
194
220
  ],
195
221
  default: detectedPlatform || Platform.ClaudeCode,
@@ -245,6 +271,9 @@ export async function setupCommand(): Promise<void> {
245
271
  }
246
272
  } else if (answers.platform === Platform.OpenCode) {
247
273
  console.log(chalk.gray(' Skills installed to ~/.claude/skills/ (works with Claude Code, OpenCode, and Cursor)'));
274
+ } else if (answers.platform === Platform.Cursor) {
275
+ console.log(chalk.gray(' Skills installed to ~/.claude/skills/ (Cursor reads from this location)'));
276
+ console.log(chalk.gray(' Note: Cursor requires nightly channel for Agent Skills support'));
248
277
  }
249
278
 
250
279
  console.log(chalk.gray('\nRun `droid skills` to browse and install skills.'));
@@ -21,7 +21,7 @@ export function SettingsDetails({
21
21
  <Text>
22
22
  <Text color={colors.textDim}>Platform: </Text>
23
23
  <Text color={colors.text}>
24
- {config.platform === Platform.ClaudeCode ? 'Claude Code' : 'OpenCode'}
24
+ {config.platform === Platform.ClaudeCode ? 'Claude Code' : config.platform === Platform.Cursor ? 'Cursor' : 'OpenCode'}
25
25
  </Text>
26
26
  </Text>
27
27
  <Text>
@@ -15,6 +15,7 @@ export interface SetupScreenProps {
15
15
 
16
16
  const platformOptions = [
17
17
  { label: 'Claude Code', value: Platform.ClaudeCode },
18
+ { label: 'Cursor', value: Platform.Cursor },
18
19
  { label: 'OpenCode', value: Platform.OpenCode },
19
20
  ];
20
21
 
@@ -214,7 +215,7 @@ export function SetupScreen({ onComplete, onSkip, initialConfig }: SetupScreenPr
214
215
  <Box flexDirection="column" marginTop={1}>
215
216
  <Text>
216
217
  <Text color={colors.textDim}>Platform: </Text>
217
- <Text color={colors.text}>{platform === Platform.ClaudeCode ? 'Claude Code' : 'OpenCode'}</Text>
218
+ <Text color={colors.text}>{platform === Platform.ClaudeCode ? 'Claude Code' : platform === Platform.Cursor ? 'Cursor' : 'OpenCode'}</Text>
218
219
  </Text>
219
220
  <Text>
220
221
  <Text color={colors.textDim}>Your @mention: </Text>
@@ -38,10 +38,11 @@ export function ToolExplorer({ tool, onViewSource, onClose }: ToolExplorerProps)
38
38
 
39
39
  // Add commands
40
40
  for (const cmd of tool.includes.commands) {
41
+ const cmdName = typeof cmd === 'string' ? cmd : cmd.name;
41
42
  result.push({
42
43
  type: 'command',
43
- name: `/${cmd}`,
44
- path: join(toolDir, tool.name, 'commands', `${cmd}.md`),
44
+ name: `/${cmdName}`,
45
+ path: join(toolDir, tool.name, 'commands', `${cmdName}.md`),
45
46
  });
46
47
  }
47
48
 
@@ -455,7 +455,9 @@ function App() {
455
455
  <Text color={colors.textDim}>
456
456
  {loadConfig().platform === Platform.ClaudeCode
457
457
  ? 'Claude Code'
458
- : 'OpenCode'}
458
+ : loadConfig().platform === Platform.Cursor
459
+ ? 'Cursor'
460
+ : 'OpenCode'}
459
461
  </Text>
460
462
  </Box>
461
463
 
@@ -112,7 +112,7 @@ function createPlatformSyncMigration(version: string): Migration {
112
112
  const originalPlatform = config.platform;
113
113
 
114
114
  // Check both platforms
115
- for (const platformKey of [Platform.ClaudeCode, Platform.OpenCode]) {
115
+ for (const platformKey of [Platform.ClaudeCode, Platform.OpenCode, Platform.Cursor]) {
116
116
  const skillsPath = getSkillsPath(platformKey);
117
117
  if (!existsSync(skillsPath)) continue;
118
118
 
@@ -176,7 +176,7 @@ function createConfigSkillNameMigration(version: string): Migration {
176
176
  const originalPlatform = config.platform;
177
177
 
178
178
  // Check both platforms
179
- for (const platformKey of [Platform.ClaudeCode, Platform.OpenCode]) {
179
+ for (const platformKey of [Platform.ClaudeCode, Platform.OpenCode, Platform.Cursor]) {
180
180
  if (!config.platforms[platformKey]) continue;
181
181
 
182
182
  config.platform = platformKey;
@@ -28,6 +28,14 @@ export const PLATFORM_PATHS = {
28
28
  agents: join(homedir(), '.config', 'opencode', 'agent'),
29
29
  config: join(homedir(), '.config', 'opencode', 'AGENTS.md'),
30
30
  },
31
+ [Platform.Cursor]: {
32
+ skills: UNIFIED_SKILLS_PATH,
33
+ // Cursor doesn't have a documented global commands path - commands are discovered from projects
34
+ // We use this path as a placeholder; commands may not work the same as Claude Code/OpenCode
35
+ commands: join(homedir(), '.cursor', 'commands'),
36
+ agents: join(homedir(), '.cursor', 'agents'),
37
+ config: join(homedir(), '.cursor', 'rules'),
38
+ },
31
39
  } as const;
32
40
 
33
41
  export type PlatformPaths = typeof PLATFORM_PATHS[Platform];
@@ -47,6 +47,12 @@ describe("getSkillsInstallPath", () => {
47
47
  const path = getSkillsInstallPath(Platform.OpenCode);
48
48
  expect(path).toBe(join(homedir(), ".claude", "skills"));
49
49
  });
50
+
51
+ it("should return unified skills path for Cursor", () => {
52
+ // Cursor also uses the unified ~/.claude/skills/ path (Agent Skills standard)
53
+ const path = getSkillsInstallPath(Platform.Cursor);
54
+ expect(path).toBe(join(homedir(), ".claude", "skills"));
55
+ });
50
56
  });
51
57
 
52
58
  describe("getCommandsInstallPath", () => {
@@ -59,6 +65,11 @@ describe("getCommandsInstallPath", () => {
59
65
  const path = getCommandsInstallPath(Platform.OpenCode);
60
66
  expect(path).toBe(join(homedir(), ".config", "opencode", "command"));
61
67
  });
68
+
69
+ it("should return Cursor commands path", () => {
70
+ const path = getCommandsInstallPath(Platform.Cursor);
71
+ expect(path).toBe(join(homedir(), ".cursor", "commands"));
72
+ });
62
73
  });
63
74
 
64
75
  describe("getPlatformConfigPath", () => {
@@ -71,6 +82,11 @@ describe("getPlatformConfigPath", () => {
71
82
  const path = getPlatformConfigPath(Platform.OpenCode);
72
83
  expect(path).toBe(join(homedir(), ".config", "opencode", "AGENTS.md"));
73
84
  });
85
+
86
+ it("should return Cursor rules path", () => {
87
+ const path = getPlatformConfigPath(Platform.Cursor);
88
+ expect(path).toBe(join(homedir(), ".cursor", "rules"));
89
+ });
74
90
  });
75
91
 
76
92
  describe("getBundledSkillsDir", () => {
package/src/lib/types.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export enum Platform {
2
2
  ClaudeCode = 'claude-code',
3
3
  OpenCode = 'opencode',
4
+ Cursor = 'cursor',
4
5
  }
5
6
 
6
7
  // Backwards compatibility alias - using different names to avoid redeclare error