@serviceme/devtools-core 2.0.0 → 2.0.2
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/dist/auth-Bzss8zOv.mjs +995 -0
- package/dist/auth-Bzss8zOv.mjs.map +1 -0
- package/dist/auth-DXam3c4S.js +1078 -0
- package/dist/auth-DXam3c4S.js.map +1 -0
- package/dist/auth.d.mts +2 -2
- package/dist/auth.d.ts +2 -2
- package/dist/auth.js +14 -1029
- package/dist/auth.mjs +2 -991
- package/dist/device-CDDcwDY6.mjs +758 -0
- package/dist/device-CDDcwDY6.mjs.map +1 -0
- package/dist/device-DuAYH8bk.js +839 -0
- package/dist/device-DuAYH8bk.js.map +1 -0
- package/dist/device.d.mts +2 -455
- package/dist/device.d.ts +2 -455
- package/dist/device.js +15 -728
- package/dist/device.mjs +2 -679
- package/dist/index-2rX86yMq.d.mts +331 -0
- package/dist/index-BI11AfMH.d.mts +377 -0
- package/dist/index-BI11AfMH.d.ts +377 -0
- package/dist/index-CoA6y0MP.d.mts +498 -0
- package/dist/index-CoA6y0MP.d.ts +498 -0
- package/dist/index-DaW7IYA-.d.mts +185 -0
- package/dist/index-DaW7IYA-.d.ts +185 -0
- package/dist/index-Dp6FwWKh.d.ts +331 -0
- package/dist/index.d.mts +2340 -2101
- package/dist/index.d.ts +2340 -2101
- package/dist/index.js +8117 -10538
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +7895 -10318
- package/dist/index.mjs.map +1 -1
- package/dist/rolldown-runtime-VH7oDXx4.js +28 -0
- package/dist/skill-linker.d.mts +82 -81
- package/dist/skill-linker.d.ts +82 -81
- package/dist/skill-linker.js +359 -402
- package/dist/skill-linker.js.map +1 -1
- package/dist/skill-linker.mjs +345 -357
- package/dist/skill-linker.mjs.map +1 -1
- package/dist/skill-store-Bym2yinU.mjs +388 -0
- package/dist/skill-store-Bym2yinU.mjs.map +1 -0
- package/dist/skill-store-CJdYyyxu.js +408 -0
- package/dist/skill-store-CJdYyyxu.js.map +1 -0
- package/dist/skill-store.d.mts +41 -42
- package/dist/skill-store.d.ts +41 -42
- package/dist/skill-store.js +5 -338
- package/dist/skill-store.mjs +2 -301
- package/dist/submit-Cg7wSa3x.mjs +84 -0
- package/dist/submit-Cg7wSa3x.mjs.map +1 -0
- package/dist/submit-CltE6YOZ.js +98 -0
- package/dist/submit-CltE6YOZ.js.map +1 -0
- package/dist/submit.d.mts +2 -3
- package/dist/submit.d.ts +2 -3
- package/dist/submit.js +4 -166
- package/dist/submit.mjs +2 -130
- package/dist/toolbox-CbfxpNg-.mjs +540 -0
- package/dist/toolbox-CbfxpNg-.mjs.map +1 -0
- package/dist/toolbox-CxnOr-FY.js +614 -0
- package/dist/toolbox-CxnOr-FY.js.map +1 -0
- package/dist/toolbox.d.mts +2 -244
- package/dist/toolbox.d.ts +2 -244
- package/dist/toolbox.js +14 -584
- package/dist/toolbox.mjs +2 -536
- package/dist/{types-B9gk3dXH.d.ts → types-BCV3IedE.d.mts} +25 -23
- package/dist/{types-B9gk3dXH.d.mts → types-BCV3IedE.d.ts} +25 -23
- package/dist/userHome-BquDeFVE.js +526 -0
- package/dist/userHome-BquDeFVE.js.map +1 -0
- package/dist/userHome-CcnAQPG1.mjs +212 -0
- package/dist/userHome-CcnAQPG1.mjs.map +1 -0
- package/package.json +10 -10
- package/dist/auth.js.map +0 -1
- package/dist/auth.mjs.map +0 -1
- package/dist/device.js.map +0 -1
- package/dist/device.mjs.map +0 -1
- package/dist/index-BMk4tqIT.d.mts +0 -328
- package/dist/index-CymN0x9Z.d.ts +0 -328
- package/dist/index-PD135hlB.d.mts +0 -626
- package/dist/index-PD135hlB.d.ts +0 -626
- package/dist/skill-store.js.map +0 -1
- package/dist/skill-store.mjs.map +0 -1
- package/dist/submit.js.map +0 -1
- package/dist/submit.mjs.map +0 -1
- package/dist/toolbox.js.map +0 -1
- package/dist/toolbox.mjs.map +0 -1
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { ExternalTool, ToolboxList, ToolboxScope } from "@serviceme/devtools-protocol";
|
|
2
|
+
//#region src/toolbox/sort.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Sort by "recently used" — entries with newer `lastUsedAt` float to
|
|
5
|
+
* the top, entries with no `lastUsedAt` sort to the bottom (preserving
|
|
6
|
+
* their relative `order` index when both are absent).
|
|
7
|
+
*
|
|
8
|
+
* Ties (same `lastUsedAt` or both missing) are broken by `order`, then
|
|
9
|
+
* by `id` for determinism.
|
|
10
|
+
*/
|
|
11
|
+
declare function sortByRecentFirst(tools: readonly ExternalTool[]): ExternalTool[];
|
|
12
|
+
/**
|
|
13
|
+
* Sort by user-defined `order` field. Entries without `order` are
|
|
14
|
+
* appended in their input order (stable sort via `id` tiebreaker).
|
|
15
|
+
*/
|
|
16
|
+
declare function sortByUserOrder(tools: readonly ExternalTool[]): ExternalTool[];
|
|
17
|
+
/**
|
|
18
|
+
* Merge built-in defaults with user-stored tools. Defaults keep
|
|
19
|
+
* `isDefault: true` and their `order`; user tools are appended with
|
|
20
|
+
* their stored metadata. Output is sorted by user order.
|
|
21
|
+
*/
|
|
22
|
+
declare function mergeWithDefaults(defaults: readonly ExternalTool[], userTools: readonly ExternalTool[]): ExternalTool[];
|
|
23
|
+
/**
|
|
24
|
+
* Re-number `order` for a list of tool ids. Used by
|
|
25
|
+
* `toolbox.update` when the user drags-and-drops entries in the UI.
|
|
26
|
+
*/
|
|
27
|
+
declare function reindexOrder(tools: ExternalTool[], newOrderIds: readonly string[]): ExternalTool[];
|
|
28
|
+
/**
|
|
29
|
+
* Stamp `lastUsedAt` on the targeted tool (clones the array). Returns
|
|
30
|
+
* a new array; the input is left untouched.
|
|
31
|
+
*/
|
|
32
|
+
declare function touchLastUsedAt(tools: readonly ExternalTool[], id: string, when?: Date): ExternalTool[];
|
|
33
|
+
//#endregion
|
|
34
|
+
//#region src/toolbox/types.d.ts
|
|
35
|
+
/** Schema version of the on-disk toolbox JSON files. Bumped on breaking changes. */
|
|
36
|
+
declare const TOOLBOX_JSON_SCHEMA_VERSION = 1;
|
|
37
|
+
interface PersistedToolbox {
|
|
38
|
+
version: number;
|
|
39
|
+
tools: ExternalTool[];
|
|
40
|
+
}
|
|
41
|
+
/** Patch payload accepted by `ToolboxCore.update` (mirrors `ExternalToolPatch`). */
|
|
42
|
+
type ToolboxPatch = Partial<Omit<ExternalTool, "id" | "isDefault">>;
|
|
43
|
+
/**
|
|
44
|
+
* Built-in (default) tool seeds. Mirrors the Extension's
|
|
45
|
+
* `apps/extension/src/config/external-tools.ts`. The Core stores these
|
|
46
|
+
* verbatim and never mutates them — the Extension's `ToolBoxService`
|
|
47
|
+
* runs the same merge on top of the Core's view.
|
|
48
|
+
*/
|
|
49
|
+
interface DefaultToolSeed {
|
|
50
|
+
id: string;
|
|
51
|
+
name: string;
|
|
52
|
+
description: string;
|
|
53
|
+
icon: string;
|
|
54
|
+
url: string;
|
|
55
|
+
}
|
|
56
|
+
/** Built-in tools rendered when the JSON file is missing or empty. */
|
|
57
|
+
declare const BUILTIN_DEFAULT_TOOLS: readonly DefaultToolSeed[];
|
|
58
|
+
/** Resolved toolbox shape returned by `ToolboxStore.read()`. */
|
|
59
|
+
interface ResolvedToolbox {
|
|
60
|
+
scope: ToolboxScope;
|
|
61
|
+
tools: ExternalTool[];
|
|
62
|
+
}
|
|
63
|
+
//#endregion
|
|
64
|
+
//#region src/toolbox/ToolboxStore.d.ts
|
|
65
|
+
declare const WORKSPACE_TOOLBOX_RELATIVE_PATH: string;
|
|
66
|
+
interface ToolboxFileBackend {
|
|
67
|
+
read(filePath: string): Promise<PersistedToolbox | null>;
|
|
68
|
+
write(filePath: string, payload: PersistedToolbox): Promise<void>;
|
|
69
|
+
exists(filePath: string): Promise<boolean>;
|
|
70
|
+
/** Maximum number of `.corrupted.*.bak` snapshots to keep per toolbox file (default: 5). */
|
|
71
|
+
maxBackupCount?: number;
|
|
72
|
+
}
|
|
73
|
+
interface ToolboxStoreOptions {
|
|
74
|
+
/** Override the user-scope file path (default: `getToolboxJsonPath()`). */
|
|
75
|
+
userFilePath?: string;
|
|
76
|
+
/** Override the workspace-scope file path resolver (default: cwd-relative). */
|
|
77
|
+
resolveWorkspacePath?: () => string | null;
|
|
78
|
+
/** Injectable built-in tool seeds (default: `BUILTIN_DEFAULT_TOOLS`). */
|
|
79
|
+
defaultTools?: readonly DefaultToolSeed[];
|
|
80
|
+
hooks?: ToolboxStoreHooks;
|
|
81
|
+
backend?: ToolboxFileBackend;
|
|
82
|
+
lockTimeoutMs?: number;
|
|
83
|
+
lockRetryMs?: number;
|
|
84
|
+
}
|
|
85
|
+
interface ToolboxStoreHooks {
|
|
86
|
+
beforeWrite?: (scope: ToolboxScope, payload: PersistedToolbox) => void | Promise<void>;
|
|
87
|
+
afterWrite?: (scope: ToolboxScope, payload: PersistedToolbox) => void | Promise<void>;
|
|
88
|
+
}
|
|
89
|
+
declare class FsToolboxFileBackend implements ToolboxFileBackend {
|
|
90
|
+
maxBackupCount: number;
|
|
91
|
+
exists(filePath: string): Promise<boolean>;
|
|
92
|
+
read(filePath: string): Promise<PersistedToolbox | null>;
|
|
93
|
+
private backupCorruptedFile;
|
|
94
|
+
private purgeExcessBackups;
|
|
95
|
+
write(filePath: string, payload: PersistedToolbox): Promise<void>;
|
|
96
|
+
}
|
|
97
|
+
declare class ToolboxStore {
|
|
98
|
+
private readonly userFilePath;
|
|
99
|
+
private readonly resolveWorkspacePath;
|
|
100
|
+
private readonly defaults;
|
|
101
|
+
private readonly hooks;
|
|
102
|
+
private readonly backend;
|
|
103
|
+
private readonly lockTimeoutMs;
|
|
104
|
+
private readonly lockRetryMs;
|
|
105
|
+
constructor(opts?: ToolboxStoreOptions);
|
|
106
|
+
/** Read a scope; returns the resolved toolbox (with defaults merged when empty). */
|
|
107
|
+
read(scope: ToolboxScope): Promise<ResolvedToolbox>;
|
|
108
|
+
/**
|
|
109
|
+
* Atomic write under a file lock. Replaces the entire `tools` array
|
|
110
|
+
* with the provided snapshot.
|
|
111
|
+
*/
|
|
112
|
+
write(scope: ToolboxScope, tools: readonly ExternalTool[]): Promise<void>;
|
|
113
|
+
/**
|
|
114
|
+
* Read-modify-write under the file lock. The mutator receives the
|
|
115
|
+
* current user-only list (defaults not included) and returns the
|
|
116
|
+
* replacement list. Throwing inside the mutator aborts the write.
|
|
117
|
+
*/
|
|
118
|
+
mutate(scope: ToolboxScope, mutator: (current: ExternalTool[]) => Promise<ExternalTool[]>): Promise<ExternalTool[]>;
|
|
119
|
+
/** Wipe a scope entirely (used by `toolbox.remove --all` extensions). */
|
|
120
|
+
clear(scope: ToolboxScope): Promise<void>;
|
|
121
|
+
/** Test seam — resolve the user-scope file path. */
|
|
122
|
+
getUserFilePath(): string;
|
|
123
|
+
/** Test seam — resolve the workspace-scope file path (or null when disabled). */
|
|
124
|
+
getWorkspaceFilePath(): string | null;
|
|
125
|
+
private filePathFor;
|
|
126
|
+
}
|
|
127
|
+
//#endregion
|
|
128
|
+
//#region src/toolbox/ToolboxCore.d.ts
|
|
129
|
+
/** Sentinel — caller tried to remove a built-in (immutable) tool. */
|
|
130
|
+
declare class DefaultToolImmutableError extends Error {
|
|
131
|
+
readonly toolId: string;
|
|
132
|
+
constructor(toolId: string);
|
|
133
|
+
}
|
|
134
|
+
interface ToolboxCoreOptions {
|
|
135
|
+
store?: ToolboxStore;
|
|
136
|
+
defaultTools?: readonly DefaultToolSeed[];
|
|
137
|
+
/** Sort applied to the merged list returned by `list()`. Default: `sortByUserOrder`. */
|
|
138
|
+
listSort?: (tools: readonly ExternalTool[]) => ExternalTool[];
|
|
139
|
+
}
|
|
140
|
+
declare class ToolboxCore {
|
|
141
|
+
private readonly store;
|
|
142
|
+
private readonly defaults;
|
|
143
|
+
private readonly listSort;
|
|
144
|
+
constructor(opts?: ToolboxCoreOptions);
|
|
145
|
+
/** List all tools in a scope. Built-in defaults are merged in. */
|
|
146
|
+
list(scope?: ToolboxScope): Promise<ToolboxList>;
|
|
147
|
+
/**
|
|
148
|
+
* Append a new tool to the requested scope. Default tools are
|
|
149
|
+
* rejected (they are seeds, not user entries).
|
|
150
|
+
*/
|
|
151
|
+
add(tool: ExternalTool, scope?: ToolboxScope): Promise<ToolboxList>;
|
|
152
|
+
/**
|
|
153
|
+
* Remove a tool by id. Returns `success: false` when the id is a
|
|
154
|
+
* built-in default (idempotent, never throws on missing entries).
|
|
155
|
+
*/
|
|
156
|
+
remove(id: string, scope?: ToolboxScope): Promise<{
|
|
157
|
+
scope: ToolboxScope;
|
|
158
|
+
toolId: string;
|
|
159
|
+
success: boolean;
|
|
160
|
+
}>;
|
|
161
|
+
/**
|
|
162
|
+
* Patch a tool by id. Default tools can only have their `order`
|
|
163
|
+
* updated; other patches are silently ignored for default entries
|
|
164
|
+
* (callers can compare before/after to detect the ignore).
|
|
165
|
+
*/
|
|
166
|
+
update(id: string, patch: ToolboxPatch, scope?: ToolboxScope): Promise<ToolboxList>;
|
|
167
|
+
/**
|
|
168
|
+
* Stamp `lastUsedAt` on the targeted tool. This is the "recently
|
|
169
|
+
* used" hook the Extension's webview uses when a user clicks a
|
|
170
|
+
* toolbox entry.
|
|
171
|
+
*/
|
|
172
|
+
recordUsage(id: string, scope?: ToolboxScope, when?: Date): Promise<ExternalTool | null>;
|
|
173
|
+
/**
|
|
174
|
+
* Combined view: user + workspace scopes merged, sorted by recent
|
|
175
|
+
* usage. Workspace tools overlay user tools (workspace entries win
|
|
176
|
+
* on `id` collision).
|
|
177
|
+
*/
|
|
178
|
+
listMerged(): Promise<ToolboxList>;
|
|
179
|
+
/** Expose the underlying store (CLI / Bridge use it for path-level access). */
|
|
180
|
+
getStore(): ToolboxStore;
|
|
181
|
+
private isDefaultId;
|
|
182
|
+
}
|
|
183
|
+
//#endregion
|
|
184
|
+
export { reindexOrder as _, ToolboxFileBackend as a, touchLastUsedAt as b, ToolboxStoreOptions as c, DefaultToolSeed as d, PersistedToolbox as f, mergeWithDefaults as g, ToolboxPatch as h, FsToolboxFileBackend as i, WORKSPACE_TOOLBOX_RELATIVE_PATH as l, TOOLBOX_JSON_SCHEMA_VERSION as m, ToolboxCore as n, ToolboxStore as o, ResolvedToolbox as p, ToolboxCoreOptions as r, ToolboxStoreHooks as s, DefaultToolImmutableError as t, BUILTIN_DEFAULT_TOOLS as u, sortByRecentFirst as v, sortByUserOrder as y };
|
|
185
|
+
//# sourceMappingURL=index-DaW7IYA-.d.ts.map
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
import { r as SkillFile } from "./types-BCV3IedE.js";
|
|
2
|
+
import { SpawnOptions } from "node:child_process";
|
|
3
|
+
//#region src/git-client/types.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Skill & Agent v2 — Client GitClient Types (M3)
|
|
6
|
+
*
|
|
7
|
+
* GitClient wraps the local `git` CLI so all commands the SERVICEME
|
|
8
|
+
* pipeline issues (clone, fetch, push, ls-remote) flow through the
|
|
9
|
+
* server's git smart-HTTP proxy instead of talking directly to GitHub.
|
|
10
|
+
*
|
|
11
|
+
* The single trick: `git` only cares about the URL we hand it as a
|
|
12
|
+
* remote. We rewrite `https://github.com/owner/repo.git` to
|
|
13
|
+
* `http://server:port/git-proxy/<id>` and `git` does the rest — the
|
|
14
|
+
* server transparently forwards + injects PATs as needed.
|
|
15
|
+
*
|
|
16
|
+
* @see docs/architecture/skill-agent-v2-repo.md §5.4 GitClient
|
|
17
|
+
*/
|
|
18
|
+
/** Result of a `git fetch` (called via the proxy's git-upload-pack). */
|
|
19
|
+
interface PullResult {
|
|
20
|
+
/** Whether new commits were fetched (false = already up-to-date). */
|
|
21
|
+
updated: boolean;
|
|
22
|
+
/** Commit SHA at FETCH_HEAD after the pull. */
|
|
23
|
+
commitSha: string;
|
|
24
|
+
/** Branch name that was pulled (e.g. "v2"). */
|
|
25
|
+
branch: string;
|
|
26
|
+
}
|
|
27
|
+
/** Result of a `git push` (called via the proxy's git-receive-pack). */
|
|
28
|
+
interface PushResult {
|
|
29
|
+
/** Remote ref updated (e.g. "refs/heads/v2"). */
|
|
30
|
+
ref: string;
|
|
31
|
+
/** New commit SHA on the remote. */
|
|
32
|
+
commitSha: string;
|
|
33
|
+
}
|
|
34
|
+
/** A branch as advertised by `git ls-remote`. */
|
|
35
|
+
interface RemoteBranch {
|
|
36
|
+
/** Full ref name, e.g. `refs/heads/main`. */
|
|
37
|
+
ref: string;
|
|
38
|
+
/** Commit SHA the ref points at. */
|
|
39
|
+
sha: string;
|
|
40
|
+
}
|
|
41
|
+
/** Outcome of any spawned `git` process. */
|
|
42
|
+
interface GitSpawnResult {
|
|
43
|
+
stdout: string;
|
|
44
|
+
stderr: string;
|
|
45
|
+
code: number;
|
|
46
|
+
}
|
|
47
|
+
/** Strategy for executing git commands. Tests inject a stub. */
|
|
48
|
+
interface GitSpawner {
|
|
49
|
+
spawn(args: string[], opts: SpawnOptions): Promise<GitSpawnResult>;
|
|
50
|
+
}
|
|
51
|
+
/** Options for instantiating GitClient. */
|
|
52
|
+
interface GitClientOptions {
|
|
53
|
+
/** Base URL of the server git proxy. e.g. `http://localhost:3000/git-proxy`. */
|
|
54
|
+
serverProxyBase: string;
|
|
55
|
+
/** Inject a custom spawner (default: spawn real `git` CLI). */
|
|
56
|
+
spawner?: GitSpawner;
|
|
57
|
+
/** Inject an env override for spawned git (default: process.env minus proxy secrets). */
|
|
58
|
+
env?: NodeJS.ProcessEnv;
|
|
59
|
+
}
|
|
60
|
+
/** Sentinel error when git exits non-zero. */
|
|
61
|
+
declare class GitError extends Error {
|
|
62
|
+
readonly args: string[];
|
|
63
|
+
readonly code: number;
|
|
64
|
+
readonly stderr: string;
|
|
65
|
+
readonly stdout: string;
|
|
66
|
+
constructor(args: string[], result: GitSpawnResult);
|
|
67
|
+
}
|
|
68
|
+
//#endregion
|
|
69
|
+
//#region src/git-client/index.d.ts
|
|
70
|
+
/**
|
|
71
|
+
* Skill & Agent v2 — Client GitClient (M3)
|
|
72
|
+
*
|
|
73
|
+
* Wraps `git` so all upstream traffic flows through the server's git
|
|
74
|
+
* proxy at `serverProxyBase`. See docs/architecture/skill-agent-v2-repo.md
|
|
75
|
+
* §5.4.
|
|
76
|
+
*
|
|
77
|
+
* Why a wrapper instead of using libgit2 directly:
|
|
78
|
+
* 1. `git` is already installed everywhere we run (extension host,
|
|
79
|
+
* CLI). No native deps.
|
|
80
|
+
* 2. Users can debug their skill repos with plain `git` commands when
|
|
81
|
+
* SERVICEME is misbehaving — the wrappers keep a familiar CLI.
|
|
82
|
+
* 3. libgit2's packfile negotiation has subtle correctness gaps that
|
|
83
|
+
* we don't want to debug server-side.
|
|
84
|
+
*
|
|
85
|
+
* URL rewrite:
|
|
86
|
+
* `https://github.com/owner/repo.git` → `<proxyBase>/<id>`
|
|
87
|
+
*
|
|
88
|
+
* When git hits `<proxyBase>/<id>` it discovers the proxy's
|
|
89
|
+
* `/info/refs?service=git-upload-pack` endpoint via the smart-HTTP
|
|
90
|
+
* protocol. From there the server takes over.
|
|
91
|
+
*/
|
|
92
|
+
declare class GitClient {
|
|
93
|
+
private readonly serverProxyBase;
|
|
94
|
+
private readonly spawner;
|
|
95
|
+
constructor(opts: GitClientOptions);
|
|
96
|
+
/**
|
|
97
|
+
* Rewrite an upstream URL to its proxy form.
|
|
98
|
+
*
|
|
99
|
+
* Examples:
|
|
100
|
+
* rewriteRemoteUrl("repo-aHR0cHM6Ly9naXRodWIuY29tL21lZGFsc29mdGNoaW5hL21zLXNraWxscy5naXQ",
|
|
101
|
+
* "https://github.com/medalsoftchina/ms-skills.git")
|
|
102
|
+
* → "http://localhost:3000/git-proxy/repo-aHR0cHM6Ly9naXRodWIuY29tL21lZGFsc29mdGNoaW5hL21zLXNraWxscy5naXQ"
|
|
103
|
+
*
|
|
104
|
+
* rewriteRemoteUrl("repo-aHR0cHM6Ly9naXRodWIuY29tL3RlYW0vaW50ZXJuYWwuZ2l0",
|
|
105
|
+
* "git@github.com:medalsoftchina/ms-skills.git")
|
|
106
|
+
* → "http://localhost:3000/git-proxy/repo-aHR0cHM6Ly9naXRodWIuY29tL3RlYW0vaW50ZXJuYWwuZ2l0"
|
|
107
|
+
*
|
|
108
|
+
* The original URL's host/owner is intentionally DROPPED — the proxy
|
|
109
|
+
* knows the upstream from the per-repo config, not from the URL. This
|
|
110
|
+
* means callers can route both default and user repos through the same
|
|
111
|
+
* dynamic proxy-id scheme.
|
|
112
|
+
*/
|
|
113
|
+
rewriteRemoteUrl(_repoId: string, originalUrl: string, useProxy?: boolean): string;
|
|
114
|
+
/**
|
|
115
|
+
* `git clone <proxyUrl> <localPath>` — initialize a new local repo
|
|
116
|
+
* from the proxy. Returns when the clone succeeds; throws on failure.
|
|
117
|
+
*
|
|
118
|
+
* When `branch` is provided, the clone is restricted to that branch
|
|
119
|
+
* via `git clone -b <branch> -- <proxyUrl> <localPath>` so the local
|
|
120
|
+
* checkout lands on the configured `repo.branch` instead of the
|
|
121
|
+
* upstream default branch. The parameter is optional and backward
|
|
122
|
+
* compatible — omitting it keeps the original behaviour.
|
|
123
|
+
*/
|
|
124
|
+
clone(repoId: string, originalUrl: string, localPath: string, branch?: string, useProxy?: boolean): Promise<void>;
|
|
125
|
+
/**
|
|
126
|
+
* `git fetch <remote> <branch>` + return the resulting commit SHA.
|
|
127
|
+
* Operates on an already-cloned repo at `localPath`.
|
|
128
|
+
*
|
|
129
|
+
* When `branch` is provided, the pull target is forced to that branch:
|
|
130
|
+
* if the local working tree is on a different branch, `git checkout
|
|
131
|
+
* <branch>` is issued first (git auto-tracks `origin/<branch>`), so
|
|
132
|
+
* the sync leaves the repo parked on the configured `repo.branch`.
|
|
133
|
+
* When `branch` is omitted the legacy behaviour is preserved — the
|
|
134
|
+
* current local branch is fast-forwarded. The parameter is optional
|
|
135
|
+
* and backward compatible.
|
|
136
|
+
*/
|
|
137
|
+
pull(repoId: string, localPath: string, branch?: string, useProxy?: boolean, originalUrl?: string): Promise<PullResult>;
|
|
138
|
+
/**
|
|
139
|
+
* `git push origin <branch>` via the proxy. Caller is responsible
|
|
140
|
+
* for committing locally first. The server's GitProxy injects the
|
|
141
|
+
* PAT on the way upstream.
|
|
142
|
+
*/
|
|
143
|
+
push(repoId: string, localPath: string, branch: string, useProxy?: boolean): Promise<PushResult>;
|
|
144
|
+
/**
|
|
145
|
+
* `git ls-remote <proxyUrl>` — list advertised branches without
|
|
146
|
+
* cloning. Used by addUserRepo to detect the default branch.
|
|
147
|
+
*/
|
|
148
|
+
lsRemote(repoId: string, originalUrl: string, useProxy?: boolean): Promise<RemoteBranch[]>;
|
|
149
|
+
/**
|
|
150
|
+
* Fetch an exact commit and detach HEAD at it. Used by workspace
|
|
151
|
+
* content restoration, which must never silently advance to a branch
|
|
152
|
+
* head. Returns the verified commit SHA.
|
|
153
|
+
*/
|
|
154
|
+
checkoutCommit(localPath: string, commit: string, repoId: string, useProxy?: boolean, originalUrl?: string): Promise<string>;
|
|
155
|
+
/**
|
|
156
|
+
* Resolve a repo-relative path inside the git directory using
|
|
157
|
+
* `git rev-parse --git-path`, which handles linked worktrees and
|
|
158
|
+
* submodules correctly (their metadata does not live under
|
|
159
|
+
* `<worktree>/.git` as a directory).
|
|
160
|
+
*/
|
|
161
|
+
gitPath(localPath: string, pathspec: string): Promise<string>;
|
|
162
|
+
/**
|
|
163
|
+
* Resolve the current HEAD commit of a local clone. Returns an empty
|
|
164
|
+
* string when git cannot resolve it (e.g. an empty repository) so
|
|
165
|
+
* callers can decide how to surface the failure.
|
|
166
|
+
*/
|
|
167
|
+
revParseHead(localPath: string): Promise<string>;
|
|
168
|
+
/**
|
|
169
|
+
* `git add <pathspec…>` followed by `git commit -m <message>`. The
|
|
170
|
+
* commit message convention follows the spec: `feat(skills): add
|
|
171
|
+
* <name>` / `feat(agents): add <name>`.
|
|
172
|
+
*/
|
|
173
|
+
commit(localPath: string, message: string, addPath?: string): Promise<{
|
|
174
|
+
commitSha: string;
|
|
175
|
+
}>;
|
|
176
|
+
private runOrThrow;
|
|
177
|
+
private getRemoteUrl;
|
|
178
|
+
private safeRevParse;
|
|
179
|
+
private currentBranch;
|
|
180
|
+
}
|
|
181
|
+
declare class NodeGitSpawner implements GitSpawner {
|
|
182
|
+
spawn(args: string[], opts: {
|
|
183
|
+
cwd?: string;
|
|
184
|
+
}): Promise<GitSpawnResult>;
|
|
185
|
+
}
|
|
186
|
+
/** Convenience: a record-based stub spawner for tests. */
|
|
187
|
+
declare class StubGitSpawner implements GitSpawner {
|
|
188
|
+
/** queue of canned responses, consumed FIFO per spawn() call. */
|
|
189
|
+
readonly script: GitSpawnResult[];
|
|
190
|
+
/** All spawn() invocations, in order, for assertions. */
|
|
191
|
+
readonly calls: Array<{
|
|
192
|
+
args: string[];
|
|
193
|
+
cwd: string | undefined;
|
|
194
|
+
}>;
|
|
195
|
+
constructor(script: GitSpawnResult[]);
|
|
196
|
+
spawn(args: string[], opts: {
|
|
197
|
+
cwd?: string;
|
|
198
|
+
}): Promise<GitSpawnResult>;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Helper: encode a bare absolute file URL (`file:///...`) for local
|
|
202
|
+
* git clone tests. Not used by GitClient directly — exposed for
|
|
203
|
+
* RepoManager's `localSeed` use case.
|
|
204
|
+
*/
|
|
205
|
+
declare function toFileUrl(absolutePath: string): string;
|
|
206
|
+
/** Path suffix appended to a server base URL to reach its git-proxy route. */
|
|
207
|
+
declare const GIT_PROXY_PATH_SUFFIX = "/git-proxy";
|
|
208
|
+
/**
|
|
209
|
+
* Single source of truth for deriving a {@link GitClientOptions.serverProxyBase}
|
|
210
|
+
* from an already-resolved, non-empty server base URL (e.g. the extension's
|
|
211
|
+
* verified marketplace server). Callers that derive `serverProxyBase` from a
|
|
212
|
+
* known server base URL — extension bootstrap, the sync scheduler, the CLI
|
|
213
|
+
* bridge subprocess env — should go through this helper instead of
|
|
214
|
+
* re-deriving the `/git-proxy` suffix locally, so the route contract only
|
|
215
|
+
* lives in one place. (Standalone CLI defaults such as
|
|
216
|
+
* `http://127.0.0.1:3000/git-proxy`, used when no server base URL is known
|
|
217
|
+
* at all, are a separate concern and don't go through this helper.)
|
|
218
|
+
*
|
|
219
|
+
* Callers MUST guard against an empty/falsy `serverBaseUrl` before calling —
|
|
220
|
+
* this function does not validate its input and will happily return the
|
|
221
|
+
* non-URL `"/git-proxy"` for an empty string.
|
|
222
|
+
*/
|
|
223
|
+
declare function buildGitProxyBase(serverBaseUrl: string): string;
|
|
224
|
+
//#endregion
|
|
225
|
+
//#region src/submit/types.d.ts
|
|
226
|
+
/**
|
|
227
|
+
* Skill & Agent v2 — SubmitClient Types (M4)
|
|
228
|
+
*
|
|
229
|
+
* Mirrors the server's POST /api/v1/skills/validate contract (M2
|
|
230
|
+
* SubmitApi). Defined here as a separate types file so the test
|
|
231
|
+
* fixtures + the client can both import without circular deps.
|
|
232
|
+
*/
|
|
233
|
+
/** Reasons the server may deny a submission. */
|
|
234
|
+
type DenyReason = "repo_not_writable" | "file_too_large" | "path_traversal" | "invalid_frontmatter" | "name_conflict" |
|
|
235
|
+
/** Local-client-side errors that don't come from the server. */
|
|
236
|
+
"network_error" | "write_error" | "commit_error" | "push_error" | "unknown";
|
|
237
|
+
/** Request payload. Identical to the server's SubmitValidationRequest. */
|
|
238
|
+
interface SubmitValidationRequest {
|
|
239
|
+
repoId: string;
|
|
240
|
+
skillName: string;
|
|
241
|
+
files: Array<{
|
|
242
|
+
path: string;
|
|
243
|
+
content: string;
|
|
244
|
+
}>;
|
|
245
|
+
}
|
|
246
|
+
/** Response payload. Identical to the server's SubmitValidationResponse. */
|
|
247
|
+
interface SubmitValidationResponse {
|
|
248
|
+
allow: boolean;
|
|
249
|
+
reason?: DenyReason;
|
|
250
|
+
detail?: string;
|
|
251
|
+
}
|
|
252
|
+
/** Sentinel error thrown by SubmitClient.submit() / validate(). */
|
|
253
|
+
declare class SubmitError extends Error {
|
|
254
|
+
readonly reason: DenyReason;
|
|
255
|
+
readonly detail: string;
|
|
256
|
+
readonly status?: number;
|
|
257
|
+
constructor(reason: DenyReason, detail: string, options?: {
|
|
258
|
+
status?: number;
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
//#endregion
|
|
262
|
+
//#region src/submit/index.d.ts
|
|
263
|
+
/**
|
|
264
|
+
* Skill & Agent v2 — SubmitClient (M4)
|
|
265
|
+
*
|
|
266
|
+
* SubmitClient orchestrates the "validate then push" flow described
|
|
267
|
+
* in docs/architecture/skill-agent-v2-repo.md §5.7:
|
|
268
|
+
*
|
|
269
|
+
* 1. **validate** — POST the candidate files to the server's
|
|
270
|
+
* `/api/v1/skills/validate` endpoint (5 deny reasons: repo_not_
|
|
271
|
+
* writable, file_too_large, path_traversal, invalid_frontmatter,
|
|
272
|
+
* name_conflict).
|
|
273
|
+
* 2. **write** — materialize the files into the local repo clone at
|
|
274
|
+
* `~/.serviceme/repos/<repoId>/skills/<name>/` (or `agents/`).
|
|
275
|
+
* 3. **commit** — `git add . && git commit -m "feat(skills): add <name>"`.
|
|
276
|
+
* 4. **push** — `git push origin <branch>` via the server proxy.
|
|
277
|
+
*
|
|
278
|
+
* The client is intentionally thin: it does NOT do its own validation
|
|
279
|
+
* (the server is the gate), and it does NOT cache anything across
|
|
280
|
+
* calls. The single source of truth for "is this submission allowed?"
|
|
281
|
+
* is the server's validate endpoint.
|
|
282
|
+
*
|
|
283
|
+
* @see docs/architecture/skill-agent-v2-repo.md §5.7 SubmitClient
|
|
284
|
+
*/
|
|
285
|
+
interface SubmitOptions {
|
|
286
|
+
/** Override the server's validate URL. Defaults to `http://localhost:3000/api/v1`. */
|
|
287
|
+
serverBaseUrl?: string;
|
|
288
|
+
/** Override the branch to push. Defaults to the repo's `branch` field. */
|
|
289
|
+
branch?: string;
|
|
290
|
+
/** Skip the actual push (for tests + dry-runs). When true, step 4 returns a synthetic PushResult. */
|
|
291
|
+
skipPush?: boolean;
|
|
292
|
+
}
|
|
293
|
+
interface SubmitResult {
|
|
294
|
+
repoId: string;
|
|
295
|
+
skillName: string;
|
|
296
|
+
commitSha: string;
|
|
297
|
+
pushedRef?: string;
|
|
298
|
+
pushedSha?: string;
|
|
299
|
+
}
|
|
300
|
+
interface SubmitClientOptions {
|
|
301
|
+
gitClient: GitClient;
|
|
302
|
+
/** Lookup the default branch for a repo (config-driven). */
|
|
303
|
+
getRepoBranch?: (repoId: string) => string | undefined;
|
|
304
|
+
/** HTTP fetch impl (defaults to the global `fetch`). */
|
|
305
|
+
fetcher?: typeof fetch;
|
|
306
|
+
/** Default server base URL when no override is supplied. */
|
|
307
|
+
defaultServerBaseUrl?: string;
|
|
308
|
+
}
|
|
309
|
+
declare class SubmitClient {
|
|
310
|
+
private readonly git;
|
|
311
|
+
private readonly getRepoBranch;
|
|
312
|
+
private readonly fetcher;
|
|
313
|
+
private readonly defaultServerBaseUrl;
|
|
314
|
+
constructor(opts: SubmitClientOptions);
|
|
315
|
+
/**
|
|
316
|
+
* Validate-only path. Useful for the UI's "Save Draft" flow which
|
|
317
|
+
* wants to surface validation errors without committing or pushing.
|
|
318
|
+
*/
|
|
319
|
+
validate(req: SubmitValidationRequest): Promise<SubmitValidationResponse>;
|
|
320
|
+
/**
|
|
321
|
+
* Full submit pipeline. Throws `SubmitError` on:
|
|
322
|
+
* - validate deny (reason echoed)
|
|
323
|
+
* - network failure (network_error)
|
|
324
|
+
* - local write failure
|
|
325
|
+
* - commit/push failure
|
|
326
|
+
*/
|
|
327
|
+
submit(repoId: string, skillName: string, files: SkillFile[], opts?: SubmitOptions): Promise<SubmitResult>;
|
|
328
|
+
}
|
|
329
|
+
//#endregion
|
|
330
|
+
export { SubmitError as a, NodeGitSpawner as c, toFileUrl as d, GitError as f, SubmitResult as i, StubGitSpawner as l, SubmitClientOptions as n, GIT_PROXY_PATH_SUFFIX as o, PullResult as p, SubmitOptions as r, GitClient as s, SubmitClient as t, buildGitProxyBase as u };
|
|
331
|
+
//# sourceMappingURL=index-Dp6FwWKh.d.ts.map
|