@openvcs/sdk 0.2.4 → 0.2.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/README.md +68 -9
- package/lib/build.d.ts +8 -0
- package/lib/build.js +81 -2
- package/lib/dist.js +1 -0
- package/lib/init.js +2 -2
- package/lib/runtime/factory.d.ts +3 -0
- package/lib/runtime/factory.js +153 -0
- package/lib/runtime/index.d.ts +7 -4
- package/lib/runtime/index.js +13 -154
- package/lib/runtime/registration.d.ts +39 -0
- package/lib/runtime/registration.js +37 -0
- package/lib/runtime/vcs-delegate-base.d.ts +125 -0
- package/lib/runtime/vcs-delegate-base.js +249 -0
- package/lib/runtime/vcs-delegate-metadata.d.ts +120 -0
- package/lib/runtime/vcs-delegate-metadata.js +58 -0
- package/package.json +3 -2
- package/src/lib/build.ts +104 -2
- package/src/lib/dist.ts +2 -0
- package/src/lib/init.ts +2 -2
- package/src/lib/runtime/factory.ts +182 -0
- package/src/lib/runtime/index.ts +14 -177
- package/src/lib/runtime/registration.ts +93 -0
- package/src/lib/runtime/vcs-delegate-base.ts +481 -0
- package/src/lib/runtime/vcs-delegate-metadata.ts +165 -0
- package/test/build.test.js +147 -6
- package/test/cli.test.js +5 -3
- package/test/dist.test.js +27 -18
- package/test/init.test.js +6 -2
- package/test/runtime.test.js +118 -1
- package/test/tsconfig.json +8 -0
- package/test/vcs-delegate-base.test.js +169 -0
- package/test/vcs-delegate-base.types.ts +44 -0
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
// Copyright © 2025-2026 OpenVCS Contributors
|
|
2
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
3
|
+
|
|
4
|
+
import type * as VcsTypes from '../types';
|
|
5
|
+
|
|
6
|
+
import type { PluginRuntimeContext } from './contracts';
|
|
7
|
+
import {
|
|
8
|
+
type VcsDelegateAssignments,
|
|
9
|
+
type VcsDelegateBindings,
|
|
10
|
+
type VcsDelegateMethodName,
|
|
11
|
+
type VcsDelegatePrototype,
|
|
12
|
+
type VcsDelegateRpcMethodName,
|
|
13
|
+
VCS_DELEGATE_METHOD_MAPPINGS,
|
|
14
|
+
} from './vcs-delegate-metadata';
|
|
15
|
+
|
|
16
|
+
/** Describes one synchronous or asynchronous VCS delegate return value. */
|
|
17
|
+
type VcsHandlerResult<TResult> = TResult | Promise<TResult>;
|
|
18
|
+
|
|
19
|
+
/** Builds exact `vcs.*` delegates from ordinary class methods. */
|
|
20
|
+
export abstract class VcsDelegateBase<
|
|
21
|
+
TDeps,
|
|
22
|
+
TContext = PluginRuntimeContext,
|
|
23
|
+
> {
|
|
24
|
+
/** Stores the runtime services exposed to the delegate implementation. */
|
|
25
|
+
protected readonly deps: TDeps;
|
|
26
|
+
|
|
27
|
+
/** Creates one delegate base with the provided runtime dependencies. */
|
|
28
|
+
constructor(deps: TDeps) {
|
|
29
|
+
this.deps = deps;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Builds an SDK `vcs.*` delegate map from the subclass overrides. */
|
|
33
|
+
toDelegates(): VcsDelegateAssignments<TContext> {
|
|
34
|
+
const delegates: VcsDelegateAssignments<TContext> = {};
|
|
35
|
+
const delegatePrototype = Object.getPrototypeOf(this) as VcsDelegatePrototype<TContext> | null;
|
|
36
|
+
const basePrototype = VcsDelegateBase.prototype as VcsDelegatePrototype<TContext>;
|
|
37
|
+
|
|
38
|
+
for (const delegateMethod of Object.keys(
|
|
39
|
+
VCS_DELEGATE_METHOD_MAPPINGS,
|
|
40
|
+
) as VcsDelegateMethodName[]) {
|
|
41
|
+
const handler = delegatePrototype?.[delegateMethod];
|
|
42
|
+
if (typeof handler !== 'function' || handler === basePrototype[delegateMethod]) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
this.assignDelegate(delegates, delegateMethod, handler);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return delegates;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Assigns one typed class method to its exact `vcs.*` delegate name. */
|
|
53
|
+
private assignDelegate<TMethodName extends VcsDelegateMethodName>(
|
|
54
|
+
delegates: VcsDelegateAssignments<TContext>,
|
|
55
|
+
delegateMethod: TMethodName,
|
|
56
|
+
handler: VcsDelegateBindings<TContext>[TMethodName],
|
|
57
|
+
): void {
|
|
58
|
+
const rpcMethod = VCS_DELEGATE_METHOD_MAPPINGS[
|
|
59
|
+
delegateMethod
|
|
60
|
+
] as VcsDelegateRpcMethodName<TMethodName>;
|
|
61
|
+
// `bind` loses the method-specific key correlation here; the cast is
|
|
62
|
+
// safe because `assignDelegate` is only called with handlers that were
|
|
63
|
+
// verified against `VcsDelegateBindings<TContext>` in the loop above.
|
|
64
|
+
const boundHandler = handler.bind(this) as VcsDelegateAssignments<TContext>[typeof rpcMethod];
|
|
65
|
+
|
|
66
|
+
delegates[rpcMethod] = boundHandler;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Throws when a subclass does not implement one required delegate method.
|
|
71
|
+
*
|
|
72
|
+
* The `never` return type is intentional: base stubs should never contribute
|
|
73
|
+
* a usable value, and subclasses should override the method with the exact
|
|
74
|
+
* signature inherited from `VcsDelegateBase`.
|
|
75
|
+
*/
|
|
76
|
+
protected unimplemented(methodName: VcsDelegateMethodName): never {
|
|
77
|
+
throw new Error(
|
|
78
|
+
`VCS delegate method '${methodName}' must be overridden before registration`,
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Handles `vcs.get_caps`. */
|
|
83
|
+
getCaps(
|
|
84
|
+
_params: VcsTypes.RequestParams,
|
|
85
|
+
_context: TContext,
|
|
86
|
+
): VcsHandlerResult<VcsTypes.VcsCapabilities> {
|
|
87
|
+
return this.unimplemented('getCaps');
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Handles `vcs.open`. */
|
|
91
|
+
open(
|
|
92
|
+
_params: VcsTypes.VcsOpenParams,
|
|
93
|
+
_context: TContext,
|
|
94
|
+
): VcsHandlerResult<VcsTypes.VcsSessionResult> {
|
|
95
|
+
return this.unimplemented('open');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** Handles `vcs.close`. */
|
|
99
|
+
close(
|
|
100
|
+
_params: VcsTypes.VcsSessionParams,
|
|
101
|
+
_context: TContext,
|
|
102
|
+
): VcsHandlerResult<null> {
|
|
103
|
+
return this.unimplemented('close');
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Handles `vcs.clone_repo`. */
|
|
107
|
+
cloneRepo(
|
|
108
|
+
_params: VcsTypes.VcsCloneRepoParams,
|
|
109
|
+
_context: TContext,
|
|
110
|
+
): VcsHandlerResult<null> {
|
|
111
|
+
return this.unimplemented('cloneRepo');
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** Handles `vcs.get_workdir`. */
|
|
115
|
+
getWorkdir(
|
|
116
|
+
_params: VcsTypes.VcsSessionParams,
|
|
117
|
+
_context: TContext,
|
|
118
|
+
): VcsHandlerResult<string> {
|
|
119
|
+
return this.unimplemented('getWorkdir');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** Handles `vcs.get_current_branch`. */
|
|
123
|
+
getCurrentBranch(
|
|
124
|
+
_params: VcsTypes.VcsSessionParams,
|
|
125
|
+
_context: TContext,
|
|
126
|
+
): VcsHandlerResult<string | null> {
|
|
127
|
+
return this.unimplemented('getCurrentBranch');
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** Handles `vcs.list_branches`. */
|
|
131
|
+
listBranches(
|
|
132
|
+
_params: VcsTypes.VcsSessionParams,
|
|
133
|
+
_context: TContext,
|
|
134
|
+
): VcsHandlerResult<VcsTypes.VcsBranchEntry[]> {
|
|
135
|
+
return this.unimplemented('listBranches');
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** Handles `vcs.list_local_branches`. */
|
|
139
|
+
listLocalBranches(
|
|
140
|
+
_params: VcsTypes.VcsSessionParams,
|
|
141
|
+
_context: TContext,
|
|
142
|
+
): VcsHandlerResult<string[]> {
|
|
143
|
+
return this.unimplemented('listLocalBranches');
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/** Handles `vcs.create_branch`. */
|
|
147
|
+
createBranch(
|
|
148
|
+
_params: VcsTypes.VcsCreateBranchParams,
|
|
149
|
+
_context: TContext,
|
|
150
|
+
): VcsHandlerResult<null> {
|
|
151
|
+
return this.unimplemented('createBranch');
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/** Handles `vcs.checkout_branch`. */
|
|
155
|
+
checkoutBranch(
|
|
156
|
+
_params: VcsTypes.VcsCheckoutBranchParams,
|
|
157
|
+
_context: TContext,
|
|
158
|
+
): VcsHandlerResult<null> {
|
|
159
|
+
return this.unimplemented('checkoutBranch');
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/** Handles `vcs.ensure_remote`. */
|
|
163
|
+
ensureRemote(
|
|
164
|
+
_params: VcsTypes.VcsEnsureRemoteParams,
|
|
165
|
+
_context: TContext,
|
|
166
|
+
): VcsHandlerResult<null> {
|
|
167
|
+
return this.unimplemented('ensureRemote');
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** Handles `vcs.list_remotes`. */
|
|
171
|
+
listRemotes(
|
|
172
|
+
_params: VcsTypes.VcsSessionParams,
|
|
173
|
+
_context: TContext,
|
|
174
|
+
): VcsHandlerResult<VcsTypes.VcsRemoteEntry[]> {
|
|
175
|
+
return this.unimplemented('listRemotes');
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** Handles `vcs.remove_remote`. */
|
|
179
|
+
removeRemote(
|
|
180
|
+
_params: VcsTypes.VcsRemoveRemoteParams,
|
|
181
|
+
_context: TContext,
|
|
182
|
+
): VcsHandlerResult<null> {
|
|
183
|
+
return this.unimplemented('removeRemote');
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/** Handles `vcs.fetch`. */
|
|
187
|
+
fetch(
|
|
188
|
+
_params: VcsTypes.VcsFetchParams,
|
|
189
|
+
_context: TContext,
|
|
190
|
+
): VcsHandlerResult<null> {
|
|
191
|
+
return this.unimplemented('fetch');
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/** Handles `vcs.fetch_with_options`. */
|
|
195
|
+
fetchWithOptions(
|
|
196
|
+
_params: VcsTypes.VcsFetchParams,
|
|
197
|
+
_context: TContext,
|
|
198
|
+
): VcsHandlerResult<null> {
|
|
199
|
+
return this.unimplemented('fetchWithOptions');
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/** Handles `vcs.push`. */
|
|
203
|
+
push(
|
|
204
|
+
_params: VcsTypes.VcsPushParams,
|
|
205
|
+
_context: TContext,
|
|
206
|
+
): VcsHandlerResult<null> {
|
|
207
|
+
return this.unimplemented('push');
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/** Handles `vcs.pull_ff_only`. */
|
|
211
|
+
pullFfOnly(
|
|
212
|
+
_params: VcsTypes.VcsPullFfOnlyParams,
|
|
213
|
+
_context: TContext,
|
|
214
|
+
): VcsHandlerResult<null> {
|
|
215
|
+
return this.unimplemented('pullFfOnly');
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/** Handles `vcs.commit`. */
|
|
219
|
+
commit(
|
|
220
|
+
_params: VcsTypes.VcsCommitParams,
|
|
221
|
+
_context: TContext,
|
|
222
|
+
): VcsHandlerResult<string> {
|
|
223
|
+
return this.unimplemented('commit');
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/** Handles `vcs.commit_index`. */
|
|
227
|
+
commitIndex(
|
|
228
|
+
_params: VcsTypes.VcsCommitParams,
|
|
229
|
+
_context: TContext,
|
|
230
|
+
): VcsHandlerResult<string> {
|
|
231
|
+
return this.unimplemented('commitIndex');
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/** Handles `vcs.get_status_summary`. */
|
|
235
|
+
getStatusSummary(
|
|
236
|
+
_params: VcsTypes.VcsSessionParams,
|
|
237
|
+
_context: TContext,
|
|
238
|
+
): VcsHandlerResult<VcsTypes.StatusSummary> {
|
|
239
|
+
return this.unimplemented('getStatusSummary');
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/** Handles `vcs.get_status_payload`. */
|
|
243
|
+
getStatusPayload(
|
|
244
|
+
_params: VcsTypes.VcsSessionParams,
|
|
245
|
+
_context: TContext,
|
|
246
|
+
): VcsHandlerResult<VcsTypes.StatusPayload> {
|
|
247
|
+
return this.unimplemented('getStatusPayload');
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/** Handles `vcs.list_commits`. */
|
|
251
|
+
listCommits(
|
|
252
|
+
_params: VcsTypes.VcsListCommitsParams,
|
|
253
|
+
_context: TContext,
|
|
254
|
+
): VcsHandlerResult<VcsTypes.CommitEntry[]> {
|
|
255
|
+
return this.unimplemented('listCommits');
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/** Handles `vcs.diff_file`. */
|
|
259
|
+
diffFile(
|
|
260
|
+
_params: VcsTypes.VcsDiffFileParams,
|
|
261
|
+
_context: TContext,
|
|
262
|
+
): VcsHandlerResult<string[]> {
|
|
263
|
+
return this.unimplemented('diffFile');
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/** Handles `vcs.diff_commit`. */
|
|
267
|
+
diffCommit(
|
|
268
|
+
_params: VcsTypes.VcsDiffCommitParams,
|
|
269
|
+
_context: TContext,
|
|
270
|
+
): VcsHandlerResult<string[]> {
|
|
271
|
+
return this.unimplemented('diffCommit');
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/** Handles `vcs.get_conflict_details`. */
|
|
275
|
+
getConflictDetails(
|
|
276
|
+
_params: VcsTypes.VcsGetConflictDetailsParams,
|
|
277
|
+
_context: TContext,
|
|
278
|
+
): VcsHandlerResult<VcsTypes.VcsConflictDetails> {
|
|
279
|
+
return this.unimplemented('getConflictDetails');
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/** Handles `vcs.checkout_conflict_side`. */
|
|
283
|
+
checkoutConflictSide(
|
|
284
|
+
_params: VcsTypes.VcsCheckoutConflictSideParams,
|
|
285
|
+
_context: TContext,
|
|
286
|
+
): VcsHandlerResult<null> {
|
|
287
|
+
return this.unimplemented('checkoutConflictSide');
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/** Handles `vcs.write_merge_result`. */
|
|
291
|
+
writeMergeResult(
|
|
292
|
+
_params: VcsTypes.VcsWriteMergeResultParams,
|
|
293
|
+
_context: TContext,
|
|
294
|
+
): VcsHandlerResult<null> {
|
|
295
|
+
return this.unimplemented('writeMergeResult');
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/** Handles `vcs.stage_patch`. */
|
|
299
|
+
stagePatch(
|
|
300
|
+
_params: VcsTypes.VcsStagePatchParams,
|
|
301
|
+
_context: TContext,
|
|
302
|
+
): VcsHandlerResult<null> {
|
|
303
|
+
return this.unimplemented('stagePatch');
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/** Handles `vcs.discard_paths`. */
|
|
307
|
+
discardPaths(
|
|
308
|
+
_params: VcsTypes.VcsDiscardPathsParams,
|
|
309
|
+
_context: TContext,
|
|
310
|
+
): VcsHandlerResult<null> {
|
|
311
|
+
return this.unimplemented('discardPaths');
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/** Handles `vcs.apply_reverse_patch`. */
|
|
315
|
+
applyReversePatch(
|
|
316
|
+
_params: VcsTypes.VcsApplyReversePatchParams,
|
|
317
|
+
_context: TContext,
|
|
318
|
+
): VcsHandlerResult<null> {
|
|
319
|
+
return this.unimplemented('applyReversePatch');
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/** Handles `vcs.delete_branch`. */
|
|
323
|
+
deleteBranch(
|
|
324
|
+
_params: VcsTypes.VcsDeleteBranchParams,
|
|
325
|
+
_context: TContext,
|
|
326
|
+
): VcsHandlerResult<null> {
|
|
327
|
+
return this.unimplemented('deleteBranch');
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/** Handles `vcs.rename_branch`. */
|
|
331
|
+
renameBranch(
|
|
332
|
+
_params: VcsTypes.VcsRenameBranchParams,
|
|
333
|
+
_context: TContext,
|
|
334
|
+
): VcsHandlerResult<null> {
|
|
335
|
+
return this.unimplemented('renameBranch');
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/** Handles `vcs.merge_into_current`. */
|
|
339
|
+
mergeIntoCurrent(
|
|
340
|
+
_params: VcsTypes.VcsMergeIntoCurrentParams,
|
|
341
|
+
_context: TContext,
|
|
342
|
+
): VcsHandlerResult<null> {
|
|
343
|
+
return this.unimplemented('mergeIntoCurrent');
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/** Handles `vcs.merge_abort`. */
|
|
347
|
+
mergeAbort(
|
|
348
|
+
_params: VcsTypes.VcsSessionParams,
|
|
349
|
+
_context: TContext,
|
|
350
|
+
): VcsHandlerResult<null> {
|
|
351
|
+
return this.unimplemented('mergeAbort');
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/** Handles `vcs.merge_continue`. */
|
|
355
|
+
mergeContinue(
|
|
356
|
+
_params: VcsTypes.VcsSessionParams,
|
|
357
|
+
_context: TContext,
|
|
358
|
+
): VcsHandlerResult<null> {
|
|
359
|
+
return this.unimplemented('mergeContinue');
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/** Handles `vcs.is_merge_in_progress`. */
|
|
363
|
+
isMergeInProgress(
|
|
364
|
+
_params: VcsTypes.VcsSessionParams,
|
|
365
|
+
_context: TContext,
|
|
366
|
+
): VcsHandlerResult<boolean> {
|
|
367
|
+
return this.unimplemented('isMergeInProgress');
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/** Handles `vcs.set_branch_upstream`. */
|
|
371
|
+
setBranchUpstream(
|
|
372
|
+
_params: VcsTypes.VcsSetBranchUpstreamParams,
|
|
373
|
+
_context: TContext,
|
|
374
|
+
): VcsHandlerResult<null> {
|
|
375
|
+
return this.unimplemented('setBranchUpstream');
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/** Handles `vcs.get_branch_upstream`. */
|
|
379
|
+
getBranchUpstream(
|
|
380
|
+
_params: VcsTypes.VcsGetBranchUpstreamParams,
|
|
381
|
+
_context: TContext,
|
|
382
|
+
): VcsHandlerResult<string | null> {
|
|
383
|
+
return this.unimplemented('getBranchUpstream');
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/** Handles `vcs.hard_reset_head`. */
|
|
387
|
+
hardResetHead(
|
|
388
|
+
_params: VcsTypes.VcsSessionParams,
|
|
389
|
+
_context: TContext,
|
|
390
|
+
): VcsHandlerResult<null> {
|
|
391
|
+
return this.unimplemented('hardResetHead');
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/** Handles `vcs.reset_soft_to`. */
|
|
395
|
+
resetSoftTo(
|
|
396
|
+
_params: VcsTypes.VcsResetSoftToParams,
|
|
397
|
+
_context: TContext,
|
|
398
|
+
): VcsHandlerResult<null> {
|
|
399
|
+
return this.unimplemented('resetSoftTo');
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/** Handles `vcs.get_identity`. */
|
|
403
|
+
getIdentity(
|
|
404
|
+
_params: VcsTypes.VcsSessionParams,
|
|
405
|
+
_context: TContext,
|
|
406
|
+
): VcsHandlerResult<VcsTypes.VcsIdentity | null> {
|
|
407
|
+
return this.unimplemented('getIdentity');
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/** Handles `vcs.set_identity_local`. */
|
|
411
|
+
setIdentityLocal(
|
|
412
|
+
_params: VcsTypes.VcsSetIdentityLocalParams,
|
|
413
|
+
_context: TContext,
|
|
414
|
+
): VcsHandlerResult<null> {
|
|
415
|
+
return this.unimplemented('setIdentityLocal');
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/** Handles `vcs.list_stashes`. */
|
|
419
|
+
listStashes(
|
|
420
|
+
_params: VcsTypes.VcsSessionParams,
|
|
421
|
+
_context: TContext,
|
|
422
|
+
): VcsHandlerResult<VcsTypes.StashEntry[]> {
|
|
423
|
+
return this.unimplemented('listStashes');
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/** Handles `vcs.stash_push`. */
|
|
427
|
+
stashPush(
|
|
428
|
+
_params: VcsTypes.VcsStashPushParams,
|
|
429
|
+
_context: TContext,
|
|
430
|
+
): VcsHandlerResult<string> {
|
|
431
|
+
return this.unimplemented('stashPush');
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/** Handles `vcs.stash_apply`. */
|
|
435
|
+
stashApply(
|
|
436
|
+
_params: VcsTypes.VcsStashSelectorParams,
|
|
437
|
+
_context: TContext,
|
|
438
|
+
): VcsHandlerResult<null> {
|
|
439
|
+
return this.unimplemented('stashApply');
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/** Handles `vcs.stash_pop`. */
|
|
443
|
+
stashPop(
|
|
444
|
+
_params: VcsTypes.VcsStashSelectorParams,
|
|
445
|
+
_context: TContext,
|
|
446
|
+
): VcsHandlerResult<null> {
|
|
447
|
+
return this.unimplemented('stashPop');
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/** Handles `vcs.stash_drop`. */
|
|
451
|
+
stashDrop(
|
|
452
|
+
_params: VcsTypes.VcsStashSelectorParams,
|
|
453
|
+
_context: TContext,
|
|
454
|
+
): VcsHandlerResult<null> {
|
|
455
|
+
return this.unimplemented('stashDrop');
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/** Handles `vcs.stash_show`. */
|
|
459
|
+
stashShow(
|
|
460
|
+
_params: VcsTypes.VcsStashSelectorParams,
|
|
461
|
+
_context: TContext,
|
|
462
|
+
): VcsHandlerResult<string> {
|
|
463
|
+
return this.unimplemented('stashShow');
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/** Handles `vcs.cherry_pick`. */
|
|
467
|
+
cherryPick(
|
|
468
|
+
_params: VcsTypes.VcsCherryPickParams,
|
|
469
|
+
_context: TContext,
|
|
470
|
+
): VcsHandlerResult<null> {
|
|
471
|
+
return this.unimplemented('cherryPick');
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
/** Handles `vcs.revert_commit`. */
|
|
475
|
+
revertCommit(
|
|
476
|
+
_params: VcsTypes.VcsRevertCommitParams,
|
|
477
|
+
_context: TContext,
|
|
478
|
+
): VcsHandlerResult<null> {
|
|
479
|
+
return this.unimplemented('revertCommit');
|
|
480
|
+
}
|
|
481
|
+
}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
// Copyright © 2025-2026 OpenVCS Contributors
|
|
2
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
3
|
+
|
|
4
|
+
import type * as VcsTypes from '../types';
|
|
5
|
+
|
|
6
|
+
import type { PluginRuntimeContext } from './contracts';
|
|
7
|
+
|
|
8
|
+
/** Stores the typed class-method signatures supported by `VcsDelegateBase`. */
|
|
9
|
+
export type VcsDelegateBindings<TContext> = {
|
|
10
|
+
getCaps: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.get_caps']>;
|
|
11
|
+
open: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.open']>;
|
|
12
|
+
close: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.close']>;
|
|
13
|
+
cloneRepo: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.clone_repo']>;
|
|
14
|
+
getWorkdir: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.get_workdir']>;
|
|
15
|
+
getCurrentBranch: NonNullable<
|
|
16
|
+
VcsTypes.VcsDelegates<TContext>['vcs.get_current_branch']
|
|
17
|
+
>;
|
|
18
|
+
listBranches: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.list_branches']>;
|
|
19
|
+
listLocalBranches: NonNullable<
|
|
20
|
+
VcsTypes.VcsDelegates<TContext>['vcs.list_local_branches']
|
|
21
|
+
>;
|
|
22
|
+
createBranch: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.create_branch']>;
|
|
23
|
+
checkoutBranch: NonNullable<
|
|
24
|
+
VcsTypes.VcsDelegates<TContext>['vcs.checkout_branch']
|
|
25
|
+
>;
|
|
26
|
+
ensureRemote: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.ensure_remote']>;
|
|
27
|
+
listRemotes: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.list_remotes']>;
|
|
28
|
+
removeRemote: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.remove_remote']>;
|
|
29
|
+
fetch: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.fetch']>;
|
|
30
|
+
fetchWithOptions: NonNullable<
|
|
31
|
+
VcsTypes.VcsDelegates<TContext>['vcs.fetch_with_options']
|
|
32
|
+
>;
|
|
33
|
+
push: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.push']>;
|
|
34
|
+
pullFfOnly: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.pull_ff_only']>;
|
|
35
|
+
commit: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.commit']>;
|
|
36
|
+
commitIndex: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.commit_index']>;
|
|
37
|
+
getStatusSummary: NonNullable<
|
|
38
|
+
VcsTypes.VcsDelegates<TContext>['vcs.get_status_summary']
|
|
39
|
+
>;
|
|
40
|
+
getStatusPayload: NonNullable<
|
|
41
|
+
VcsTypes.VcsDelegates<TContext>['vcs.get_status_payload']
|
|
42
|
+
>;
|
|
43
|
+
listCommits: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.list_commits']>;
|
|
44
|
+
diffFile: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.diff_file']>;
|
|
45
|
+
diffCommit: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.diff_commit']>;
|
|
46
|
+
getConflictDetails: NonNullable<
|
|
47
|
+
VcsTypes.VcsDelegates<TContext>['vcs.get_conflict_details']
|
|
48
|
+
>;
|
|
49
|
+
checkoutConflictSide: NonNullable<
|
|
50
|
+
VcsTypes.VcsDelegates<TContext>['vcs.checkout_conflict_side']
|
|
51
|
+
>;
|
|
52
|
+
writeMergeResult: NonNullable<
|
|
53
|
+
VcsTypes.VcsDelegates<TContext>['vcs.write_merge_result']
|
|
54
|
+
>;
|
|
55
|
+
stagePatch: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.stage_patch']>;
|
|
56
|
+
discardPaths: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.discard_paths']>;
|
|
57
|
+
applyReversePatch: NonNullable<
|
|
58
|
+
VcsTypes.VcsDelegates<TContext>['vcs.apply_reverse_patch']
|
|
59
|
+
>;
|
|
60
|
+
deleteBranch: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.delete_branch']>;
|
|
61
|
+
renameBranch: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.rename_branch']>;
|
|
62
|
+
mergeIntoCurrent: NonNullable<
|
|
63
|
+
VcsTypes.VcsDelegates<TContext>['vcs.merge_into_current']
|
|
64
|
+
>;
|
|
65
|
+
mergeAbort: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.merge_abort']>;
|
|
66
|
+
mergeContinue: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.merge_continue']>;
|
|
67
|
+
isMergeInProgress: NonNullable<
|
|
68
|
+
VcsTypes.VcsDelegates<TContext>['vcs.is_merge_in_progress']
|
|
69
|
+
>;
|
|
70
|
+
setBranchUpstream: NonNullable<
|
|
71
|
+
VcsTypes.VcsDelegates<TContext>['vcs.set_branch_upstream']
|
|
72
|
+
>;
|
|
73
|
+
getBranchUpstream: NonNullable<
|
|
74
|
+
VcsTypes.VcsDelegates<TContext>['vcs.get_branch_upstream']
|
|
75
|
+
>;
|
|
76
|
+
hardResetHead: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.hard_reset_head']>;
|
|
77
|
+
resetSoftTo: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.reset_soft_to']>;
|
|
78
|
+
getIdentity: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.get_identity']>;
|
|
79
|
+
setIdentityLocal: NonNullable<
|
|
80
|
+
VcsTypes.VcsDelegates<TContext>['vcs.set_identity_local']
|
|
81
|
+
>;
|
|
82
|
+
listStashes: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.list_stashes']>;
|
|
83
|
+
stashPush: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.stash_push']>;
|
|
84
|
+
stashApply: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.stash_apply']>;
|
|
85
|
+
stashPop: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.stash_pop']>;
|
|
86
|
+
stashDrop: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.stash_drop']>;
|
|
87
|
+
stashShow: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.stash_show']>;
|
|
88
|
+
cherryPick: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.cherry_pick']>;
|
|
89
|
+
revertCommit: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.revert_commit']>;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
/** Enumerates the class-friendly method names recognized by `VcsDelegateBase`. */
|
|
93
|
+
export type VcsDelegateMethodName = keyof VcsDelegateBindings<PluginRuntimeContext>;
|
|
94
|
+
|
|
95
|
+
/** Maps one delegate class method to the SDK runtime RPC key it implements. */
|
|
96
|
+
export const VCS_DELEGATE_METHOD_MAPPINGS = {
|
|
97
|
+
getCaps: 'vcs.get_caps',
|
|
98
|
+
open: 'vcs.open',
|
|
99
|
+
close: 'vcs.close',
|
|
100
|
+
cloneRepo: 'vcs.clone_repo',
|
|
101
|
+
getWorkdir: 'vcs.get_workdir',
|
|
102
|
+
getCurrentBranch: 'vcs.get_current_branch',
|
|
103
|
+
listBranches: 'vcs.list_branches',
|
|
104
|
+
listLocalBranches: 'vcs.list_local_branches',
|
|
105
|
+
createBranch: 'vcs.create_branch',
|
|
106
|
+
checkoutBranch: 'vcs.checkout_branch',
|
|
107
|
+
ensureRemote: 'vcs.ensure_remote',
|
|
108
|
+
listRemotes: 'vcs.list_remotes',
|
|
109
|
+
removeRemote: 'vcs.remove_remote',
|
|
110
|
+
fetch: 'vcs.fetch',
|
|
111
|
+
fetchWithOptions: 'vcs.fetch_with_options',
|
|
112
|
+
push: 'vcs.push',
|
|
113
|
+
pullFfOnly: 'vcs.pull_ff_only',
|
|
114
|
+
commit: 'vcs.commit',
|
|
115
|
+
commitIndex: 'vcs.commit_index',
|
|
116
|
+
getStatusSummary: 'vcs.get_status_summary',
|
|
117
|
+
getStatusPayload: 'vcs.get_status_payload',
|
|
118
|
+
listCommits: 'vcs.list_commits',
|
|
119
|
+
diffFile: 'vcs.diff_file',
|
|
120
|
+
diffCommit: 'vcs.diff_commit',
|
|
121
|
+
getConflictDetails: 'vcs.get_conflict_details',
|
|
122
|
+
checkoutConflictSide: 'vcs.checkout_conflict_side',
|
|
123
|
+
writeMergeResult: 'vcs.write_merge_result',
|
|
124
|
+
stagePatch: 'vcs.stage_patch',
|
|
125
|
+
discardPaths: 'vcs.discard_paths',
|
|
126
|
+
applyReversePatch: 'vcs.apply_reverse_patch',
|
|
127
|
+
deleteBranch: 'vcs.delete_branch',
|
|
128
|
+
renameBranch: 'vcs.rename_branch',
|
|
129
|
+
mergeIntoCurrent: 'vcs.merge_into_current',
|
|
130
|
+
mergeAbort: 'vcs.merge_abort',
|
|
131
|
+
mergeContinue: 'vcs.merge_continue',
|
|
132
|
+
isMergeInProgress: 'vcs.is_merge_in_progress',
|
|
133
|
+
setBranchUpstream: 'vcs.set_branch_upstream',
|
|
134
|
+
getBranchUpstream: 'vcs.get_branch_upstream',
|
|
135
|
+
hardResetHead: 'vcs.hard_reset_head',
|
|
136
|
+
resetSoftTo: 'vcs.reset_soft_to',
|
|
137
|
+
getIdentity: 'vcs.get_identity',
|
|
138
|
+
setIdentityLocal: 'vcs.set_identity_local',
|
|
139
|
+
listStashes: 'vcs.list_stashes',
|
|
140
|
+
stashPush: 'vcs.stash_push',
|
|
141
|
+
stashApply: 'vcs.stash_apply',
|
|
142
|
+
stashPop: 'vcs.stash_pop',
|
|
143
|
+
stashDrop: 'vcs.stash_drop',
|
|
144
|
+
stashShow: 'vcs.stash_show',
|
|
145
|
+
cherryPick: 'vcs.cherry_pick',
|
|
146
|
+
revertCommit: 'vcs.revert_commit',
|
|
147
|
+
} as const satisfies Record<
|
|
148
|
+
VcsDelegateMethodName,
|
|
149
|
+
keyof VcsTypes.VcsDelegates<PluginRuntimeContext>
|
|
150
|
+
>;
|
|
151
|
+
|
|
152
|
+
/** Resolves the RPC method implemented by one class-friendly delegate method. */
|
|
153
|
+
export type VcsDelegateRpcMethodName<TMethodName extends VcsDelegateMethodName> =
|
|
154
|
+
(typeof VCS_DELEGATE_METHOD_MAPPINGS)[TMethodName];
|
|
155
|
+
|
|
156
|
+
/** Describes the callable prototype surface required by `toDelegates()`. */
|
|
157
|
+
export type VcsDelegatePrototype<TContext> = {
|
|
158
|
+
[TMethodName in keyof VcsDelegateBindings<TContext>]: VcsDelegateBindings<TContext>[TMethodName];
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
/** Stores the exact `vcs.*` delegate object shape produced from class methods. */
|
|
162
|
+
export type VcsDelegateAssignments<TContext> = {
|
|
163
|
+
[TMethodName in VcsDelegateMethodName as VcsDelegateRpcMethodName<TMethodName>]?:
|
|
164
|
+
VcsDelegateBindings<TContext>[TMethodName];
|
|
165
|
+
};
|