@cleocode/adapters 2.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.
Files changed (217) hide show
  1. package/dist/index.d.ts +27 -0
  2. package/dist/index.d.ts.map +1 -0
  3. package/dist/index.js +1927 -0
  4. package/dist/index.js.map +7 -0
  5. package/dist/providers/claude-code/adapter.d.ts +75 -0
  6. package/dist/providers/claude-code/adapter.d.ts.map +1 -0
  7. package/dist/providers/claude-code/adapter.js +154 -0
  8. package/dist/providers/claude-code/adapter.js.map +1 -0
  9. package/dist/providers/claude-code/context-monitor.d.ts +24 -0
  10. package/dist/providers/claude-code/context-monitor.d.ts.map +1 -0
  11. package/dist/providers/claude-code/context-monitor.js +148 -0
  12. package/dist/providers/claude-code/context-monitor.js.map +1 -0
  13. package/dist/providers/claude-code/hooks.d.ts +59 -0
  14. package/dist/providers/claude-code/hooks.d.ts.map +1 -0
  15. package/dist/providers/claude-code/hooks.js +77 -0
  16. package/dist/providers/claude-code/hooks.js.map +1 -0
  17. package/dist/providers/claude-code/index.d.ts +24 -0
  18. package/dist/providers/claude-code/index.d.ts.map +1 -0
  19. package/dist/providers/claude-code/index.js +26 -0
  20. package/dist/providers/claude-code/index.js.map +1 -0
  21. package/dist/providers/claude-code/install.d.ts +75 -0
  22. package/dist/providers/claude-code/install.d.ts.map +1 -0
  23. package/dist/providers/claude-code/install.js +237 -0
  24. package/dist/providers/claude-code/install.js.map +1 -0
  25. package/dist/providers/claude-code/paths.d.ts +24 -0
  26. package/dist/providers/claude-code/paths.d.ts.map +1 -0
  27. package/dist/providers/claude-code/paths.js +33 -0
  28. package/dist/providers/claude-code/paths.js.map +1 -0
  29. package/dist/providers/claude-code/spawn.d.ts +60 -0
  30. package/dist/providers/claude-code/spawn.d.ts.map +1 -0
  31. package/dist/providers/claude-code/spawn.js +160 -0
  32. package/dist/providers/claude-code/spawn.js.map +1 -0
  33. package/dist/providers/claude-code/statusline.d.ts +24 -0
  34. package/dist/providers/claude-code/statusline.d.ts.map +1 -0
  35. package/dist/providers/claude-code/statusline.js +85 -0
  36. package/dist/providers/claude-code/statusline.js.map +1 -0
  37. package/dist/providers/claude-code/task-sync.d.ts +27 -0
  38. package/dist/providers/claude-code/task-sync.d.ts.map +1 -0
  39. package/dist/providers/claude-code/task-sync.js +124 -0
  40. package/dist/providers/claude-code/task-sync.js.map +1 -0
  41. package/dist/providers/claude-code/transport.d.ts +14 -0
  42. package/dist/providers/claude-code/transport.d.ts.map +1 -0
  43. package/dist/providers/claude-code/transport.js +18 -0
  44. package/dist/providers/claude-code/transport.js.map +1 -0
  45. package/dist/providers/cursor/adapter.d.ts +62 -0
  46. package/dist/providers/cursor/adapter.d.ts.map +1 -0
  47. package/dist/providers/cursor/adapter.js +124 -0
  48. package/dist/providers/cursor/adapter.js.map +1 -0
  49. package/dist/providers/cursor/hooks.d.ts +48 -0
  50. package/dist/providers/cursor/hooks.d.ts.map +1 -0
  51. package/dist/providers/cursor/hooks.js +55 -0
  52. package/dist/providers/cursor/hooks.js.map +1 -0
  53. package/dist/providers/cursor/index.d.ts +19 -0
  54. package/dist/providers/cursor/index.d.ts.map +1 -0
  55. package/dist/providers/cursor/index.js +21 -0
  56. package/dist/providers/cursor/index.js.map +1 -0
  57. package/dist/providers/cursor/install.d.ts +94 -0
  58. package/dist/providers/cursor/install.d.ts.map +1 -0
  59. package/dist/providers/cursor/install.js +241 -0
  60. package/dist/providers/cursor/install.js.map +1 -0
  61. package/dist/providers/cursor/spawn.d.ts +50 -0
  62. package/dist/providers/cursor/spawn.d.ts.map +1 -0
  63. package/dist/providers/cursor/spawn.js +59 -0
  64. package/dist/providers/cursor/spawn.js.map +1 -0
  65. package/dist/providers/opencode/adapter.d.ts +67 -0
  66. package/dist/providers/opencode/adapter.d.ts.map +1 -0
  67. package/dist/providers/opencode/adapter.js +144 -0
  68. package/dist/providers/opencode/adapter.js.map +1 -0
  69. package/dist/providers/opencode/hooks.d.ts +66 -0
  70. package/dist/providers/opencode/hooks.d.ts.map +1 -0
  71. package/dist/providers/opencode/hooks.js +89 -0
  72. package/dist/providers/opencode/hooks.js.map +1 -0
  73. package/dist/providers/opencode/index.d.ts +20 -0
  74. package/dist/providers/opencode/index.d.ts.map +1 -0
  75. package/dist/providers/opencode/index.js +22 -0
  76. package/dist/providers/opencode/index.js.map +1 -0
  77. package/dist/providers/opencode/install.d.ts +65 -0
  78. package/dist/providers/opencode/install.d.ts.map +1 -0
  79. package/dist/providers/opencode/install.js +183 -0
  80. package/dist/providers/opencode/install.js.map +1 -0
  81. package/dist/providers/opencode/spawn.d.ts +72 -0
  82. package/dist/providers/opencode/spawn.d.ts.map +1 -0
  83. package/dist/providers/opencode/spawn.js +219 -0
  84. package/dist/providers/opencode/spawn.js.map +1 -0
  85. package/dist/registry.d.ts +36 -0
  86. package/dist/registry.d.ts.map +1 -0
  87. package/dist/registry.js +55 -0
  88. package/dist/registry.js.map +1 -0
  89. package/package.json +32 -0
  90. package/src/index.d.ts +27 -0
  91. package/src/index.d.ts.map +1 -0
  92. package/src/index.js +28 -0
  93. package/src/index.js.map +1 -0
  94. package/src/index.ts +37 -0
  95. package/src/providers/claude-code/__tests__/adapter.test.d.ts +7 -0
  96. package/src/providers/claude-code/__tests__/adapter.test.d.ts.map +1 -0
  97. package/src/providers/claude-code/__tests__/adapter.test.js +249 -0
  98. package/src/providers/claude-code/__tests__/adapter.test.js.map +1 -0
  99. package/src/providers/claude-code/__tests__/adapter.test.ts +291 -0
  100. package/src/providers/claude-code/adapter.d.ts +75 -0
  101. package/src/providers/claude-code/adapter.d.ts.map +1 -0
  102. package/src/providers/claude-code/adapter.js +154 -0
  103. package/src/providers/claude-code/adapter.js.map +1 -0
  104. package/src/providers/claude-code/adapter.ts +175 -0
  105. package/src/providers/claude-code/context-monitor.d.ts +24 -0
  106. package/src/providers/claude-code/context-monitor.d.ts.map +1 -0
  107. package/src/providers/claude-code/context-monitor.js +148 -0
  108. package/src/providers/claude-code/context-monitor.js.map +1 -0
  109. package/src/providers/claude-code/context-monitor.ts +175 -0
  110. package/src/providers/claude-code/hooks.d.ts +59 -0
  111. package/src/providers/claude-code/hooks.d.ts.map +1 -0
  112. package/src/providers/claude-code/hooks.js +77 -0
  113. package/src/providers/claude-code/hooks.js.map +1 -0
  114. package/src/providers/claude-code/hooks.ts +85 -0
  115. package/src/providers/claude-code/index.d.ts +24 -0
  116. package/src/providers/claude-code/index.d.ts.map +1 -0
  117. package/src/providers/claude-code/index.js +26 -0
  118. package/src/providers/claude-code/index.js.map +1 -0
  119. package/src/providers/claude-code/index.ts +33 -0
  120. package/src/providers/claude-code/install.d.ts +75 -0
  121. package/src/providers/claude-code/install.d.ts.map +1 -0
  122. package/src/providers/claude-code/install.js +237 -0
  123. package/src/providers/claude-code/install.js.map +1 -0
  124. package/src/providers/claude-code/install.ts +267 -0
  125. package/src/providers/claude-code/manifest.json +26 -0
  126. package/src/providers/claude-code/paths.d.ts +24 -0
  127. package/src/providers/claude-code/paths.d.ts.map +1 -0
  128. package/src/providers/claude-code/paths.js +33 -0
  129. package/src/providers/claude-code/paths.js.map +1 -0
  130. package/src/providers/claude-code/paths.ts +38 -0
  131. package/src/providers/claude-code/spawn.d.ts +60 -0
  132. package/src/providers/claude-code/spawn.d.ts.map +1 -0
  133. package/src/providers/claude-code/spawn.js +160 -0
  134. package/src/providers/claude-code/spawn.js.map +1 -0
  135. package/src/providers/claude-code/spawn.ts +178 -0
  136. package/src/providers/claude-code/statusline.d.ts +24 -0
  137. package/src/providers/claude-code/statusline.d.ts.map +1 -0
  138. package/src/providers/claude-code/statusline.js +85 -0
  139. package/src/providers/claude-code/statusline.js.map +1 -0
  140. package/src/providers/claude-code/statusline.ts +99 -0
  141. package/src/providers/claude-code/task-sync.d.ts +27 -0
  142. package/src/providers/claude-code/task-sync.d.ts.map +1 -0
  143. package/src/providers/claude-code/task-sync.js +124 -0
  144. package/src/providers/claude-code/task-sync.js.map +1 -0
  145. package/src/providers/claude-code/task-sync.ts +158 -0
  146. package/src/providers/claude-code/transport.d.ts +14 -0
  147. package/src/providers/claude-code/transport.d.ts.map +1 -0
  148. package/src/providers/claude-code/transport.js +18 -0
  149. package/src/providers/claude-code/transport.js.map +1 -0
  150. package/src/providers/claude-code/transport.ts +21 -0
  151. package/src/providers/cursor/__tests__/adapter.test.d.ts +7 -0
  152. package/src/providers/cursor/__tests__/adapter.test.d.ts.map +1 -0
  153. package/src/providers/cursor/__tests__/adapter.test.js +246 -0
  154. package/src/providers/cursor/__tests__/adapter.test.js.map +1 -0
  155. package/src/providers/cursor/__tests__/adapter.test.ts +291 -0
  156. package/src/providers/cursor/adapter.d.ts +62 -0
  157. package/src/providers/cursor/adapter.d.ts.map +1 -0
  158. package/src/providers/cursor/adapter.js +124 -0
  159. package/src/providers/cursor/adapter.js.map +1 -0
  160. package/src/providers/cursor/adapter.ts +145 -0
  161. package/src/providers/cursor/hooks.d.ts +48 -0
  162. package/src/providers/cursor/hooks.d.ts.map +1 -0
  163. package/src/providers/cursor/hooks.js +55 -0
  164. package/src/providers/cursor/hooks.js.map +1 -0
  165. package/src/providers/cursor/hooks.ts +61 -0
  166. package/src/providers/cursor/index.d.ts +19 -0
  167. package/src/providers/cursor/index.d.ts.map +1 -0
  168. package/src/providers/cursor/index.js +21 -0
  169. package/src/providers/cursor/index.js.map +1 -0
  170. package/src/providers/cursor/index.ts +24 -0
  171. package/src/providers/cursor/install.d.ts +94 -0
  172. package/src/providers/cursor/install.d.ts.map +1 -0
  173. package/src/providers/cursor/install.js +241 -0
  174. package/src/providers/cursor/install.js.map +1 -0
  175. package/src/providers/cursor/install.ts +271 -0
  176. package/src/providers/cursor/manifest.json +26 -0
  177. package/src/providers/cursor/spawn.d.ts +50 -0
  178. package/src/providers/cursor/spawn.d.ts.map +1 -0
  179. package/src/providers/cursor/spawn.js +59 -0
  180. package/src/providers/cursor/spawn.js.map +1 -0
  181. package/src/providers/cursor/spawn.ts +66 -0
  182. package/src/providers/opencode/__tests__/adapter.test.d.ts +7 -0
  183. package/src/providers/opencode/__tests__/adapter.test.d.ts.map +1 -0
  184. package/src/providers/opencode/__tests__/adapter.test.js +263 -0
  185. package/src/providers/opencode/__tests__/adapter.test.js.map +1 -0
  186. package/src/providers/opencode/__tests__/adapter.test.ts +309 -0
  187. package/src/providers/opencode/adapter.d.ts +67 -0
  188. package/src/providers/opencode/adapter.d.ts.map +1 -0
  189. package/src/providers/opencode/adapter.js +144 -0
  190. package/src/providers/opencode/adapter.js.map +1 -0
  191. package/src/providers/opencode/adapter.ts +165 -0
  192. package/src/providers/opencode/hooks.d.ts +66 -0
  193. package/src/providers/opencode/hooks.d.ts.map +1 -0
  194. package/src/providers/opencode/hooks.js +89 -0
  195. package/src/providers/opencode/hooks.js.map +1 -0
  196. package/src/providers/opencode/hooks.ts +97 -0
  197. package/src/providers/opencode/index.d.ts +20 -0
  198. package/src/providers/opencode/index.d.ts.map +1 -0
  199. package/src/providers/opencode/index.js +22 -0
  200. package/src/providers/opencode/index.js.map +1 -0
  201. package/src/providers/opencode/index.ts +25 -0
  202. package/src/providers/opencode/install.d.ts +65 -0
  203. package/src/providers/opencode/install.d.ts.map +1 -0
  204. package/src/providers/opencode/install.js +183 -0
  205. package/src/providers/opencode/install.js.map +1 -0
  206. package/src/providers/opencode/install.ts +206 -0
  207. package/src/providers/opencode/manifest.json +26 -0
  208. package/src/providers/opencode/spawn.d.ts +72 -0
  209. package/src/providers/opencode/spawn.d.ts.map +1 -0
  210. package/src/providers/opencode/spawn.js +219 -0
  211. package/src/providers/opencode/spawn.js.map +1 -0
  212. package/src/providers/opencode/spawn.ts +253 -0
  213. package/src/registry.d.ts +36 -0
  214. package/src/registry.d.ts.map +1 -0
  215. package/src/registry.js +55 -0
  216. package/src/registry.js.map +1 -0
  217. package/src/registry.ts +81 -0
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Claude Code TaskSyncProvider — bridges Claude's TodoWrite format
3
+ * to the provider-agnostic reconciliation system.
4
+ *
5
+ * All Claude Code / TodoWrite-specific parsing lives here.
6
+ * The core reconciliation engine never sees TodoWrite formats.
7
+ *
8
+ * @task T5800
9
+ */
10
+ import { readFile, rm, stat } from 'node:fs/promises';
11
+ import { join } from 'node:path';
12
+ // ---------------------------------------------------------------------------
13
+ // Parsing helpers
14
+ // ---------------------------------------------------------------------------
15
+ /**
16
+ * Parse a CLEO task ID from TodoWrite content prefix: "[T001] ..." -> "T001".
17
+ */
18
+ function parseTaskId(content) {
19
+ const match = content.match(/^\[T(\d+)\]/);
20
+ return match ? `T${match[1]}` : null;
21
+ }
22
+ /**
23
+ * Strip ID and status prefixes from content to extract the clean title.
24
+ */
25
+ function stripPrefixes(content) {
26
+ return content
27
+ .replace(/^\[T\d+\]\s*/, '')
28
+ .replace(/^\[!\]\s*/, '')
29
+ .replace(/^\[BLOCKED\]\s*/, '');
30
+ }
31
+ /**
32
+ * Map TodoWrite status to normalized ExternalTaskStatus.
33
+ */
34
+ function mapStatus(twStatus) {
35
+ switch (twStatus) {
36
+ case 'completed':
37
+ return 'completed';
38
+ case 'in_progress':
39
+ return 'active';
40
+ case 'pending':
41
+ return 'pending';
42
+ default:
43
+ return 'pending';
44
+ }
45
+ }
46
+ /**
47
+ * Resolve the TodoWrite state file path.
48
+ * Claude Code writes its TodoWrite state to a known location.
49
+ */
50
+ function getTodoWriteFilePath(projectDir) {
51
+ return join(projectDir, '.cleo', 'sync', 'todowrite-state.json');
52
+ }
53
+ // ---------------------------------------------------------------------------
54
+ // Provider implementation
55
+ // ---------------------------------------------------------------------------
56
+ /**
57
+ * Claude Code TaskSyncProvider.
58
+ *
59
+ * Reads Claude's TodoWrite JSON state, parses [T001]-prefixed task IDs
60
+ * and status, and returns normalized ExternalTask[].
61
+ *
62
+ * Optional: accepts a custom file path for testing.
63
+ */
64
+ export class ClaudeCodeTaskSyncProvider {
65
+ customFilePath;
66
+ constructor(options) {
67
+ this.customFilePath = options?.filePath;
68
+ }
69
+ async getExternalTasks(projectDir) {
70
+ const filePath = this.customFilePath ?? getTodoWriteFilePath(projectDir);
71
+ // Check file exists
72
+ try {
73
+ await stat(filePath);
74
+ }
75
+ catch {
76
+ // No TodoWrite state — return empty (no tasks to sync)
77
+ return [];
78
+ }
79
+ // Parse the TodoWrite JSON
80
+ const raw = await readFile(filePath, 'utf-8');
81
+ let state;
82
+ try {
83
+ state = JSON.parse(raw);
84
+ }
85
+ catch {
86
+ return []; // Malformed JSON — treat as empty
87
+ }
88
+ if (!state.todos || !Array.isArray(state.todos)) {
89
+ return [];
90
+ }
91
+ const tasks = [];
92
+ let syntheticIndex = 0;
93
+ for (const item of state.todos) {
94
+ const cleoTaskId = parseTaskId(item.content);
95
+ const title = cleoTaskId
96
+ ? stripPrefixes(item.content).trim()
97
+ : item.content.trim();
98
+ if (!title)
99
+ continue;
100
+ tasks.push({
101
+ externalId: cleoTaskId ?? `tw-new-${syntheticIndex++}`,
102
+ cleoTaskId,
103
+ title,
104
+ status: mapStatus(item.status),
105
+ providerMeta: {
106
+ source: 'todowrite',
107
+ activeForm: item.activeForm,
108
+ rawContent: item.content,
109
+ },
110
+ });
111
+ }
112
+ return tasks;
113
+ }
114
+ async cleanup(projectDir) {
115
+ const filePath = this.customFilePath ?? getTodoWriteFilePath(projectDir);
116
+ try {
117
+ await rm(filePath);
118
+ }
119
+ catch {
120
+ // File may not exist — that's fine
121
+ }
122
+ }
123
+ }
124
+ //# sourceMappingURL=task-sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-sync.js","sourceRoot":"","sources":["task-sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Claude Code TaskSyncProvider — bridges Claude's TodoWrite format
3
+ * to the provider-agnostic reconciliation system.
4
+ *
5
+ * All Claude Code / TodoWrite-specific parsing lives here.
6
+ * The core reconciliation engine never sees TodoWrite formats.
7
+ *
8
+ * @task T5800
9
+ */
10
+
11
+ import { readFile, rm, stat } from 'node:fs/promises';
12
+ import { join } from 'node:path';
13
+
14
+ import type {
15
+ AdapterTaskSyncProvider,
16
+ ExternalTask,
17
+ ExternalTaskStatus,
18
+ } from '@cleocode/contracts';
19
+
20
+ // ---------------------------------------------------------------------------
21
+ // TodoWrite native types (Claude-specific, never exposed beyond this file)
22
+ // ---------------------------------------------------------------------------
23
+
24
+ interface TodoWriteItem {
25
+ content: string;
26
+ status: 'pending' | 'in_progress' | 'completed';
27
+ activeForm?: string;
28
+ }
29
+
30
+ interface TodoWriteState {
31
+ todos: TodoWriteItem[];
32
+ }
33
+
34
+ // ---------------------------------------------------------------------------
35
+ // Parsing helpers
36
+ // ---------------------------------------------------------------------------
37
+
38
+ /**
39
+ * Parse a CLEO task ID from TodoWrite content prefix: "[T001] ..." -> "T001".
40
+ */
41
+ function parseTaskId(content: string): string | null {
42
+ const match = content.match(/^\[T(\d+)\]/);
43
+ return match ? `T${match[1]}` : null;
44
+ }
45
+
46
+ /**
47
+ * Strip ID and status prefixes from content to extract the clean title.
48
+ */
49
+ function stripPrefixes(content: string): string {
50
+ return content
51
+ .replace(/^\[T\d+\]\s*/, '')
52
+ .replace(/^\[!\]\s*/, '')
53
+ .replace(/^\[BLOCKED\]\s*/, '');
54
+ }
55
+
56
+ /**
57
+ * Map TodoWrite status to normalized ExternalTaskStatus.
58
+ */
59
+ function mapStatus(twStatus: TodoWriteItem['status']): ExternalTaskStatus {
60
+ switch (twStatus) {
61
+ case 'completed':
62
+ return 'completed';
63
+ case 'in_progress':
64
+ return 'active';
65
+ case 'pending':
66
+ return 'pending';
67
+ default:
68
+ return 'pending';
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Resolve the TodoWrite state file path.
74
+ * Claude Code writes its TodoWrite state to a known location.
75
+ */
76
+ function getTodoWriteFilePath(projectDir: string): string {
77
+ return join(projectDir, '.cleo', 'sync', 'todowrite-state.json');
78
+ }
79
+
80
+ // ---------------------------------------------------------------------------
81
+ // Provider implementation
82
+ // ---------------------------------------------------------------------------
83
+
84
+ /**
85
+ * Claude Code TaskSyncProvider.
86
+ *
87
+ * Reads Claude's TodoWrite JSON state, parses [T001]-prefixed task IDs
88
+ * and status, and returns normalized ExternalTask[].
89
+ *
90
+ * Optional: accepts a custom file path for testing.
91
+ */
92
+ export class ClaudeCodeTaskSyncProvider implements AdapterTaskSyncProvider {
93
+ private readonly customFilePath?: string;
94
+
95
+ constructor(options?: { filePath?: string }) {
96
+ this.customFilePath = options?.filePath;
97
+ }
98
+
99
+ async getExternalTasks(projectDir: string): Promise<ExternalTask[]> {
100
+ const filePath = this.customFilePath ?? getTodoWriteFilePath(projectDir);
101
+
102
+ // Check file exists
103
+ try {
104
+ await stat(filePath);
105
+ } catch {
106
+ // No TodoWrite state — return empty (no tasks to sync)
107
+ return [];
108
+ }
109
+
110
+ // Parse the TodoWrite JSON
111
+ const raw = await readFile(filePath, 'utf-8');
112
+ let state: TodoWriteState;
113
+ try {
114
+ state = JSON.parse(raw) as TodoWriteState;
115
+ } catch {
116
+ return []; // Malformed JSON — treat as empty
117
+ }
118
+
119
+ if (!state.todos || !Array.isArray(state.todos)) {
120
+ return [];
121
+ }
122
+
123
+ const tasks: ExternalTask[] = [];
124
+ let syntheticIndex = 0;
125
+
126
+ for (const item of state.todos) {
127
+ const cleoTaskId = parseTaskId(item.content);
128
+ const title = cleoTaskId
129
+ ? stripPrefixes(item.content).trim()
130
+ : item.content.trim();
131
+
132
+ if (!title) continue;
133
+
134
+ tasks.push({
135
+ externalId: cleoTaskId ?? `tw-new-${syntheticIndex++}`,
136
+ cleoTaskId,
137
+ title,
138
+ status: mapStatus(item.status),
139
+ providerMeta: {
140
+ source: 'todowrite',
141
+ activeForm: item.activeForm,
142
+ rawContent: item.content,
143
+ },
144
+ });
145
+ }
146
+
147
+ return tasks;
148
+ }
149
+
150
+ async cleanup(projectDir: string): Promise<void> {
151
+ const filePath = this.customFilePath ?? getTodoWriteFilePath(projectDir);
152
+ try {
153
+ await rm(filePath);
154
+ } catch {
155
+ // File may not exist — that's fine
156
+ }
157
+ }
158
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Transport provider for the Claude Code adapter.
3
+ *
4
+ * Implements AdapterTransportProvider to supply Claude Code's
5
+ * native inter-agent transport mechanism.
6
+ *
7
+ * @task T5240
8
+ */
9
+ import type { AdapterTransportProvider } from '@cleocode/contracts';
10
+ export declare class ClaudeCodeTransportProvider implements AdapterTransportProvider {
11
+ readonly transportName = "claude-code";
12
+ createTransport(): unknown;
13
+ }
14
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["transport.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAEpE,qBAAa,2BAA4B,YAAW,wBAAwB;IAC1E,QAAQ,CAAC,aAAa,iBAAiB;IAEvC,eAAe,IAAI,OAAO;CAM3B"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Transport provider for the Claude Code adapter.
3
+ *
4
+ * Implements AdapterTransportProvider to supply Claude Code's
5
+ * native inter-agent transport mechanism.
6
+ *
7
+ * @task T5240
8
+ */
9
+ export class ClaudeCodeTransportProvider {
10
+ transportName = 'claude-code';
11
+ createTransport() {
12
+ // Returns null — actual transport creation is handled by the signaldock factory
13
+ // which checks for this adapter's transport capability.
14
+ // Full wiring will be completed in Phase 5.
15
+ return null;
16
+ }
17
+ }
18
+ //# sourceMappingURL=transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["transport.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,OAAO,2BAA2B;IAC7B,aAAa,GAAG,aAAa,CAAC;IAEvC,eAAe;QACb,gFAAgF;QAChF,wDAAwD;QACxD,4CAA4C;QAC5C,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Transport provider for the Claude Code adapter.
3
+ *
4
+ * Implements AdapterTransportProvider to supply Claude Code's
5
+ * native inter-agent transport mechanism.
6
+ *
7
+ * @task T5240
8
+ */
9
+
10
+ import type { AdapterTransportProvider } from '@cleocode/contracts';
11
+
12
+ export class ClaudeCodeTransportProvider implements AdapterTransportProvider {
13
+ readonly transportName = 'claude-code';
14
+
15
+ createTransport(): unknown {
16
+ // Returns null — actual transport creation is handled by the signaldock factory
17
+ // which checks for this adapter's transport capability.
18
+ // Full wiring will be completed in Phase 5.
19
+ return null;
20
+ }
21
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Tests for the Cursor adapter package.
3
+ *
4
+ * @task T5240
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=adapter.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.test.d.ts","sourceRoot":"","sources":["adapter.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,246 @@
1
+ /**
2
+ * Tests for the Cursor adapter package.
3
+ *
4
+ * @task T5240
5
+ */
6
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
7
+ import { CursorAdapter } from '../adapter.js';
8
+ import { CursorHookProvider } from '../hooks.js';
9
+ import { CursorSpawnProvider } from '../spawn.js'; // spawn.ts still exists for direct use
10
+ import { CursorInstallProvider } from '../install.js';
11
+ vi.mock('node:fs', async (importOriginal) => {
12
+ const actual = await importOriginal();
13
+ return {
14
+ ...actual,
15
+ existsSync: vi.fn((path) => {
16
+ if (typeof path === 'string' && path.includes('.cursor'))
17
+ return true;
18
+ if (typeof path === 'string' && path.includes('.cursorrules'))
19
+ return false;
20
+ return false;
21
+ }),
22
+ readFileSync: vi.fn((path) => {
23
+ if (typeof path === 'string' && path.includes('mcp.json')) {
24
+ return JSON.stringify({ mcpServers: { cleo: { command: 'node', args: ['mcp.js'] } } });
25
+ }
26
+ return '{}';
27
+ }),
28
+ writeFileSync: vi.fn(),
29
+ mkdirSync: vi.fn(),
30
+ };
31
+ });
32
+ describe('CursorAdapter', () => {
33
+ let adapter;
34
+ beforeEach(() => {
35
+ adapter = new CursorAdapter();
36
+ });
37
+ afterEach(async () => {
38
+ if (adapter.isInitialized()) {
39
+ await adapter.dispose();
40
+ }
41
+ vi.restoreAllMocks();
42
+ });
43
+ describe('identity', () => {
44
+ it('has correct id', () => {
45
+ expect(adapter.id).toBe('cursor');
46
+ });
47
+ it('has correct name', () => {
48
+ expect(adapter.name).toBe('Cursor');
49
+ });
50
+ it('has correct version', () => {
51
+ expect(adapter.version).toBe('1.0.0');
52
+ });
53
+ });
54
+ describe('capabilities', () => {
55
+ it('does not support hooks', () => {
56
+ expect(adapter.capabilities.supportsHooks).toBe(false);
57
+ });
58
+ it('has no supported hook events', () => {
59
+ expect(adapter.capabilities.supportedHookEvents).toHaveLength(0);
60
+ });
61
+ it('does not support spawn', () => {
62
+ expect(adapter.capabilities.supportsSpawn).toBe(false);
63
+ });
64
+ it('supports install', () => {
65
+ expect(adapter.capabilities.supportsInstall).toBe(true);
66
+ });
67
+ it('supports MCP', () => {
68
+ expect(adapter.capabilities.supportsMcp).toBe(true);
69
+ });
70
+ it('supports instruction files with MDC pattern', () => {
71
+ expect(adapter.capabilities.supportsInstructionFiles).toBe(true);
72
+ expect(adapter.capabilities.instructionFilePattern).toBe('.cursor/rules/*.mdc');
73
+ });
74
+ });
75
+ describe('sub-providers', () => {
76
+ it('provides a hook provider (stub)', () => {
77
+ expect(adapter.hooks).toBeInstanceOf(CursorHookProvider);
78
+ });
79
+ it('provides an install provider', () => {
80
+ expect(adapter.install).toBeInstanceOf(CursorInstallProvider);
81
+ });
82
+ });
83
+ describe('initialize', () => {
84
+ it('sets initialized state', async () => {
85
+ expect(adapter.isInitialized()).toBe(false);
86
+ await adapter.initialize('/tmp/test-project');
87
+ expect(adapter.isInitialized()).toBe(true);
88
+ });
89
+ it('stores project directory', async () => {
90
+ await adapter.initialize('/tmp/test-project');
91
+ expect(adapter.getProjectDir()).toBe('/tmp/test-project');
92
+ });
93
+ });
94
+ describe('dispose', () => {
95
+ it('resets initialized state', async () => {
96
+ await adapter.initialize('/tmp/test-project');
97
+ await adapter.dispose();
98
+ expect(adapter.isInitialized()).toBe(false);
99
+ expect(adapter.getProjectDir()).toBeNull();
100
+ });
101
+ });
102
+ describe('healthCheck', () => {
103
+ it('returns unhealthy when not initialized', async () => {
104
+ const status = await adapter.healthCheck();
105
+ expect(status.healthy).toBe(false);
106
+ expect(status.provider).toBe('cursor');
107
+ expect(status.details?.error).toBe('Adapter not initialized');
108
+ });
109
+ it('returns health status with provider id', async () => {
110
+ await adapter.initialize('/tmp/test-project');
111
+ const status = await adapter.healthCheck();
112
+ expect(status.provider).toBe('cursor');
113
+ expect(typeof status.healthy).toBe('boolean');
114
+ });
115
+ it('checks for .cursor directory existence', async () => {
116
+ await adapter.initialize('/tmp/test-project');
117
+ const status = await adapter.healthCheck();
118
+ expect(status.details?.configDirExists).toBeDefined();
119
+ });
120
+ it('checks for CURSOR_EDITOR env var', async () => {
121
+ await adapter.initialize('/tmp/test-project');
122
+ const status = await adapter.healthCheck();
123
+ expect(status.details?.editorEnvSet).toBeDefined();
124
+ });
125
+ });
126
+ });
127
+ describe('CursorHookProvider', () => {
128
+ let hooks;
129
+ beforeEach(() => {
130
+ hooks = new CursorHookProvider();
131
+ });
132
+ describe('mapProviderEvent', () => {
133
+ it('returns null for any event (no hook support)', () => {
134
+ expect(hooks.mapProviderEvent('session.start')).toBeNull();
135
+ expect(hooks.mapProviderEvent('tool.complete')).toBeNull();
136
+ expect(hooks.mapProviderEvent('any-event')).toBeNull();
137
+ expect(hooks.mapProviderEvent('')).toBeNull();
138
+ });
139
+ });
140
+ describe('registerNativeHooks', () => {
141
+ it('completes without error and marks as registered', async () => {
142
+ expect(hooks.isRegistered()).toBe(false);
143
+ await hooks.registerNativeHooks('/tmp/project');
144
+ expect(hooks.isRegistered()).toBe(true);
145
+ });
146
+ });
147
+ describe('unregisterNativeHooks', () => {
148
+ it('completes without error and marks as unregistered', async () => {
149
+ await hooks.registerNativeHooks('/tmp/project');
150
+ await hooks.unregisterNativeHooks();
151
+ expect(hooks.isRegistered()).toBe(false);
152
+ });
153
+ });
154
+ });
155
+ describe('CursorSpawnProvider', () => {
156
+ let spawnProvider;
157
+ beforeEach(() => {
158
+ spawnProvider = new CursorSpawnProvider();
159
+ });
160
+ describe('canSpawn', () => {
161
+ it('returns false (spawn not supported)', async () => {
162
+ const result = await spawnProvider.canSpawn();
163
+ expect(result).toBe(false);
164
+ });
165
+ });
166
+ describe('spawn', () => {
167
+ it('throws an error explaining spawn is not supported', async () => {
168
+ await expect(spawnProvider.spawn({
169
+ taskId: 'T1234',
170
+ prompt: 'test prompt',
171
+ })).rejects.toThrow('Cursor does not support subagent spawning');
172
+ });
173
+ });
174
+ describe('listRunning', () => {
175
+ it('returns empty array', async () => {
176
+ const running = await spawnProvider.listRunning();
177
+ expect(running).toEqual([]);
178
+ });
179
+ });
180
+ describe('terminate', () => {
181
+ it('handles any instance id gracefully (no-op)', async () => {
182
+ await expect(spawnProvider.terminate('any-id')).resolves.toBeUndefined();
183
+ });
184
+ });
185
+ });
186
+ describe('CursorInstallProvider', () => {
187
+ let installProvider;
188
+ beforeEach(() => {
189
+ installProvider = new CursorInstallProvider();
190
+ });
191
+ describe('isInstalled', () => {
192
+ it('returns a boolean', async () => {
193
+ const result = await installProvider.isInstalled();
194
+ expect(typeof result).toBe('boolean');
195
+ });
196
+ });
197
+ describe('install', () => {
198
+ it('returns a success result', async () => {
199
+ const result = await installProvider.install({
200
+ projectDir: '/tmp/test-project',
201
+ });
202
+ expect(result.success).toBe(true);
203
+ expect(result.installedAt).toBeTruthy();
204
+ expect(typeof result.instructionFileUpdated).toBe('boolean');
205
+ expect(typeof result.mcpRegistered).toBe('boolean');
206
+ });
207
+ it('registers MCP when mcpServerPath provided', async () => {
208
+ const result = await installProvider.install({
209
+ projectDir: '/tmp/test-project',
210
+ mcpServerPath: '/path/to/mcp-server.js',
211
+ });
212
+ expect(result.mcpRegistered).toBe(true);
213
+ });
214
+ it('includes instruction files in details', async () => {
215
+ const result = await installProvider.install({
216
+ projectDir: '/tmp/test-project',
217
+ });
218
+ const files = result.details?.instructionFiles;
219
+ expect(Array.isArray(files)).toBe(true);
220
+ expect(files.some((f) => f.includes('cleo.mdc'))).toBe(true);
221
+ });
222
+ });
223
+ describe('uninstall', () => {
224
+ it('handles uninstall when not installed', async () => {
225
+ await expect(installProvider.uninstall()).resolves.toBeUndefined();
226
+ });
227
+ });
228
+ describe('ensureInstructionReferences', () => {
229
+ it('completes without error', async () => {
230
+ await expect(installProvider.ensureInstructionReferences('/tmp/test-project')).resolves.toBeUndefined();
231
+ });
232
+ });
233
+ });
234
+ describe('barrel exports', () => {
235
+ it('exports createAdapter factory function', async () => {
236
+ const module = await import('../index.js');
237
+ expect(typeof module.createAdapter).toBe('function');
238
+ const adapter = module.createAdapter();
239
+ expect(adapter).toBeInstanceOf(CursorAdapter);
240
+ });
241
+ it('exports CursorAdapter as default', async () => {
242
+ const module = await import('../index.js');
243
+ expect(module.default).toBe(CursorAdapter);
244
+ });
245
+ });
246
+ //# sourceMappingURL=adapter.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.test.js","sourceRoot":"","sources":["adapter.test.ts"],"names":[],"mappings":"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"}