@hasna/skills 0.3.0 → 0.4.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.
@@ -87,7 +87,7 @@ export declare function getAuthConfigReadOnly(env?: Env, options?: SkillsFleetOp
87
87
  * Returns the file it wrote, so the CLI can name the real path rather than a
88
88
  * path it assumed.
89
89
  */
90
- export declare function saveAuthConfig(config: StoredAuthConfig, env?: Env): string;
90
+ export declare function saveAuthConfig(config: StoredAuthConfig, env?: Env, authenticatedOrigin?: string): string;
91
91
  /** Store (or clear, with null) the API URL beside the credential. */
92
92
  export declare function saveApiUrl(apiUrl: string | null, env?: Env): string;
93
93
  /** The API URL recorded in the credentials file, or null. */
@@ -114,7 +114,7 @@ export interface LocalSkillsFleet {
114
114
  }
115
115
  export type SkillsFleet = HostedSkillsFleet | LocalSkillsFleet;
116
116
  /** Machine-readable reasons a hosted resolution was refused. */
117
- export type SkillsFleetErrorCode = "MISSING_API_CREDENTIAL" | "INVALID_API_URL";
117
+ export type SkillsFleetErrorCode = "MISSING_API_CREDENTIAL" | "INVALID_API_URL" | "INSTANCE_CREDENTIAL_MISMATCH";
118
118
  /**
119
119
  * A configured install could not produce a usable hosted client.
120
120
  *
@@ -151,7 +151,7 @@ export interface ConfiguredSkillsApiUrl {
151
151
  * default apply for a credentialled install and what keeps an install with no
152
152
  * credential from naming a host at all.
153
153
  */
154
- export declare function configuredSkillsApiUrl(env?: Env, keychain?: KeychainTierOptions): ConfiguredSkillsApiUrl | null;
154
+ export declare function configuredSkillsApiUrl(env?: Env, keychain?: KeychainTierOptions, profile?: string): ConfiguredSkillsApiUrl | null;
155
155
  /** The credential file paths consulted, for a message that has to name them. */
156
156
  export declare function skillsCredentialFiles(env?: Env): string[];
157
157
  /**
@@ -193,6 +193,10 @@ export declare function resolveSkillsFleet(env?: Env, options?: SkillsFleetOptio
193
193
  * when a credential is configured and cannot be produced — never a fallback.
194
194
  */
195
195
  export declare function resolveSkillsApiKey(env?: Env, options?: SkillsFleetOptions): Promise<string | null>;
196
+ /** Resolve the URL and credential once, including any asynchronous vault lookup. */
197
+ export declare function resolveSkillsConnection(env?: Env, options?: SkillsFleetOptions): Promise<(HostedSkillsFleet & {
198
+ apiKey: string;
199
+ }) | null>;
196
200
  /** The usable API key, or throw naming what is missing. Use on every send path. */
197
201
  export declare function requireSkillsApiKey(action?: string, env?: Env, options?: SkillsFleetOptions): Promise<string>;
198
202
  /**
@@ -206,9 +210,11 @@ export declare function requireSkillsApiKey(action?: string, env?: Env, options?
206
210
  */
207
211
  export declare function skillsCredentialOrReason(env?: Env, options?: SkillsFleetOptions): Promise<{
208
212
  apiKey: string;
213
+ apiOrigin: string;
209
214
  reason: null;
210
215
  } | {
211
216
  apiKey: null;
217
+ apiOrigin: null;
212
218
  reason: string | null;
213
219
  }>;
214
220
  /**
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,13 @@
1
+ export declare const SKILLS_BOUND_API_URL = "HASNA_SKILLS_BOUND_API_URL";
2
+ type Env = Record<string, string | undefined>;
3
+ /** Match the shared resolver's profile syntax before using its path helper. */
4
+ export declare function selectedSkillsProfile(env: Env, explicit?: string): string | null;
5
+ export declare function skillsProfileCredentialFiles(env: Env, explicit?: string): string[];
6
+ /** Fence the released credential reader and this package's routing reads together. */
7
+ export declare function captureSkillsCredentialFiles(files: string[]): () => void;
8
+ /** Read only known non-secret routing fields, never export an API key or an arbitrary field. */
9
+ export declare function readSkillsInstanceMetadata(file: string): {
10
+ apiUrl?: string;
11
+ binding?: string;
12
+ };
13
+ export {};
@@ -9,6 +9,10 @@ export interface JsonSchemaObject {
9
9
  default?: unknown;
10
10
  format?: string;
11
11
  minimum?: number;
12
+ maximum?: number;
13
+ pattern?: string;
14
+ maxItems?: number;
15
+ maxLength?: number;
12
16
  items?: JsonSchemaObject;
13
17
  properties?: Record<string, JsonSchemaObject>;
14
18
  required?: string[];
@@ -22,10 +22,14 @@ export declare function parseSkillKind(value: string | undefined): SkillKind | u
22
22
  export declare function readDeclaredSkillVersion(skillPath: string): string | undefined;
23
23
  export declare function createInstructionManifest(name: string, options: {
24
24
  description: string;
25
+ category?: string;
26
+ tags?: string[];
25
27
  }): PortableSkillManifest;
26
28
  export declare function writeInstructionSkillTemplate(skillPath: string, manifest: PortableSkillManifest): void;
27
29
  export declare function createPortableManifest(name: string, options: {
28
30
  description: string;
31
+ category?: string;
32
+ tags?: string[];
29
33
  }): PortableSkillManifest;
30
34
  export declare function writePortableSkillTemplate(skillPath: string, manifest: PortableSkillManifest): void;
31
35
  /**
@@ -98,6 +98,8 @@ export interface PortableSkillOptions {
98
98
  }
99
99
  export interface ScaffoldPortableSkillOptions extends PortableSkillOptions {
100
100
  description?: string;
101
+ category?: string;
102
+ tags?: string[];
101
103
  overwrite?: boolean;
102
104
  kind?: SkillKind;
103
105
  }
@@ -0,0 +1,42 @@
1
+ import type { RemoteInputFileDescriptor } from "./remote-files.js";
2
+ /** Optional account APIs supplied by a configured Skills server. No local prices or provider policy. */
3
+ export interface RemoteRunQuote {
4
+ skill: string;
5
+ pricing: {
6
+ costCents: number;
7
+ formattedCost: string;
8
+ [key: string]: unknown;
9
+ };
10
+ [key: string]: unknown;
11
+ }
12
+ export interface RemoteRunApproval {
13
+ /** Preferred public spelling: maximum integer credits approved by the caller. */
14
+ maxCredits?: number;
15
+ /** Maximum integer credits approved by the caller (legacy wire spelling). */
16
+ maxCostCents?: number;
17
+ idempotencyKey?: string;
18
+ inputFiles?: RemoteInputFileDescriptor[];
19
+ }
20
+ export interface RemoteCreditPack {
21
+ id: string;
22
+ credits: number;
23
+ expiresInDays?: number;
24
+ }
25
+ export declare class RemoteCreditApprovalError extends Error {
26
+ readonly requiredCredits: number;
27
+ readonly maximumCredits: number;
28
+ readonly code = "CREDIT_APPROVAL_REQUIRED";
29
+ constructor(requiredCredits: number, maximumCredits: number);
30
+ }
31
+ export declare function creditCount(value: unknown): number;
32
+ export declare function parseRemoteRunQuote(value: unknown): RemoteRunQuote;
33
+ export declare function parseRemoteCreditPacks(value: unknown): RemoteCreditPack[];
34
+ export declare function parseRemoteBillingStatus(value: unknown): {
35
+ hasPaymentMethod?: boolean | undefined;
36
+ plan?: string | undefined;
37
+ creditBalance: number;
38
+ formattedCreditBalance: string;
39
+ };
40
+ export declare function parseRemoteCheckout(value: unknown): {
41
+ url: string;
42
+ };
@@ -0,0 +1,32 @@
1
+ export declare class HostedApiError extends Error {
2
+ readonly status?: number;
3
+ readonly code?: string;
4
+ readonly detail?: string;
5
+ readonly endpoint?: string;
6
+ readonly apiUrl?: string;
7
+ constructor(message: string, options?: {
8
+ status?: number;
9
+ code?: string;
10
+ detail?: string;
11
+ endpoint?: string;
12
+ apiUrl?: string;
13
+ });
14
+ }
15
+ /** Passwordless auth transport for an explicitly selected instance. It never writes credentials. */
16
+ export declare class RemoteSkillsAuthClient {
17
+ readonly apiOrigin: string;
18
+ constructor(apiUrl: string);
19
+ requestCode(email: string): Promise<any>;
20
+ verifyCode(email: string, code: string): Promise<any>;
21
+ startDevice(): Promise<any>;
22
+ pollDevice(deviceCode: string): Promise<any>;
23
+ private sessionClient;
24
+ createApiKey(email: string, code: string, name: string, scopes?: string[]): Promise<{
25
+ [field: string]: unknown;
26
+ key: string;
27
+ }>;
28
+ listApiKeys(email: string, code: string): Promise<Record<string, unknown>[]>;
29
+ revokeApiKey(email: string, code: string, keyId: string): Promise<Record<string, unknown>>;
30
+ /** Common auth transport used by CLI login, preserving the selected instance through awaits. */
31
+ request(path: string, options?: RequestInit): Promise<any>;
32
+ }
@@ -1,4 +1,6 @@
1
1
  import { type RemoteSkillRunContract } from "./remote-run-contract.js";
2
+ import { type RemoteCreditPack, type RemoteRunApproval, type RemoteRunQuote } from "./remote-account.js";
3
+ import { type RemoteInputFile } from "./remote-files.js";
2
4
  /**
3
5
  * A server that predates this client's pin/tag/incremental-sync routes answered
4
6
  * 404/405 for them. The caller must never mistake that for "no pins" or "empty
@@ -55,6 +57,7 @@ export interface UpdatedSincePage {
55
57
  export declare class RemoteSkillsClient {
56
58
  private apiUrl;
57
59
  private apiKey;
60
+ private capabilities?;
58
61
  constructor(apiKey: string, apiUrl?: string);
59
62
  private request;
60
63
  /**
@@ -88,12 +91,64 @@ export declare class RemoteSkillsClient {
88
91
  status: number;
89
92
  body: unknown;
90
93
  }>;
91
- submitRun(slug: string, input?: Record<string, unknown>, args?: string[]): Promise<RemoteSkillRunContract>;
94
+ /** Low-level admission transport; interactive surfaces use submitQuotedRun. */
95
+ submitRun(slug: string, input?: Record<string, unknown>, args?: string[], approval?: RemoteRunApproval): Promise<RemoteSkillRunContract>;
96
+ quoteRun(slug: string, input?: Record<string, unknown>, args?: string[]): Promise<RemoteRunQuote>;
97
+ getCapabilities(): Promise<{
98
+ contractVersion: 1;
99
+ apiVersion: 1;
100
+ capabilities: string[];
101
+ billing?: {
102
+ boundedRunApproval?: boolean;
103
+ unit?: string;
104
+ };
105
+ }>;
106
+ /** Quote first and fail closed when the caller has not approved the required credits. */
107
+ submitQuotedRun(slug: string, input?: Record<string, unknown>, args?: string[], approval?: RemoteRunApproval): Promise<RemoteSkillRunContract>;
108
+ getIdentity(): Promise<Record<string, unknown>>;
109
+ listApiKeys(): Promise<Record<string, unknown>[]>;
110
+ createApiKey(name: string, scopes?: string[]): Promise<{
111
+ key: string;
112
+ [field: string]: unknown;
113
+ }>;
114
+ revokeApiKey(keyId: string): Promise<Record<string, unknown>>;
115
+ getBillingStatus(): Promise<{
116
+ hasPaymentMethod?: boolean | undefined;
117
+ plan?: string | undefined;
118
+ creditBalance: number;
119
+ formattedCreditBalance: string;
120
+ }>;
121
+ listCreditPacks(): Promise<RemoteCreditPack[]>;
122
+ createCreditCheckout(packId: string): Promise<{
123
+ url: string;
124
+ }>;
125
+ getUsage(): Promise<Record<string, unknown>[]>;
126
+ listInvoices(): Promise<Record<string, unknown>[]>;
127
+ createBillingCheckout(): Promise<{
128
+ url: string;
129
+ }>;
130
+ createBillingPortal(): Promise<{
131
+ url: string;
132
+ }>;
133
+ cancelRun(runId: string): Promise<RemoteSkillRunContract>;
134
+ resumeRun(runId: string): Promise<RemoteSkillRunContract>;
135
+ private controlRun;
136
+ private checkoutResponse;
137
+ private arrayResponse;
92
138
  getRun(runId: string): Promise<RemoteSkillRunContract | null>;
93
139
  getRunLogs(runId: string): Promise<any[]>;
94
140
  listRuns(limit?: number): Promise<any[]>;
95
141
  getRunArtifacts(runId: string): Promise<any[]>;
96
142
  downloadRunArtifact(runId: string, artifactId: string): Promise<Response>;
143
+ getVerifiedRunArtifact(runId: string, artifactId: string, maximumBytes?: number): Promise<{
144
+ id: string;
145
+ fileName: string;
146
+ bytes: Uint8Array<ArrayBufferLike>;
147
+ byteSize: number;
148
+ sha256: any;
149
+ }>;
150
+ submitQuotedRunWithFiles(slug: string, input: Record<string, unknown>, args: string[], files: RemoteInputFile[], approval?: RemoteRunApproval): Promise<RemoteSkillRunContract>;
151
+ uploadRunFiles(runId: string, files: RemoteInputFile[]): Promise<void>;
97
152
  /**
98
153
  * Publish a skill to the configured instance.
99
154
  *
@@ -0,0 +1,106 @@
1
+ import type { RemoteSkillsClient } from "./remote-client.js";
2
+ /** Shared customer operation declarations for MCP registration and its discovery contract. */
3
+ export declare const REMOTE_CUSTOMER_OPERATIONS: readonly [{
4
+ readonly name: "get_account";
5
+ readonly title: "Get Account Identity";
6
+ readonly parameter: null;
7
+ readonly mutates: false;
8
+ readonly invoke: (client: RemoteSkillsClient) => Promise<Record<string, unknown>>;
9
+ }, {
10
+ readonly name: "get_server_capabilities";
11
+ readonly title: "Get Server Capabilities";
12
+ readonly parameter: null;
13
+ readonly mutates: false;
14
+ readonly invoke: (client: RemoteSkillsClient) => Promise<{
15
+ contractVersion: 1;
16
+ apiVersion: 1;
17
+ capabilities: string[];
18
+ billing?: {
19
+ boundedRunApproval?: boolean;
20
+ unit?: string;
21
+ };
22
+ }>;
23
+ }, {
24
+ readonly name: "list_remote_skills";
25
+ readonly title: "List Remote Skills";
26
+ readonly parameter: null;
27
+ readonly mutates: false;
28
+ readonly invoke: (client: RemoteSkillsClient) => Promise<any[]>;
29
+ }, {
30
+ readonly name: "get_billing_status";
31
+ readonly title: "Get Billing Status";
32
+ readonly parameter: null;
33
+ readonly mutates: false;
34
+ readonly invoke: (client: RemoteSkillsClient) => Promise<{
35
+ hasPaymentMethod?: boolean | undefined;
36
+ plan?: string | undefined;
37
+ creditBalance: number;
38
+ formattedCreditBalance: string;
39
+ }>;
40
+ }, {
41
+ readonly name: "list_credit_packs";
42
+ readonly title: "List Credit Packs";
43
+ readonly parameter: null;
44
+ readonly mutates: false;
45
+ readonly invoke: (client: RemoteSkillsClient) => Promise<import("./remote-account.js").RemoteCreditPack[]>;
46
+ }, {
47
+ readonly name: "create_credit_checkout";
48
+ readonly title: "Create Credit Checkout";
49
+ readonly parameter: "pack_id";
50
+ readonly mutates: true;
51
+ readonly invoke: (client: RemoteSkillsClient, value: string) => Promise<{
52
+ url: string;
53
+ }>;
54
+ }, {
55
+ readonly name: "get_billing_usage";
56
+ readonly title: "Get Billing Usage";
57
+ readonly parameter: null;
58
+ readonly mutates: false;
59
+ readonly invoke: (client: RemoteSkillsClient) => Promise<Record<string, unknown>[]>;
60
+ }, {
61
+ readonly name: "list_invoices";
62
+ readonly title: "List Invoices";
63
+ readonly parameter: null;
64
+ readonly mutates: false;
65
+ readonly invoke: (client: RemoteSkillsClient) => Promise<Record<string, unknown>[]>;
66
+ }, {
67
+ readonly name: "create_billing_checkout";
68
+ readonly title: "Create Billing Checkout";
69
+ readonly parameter: null;
70
+ readonly mutates: true;
71
+ readonly invoke: (client: RemoteSkillsClient) => Promise<{
72
+ url: string;
73
+ }>;
74
+ }, {
75
+ readonly name: "create_billing_portal";
76
+ readonly title: "Create Billing Portal";
77
+ readonly parameter: null;
78
+ readonly mutates: true;
79
+ readonly invoke: (client: RemoteSkillsClient) => Promise<{
80
+ url: string;
81
+ }>;
82
+ }, {
83
+ readonly name: "get_run_logs";
84
+ readonly title: "Get Run Logs";
85
+ readonly parameter: "run_id";
86
+ readonly mutates: false;
87
+ readonly invoke: (client: RemoteSkillsClient, value: string) => Promise<any[]>;
88
+ }, {
89
+ readonly name: "cancel_run";
90
+ readonly title: "Cancel Run";
91
+ readonly parameter: "run_id";
92
+ readonly mutates: true;
93
+ readonly invoke: (client: RemoteSkillsClient, value: string) => Promise<import("./remote-run-contract.js").RemoteSkillRunContract>;
94
+ }, {
95
+ readonly name: "resume_run";
96
+ readonly title: "Resume Run";
97
+ readonly parameter: "run_id";
98
+ readonly mutates: true;
99
+ readonly invoke: (client: RemoteSkillsClient, value: string) => Promise<import("./remote-run-contract.js").RemoteSkillRunContract>;
100
+ }, {
101
+ readonly name: "list_run_artifacts";
102
+ readonly title: "List Run Artifacts";
103
+ readonly parameter: "run_id";
104
+ readonly mutates: false;
105
+ readonly invoke: (client: RemoteSkillsClient, value: string) => Promise<any[]>;
106
+ }];
@@ -0,0 +1,21 @@
1
+ export declare const MAX_REMOTE_FILE_BYTES: number;
2
+ export interface RemoteInputFile {
3
+ name: string;
4
+ bytes: Uint8Array;
5
+ contentType?: string;
6
+ }
7
+ export interface RemoteInputFileDescriptor {
8
+ name: string;
9
+ sizeBytes: number;
10
+ sha256: string;
11
+ contentType: string;
12
+ }
13
+ export declare function describeRemoteFiles(files: RemoteInputFile[]): RemoteInputFileDescriptor[];
14
+ export declare function sha256(bytes: Uint8Array): string;
15
+ export declare function readBoundedResponse(response: Response, maximum: number): Promise<Uint8Array>;
16
+ /** Small inline inputs for agent transports; larger files belong in the CLI/SDK. */
17
+ export declare function decodeRemoteFiles(files: Array<{
18
+ name: string;
19
+ base64: string;
20
+ contentType?: string;
21
+ }>): RemoteInputFile[];
@@ -35,6 +35,7 @@ export type RunRoutingErrorCode = "REMOTE_REQUIRES_ORIGIN" | "REMOTE_REQUIRES_CR
35
35
  export type RunRouting = {
36
36
  route: "remote";
37
37
  apiKey: string;
38
+ apiOrigin: string;
38
39
  } | {
39
40
  route: "local";
40
41
  } | {
@@ -25,6 +25,8 @@ export interface SkillRunRecord {
25
25
  durationMs?: number;
26
26
  remote: boolean;
27
27
  remoteRunId?: string;
28
+ /** Exact configured instance that owns a remote run; absent on historical records. */
29
+ remoteApiOrigin?: string;
28
30
  costCents?: number;
29
31
  error?: string;
30
32
  artifacts: SkillRunArtifact[];
@@ -47,6 +49,7 @@ export declare function createSkillRun(params: {
47
49
  prompt?: string;
48
50
  remote?: boolean;
49
51
  remoteRunId?: string;
52
+ remoteApiOrigin?: string;
50
53
  costCents?: number;
51
54
  status?: SkillRunStatus;
52
55
  }, targetDir?: string): SkillRunContext;
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerRemoteCustomerTools(server: McpServer): void;
@@ -30,3 +30,7 @@ export * from "./events.js";
30
30
  export * from "./spend.js";
31
31
  export * from "./offline.js";
32
32
  export * from "./execution/index.js";
33
+ export { RemoteSkillsClient, createRemoteSkillsClient, RemoteRequestError, RemoteRouteUnsupportedError } from "../lib/remote-client.js";
34
+ export { RemoteCreditApprovalError, type RemoteRunApproval, type RemoteRunQuote, type RemoteCreditPack } from "../lib/remote-account.js";
35
+ export { type RemoteInputFile, type RemoteInputFileDescriptor } from "../lib/remote-files.js";
36
+ export { RemoteSkillsAuthClient, HostedApiError } from "../lib/remote-auth.js";