@hasna/skills 0.3.0 → 0.5.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.
- package/README.md +269 -14
- package/bin/index.js +7835 -5440
- package/bin/mcp.js +2040 -589
- package/bin/migrate.js +148 -40
- package/bin/server.js +66 -87
- package/bin/worker.js +42 -75
- package/dist/admin-contract.d.ts +37 -19
- package/dist/admin-contract.js +1 -1
- package/dist/cli/cli.test-utils.d.ts +10 -8
- package/dist/cli/commands/customer-profile.d.ts +2 -0
- package/dist/cli/commands/customer-verification.d.ts +5 -0
- package/dist/cli/commands/remote-account.d.ts +7 -0
- package/dist/cli/commands/tool-primitives.d.ts +1 -1
- package/dist/cli/commands/workspace-member-mutations.d.ts +2 -0
- package/dist/cli/commands/workspace-members.d.ts +2 -0
- package/dist/cli/env-assignment.d.ts +9 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.js +1369 -349
- package/dist/lib/agent-sync.d.ts +13 -8
- package/dist/lib/api-url.d.ts +4 -3
- package/dist/lib/app-home.d.ts +0 -1
- package/dist/lib/auth-store.d.ts +1 -1
- package/dist/lib/client-types.d.ts +75 -0
- package/dist/lib/credential-state.d.ts +12 -0
- package/dist/lib/fleet-credentials.d.ts +49 -17
- package/dist/lib/home-adoption.d.ts +2 -0
- package/dist/lib/home-census.d.ts +3 -1
- package/dist/lib/instance-credentials.d.ts +13 -0
- package/dist/lib/local-opt-in.d.ts +24 -0
- package/dist/lib/mcp-contracts.d.ts +4 -0
- package/dist/lib/portable-skills-files.d.ts +10 -2
- package/dist/lib/portable-skills-types.d.ts +2 -0
- package/dist/lib/read-access.d.ts +83 -0
- package/dist/lib/remote-account.d.ts +42 -0
- package/dist/lib/remote-auth.d.ts +46 -0
- package/dist/lib/remote-client.d.ts +90 -6
- package/dist/lib/remote-customer-operations.d.ts +106 -0
- package/dist/lib/remote-files.d.ts +21 -0
- package/dist/lib/remote-profile.d.ts +26 -0
- package/dist/lib/remote-registry.d.ts +7 -3
- package/dist/lib/remote-workspace.d.ts +76 -0
- package/dist/lib/run-routing.d.ts +1 -0
- package/dist/lib/run-state.d.ts +3 -0
- package/dist/lib/skillinfo.d.ts +1 -1
- package/dist/mcp/helpers.d.ts +22 -0
- package/dist/mcp/index.d.ts +16 -0
- package/dist/mcp/remote-customer-tools.d.ts +2 -0
- package/dist/sdk/governance-store.d.ts +1 -0
- package/dist/sdk/index.d.ts +8 -1
- package/dist/sdk/index.js +1994 -416
- package/dist/sdk/outputs.d.ts +0 -11
- package/dist/sdk/runs.d.ts +5 -5
- package/dist/storage.js +6 -40
- package/docs/skill-standard.md +30 -2
- package/package.json +7 -6
|
@@ -1,4 +1,9 @@
|
|
|
1
|
+
import { type RemoteWorkspaceMembersOptions, type RemoteWorkspaceMembersPage } from "./remote-workspace.js";
|
|
2
|
+
import { type RemoteWorkspaceMemberErrorCode, type SetRemoteWorkspaceMemberRole, type RemoveRemoteWorkspaceMember, type RemoteWorkspaceMemberRoleResult, type RemoteWorkspaceMemberRemovalResult } from "./remote-workspace.js";
|
|
1
3
|
import { type RemoteSkillRunContract } from "./remote-run-contract.js";
|
|
4
|
+
import { type RemoteCreditPack, type RemoteRunApproval, type RemoteRunQuote } from "./remote-account.js";
|
|
5
|
+
import { type RemoteInputFile } from "./remote-files.js";
|
|
6
|
+
import { type UpdateRemoteProfile, type UpdateRemoteWorkspace } from "./remote-profile.js";
|
|
2
7
|
/**
|
|
3
8
|
* A server that predates this client's pin/tag/incremental-sync routes answered
|
|
4
9
|
* 404/405 for them. The caller must never mistake that for "no pins" or "empty
|
|
@@ -15,7 +20,17 @@ export declare class RemoteRouteUnsupportedError extends Error {
|
|
|
15
20
|
export declare class RemoteRequestError extends Error {
|
|
16
21
|
readonly path: string;
|
|
17
22
|
readonly status: number;
|
|
18
|
-
constructor(path: string, status: number,
|
|
23
|
+
constructor(path: string, status: number, _statusText?: string);
|
|
24
|
+
}
|
|
25
|
+
/** A recognized membership refusal, with fixed text and no server payload. */
|
|
26
|
+
export declare class RemoteWorkspaceMemberError extends RemoteRequestError {
|
|
27
|
+
readonly code: RemoteWorkspaceMemberErrorCode;
|
|
28
|
+
constructor(path: string, code: RemoteWorkspaceMemberErrorCode);
|
|
29
|
+
}
|
|
30
|
+
/** A recognized unavailable capability; all displayed text is client-owned. */
|
|
31
|
+
export declare class RemoteCapabilityUnavailableError extends RemoteRequestError {
|
|
32
|
+
readonly code: "SUBSCRIPTION_CHECKOUT_UNAVAILABLE";
|
|
33
|
+
constructor();
|
|
19
34
|
}
|
|
20
35
|
/**
|
|
21
36
|
* A remote pin on a skill, matching the hosted-pins wire shape
|
|
@@ -55,6 +70,7 @@ export interface UpdatedSincePage {
|
|
|
55
70
|
export declare class RemoteSkillsClient {
|
|
56
71
|
private apiUrl;
|
|
57
72
|
private apiKey;
|
|
73
|
+
private capabilities?;
|
|
58
74
|
constructor(apiKey: string, apiUrl?: string);
|
|
59
75
|
private request;
|
|
60
76
|
/**
|
|
@@ -88,12 +104,79 @@ export declare class RemoteSkillsClient {
|
|
|
88
104
|
status: number;
|
|
89
105
|
body: unknown;
|
|
90
106
|
}>;
|
|
91
|
-
|
|
107
|
+
/** Low-level admission transport; interactive surfaces use submitQuotedRun. */
|
|
108
|
+
submitRun(slug: string, input?: Record<string, unknown>, args?: string[], approval?: RemoteRunApproval): Promise<RemoteSkillRunContract>;
|
|
109
|
+
quoteRun(slug: string, input?: Record<string, unknown>, args?: string[]): Promise<RemoteRunQuote>;
|
|
110
|
+
getCapabilities(): Promise<{
|
|
111
|
+
contractVersion: 1;
|
|
112
|
+
apiVersion: 1;
|
|
113
|
+
capabilities: string[];
|
|
114
|
+
billing?: {
|
|
115
|
+
boundedRunApproval?: boolean;
|
|
116
|
+
unit?: string;
|
|
117
|
+
};
|
|
118
|
+
}>;
|
|
119
|
+
/** Quote first and fail closed when the caller has not approved the required credits. */
|
|
120
|
+
submitQuotedRun(slug: string, input?: Record<string, unknown>, args?: string[], approval?: RemoteRunApproval): Promise<RemoteSkillRunContract>;
|
|
121
|
+
getIdentity(): Promise<Record<string, unknown>>;
|
|
122
|
+
/** Requires a customer session; API keys and support impersonation cannot edit names. */
|
|
123
|
+
updateProfile(input: UpdateRemoteProfile): Promise<{
|
|
124
|
+
user: import("./remote-profile.js").RemoteCustomerProfile;
|
|
125
|
+
}>;
|
|
126
|
+
/** Owner/admin session only; the current workspace identity and slug stay fixed. */
|
|
127
|
+
updateCurrentWorkspace(input: UpdateRemoteWorkspace): Promise<{
|
|
128
|
+
organization: import("./remote-profile.js").RemoteCurrentWorkspace;
|
|
129
|
+
}>;
|
|
130
|
+
/** Current owner/admin customer session only; the server refuses API keys and impersonation. */
|
|
131
|
+
listWorkspaceMembers(options?: RemoteWorkspaceMembersOptions): Promise<RemoteWorkspaceMembersPage>;
|
|
132
|
+
/** Exact incarnation and expected role; no refresh or retry. Server enforces current authority. */
|
|
133
|
+
setWorkspaceMemberRole(membershipId: string, input: SetRemoteWorkspaceMemberRole): Promise<RemoteWorkspaceMemberRoleResult>;
|
|
134
|
+
/** Removes only this incarnation. A successful tombstone replay is returned unchanged. */
|
|
135
|
+
removeWorkspaceMember(membershipId: string, input: RemoveRemoteWorkspaceMember): Promise<RemoteWorkspaceMemberRemovalResult>;
|
|
136
|
+
private requestWorkspaceMember;
|
|
137
|
+
listApiKeys(): Promise<Record<string, unknown>[]>;
|
|
138
|
+
createApiKey(name: string, scopes?: string[]): Promise<{
|
|
139
|
+
key: string;
|
|
140
|
+
[field: string]: unknown;
|
|
141
|
+
}>;
|
|
142
|
+
revokeApiKey(keyId: string): Promise<Record<string, unknown>>;
|
|
143
|
+
getBillingStatus(): Promise<{
|
|
144
|
+
hasPaymentMethod?: boolean | undefined;
|
|
145
|
+
plan?: string | undefined;
|
|
146
|
+
creditBalance: number;
|
|
147
|
+
formattedCreditBalance: string;
|
|
148
|
+
}>;
|
|
149
|
+
listCreditPacks(): Promise<RemoteCreditPack[]>;
|
|
150
|
+
createCreditCheckout(packId: string): Promise<{
|
|
151
|
+
url: string;
|
|
152
|
+
}>;
|
|
153
|
+
getUsage(): Promise<Record<string, unknown>[]>;
|
|
154
|
+
listInvoices(): Promise<Record<string, unknown>[]>;
|
|
155
|
+
createBillingCheckout(): Promise<{
|
|
156
|
+
url: string;
|
|
157
|
+
}>;
|
|
158
|
+
createBillingPortal(): Promise<{
|
|
159
|
+
url: string;
|
|
160
|
+
}>;
|
|
161
|
+
cancelRun(runId: string): Promise<RemoteSkillRunContract>;
|
|
162
|
+
resumeRun(runId: string): Promise<RemoteSkillRunContract>;
|
|
163
|
+
private controlRun;
|
|
164
|
+
private checkoutResponse;
|
|
165
|
+
private arrayResponse;
|
|
92
166
|
getRun(runId: string): Promise<RemoteSkillRunContract | null>;
|
|
93
167
|
getRunLogs(runId: string): Promise<any[]>;
|
|
94
168
|
listRuns(limit?: number): Promise<any[]>;
|
|
95
169
|
getRunArtifacts(runId: string): Promise<any[]>;
|
|
96
170
|
downloadRunArtifact(runId: string, artifactId: string): Promise<Response>;
|
|
171
|
+
getVerifiedRunArtifact(runId: string, artifactId: string, maximumBytes?: number): Promise<{
|
|
172
|
+
id: string;
|
|
173
|
+
fileName: string;
|
|
174
|
+
bytes: Uint8Array<ArrayBufferLike>;
|
|
175
|
+
byteSize: number;
|
|
176
|
+
sha256: any;
|
|
177
|
+
}>;
|
|
178
|
+
submitQuotedRunWithFiles(slug: string, input: Record<string, unknown>, args: string[], files: RemoteInputFile[], approval?: RemoteRunApproval): Promise<RemoteSkillRunContract>;
|
|
179
|
+
uploadRunFiles(runId: string, files: RemoteInputFile[]): Promise<void>;
|
|
97
180
|
/**
|
|
98
181
|
* Publish a skill to the configured instance.
|
|
99
182
|
*
|
|
@@ -156,11 +239,12 @@ export declare class RemoteSkillsClient {
|
|
|
156
239
|
}
|
|
157
240
|
/**
|
|
158
241
|
* The client for the configured instance, or null when this install runs on
|
|
159
|
-
* this machine
|
|
242
|
+
* this machine — which is now the explicit local opt-in only
|
|
243
|
+
* (`HASNA_SKILLS_LOCAL=1`); with no credential, no authority and no opt-in the
|
|
244
|
+
* shared ladder throws (fail-closed ruling), so the caller fails loudly instead
|
|
245
|
+
* of quietly reading the bundled corpus while authentication is unconfigured.
|
|
160
246
|
*
|
|
161
|
-
* A configured authority with no credential
|
|
162
|
-
* ladder throws, so the caller fails loudly instead of quietly reading the
|
|
163
|
-
* bundled corpus while authentication is unconfigured.
|
|
247
|
+
* A configured authority with no credential also throws for the same reason.
|
|
164
248
|
*
|
|
165
249
|
* ASYNC because the credential ladder is: a vault pointer
|
|
166
250
|
* (`HASNA_SKILLS_API_KEY_REF`) is completed through the secrets vault before a
|
|
@@ -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[];
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type RemoteCustomerRole = "owner" | "admin" | "member" | "viewer";
|
|
2
|
+
export type RemoteCustomerProfile = {
|
|
3
|
+
id: string;
|
|
4
|
+
email: string;
|
|
5
|
+
displayName: string | null;
|
|
6
|
+
role: RemoteCustomerRole;
|
|
7
|
+
};
|
|
8
|
+
export type RemoteCurrentWorkspace = {
|
|
9
|
+
id: string;
|
|
10
|
+
slug: string;
|
|
11
|
+
name: string;
|
|
12
|
+
};
|
|
13
|
+
export type UpdateRemoteProfile = {
|
|
14
|
+
displayName: string;
|
|
15
|
+
};
|
|
16
|
+
export type UpdateRemoteWorkspace = {
|
|
17
|
+
name: string;
|
|
18
|
+
};
|
|
19
|
+
/** Client input checks do not grant authority; the selected server owns policy. */
|
|
20
|
+
export declare function customerNamePatch(input: unknown, field: "displayName" | "name"): Record<string, string>;
|
|
21
|
+
export declare function parseUpdatedProfile(value: unknown): {
|
|
22
|
+
user: RemoteCustomerProfile;
|
|
23
|
+
};
|
|
24
|
+
export declare function parseUpdatedWorkspace(value: unknown): {
|
|
25
|
+
organization: RemoteCurrentWorkspace;
|
|
26
|
+
};
|
|
@@ -45,9 +45,13 @@ export declare function loadRemoteRegistry(options?: RemoteRegistryOptions): Pro
|
|
|
45
45
|
* origin sees the folder UNION cloud in the plain `list`/`search` path, while
|
|
46
46
|
* every other install keeps today's exact local behavior.
|
|
47
47
|
*
|
|
48
|
-
* - Nothing configured
|
|
49
|
-
*
|
|
50
|
-
*
|
|
48
|
+
* - Nothing configured, local opted in -> the local list is returned
|
|
49
|
+
* unchanged and no request is attempted. An install running on this
|
|
50
|
+
* machine must stay byte-identical to the pre-merge output.
|
|
51
|
+
* - Nothing configured and NO local opt-in -> this throws, from the shared
|
|
52
|
+
* ladder (MISSING_API_CREDENTIAL, naming `HASNA_SKILLS_LOCAL` as the
|
|
53
|
+
* deliberate way out): local mode is opt-in only, and an unconfigured
|
|
54
|
+
* install is a refusal rather than a silent local listing.
|
|
51
55
|
* - An authority configured with NO credential -> this throws, from the
|
|
52
56
|
* shared ladder. It used to return the local half silently, which is the
|
|
53
57
|
* false green the 2026-09-04 ruling removes: an operator who pointed this
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { RemoteCustomerRole } from "./remote-profile.js";
|
|
2
|
+
export type RemoteWorkspaceMember = {
|
|
3
|
+
membershipId: string;
|
|
4
|
+
userId: string;
|
|
5
|
+
email: string;
|
|
6
|
+
displayName: string | null;
|
|
7
|
+
role: RemoteCustomerRole;
|
|
8
|
+
/** Exact server timestamp, including microseconds; never rounded to Date. */
|
|
9
|
+
createdAt: string;
|
|
10
|
+
};
|
|
11
|
+
export type RemoteWorkspaceMembersPage = {
|
|
12
|
+
organizationId: string;
|
|
13
|
+
members: RemoteWorkspaceMember[];
|
|
14
|
+
nextCursor: string | null;
|
|
15
|
+
};
|
|
16
|
+
export type RemoteWorkspaceMembersOptions = {
|
|
17
|
+
limit?: number;
|
|
18
|
+
cursor?: string;
|
|
19
|
+
};
|
|
20
|
+
export type SetRemoteWorkspaceMemberRole = {
|
|
21
|
+
role: RemoteCustomerRole;
|
|
22
|
+
expectedRole: RemoteCustomerRole;
|
|
23
|
+
};
|
|
24
|
+
export type RemoveRemoteWorkspaceMember = {
|
|
25
|
+
expectedRole: RemoteCustomerRole;
|
|
26
|
+
};
|
|
27
|
+
export type RemoteWorkspaceMemberRoleResult = {
|
|
28
|
+
organizationId: string;
|
|
29
|
+
member: RemoteWorkspaceMember;
|
|
30
|
+
changed: boolean;
|
|
31
|
+
};
|
|
32
|
+
export type RemoteWorkspaceMemberRemovalResult = {
|
|
33
|
+
organizationId: string;
|
|
34
|
+
membershipId: string;
|
|
35
|
+
removed: true;
|
|
36
|
+
alreadyRemoved: boolean;
|
|
37
|
+
};
|
|
38
|
+
/** Pagination is transport input, not a workspace or authority selector. */
|
|
39
|
+
export declare function workspaceMembersQuery(options?: RemoteWorkspaceMembersOptions): string;
|
|
40
|
+
export declare class WorkspaceMemberInputError extends Error {
|
|
41
|
+
constructor();
|
|
42
|
+
}
|
|
43
|
+
/** Snapshot transport input before verification awaits; authority stays on the server. */
|
|
44
|
+
export declare function workspaceMemberRoleInput(membershipId: string, input: SetRemoteWorkspaceMemberRole): {
|
|
45
|
+
membershipId: string;
|
|
46
|
+
body: {
|
|
47
|
+
role: RemoteCustomerRole;
|
|
48
|
+
expectedRole: RemoteCustomerRole;
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
export declare function workspaceMemberRemovalInput(membershipId: string, input: RemoveRemoteWorkspaceMember): {
|
|
52
|
+
membershipId: string;
|
|
53
|
+
body: {
|
|
54
|
+
expectedRole: RemoteCustomerRole;
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
export declare const invalidMemberResult = "The server returned an invalid workspace member result. Refresh the roster before another action.";
|
|
58
|
+
export declare function parseWorkspaceMemberRoleResult(value: unknown, membershipId: string, role: RemoteCustomerRole): RemoteWorkspaceMemberRoleResult;
|
|
59
|
+
export declare function parseWorkspaceMemberRemovalResult(value: unknown, membershipId: string): RemoteWorkspaceMemberRemovalResult;
|
|
60
|
+
/** Only known code/status pairs become public messages; arbitrary server text stays private. */
|
|
61
|
+
export declare const workspaceMemberFailures: {
|
|
62
|
+
readonly INVALID_REQUEST: readonly [400, "Provide the exact membership role parameters."];
|
|
63
|
+
readonly ACCOUNT_UNAVAILABLE: readonly [403, "Account is unavailable."];
|
|
64
|
+
readonly INTERACTIVE_SESSION_REQUIRED: readonly [403, "Fresh interactive sign-in is required."];
|
|
65
|
+
readonly WORKSPACE_ADMIN_REQUIRED: readonly [403, "A current workspace owner or admin is required."];
|
|
66
|
+
readonly MEMBERSHIP_ACTION_FORBIDDEN: readonly [403, "Your current workspace role cannot perform this membership action."];
|
|
67
|
+
readonly MEMBERSHIP_NOT_FOUND: readonly [404, "Membership was not found in the current workspace."];
|
|
68
|
+
readonly SELF_REMOVAL_UNAVAILABLE: readonly [409, "Leaving your own workspace is not available through member removal."];
|
|
69
|
+
readonly MEMBERSHIP_ROLE_CHANGED: readonly [409, "The member role changed. Refresh the roster before another action."];
|
|
70
|
+
readonly LAST_OWNER_REQUIRED: readonly [409, "The workspace must retain at least one active owner."];
|
|
71
|
+
readonly MEMBERSHIP_BUSY: readonly [503, "Membership is busy. Refresh the roster before another action."];
|
|
72
|
+
};
|
|
73
|
+
export type RemoteWorkspaceMemberErrorCode = keyof typeof workspaceMemberFailures;
|
|
74
|
+
export declare function workspaceMemberFailure(value: unknown, status: number): RemoteWorkspaceMemberErrorCode | null;
|
|
75
|
+
/** Project the documented roster only; auth metadata and other fields stay out. */
|
|
76
|
+
export declare function parseWorkspaceMembersPage(value: unknown): RemoteWorkspaceMembersPage;
|
package/dist/lib/run-state.d.ts
CHANGED
|
@@ -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;
|
package/dist/lib/skillinfo.d.ts
CHANGED
|
@@ -45,7 +45,7 @@ export declare function getSkillDependencyStatus(name: string): SkillDependencyS
|
|
|
45
45
|
*/
|
|
46
46
|
export declare function runSkill(name: string, args: string[], options?: {
|
|
47
47
|
installed?: boolean;
|
|
48
|
-
stdio?: "inherit" | "pipe";
|
|
48
|
+
stdio?: "inherit" | "pipe" | "stderr";
|
|
49
49
|
env?: Record<string, string>;
|
|
50
50
|
}): Promise<{
|
|
51
51
|
exitCode: number;
|
package/dist/mcp/helpers.d.ts
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
/** The shape every tool handler returns; kept structural so registrars need no SDK type import. */
|
|
2
|
+
type McpToolResult = {
|
|
3
|
+
content: Array<{
|
|
4
|
+
type: "text";
|
|
5
|
+
text: string;
|
|
6
|
+
}>;
|
|
7
|
+
isError?: boolean;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Run a DATA tool behind the fleet ladder's refusal.
|
|
11
|
+
*
|
|
12
|
+
* The body is expected to go through `requireSkillsReadAccess()` /
|
|
13
|
+
* `getBrowseRegistry()` (lib/read-access.ts) before it reads the bundled
|
|
14
|
+
* catalog or the on-machine corpus. When the ladder refuses — no credential, no
|
|
15
|
+
* authority, no `HASNA_SKILLS_LOCAL=1` opt-in; an authority with no key; a
|
|
16
|
+
* deliberate selection that cannot be honoured — the refusal comes back as the
|
|
17
|
+
* same `AUTH_REQUIRED` result `get_run_status` already gives, never as the
|
|
18
|
+
* local answer. Any other failure propagates unchanged (the SDK reports it as
|
|
19
|
+
* a tool error with its message).
|
|
20
|
+
*/
|
|
21
|
+
export declare function readSurface(body: () => Promise<McpToolResult>): Promise<McpToolResult>;
|
|
1
22
|
export declare function stripNulls(obj: Record<string, unknown>): Record<string, unknown>;
|
|
2
23
|
export declare function cacheGet(key: string): unknown | undefined;
|
|
3
24
|
export declare function cacheSet(key: string, value: unknown): void;
|
|
@@ -24,3 +45,4 @@ export declare const TOOL_DESCRIPTIONS: Record<string, {
|
|
|
24
45
|
description: string;
|
|
25
46
|
params: string[];
|
|
26
47
|
}>;
|
|
48
|
+
export {};
|
package/dist/mcp/index.d.ts
CHANGED
|
@@ -8,6 +8,22 @@
|
|
|
8
8
|
* skills-mcp # Direct binary
|
|
9
9
|
* skills-mcp --http # Streamable HTTP on 127.0.0.1:8836
|
|
10
10
|
*/
|
|
11
|
+
/**
|
|
12
|
+
* FAIL CLOSED AT STARTUP (owner ruling 2026-09-04, hasna/apps#1720; #1720
|
|
13
|
+
* validation, round 1): the MCP process resolves the fleet ladder BEFORE it
|
|
14
|
+
* connects any transport. With no credential, no authority and no
|
|
15
|
+
* `HASNA_SKILLS_LOCAL=1` opt-in it exits 1 with the ladder's one line on
|
|
16
|
+
* stderr — before `initialize` is answered, before an HTTP port is bound —
|
|
17
|
+
* mirroring the CLI, which exits 1 on the same machine. Serving the bundled
|
|
18
|
+
* catalog to an agent host that registered `skills-mcp` on a station without
|
|
19
|
+
* its credential is the false green the ruling removed. The explicit local
|
|
20
|
+
* opt-in starts the server and announces local mode once on stderr; a
|
|
21
|
+
* credential (or a vault pointer the tools complete per call) starts it hosted.
|
|
22
|
+
*
|
|
23
|
+
* Every data tool still runs the same gate per call (lib/read-access.ts), so a
|
|
24
|
+
* credential that disappears mid-process is refused by the next call too.
|
|
25
|
+
*/
|
|
26
|
+
export declare function assertSkillsMcpConfigured(env?: Record<string, string | undefined>): void;
|
|
11
27
|
/**
|
|
12
28
|
* Start the Skills MCP server on stdio (newline-delimited JSON-RPC).
|
|
13
29
|
*
|
|
@@ -51,6 +51,7 @@ export interface GovernanceStore {
|
|
|
51
51
|
estimatedCents: number;
|
|
52
52
|
}): Promise<CreditReservation>;
|
|
53
53
|
reservationsForRun(orgId: string, runId: string): Promise<CreditReservation[]>;
|
|
54
|
+
/** First terminal reconciliation wins; retries return that persisted state unchanged. */
|
|
54
55
|
reconcileReservation(reservationId: string, actualCents: number, status: "charged" | "released"): Promise<CreditReservation | null>;
|
|
55
56
|
/** Sum of cost_cents of runs created in the given calendar month (YYYY-MM), plus un-reconciled reservations. */
|
|
56
57
|
monthlySpendCents(orgId: string, monthPrefix: string): Promise<number>;
|
package/dist/sdk/index.d.ts
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* — the shared @hasna/contracts ladder — instead of reading an environment
|
|
16
16
|
* variable of its own. See lib/fleet-credentials.ts.
|
|
17
17
|
*/
|
|
18
|
-
export { MissingSkillsFleetError, SkillsFleetCredentialError, SKILLS_API_KEY_ENV, SKILLS_API_URL_ENV, SKILLS_APP, configuredSkillsApiUrl, noticeLocalSkillsMode, normalizeSkillsApiOrigin, requireSkillsApiOrigin, requireSkillsFleet, resolveSkillsApiOrigin, resolveSkillsFleet, skillsCredentialFilePath, skillsCredentialFiles, skillsCredentialOrReason, type HostedSkillsFleet, type LocalSkillsFleet, type SkillsFleet, type SkillsFleetErrorCode, type SkillsFleetOptions, } from "../lib/fleet-credentials.js";
|
|
18
|
+
export { MissingSkillsFleetError, SkillsFleetCredentialError, SKILLS_API_KEY_ENV, SKILLS_API_URL_ENV, SKILLS_APP, SKILLS_LOCAL_OPT_IN_ENV_KEYS, configuredSkillsApiUrl, isSkillsLocalOptIn, noticeLocalSkillsMode, normalizeSkillsApiOrigin, requireSkillsApiOrigin, requireSkillsFleet, resolveSkillsApiOrigin, resolveSkillsFleet, selectsSkillsLocalMode, skillsCredentialFilePath, skillsCredentialFiles, skillsCredentialOrReason, type HostedSkillsFleet, type LocalSkillsFleet, type SkillsFleet, type SkillsFleetErrorCode, type SkillsFleetOptions, } from "../lib/fleet-credentials.js";
|
|
19
19
|
export * from "./server.js";
|
|
20
20
|
export * from "./registry.js";
|
|
21
21
|
export * from "./runs.js";
|
|
@@ -30,3 +30,10 @@ 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, RemoteCapabilityUnavailableError, RemoteWorkspaceMemberError } 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";
|
|
37
|
+
export type { RemoteWorkspaceMember, RemoteWorkspaceMembersPage, RemoteWorkspaceMembersOptions } from "../lib/remote-workspace.js";
|
|
38
|
+
export type { SetRemoteWorkspaceMemberRole, RemoveRemoteWorkspaceMember, RemoteWorkspaceMemberRoleResult, RemoteWorkspaceMemberRemovalResult, RemoteWorkspaceMemberErrorCode } from "../lib/remote-workspace.js";
|
|
39
|
+
export type { RemoteCustomerRole, RemoteCustomerProfile, RemoteCurrentWorkspace, UpdateRemoteProfile, UpdateRemoteWorkspace } from "../lib/remote-profile.js";
|