@nospt/plugin-dev-ai-hub-common 0.2.4 → 0.3.1

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/index.cjs.js CHANGED
@@ -1,13 +1,39 @@
1
1
  'use strict';
2
2
 
3
- var schemas = require('./schemas.cjs.js');
4
- var installPaths = require('./installPaths.cjs.js');
3
+ var resources = require('./resources.cjs.js');
4
+ var telemetry = require('./telemetry.cjs.js');
5
5
 
6
6
 
7
7
 
8
- exports.AiAssetFrontmatterSchema = schemas.AiAssetFrontmatterSchema;
9
- exports.AiToolEnum = schemas.AiToolEnum;
10
- exports.AssetTypeEnum = schemas.AssetTypeEnum;
11
- exports.getInstallPath = installPaths.getInstallPath;
12
- exports.getInstallPathsForAsset = installPaths.getInstallPathsForAsset;
8
+ exports.AGENT_LINK_CAPABLE_FRAMEWORKS = resources.AGENT_LINK_CAPABLE_FRAMEWORKS;
9
+ exports.ANNOTATION_COMPATIBLE_FRAMEWORKS = resources.ANNOTATION_COMPATIBLE_FRAMEWORKS;
10
+ exports.ANNOTATION_HELP = resources.ANNOTATION_HELP;
11
+ exports.ANNOTATION_VERSION = resources.ANNOTATION_VERSION;
12
+ exports.DEVAIHUB_ANNOTATION_PREFIX = resources.DEVAIHUB_ANNOTATION_PREFIX;
13
+ exports.INSTALLABLE_FRAMEWORKS = resources.INSTALLABLE_FRAMEWORKS;
14
+ exports.KNOWN_FRAMEWORKS = resources.KNOWN_FRAMEWORKS;
15
+ exports.MARKETPLACE_CAPABLE_FRAMEWORKS = resources.MARKETPLACE_CAPABLE_FRAMEWORKS;
16
+ exports.MCP_LINK_CAPABLE_FRAMEWORKS = resources.MCP_LINK_CAPABLE_FRAMEWORKS;
17
+ exports.PROMPT_LINK_CAPABLE_FRAMEWORKS = resources.PROMPT_LINK_CAPABLE_FRAMEWORKS;
18
+ exports.RESOURCE_TYPES = resources.RESOURCE_TYPES;
19
+ exports.RESOURCE_TYPE_REGISTRY = resources.RESOURCE_TYPE_REGISTRY;
20
+ exports.expandInstallFrameworks = resources.expandInstallFrameworks;
21
+ exports.getAgentInstallLinks = resources.getAgentInstallLinks;
22
+ exports.getBodyShape = resources.getBodyShape;
23
+ exports.getFrameworks = resources.getFrameworks;
24
+ exports.getInstallSteps = resources.getInstallSteps;
25
+ exports.getMarketplaceAddCommands = resources.getMarketplaceAddCommands;
26
+ exports.getMarketplaceInstallTemplate = resources.getMarketplaceInstallTemplate;
27
+ exports.getMarketplaceRepoSlug = resources.getMarketplaceRepoSlug;
28
+ exports.getMarketplaceTeamSnippet = resources.getMarketplaceTeamSnippet;
29
+ exports.getMcpInstallLinks = resources.getMcpInstallLinks;
30
+ exports.getPromptInstallLinks = resources.getPromptInstallLinks;
31
+ exports.getResourceInstallTarget = resources.getResourceInstallTarget;
32
+ exports.hasCopyableBody = resources.hasCopyableBody;
33
+ exports.hasDownloadableArtifact = resources.hasDownloadableArtifact;
34
+ exports.isResourceType = resources.isResourceType;
35
+ exports.normalizeFramework = resources.normalizeFramework;
36
+ exports.resolveCapableFrameworks = resources.resolveCapableFrameworks;
37
+ exports.TelemetryActionEnum = telemetry.TelemetryActionEnum;
38
+ exports.TelemetryEventInputSchema = telemetry.TelemetryEventInputSchema;
13
39
  //# sourceMappingURL=index.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;"}
