@serviceme/devtools-core 0.1.8 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/auth.d.mts +590 -0
  2. package/dist/auth.d.ts +590 -0
  3. package/dist/auth.js +842 -0
  4. package/dist/auth.js.map +1 -0
  5. package/dist/auth.mjs +804 -0
  6. package/dist/auth.mjs.map +1 -0
  7. package/dist/device.d.mts +456 -0
  8. package/dist/device.d.ts +456 -0
  9. package/dist/device.js +696 -0
  10. package/dist/device.js.map +1 -0
  11. package/dist/device.mjs +647 -0
  12. package/dist/device.mjs.map +1 -0
  13. package/dist/index-CrNC-aao.d.ts +277 -0
  14. package/dist/index-Dmyy4urr.d.mts +277 -0
  15. package/dist/index.d.mts +1372 -27
  16. package/dist/index.d.ts +1372 -27
  17. package/dist/index.js +5125 -888
  18. package/dist/index.js.map +1 -0
  19. package/dist/index.mjs +5022 -906
  20. package/dist/index.mjs.map +1 -0
  21. package/dist/skill-linker.d.mts +188 -0
  22. package/dist/skill-linker.d.ts +188 -0
  23. package/dist/skill-linker.js +374 -0
  24. package/dist/skill-linker.js.map +1 -0
  25. package/dist/skill-linker.mjs +330 -0
  26. package/dist/skill-linker.mjs.map +1 -0
  27. package/dist/skill-store.d.mts +35 -0
  28. package/dist/skill-store.d.ts +35 -0
  29. package/dist/skill-store.js +291 -0
  30. package/dist/skill-store.js.map +1 -0
  31. package/dist/skill-store.mjs +254 -0
  32. package/dist/skill-store.mjs.map +1 -0
  33. package/dist/submit.d.mts +3 -0
  34. package/dist/submit.d.ts +3 -0
  35. package/dist/submit.js +166 -0
  36. package/dist/submit.js.map +1 -0
  37. package/dist/submit.mjs +130 -0
  38. package/dist/submit.mjs.map +1 -0
  39. package/dist/toolbox.d.mts +240 -0
  40. package/dist/toolbox.d.ts +240 -0
  41. package/dist/toolbox.js +530 -0
  42. package/dist/toolbox.js.map +1 -0
  43. package/dist/toolbox.mjs +482 -0
  44. package/dist/toolbox.mjs.map +1 -0
  45. package/dist/types-B9gk3dXH.d.mts +62 -0
  46. package/dist/types-B9gk3dXH.d.ts +62 -0
  47. package/package.json +50 -5
