@openvcs/sdk 0.2.2 → 0.2.4

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 (51) hide show
  1. package/README.md +76 -7
  2. package/lib/build.d.ts +28 -0
  3. package/lib/build.js +188 -0
  4. package/lib/cli.js +21 -2
  5. package/lib/dist.d.ts +4 -7
  6. package/lib/dist.js +67 -113
  7. package/lib/init.d.ts +2 -0
  8. package/lib/init.js +13 -8
  9. package/lib/runtime/contracts.d.ts +45 -0
  10. package/lib/runtime/contracts.js +4 -0
  11. package/lib/runtime/dispatcher.d.ts +16 -0
  12. package/lib/runtime/dispatcher.js +133 -0
  13. package/lib/runtime/errors.d.ts +5 -0
  14. package/lib/runtime/errors.js +26 -0
  15. package/lib/runtime/host.d.ts +10 -0
  16. package/lib/runtime/host.js +48 -0
  17. package/lib/runtime/index.d.ts +9 -0
  18. package/lib/runtime/index.js +166 -0
  19. package/lib/runtime/transport.d.ts +14 -0
  20. package/lib/runtime/transport.js +72 -0
  21. package/lib/types/host.d.ts +57 -0
  22. package/lib/types/host.js +4 -0
  23. package/lib/types/index.d.ts +4 -0
  24. package/lib/types/index.js +22 -0
  25. package/lib/types/plugin.d.ts +56 -0
  26. package/lib/types/plugin.js +4 -0
  27. package/lib/types/protocol.d.ts +77 -0
  28. package/lib/types/protocol.js +13 -0
  29. package/lib/types/vcs.d.ts +459 -0
  30. package/lib/types/vcs.js +4 -0
  31. package/package.json +16 -3
  32. package/src/lib/build.ts +229 -0
  33. package/src/lib/cli.ts +21 -2
  34. package/src/lib/dist.ts +76 -128
  35. package/src/lib/init.ts +13 -8
  36. package/src/lib/runtime/contracts.ts +52 -0
  37. package/src/lib/runtime/dispatcher.ts +185 -0
  38. package/src/lib/runtime/errors.ts +27 -0
  39. package/src/lib/runtime/host.ts +72 -0
  40. package/src/lib/runtime/index.ts +201 -0
  41. package/src/lib/runtime/transport.ts +93 -0
  42. package/src/lib/types/host.ts +71 -0
  43. package/src/lib/types/index.ts +7 -0
  44. package/src/lib/types/plugin.ts +110 -0
  45. package/src/lib/types/protocol.ts +97 -0
  46. package/src/lib/types/vcs.ts +579 -0
  47. package/test/build.test.js +95 -0
  48. package/test/cli.test.js +37 -0
  49. package/test/dist.test.js +239 -15
  50. package/test/init.test.js +25 -0
  51. package/test/runtime.test.js +118 -0