1
+ {"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/dist/index.d.ts CHANGED
@@ -1,179 +1,322 @@
1
1
  import { z } from 'zod';
2
2
 
3
- type AssetType = 'instruction' | 'agent' | 'skill' | 'workflow';
4
- type AiTool = 'all' | 'github-copilot' | 'claude-code' | 'google-gemini' | 'cursor';
5
- /** Lightweight summary returned by list endpoints — no markdown content. */
6
- interface AiAssetSummary {
7
- id: string;
8
- providerId: string;
9
- name: string;
10
- /** Human-readable display name. Falls back to `name` when not set. */
11
- label?: string;
12
- description: string;
13
- type: AssetType;
14
- tools: AiTool[];
15
- tags: string[];
16
- author: string;
17
- icon?: string;
18
- version: string;
19
- installCount: number;
20
- syncedAt: string;
21
- createdAt: string;
22
- updatedAt: string;
3
+ /**
4
+ * The v2 read contract: AiResource vocabulary, the flat ResourceSummary
5
+ * returned by the backend, and the shared framework resolver (ADR-0003).
6
+ *
7
+ * The legacy asset-model types in `types.ts` coexist with this module until
8
+ * the legacy silo is deleted (slice 8, issue #34).
9
+ */
10
+ /** The six canonical `spec.type` values of an AiResource (ADR-0003, ADR-0010). */
11
+ declare const RESOURCE_TYPES: readonly ["skill", "agent", "hook", "mcp-config", "plugin", "marketplace"];
12
+ type ResourceType = (typeof RESOURCE_TYPES)[number];
13
+ declare function isResourceType(value: unknown): value is ResourceType;
14
+ /** Annotation prefix owned by DevAI Hub. */
15
+ declare const DEVAIHUB_ANNOTATION_PREFIX = "devaihub.io";
16
+ /** Comma-separated compatible-framework tokens (non-skill read path, ADR-0003). */
17
+ declare const ANNOTATION_COMPATIBLE_FRAMEWORKS = "devaihub.io/compatible-frameworks";
18
+ /** Optional semantic version string, displayed on cards. */
19
+ declare const ANNOTATION_VERSION = "devaihub.io/version";
20
+ /** Optional free-form help text shown on the detail panel. */
21
+ declare const ANNOTATION_HELP = "devaihub.io/help";
22
+ /** Known framework tokens; unknown tokens pass through as-is (ADR-0003). */
23
+ declare const KNOWN_FRAMEWORKS: readonly ["github-copilot", "claude-code", "cursor", "google-gemini", "all"];
24
+ type FrameworkToken = (typeof KNOWN_FRAMEWORKS)[number];
25
+ /**
26
+ * Normalise a framework token: trim, lowercase, resolve aliases
27
+ * (`claude` → `claude-code`). Unknown tokens pass through literally.
28
+ */
29
+ declare function normalizeFramework(token: string): string;
30
+ /**
31
+ * The minimal structural shape of an AiResource entity that the read helpers
32
+ * need. A real `@backstage/catalog-model` `Entity` satisfies it, but keeping
33
+ * the shape local means `-common` (and therefore the frontend) never depends
34
+ * on catalog packages (architecture.md).
35
+ */
36
+ interface AiResourceEntityLike {
37
+ metadata: {
38
+ annotations?: Record<string, string>;
39
+ };
40
+ spec?: {
41
+ type?: unknown;
42
+ /** Native skill subtype field: compatible frameworks. */
43
+ agents?: unknown;
44
+ [key: string]: unknown;
45
+ };
23
46
  }
24
- interface AiAsset {
25
- id: string;
26
- providerId: string;
27
- name: string;
28
- /** Human-readable display name. Falls back to `name` when not set. */
29
- label?: string;
30
- description: string;
31
- type: AssetType;
32
- tools: AiTool[];
33
- tags: string[];
34
- author: string;
35
- icon?: string;
36
- version: string;
37
- /** Override the install path for all tools */
38
- installPath?: string;
39
- /** Override the install path per tool */
40
- installPaths?: Record<string, string>;
41
- /** Pure markdown content from the .md file, never modified */
42
- content: string;
43
- /** Raw YAML of the metadata file */
44
- yamlRaw: string;
45
- /** Extra metadata stored from the envelope (e.g. resources for skills) */
46
- metadata?: Record<string, unknown>;
47
+ /**
48
+ * Resolve the compatible frameworks of an AiResource (ADR-0003):
49
+ * 1. `skill` with a non-empty `spec.agents` → the native field;
50
+ * 2. otherwise → the `devaihub.io/compatible-frameworks` annotation
51
+ * (also the fallback for a skill whose `spec.agents` is empty/absent);
52
+ * 3. otherwise → `[]`.
53
+ * Tokens are normalised; unknown tokens pass through.
54
+ */
55
+ declare function getFrameworks(entity: AiResourceEntityLike): string[];
56
+ /**
57
+ * Icon identifiers for the type→card registry. `-common` is imported by the
58
+ * backend, so it stays React-free: the frontend maps these identifiers to
59
+ * actual icon components.
60
+ */
61
+ type ResourceTypeIcon = 'tools' | 'robot' | 'flash' | 'plug' | 'puzzle' | 'store';
62
+ interface ResourceTypeInfo {
63
+ type: ResourceType;
64
+ /** Singular display label, e.g. "Skill" (card type caption). */
65
+ label: string;
66
+ /** Plural display label, e.g. "Skills" (stat tiles, filters). */
67
+ pluralLabel: string;
68
+ /** Icon identifier resolved to a component by the frontend. */
69
+ icon: ResourceTypeIcon;
47
70
  /**
48
- * Content of bundled resource files for skills (path → file content).
49
- * Only populated for assets of type `skill` that declare `resources` in the envelope.
71
+ * Colour role name; the frontend resolves it to the plugin-owned
72
+ * `--devaihub-type-<role>` custom properties (ADR-0008, NOS palette).
50
73
  */
51
- resourcesContent?: Record<string, string>;
52
- /** Path of the .yaml file in the repository */
53
- yamlPath: string;
54
- /** Path of the .md file in the repository */
55
- mdPath: string;
56
- repoUrl: string;
57
- branch: string;
58
- commitSha?: string;
59
- installCount: number;
60
- syncedAt: string;
61
- createdAt: string;
62
- updatedAt: string;
74
+ colorRole: ResourceType;
63
75
  }
64
- interface AiAssetListResponse {
65
- items: AiAssetSummary[];
66
- totalCount: number;
67
- page: number;
68
- pageSize: number;
76
+ /**
77
+ * The typed type→card registry (ADR-0003/ADR-0008): producer vocabulary and
78
+ * consumer rendering share this single source, so they cannot drift. Adding
79
+ * a type is one entry here plus one CSS token pair in the frontend.
80
+ */
81
+ declare const RESOURCE_TYPE_REGISTRY: Record<ResourceType, ResourceTypeInfo>;
82
+ /**
83
+ * The flat contract the backend returns to the frontend. The frontend never
84
+ * sees a raw Backstage `Entity` — only this (architecture.md).
85
+ */
86
+ interface ResourceSummary {
87
+ entityRef: string;
88
+ name: string;
89
+ title?: string;
90
+ description?: string;
91
+ tags: string[];
92
+ type: ResourceType;
93
+ lifecycle: string;
94
+ owner?: string;
95
+ sourceLocation?: string;
96
+ frameworks: string[];
97
+ version?: string;
98
+ kind: string;
99
+ /** `plugin` dependsOn count; unpopulated until containment lands (issue #32). */
100
+ childCount?: number;
101
+ helpText?: string;
102
+ annotations: Record<string, string>;
103
+ }
104
+ interface ResourceListResponse {
105
+ items: ResourceSummary[];
69
106
  }
70
- interface AiHubProvider {
71
- id: string;
72
- type: 'github' | 'bitbucket' | 'azure-devops' | 'gitlab' | 'git';
73
- target: string;
74
- branch: string;
75
- lastSync?: string;
76
- lastCommit?: string;
77
- status: 'idle' | 'syncing' | 'error';
78
- error?: string;
79
- assetCount: number;
107
+ /**
108
+ * The shape of a resource's body (CONTEXT.md: bodies are type-shaped, not
109
+ * uniformly markdown). Drives detail-panel rendering: markdown is rendered,
110
+ * json is shown as a copyable code block.
111
+ */
112
+ type BodyShape = 'markdown' | 'json';
113
+ declare function getBodyShape(type: ResourceType): BodyShape;
114
+ /**
115
+ * Whether downloading the body delivers the artifact itself. True for the
116
+ * types whose body IS the installable content (skill files, agent
117
+ * definition, hook/mcp-config config to merge). False for the pointer-shaped
118
+ * bodies: a `plugin` installs through its framework
119
+ * (`/plugin install name@marketplace`) and a `marketplace` is *registered*,
120
+ * not fetched — for both, a download could only deliver the instructions
121
+ * doc, misrepresenting itself as the thing (ADR-0009 amendment, ADR-0010).
122
+ */
123
+ declare function hasDownloadableArtifact(type: ResourceType): boolean;
124
+ /**
125
+ * Whether copying the body to the clipboard is a meaningful install action.
126
+ * False only for `marketplace`: its body is an instructions doc, and the
127
+ * actionable copies (add command, team snippet) each carry their own copy
128
+ * button — a "Copy content" that delivers the doc misrepresents itself as
129
+ * the marketplace, mirroring the Download reasoning (ADR-0010). A `plugin`
130
+ * body keeps copy: it is the canonical per-framework install guidance.
131
+ */
132
+ declare function hasCopyableBody(type: ResourceType): boolean;
133
+ /**
134
+ * How a body reaches its install path.
135
+ *
136
+ * `drop-in` — the body becomes the file (or directory) at `path`, which is
137
+ * the resource's own; writing it touches nothing else.
138
+ *
139
+ * `merge` — `path` is a shared settings file the user already owns, and the
140
+ * body is a fragment to merge into it. The distinction is not cosmetic:
141
+ * following a `merge` target as if it were a `drop-in` overwrites the user's
142
+ * existing configuration, so the UI must never present the two identically.
143
+ */
144
+ type InstallMode = 'drop-in' | 'merge';
145
+ interface ResourceInstallTarget {
146
+ /** Workspace-relative path. */
147
+ path: string;
148
+ mode: InstallMode;
80
149
  }
81
- interface AiHubStats {
82
- totalAssets: number;
83
- byType: Record<AssetType, number>;
84
- byTool: Record<string, number>;
85
- byProvider: Record<string, number>;
86
- lastSync?: string;
150
+ /**
151
+ * The concrete framework tokens a body can be installed into — `all` is a
152
+ * wildcard over these, never a destination itself.
153
+ */
154
+ declare const INSTALLABLE_FRAMEWORKS: readonly ["claude-code", "github-copilot", "google-gemini", "cursor"];
155
+ /**
156
+ * Where a resource's body installs for one framework, and whether that path
157
+ * is the body's own file or a settings file to merge into. Returns
158
+ * `undefined` when the (type, framework) pair has no filesystem convention.
159
+ */
160
+ declare function getResourceInstallTarget(type: ResourceType, framework: string, name: string): ResourceInstallTarget | undefined;
161
+ /**
162
+ * The frameworks to show install paths for. An empty list means the resource
163
+ * declared no compatibility and gets the neutral `default` convention; `all`
164
+ * is a wildcard and expands to every installable host, so it never collapses
165
+ * to a single row — or, for types with no `default`, to no rows at all.
166
+ */
167
+ declare function expandInstallFrameworks(frameworks: string[]): string[];
168
+ /** Frameworks with a marketplace-add concept (Cursor/Gemini have none). */
169
+ declare const MARKETPLACE_CAPABLE_FRAMEWORKS: readonly ["claude-code", "github-copilot"];
170
+ /**
171
+ * Narrow a resource's declared frameworks to those a given journey can
172
+ * actually launch. A deep link is a claim about compatibility: offering
173
+ * "Install in Claude" for a resource that never declared `claude-code` tells
174
+ * the user something untrue about the resource.
175
+ *
176
+ * `all` and an empty list both mean "unrestricted" and expand to every
177
+ * capable host. Anything else is intersected, so a declared framework with no
178
+ * handler (Gemini) — or an unknown token — yields no links rather than
179
+ * silently widening to every host.
180
+ */
181
+ declare function resolveCapableFrameworks(declared: string[], capable: readonly string[]): string[];
182
+ /**
183
+ * Derive the `owner/repo` slug from a marketplace's `source-location`.
184
+ * GitHub URLs only — other hosts return `undefined` (body-only fallback).
185
+ */
186
+ declare function getMarketplaceRepoSlug(sourceLocation: string | undefined): string | undefined;
187
+ /**
188
+ * A one-click launcher for an add command: a custom-scheme URL that opens
189
+ * the host app with the command pre-filled in the prompt box. The host
190
+ * never auto-executes it — the user reviews and presses Enter — and an
191
+ * unregistered scheme is a harmless no-op, so these complement the copy
192
+ * button rather than replace it.
193
+ */
194
+ interface ResourceDeepLink {
195
+ /** Host application name; render as "Add in <label>" / "Install in <label>". */
196
+ label: string;
197
+ href: string;
87
198
  }
88
- interface AssetListFilter {
89
- type?: AssetType;
90
- tool?: string;
91
- tags?: string[];
92
- search?: string;
93
- providerId?: string;
94
- page?: number;
95
- pageSize?: number;
199
+ interface MarketplaceAddCommand {
200
+ framework: string;
201
+ command: string;
202
+ deepLinks: ResourceDeepLink[];
96
203
  }
97
-
98
- declare const AiToolEnum: z.ZodEnum<["all", "github-copilot", "claude-code", "google-gemini", "cursor"]>;
99
- declare const AssetTypeEnum: z.ZodEnum<["instruction", "agent", "skill", "workflow"]>;
100
- /**
101
- * Schema for the YAML metadata file (.yaml) that acts as an envelope.
102
- * The actual asset content lives in the referenced .md file.
103
- */
104
- declare const AiAssetFrontmatterSchema: z.ZodObject<{
105
- /** Path to the .md content file, relative to the .yaml file directory.
106
- * If omitted, the parser falls back to <same-name>.md by convention. */
107
- content: z.ZodOptional<z.ZodString>;
108
- name: z.ZodString;
109
- /** Human-readable display label shown in the UI. Falls back to `name` when omitted. */
110
- label: z.ZodOptional<z.ZodString>;
111
- description: z.ZodString;
112
- type: z.ZodEnum<["instruction", "agent", "skill", "workflow"]>;
113
- tools: z.ZodArray<z.ZodEnum<["all", "github-copilot", "claude-code", "google-gemini", "cursor"]>, "many">;
114
- tags: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
115
- author: z.ZodDefault<z.ZodOptional<z.ZodString>>;
116
- icon: z.ZodOptional<z.ZodString>;
117
- version: z.ZodDefault<z.ZodOptional<z.ZodString>>;
118
- updatedAt: z.ZodOptional<z.ZodString>;
119
- installPath: z.ZodOptional<z.ZodString>;
120
- installPaths: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
121
- resources: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
122
- }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
123
- /** Path to the .md content file, relative to the .yaml file directory.
124
- * If omitted, the parser falls back to <same-name>.md by convention. */
125
- content: z.ZodOptional<z.ZodString>;
126
- name: z.ZodString;
127
- /** Human-readable display label shown in the UI. Falls back to `name` when omitted. */
128
- label: z.ZodOptional<z.ZodString>;
129
- description: z.ZodString;
130
- type: z.ZodEnum<["instruction", "agent", "skill", "workflow"]>;
131
- tools: z.ZodArray<z.ZodEnum<["all", "github-copilot", "claude-code", "google-gemini", "cursor"]>, "many">;
132
- tags: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
133
- author: z.ZodDefault<z.ZodOptional<z.ZodString>>;
134
- icon: z.ZodOptional<z.ZodString>;
135
- version: z.ZodDefault<z.ZodOptional<z.ZodString>>;
136
- updatedAt: z.ZodOptional<z.ZodString>;
137
- installPath: z.ZodOptional<z.ZodString>;
138
- installPaths: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
139
- resources: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
140
- }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
141
- /** Path to the .md content file, relative to the .yaml file directory.
142
- * If omitted, the parser falls back to <same-name>.md by convention. */
143
- content: z.ZodOptional<z.ZodString>;
144
- name: z.ZodString;
145
- /** Human-readable display label shown in the UI. Falls back to `name` when omitted. */
146
- label: z.ZodOptional<z.ZodString>;
147
- description: z.ZodString;
148
- type: z.ZodEnum<["instruction", "agent", "skill", "workflow"]>;
149
- tools: z.ZodArray<z.ZodEnum<["all", "github-copilot", "claude-code", "google-gemini", "cursor"]>, "many">;
150
- tags: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
151
- author: z.ZodDefault<z.ZodOptional<z.ZodString>>;
152
- icon: z.ZodOptional<z.ZodString>;
153
- version: z.ZodDefault<z.ZodOptional<z.ZodString>>;
154
- updatedAt: z.ZodOptional<z.ZodString>;
155
- installPath: z.ZodOptional<z.ZodString>;
156
- installPaths: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
157
- resources: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
158
- }, z.ZodTypeAny, "passthrough">>;
159
- type AiAssetFrontmatter = z.infer<typeof AiAssetFrontmatterSchema>;
160
-
161
- interface InstallPathOverrides {
162
- /** Single path override — applies to all tools when installPaths has no entry for the tool */
163
- installPath?: string;
164
- /** Per-tool path overrides — highest priority */
165
- installPaths?: Record<string, string>;
204
+ /**
205
+ * The copyable marketplace-add command per compatible framework. `all`,
206
+ * unknown-only, or empty framework lists expand to every capable framework;
207
+ * frameworks without a marketplace concept produce no row.
208
+ *
209
+ * Claude Code carries a single deep link on the CLI's documented
210
+ * `claude-cli://open?q=` handler, which opens a Claude Code terminal
211
+ * session with the command pre-filled regardless of the user's editor.
212
+ *
213
+ * Copilot's CLI still has no URI scheme, but Copilot's *other* surface does:
214
+ * VS Code 1.113 ships `vscode://chat-plugin/add-marketplace?ref=`, which
215
+ * accepts a plain or base64 `owner/repo` and always shows a confirmation
216
+ * dialog before registering the marketplace (it also dedupes against the
217
+ * user's existing entries). So the Copilot row keeps its terminal command for
218
+ * CLI users *and* gains editor launchers, mirroring how `mcp-config` already
219
+ * maps `github-copilot` onto the VS Code stable/Insiders pair.
220
+ */
221
+ declare function getMarketplaceAddCommands(frameworks: string[], repoSlug: string): MarketplaceAddCommand[];
222
+ /** Frameworks with a one-click agent-install handler (Gemini has none). */
223
+ declare const AGENT_LINK_CAPABLE_FRAMEWORKS: readonly ["claude-code", "github-copilot", "cursor"];
224
+ /** Hosts reachable by a generic prompt URI — the only route for skill/hook. */
225
+ declare const PROMPT_LINK_CAPABLE_FRAMEWORKS: readonly ["claude-code", "cursor"];
226
+ /**
227
+ * One-click launchers for the types with no purpose-built install route —
228
+ * `skill` and `hook`. Both ride the generic prompt handlers, so the prompt
229
+ * names the *host's own* install path and respects its install mode: a `merge`
230
+ * target is asked to be merged into, never overwritten, so a launcher can
231
+ * never cost the user their existing settings.
232
+ *
233
+ * Returns `[]` when the source URL cannot be derived, or for hosts with no
234
+ * prompt route (Copilot, Gemini) — the path list and copy/download remain.
235
+ */
236
+ declare function getPromptInstallLinks(type: ResourceType, sourceLocation: string | undefined, name: string, frameworks?: string[]): ResourceDeepLink[];
237
+ /**
238
+ * Everything a single host needs to install a resource: where the body goes,
239
+ * the prompt that puts it there, and a launcher when the host has a URI to
240
+ * launch.
241
+ *
242
+ * `link` is absent for hosts with no prompt route — Copilot and Gemini. That
243
+ * absence is why the step carries `prompt` as text: a host without a URI is
244
+ * not a host without an install path, and the same instruction that a launcher
245
+ * would pre-fill can be pasted into that agent by hand. Every declared
246
+ * framework therefore gets something actionable, not a bare path.
247
+ */
248
+ interface ResourceInstallStep {
249
+ framework: string;
250
+ target: ResourceInstallTarget;
251
+ /** The install instruction, ready to run in that host's agent. */
252
+ prompt: string;
253
+ /** One-click launcher, where the host exposes a generic prompt URI. */
254
+ link?: ResourceDeepLink;
166
255
  }
256
+ declare function getInstallSteps(type: ResourceType, sourceLocation: string | undefined, name: string, frameworks?: string[]): ResourceInstallStep[];
257
+ /** Frameworks with a one-click MCP-install handler (Gemini has none). */
258
+ declare const MCP_LINK_CAPABLE_FRAMEWORKS: readonly ["claude-code", "github-copilot", "cursor"];
167
259
  /**
168
- * Returns the recommended install path for an asset in a given tool's workspace.
169
- * Resolution order: installPaths[tool] > installPath > built-in convention.
260
+ * One-click install links for an `agent` resource, restricted to the
261
+ * resource's own compatible frameworks. VS Code stable and Insiders use the
262
+ * native `chat-agent/install?url=` handler (the mechanism behind
263
+ * awesome-copilot's Install buttons) and are Copilot's hosts, so they follow
264
+ * `github-copilot`: VS Code downloads the file at `url` and asks the user
265
+ * where to save it. Claude Code uses the `claude-cli://open?q=` handler with
266
+ * an install prompt pre-filled to the convention path — reviewed and sent by
267
+ * the user, never auto-executed. All derive from the GitHub blob URL in
268
+ * `source-location`; anything else returns `[]` (copy/download fallback).
170
269
  */
171
- declare function getInstallPath(type: AssetType, tool: AiTool | string, name: string, overrides?: InstallPathOverrides): string;
270
+ declare function getAgentInstallLinks(sourceLocation: string | undefined, name: string, frameworks?: string[]): ResourceDeepLink[];
271
+ /**
272
+ * One-click install links for an `mcp-config` resource, derived from its body —
273
+ * the canonical `.mcp.json` snippet (spec §3.4). VS Code carries a native
274
+ * `vscode:mcp/install?{json}` handler (Insiders scheme twin), Cursor a
275
+ * documented `cursor://anysphere.cursor-deeplink/mcp/install` one, and
276
+ * Claude Code gets a `claude-cli://open?q=` prompt around
277
+ * `claude mcp add-json` — pre-filled, reviewed, never auto-executed.
278
+ * Hosts follow the resource's own compatible frameworks: `all`/empty expand
279
+ * to every capable host, anything else is intersected, so an mcp-config
280
+ * declaring only Gemini (no handler) gets no links rather than every host's.
281
+ * A missing, unparseable, or multi-server body returns `[]` (copy fallback) —
282
+ * the body stays canonical, links are conveniences derived from it.
283
+ */
284
+ declare function getMcpInstallLinks(frameworks: string[], resourceName: string, bodyContent: string | undefined): ResourceDeepLink[];
285
+ /**
286
+ * Step two of the journey: how to install a plugin from the marketplace.
287
+ * `marketplaceName` is the entity name, which the producer contract requires
288
+ * to equal the `name` in `marketplace.json`.
289
+ */
290
+ declare function getMarketplaceInstallTemplate(marketplaceName: string): string;
291
+ /**
292
+ * The `.claude/settings.json` snippet a team commits so collaborators are
293
+ * prompted to install the marketplace automatically (Claude Code).
294
+ */
295
+ declare function getMarketplaceTeamSnippet(marketplaceName: string, repoSlug: string): string;
296
+
172
297
  /**
173
- * Returns install paths for all tools in the asset's tools list.
174
- * If tools contains 'all', returns paths for every known tool.
298
+ * Telemetry actions (ADR-0007). All four are stored raw and returned raw by
299
+ * `GET /telemetry/:ref` as lifetime totals. `view` is recorded when a user
300
+ * opens a resource, not when a card renders.
175
301
  */
176
- declare function getInstallPathsForAsset(type: AssetType, tools: (AiTool | string)[], name: string, overrides?: InstallPathOverrides): Record<string, string>;
302
+ declare const TelemetryActionEnum: z.ZodEnum<["install", "copy", "download", "view"]>;
303
+ type TelemetryAction = z.infer<typeof TelemetryActionEnum>;
304
+ declare const TelemetryEventInputSchema: z.ZodObject<{
305
+ ref: z.ZodString;
306
+ action: z.ZodEnum<["install", "copy", "download", "view"]>;
307
+ tool: z.ZodOptional<z.ZodString>;
308
+ }, "strip", z.ZodTypeAny, {
309
+ ref: string;
310
+ action: "install" | "copy" | "download" | "view";
311
+ tool?: string | undefined;
312
+ }, {
313
+ ref: string;
314
+ action: "install" | "copy" | "download" | "view";
315
+ tool?: string | undefined;
316
+ }>;
317
+ type TelemetryEventInput = z.infer<typeof TelemetryEventInputSchema>;
318
+ /** Raw per-action counts for one resource, as returned by `GET /telemetry/:ref`. */
319
+ type TelemetryCounts = Record<TelemetryAction, number>;
177
320
 
178
- export { AiAssetFrontmatterSchema, AiToolEnum, AssetTypeEnum, getInstallPath, getInstallPathsForAsset };
179
- export type { AiAsset, AiAssetFrontmatter, AiAssetListResponse, AiAssetSummary, AiHubProvider, AiHubStats, AiTool, AssetListFilter, AssetType, InstallPathOverrides };
321
+ export { AGENT_LINK_CAPABLE_FRAMEWORKS, ANNOTATION_COMPATIBLE_FRAMEWORKS, ANNOTATION_HELP, ANNOTATION_VERSION, DEVAIHUB_ANNOTATION_PREFIX, INSTALLABLE_FRAMEWORKS, KNOWN_FRAMEWORKS, MARKETPLACE_CAPABLE_FRAMEWORKS, MCP_LINK_CAPABLE_FRAMEWORKS, PROMPT_LINK_CAPABLE_FRAMEWORKS, RESOURCE_TYPES, RESOURCE_TYPE_REGISTRY, TelemetryActionEnum, TelemetryEventInputSchema, expandInstallFrameworks, getAgentInstallLinks, getBodyShape, getFrameworks, getInstallSteps, getMarketplaceAddCommands, getMarketplaceInstallTemplate, getMarketplaceRepoSlug, getMarketplaceTeamSnippet, getMcpInstallLinks, getPromptInstallLinks, getResourceInstallTarget, hasCopyableBody, hasDownloadableArtifact, isResourceType, normalizeFramework, resolveCapableFrameworks };
322
+ export type { AiResourceEntityLike, BodyShape, FrameworkToken, InstallMode, MarketplaceAddCommand, ResourceDeepLink, ResourceInstallStep, ResourceInstallTarget, ResourceListResponse, ResourceSummary, ResourceType, ResourceTypeIcon, ResourceTypeInfo, TelemetryAction, TelemetryCounts, TelemetryEventInput };
package/dist/index.esm.js CHANGED
@@ -1,3 +1,3 @@
1
- export { AiAssetFrontmatterSchema, AiToolEnum, AssetTypeEnum } from './schemas.esm.js';
2
- export { getInstallPath, getInstallPathsForAsset } from './installPaths.esm.js';
1
+ export { AGENT_LINK_CAPABLE_FRAMEWORKS, ANNOTATION_COMPATIBLE_FRAMEWORKS, ANNOTATION_HELP, ANNOTATION_VERSION, DEVAIHUB_ANNOTATION_PREFIX, INSTALLABLE_FRAMEWORKS, KNOWN_FRAMEWORKS, MARKETPLACE_CAPABLE_FRAMEWORKS, MCP_LINK_CAPABLE_FRAMEWORKS, PROMPT_LINK_CAPABLE_FRAMEWORKS, RESOURCE_TYPES, RESOURCE_TYPE_REGISTRY, expandInstallFrameworks, getAgentInstallLinks, getBodyShape, getFrameworks, getInstallSteps, getMarketplaceAddCommands, getMarketplaceInstallTemplate, getMarketplaceRepoSlug, getMarketplaceTeamSnippet, getMcpInstallLinks, getPromptInstallLinks, getResourceInstallTarget, hasCopyableBody, hasDownloadableArtifact, isResourceType, normalizeFramework, resolveCapableFrameworks } from './resources.esm.js';
2
+ export { TelemetryActionEnum, TelemetryEventInputSchema } from './telemetry.esm.js';
3
3
  //# sourceMappingURL=index.esm.js.map