@@ -0,0 +1,188 @@
1
+ /**
2
+ * Skill & Agent v2 — Client SkillLinker (M3, path-parity revision)
3
+ *
4
+ * SkillLinker exposes a skill/agent from the user's global repos
5
+ * (`~/.serviceme/repos/<repoId>/{skills,agents}/<name>/`) into either:
6
+ *
7
+ * - a workspace, at `<workspace>/.github/{skills,agents}/<name>` —
8
+ * the same path Copilot/Claude actually scan for `SKILL.md` /
9
+ * `AGENT.md`, so linking here has real effect (see the v1 parity
10
+ * note below); or
11
+ * - the user's global scope, at `~/.agents/{skills,agents}/<name>`,
12
+ * visible to every workspace.
13
+ *
14
+ * **v1 parity note**: an earlier revision linked into a private
15
+ * `<workspace>/.serviceme/skills/<repoId>/<name>` directory. That path
16
+ * is never scanned by the actual tooling, so installs were silently
17
+ * inert. The path was moved to match `.github/skills` (the same
18
+ * location the legacy v1 marketplace pipeline used). Because the link
19
+ * path is now flat (no `<repoId>` segment), only one repo's version of
20
+ * a given `<name>` can be linked into a given scope at a time.
21
+ *
22
+ * Platform behavior (per spec §11.8 — owner explicitly chose throw
23
+ * over silent copy fallback):
24
+ *
25
+ * | platform | default mode | on failure |
26
+ * |----------|--------------|-----------------------------|
27
+ * | macOS | symlink | throw + platform hint |
28
+ * | Linux | symlink | throw + platform hint |
29
+ * | Windows | junction | throw + platform hint |
30
+ *
31
+ * Why junction first on Windows: NTFS junction doesn't require
32
+ * SeCreateSymbolicLinkPrivilege; it works for any user. The limit is
33
+ * the link target must be on a local NTFS volume. OneDrive / network
34
+ * shares sometimes fail; we surface that as a typed error so callers
35
+ * can decide whether to retry.
36
+ *
37
+ * @see docs/architecture/skill-agent-v2-repo.md §5.6 SkillLinker
38
+ * @see docs/architecture/skill-agent-v2-repo.md §11.8 (throw, not copy)
39
+ */
40
+ type LinkMode = "symlink" | "junction" | "copy";
41
+ /** Kind of artifact being linked. Mirrors `BridgeSkillKind`. */
42
+ type EntryKind = "skill" | "agent";
43
+ /**
44
+ * Which scope the link lives in:
45
+ * - `"workspace"` (default) → `<workspaceDir>/.github/<kind>/<name>`
46
+ * - `"user"` → `~/.agents/<kind>/<name>` (visible to every workspace)
47
+ */
48
+ type LinkScope = "workspace" | "user";
49
+ interface InstallSkillOptions {
50
+ repoId: string;
51
+ skillName: string;
52
+ workspaceDir: string;
53
+ /** Choose link mode explicitly. Defaults to platform-optimal. */
54
+ mode?: "auto" | LinkMode;
55
+ /** "skill" (default) or "agent". */
56
+ kind?: EntryKind;
57
+ /** "workspace" (default) or "user". */
58
+ scope?: LinkScope;
59
+ /**
60
+ * Pre-resolved absolute source path (from `SkillStore`), overriding
61
+ * the `<repoRoot>/{skills,agents}/<name>` formula in
62
+ * {@link resolveSkillTarget}. Required for repos with non-standard
63
+ * layouts — flat root (no `skills/` prefix), nested scope dirs
64
+ * (`skills/official/<name>`), or flat single-file agent manifests
65
+ * (`agents/<name>.agent.md`) — which the formula can't predict.
66
+ * When omitted, falls back to the formula (kept for callers that
67
+ * install a hand-authored skill without going through `SkillStore`).
68
+ */
69
+ sourcePath?: string;
70
+ /**
71
+ * True when `sourcePath` points at a single manifest FILE (e.g. a
72
+ * flat `<name>.agent.md`) rather than a directory. Determines the
73
+ * symlink type (file vs dir/junction) and the link's basename (the
74
+ * link mirrors the source file's name + extension, since Copilot/
75
+ * VS Code scan `.github/agents/<name>.agent.md` as a FILE).
76
+ */
77
+ sourceIsFile?: boolean;
78
+ }
79
+ interface InstallSkillResult {
80
+ mode: LinkMode;
81
+ linkPath: string;
82
+ targetPath: string;
83
+ }
84
+ /** Describes one symlink/junction currently present in a workspace/user scope. */
85
+ interface LinkedSkill {
86
+ /**
87
+ * Repo id the link resolves to, parsed back out of the symlink
88
+ * target. Empty string when the target isn't under a recognizable
89
+ * `~/.serviceme/repos/<repoId>/...` path.
90
+ */
91
+ repoId: string;
92
+ skillName: string;
93
+ linkPath: string;
94
+ targetPath: string;
95
+ mode: LinkMode;
96
+ /** Which scope this link was found in — "workspace" or "user" (global). */
97
+ scope: LinkScope;
98
+ }
99
+ /**
100
+ * Sentinel error for link failures. Carries the chosen mode + platform
101
+ * hint so the UI can render an actionable message.
102
+ */
103
+ declare class LinkError extends Error {
104
+ readonly mode: LinkMode;
105
+ readonly target: string;
106
+ readonly linkPath: string;
107
+ readonly platform: NodeJS.Platform;
108
+ readonly cause: unknown;
109
+ constructor(opts: {
110
+ mode: LinkMode;
111
+ target: string;
112
+ linkPath: string;
113
+ platform: NodeJS.Platform;
114
+ cause: unknown;
115
+ });
116
+ /** A user-facing hint for the platform that failed. */
117
+ hint(): string;
118
+ }
119
+ /** Choose the platform-optimal link mode. */
120
+ declare function pickMode(platform?: NodeJS.Platform): LinkMode;
121
+ /** A short hint string for the platform where the link failed. */
122
+ declare function getPlatformHint(platform: NodeJS.Platform): string;
123
+ /**
124
+ * Resolve the source path inside `~/.serviceme/repos/<repoId>/{skills,agents}/<name>`.
125
+ * Exported for callers that need to inspect the target without installing.
126
+ */
127
+ declare function resolveSkillTarget(repoId: string, skillName: string, kind?: EntryKind): string;
128
+ /**
129
+ * Resolve the workspace link path — `<workspaceDir>/.github/{skills,agents}/<name>` —
130
+ * the same directory Copilot/Claude actually scan.
131
+ */
132
+ declare function resolveSkillLinkPath(workspaceDir: string, skillName: string, kind?: EntryKind): string;
133
+ /**
134
+ * Resolve the user-scope link path — `~/.agents/{skills,agents}/<name>` —
135
+ * visible to every workspace.
136
+ */
137
+ declare function resolveUserSkillLinkPath(skillName: string, kind?: EntryKind): string;
138
+ /**
139
+ * Install a skill into a workspace by creating a link at the standard
140
+ * path. Throws `LinkError` on failure (no silent copy fallback per
141
+ * §11.8).
142
+ *
143
+ * Idempotent: if the correct link already exists, returns the existing
144
+ * record without touching the filesystem. If a *wrong* link exists at
145
+ * the target path, it is replaced.
146
+ */
147
+ declare function installSkillToWorkspace(opts: InstallSkillOptions): Promise<InstallSkillResult>;
148
+ /**
149
+ * Convert an existing, real (non-symlink) skill/agent directory at the
150
+ * standard scan path into a symlink pointing at the matching global
151
+ * repo entry. Refuses to run when there's nothing real to convert —
152
+ * callers should only surface this action when a marketplace/scope
153
+ * state check already confirmed a non-symlink install is present.
154
+ */
155
+ declare function convertToSymlink(opts: InstallSkillOptions): Promise<InstallSkillResult>;
156
+ /**
157
+ * Remove a skill/agent link from a workspace/user scope. Idempotent:
158
+ * succeeds when the link does not exist (no error).
159
+ *
160
+ * Tries the bare `<name>` path first (directory-based entries), then
161
+ * falls back to scanning the scope dir for a `<name>.<ext>` file (flat
162
+ * manifest entries, e.g. `CSharpExpert.agent.md`) — the caller doesn't
163
+ * necessarily still have the source repo entry to know which shape was
164
+ * installed (e.g. the repo may have been removed since).
165
+ */
166
+ declare function uninstallSkillFromWorkspace(opts: {
167
+ repoId: string;
168
+ skillName: string;
169
+ workspaceDir: string;
170
+ kind?: EntryKind;
171
+ scope?: LinkScope;
172
+ }): Promise<void>;
173
+ /**
174
+ * Enumerate all skill/agent entries currently present in a workspace/user
175
+ * scope — both symlinked installs (`mode: "symlink"`/`"junction"`) AND
176
+ * real, non-symlink directories/files that already carry a valid
177
+ * manifest (`mode: "copy"`). Used by the UI's "Manage installed skills"
178
+ * view so it can show a real (copy-installed) entry as installed too —
179
+ * this is common for the user (global) scope, where many skills are
180
+ * placed by other tools/installers as plain copies rather than via this
181
+ * package's symlink-only install flow. `repoId` is `""` for `"copy"`
182
+ * entries since there's no symlink target to resolve it from; callers
183
+ * match these by name only. Returns an empty array when the scan
184
+ * directory doesn't exist.
185
+ */
186
+ declare function listLinkedSkills(workspaceDir: string, kind?: EntryKind, scope?: LinkScope): Promise<LinkedSkill[]>;
187
+
188
+ export { type EntryKind, type InstallSkillOptions, type InstallSkillResult, LinkError, type LinkMode, type LinkScope, type LinkedSkill, convertToSymlink, getPlatformHint, installSkillToWorkspace, listLinkedSkills, pickMode, resolveSkillLinkPath, resolveSkillTarget, resolveUserSkillLinkPath, uninstallSkillFromWorkspace };
@@ -0,0 +1,188 @@
1
+ /**
2
+ * Skill & Agent v2 — Client SkillLinker (M3, path-parity revision)
3
+ *
4
+ * SkillLinker exposes a skill/agent from the user's global repos
5
+ * (`~/.serviceme/repos/<repoId>/{skills,agents}/<name>/`) into either:
6
+ *
7
+ * - a workspace, at `<workspace>/.github/{skills,agents}/<name>` —
8
+ * the same path Copilot/Claude actually scan for `SKILL.md` /
9
+ * `AGENT.md`, so linking here has real effect (see the v1 parity
10
+ * note below); or
11
+ * - the user's global scope, at `~/.agents/{skills,agents}/<name>`,
12
+ * visible to every workspace.
13
+ *
14
+ * **v1 parity note**: an earlier revision linked into a private
15
+ * `<workspace>/.serviceme/skills/<repoId>/<name>` directory. That path
16
+ * is never scanned by the actual tooling, so installs were silently
17
+ * inert. The path was moved to match `.github/skills` (the same
18
+ * location the legacy v1 marketplace pipeline used). Because the link
19
+ * path is now flat (no `<repoId>` segment), only one repo's version of
20
+ * a given `<name>` can be linked into a given scope at a time.
21
+ *
22
+ * Platform behavior (per spec §11.8 — owner explicitly chose throw
23
+ * over silent copy fallback):
24
+ *
25
+ * | platform | default mode | on failure |
26
+ * |----------|--------------|-----------------------------|
27
+ * | macOS | symlink | throw + platform hint |
28
+ * | Linux | symlink | throw + platform hint |
29
+ * | Windows | junction | throw + platform hint |
30
+ *
31
+ * Why junction first on Windows: NTFS junction doesn't require
32
+ * SeCreateSymbolicLinkPrivilege; it works for any user. The limit is
33
+ * the link target must be on a local NTFS volume. OneDrive / network
34
+ * shares sometimes fail; we surface that as a typed error so callers
35
+ * can decide whether to retry.
36
+ *
37
+ * @see docs/architecture/skill-agent-v2-repo.md §5.6 SkillLinker
38
+ * @see docs/architecture/skill-agent-v2-repo.md §11.8 (throw, not copy)
39
+ */
40
+ type LinkMode = "symlink" | "junction" | "copy";
41
+ /** Kind of artifact being linked. Mirrors `BridgeSkillKind`. */
42
+ type EntryKind = "skill" | "agent";
43
+ /**
44
+ * Which scope the link lives in:
45
+ * - `"workspace"` (default) → `<workspaceDir>/.github/<kind>/<name>`
46
+ * - `"user"` → `~/.agents/<kind>/<name>` (visible to every workspace)
47
+ */
48
+ type LinkScope = "workspace" | "user";
49
+ interface InstallSkillOptions {
50
+ repoId: string;
51
+ skillName: string;
52
+ workspaceDir: string;
53
+ /** Choose link mode explicitly. Defaults to platform-optimal. */
54
+ mode?: "auto" | LinkMode;
55
+ /** "skill" (default) or "agent". */
56
+ kind?: EntryKind;
57
+ /** "workspace" (default) or "user". */
58
+ scope?: LinkScope;
59
+ /**
60
+ * Pre-resolved absolute source path (from `SkillStore`), overriding
61
+ * the `<repoRoot>/{skills,agents}/<name>` formula in
62
+ * {@link resolveSkillTarget}. Required for repos with non-standard
63
+ * layouts — flat root (no `skills/` prefix), nested scope dirs
64
+ * (`skills/official/<name>`), or flat single-file agent manifests
65
+ * (`agents/<name>.agent.md`) — which the formula can't predict.
66
+ * When omitted, falls back to the formula (kept for callers that
67
+ * install a hand-authored skill without going through `SkillStore`).
68
+ */
69
+ sourcePath?: string;
70
+ /**
71
+ * True when `sourcePath` points at a single manifest FILE (e.g. a
72
+ * flat `<name>.agent.md`) rather than a directory. Determines the
73
+ * symlink type (file vs dir/junction) and the link's basename (the
74
+ * link mirrors the source file's name + extension, since Copilot/
75
+ * VS Code scan `.github/agents/<name>.agent.md` as a FILE).
76
+ */
77
+ sourceIsFile?: boolean;
78
+ }
79
+ interface InstallSkillResult {
80
+ mode: LinkMode;
81
+ linkPath: string;
82
+ targetPath: string;
83
+ }
84
+ /** Describes one symlink/junction currently present in a workspace/user scope. */
85
+ interface LinkedSkill {
86
+ /**
87
+ * Repo id the link resolves to, parsed back out of the symlink
88
+ * target. Empty string when the target isn't under a recognizable
89
+ * `~/.serviceme/repos/<repoId>/...` path.
90
+ */
91
+ repoId: string;
92
+ skillName: string;
93
+ linkPath: string;
94
+ targetPath: string;
95
+ mode: LinkMode;
96
+ /** Which scope this link was found in — "workspace" or "user" (global). */
97
+ scope: LinkScope;
98
+ }
99
+ /**
100
+ * Sentinel error for link failures. Carries the chosen mode + platform
101
+ * hint so the UI can render an actionable message.
102
+ */
103
+ declare class LinkError extends Error {
104
+ readonly mode: LinkMode;
105
+ readonly target: string;
106
+ readonly linkPath: string;
107
+ readonly platform: NodeJS.Platform;
108
+ readonly cause: unknown;
109
+ constructor(opts: {
110
+ mode: LinkMode;
111
+ target: string;
112
+ linkPath: string;
113
+ platform: NodeJS.Platform;
114
+ cause: unknown;
115
+ });
116
+ /** A user-facing hint for the platform that failed. */
117
+ hint(): string;
118
+ }
119
+ /** Choose the platform-optimal link mode. */
120
+ declare function pickMode(platform?: NodeJS.Platform): LinkMode;
121
+ /** A short hint string for the platform where the link failed. */
122
+ declare function getPlatformHint(platform: NodeJS.Platform): string;
123
+ /**
124
+ * Resolve the source path inside `~/.serviceme/repos/<repoId>/{skills,agents}/<name>`.
125
+ * Exported for callers that need to inspect the target without installing.
126
+ */
127
+ declare function resolveSkillTarget(repoId: string, skillName: string, kind?: EntryKind): string;
128
+ /**
129
+ * Resolve the workspace link path — `<workspaceDir>/.github/{skills,agents}/<name>` —
130
+ * the same directory Copilot/Claude actually scan.
131
+ */
132
+ declare function resolveSkillLinkPath(workspaceDir: string, skillName: string, kind?: EntryKind): string;
133
+ /**
134
+ * Resolve the user-scope link path — `~/.agents/{skills,agents}/<name>` —
135
+ * visible to every workspace.
136
+ */
137
+ declare function resolveUserSkillLinkPath(skillName: string, kind?: EntryKind): string;
138
+ /**
139
+ * Install a skill into a workspace by creating a link at the standard
140
+ * path. Throws `LinkError` on failure (no silent copy fallback per
141
+ * §11.8).
142
+ *
143
+ * Idempotent: if the correct link already exists, returns the existing
144
+ * record without touching the filesystem. If a *wrong* link exists at
145
+ * the target path, it is replaced.
146
+ */
147
+ declare function installSkillToWorkspace(opts: InstallSkillOptions): Promise<InstallSkillResult>;
148
+ /**
149
+ * Convert an existing, real (non-symlink) skill/agent directory at the
150
+ * standard scan path into a symlink pointing at the matching global
151
+ * repo entry. Refuses to run when there's nothing real to convert —
152
+ * callers should only surface this action when a marketplace/scope
153
+ * state check already confirmed a non-symlink install is present.
154
+ */
155
+ declare function convertToSymlink(opts: InstallSkillOptions): Promise<InstallSkillResult>;
156
+ /**
157
+ * Remove a skill/agent link from a workspace/user scope. Idempotent:
158
+ * succeeds when the link does not exist (no error).
159
+ *
160
+ * Tries the bare `<name>` path first (directory-based entries), then
161
+ * falls back to scanning the scope dir for a `<name>.<ext>` file (flat
162
+ * manifest entries, e.g. `CSharpExpert.agent.md`) — the caller doesn't
163
+ * necessarily still have the source repo entry to know which shape was
164
+ * installed (e.g. the repo may have been removed since).
165
+ */
166
+ declare function uninstallSkillFromWorkspace(opts: {
167
+ repoId: string;
168
+ skillName: string;
169
+ workspaceDir: string;
170
+ kind?: EntryKind;
171
+ scope?: LinkScope;
172
+ }): Promise<void>;
173
+ /**
174
+ * Enumerate all skill/agent entries currently present in a workspace/user
175
+ * scope — both symlinked installs (`mode: "symlink"`/`"junction"`) AND
176
+ * real, non-symlink directories/files that already carry a valid
177
+ * manifest (`mode: "copy"`). Used by the UI's "Manage installed skills"
178
+ * view so it can show a real (copy-installed) entry as installed too —
179
+ * this is common for the user (global) scope, where many skills are
180
+ * placed by other tools/installers as plain copies rather than via this
181
+ * package's symlink-only install flow. `repoId` is `""` for `"copy"`
182
+ * entries since there's no symlink target to resolve it from; callers
183
+ * match these by name only. Returns an empty array when the scan
184
+ * directory doesn't exist.
185
+ */
186
+ declare function listLinkedSkills(workspaceDir: string, kind?: EntryKind, scope?: LinkScope): Promise<LinkedSkill[]>;
187
+
188
+ export { type EntryKind, type InstallSkillOptions, type InstallSkillResult, LinkError, type LinkMode, type LinkScope, type LinkedSkill, convertToSymlink, getPlatformHint, installSkillToWorkspace, listLinkedSkills, pickMode, resolveSkillLinkPath, resolveSkillTarget, resolveUserSkillLinkPath, uninstallSkillFromWorkspace };