@openvcs/sdk 0.2.5 → 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 CHANGED
@@ -81,10 +81,62 @@ export const PluginDefinition: PluginModuleDefinition = {
81
81
  export function OnPluginStart(): void {}
82
82
  ```
83
83
 
84
+ VCS backends can also derive from `VcsDelegateBase` and attach exact `vcs.*`
85
+ delegates during startup:
86
+
87
+ ```ts
88
+ import {
89
+ VcsDelegateBase,
90
+ type PluginRuntimeContext,
91
+ type PluginModuleDefinition,
92
+ } from '@openvcs/sdk/runtime';
93
+ import type { RequestParams, VcsCapabilities } from '@openvcs/sdk/types';
94
+
95
+ class ExampleVcsDelegates extends VcsDelegateBase<{ cwd: string }> {
96
+ override getCaps(
97
+ _params: RequestParams,
98
+ _context: PluginRuntimeContext,
99
+ ): VcsCapabilities {
100
+ return {
101
+ commits: true,
102
+ branches: true,
103
+ tags: false,
104
+ staging: true,
105
+ push_pull: true,
106
+ fast_forward: true,
107
+ };
108
+ }
109
+ }
110
+
111
+ export const PluginDefinition: PluginModuleDefinition = {};
112
+
113
+ export function OnPluginStart(): void {
114
+ const vcs = new ExampleVcsDelegates({ cwd: process.cwd() });
115
+ PluginDefinition.vcs = vcs.toDelegates();
116
+ }
117
+ ```
118
+
119
+ Define ordinary prototype methods such as `getCaps()` and `commitIndex()` on the
120
+ subclass. `toDelegates()` maps those camelCase methods to the exact host method
121
+ names like `vcs.get_caps` and `vcs.commit_index`, and only registers methods
122
+ that differ from the SDK base class. Use `override` with the full params/context
123
+ signature so TypeScript checks your subclass against the SDK contract. Base
124
+ stubs throw through an internal `never`-returning helper, which is why concrete
125
+ plugins should always implement the methods they intend to expose.
126
+
127
+ ### Compile-time override safety
128
+
129
+ The SDK enforces correct method signatures at compile time. Subclasses that
130
+ override with the wrong return type or parameter shape produce a TypeScript error.
131
+ The SDK test suite includes `test/vcs-delegate-base.types.ts` which explicitly
132
+ verifies that incompatible overrides (e.g. returning `string` instead of
133
+ `VcsCapabilities`) fail the compiler under `@ts-expect-error`. Runtime tests
134
+ in `test/vcs-delegate-base.test.js` cover behavior — not signatures.
135
+
84
136
  Runtime and protocol imports are exposed as npm subpaths:
85
137
 
86
138
  ```ts
87
- import { pluginError } from '@openvcs/sdk/runtime';
139
+ import { VcsDelegateBase, pluginError } from '@openvcs/sdk/runtime';
88
140
  import type { PluginDelegates, VcsDelegates } from '@openvcs/sdk/types';
89
141
  ```
90
142
 
@@ -6,5 +6,7 @@ export { isPluginFailure, pluginError } from './errors';
6
6
  export { createPluginRuntime } from './factory';
7
7
  export { createHost } from './host';
8
8
  export { bootstrapPluginModule, createRegisteredPluginRuntime, } from './registration';
9
+ export { VcsDelegateBase } from './vcs-delegate-base';
10
+ export type { VcsDelegateAssignments } from './vcs-delegate-metadata';
9
11
  /** Starts a previously created plugin runtime on process stdio. */
10
12
  export declare function startPluginRuntime(runtime: PluginRuntime, transport?: PluginRuntimeTransport): void;
@@ -2,7 +2,7 @@
2
2
  // Copyright © 2025-2026 OpenVCS Contributors
3
3
  // SPDX-License-Identifier: GPL-3.0-or-later
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.createRegisteredPluginRuntime = exports.bootstrapPluginModule = exports.createHost = exports.createPluginRuntime = exports.pluginError = exports.isPluginFailure = exports.createRuntimeDispatcher = exports.createDefaultPluginDelegates = void 0;
5
+ exports.VcsDelegateBase = exports.createRegisteredPluginRuntime = exports.bootstrapPluginModule = exports.createHost = exports.createPluginRuntime = exports.pluginError = exports.isPluginFailure = exports.createRuntimeDispatcher = exports.createDefaultPluginDelegates = void 0;
6
6
  exports.startPluginRuntime = startPluginRuntime;
7
7
  var dispatcher_1 = require("./dispatcher");
8
8
  Object.defineProperty(exports, "createDefaultPluginDelegates", { enumerable: true, get: function () { return dispatcher_1.createDefaultPluginDelegates; } });
@@ -17,6 +17,8 @@ Object.defineProperty(exports, "createHost", { enumerable: true, get: function (
17
17
  var registration_1 = require("./registration");
18
18
  Object.defineProperty(exports, "bootstrapPluginModule", { enumerable: true, get: function () { return registration_1.bootstrapPluginModule; } });
19
19
  Object.defineProperty(exports, "createRegisteredPluginRuntime", { enumerable: true, get: function () { return registration_1.createRegisteredPluginRuntime; } });
20
+ var vcs_delegate_base_1 = require("./vcs-delegate-base");
21
+ Object.defineProperty(exports, "VcsDelegateBase", { enumerable: true, get: function () { return vcs_delegate_base_1.VcsDelegateBase; } });
20
22
  /** Starts a previously created plugin runtime on process stdio. */
21
23
  function startPluginRuntime(runtime, transport) {
22
24
  runtime.start(transport);
@@ -0,0 +1,125 @@
1
+ import type * as VcsTypes from '../types';
2
+ import type { PluginRuntimeContext } from './contracts';
3
+ import { type VcsDelegateAssignments, type VcsDelegateMethodName } from './vcs-delegate-metadata';
4
+ /** Describes one synchronous or asynchronous VCS delegate return value. */
5
+ type VcsHandlerResult<TResult> = TResult | Promise<TResult>;
6
+ /** Builds exact `vcs.*` delegates from ordinary class methods. */
7
+ export declare abstract class VcsDelegateBase<TDeps, TContext = PluginRuntimeContext> {
8
+ /** Stores the runtime services exposed to the delegate implementation. */
9
+ protected readonly deps: TDeps;
10
+ /** Creates one delegate base with the provided runtime dependencies. */
11
+ constructor(deps: TDeps);
12
+ /** Builds an SDK `vcs.*` delegate map from the subclass overrides. */
13
+ toDelegates(): VcsDelegateAssignments<TContext>;
14
+ /** Assigns one typed class method to its exact `vcs.*` delegate name. */
15
+ private assignDelegate;
16
+ /**
17
+ * Throws when a subclass does not implement one required delegate method.
18
+ *
19
+ * The `never` return type is intentional: base stubs should never contribute
20
+ * a usable value, and subclasses should override the method with the exact
21
+ * signature inherited from `VcsDelegateBase`.
22
+ */
23
+ protected unimplemented(methodName: VcsDelegateMethodName): never;
24
+ /** Handles `vcs.get_caps`. */
25
+ getCaps(_params: VcsTypes.RequestParams, _context: TContext): VcsHandlerResult<VcsTypes.VcsCapabilities>;
26
+ /** Handles `vcs.open`. */
27
+ open(_params: VcsTypes.VcsOpenParams, _context: TContext): VcsHandlerResult<VcsTypes.VcsSessionResult>;
28
+ /** Handles `vcs.close`. */
29
+ close(_params: VcsTypes.VcsSessionParams, _context: TContext): VcsHandlerResult<null>;
30
+ /** Handles `vcs.clone_repo`. */
31
+ cloneRepo(_params: VcsTypes.VcsCloneRepoParams, _context: TContext): VcsHandlerResult<null>;
32
+ /** Handles `vcs.get_workdir`. */
33
+ getWorkdir(_params: VcsTypes.VcsSessionParams, _context: TContext): VcsHandlerResult<string>;
34
+ /** Handles `vcs.get_current_branch`. */
35
+ getCurrentBranch(_params: VcsTypes.VcsSessionParams, _context: TContext): VcsHandlerResult<string | null>;
36
+ /** Handles `vcs.list_branches`. */
37
+ listBranches(_params: VcsTypes.VcsSessionParams, _context: TContext): VcsHandlerResult<VcsTypes.VcsBranchEntry[]>;
38
+ /** Handles `vcs.list_local_branches`. */
39
+ listLocalBranches(_params: VcsTypes.VcsSessionParams, _context: TContext): VcsHandlerResult<string[]>;
40
+ /** Handles `vcs.create_branch`. */
41
+ createBranch(_params: VcsTypes.VcsCreateBranchParams, _context: TContext): VcsHandlerResult<null>;
42
+ /** Handles `vcs.checkout_branch`. */
43
+ checkoutBranch(_params: VcsTypes.VcsCheckoutBranchParams, _context: TContext): VcsHandlerResult<null>;
44
+ /** Handles `vcs.ensure_remote`. */
45
+ ensureRemote(_params: VcsTypes.VcsEnsureRemoteParams, _context: TContext): VcsHandlerResult<null>;
46
+ /** Handles `vcs.list_remotes`. */
47
+ listRemotes(_params: VcsTypes.VcsSessionParams, _context: TContext): VcsHandlerResult<VcsTypes.VcsRemoteEntry[]>;
48
+ /** Handles `vcs.remove_remote`. */
49
+ removeRemote(_params: VcsTypes.VcsRemoveRemoteParams, _context: TContext): VcsHandlerResult<null>;
50
+ /** Handles `vcs.fetch`. */
51
+ fetch(_params: VcsTypes.VcsFetchParams, _context: TContext): VcsHandlerResult<null>;
52
+ /** Handles `vcs.fetch_with_options`. */
53
+ fetchWithOptions(_params: VcsTypes.VcsFetchParams, _context: TContext): VcsHandlerResult<null>;
54
+ /** Handles `vcs.push`. */
55
+ push(_params: VcsTypes.VcsPushParams, _context: TContext): VcsHandlerResult<null>;
56
+ /** Handles `vcs.pull_ff_only`. */
57
+ pullFfOnly(_params: VcsTypes.VcsPullFfOnlyParams, _context: TContext): VcsHandlerResult<null>;
58
+ /** Handles `vcs.commit`. */
59
+ commit(_params: VcsTypes.VcsCommitParams, _context: TContext): VcsHandlerResult<string>;
60
+ /** Handles `vcs.commit_index`. */
61
+ commitIndex(_params: VcsTypes.VcsCommitParams, _context: TContext): VcsHandlerResult<string>;
62
+ /** Handles `vcs.get_status_summary`. */
63
+ getStatusSummary(_params: VcsTypes.VcsSessionParams, _context: TContext): VcsHandlerResult<VcsTypes.StatusSummary>;
64
+ /** Handles `vcs.get_status_payload`. */
65
+ getStatusPayload(_params: VcsTypes.VcsSessionParams, _context: TContext): VcsHandlerResult<VcsTypes.StatusPayload>;
66
+ /** Handles `vcs.list_commits`. */
67
+ listCommits(_params: VcsTypes.VcsListCommitsParams, _context: TContext): VcsHandlerResult<VcsTypes.CommitEntry[]>;
68
+ /** Handles `vcs.diff_file`. */
69
+ diffFile(_params: VcsTypes.VcsDiffFileParams, _context: TContext): VcsHandlerResult<string[]>;
70
+ /** Handles `vcs.diff_commit`. */
71
+ diffCommit(_params: VcsTypes.VcsDiffCommitParams, _context: TContext): VcsHandlerResult<string[]>;
72
+ /** Handles `vcs.get_conflict_details`. */
73
+ getConflictDetails(_params: VcsTypes.VcsGetConflictDetailsParams, _context: TContext): VcsHandlerResult<VcsTypes.VcsConflictDetails>;
74
+ /** Handles `vcs.checkout_conflict_side`. */
75
+ checkoutConflictSide(_params: VcsTypes.VcsCheckoutConflictSideParams, _context: TContext): VcsHandlerResult<null>;
76
+ /** Handles `vcs.write_merge_result`. */
77
+ writeMergeResult(_params: VcsTypes.VcsWriteMergeResultParams, _context: TContext): VcsHandlerResult<null>;
78
+ /** Handles `vcs.stage_patch`. */
79
+ stagePatch(_params: VcsTypes.VcsStagePatchParams, _context: TContext): VcsHandlerResult<null>;
80
+ /** Handles `vcs.discard_paths`. */
81
+ discardPaths(_params: VcsTypes.VcsDiscardPathsParams, _context: TContext): VcsHandlerResult<null>;
82
+ /** Handles `vcs.apply_reverse_patch`. */
83
+ applyReversePatch(_params: VcsTypes.VcsApplyReversePatchParams, _context: TContext): VcsHandlerResult<null>;
84
+ /** Handles `vcs.delete_branch`. */
85
+ deleteBranch(_params: VcsTypes.VcsDeleteBranchParams, _context: TContext): VcsHandlerResult<null>;
86
+ /** Handles `vcs.rename_branch`. */
87
+ renameBranch(_params: VcsTypes.VcsRenameBranchParams, _context: TContext): VcsHandlerResult<null>;
88
+ /** Handles `vcs.merge_into_current`. */
89
+ mergeIntoCurrent(_params: VcsTypes.VcsMergeIntoCurrentParams, _context: TContext): VcsHandlerResult<null>;
90
+ /** Handles `vcs.merge_abort`. */
91
+ mergeAbort(_params: VcsTypes.VcsSessionParams, _context: TContext): VcsHandlerResult<null>;
92
+ /** Handles `vcs.merge_continue`. */
93
+ mergeContinue(_params: VcsTypes.VcsSessionParams, _context: TContext): VcsHandlerResult<null>;
94
+ /** Handles `vcs.is_merge_in_progress`. */
95
+ isMergeInProgress(_params: VcsTypes.VcsSessionParams, _context: TContext): VcsHandlerResult<boolean>;
96
+ /** Handles `vcs.set_branch_upstream`. */
97
+ setBranchUpstream(_params: VcsTypes.VcsSetBranchUpstreamParams, _context: TContext): VcsHandlerResult<null>;
98
+ /** Handles `vcs.get_branch_upstream`. */
99
+ getBranchUpstream(_params: VcsTypes.VcsGetBranchUpstreamParams, _context: TContext): VcsHandlerResult<string | null>;
100
+ /** Handles `vcs.hard_reset_head`. */
101
+ hardResetHead(_params: VcsTypes.VcsSessionParams, _context: TContext): VcsHandlerResult<null>;
102
+ /** Handles `vcs.reset_soft_to`. */
103
+ resetSoftTo(_params: VcsTypes.VcsResetSoftToParams, _context: TContext): VcsHandlerResult<null>;
104
+ /** Handles `vcs.get_identity`. */
105
+ getIdentity(_params: VcsTypes.VcsSessionParams, _context: TContext): VcsHandlerResult<VcsTypes.VcsIdentity | null>;
106
+ /** Handles `vcs.set_identity_local`. */
107
+ setIdentityLocal(_params: VcsTypes.VcsSetIdentityLocalParams, _context: TContext): VcsHandlerResult<null>;
108
+ /** Handles `vcs.list_stashes`. */
109
+ listStashes(_params: VcsTypes.VcsSessionParams, _context: TContext): VcsHandlerResult<VcsTypes.StashEntry[]>;
110
+ /** Handles `vcs.stash_push`. */
111
+ stashPush(_params: VcsTypes.VcsStashPushParams, _context: TContext): VcsHandlerResult<string>;
112
+ /** Handles `vcs.stash_apply`. */
113
+ stashApply(_params: VcsTypes.VcsStashSelectorParams, _context: TContext): VcsHandlerResult<null>;
114
+ /** Handles `vcs.stash_pop`. */
115
+ stashPop(_params: VcsTypes.VcsStashSelectorParams, _context: TContext): VcsHandlerResult<null>;
116
+ /** Handles `vcs.stash_drop`. */
117
+ stashDrop(_params: VcsTypes.VcsStashSelectorParams, _context: TContext): VcsHandlerResult<null>;
118
+ /** Handles `vcs.stash_show`. */
119
+ stashShow(_params: VcsTypes.VcsStashSelectorParams, _context: TContext): VcsHandlerResult<string>;
120
+ /** Handles `vcs.cherry_pick`. */
121
+ cherryPick(_params: VcsTypes.VcsCherryPickParams, _context: TContext): VcsHandlerResult<null>;
122
+ /** Handles `vcs.revert_commit`. */
123
+ revertCommit(_params: VcsTypes.VcsRevertCommitParams, _context: TContext): VcsHandlerResult<null>;
124
+ }
125
+ export {};
@@ -0,0 +1,249 @@
1
+ "use strict";
2
+ // Copyright © 2025-2026 OpenVCS Contributors
3
+ // SPDX-License-Identifier: GPL-3.0-or-later
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.VcsDelegateBase = void 0;
6
+ const vcs_delegate_metadata_1 = require("./vcs-delegate-metadata");
7
+ /** Builds exact `vcs.*` delegates from ordinary class methods. */
8
+ class VcsDelegateBase {
9
+ /** Stores the runtime services exposed to the delegate implementation. */
10
+ deps;
11
+ /** Creates one delegate base with the provided runtime dependencies. */
12
+ constructor(deps) {
13
+ this.deps = deps;
14
+ }
15
+ /** Builds an SDK `vcs.*` delegate map from the subclass overrides. */
16
+ toDelegates() {
17
+ const delegates = {};
18
+ const delegatePrototype = Object.getPrototypeOf(this);
19
+ const basePrototype = VcsDelegateBase.prototype;
20
+ for (const delegateMethod of Object.keys(vcs_delegate_metadata_1.VCS_DELEGATE_METHOD_MAPPINGS)) {
21
+ const handler = delegatePrototype?.[delegateMethod];
22
+ if (typeof handler !== 'function' || handler === basePrototype[delegateMethod]) {
23
+ continue;
24
+ }
25
+ this.assignDelegate(delegates, delegateMethod, handler);
26
+ }
27
+ return delegates;
28
+ }
29
+ /** Assigns one typed class method to its exact `vcs.*` delegate name. */
30
+ assignDelegate(delegates, delegateMethod, handler) {
31
+ const rpcMethod = vcs_delegate_metadata_1.VCS_DELEGATE_METHOD_MAPPINGS[delegateMethod];
32
+ // `bind` loses the method-specific key correlation here; the cast is
33
+ // safe because `assignDelegate` is only called with handlers that were
34
+ // verified against `VcsDelegateBindings<TContext>` in the loop above.
35
+ const boundHandler = handler.bind(this);
36
+ delegates[rpcMethod] = boundHandler;
37
+ }
38
+ /**
39
+ * Throws when a subclass does not implement one required delegate method.
40
+ *
41
+ * The `never` return type is intentional: base stubs should never contribute
42
+ * a usable value, and subclasses should override the method with the exact
43
+ * signature inherited from `VcsDelegateBase`.
44
+ */
45
+ unimplemented(methodName) {
46
+ throw new Error(`VCS delegate method '${methodName}' must be overridden before registration`);
47
+ }
48
+ /** Handles `vcs.get_caps`. */
49
+ getCaps(_params, _context) {
50
+ return this.unimplemented('getCaps');
51
+ }
52
+ /** Handles `vcs.open`. */
53
+ open(_params, _context) {
54
+ return this.unimplemented('open');
55
+ }
56
+ /** Handles `vcs.close`. */
57
+ close(_params, _context) {
58
+ return this.unimplemented('close');
59
+ }
60
+ /** Handles `vcs.clone_repo`. */
61
+ cloneRepo(_params, _context) {
62
+ return this.unimplemented('cloneRepo');
63
+ }
64
+ /** Handles `vcs.get_workdir`. */
65
+ getWorkdir(_params, _context) {
66
+ return this.unimplemented('getWorkdir');
67
+ }
68
+ /** Handles `vcs.get_current_branch`. */
69
+ getCurrentBranch(_params, _context) {
70
+ return this.unimplemented('getCurrentBranch');
71
+ }
72
+ /** Handles `vcs.list_branches`. */
73
+ listBranches(_params, _context) {
74
+ return this.unimplemented('listBranches');
75
+ }
76
+ /** Handles `vcs.list_local_branches`. */
77
+ listLocalBranches(_params, _context) {
78
+ return this.unimplemented('listLocalBranches');
79
+ }
80
+ /** Handles `vcs.create_branch`. */
81
+ createBranch(_params, _context) {
82
+ return this.unimplemented('createBranch');
83
+ }
84
+ /** Handles `vcs.checkout_branch`. */
85
+ checkoutBranch(_params, _context) {
86
+ return this.unimplemented('checkoutBranch');
87
+ }
88
+ /** Handles `vcs.ensure_remote`. */
89
+ ensureRemote(_params, _context) {
90
+ return this.unimplemented('ensureRemote');
91
+ }
92
+ /** Handles `vcs.list_remotes`. */
93
+ listRemotes(_params, _context) {
94
+ return this.unimplemented('listRemotes');
95
+ }
96
+ /** Handles `vcs.remove_remote`. */
97
+ removeRemote(_params, _context) {
98
+ return this.unimplemented('removeRemote');
99
+ }
100
+ /** Handles `vcs.fetch`. */
101
+ fetch(_params, _context) {
102
+ return this.unimplemented('fetch');
103
+ }
104
+ /** Handles `vcs.fetch_with_options`. */
105
+ fetchWithOptions(_params, _context) {
106
+ return this.unimplemented('fetchWithOptions');
107
+ }
108
+ /** Handles `vcs.push`. */
109
+ push(_params, _context) {
110
+ return this.unimplemented('push');
111
+ }
112
+ /** Handles `vcs.pull_ff_only`. */
113
+ pullFfOnly(_params, _context) {
114
+ return this.unimplemented('pullFfOnly');
115
+ }
116
+ /** Handles `vcs.commit`. */
117
+ commit(_params, _context) {
118
+ return this.unimplemented('commit');
119
+ }
120
+ /** Handles `vcs.commit_index`. */
121
+ commitIndex(_params, _context) {
122
+ return this.unimplemented('commitIndex');
123
+ }
124
+ /** Handles `vcs.get_status_summary`. */
125
+ getStatusSummary(_params, _context) {
126
+ return this.unimplemented('getStatusSummary');
127
+ }
128
+ /** Handles `vcs.get_status_payload`. */
129
+ getStatusPayload(_params, _context) {
130
+ return this.unimplemented('getStatusPayload');
131
+ }
132
+ /** Handles `vcs.list_commits`. */
133
+ listCommits(_params, _context) {
134
+ return this.unimplemented('listCommits');
135
+ }
136
+ /** Handles `vcs.diff_file`. */
137
+ diffFile(_params, _context) {
138
+ return this.unimplemented('diffFile');
139
+ }
140
+ /** Handles `vcs.diff_commit`. */
141
+ diffCommit(_params, _context) {
142
+ return this.unimplemented('diffCommit');
143
+ }
144
+ /** Handles `vcs.get_conflict_details`. */
145
+ getConflictDetails(_params, _context) {
146
+ return this.unimplemented('getConflictDetails');
147
+ }
148
+ /** Handles `vcs.checkout_conflict_side`. */
149
+ checkoutConflictSide(_params, _context) {
150
+ return this.unimplemented('checkoutConflictSide');
151
+ }
152
+ /** Handles `vcs.write_merge_result`. */
153
+ writeMergeResult(_params, _context) {
154
+ return this.unimplemented('writeMergeResult');
155
+ }
156
+ /** Handles `vcs.stage_patch`. */
157
+ stagePatch(_params, _context) {
158
+ return this.unimplemented('stagePatch');
159
+ }
160
+ /** Handles `vcs.discard_paths`. */
161
+ discardPaths(_params, _context) {
162
+ return this.unimplemented('discardPaths');
163
+ }
164
+ /** Handles `vcs.apply_reverse_patch`. */
165
+ applyReversePatch(_params, _context) {
166
+ return this.unimplemented('applyReversePatch');
167
+ }
168
+ /** Handles `vcs.delete_branch`. */
169
+ deleteBranch(_params, _context) {
170
+ return this.unimplemented('deleteBranch');
171
+ }
172
+ /** Handles `vcs.rename_branch`. */
173
+ renameBranch(_params, _context) {
174
+ return this.unimplemented('renameBranch');
175
+ }
176
+ /** Handles `vcs.merge_into_current`. */
177
+ mergeIntoCurrent(_params, _context) {
178
+ return this.unimplemented('mergeIntoCurrent');
179
+ }
180
+ /** Handles `vcs.merge_abort`. */
181
+ mergeAbort(_params, _context) {
182
+ return this.unimplemented('mergeAbort');
183
+ }
184
+ /** Handles `vcs.merge_continue`. */
185
+ mergeContinue(_params, _context) {
186
+ return this.unimplemented('mergeContinue');
187
+ }
188
+ /** Handles `vcs.is_merge_in_progress`. */
189
+ isMergeInProgress(_params, _context) {
190
+ return this.unimplemented('isMergeInProgress');
191
+ }
192
+ /** Handles `vcs.set_branch_upstream`. */
193
+ setBranchUpstream(_params, _context) {
194
+ return this.unimplemented('setBranchUpstream');
195
+ }
196
+ /** Handles `vcs.get_branch_upstream`. */
197
+ getBranchUpstream(_params, _context) {
198
+ return this.unimplemented('getBranchUpstream');
199
+ }
200
+ /** Handles `vcs.hard_reset_head`. */
201
+ hardResetHead(_params, _context) {
202
+ return this.unimplemented('hardResetHead');
203
+ }
204
+ /** Handles `vcs.reset_soft_to`. */
205
+ resetSoftTo(_params, _context) {
206
+ return this.unimplemented('resetSoftTo');
207
+ }
208
+ /** Handles `vcs.get_identity`. */
209
+ getIdentity(_params, _context) {
210
+ return this.unimplemented('getIdentity');
211
+ }
212
+ /** Handles `vcs.set_identity_local`. */
213
+ setIdentityLocal(_params, _context) {
214
+ return this.unimplemented('setIdentityLocal');
215
+ }
216
+ /** Handles `vcs.list_stashes`. */
217
+ listStashes(_params, _context) {
218
+ return this.unimplemented('listStashes');
219
+ }
220
+ /** Handles `vcs.stash_push`. */
221
+ stashPush(_params, _context) {
222
+ return this.unimplemented('stashPush');
223
+ }
224
+ /** Handles `vcs.stash_apply`. */
225
+ stashApply(_params, _context) {
226
+ return this.unimplemented('stashApply');
227
+ }
228
+ /** Handles `vcs.stash_pop`. */
229
+ stashPop(_params, _context) {
230
+ return this.unimplemented('stashPop');
231
+ }
232
+ /** Handles `vcs.stash_drop`. */
233
+ stashDrop(_params, _context) {
234
+ return this.unimplemented('stashDrop');
235
+ }
236
+ /** Handles `vcs.stash_show`. */
237
+ stashShow(_params, _context) {
238
+ return this.unimplemented('stashShow');
239
+ }
240
+ /** Handles `vcs.cherry_pick`. */
241
+ cherryPick(_params, _context) {
242
+ return this.unimplemented('cherryPick');
243
+ }
244
+ /** Handles `vcs.revert_commit`. */
245
+ revertCommit(_params, _context) {
246
+ return this.unimplemented('revertCommit');
247
+ }
248
+ }
249
+ exports.VcsDelegateBase = VcsDelegateBase;
@@ -0,0 +1,120 @@
1
+ import type * as VcsTypes from '../types';
2
+ import type { PluginRuntimeContext } from './contracts';
3
+ /** Stores the typed class-method signatures supported by `VcsDelegateBase`. */
4
+ export type VcsDelegateBindings<TContext> = {
5
+ getCaps: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.get_caps']>;
6
+ open: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.open']>;
7
+ close: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.close']>;
8
+ cloneRepo: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.clone_repo']>;
9
+ getWorkdir: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.get_workdir']>;
10
+ getCurrentBranch: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.get_current_branch']>;
11
+ listBranches: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.list_branches']>;
12
+ listLocalBranches: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.list_local_branches']>;
13
+ createBranch: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.create_branch']>;
14
+ checkoutBranch: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.checkout_branch']>;
15
+ ensureRemote: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.ensure_remote']>;
16
+ listRemotes: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.list_remotes']>;
17
+ removeRemote: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.remove_remote']>;
18
+ fetch: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.fetch']>;
19
+ fetchWithOptions: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.fetch_with_options']>;
20
+ push: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.push']>;
21
+ pullFfOnly: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.pull_ff_only']>;
22
+ commit: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.commit']>;
23
+ commitIndex: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.commit_index']>;
24
+ getStatusSummary: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.get_status_summary']>;
25
+ getStatusPayload: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.get_status_payload']>;
26
+ listCommits: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.list_commits']>;
27
+ diffFile: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.diff_file']>;
28
+ diffCommit: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.diff_commit']>;
29
+ getConflictDetails: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.get_conflict_details']>;
30
+ checkoutConflictSide: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.checkout_conflict_side']>;
31
+ writeMergeResult: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.write_merge_result']>;
32
+ stagePatch: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.stage_patch']>;
33
+ discardPaths: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.discard_paths']>;
34
+ applyReversePatch: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.apply_reverse_patch']>;
35
+ deleteBranch: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.delete_branch']>;
36
+ renameBranch: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.rename_branch']>;
37
+ mergeIntoCurrent: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.merge_into_current']>;
38
+ mergeAbort: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.merge_abort']>;
39
+ mergeContinue: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.merge_continue']>;
40
+ isMergeInProgress: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.is_merge_in_progress']>;
41
+ setBranchUpstream: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.set_branch_upstream']>;
42
+ getBranchUpstream: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.get_branch_upstream']>;
43
+ hardResetHead: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.hard_reset_head']>;
44
+ resetSoftTo: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.reset_soft_to']>;
45
+ getIdentity: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.get_identity']>;
46
+ setIdentityLocal: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.set_identity_local']>;
47
+ listStashes: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.list_stashes']>;
48
+ stashPush: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.stash_push']>;
49
+ stashApply: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.stash_apply']>;
50
+ stashPop: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.stash_pop']>;
51
+ stashDrop: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.stash_drop']>;
52
+ stashShow: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.stash_show']>;
53
+ cherryPick: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.cherry_pick']>;
54
+ revertCommit: NonNullable<VcsTypes.VcsDelegates<TContext>['vcs.revert_commit']>;
55
+ };
56
+ /** Enumerates the class-friendly method names recognized by `VcsDelegateBase`. */
57
+ export type VcsDelegateMethodName = keyof VcsDelegateBindings<PluginRuntimeContext>;
58
+ /** Maps one delegate class method to the SDK runtime RPC key it implements. */
59
+ export declare const VCS_DELEGATE_METHOD_MAPPINGS: {
60
+ readonly getCaps: "vcs.get_caps";
61
+ readonly open: "vcs.open";
62
+ readonly close: "vcs.close";
63
+ readonly cloneRepo: "vcs.clone_repo";
64
+ readonly getWorkdir: "vcs.get_workdir";
65
+ readonly getCurrentBranch: "vcs.get_current_branch";
66
+ readonly listBranches: "vcs.list_branches";
67
+ readonly listLocalBranches: "vcs.list_local_branches";
68
+ readonly createBranch: "vcs.create_branch";
69
+ readonly checkoutBranch: "vcs.checkout_branch";
70
+ readonly ensureRemote: "vcs.ensure_remote";
71
+ readonly listRemotes: "vcs.list_remotes";
72
+ readonly removeRemote: "vcs.remove_remote";
73
+ readonly fetch: "vcs.fetch";
74
+ readonly fetchWithOptions: "vcs.fetch_with_options";
75
+ readonly push: "vcs.push";
76
+ readonly pullFfOnly: "vcs.pull_ff_only";
77
+ readonly commit: "vcs.commit";
78
+ readonly commitIndex: "vcs.commit_index";
79
+ readonly getStatusSummary: "vcs.get_status_summary";
80
+ readonly getStatusPayload: "vcs.get_status_payload";
81
+ readonly listCommits: "vcs.list_commits";
82
+ readonly diffFile: "vcs.diff_file";
83
+ readonly diffCommit: "vcs.diff_commit";
84
+ readonly getConflictDetails: "vcs.get_conflict_details";
85
+ readonly checkoutConflictSide: "vcs.checkout_conflict_side";
86
+ readonly writeMergeResult: "vcs.write_merge_result";
87
+ readonly stagePatch: "vcs.stage_patch";
88
+ readonly discardPaths: "vcs.discard_paths";
89
+ readonly applyReversePatch: "vcs.apply_reverse_patch";
90
+ readonly deleteBranch: "vcs.delete_branch";
91
+ readonly renameBranch: "vcs.rename_branch";
92
+ readonly mergeIntoCurrent: "vcs.merge_into_current";
93
+ readonly mergeAbort: "vcs.merge_abort";
94
+ readonly mergeContinue: "vcs.merge_continue";
95
+ readonly isMergeInProgress: "vcs.is_merge_in_progress";
96
+ readonly setBranchUpstream: "vcs.set_branch_upstream";
97
+ readonly getBranchUpstream: "vcs.get_branch_upstream";
98
+ readonly hardResetHead: "vcs.hard_reset_head";
99
+ readonly resetSoftTo: "vcs.reset_soft_to";
100
+ readonly getIdentity: "vcs.get_identity";
101
+ readonly setIdentityLocal: "vcs.set_identity_local";
102
+ readonly listStashes: "vcs.list_stashes";
103
+ readonly stashPush: "vcs.stash_push";
104
+ readonly stashApply: "vcs.stash_apply";
105
+ readonly stashPop: "vcs.stash_pop";
106
+ readonly stashDrop: "vcs.stash_drop";
107
+ readonly stashShow: "vcs.stash_show";
108
+ readonly cherryPick: "vcs.cherry_pick";
109
+ readonly revertCommit: "vcs.revert_commit";
110
+ };
111
+ /** Resolves the RPC method implemented by one class-friendly delegate method. */
112
+ export type VcsDelegateRpcMethodName<TMethodName extends VcsDelegateMethodName> = (typeof VCS_DELEGATE_METHOD_MAPPINGS)[TMethodName];
113
+ /** Describes the callable prototype surface required by `toDelegates()`. */
114
+ export type VcsDelegatePrototype<TContext> = {
115
+ [TMethodName in keyof VcsDelegateBindings<TContext>]: VcsDelegateBindings<TContext>[TMethodName];
116
+ };
117
+ /** Stores the exact `vcs.*` delegate object shape produced from class methods. */
118
+ export type VcsDelegateAssignments<TContext> = {
119
+ [TMethodName in VcsDelegateMethodName as VcsDelegateRpcMethodName<TMethodName>]?: VcsDelegateBindings<TContext>[TMethodName];
120
+ };
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ // Copyright © 2025-2026 OpenVCS Contributors
3
+ // SPDX-License-Identifier: GPL-3.0-or-later
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.VCS_DELEGATE_METHOD_MAPPINGS = void 0;
6
+ /** Maps one delegate class method to the SDK runtime RPC key it implements. */
7
+ exports.VCS_DELEGATE_METHOD_MAPPINGS = {
8
+ getCaps: 'vcs.get_caps',
9
+ open: 'vcs.open',
10
+ close: 'vcs.close',
11
+ cloneRepo: 'vcs.clone_repo',
12
+ getWorkdir: 'vcs.get_workdir',
13
+ getCurrentBranch: 'vcs.get_current_branch',
14
+ listBranches: 'vcs.list_branches',
15
+ listLocalBranches: 'vcs.list_local_branches',
16
+ createBranch: 'vcs.create_branch',
17
+ checkoutBranch: 'vcs.checkout_branch',
18
+ ensureRemote: 'vcs.ensure_remote',
19
+ listRemotes: 'vcs.list_remotes',
20
+ removeRemote: 'vcs.remove_remote',
21
+ fetch: 'vcs.fetch',
22
+ fetchWithOptions: 'vcs.fetch_with_options',
23
+ push: 'vcs.push',
24
+ pullFfOnly: 'vcs.pull_ff_only',
25
+ commit: 'vcs.commit',
26
+ commitIndex: 'vcs.commit_index',
27
+ getStatusSummary: 'vcs.get_status_summary',
28
+ getStatusPayload: 'vcs.get_status_payload',
29
+ listCommits: 'vcs.list_commits',
30
+ diffFile: 'vcs.diff_file',
31
+ diffCommit: 'vcs.diff_commit',
32
+ getConflictDetails: 'vcs.get_conflict_details',
33
+ checkoutConflictSide: 'vcs.checkout_conflict_side',
34
+ writeMergeResult: 'vcs.write_merge_result',
35
+ stagePatch: 'vcs.stage_patch',
36
+ discardPaths: 'vcs.discard_paths',
37
+ applyReversePatch: 'vcs.apply_reverse_patch',
38
+ deleteBranch: 'vcs.delete_branch',
39
+ renameBranch: 'vcs.rename_branch',
40
+ mergeIntoCurrent: 'vcs.merge_into_current',
41
+ mergeAbort: 'vcs.merge_abort',
42
+ mergeContinue: 'vcs.merge_continue',
43
+ isMergeInProgress: 'vcs.is_merge_in_progress',
44
+ setBranchUpstream: 'vcs.set_branch_upstream',
45
+ getBranchUpstream: 'vcs.get_branch_upstream',
46
+ hardResetHead: 'vcs.hard_reset_head',
47
+ resetSoftTo: 'vcs.reset_soft_to',
48
+ getIdentity: 'vcs.get_identity',
49
+ setIdentityLocal: 'vcs.set_identity_local',
50
+ listStashes: 'vcs.list_stashes',
51
+ stashPush: 'vcs.stash_push',
52
+ stashApply: 'vcs.stash_apply',
53
+ stashPop: 'vcs.stash_pop',
54
+ stashDrop: 'vcs.stash_drop',
55
+ stashShow: 'vcs.stash_show',
56
+ cherryPick: 'vcs.cherry_pick',
57
+ revertCommit: 'vcs.revert_commit',
58
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openvcs/sdk",
3
- "version": "0.2.5",
3
+ "version": "0.2.6",
4
4
  "description": "OpenVCS SDK CLI for plugin scaffolding and .ovcsp tar.gz packaging",
5
5
  "license": "GPL-3.0-or-later",
6
6
  "homepage": "https://openvcs.app/",
@@ -32,7 +32,8 @@
32
32
  },
33
33
  "scripts": {
34
34
  "build": "node scripts/build-sdk.js",
35
- "test": "npm run build && node --test test/*.test.js",
35
+ "test": "npm run build && npm run test:types && node --test test/*.test.js",
36
+ "test:types": "node ./node_modules/typescript/bin/tsc -p test/tsconfig.json",
36
37
  "prepack": "npm run build",
37
38
  "preopenvcs": "npm run build",
38
39
  "openvcs": "node bin/openvcs.js"