@@ -0,0 +1,579 @@
1
+ // Copyright © 2025-2026 OpenVCS Contributors
2
+ // SPDX-License-Identifier: GPL-3.0-or-later
3
+
4
+ import type { RequestParams, RpcMethodHandler } from './protocol';
5
+
6
+ /** Describes the feature flags reported by a VCS backend plugin. */
7
+ export interface VcsCapabilities {
8
+ /** Indicates whether commit history operations are supported. */
9
+ commits: boolean;
10
+ /** Indicates whether branch operations are supported. */
11
+ branches: boolean;
12
+ /** Indicates whether tag operations are supported. */
13
+ tags: boolean;
14
+ /** Indicates whether index staging operations are supported. */
15
+ staging: boolean;
16
+ /** Indicates whether push and pull operations are supported. */
17
+ push_pull: boolean;
18
+ /** Indicates whether fast-forward helpers are supported. */
19
+ fast_forward: boolean;
20
+ }
21
+
22
+ /** Describes params that carry a repository session id. */
23
+ export interface VcsSessionParams extends RequestParams {
24
+ /** Stores the repository session id allocated by `vcs.open`. */
25
+ session_id: string;
26
+ }
27
+
28
+ /** Describes the params used by `vcs.open`. */
29
+ export interface VcsOpenParams extends RequestParams {
30
+ /** Stores the repository path to open. */
31
+ path: string;
32
+ }
33
+
34
+ /** Describes the result returned by `vcs.open`. */
35
+ export interface VcsSessionResult {
36
+ /** Stores the allocated repository session id. */
37
+ session_id: string;
38
+ }
39
+
40
+ /** Describes the params used by `vcs.clone_repo`. */
41
+ export interface VcsCloneRepoParams extends RequestParams {
42
+ /** Stores the source repository URL. */
43
+ url: string;
44
+ /** Stores the destination path. */
45
+ dest: string;
46
+ }
47
+
48
+ /** Describes one local branch kind marker. */
49
+ export interface VcsLocalBranchKind {
50
+ /** Stores the branch kind discriminator. */
51
+ type: 'Local';
52
+ }
53
+
54
+ /** Describes one remote branch kind marker. */
55
+ export interface VcsRemoteBranchKind {
56
+ /** Stores the branch kind discriminator. */
57
+ type: 'Remote';
58
+ /** Stores the remote name when known. */
59
+ remote: string | null;
60
+ }
61
+
62
+ /** Describes the branch kind union returned to the host. */
63
+ export type VcsBranchKind = VcsLocalBranchKind | VcsRemoteBranchKind;
64
+
65
+ /** Describes one branch entry returned by `vcs.list_branches`. */
66
+ export interface VcsBranchEntry {
67
+ /** Stores the short branch name. */
68
+ name: string;
69
+ /** Stores the full ref path. */
70
+ full_ref: string;
71
+ /** Stores the local or remote branch kind. */
72
+ kind: VcsBranchKind;
73
+ /** Indicates whether the branch is currently checked out. */
74
+ current: boolean;
75
+ }
76
+
77
+ /** Describes params for branch creation. */
78
+ export interface VcsCreateBranchParams extends VcsSessionParams {
79
+ /** Stores the new branch name. */
80
+ name: string;
81
+ /** Indicates whether the new branch should be checked out immediately. */
82
+ checkout?: boolean;
83
+ }
84
+
85
+ /** Describes params for branch checkout. */
86
+ export interface VcsCheckoutBranchParams extends VcsSessionParams {
87
+ /** Stores the branch name to check out. */
88
+ name: string;
89
+ }
90
+
91
+ /** Describes params for ensuring a remote exists. */
92
+ export interface VcsEnsureRemoteParams extends VcsSessionParams {
93
+ /** Stores the remote name. */
94
+ name: string;
95
+ /** Stores the remote URL. */
96
+ url: string;
97
+ }
98
+
99
+ /** Describes one remote entry. */
100
+ export interface VcsRemoteEntry {
101
+ /** Stores the remote name. */
102
+ name: string;
103
+ /** Stores the remote URL. */
104
+ url: string;
105
+ }
106
+
107
+ /** Describes params for removing a remote. */
108
+ export interface VcsRemoveRemoteParams extends VcsSessionParams {
109
+ /** Stores the remote name to remove. */
110
+ name: string;
111
+ }
112
+
113
+ /** Describes optional fetch flags. */
114
+ export interface VcsFetchOptions {
115
+ /** Indicates whether stale remote references should be pruned. */
116
+ prune?: boolean;
117
+ }
118
+
119
+ /** Describes params for fetch methods. */
120
+ export interface VcsFetchParams extends VcsSessionParams {
121
+ /** Stores the remote to fetch when one is supplied. */
122
+ remote?: string;
123
+ /** Stores the refspec to fetch when one is supplied. */
124
+ refspec?: string;
125
+ /** Stores optional fetch flags. */
126
+ opts?: VcsFetchOptions;
127
+ }
128
+
129
+ /** Describes params for push. */
130
+ export interface VcsPushParams extends VcsSessionParams {
131
+ /** Stores the remote to push to when one is supplied. */
132
+ remote?: string;
133
+ /** Stores the refspec to push when one is supplied. */
134
+ refspec?: string;
135
+ }
136
+
137
+ /** Describes params for fast-forward-only pull. */
138
+ export interface VcsPullFfOnlyParams extends VcsSessionParams {
139
+ /** Stores the remote to pull from when one is supplied. */
140
+ remote?: string;
141
+ /** Stores the branch to pull when one is supplied. */
142
+ branch?: string;
143
+ }
144
+
145
+ /** Describes params for commit creation. */
146
+ export interface VcsCommitParams extends VcsSessionParams {
147
+ /** Stores the commit author name. */
148
+ name: string;
149
+ /** Stores the commit author email. */
150
+ email: string;
151
+ /** Stores the commit message. */
152
+ message: string;
153
+ /** Stores the optional path subset to add before committing. */
154
+ paths?: string[];
155
+ }
156
+
157
+ /** Describes the aggregate repository status counts returned to the host. */
158
+ export interface StatusSummary {
159
+ /** Counts untracked files. */
160
+ untracked: number;
161
+ /** Counts modified working tree files. */
162
+ modified: number;
163
+ /** Counts staged files. */
164
+ staged: number;
165
+ /** Counts conflicted files. */
166
+ conflicted: number;
167
+ }
168
+
169
+ /** Describes one file entry in the OpenVCS status payload. */
170
+ export interface StatusFileEntry {
171
+ /** Stores the current file path. */
172
+ path: string;
173
+ /** Stores the prior path for rename and copy records. */
174
+ old_path: string | null;
175
+ /** Stores the porcelain status code. */
176
+ status: string;
177
+ /** Indicates whether the file has staged changes. */
178
+ staged: boolean;
179
+ /** Indicates whether a conflict has been resolved. */
180
+ resolved_conflict: boolean;
181
+ /** Stores placeholder hunk information until richer diff support exists. */
182
+ hunks: never[];
183
+ }
184
+
185
+ /** Describes the structured status payload returned to the host. */
186
+ export interface StatusPayload {
187
+ /** Stores file-level status entries. */
188
+ files: StatusFileEntry[];
189
+ /** Stores the local branch ahead count relative to its upstream. */
190
+ ahead: number;
191
+ /** Stores the local branch behind count relative to its upstream. */
192
+ behind: number;
193
+ }
194
+
195
+ /** Describes the complete parsed status result. */
196
+ export interface StatusParseResult {
197
+ /** Stores the aggregate status summary. */
198
+ summary: StatusSummary;
199
+ /** Stores the detailed status payload. */
200
+ payload: StatusPayload;
201
+ }
202
+
203
+ /** Describes one list-commits query payload. */
204
+ export interface VcsListCommitsQuery extends RequestParams {
205
+ /** Stores the number of commits to skip. */
206
+ skip?: number;
207
+ /** Stores the maximum number of commits to return. */
208
+ limit?: number;
209
+ /** Indicates whether topo-order should be used. */
210
+ topo_order?: boolean;
211
+ /** Indicates whether merge commits should be included. */
212
+ include_merges?: boolean;
213
+ /** Stores an optional author substring filter. */
214
+ author_contains?: string;
215
+ /** Stores an optional lower timestamp bound in UTC. */
216
+ since_utc?: string;
217
+ /** Stores an optional upper timestamp bound in UTC. */
218
+ until_utc?: string;
219
+ /** Stores the revision to walk from. */
220
+ rev?: string;
221
+ /** Stores an optional path filter. */
222
+ path?: string;
223
+ }
224
+
225
+ /** Describes params for `vcs.list_commits`. */
226
+ export interface VcsListCommitsParams extends VcsSessionParams {
227
+ /** Stores the query object sent by the host. */
228
+ query?: VcsListCommitsQuery;
229
+ }
230
+
231
+ /** Describes one commit entry returned from `git log`. */
232
+ export interface CommitEntry {
233
+ /** Stores the full commit id. */
234
+ id: string;
235
+ /** Stores the commit subject. */
236
+ msg: string;
237
+ /** Stores the author display name. */
238
+ author: string;
239
+ /** Stores the formatted metadata string. */
240
+ meta: string;
241
+ }
242
+
243
+ /** Describes params for `vcs.diff_file`. */
244
+ export interface VcsDiffFileParams extends VcsSessionParams {
245
+ /** Stores the file path to diff. */
246
+ path: string;
247
+ }
248
+
249
+ /** Describes params for `vcs.diff_commit`. */
250
+ export interface VcsDiffCommitParams extends VcsSessionParams {
251
+ /** Stores the revision to diff. */
252
+ rev: string;
253
+ }
254
+
255
+ /** Describes params for `vcs.get_conflict_details`. */
256
+ export interface VcsGetConflictDetailsParams extends VcsSessionParams {
257
+ /** Stores the conflicted path. */
258
+ path: string;
259
+ }
260
+
261
+ /** Describes one conflict details payload. */
262
+ export interface VcsConflictDetails {
263
+ /** Stores the conflicted path. */
264
+ path: string;
265
+ /** Stores the base version content when available. */
266
+ base: string | null;
267
+ /** Stores the current branch content when available. */
268
+ ours: string | null;
269
+ /** Stores the incoming branch content when available. */
270
+ theirs: string | null;
271
+ /** Indicates whether the conflict is binary. */
272
+ binary: boolean;
273
+ /** Indicates whether the conflict references Git LFS content. */
274
+ lfs_pointer: boolean;
275
+ }
276
+
277
+ /** Describes params for checking out one side of a conflict. */
278
+ export interface VcsCheckoutConflictSideParams extends VcsSessionParams {
279
+ /** Stores the side name, usually `ours` or `theirs`. */
280
+ side?: string;
281
+ /** Stores the conflicted file path. */
282
+ path: string;
283
+ }
284
+
285
+ /** Describes params for writing a merge result to disk. */
286
+ export interface VcsWriteMergeResultParams extends VcsSessionParams {
287
+ /** Stores the output file path. */
288
+ path: string;
289
+ /** Stores the file contents encoded as base64. */
290
+ content_b64: string;
291
+ }
292
+
293
+ /** Describes params for staging a text patch. */
294
+ export interface VcsStagePatchParams extends VcsSessionParams {
295
+ /** Stores the textual patch content. */
296
+ patch: string;
297
+ }
298
+
299
+ /** Describes params for discarding path changes. */
300
+ export interface VcsDiscardPathsParams extends VcsSessionParams {
301
+ /** Stores the paths to discard. */
302
+ paths?: string[];
303
+ }
304
+
305
+ /** Describes params for applying a reverse patch. */
306
+ export interface VcsApplyReversePatchParams extends VcsSessionParams {
307
+ /** Stores the textual patch content. */
308
+ patch: string;
309
+ }
310
+
311
+ /** Describes params for deleting a branch. */
312
+ export interface VcsDeleteBranchParams extends VcsSessionParams {
313
+ /** Stores the branch name to delete. */
314
+ name: string;
315
+ /** Indicates whether the delete should be forced. */
316
+ force?: boolean;
317
+ }
318
+
319
+ /** Describes params for renaming a branch. */
320
+ export interface VcsRenameBranchParams extends VcsSessionParams {
321
+ /** Stores the current branch name. */
322
+ old: string;
323
+ /** Stores the next branch name. */
324
+ new: string;
325
+ }
326
+
327
+ /** Describes params for merging another branch into the current branch. */
328
+ export interface VcsMergeIntoCurrentParams extends VcsSessionParams {
329
+ /** Stores the branch name to merge. */
330
+ name: string;
331
+ /** Stores an optional merge commit message. */
332
+ message?: string;
333
+ }
334
+
335
+ /** Describes params for setting a branch upstream. */
336
+ export interface VcsSetBranchUpstreamParams extends VcsSessionParams {
337
+ /** Stores the local branch name. */
338
+ branch: string;
339
+ /** Stores the upstream ref to track. */
340
+ upstream: string;
341
+ }
342
+
343
+ /** Describes params for getting a branch upstream. */
344
+ export interface VcsGetBranchUpstreamParams extends VcsSessionParams {
345
+ /** Stores the local branch name. */
346
+ branch: string;
347
+ }
348
+
349
+ /** Describes params for soft reset. */
350
+ export interface VcsResetSoftToParams extends VcsSessionParams {
351
+ /** Stores the revision to reset to. */
352
+ rev: string;
353
+ }
354
+
355
+ /** Describes one configured author identity. */
356
+ export interface VcsIdentity {
357
+ /** Stores the configured author name. */
358
+ name: string;
359
+ /** Stores the configured author email. */
360
+ email: string;
361
+ }
362
+
363
+ /** Describes params for configuring the local repository identity. */
364
+ export interface VcsSetIdentityLocalParams extends VcsSessionParams {
365
+ /** Stores the author name. */
366
+ name: string;
367
+ /** Stores the author email. */
368
+ email: string;
369
+ }
370
+
371
+ /** Describes one stash entry returned to the host. */
372
+ export interface StashEntry {
373
+ /** Stores the stash selector such as `stash@{0}`. */
374
+ selector: string;
375
+ /** Stores the stash message. */
376
+ msg: string;
377
+ /** Stores extra metadata reserved for future expansion. */
378
+ meta: string;
379
+ }
380
+
381
+ /** Describes params for stash push. */
382
+ export interface VcsStashPushParams extends VcsSessionParams {
383
+ /** Indicates whether untracked files should be included. */
384
+ include_untracked?: boolean;
385
+ /** Stores an optional stash message. */
386
+ message?: string;
387
+ }
388
+
389
+ /** Describes params for stash selection operations. */
390
+ export interface VcsStashSelectorParams extends VcsSessionParams {
391
+ /** Stores the stash selector, such as `stash@{0}`. */
392
+ selector: string;
393
+ }
394
+
395
+ /** Describes params for cherry-picking a commit. */
396
+ export interface VcsCherryPickParams extends VcsSessionParams {
397
+ /** Stores the commit to cherry-pick. */
398
+ commit: string;
399
+ }
400
+
401
+ /** Describes params for reverting a commit. */
402
+ export interface VcsRevertCommitParams extends VcsSessionParams {
403
+ /** Stores the commit to revert. */
404
+ commit: string;
405
+ /** Indicates whether the editor should be skipped. */
406
+ no_edit?: boolean;
407
+ }
408
+
409
+ /** Describes the delegate map supported by the SDK runtime for `vcs.*`. */
410
+ export interface VcsDelegates<TContext = unknown> {
411
+ /** Handles `vcs.get_caps`. */
412
+ 'vcs.get_caps'?: RpcMethodHandler<RequestParams, VcsCapabilities, TContext>;
413
+ /** Handles `vcs.open`. */
414
+ 'vcs.open'?: RpcMethodHandler<VcsOpenParams, VcsSessionResult, TContext>;
415
+ /** Handles `vcs.close`. */
416
+ 'vcs.close'?: RpcMethodHandler<VcsSessionParams, null, TContext>;
417
+ /** Handles `vcs.clone_repo`. */
418
+ 'vcs.clone_repo'?: RpcMethodHandler<VcsCloneRepoParams, null, TContext>;
419
+ /** Handles `vcs.get_workdir`. */
420
+ 'vcs.get_workdir'?: RpcMethodHandler<VcsSessionParams, string, TContext>;
421
+ /** Handles `vcs.get_current_branch`. */
422
+ 'vcs.get_current_branch'?: RpcMethodHandler<
423
+ VcsSessionParams,
424
+ string | null,
425
+ TContext
426
+ >;
427
+ /** Handles `vcs.list_branches`. */
428
+ 'vcs.list_branches'?: RpcMethodHandler<
429
+ VcsSessionParams,
430
+ VcsBranchEntry[],
431
+ TContext
432
+ >;
433
+ /** Handles `vcs.list_local_branches`. */
434
+ 'vcs.list_local_branches'?: RpcMethodHandler<
435
+ VcsSessionParams,
436
+ string[],
437
+ TContext
438
+ >;
439
+ /** Handles `vcs.create_branch`. */
440
+ 'vcs.create_branch'?: RpcMethodHandler<VcsCreateBranchParams, null, TContext>;
441
+ /** Handles `vcs.checkout_branch`. */
442
+ 'vcs.checkout_branch'?: RpcMethodHandler<VcsCheckoutBranchParams, null, TContext>;
443
+ /** Handles `vcs.ensure_remote`. */
444
+ 'vcs.ensure_remote'?: RpcMethodHandler<VcsEnsureRemoteParams, null, TContext>;
445
+ /** Handles `vcs.list_remotes`. */
446
+ 'vcs.list_remotes'?: RpcMethodHandler<
447
+ VcsSessionParams,
448
+ VcsRemoteEntry[],
449
+ TContext
450
+ >;
451
+ /** Handles `vcs.remove_remote`. */
452
+ 'vcs.remove_remote'?: RpcMethodHandler<VcsRemoveRemoteParams, null, TContext>;
453
+ /** Handles `vcs.fetch`. */
454
+ 'vcs.fetch'?: RpcMethodHandler<VcsFetchParams, null, TContext>;
455
+ /** Handles `vcs.fetch_with_options`. */
456
+ 'vcs.fetch_with_options'?: RpcMethodHandler<VcsFetchParams, null, TContext>;
457
+ /** Handles `vcs.push`. */
458
+ 'vcs.push'?: RpcMethodHandler<VcsPushParams, null, TContext>;
459
+ /** Handles `vcs.pull_ff_only`. */
460
+ 'vcs.pull_ff_only'?: RpcMethodHandler<VcsPullFfOnlyParams, null, TContext>;
461
+ /** Handles `vcs.commit`. */
462
+ 'vcs.commit'?: RpcMethodHandler<VcsCommitParams, string, TContext>;
463
+ /** Handles `vcs.commit_index`. */
464
+ 'vcs.commit_index'?: RpcMethodHandler<VcsCommitParams, string, TContext>;
465
+ /** Handles `vcs.get_status_summary`. */
466
+ 'vcs.get_status_summary'?: RpcMethodHandler<
467
+ VcsSessionParams,
468
+ StatusSummary,
469
+ TContext
470
+ >;
471
+ /** Handles `vcs.get_status_payload`. */
472
+ 'vcs.get_status_payload'?: RpcMethodHandler<
473
+ VcsSessionParams,
474
+ StatusPayload,
475
+ TContext
476
+ >;
477
+ /** Handles `vcs.list_commits`. */
478
+ 'vcs.list_commits'?: RpcMethodHandler<
479
+ VcsListCommitsParams,
480
+ CommitEntry[],
481
+ TContext
482
+ >;
483
+ /** Handles `vcs.diff_file`. */
484
+ 'vcs.diff_file'?: RpcMethodHandler<VcsDiffFileParams, string[], TContext>;
485
+ /** Handles `vcs.diff_commit`. */
486
+ 'vcs.diff_commit'?: RpcMethodHandler<VcsDiffCommitParams, string[], TContext>;
487
+ /** Handles `vcs.get_conflict_details`. */
488
+ 'vcs.get_conflict_details'?: RpcMethodHandler<
489
+ VcsGetConflictDetailsParams,
490
+ VcsConflictDetails,
491
+ TContext
492
+ >;
493
+ /** Handles `vcs.checkout_conflict_side`. */
494
+ 'vcs.checkout_conflict_side'?: RpcMethodHandler<
495
+ VcsCheckoutConflictSideParams,
496
+ null,
497
+ TContext
498
+ >;
499
+ /** Handles `vcs.write_merge_result`. */
500
+ 'vcs.write_merge_result'?: RpcMethodHandler<
501
+ VcsWriteMergeResultParams,
502
+ null,
503
+ TContext
504
+ >;
505
+ /** Handles `vcs.stage_patch`. */
506
+ 'vcs.stage_patch'?: RpcMethodHandler<VcsStagePatchParams, null, TContext>;
507
+ /** Handles `vcs.discard_paths`. */
508
+ 'vcs.discard_paths'?: RpcMethodHandler<VcsDiscardPathsParams, null, TContext>;
509
+ /** Handles `vcs.apply_reverse_patch`. */
510
+ 'vcs.apply_reverse_patch'?: RpcMethodHandler<
511
+ VcsApplyReversePatchParams,
512
+ null,
513
+ TContext
514
+ >;
515
+ /** Handles `vcs.delete_branch`. */
516
+ 'vcs.delete_branch'?: RpcMethodHandler<VcsDeleteBranchParams, null, TContext>;
517
+ /** Handles `vcs.rename_branch`. */
518
+ 'vcs.rename_branch'?: RpcMethodHandler<VcsRenameBranchParams, null, TContext>;
519
+ /** Handles `vcs.merge_into_current`. */
520
+ 'vcs.merge_into_current'?: RpcMethodHandler<
521
+ VcsMergeIntoCurrentParams,
522
+ null,
523
+ TContext
524
+ >;
525
+ /** Handles `vcs.merge_abort`. */
526
+ 'vcs.merge_abort'?: RpcMethodHandler<VcsSessionParams, null, TContext>;
527
+ /** Handles `vcs.merge_continue`. */
528
+ 'vcs.merge_continue'?: RpcMethodHandler<VcsSessionParams, null, TContext>;
529
+ /** Handles `vcs.is_merge_in_progress`. */
530
+ 'vcs.is_merge_in_progress'?: RpcMethodHandler<
531
+ VcsSessionParams,
532
+ boolean,
533
+ TContext
534
+ >;
535
+ /** Handles `vcs.set_branch_upstream`. */
536
+ 'vcs.set_branch_upstream'?: RpcMethodHandler<
537
+ VcsSetBranchUpstreamParams,
538
+ null,
539
+ TContext
540
+ >;
541
+ /** Handles `vcs.get_branch_upstream`. */
542
+ 'vcs.get_branch_upstream'?: RpcMethodHandler<
543
+ VcsGetBranchUpstreamParams,
544
+ string | null,
545
+ TContext
546
+ >;
547
+ /** Handles `vcs.hard_reset_head`. */
548
+ 'vcs.hard_reset_head'?: RpcMethodHandler<VcsSessionParams, null, TContext>;
549
+ /** Handles `vcs.reset_soft_to`. */
550
+ 'vcs.reset_soft_to'?: RpcMethodHandler<VcsResetSoftToParams, null, TContext>;
551
+ /** Handles `vcs.get_identity`. */
552
+ 'vcs.get_identity'?: RpcMethodHandler<
553
+ VcsSessionParams,
554
+ VcsIdentity | null,
555
+ TContext
556
+ >;
557
+ /** Handles `vcs.set_identity_local`. */
558
+ 'vcs.set_identity_local'?: RpcMethodHandler<
559
+ VcsSetIdentityLocalParams,
560
+ null,
561
+ TContext
562
+ >;
563
+ /** Handles `vcs.list_stashes`. */
564
+ 'vcs.list_stashes'?: RpcMethodHandler<VcsSessionParams, StashEntry[], TContext>;
565
+ /** Handles `vcs.stash_push`. */
566
+ 'vcs.stash_push'?: RpcMethodHandler<VcsStashPushParams, string, TContext>;
567
+ /** Handles `vcs.stash_apply`. */
568
+ 'vcs.stash_apply'?: RpcMethodHandler<VcsStashSelectorParams, null, TContext>;
569
+ /** Handles `vcs.stash_pop`. */
570
+ 'vcs.stash_pop'?: RpcMethodHandler<VcsStashSelectorParams, null, TContext>;
571
+ /** Handles `vcs.stash_drop`. */
572
+ 'vcs.stash_drop'?: RpcMethodHandler<VcsStashSelectorParams, null, TContext>;
573
+ /** Handles `vcs.stash_show`. */
574
+ 'vcs.stash_show'?: RpcMethodHandler<VcsStashSelectorParams, string, TContext>;
575
+ /** Handles `vcs.cherry_pick`. */
576
+ 'vcs.cherry_pick'?: RpcMethodHandler<VcsCherryPickParams, null, TContext>;
577
+ /** Handles `vcs.revert_commit`. */
578
+ 'vcs.revert_commit'?: RpcMethodHandler<VcsRevertCommitParams, null, TContext>;
579
+ }
@@ -0,0 +1,95 @@
1
+ const assert = require("node:assert/strict");
2
+ const fs = require("node:fs");
3
+ const path = require("node:path");
4
+ const test = require("node:test");
5
+
6
+ const { buildPluginAssets, parseBuildArgs, readManifest, validateDeclaredModuleExec } = require("../lib/build");
7
+ const { cleanupTempDir, makeTempDir, writeJson, writeText } = require("./helpers");
8
+
9
+ test("parseBuildArgs uses defaults", () => {
10
+ const parsed = parseBuildArgs([]);
11
+ assert.equal(parsed.pluginDir, process.cwd());
12
+ assert.equal(parsed.verbose, false);
13
+ });
14
+
15
+ test("parseBuildArgs parses known flags", () => {
16
+ const parsed = parseBuildArgs(["--plugin-dir", "some/plugin", "--verbose"]);
17
+ assert.equal(parsed.pluginDir, path.resolve("some/plugin"));
18
+ assert.equal(parsed.verbose, true);
19
+ });
20
+
21
+ test("parseBuildArgs help returns usage error", () => {
22
+ assert.throws(() => parseBuildArgs(["--help"]), /openvcs build \[args\]/);
23
+ });
24
+
25
+ test("buildPluginAssets no-ops for theme-only plugins", () => {
26
+ const root = makeTempDir("openvcs-sdk-test");
27
+ const pluginDir = path.join(root, "plugin");
28
+
29
+ writeJson(path.join(pluginDir, "openvcs.plugin.json"), { id: "theme-only" });
30
+ const manifest = buildPluginAssets({ pluginDir, verbose: false });
31
+
32
+ assert.equal(manifest.pluginId, "theme-only");
33
+ cleanupTempDir(root);
34
+ });
35
+
36
+ test("buildPluginAssets requires package.json for code plugins", () => {
37
+ const root = makeTempDir("openvcs-sdk-test");
38
+ const pluginDir = path.join(root, "plugin");
39
+
40
+ writeJson(path.join(pluginDir, "openvcs.plugin.json"), {
41
+ id: "missing-package",
42
+ module: { exec: "plugin.js" },
43
+ });
44
+
45
+ assert.throws(
46
+ () => buildPluginAssets({ pluginDir, verbose: false }),
47
+ /code plugins must include package\.json/
48
+ );
49
+
50
+ cleanupTempDir(root);
51
+ });
52
+
53
+ test("buildPluginAssets runs build:plugin and validates output", () => {
54
+ const root = makeTempDir("openvcs-sdk-test");
55
+ const pluginDir = path.join(root, "plugin");
56
+
57
+ writeJson(path.join(pluginDir, "openvcs.plugin.json"), {
58
+ id: "builder",
59
+ module: { exec: "plugin.js" },
60
+ });
61
+ writeJson(path.join(pluginDir, "package.json"), {
62
+ name: "builder",
63
+ private: true,
64
+ scripts: {
65
+ "build:plugin": "node ./scripts/build-plugin.js",
66
+ },
67
+ });
68
+ writeText(
69
+ path.join(pluginDir, "scripts", "build-plugin.js"),
70
+ "const fs = require('node:fs');\nconst path = require('node:path');\nconst out = path.join(process.cwd(), 'bin', 'plugin.js');\nfs.mkdirSync(path.dirname(out), { recursive: true });\nfs.writeFileSync(out, 'export {};\\n', 'utf8');\n"
71
+ );
72
+
73
+ const manifest = buildPluginAssets({ pluginDir, verbose: false });
74
+
75
+ assert.equal(manifest.pluginId, "builder");
76
+ assert.equal(fs.existsSync(path.join(pluginDir, "bin", "plugin.js")), true);
77
+ cleanupTempDir(root);
78
+ });
79
+
80
+ test("readManifest and validateDeclaredModuleExec stay reusable", () => {
81
+ const root = makeTempDir("openvcs-sdk-test");
82
+ const pluginDir = path.join(root, "plugin");
83
+
84
+ writeJson(path.join(pluginDir, "openvcs.plugin.json"), {
85
+ id: "reusable",
86
+ module: { exec: "plugin.js" },
87
+ });
88
+ writeText(path.join(pluginDir, "bin", "plugin.js"), "export {};\n");
89
+
90
+ const manifest = readManifest(pluginDir);
91
+ assert.equal(manifest.moduleExec, "plugin.js");
92
+ assert.doesNotThrow(() => validateDeclaredModuleExec(pluginDir, manifest.moduleExec));
93
+
94
+ cleanupTempDir(root);
95
+ });