@hasna/skills 0.5.1 → 0.5.3
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 +196 -1
- package/bin/index.js +1339 -619
- package/bin/mcp.js +28222 -26875
- package/bin/migrate.js +172 -1
- package/bin/server.js +187 -1
- package/bin/worker.js +225 -40
- package/dist/cli/commands/invitation-recovery.d.ts +2 -0
- package/dist/cli/commands/invitation-verification.d.ts +8 -0
- package/dist/cli/commands/workspace-invitations.d.ts +2 -0
- package/dist/cli/commands/workspace-leave.d.ts +2 -0
- package/dist/index.d.ts +7 -1
- package/dist/index.js +1075 -163
- package/dist/lib/invitation-customer-action.d.ts +14 -0
- package/dist/lib/invitation-recovery-target.d.ts +5 -0
- package/dist/lib/remote-auth.d.ts +15 -0
- package/dist/lib/remote-client.d.ts +15 -0
- package/dist/lib/remote-invitation-recovery.d.ts +62 -0
- package/dist/lib/remote-invitations.d.ts +128 -0
- package/dist/lib/remote-workspace-leave.d.ts +52 -0
- package/dist/lib/skill-bundle.d.ts +54 -1
- package/dist/lib/skill-entry-path.d.ts +6 -0
- package/dist/lib/skill-hash.d.ts +33 -0
- package/dist/mcp/index.d.ts +0 -1
- package/dist/mcp/invitation-recovery.d.ts +2 -0
- package/dist/mcp/remote-invitation-tools.d.ts +2 -0
- package/dist/sdk/index.d.ts +5 -0
- package/dist/sdk/index.js +1020 -103
- package/dist/sdk/registry.d.ts +6 -0
- package/package.json +1 -1
package/bin/index.js
CHANGED
|
@@ -36860,7 +36860,7 @@ var package_default;
|
|
|
36860
36860
|
var init_package = __esm(() => {
|
|
36861
36861
|
package_default = {
|
|
36862
36862
|
name: "@hasna/skills",
|
|
36863
|
-
version: "0.5.
|
|
36863
|
+
version: "0.5.3",
|
|
36864
36864
|
description: "Skills library for AI coding agents",
|
|
36865
36865
|
type: "module",
|
|
36866
36866
|
bin: {
|
|
@@ -39323,10 +39323,45 @@ var init_skill_validation = __esm(() => {
|
|
|
39323
39323
|
VALID_BIN_COMMAND = /^[a-z0-9][a-z0-9._-]*$/;
|
|
39324
39324
|
});
|
|
39325
39325
|
|
|
39326
|
+
// src/lib/skill-entry-path.ts
|
|
39327
|
+
class SkillEntryPaths {
|
|
39328
|
+
files = new Set;
|
|
39329
|
+
directories = new Set;
|
|
39330
|
+
add(path, maxBytes, invalid, limit) {
|
|
39331
|
+
if (path.length > maxBytes)
|
|
39332
|
+
limit();
|
|
39333
|
+
const encoded = new TextEncoder().encode(path);
|
|
39334
|
+
if (encoded.byteLength > maxBytes)
|
|
39335
|
+
limit();
|
|
39336
|
+
if (new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(encoded) !== path)
|
|
39337
|
+
invalid("Invalid UTF-8 entry path");
|
|
39338
|
+
if (!path || /[\\:\x00-\x1f\x7f]/u.test(path))
|
|
39339
|
+
invalid("Unsafe entry path");
|
|
39340
|
+
if (path.split("/").some((segment) => !segment || segment === "." || segment === ".."))
|
|
39341
|
+
invalid("Unsafe entry path segment");
|
|
39342
|
+
const key = path.normalize("NFC").toLowerCase().normalize("NFC");
|
|
39343
|
+
if (this.files.has(key) || this.directories.has(key))
|
|
39344
|
+
invalid("Duplicate or conflicting entry path");
|
|
39345
|
+
const parents = key.split("/");
|
|
39346
|
+
parents.pop();
|
|
39347
|
+
while (parents.length) {
|
|
39348
|
+
const parent = parents.join("/");
|
|
39349
|
+
if (this.files.has(parent))
|
|
39350
|
+
invalid("Conflicting entry file ancestor");
|
|
39351
|
+
this.directories.add(parent);
|
|
39352
|
+
parents.pop();
|
|
39353
|
+
}
|
|
39354
|
+
this.files.add(key);
|
|
39355
|
+
}
|
|
39356
|
+
}
|
|
39357
|
+
|
|
39326
39358
|
// src/lib/skill-hash.ts
|
|
39327
39359
|
import { createHash } from "crypto";
|
|
39328
39360
|
import { existsSync as existsSync9, readdirSync as readdirSync4, readFileSync as readFileSync5, statSync as statSync4 } from "fs";
|
|
39329
39361
|
import { join as join9, sep } from "path";
|
|
39362
|
+
function excludedHashEntry(name, directory) {
|
|
39363
|
+
return name.startsWith(".") || directory && HASH_EXCLUDE_DIRS.has(name);
|
|
39364
|
+
}
|
|
39330
39365
|
function normalizeLineEndings(content) {
|
|
39331
39366
|
return content.replace(/\r\n/g, `
|
|
39332
39367
|
`).replace(/\r/g, `
|
|
@@ -39397,7 +39432,7 @@ function collectDirectory(files, dir, rel) {
|
|
|
39397
39432
|
if (stats.isSymbolicLink())
|
|
39398
39433
|
continue;
|
|
39399
39434
|
if (stats.isDirectory()) {
|
|
39400
|
-
if (
|
|
39435
|
+
if (excludedHashEntry(entry, true))
|
|
39401
39436
|
continue;
|
|
39402
39437
|
collectDirectory(files, absolute, childRel);
|
|
39403
39438
|
} else if (stats.isFile()) {
|
|
@@ -39407,26 +39442,34 @@ function collectDirectory(files, dir, rel) {
|
|
|
39407
39442
|
}
|
|
39408
39443
|
function collectFile(files, absolute, rel) {
|
|
39409
39444
|
const buffer = readFileSync5(absolute);
|
|
39445
|
+
files.push(normalizeBundleFile(rel.split(sep).join("/"), buffer));
|
|
39446
|
+
}
|
|
39447
|
+
function normalizeBundleFile(rel, buffer) {
|
|
39410
39448
|
if (rel === "skill.json") {
|
|
39411
|
-
|
|
39412
|
-
return;
|
|
39449
|
+
return { rel, content: new TextEncoder().encode(canonicalizeManifest(new TextDecoder().decode(buffer))) };
|
|
39413
39450
|
}
|
|
39414
39451
|
if (looksLikeText(buffer)) {
|
|
39415
39452
|
const normalized = normalizeLineEndings(new TextDecoder().decode(buffer));
|
|
39416
|
-
|
|
39417
|
-
return;
|
|
39453
|
+
return { rel, content: new TextEncoder().encode(normalized) };
|
|
39418
39454
|
}
|
|
39419
|
-
|
|
39455
|
+
return { rel, content: buffer };
|
|
39420
39456
|
}
|
|
39421
39457
|
function computeContentHash(skillPath) {
|
|
39422
|
-
|
|
39423
|
-
|
|
39424
|
-
|
|
39425
|
-
|
|
39426
|
-
|
|
39427
|
-
|
|
39458
|
+
return hashBundleFiles(collectBundleFiles(skillPath));
|
|
39459
|
+
}
|
|
39460
|
+
function* bundleHashParts(files) {
|
|
39461
|
+
for (const file of files) {
|
|
39462
|
+
yield new TextEncoder().encode(file.rel);
|
|
39463
|
+
yield new TextEncoder().encode(`\x00${file.content.length}\x00`);
|
|
39464
|
+
yield file.content;
|
|
39465
|
+
yield new TextEncoder().encode("\x00");
|
|
39428
39466
|
}
|
|
39429
|
-
|
|
39467
|
+
yield new TextEncoder().encode("\x00");
|
|
39468
|
+
}
|
|
39469
|
+
function hashBundleFiles(files) {
|
|
39470
|
+
const hash = createHash(CONTENT_HASH_ALGORITHM);
|
|
39471
|
+
for (const part of bundleHashParts(files))
|
|
39472
|
+
hash.update(part);
|
|
39430
39473
|
return hash.digest("hex");
|
|
39431
39474
|
}
|
|
39432
39475
|
function verifyContentHash(skillPath, manifest) {
|
|
@@ -39463,7 +39506,7 @@ function hashSkillMarkdown(content) {
|
|
|
39463
39506
|
function hashSkillMarkdownFile(path) {
|
|
39464
39507
|
return hashSkillMarkdown(readFileSync5(path, "utf-8"));
|
|
39465
39508
|
}
|
|
39466
|
-
var CONTENT_HASH_ALGORITHM = "sha256", HASH_EXCLUDE_DIRS, HASH_COVERAGE;
|
|
39509
|
+
var CONTENT_HASH_ALGORITHM = "sha256", HASH_EXCLUDE_DIRS, HASH_COVERAGE, CONTENT_HASH_LIMITS, typedArrayPrototype, byteLengthOf, bufferOf;
|
|
39467
39510
|
var init_skill_hash = __esm(() => {
|
|
39468
39511
|
HASH_EXCLUDE_DIRS = new Set([".git", "node_modules", "dist", "build", ".turbo"]);
|
|
39469
39512
|
HASH_COVERAGE = [
|
|
@@ -39477,6 +39520,20 @@ var init_skill_hash = __esm(() => {
|
|
|
39477
39520
|
"assets",
|
|
39478
39521
|
"references"
|
|
39479
39522
|
];
|
|
39523
|
+
CONTENT_HASH_LIMITS = Object.freeze({
|
|
39524
|
+
entries: 1024,
|
|
39525
|
+
rawBytes: 64 * 1024 * 1024,
|
|
39526
|
+
normalizedBytes: 64 * 1024 * 1024,
|
|
39527
|
+
fileBytes: 16 * 1024 * 1024,
|
|
39528
|
+
normalizedFileBytes: 16 * 1024 * 1024,
|
|
39529
|
+
pathBytes: 100,
|
|
39530
|
+
manifestBytes: 16 * 1024,
|
|
39531
|
+
manifestDepth: 64,
|
|
39532
|
+
timeoutMs: 5000
|
|
39533
|
+
});
|
|
39534
|
+
typedArrayPrototype = Object.getPrototypeOf(Uint8Array.prototype);
|
|
39535
|
+
byteLengthOf = Object.getOwnPropertyDescriptor(typedArrayPrototype, "byteLength").get;
|
|
39536
|
+
bufferOf = Object.getOwnPropertyDescriptor(typedArrayPrototype, "buffer").get;
|
|
39480
39537
|
});
|
|
39481
39538
|
|
|
39482
39539
|
// src/lib/portable-skills-types.ts
|
|
@@ -49045,50 +49102,210 @@ var init_read_access = __esm(() => {
|
|
|
49045
49102
|
init_remote_registry();
|
|
49046
49103
|
});
|
|
49047
49104
|
|
|
49105
|
+
// src/lib/remote-invitations.ts
|
|
49106
|
+
function invitationFailure(value, status) {
|
|
49107
|
+
if (!record(value) || typeof value.code !== "string" || !Object.hasOwn(invitationFailures, value.code))
|
|
49108
|
+
return null;
|
|
49109
|
+
const code = value.code;
|
|
49110
|
+
return invitationFailures[code][0] === status ? code : null;
|
|
49111
|
+
}
|
|
49112
|
+
function invitationId(value) {
|
|
49113
|
+
return uuid(value) ? value : inputFailure();
|
|
49114
|
+
}
|
|
49115
|
+
function invitationInput(action, input) {
|
|
49116
|
+
if (!record(input))
|
|
49117
|
+
return inputFailure();
|
|
49118
|
+
const keys2 = {
|
|
49119
|
+
list: ["after"],
|
|
49120
|
+
get: ["invitationId"],
|
|
49121
|
+
issue: ["email", "role", "idempotencyKey", "confirm"],
|
|
49122
|
+
resend: ["invitationId", "expectedGeneration", "idempotencyKey", "confirm"],
|
|
49123
|
+
revoke: ["invitationId", "expectedGeneration", "confirm"],
|
|
49124
|
+
accept: ["invitationId", "token", "confirm"]
|
|
49125
|
+
};
|
|
49126
|
+
if (Object.keys(input).some((key) => !keys2[action].includes(key)) || action !== "list" && keys2[action].some((key) => !Object.hasOwn(input, key)))
|
|
49127
|
+
return inputFailure();
|
|
49128
|
+
const value = { ...input };
|
|
49129
|
+
if (action === "list") {
|
|
49130
|
+
if (value.after !== undefined && !uuid(value.after))
|
|
49131
|
+
return inputFailure();
|
|
49132
|
+
}
|
|
49133
|
+
if (["get", "resend", "revoke", "accept"].includes(action) && !uuid(value.invitationId))
|
|
49134
|
+
return inputFailure();
|
|
49135
|
+
if (!["list", "get"].includes(action) && value.confirm !== true)
|
|
49136
|
+
return inputFailure();
|
|
49137
|
+
if (["issue", "resend"].includes(action) && !uuid(value.idempotencyKey))
|
|
49138
|
+
return inputFailure();
|
|
49139
|
+
if (action === "issue") {
|
|
49140
|
+
if (typeof value.email !== "string")
|
|
49141
|
+
return inputFailure();
|
|
49142
|
+
value.email = value.email.trim().toLowerCase();
|
|
49143
|
+
if (!email(value.email) || !role(value.role))
|
|
49144
|
+
return inputFailure();
|
|
49145
|
+
}
|
|
49146
|
+
if (["resend", "revoke"].includes(action) && (!Number.isInteger(value.expectedGeneration) || Number(value.expectedGeneration) < 1 || Number(value.expectedGeneration) > 10))
|
|
49147
|
+
return inputFailure();
|
|
49148
|
+
if (action === "accept" && (typeof value.token !== "string" || !/^[A-Za-z0-9_-]{43}$/.test(value.token)))
|
|
49149
|
+
return inputFailure();
|
|
49150
|
+
return value;
|
|
49151
|
+
}
|
|
49152
|
+
function invitationRequest(action, input) {
|
|
49153
|
+
const base2 = "/api/v1/workspace/invitations", value = input;
|
|
49154
|
+
const { confirm: _confirm, invitationId: id, ...body } = value;
|
|
49155
|
+
if (action === "list")
|
|
49156
|
+
return { path: base2 + (value.after ? `?after=${value.after}` : ""), method: "GET" };
|
|
49157
|
+
if (action === "get")
|
|
49158
|
+
return { path: `${base2}/${id}`, method: "GET" };
|
|
49159
|
+
if (action === "accept")
|
|
49160
|
+
return { path: "/api/v1/account/invitations/accept", method: "POST", body: JSON.stringify({ invitationId: id, token: value.token }) };
|
|
49161
|
+
return { path: action === "issue" ? base2 : `${base2}/${id}${action === "resend" ? "/resend" : ""}`, method: action === "revoke" ? "DELETE" : "POST", body: JSON.stringify(body) };
|
|
49162
|
+
}
|
|
49163
|
+
function invalid() {
|
|
49164
|
+
throw new RemoteWorkspaceInvitationReadError;
|
|
49165
|
+
}
|
|
49166
|
+
function projection(v, organizationId) {
|
|
49167
|
+
if (!record(v) || !uuid(v.id) || v.organizationId !== organizationId || !email(v.email) || v.email !== v.email.trim().toLowerCase() || !role(v.role) || !Number.isInteger(v.generation) || Number(v.generation) < 1 || Number(v.generation) > 10 || typeof v.status !== "string" || !["pending", "expired", "accepted", "revoked"].includes(v.status) || !timestamp(v.expiresAt) || !timestamp(v.createdAt) || !record(v.delivery) || typeof v.delivery.state !== "string" || !["queued", "sending", "uncertain", "provider_accepted", "failed", "cancelled"].includes(v.delivery.state) || !Number.isInteger(v.delivery.attempts) || Number(v.delivery.attempts) < 0 || Number(v.delivery.attempts) > 5)
|
|
49168
|
+
return invalid();
|
|
49169
|
+
return {
|
|
49170
|
+
id: v.id,
|
|
49171
|
+
organizationId,
|
|
49172
|
+
email: v.email,
|
|
49173
|
+
role: v.role,
|
|
49174
|
+
generation: Number(v.generation),
|
|
49175
|
+
status: v.status,
|
|
49176
|
+
expiresAt: v.expiresAt,
|
|
49177
|
+
createdAt: v.createdAt,
|
|
49178
|
+
delivery: { state: v.delivery.state, attempts: Number(v.delivery.attempts) }
|
|
49179
|
+
};
|
|
49180
|
+
}
|
|
49181
|
+
function parseInvitationResult(action, value, input, organizationId) {
|
|
49182
|
+
if (!record(value))
|
|
49183
|
+
return invalid();
|
|
49184
|
+
const request = input;
|
|
49185
|
+
if (action === "accept") {
|
|
49186
|
+
if (!uuid(value.organizationId) || !uuid(value.membershipId) || value.accepted !== true || typeof value.changed !== "boolean")
|
|
49187
|
+
return invalid();
|
|
49188
|
+
return { organizationId: value.organizationId, membershipId: value.membershipId, accepted: true, changed: value.changed };
|
|
49189
|
+
}
|
|
49190
|
+
if (action === "list") {
|
|
49191
|
+
if (value.organizationId !== organizationId || !Array.isArray(value.invitations) || value.invitations.length > 50 || value.nextCursor !== null && !uuid(value.nextCursor))
|
|
49192
|
+
return invalid();
|
|
49193
|
+
const invitations = value.invitations.map((v) => projection(v, organizationId));
|
|
49194
|
+
if (invitations.some((v, n) => v.id <= String(n ? invitations[n - 1].id : request.after ?? "")) || value.nextCursor !== null && (invitations.length !== 50 || value.nextCursor !== invitations.at(-1)?.id))
|
|
49195
|
+
return invalid();
|
|
49196
|
+
return { organizationId, invitations, nextCursor: value.nextCursor };
|
|
49197
|
+
}
|
|
49198
|
+
const invitation = projection(value.invitation, organizationId);
|
|
49199
|
+
if (action !== "issue" && invitation.id !== request.invitationId)
|
|
49200
|
+
return invalid();
|
|
49201
|
+
if (action === "get")
|
|
49202
|
+
return { invitation };
|
|
49203
|
+
if (typeof value.changed !== "boolean")
|
|
49204
|
+
return invalid();
|
|
49205
|
+
if (action === "issue" && (invitation.email !== request.email || invitation.role !== request.role || value.changed && invitation.generation !== 1))
|
|
49206
|
+
return invalid();
|
|
49207
|
+
if (action === "resend" && (value.changed ? invitation.generation !== Number(request.expectedGeneration) + 1 : invitation.generation <= Number(request.expectedGeneration)))
|
|
49208
|
+
return invalid();
|
|
49209
|
+
if (action === "revoke" && (invitation.status !== "revoked" || invitation.generation < Number(request.expectedGeneration) || value.changed && invitation.generation !== request.expectedGeneration))
|
|
49210
|
+
return invalid();
|
|
49211
|
+
return { invitation, changed: value.changed };
|
|
49212
|
+
}
|
|
49213
|
+
var WorkspaceInvitationInputError, invitationFailures, RemoteWorkspaceInvitationError, RemoteWorkspaceInvitationUnconfirmedError, RemoteWorkspaceInvitationReadError, record = (v) => !!v && typeof v === "object" && !Array.isArray(v), uuid = (v) => typeof v === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v), role = (v) => typeof v === "string" && ["owner", "admin", "member", "viewer"].includes(v), email = (v) => typeof v === "string" && v.length <= 254 && !/[\p{Cc}\p{Cs}\u2028\u2029\s]/u.test(v) && /^[^@]+@[^@]+\.[^@]+$/.test(v), timestamp = (v) => typeof v === "string" && v.length <= 40 && /^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d(?:\.\d{1,6})?(?:Z|[+-]\d\d:\d\d)$/.test(v) && Number.isFinite(Date.parse(v)), inputFailure = () => {
|
|
49214
|
+
throw new WorkspaceInvitationInputError;
|
|
49215
|
+
};
|
|
49216
|
+
var init_remote_invitations = __esm(() => {
|
|
49217
|
+
WorkspaceInvitationInputError = class WorkspaceInvitationInputError extends Error {
|
|
49218
|
+
code = "INVITATION_INPUT_INVALID";
|
|
49219
|
+
constructor() {
|
|
49220
|
+
super("Provide only the documented invitation fields, exact lowercase IDs, expected generation and explicit confirmation. Issue and resend require your stable idempotency key.");
|
|
49221
|
+
this.name = "WorkspaceInvitationInputError";
|
|
49222
|
+
}
|
|
49223
|
+
};
|
|
49224
|
+
invitationFailures = {
|
|
49225
|
+
INVALID_REQUEST: [400, "Invitation parameters were refused."],
|
|
49226
|
+
ACCOUNT_UNAVAILABLE: [403, "Account is unavailable."],
|
|
49227
|
+
INTERACTIVE_SESSION_REQUIRED: [403, "Fresh interactive sign-in is required."],
|
|
49228
|
+
WORKSPACE_ADMIN_REQUIRED: [403, "A current workspace owner or admin is required."],
|
|
49229
|
+
INVITATION_FORBIDDEN: [403, "Your current role cannot manage this invitation."],
|
|
49230
|
+
INVITATION_UNAVAILABLE: [404, "Invitation is unavailable for this account."],
|
|
49231
|
+
INVITATION_CHANGED: [409, "Invitation changed. Read its current generation before another action."],
|
|
49232
|
+
INVITATION_EXISTS: [409, "A pending invitation already exists. Read current invitations."],
|
|
49233
|
+
ALREADY_MEMBER: [409, "An active membership already exists. An invitation cannot change its role."],
|
|
49234
|
+
IDEMPOTENCY_CONFLICT: [409, "This request key was used for different invitation parameters. Reconcile the original request."],
|
|
49235
|
+
INVITATION_LIMIT: [429, "Invitation limit reached. Wait before issuing or resending."],
|
|
49236
|
+
INVITATION_BUSY: [503, "Invitation is busy. Read its state before another action."],
|
|
49237
|
+
INVITATION_DELIVERY_UNAVAILABLE: [503, "Invitation email delivery is unavailable."]
|
|
49238
|
+
};
|
|
49239
|
+
RemoteWorkspaceInvitationError = class RemoteWorkspaceInvitationError extends Error {
|
|
49240
|
+
code;
|
|
49241
|
+
status;
|
|
49242
|
+
constructor(code) {
|
|
49243
|
+
super(invitationFailures[code][1]);
|
|
49244
|
+
this.code = code;
|
|
49245
|
+
this.name = "RemoteWorkspaceInvitationError";
|
|
49246
|
+
this.status = invitationFailures[code][0];
|
|
49247
|
+
}
|
|
49248
|
+
};
|
|
49249
|
+
RemoteWorkspaceInvitationUnconfirmedError = class RemoteWorkspaceInvitationUnconfirmedError extends Error {
|
|
49250
|
+
code = "INVITATION_UNCONFIRMED";
|
|
49251
|
+
constructor() {
|
|
49252
|
+
super("The invitation outcome is unconfirmed. Read current invitations or memberships. Reconcile issue/resend only with the same request key, parameters, server and membership; never generate a new key or retry automatically. Saved credentials are unchanged.");
|
|
49253
|
+
this.name = "RemoteWorkspaceInvitationUnconfirmedError";
|
|
49254
|
+
}
|
|
49255
|
+
};
|
|
49256
|
+
RemoteWorkspaceInvitationReadError = class RemoteWorkspaceInvitationReadError extends Error {
|
|
49257
|
+
code = "INVITATION_READ_FAILED";
|
|
49258
|
+
constructor() {
|
|
49259
|
+
super("Unable to read a valid invitation result. Check the selected server, account, current membership and permissions.");
|
|
49260
|
+
this.name = "RemoteWorkspaceInvitationReadError";
|
|
49261
|
+
}
|
|
49262
|
+
};
|
|
49263
|
+
});
|
|
49264
|
+
|
|
49048
49265
|
// src/lib/remote-workspace-selection.ts
|
|
49049
49266
|
function workspaceExpectedUserId(value) {
|
|
49050
|
-
if (!
|
|
49267
|
+
if (!uuid2(value))
|
|
49051
49268
|
throw new WorkspaceContextInputError;
|
|
49052
49269
|
return value;
|
|
49053
49270
|
}
|
|
49054
49271
|
function workspaceContext(value) {
|
|
49055
|
-
if (!
|
|
49272
|
+
if (!record2(value) || Object.keys(value).sort().join(",") !== "membershipId,userId" || !uuid2(value.userId) || !uuid2(value.membershipId))
|
|
49056
49273
|
throw new WorkspaceContextInputError;
|
|
49057
49274
|
return { userId: value.userId, membershipId: value.membershipId };
|
|
49058
49275
|
}
|
|
49059
|
-
function
|
|
49276
|
+
function invalid2() {
|
|
49060
49277
|
throw new Error(invalidWorkspaceResult);
|
|
49061
49278
|
}
|
|
49062
49279
|
function organization(v) {
|
|
49063
|
-
if (!
|
|
49064
|
-
return
|
|
49280
|
+
if (!record2(v) || !uuid2(v.id) || !text(v.slug) || !text(v.name))
|
|
49281
|
+
return invalid2();
|
|
49065
49282
|
return { id: v.id, slug: v.slug, name: v.name };
|
|
49066
49283
|
}
|
|
49067
49284
|
function parseAccountWorkspaces(value) {
|
|
49068
|
-
if (!
|
|
49069
|
-
return
|
|
49285
|
+
if (!record2(value) || !Array.isArray(value.workspaces) || !value.workspaces.length || value.workspaces.length > 1000)
|
|
49286
|
+
return invalid2();
|
|
49070
49287
|
const workspaces = value.workspaces.map((v) => {
|
|
49071
|
-
if (!
|
|
49072
|
-
return
|
|
49288
|
+
if (!record2(v) || !uuid2(v.membershipId) || !role2(v.role) || typeof v.current !== "boolean")
|
|
49289
|
+
return invalid2();
|
|
49073
49290
|
return { membershipId: v.membershipId, organization: organization(v.organization), role: v.role, current: v.current };
|
|
49074
49291
|
});
|
|
49075
49292
|
if (workspaces.filter((w) => w.current).length !== 1 || new Set(workspaces.map((w) => w.membershipId)).size !== workspaces.length || new Set(workspaces.map((w) => w.organization.id)).size !== workspaces.length)
|
|
49076
|
-
return
|
|
49293
|
+
return invalid2();
|
|
49077
49294
|
return { workspaces };
|
|
49078
49295
|
}
|
|
49079
49296
|
function parseWorkspaceIdentity(value, expectedUserId) {
|
|
49080
|
-
if (!
|
|
49081
|
-
return
|
|
49297
|
+
if (!record2(value))
|
|
49298
|
+
return invalid2();
|
|
49082
49299
|
const user = value.user;
|
|
49083
|
-
if (!
|
|
49084
|
-
return
|
|
49300
|
+
if (!record2(user) || !uuid2(user.id) || !uuid2(user.membershipId) || !text(user.email, 320) || !(user.displayName === null || text(user.displayName)) || !role2(user.role))
|
|
49301
|
+
return invalid2();
|
|
49085
49302
|
if (user.id !== expectedUserId)
|
|
49086
49303
|
throw new WorkspaceIdentityMismatchError;
|
|
49087
49304
|
return { user: { id: user.id, membershipId: user.membershipId, email: user.email, displayName: user.displayName, role: user.role }, organization: organization(value.organization) };
|
|
49088
49305
|
}
|
|
49089
49306
|
function sessionToken(value) {
|
|
49090
49307
|
if (typeof value !== "string" || !value || value.length > 8192 || /[^\x21-\x7e]/.test(value) || value.startsWith("sk_"))
|
|
49091
|
-
return
|
|
49308
|
+
return invalid2();
|
|
49092
49309
|
return value;
|
|
49093
49310
|
}
|
|
49094
49311
|
function parseWorkspaceSession(value, expected) {
|
|
@@ -49098,20 +49315,20 @@ function parseWorkspaceSession(value, expected) {
|
|
|
49098
49315
|
return { token: sessionToken(value.token), ...identity2 };
|
|
49099
49316
|
}
|
|
49100
49317
|
function parseWorkspaceLogin(value, expectedUserId) {
|
|
49101
|
-
const user =
|
|
49102
|
-
if (!
|
|
49103
|
-
return
|
|
49318
|
+
const user = record2(value) && value.user;
|
|
49319
|
+
if (!record2(value) || !record2(user) || !uuid2(user.id))
|
|
49320
|
+
return invalid2();
|
|
49104
49321
|
if (expectedUserId !== undefined && user.id !== expectedUserId)
|
|
49105
49322
|
throw new WorkspaceIdentityMismatchError;
|
|
49106
49323
|
return { token: sessionToken(value.token), userId: user.id };
|
|
49107
49324
|
}
|
|
49108
49325
|
function workspaceSelectionFailure(value, status) {
|
|
49109
|
-
if (!
|
|
49326
|
+
if (!record2(value) || typeof value.code !== "string" || !Object.hasOwn(workspaceSelectionFailures, value.code))
|
|
49110
49327
|
return null;
|
|
49111
49328
|
const code = value.code;
|
|
49112
49329
|
return workspaceSelectionFailures[code][0] === status ? code : null;
|
|
49113
49330
|
}
|
|
49114
|
-
var
|
|
49331
|
+
var record2 = (v) => !!v && typeof v === "object" && !Array.isArray(v), uuid2 = (v) => typeof v === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v), text = (v, max2 = 1024) => typeof v === "string" && !!v.trim() && v.length <= max2 && !/[\p{Cc}\p{Cs}\u2028\u2029]/u.test(v), role2 = (v) => typeof v === "string" && ["owner", "admin", "member", "viewer"].includes(v), invalidWorkspaceResult = "The server returned an invalid workspace selection result.", WorkspaceContextInputError, WorkspaceIdentityMismatchError, workspaceSelectionFailures;
|
|
49115
49332
|
var init_remote_workspace_selection = __esm(() => {
|
|
49116
49333
|
WorkspaceContextInputError = class WorkspaceContextInputError extends Error {
|
|
49117
49334
|
constructor() {
|
|
@@ -49137,7 +49354,7 @@ var init_remote_workspace_selection = __esm(() => {
|
|
|
49137
49354
|
|
|
49138
49355
|
// src/lib/remote-workspace.ts
|
|
49139
49356
|
function workspaceMembersQuery(options = {}) {
|
|
49140
|
-
if (!
|
|
49357
|
+
if (!record3(options) || Object.keys(options).some((key) => key !== "limit" && key !== "cursor") || options.limit !== undefined && (!Number.isInteger(options.limit) || options.limit < 1 || options.limit > 100) || options.cursor !== undefined && !cursor(options.cursor))
|
|
49141
49358
|
throw new Error("Use a roster limit from 1 to 100 and an unchanged continuation cursor.");
|
|
49142
49359
|
const query = new URLSearchParams;
|
|
49143
49360
|
if (options.limit !== undefined)
|
|
@@ -49146,14 +49363,14 @@ function workspaceMembersQuery(options = {}) {
|
|
|
49146
49363
|
query.set("cursor", options.cursor);
|
|
49147
49364
|
return query.size ? `?${query}` : "";
|
|
49148
49365
|
}
|
|
49149
|
-
function
|
|
49366
|
+
function timestamp2(value) {
|
|
49150
49367
|
if (typeof value !== "string" || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}Z$/.test(value))
|
|
49151
49368
|
return false;
|
|
49152
49369
|
const time = Date.parse(value);
|
|
49153
49370
|
return Number.isFinite(time) && new Date(time).toISOString().slice(0, 23) === value.slice(0, 23);
|
|
49154
49371
|
}
|
|
49155
49372
|
function parseMember(row, fail2) {
|
|
49156
|
-
if (!
|
|
49373
|
+
if (!record3(row) || !uuid3(row.membershipId) || !uuid3(row.userId) || typeof row.email !== "string" || !row.email || !(row.displayName === null || typeof row.displayName === "string") || !isRole(row.role) || !timestamp2(row.createdAt))
|
|
49157
49374
|
return fail2();
|
|
49158
49375
|
return {
|
|
49159
49376
|
membershipId: row.membershipId,
|
|
@@ -49165,12 +49382,12 @@ function parseMember(row, fail2) {
|
|
|
49165
49382
|
};
|
|
49166
49383
|
}
|
|
49167
49384
|
function mutationInput(membershipId, input, roleChange) {
|
|
49168
|
-
if (typeof membershipId !== "string" || !
|
|
49385
|
+
if (typeof membershipId !== "string" || !uuid3(membershipId) || membershipId !== membershipId.toLowerCase() || !record3(input) || Object.keys(input).sort().join(",") !== (roleChange ? "expectedRole,role" : "expectedRole"))
|
|
49169
49386
|
throw new WorkspaceMemberInputError;
|
|
49170
|
-
const expectedRole = input.expectedRole,
|
|
49171
|
-
if (!isRole(expectedRole) || roleChange && !isRole(
|
|
49387
|
+
const expectedRole = input.expectedRole, role3 = roleChange ? input.role : undefined;
|
|
49388
|
+
if (!isRole(expectedRole) || roleChange && !isRole(role3))
|
|
49172
49389
|
throw new WorkspaceMemberInputError;
|
|
49173
|
-
return { membershipId, role:
|
|
49390
|
+
return { membershipId, role: role3, expectedRole };
|
|
49174
49391
|
}
|
|
49175
49392
|
function workspaceMemberRoleInput(membershipId, input) {
|
|
49176
49393
|
const value = mutationInput(membershipId, input, true);
|
|
@@ -49180,24 +49397,24 @@ function workspaceMemberRemovalInput(membershipId, input) {
|
|
|
49180
49397
|
const value = mutationInput(membershipId, input, false);
|
|
49181
49398
|
return { membershipId: value.membershipId, body: { expectedRole: value.expectedRole } };
|
|
49182
49399
|
}
|
|
49183
|
-
function parseWorkspaceMemberRoleResult(value, membershipId,
|
|
49400
|
+
function parseWorkspaceMemberRoleResult(value, membershipId, role3) {
|
|
49184
49401
|
const fail2 = () => {
|
|
49185
49402
|
throw new Error(invalidMemberResult);
|
|
49186
49403
|
};
|
|
49187
|
-
if (!
|
|
49404
|
+
if (!record3(value) || !uuid3(value.organizationId) || typeof value.changed !== "boolean")
|
|
49188
49405
|
return fail2();
|
|
49189
49406
|
const member = parseMember(value.member, fail2);
|
|
49190
|
-
if (member.membershipId !== membershipId || member.role !==
|
|
49407
|
+
if (member.membershipId !== membershipId || member.role !== role3)
|
|
49191
49408
|
return fail2();
|
|
49192
49409
|
return { organizationId: value.organizationId, member, changed: value.changed };
|
|
49193
49410
|
}
|
|
49194
49411
|
function parseWorkspaceMemberRemovalResult(value, membershipId) {
|
|
49195
|
-
if (!
|
|
49412
|
+
if (!record3(value) || !uuid3(value.organizationId) || value.membershipId !== membershipId || value.removed !== true || typeof value.alreadyRemoved !== "boolean")
|
|
49196
49413
|
throw new Error(invalidMemberResult);
|
|
49197
49414
|
return { organizationId: value.organizationId, membershipId, removed: true, alreadyRemoved: value.alreadyRemoved };
|
|
49198
49415
|
}
|
|
49199
49416
|
function workspaceMemberFailure(value, status) {
|
|
49200
|
-
if (!
|
|
49417
|
+
if (!record3(value) || typeof value.code !== "string" || !Object.hasOwn(workspaceMemberFailures, value.code))
|
|
49201
49418
|
return null;
|
|
49202
49419
|
const code = value.code;
|
|
49203
49420
|
return workspaceMemberFailures[code][0] === status ? code : null;
|
|
@@ -49206,14 +49423,14 @@ function parseWorkspaceMembersPage(value) {
|
|
|
49206
49423
|
const fail2 = () => {
|
|
49207
49424
|
throw new Error("The server returned an invalid workspace roster.");
|
|
49208
49425
|
};
|
|
49209
|
-
if (!
|
|
49426
|
+
if (!record3(value) || !uuid3(value.organizationId) || !Array.isArray(value.members) || value.members.length > 100 || !(value.nextCursor === null || cursor(value.nextCursor)) || !value.members.length && value.nextCursor !== null)
|
|
49210
49427
|
return fail2();
|
|
49211
49428
|
const members = value.members.map((row) => parseMember(row, fail2));
|
|
49212
49429
|
if (new Set(members.map((row) => row.membershipId)).size !== members.length)
|
|
49213
49430
|
return fail2();
|
|
49214
49431
|
return { organizationId: value.organizationId, members, nextCursor: value.nextCursor };
|
|
49215
49432
|
}
|
|
49216
|
-
var
|
|
49433
|
+
var record3 = (value) => !!value && typeof value === "object" && !Array.isArray(value), cursor = (value) => typeof value === "string" && /^[A-Za-z0-9_-]{1,512}$/.test(value), uuid3 = (value) => typeof value === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i.test(value), isRole = (value) => typeof value === "string" && ["owner", "admin", "member", "viewer"].includes(value), WorkspaceMemberInputError, invalidMemberResult = "The server returned an invalid workspace member result. Refresh the roster before another action.", workspaceMemberFailures;
|
|
49217
49434
|
var init_remote_workspace = __esm(() => {
|
|
49218
49435
|
WorkspaceMemberInputError = class WorkspaceMemberInputError extends Error {
|
|
49219
49436
|
constructor() {
|
|
@@ -49235,6 +49452,75 @@ var init_remote_workspace = __esm(() => {
|
|
|
49235
49452
|
};
|
|
49236
49453
|
});
|
|
49237
49454
|
|
|
49455
|
+
// src/lib/remote-workspace-leave.ts
|
|
49456
|
+
function workspaceLeaveInput(context, input) {
|
|
49457
|
+
const target = workspaceContext(context);
|
|
49458
|
+
if (!input || typeof input !== "object" || Array.isArray(input) || Object.keys(input).sort().join(",") !== "confirm,expectedRole" || input.confirm !== true)
|
|
49459
|
+
throw new WorkspaceLeaveInputError;
|
|
49460
|
+
const captured = workspaceMemberRemovalInput(target.membershipId, { expectedRole: input.expectedRole });
|
|
49461
|
+
return {
|
|
49462
|
+
context: target,
|
|
49463
|
+
input: { expectedRole: captured.body.expectedRole, confirm: true },
|
|
49464
|
+
body: { membershipId: target.membershipId, expectedRole: captured.body.expectedRole }
|
|
49465
|
+
};
|
|
49466
|
+
}
|
|
49467
|
+
function workspaceLeaveFailure(value, status) {
|
|
49468
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
49469
|
+
return null;
|
|
49470
|
+
const code = value.code;
|
|
49471
|
+
return typeof code === "string" && Object.hasOwn(workspaceLeaveFailures, code) && workspaceLeaveFailures[code][0] === status ? code : null;
|
|
49472
|
+
}
|
|
49473
|
+
function parseWorkspaceLeaveResult(value, membershipId, organizationId) {
|
|
49474
|
+
const row = value;
|
|
49475
|
+
if (!row || typeof row !== "object" || Array.isArray(row) || row.membershipId !== membershipId || row.organizationId !== organizationId || row.removed !== true || row.signInRequired !== true)
|
|
49476
|
+
throw new RemoteWorkspaceLeaveUnconfirmedError;
|
|
49477
|
+
return { membershipId, organizationId, removed: true, signInRequired: true };
|
|
49478
|
+
}
|
|
49479
|
+
function workspaceLeaveProfileContext(membershipId, userId, profile) {
|
|
49480
|
+
const observed = profile === undefined ? undefined : workspaceContext(profile);
|
|
49481
|
+
const target = workspaceContext({ userId: userId ?? observed?.userId, membershipId });
|
|
49482
|
+
if (observed && (observed.userId !== target.userId || observed.membershipId !== target.membershipId))
|
|
49483
|
+
throw new WorkspaceIdentityMismatchError;
|
|
49484
|
+
return target;
|
|
49485
|
+
}
|
|
49486
|
+
var WorkspaceLeaveInputError, workspaceLeaveFailures, RemoteWorkspaceLeaveError, RemoteWorkspaceLeaveUnconfirmedError;
|
|
49487
|
+
var init_remote_workspace_leave = __esm(() => {
|
|
49488
|
+
init_remote_workspace_selection();
|
|
49489
|
+
init_remote_workspace();
|
|
49490
|
+
WorkspaceLeaveInputError = class WorkspaceLeaveInputError extends Error {
|
|
49491
|
+
constructor() {
|
|
49492
|
+
super("Confirm leaving the exact observed user and membership with its expected role.");
|
|
49493
|
+
this.name = "WorkspaceLeaveInputError";
|
|
49494
|
+
}
|
|
49495
|
+
};
|
|
49496
|
+
workspaceLeaveFailures = {
|
|
49497
|
+
INVALID_REQUEST: [400, "Provide the exact current membership and expected role."],
|
|
49498
|
+
ACCOUNT_UNAVAILABLE: [403, "Account is unavailable."],
|
|
49499
|
+
INTERACTIVE_SESSION_REQUIRED: [403, "Fresh interactive sign-in is required to leave a workspace."],
|
|
49500
|
+
MEMBERSHIP_ROLE_CHANGED: [409, "Your role changed. Sign in and inspect the workspace before leaving."],
|
|
49501
|
+
LAST_OWNER_REQUIRED: [409, "The workspace must retain another active owner."],
|
|
49502
|
+
LAST_WORKSPACE_REQUIRED: [409, "Another available workspace is required before leaving."],
|
|
49503
|
+
MEMBERSHIP_BUSY: [503, "Membership is busy. Inspect the workspace before another leave action."]
|
|
49504
|
+
};
|
|
49505
|
+
RemoteWorkspaceLeaveError = class RemoteWorkspaceLeaveError extends Error {
|
|
49506
|
+
code;
|
|
49507
|
+
status;
|
|
49508
|
+
constructor(code) {
|
|
49509
|
+
super(workspaceLeaveFailures[code][1]);
|
|
49510
|
+
this.code = code;
|
|
49511
|
+
this.name = "RemoteWorkspaceLeaveError";
|
|
49512
|
+
this.status = workspaceLeaveFailures[code][0];
|
|
49513
|
+
}
|
|
49514
|
+
};
|
|
49515
|
+
RemoteWorkspaceLeaveUnconfirmedError = class RemoteWorkspaceLeaveUnconfirmedError extends Error {
|
|
49516
|
+
code = "WORKSPACE_LEAVE_UNCONFIRMED";
|
|
49517
|
+
constructor() {
|
|
49518
|
+
super("The leave outcome is unconfirmed. Sign in again and inspect available memberships before another action. Do not retry automatically; saved credentials are unchanged.");
|
|
49519
|
+
this.name = "RemoteWorkspaceLeaveUnconfirmedError";
|
|
49520
|
+
}
|
|
49521
|
+
};
|
|
49522
|
+
});
|
|
49523
|
+
|
|
49238
49524
|
// src/lib/auth-store.ts
|
|
49239
49525
|
import { chmodSync, existsSync as existsSync17, mkdirSync as mkdirSync7, readFileSync as readFileSync12, renameSync as renameSync4, statSync as statSync9, unlinkSync, writeFileSync as writeFileSync7 } from "fs";
|
|
49240
49526
|
import { basename as basename4, dirname as dirname6, join as join18 } from "path";
|
|
@@ -49253,14 +49539,14 @@ function readIdentity(env3 = process.env) {
|
|
|
49253
49539
|
const parsed = JSON.parse(readFileSync12(getIdentityFilePath(env3), "utf-8"));
|
|
49254
49540
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
49255
49541
|
return {};
|
|
49256
|
-
const
|
|
49542
|
+
const record4 = parsed;
|
|
49257
49543
|
const selected = resolveSkillsApiOrigin(env3)?.origin;
|
|
49258
|
-
const bound = typeof
|
|
49544
|
+
const bound = typeof record4.apiUrl === "string" ? record4.apiUrl : readCredentialValue(SKILLS_BOUND_API_URL, env3) ?? readStoredApiUrl(env3) ?? defaultFleetGatewayBaseUrl("skills");
|
|
49259
49545
|
if (selected && normalizeSkillsApiOrigin(bound) !== selected)
|
|
49260
49546
|
return {};
|
|
49261
49547
|
const identity2 = {};
|
|
49262
49548
|
for (const field of ["email", "orgId", "orgSlug", "userId"]) {
|
|
49263
|
-
const value =
|
|
49549
|
+
const value = record4[field];
|
|
49264
49550
|
if (typeof value === "string" && value.length > 0)
|
|
49265
49551
|
identity2[field] = value;
|
|
49266
49552
|
}
|
|
@@ -49409,44 +49695,44 @@ var init_auth_store = __esm(() => {
|
|
|
49409
49695
|
|
|
49410
49696
|
// src/lib/remote-run-contract.ts
|
|
49411
49697
|
function normalizeRemoteSkillRunContract(payload, fallbackSkill) {
|
|
49412
|
-
const
|
|
49698
|
+
const record4 = isRecord3(payload) ? payload : {};
|
|
49413
49699
|
return {
|
|
49414
49700
|
contractVersion: REMOTE_SKILL_RUN_CONTRACT_VERSION,
|
|
49415
|
-
...pickString(
|
|
49416
|
-
skill: pickStringValue(
|
|
49417
|
-
...pickString(
|
|
49418
|
-
...pickString(
|
|
49419
|
-
...pickNumber(
|
|
49420
|
-
...pickString(
|
|
49421
|
-
...pickString(
|
|
49422
|
-
...pickString(
|
|
49423
|
-
...pickString(
|
|
49424
|
-
...pickNumber(
|
|
49425
|
-
...pickString(
|
|
49426
|
-
...hasOwn(
|
|
49427
|
-
...pickString(
|
|
49428
|
-
...pickString(
|
|
49429
|
-
...pickString(
|
|
49430
|
-
...pickString(
|
|
49431
|
-
...hasOwn(
|
|
49701
|
+
...pickString(record4, "id"),
|
|
49702
|
+
skill: pickStringValue(record4, "skill") ?? fallbackSkill,
|
|
49703
|
+
...pickString(record4, "requestedSlug"),
|
|
49704
|
+
...pickString(record4, "status"),
|
|
49705
|
+
...pickNumber(record4, "exitCode"),
|
|
49706
|
+
...pickString(record4, "correlationId"),
|
|
49707
|
+
...pickString(record4, "createdAt"),
|
|
49708
|
+
...pickString(record4, "startedAt"),
|
|
49709
|
+
...pickString(record4, "completedAt"),
|
|
49710
|
+
...pickNumber(record4, "durationMs"),
|
|
49711
|
+
...pickString(record4, "outputType"),
|
|
49712
|
+
...hasOwn(record4, "outputPreview") ? { outputPreview: record4.outputPreview } : {},
|
|
49713
|
+
...pickString(record4, "errorCode"),
|
|
49714
|
+
...pickString(record4, "errorMessage"),
|
|
49715
|
+
...pickString(record4, "error"),
|
|
49716
|
+
...pickString(record4, "code"),
|
|
49717
|
+
...hasOwn(record4, "details") ? { details: record4.details } : {}
|
|
49432
49718
|
};
|
|
49433
49719
|
}
|
|
49434
49720
|
function isRecord3(value) {
|
|
49435
49721
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
49436
49722
|
}
|
|
49437
|
-
function hasOwn(
|
|
49438
|
-
return Object.prototype.hasOwnProperty.call(
|
|
49723
|
+
function hasOwn(record4, key) {
|
|
49724
|
+
return Object.prototype.hasOwnProperty.call(record4, key);
|
|
49439
49725
|
}
|
|
49440
|
-
function pickString(
|
|
49441
|
-
const value = pickStringValue(
|
|
49726
|
+
function pickString(record4, key) {
|
|
49727
|
+
const value = pickStringValue(record4, key);
|
|
49442
49728
|
return value === undefined ? {} : { [key]: value };
|
|
49443
49729
|
}
|
|
49444
|
-
function pickStringValue(
|
|
49445
|
-
const value =
|
|
49730
|
+
function pickStringValue(record4, key) {
|
|
49731
|
+
const value = record4[key];
|
|
49446
49732
|
return typeof value === "string" ? value : undefined;
|
|
49447
49733
|
}
|
|
49448
|
-
function pickNumber(
|
|
49449
|
-
const value =
|
|
49734
|
+
function pickNumber(record4, key) {
|
|
49735
|
+
const value = record4[key];
|
|
49450
49736
|
return typeof value === "number" && Number.isFinite(value) ? { [key]: value } : {};
|
|
49451
49737
|
}
|
|
49452
49738
|
var REMOTE_SKILL_RUN_CONTRACT_VERSION = 1;
|
|
@@ -49888,6 +50174,77 @@ class RemoteSkillsClient {
|
|
|
49888
50174
|
}
|
|
49889
50175
|
return value;
|
|
49890
50176
|
}
|
|
50177
|
+
async leaveWorkspace(context, input) {
|
|
50178
|
+
const captured = workspaceLeaveInput(context, input);
|
|
50179
|
+
const connection = new RemoteSkillsClient(this.apiKey, this.apiUrl);
|
|
50180
|
+
const value = await connection.requestWorkspaceSelection("/api/auth/whoami");
|
|
50181
|
+
if (!value || typeof value !== "object" || value.authMethod !== "jwt")
|
|
50182
|
+
throw new RemoteWorkspaceLeaveError("INTERACTIVE_SESSION_REQUIRED");
|
|
50183
|
+
const identity2 = parseWorkspaceIdentity(value, captured.context.userId);
|
|
50184
|
+
if (identity2.user.membershipId !== captured.context.membershipId)
|
|
50185
|
+
throw new WorkspaceIdentityMismatchError;
|
|
50186
|
+
let response, body;
|
|
50187
|
+
try {
|
|
50188
|
+
response = await connection.request("/api/v1/account/workspaces/leave", { method: "POST", body: JSON.stringify(captured.body) });
|
|
50189
|
+
body = JSON.parse(new TextDecoder().decode(await readBoundedResponse(response, 4096)));
|
|
50190
|
+
} catch {
|
|
50191
|
+
throw new RemoteWorkspaceLeaveUnconfirmedError;
|
|
50192
|
+
}
|
|
50193
|
+
if (!response.ok) {
|
|
50194
|
+
const code = workspaceLeaveFailure(body, response.status);
|
|
50195
|
+
if (code)
|
|
50196
|
+
throw new RemoteWorkspaceLeaveError(code);
|
|
50197
|
+
throw new RemoteWorkspaceLeaveUnconfirmedError;
|
|
50198
|
+
}
|
|
50199
|
+
return parseWorkspaceLeaveResult(body, captured.context.membershipId, identity2.organization.id);
|
|
50200
|
+
}
|
|
50201
|
+
listWorkspaceInvitations(context, options = {}) {
|
|
50202
|
+
return this.requestWorkspaceInvitation(context, "list", options);
|
|
50203
|
+
}
|
|
50204
|
+
getWorkspaceInvitation(context, invitationId2) {
|
|
50205
|
+
return this.requestWorkspaceInvitation(context, "get", { invitationId: invitationId2 });
|
|
50206
|
+
}
|
|
50207
|
+
issueWorkspaceInvitation(context, input) {
|
|
50208
|
+
return this.requestWorkspaceInvitation(context, "issue", input);
|
|
50209
|
+
}
|
|
50210
|
+
resendWorkspaceInvitation(context, invitationId2, input) {
|
|
50211
|
+
return this.requestWorkspaceInvitation(context, "resend", { ...input, invitationId: invitationId2 });
|
|
50212
|
+
}
|
|
50213
|
+
revokeWorkspaceInvitation(context, invitationId2, input) {
|
|
50214
|
+
return this.requestWorkspaceInvitation(context, "revoke", { ...input, invitationId: invitationId2 });
|
|
50215
|
+
}
|
|
50216
|
+
acceptWorkspaceInvitation(context, invitationId2, input) {
|
|
50217
|
+
return this.requestWorkspaceInvitation(context, "accept", { ...input, invitationId: invitationId2 });
|
|
50218
|
+
}
|
|
50219
|
+
async requestWorkspaceInvitation(context, action, input) {
|
|
50220
|
+
const target = workspaceContext(context), captured = invitationInput(action, input);
|
|
50221
|
+
const connection = new RemoteSkillsClient(this.apiKey, this.apiUrl);
|
|
50222
|
+
const identityValue = await connection.requestWorkspaceSelection("/api/auth/whoami");
|
|
50223
|
+
if (!identityValue || typeof identityValue !== "object" || identityValue.authMethod !== "jwt")
|
|
50224
|
+
throw new RemoteWorkspaceInvitationError("INTERACTIVE_SESSION_REQUIRED");
|
|
50225
|
+
const identity2 = parseWorkspaceIdentity(identityValue, target.userId);
|
|
50226
|
+
if (identity2.user.membershipId !== target.membershipId)
|
|
50227
|
+
throw new WorkspaceIdentityMismatchError;
|
|
50228
|
+
const request = invitationRequest(action, captured), read = action === "list" || action === "get";
|
|
50229
|
+
let response, value;
|
|
50230
|
+
try {
|
|
50231
|
+
response = await connection.request(request.path, { method: request.method, ...request.body ? { body: request.body } : {}, credentials: "omit" });
|
|
50232
|
+
value = JSON.parse(new TextDecoder().decode(await readBoundedResponse(response, response.ok ? 64 * 1024 : 4096)));
|
|
50233
|
+
} catch {
|
|
50234
|
+
throw read ? new RemoteWorkspaceInvitationReadError : new RemoteWorkspaceInvitationUnconfirmedError;
|
|
50235
|
+
}
|
|
50236
|
+
if (!response.ok) {
|
|
50237
|
+
const code = invitationFailure(value, response.status);
|
|
50238
|
+
if (code)
|
|
50239
|
+
throw new RemoteWorkspaceInvitationError(code);
|
|
50240
|
+
throw read ? new RemoteWorkspaceInvitationReadError : new RemoteWorkspaceInvitationUnconfirmedError;
|
|
50241
|
+
}
|
|
50242
|
+
try {
|
|
50243
|
+
return parseInvitationResult(action, value, captured, identity2.organization.id);
|
|
50244
|
+
} catch {
|
|
50245
|
+
throw read ? new RemoteWorkspaceInvitationReadError : new RemoteWorkspaceInvitationUnconfirmedError;
|
|
50246
|
+
}
|
|
50247
|
+
}
|
|
49891
50248
|
async listApiKeys() {
|
|
49892
50249
|
return this.arrayResponse("/api/auth/keys");
|
|
49893
50250
|
}
|
|
@@ -50138,13 +50495,13 @@ class RemoteSkillsClient {
|
|
|
50138
50495
|
return normalizeUpdatedSincePage(await response.json());
|
|
50139
50496
|
}
|
|
50140
50497
|
}
|
|
50141
|
-
function requireOptionalString(
|
|
50142
|
-
if (
|
|
50498
|
+
function requireOptionalString(record4, field) {
|
|
50499
|
+
if (record4[field] === undefined)
|
|
50143
50500
|
return;
|
|
50144
|
-
if (typeof
|
|
50501
|
+
if (typeof record4[field] !== "string") {
|
|
50145
50502
|
throw new Error(`Remote payload did not match the expected contract (${field} must be a string when present)`);
|
|
50146
50503
|
}
|
|
50147
|
-
return
|
|
50504
|
+
return record4[field];
|
|
50148
50505
|
}
|
|
50149
50506
|
function isVersionRecord(value) {
|
|
50150
50507
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -50166,19 +50523,19 @@ function normalizePin(entry) {
|
|
|
50166
50523
|
if (!entry || typeof entry !== "object") {
|
|
50167
50524
|
throw new Error("Remote pin payload did not match the expected contract (expected an object)");
|
|
50168
50525
|
}
|
|
50169
|
-
const
|
|
50170
|
-
const slug = typeof
|
|
50526
|
+
const record4 = entry;
|
|
50527
|
+
const slug = typeof record4.slug === "string" && record4.slug.trim() ? record4.slug.trim() : undefined;
|
|
50171
50528
|
if (!slug) {
|
|
50172
50529
|
throw new Error("Remote pin payload did not match the expected contract (missing slug)");
|
|
50173
50530
|
}
|
|
50174
50531
|
let metadata;
|
|
50175
|
-
if (
|
|
50176
|
-
if (!
|
|
50532
|
+
if (record4.metadata !== undefined) {
|
|
50533
|
+
if (!record4.metadata || typeof record4.metadata !== "object" || Array.isArray(record4.metadata)) {
|
|
50177
50534
|
throw new Error("Remote pin payload did not match the expected contract (metadata must be a JSON object when present)");
|
|
50178
50535
|
}
|
|
50179
|
-
metadata =
|
|
50536
|
+
metadata = record4.metadata;
|
|
50180
50537
|
}
|
|
50181
|
-
const pinnedAt = requireOptionalString(
|
|
50538
|
+
const pinnedAt = requireOptionalString(record4, "pinnedAt");
|
|
50182
50539
|
return {
|
|
50183
50540
|
slug,
|
|
50184
50541
|
...pinnedAt !== undefined ? { pinnedAt } : {},
|
|
@@ -50195,16 +50552,16 @@ function normalizeSkillSummary(entry) {
|
|
|
50195
50552
|
if (!entry || typeof entry !== "object") {
|
|
50196
50553
|
throw new Error("Remote skill payload did not match the expected contract (expected an object)");
|
|
50197
50554
|
}
|
|
50198
|
-
const
|
|
50199
|
-
const slug = typeof
|
|
50555
|
+
const record4 = entry;
|
|
50556
|
+
const slug = typeof record4.slug === "string" && record4.slug.trim() ? record4.slug.trim() : undefined;
|
|
50200
50557
|
if (!slug) {
|
|
50201
50558
|
throw new Error("Remote skill payload did not match the expected contract (missing slug)");
|
|
50202
50559
|
}
|
|
50203
50560
|
return {
|
|
50204
50561
|
slug,
|
|
50205
|
-
...requireOptionalString(
|
|
50206
|
-
...requireOptionalString(
|
|
50207
|
-
...requireOptionalString(
|
|
50562
|
+
...requireOptionalString(record4, "name") !== undefined ? { name: requireOptionalString(record4, "name") } : {},
|
|
50563
|
+
...requireOptionalString(record4, "version") !== undefined ? { version: requireOptionalString(record4, "version") } : {},
|
|
50564
|
+
...requireOptionalString(record4, "updatedAt") !== undefined ? { updatedAt: requireOptionalString(record4, "updatedAt") } : {}
|
|
50208
50565
|
};
|
|
50209
50566
|
}
|
|
50210
50567
|
function normalizeSkillSummaryList(payload) {
|
|
@@ -50257,12 +50614,12 @@ function normalizeUpdatedSincePage(payload) {
|
|
|
50257
50614
|
if (!payload || typeof payload !== "object") {
|
|
50258
50615
|
throw new Error("Updated-since payload did not match the expected contract (expected an object)");
|
|
50259
50616
|
}
|
|
50260
|
-
const
|
|
50261
|
-
if (!Array.isArray(
|
|
50617
|
+
const record4 = payload;
|
|
50618
|
+
if (!Array.isArray(record4.skills)) {
|
|
50262
50619
|
throw new Error("Updated-since payload did not match the expected contract (missing skills array)");
|
|
50263
50620
|
}
|
|
50264
|
-
const skills =
|
|
50265
|
-
const nextCursor =
|
|
50621
|
+
const skills = record4.skills.map(normalizeSkillSummary);
|
|
50622
|
+
const nextCursor = record4.nextCursor === undefined || record4.nextCursor === null ? null : record4.nextCursor;
|
|
50266
50623
|
if (nextCursor !== null && typeof nextCursor !== "string") {
|
|
50267
50624
|
throw new Error("Updated-since payload did not match the expected contract (nextCursor must be a string or absent)");
|
|
50268
50625
|
}
|
|
@@ -50277,6 +50634,8 @@ function createRemoteSkillsClientReadOnly(env3 = process.env) {
|
|
|
50277
50634
|
}
|
|
50278
50635
|
var RemoteRouteUnsupportedError, RemoteRequestError, RemoteWorkspaceMemberError, RemoteWorkspaceSelectionError, RemoteCapabilityUnavailableError, INVALID_SKILL_VERSION_RESPONSE = "Remote skill version payload did not match the expected contract.";
|
|
50279
50636
|
var init_remote_client = __esm(() => {
|
|
50637
|
+
init_remote_invitations();
|
|
50638
|
+
init_remote_workspace_leave();
|
|
50280
50639
|
init_remote_workspace_selection();
|
|
50281
50640
|
init_remote_workspace();
|
|
50282
50641
|
init_remote_workspace();
|
|
@@ -50560,7 +50919,129 @@ function concat2(chunks) {
|
|
|
50560
50919
|
}
|
|
50561
50920
|
return merged;
|
|
50562
50921
|
}
|
|
50563
|
-
|
|
50922
|
+
function invalidBundle(message) {
|
|
50923
|
+
throw new SkillBundleInspectionError("BUNDLE_INVALID", message);
|
|
50924
|
+
}
|
|
50925
|
+
|
|
50926
|
+
class BoundedTarReader {
|
|
50927
|
+
limits;
|
|
50928
|
+
check;
|
|
50929
|
+
header = new Uint8Array(BLOCK);
|
|
50930
|
+
headerOffset = 0;
|
|
50931
|
+
pending;
|
|
50932
|
+
bodyOffset = 0;
|
|
50933
|
+
padding = 0;
|
|
50934
|
+
zeroBlocks = 0;
|
|
50935
|
+
entries = [];
|
|
50936
|
+
paths = new SkillEntryPaths;
|
|
50937
|
+
fileBytes = 0;
|
|
50938
|
+
constructor(limits, check) {
|
|
50939
|
+
this.limits = limits;
|
|
50940
|
+
this.check = check;
|
|
50941
|
+
}
|
|
50942
|
+
push(chunk2) {
|
|
50943
|
+
let offset = 0;
|
|
50944
|
+
while (offset < chunk2.byteLength) {
|
|
50945
|
+
this.check();
|
|
50946
|
+
if (this.pending) {
|
|
50947
|
+
const count = Math.min(this.pending.bytes.byteLength - this.bodyOffset, chunk2.byteLength - offset);
|
|
50948
|
+
this.pending.bytes.set(chunk2.subarray(offset, offset + count), this.bodyOffset);
|
|
50949
|
+
offset += count;
|
|
50950
|
+
this.bodyOffset += count;
|
|
50951
|
+
if (this.bodyOffset === this.pending.bytes.byteLength) {
|
|
50952
|
+
this.entries.push(this.pending);
|
|
50953
|
+
this.pending = undefined;
|
|
50954
|
+
}
|
|
50955
|
+
} else if (this.padding) {
|
|
50956
|
+
const count = Math.min(this.padding, chunk2.byteLength - offset);
|
|
50957
|
+
if (chunk2.subarray(offset, offset + count).some((byte) => byte !== 0))
|
|
50958
|
+
invalidBundle("Nonzero tar body padding");
|
|
50959
|
+
offset += count;
|
|
50960
|
+
this.padding -= count;
|
|
50961
|
+
} else {
|
|
50962
|
+
const count = Math.min(BLOCK - this.headerOffset, chunk2.byteLength - offset);
|
|
50963
|
+
this.header.set(chunk2.subarray(offset, offset + count), this.headerOffset);
|
|
50964
|
+
offset += count;
|
|
50965
|
+
this.headerOffset += count;
|
|
50966
|
+
if (this.headerOffset === BLOCK) {
|
|
50967
|
+
this.readHeader();
|
|
50968
|
+
this.headerOffset = 0;
|
|
50969
|
+
}
|
|
50970
|
+
}
|
|
50971
|
+
}
|
|
50972
|
+
}
|
|
50973
|
+
finish() {
|
|
50974
|
+
this.check();
|
|
50975
|
+
if (this.pending || this.padding || this.headerOffset || this.zeroBlocks < 2)
|
|
50976
|
+
invalidBundle("Truncated tar bundle");
|
|
50977
|
+
return this.entries;
|
|
50978
|
+
}
|
|
50979
|
+
readHeader() {
|
|
50980
|
+
this.check();
|
|
50981
|
+
const h = this.header;
|
|
50982
|
+
if (h.every((byte) => byte === 0)) {
|
|
50983
|
+
this.zeroBlocks++;
|
|
50984
|
+
return;
|
|
50985
|
+
}
|
|
50986
|
+
if (this.zeroBlocks)
|
|
50987
|
+
invalidBundle("Nonzero tar data after terminator");
|
|
50988
|
+
if (this.entries.length >= this.limits.entries)
|
|
50989
|
+
throw new SkillBundleInspectionError("BUNDLE_LIMIT", "Bundle entry limit exceeded");
|
|
50990
|
+
let checksum = 0;
|
|
50991
|
+
for (let i = 0;i < BLOCK; i++)
|
|
50992
|
+
checksum += i >= 148 && i < 156 ? 32 : h[i];
|
|
50993
|
+
if (tarOctal(h.subarray(148, 156)) !== checksum)
|
|
50994
|
+
invalidBundle("Invalid tar header checksum");
|
|
50995
|
+
if (new TextDecoder().decode(h.subarray(257, 265)) !== "ustar\x00" + "00")
|
|
50996
|
+
invalidBundle("Unsupported tar format");
|
|
50997
|
+
if (h[156] !== 48 && h[156] !== 0 || h.subarray(157, 257).some((b) => b !== 0) || h.subarray(345).some((b) => b !== 0))
|
|
50998
|
+
invalidBundle("Unsupported tar entry or path prefix");
|
|
50999
|
+
const mode = tarOctal(h.subarray(100, 108));
|
|
51000
|
+
if (mode > 511)
|
|
51001
|
+
invalidBundle("Unsupported tar permission bits");
|
|
51002
|
+
tarOctal(h.subarray(108, 116));
|
|
51003
|
+
tarOctal(h.subarray(116, 124));
|
|
51004
|
+
tarOctal(h.subarray(136, 148));
|
|
51005
|
+
const size2 = tarOctal(h.subarray(124, 136));
|
|
51006
|
+
if (size2 > this.limits.fileBytes || this.fileBytes + size2 > this.limits.decompressedBytes) {
|
|
51007
|
+
throw new SkillBundleInspectionError("BUNDLE_LIMIT", "Bundle file byte limit exceeded");
|
|
51008
|
+
}
|
|
51009
|
+
const name = h.subarray(0, 100);
|
|
51010
|
+
const end = name.indexOf(0);
|
|
51011
|
+
if (end !== -1 && name.subarray(end).some((b) => b !== 0))
|
|
51012
|
+
invalidBundle("Invalid tar path padding");
|
|
51013
|
+
const raw = end === -1 ? name : name.subarray(0, end);
|
|
51014
|
+
if (raw.byteLength > this.limits.pathBytes)
|
|
51015
|
+
throw new SkillBundleInspectionError("BUNDLE_LIMIT", "Bundle path byte limit exceeded");
|
|
51016
|
+
let path;
|
|
51017
|
+
try {
|
|
51018
|
+
path = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(raw);
|
|
51019
|
+
} catch {
|
|
51020
|
+
return invalidBundle("Invalid UTF-8 bundle path");
|
|
51021
|
+
}
|
|
51022
|
+
this.paths.add(path, this.limits.pathBytes, invalidBundle, () => {
|
|
51023
|
+
throw new SkillBundleInspectionError("BUNDLE_LIMIT", "Bundle path byte limit exceeded");
|
|
51024
|
+
});
|
|
51025
|
+
this.fileBytes += size2;
|
|
51026
|
+
this.pending = { path, mode, bytes: new Uint8Array(new ArrayBuffer(size2)) };
|
|
51027
|
+
this.bodyOffset = 0;
|
|
51028
|
+
this.padding = (BLOCK - size2 % BLOCK) % BLOCK;
|
|
51029
|
+
if (!size2) {
|
|
51030
|
+
this.entries.push(this.pending);
|
|
51031
|
+
this.pending = undefined;
|
|
51032
|
+
}
|
|
51033
|
+
}
|
|
51034
|
+
}
|
|
51035
|
+
function tarOctal(field) {
|
|
51036
|
+
const text2 = new TextDecoder().decode(field);
|
|
51037
|
+
if (!/^[0-7]+[\0 ]*$/.test(text2))
|
|
51038
|
+
invalidBundle("Invalid tar octal field");
|
|
51039
|
+
const value = Number.parseInt(text2, 8);
|
|
51040
|
+
if (!Number.isSafeInteger(value))
|
|
51041
|
+
invalidBundle("Tar integer is out of range");
|
|
51042
|
+
return value;
|
|
51043
|
+
}
|
|
51044
|
+
var BLOCK = 512, ANY_SEGMENT_EXCLUDES, ROOT_EXCLUDES, TOOL_SIDECAR_FILENAMES, CREDENTIAL_FILENAMES, CREDENTIAL_EXTENSIONS, ENV_TEMPLATE_NAMES, NON_DOTENV_EXTENSIONS, SKILL_BUNDLE_INSPECTION_LIMITS, SkillBundleInspectionError;
|
|
50564
51045
|
var init_skill_bundle = __esm(() => {
|
|
50565
51046
|
ANY_SEGMENT_EXCLUDES = new Set([
|
|
50566
51047
|
".git",
|
|
@@ -50684,6 +51165,22 @@ var init_skill_bundle = __esm(() => {
|
|
|
50684
51165
|
"tar",
|
|
50685
51166
|
"wasm"
|
|
50686
51167
|
]);
|
|
51168
|
+
SKILL_BUNDLE_INSPECTION_LIMITS = Object.freeze({
|
|
51169
|
+
compressedBytes: 16 * 1024 * 1024,
|
|
51170
|
+
decompressedBytes: 64 * 1024 * 1024,
|
|
51171
|
+
entries: 1024,
|
|
51172
|
+
fileBytes: 16 * 1024 * 1024,
|
|
51173
|
+
pathBytes: 100,
|
|
51174
|
+
timeoutMs: 5000
|
|
51175
|
+
});
|
|
51176
|
+
SkillBundleInspectionError = class SkillBundleInspectionError extends Error {
|
|
51177
|
+
code;
|
|
51178
|
+
constructor(code, message) {
|
|
51179
|
+
super(message);
|
|
51180
|
+
this.code = code;
|
|
51181
|
+
this.name = "SkillBundleInspectionError";
|
|
51182
|
+
}
|
|
51183
|
+
};
|
|
50687
51184
|
});
|
|
50688
51185
|
|
|
50689
51186
|
// src/lib/skill-version.ts
|
|
@@ -51052,16 +51549,16 @@ function installBundleAtomically(name, entries, options = {}, marker = {}) {
|
|
|
51052
51549
|
}
|
|
51053
51550
|
return { path: target, created };
|
|
51054
51551
|
}
|
|
51055
|
-
function writePullMarker(dir,
|
|
51552
|
+
function writePullMarker(dir, record4) {
|
|
51056
51553
|
const marker = {
|
|
51057
51554
|
managedBy: "@hasna/skills",
|
|
51058
|
-
skill:
|
|
51059
|
-
source:
|
|
51060
|
-
...
|
|
51061
|
-
...
|
|
51062
|
-
...
|
|
51063
|
-
...
|
|
51064
|
-
...
|
|
51555
|
+
skill: record4.skill,
|
|
51556
|
+
source: record4.source ?? "pull",
|
|
51557
|
+
...record4.version ? { version: record4.version } : {},
|
|
51558
|
+
...record4.contentHash ? { contentHash: record4.contentHash } : {},
|
|
51559
|
+
...record4.sourceCommit ? { sourceCommit: record4.sourceCommit } : {},
|
|
51560
|
+
...record4.signature ? { signature: record4.signature } : {},
|
|
51561
|
+
...record4.revisionId ? { revisionId: record4.revisionId } : {},
|
|
51065
51562
|
syncedAt: new Date().toISOString()
|
|
51066
51563
|
};
|
|
51067
51564
|
writeFileSync8(join20(dir, PULL_MARKER_FILE), `${JSON.stringify(marker, null, 2)}
|
|
@@ -51076,19 +51573,19 @@ async function safeMeta(client, slug) {
|
|
|
51076
51573
|
}
|
|
51077
51574
|
if (!raw || typeof raw !== "object")
|
|
51078
51575
|
return null;
|
|
51079
|
-
const
|
|
51080
|
-
const kind =
|
|
51081
|
-
const tags = Array.isArray(
|
|
51576
|
+
const record4 = raw;
|
|
51577
|
+
const kind = record4.kind === "instruction" || record4.kind === "executable" ? record4.kind : undefined;
|
|
51578
|
+
const tags = Array.isArray(record4.tags) ? record4.tags.filter((tag) => typeof tag === "string" && tag.trim().length > 0) : undefined;
|
|
51082
51579
|
return {
|
|
51083
|
-
...str(
|
|
51084
|
-
...str(
|
|
51085
|
-
...str(
|
|
51580
|
+
...str(record4.displayName) ? { displayName: str(record4.displayName) } : {},
|
|
51581
|
+
...str(record4.description) ? { description: str(record4.description) } : {},
|
|
51582
|
+
...str(record4.category) ? { category: str(record4.category) } : {},
|
|
51086
51583
|
...tags && tags.length ? { tags } : {},
|
|
51087
|
-
...str(
|
|
51584
|
+
...str(record4.version) ? { version: str(record4.version) } : {},
|
|
51088
51585
|
...kind ? { kind } : {},
|
|
51089
|
-
...REVISION_ID_PATTERN.test(str(
|
|
51090
|
-
...typeof
|
|
51091
|
-
...str(
|
|
51586
|
+
...REVISION_ID_PATTERN.test(str(record4.revisionId) ?? "") ? { revisionId: str(record4.revisionId) } : {},
|
|
51587
|
+
...typeof record4.skillMd === "string" && record4.skillMd.length > 0 ? { skillMd: record4.skillMd } : {},
|
|
51588
|
+
...str(record4.publishedSource) ? { publishedSource: str(record4.publishedSource) } : {}
|
|
51092
51589
|
};
|
|
51093
51590
|
}
|
|
51094
51591
|
function pickCorpusOptions(options) {
|
|
@@ -51097,8 +51594,8 @@ function pickCorpusOptions(options) {
|
|
|
51097
51594
|
function extractSlug(entry) {
|
|
51098
51595
|
if (!entry || typeof entry !== "object")
|
|
51099
51596
|
return;
|
|
51100
|
-
const
|
|
51101
|
-
return str(
|
|
51597
|
+
const record4 = entry;
|
|
51598
|
+
return str(record4.slug) ?? str(record4.name);
|
|
51102
51599
|
}
|
|
51103
51600
|
function dedupe(values2) {
|
|
51104
51601
|
return [...new Set(values2)];
|
|
@@ -53421,8 +53918,8 @@ function writeRollbackRecord(mode, entries, appDir = getDataDir()) {
|
|
|
53421
53918
|
const dir = join24(appDir, ROLLBACK_DIRNAME);
|
|
53422
53919
|
mkdirSync9(dir, { recursive: true });
|
|
53423
53920
|
const file = join24(dir, `${mode}-${Date.now()}.json`);
|
|
53424
|
-
const
|
|
53425
|
-
writeFileSync10(file, `${JSON.stringify(
|
|
53921
|
+
const record4 = { version: 1, mode, timestamp: new Date().toISOString(), entries };
|
|
53922
|
+
writeFileSync10(file, `${JSON.stringify(record4, null, 2)}
|
|
53426
53923
|
`);
|
|
53427
53924
|
return file;
|
|
53428
53925
|
}
|
|
@@ -54300,7 +54797,7 @@ function createSkillRun(params, targetDir = process.cwd()) {
|
|
|
54300
54797
|
mkdirSync10(logsDir, { recursive: true });
|
|
54301
54798
|
mkdirSync10(exportDir, { recursive: true });
|
|
54302
54799
|
mkdirSync10(join27(root, "tmp"), { recursive: true });
|
|
54303
|
-
const
|
|
54800
|
+
const record4 = {
|
|
54304
54801
|
id,
|
|
54305
54802
|
skill: skillName,
|
|
54306
54803
|
status: params.status ?? "running",
|
|
@@ -54318,10 +54815,10 @@ function createSkillRun(params, targetDir = process.cwd()) {
|
|
|
54318
54815
|
logsDir: toProjectRelative(targetDir, logsDir)
|
|
54319
54816
|
}
|
|
54320
54817
|
};
|
|
54321
|
-
const context = { targetDir, runDir, exportDir, logsDir, record:
|
|
54818
|
+
const context = { targetDir, runDir, exportDir, logsDir, record: record4 };
|
|
54322
54819
|
writeRunRecord(context);
|
|
54323
54820
|
writeArtifactsManifest(context, []);
|
|
54324
|
-
appendRunEvent(context, "created", { status:
|
|
54821
|
+
appendRunEvent(context, "created", { status: record4.status });
|
|
54325
54822
|
return context;
|
|
54326
54823
|
}
|
|
54327
54824
|
function completeSkillRun(context, patch) {
|
|
@@ -54371,9 +54868,9 @@ function listSkillRuns(targetDir = process.cwd(), limit = 50) {
|
|
|
54371
54868
|
if (!statSync14(dayDir).isDirectory())
|
|
54372
54869
|
continue;
|
|
54373
54870
|
for (const runId of readdirSync13(dayDir).sort().reverse()) {
|
|
54374
|
-
const
|
|
54375
|
-
if (
|
|
54376
|
-
records.push(
|
|
54871
|
+
const record4 = readRunRecord(join27(dayDir, runId));
|
|
54872
|
+
if (record4)
|
|
54873
|
+
records.push(record4);
|
|
54377
54874
|
if (records.length >= limit)
|
|
54378
54875
|
return records;
|
|
54379
54876
|
}
|
|
@@ -54385,9 +54882,9 @@ function findSkillRun(runId, targetDir = process.cwd()) {
|
|
|
54385
54882
|
if (!existsSync25(runsRoot))
|
|
54386
54883
|
return null;
|
|
54387
54884
|
for (const day of readdirSync13(runsRoot)) {
|
|
54388
|
-
const
|
|
54389
|
-
if (
|
|
54390
|
-
return
|
|
54885
|
+
const record4 = readRunRecord(join27(runsRoot, day, runId));
|
|
54886
|
+
if (record4)
|
|
54887
|
+
return record4;
|
|
54391
54888
|
}
|
|
54392
54889
|
return null;
|
|
54393
54890
|
}
|
|
@@ -55223,11 +55720,11 @@ function datetime(args) {
|
|
|
55223
55720
|
const timeRegex2 = `${time2}(?:${opts.join("|")})`;
|
|
55224
55721
|
return new RegExp(`^${dateSource}T(?:${timeRegex2})$`);
|
|
55225
55722
|
}
|
|
55226
|
-
var cuid, cuid2, ulid, xid, ksuid, nanoid, duration, guid,
|
|
55723
|
+
var cuid, cuid2, ulid, xid, ksuid, nanoid, duration, guid, uuid4 = (version) => {
|
|
55227
55724
|
if (!version)
|
|
55228
55725
|
return /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000)$/;
|
|
55229
55726
|
return new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${version}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`);
|
|
55230
|
-
},
|
|
55727
|
+
}, email2, _emoji = `^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`, ipv4, ipv6, cidrv4, cidrv6, base64, base64url, hostname, e164, dateSource = `(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))`, date, string2 = (params) => {
|
|
55231
55728
|
const regex2 = params ? `[\\s\\S]{${params?.minimum ?? 0},${params?.maximum ?? ""}}` : `[\\s\\S]*`;
|
|
55232
55729
|
return new RegExp(`^${regex2}$`);
|
|
55233
55730
|
}, integer, number, boolean, _null, lowercase, uppercase;
|
|
@@ -55240,7 +55737,7 @@ var init_regexes = __esm(() => {
|
|
|
55240
55737
|
nanoid = /^[a-zA-Z0-9_-]{21}$/;
|
|
55241
55738
|
duration = /^P(?:(\d+W)|(?!.*W)(?=\d|T\d)(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+([.,]\d+)?S)?)?)$/;
|
|
55242
55739
|
guid = /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$/;
|
|
55243
|
-
|
|
55740
|
+
email2 = /^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$/;
|
|
55244
55741
|
ipv4 = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
|
|
55245
55742
|
ipv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::|([0-9a-fA-F]{1,4})?::([0-9a-fA-F]{1,4}:?){0,6})$/;
|
|
55246
55743
|
cidrv4 = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/;
|
|
@@ -56017,13 +56514,13 @@ var init_schemas = __esm(() => {
|
|
|
56017
56514
|
const v = versionMap[def.version];
|
|
56018
56515
|
if (v === undefined)
|
|
56019
56516
|
throw new Error(`Invalid UUID version: "${def.version}"`);
|
|
56020
|
-
def.pattern ?? (def.pattern =
|
|
56517
|
+
def.pattern ?? (def.pattern = uuid4(v));
|
|
56021
56518
|
} else
|
|
56022
|
-
def.pattern ?? (def.pattern =
|
|
56519
|
+
def.pattern ?? (def.pattern = uuid4());
|
|
56023
56520
|
$ZodStringFormat.init(inst, def);
|
|
56024
56521
|
});
|
|
56025
56522
|
$ZodEmail = /* @__PURE__ */ $constructor("$ZodEmail", (inst, def) => {
|
|
56026
|
-
def.pattern ?? (def.pattern =
|
|
56523
|
+
def.pattern ?? (def.pattern = email2);
|
|
56027
56524
|
$ZodStringFormat.init(inst, def);
|
|
56028
56525
|
});
|
|
56029
56526
|
$ZodURL = /* @__PURE__ */ $constructor("$ZodURL", (inst, def) => {
|
|
@@ -58499,7 +58996,7 @@ function intersection2(left, right) {
|
|
|
58499
58996
|
right
|
|
58500
58997
|
});
|
|
58501
58998
|
}
|
|
58502
|
-
function
|
|
58999
|
+
function record4(keyType, valueType, params) {
|
|
58503
59000
|
return new ZodRecord2({
|
|
58504
59001
|
type: "record",
|
|
58505
59002
|
keyType,
|
|
@@ -59200,7 +59697,7 @@ var init_types2 = __esm(() => {
|
|
|
59200
59697
|
});
|
|
59201
59698
|
FormElicitationCapabilitySchema = intersection2(object2({
|
|
59202
59699
|
applyDefaults: boolean2().optional()
|
|
59203
|
-
}),
|
|
59700
|
+
}), record4(string3(), unknown()));
|
|
59204
59701
|
ElicitationCapabilitySchema = preprocess((value) => {
|
|
59205
59702
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
59206
59703
|
if (Object.keys(value).length === 0) {
|
|
@@ -59211,7 +59708,7 @@ var init_types2 = __esm(() => {
|
|
|
59211
59708
|
}, intersection2(object2({
|
|
59212
59709
|
form: FormElicitationCapabilitySchema.optional(),
|
|
59213
59710
|
url: AssertObjectSchema.optional()
|
|
59214
|
-
}),
|
|
59711
|
+
}), record4(string3(), unknown()).optional()));
|
|
59215
59712
|
ClientTasksCapabilitySchema = looseObject({
|
|
59216
59713
|
list: AssertObjectSchema.optional(),
|
|
59217
59714
|
cancel: AssertObjectSchema.optional(),
|
|
@@ -59234,7 +59731,7 @@ var init_types2 = __esm(() => {
|
|
|
59234
59731
|
}).optional()
|
|
59235
59732
|
});
|
|
59236
59733
|
ClientCapabilitiesSchema = object2({
|
|
59237
|
-
experimental:
|
|
59734
|
+
experimental: record4(string3(), AssertObjectSchema).optional(),
|
|
59238
59735
|
sampling: object2({
|
|
59239
59736
|
context: AssertObjectSchema.optional(),
|
|
59240
59737
|
tools: AssertObjectSchema.optional()
|
|
@@ -59244,7 +59741,7 @@ var init_types2 = __esm(() => {
|
|
|
59244
59741
|
listChanged: boolean2().optional()
|
|
59245
59742
|
}).optional(),
|
|
59246
59743
|
tasks: ClientTasksCapabilitySchema.optional(),
|
|
59247
|
-
extensions:
|
|
59744
|
+
extensions: record4(string3(), AssertObjectSchema).optional()
|
|
59248
59745
|
});
|
|
59249
59746
|
InitializeRequestParamsSchema = BaseRequestParamsSchema.extend({
|
|
59250
59747
|
protocolVersion: string3(),
|
|
@@ -59256,7 +59753,7 @@ var init_types2 = __esm(() => {
|
|
|
59256
59753
|
params: InitializeRequestParamsSchema
|
|
59257
59754
|
});
|
|
59258
59755
|
ServerCapabilitiesSchema = object2({
|
|
59259
|
-
experimental:
|
|
59756
|
+
experimental: record4(string3(), AssertObjectSchema).optional(),
|
|
59260
59757
|
logging: AssertObjectSchema.optional(),
|
|
59261
59758
|
completions: AssertObjectSchema.optional(),
|
|
59262
59759
|
prompts: object2({
|
|
@@ -59270,7 +59767,7 @@ var init_types2 = __esm(() => {
|
|
|
59270
59767
|
listChanged: boolean2().optional()
|
|
59271
59768
|
}).optional(),
|
|
59272
59769
|
tasks: ServerTasksCapabilitySchema.optional(),
|
|
59273
|
-
extensions:
|
|
59770
|
+
extensions: record4(string3(), AssertObjectSchema).optional()
|
|
59274
59771
|
});
|
|
59275
59772
|
InitializeResultSchema = ResultSchema.extend({
|
|
59276
59773
|
protocolVersion: string3(),
|
|
@@ -59357,7 +59854,7 @@ var init_types2 = __esm(() => {
|
|
|
59357
59854
|
ResourceContentsSchema = object2({
|
|
59358
59855
|
uri: string3(),
|
|
59359
59856
|
mimeType: optional(string3()),
|
|
59360
|
-
_meta:
|
|
59857
|
+
_meta: record4(string3(), unknown()).optional()
|
|
59361
59858
|
});
|
|
59362
59859
|
TextResourceContentsSchema = ResourceContentsSchema.extend({
|
|
59363
59860
|
text: string3()
|
|
@@ -59462,7 +59959,7 @@ var init_types2 = __esm(() => {
|
|
|
59462
59959
|
});
|
|
59463
59960
|
GetPromptRequestParamsSchema = BaseRequestParamsSchema.extend({
|
|
59464
59961
|
name: string3(),
|
|
59465
|
-
arguments:
|
|
59962
|
+
arguments: record4(string3(), string3()).optional()
|
|
59466
59963
|
});
|
|
59467
59964
|
GetPromptRequestSchema = RequestSchema.extend({
|
|
59468
59965
|
method: literal("prompts/get"),
|
|
@@ -59472,34 +59969,34 @@ var init_types2 = __esm(() => {
|
|
|
59472
59969
|
type: literal("text"),
|
|
59473
59970
|
text: string3(),
|
|
59474
59971
|
annotations: AnnotationsSchema.optional(),
|
|
59475
|
-
_meta:
|
|
59972
|
+
_meta: record4(string3(), unknown()).optional()
|
|
59476
59973
|
});
|
|
59477
59974
|
ImageContentSchema = object2({
|
|
59478
59975
|
type: literal("image"),
|
|
59479
59976
|
data: Base64Schema,
|
|
59480
59977
|
mimeType: string3(),
|
|
59481
59978
|
annotations: AnnotationsSchema.optional(),
|
|
59482
|
-
_meta:
|
|
59979
|
+
_meta: record4(string3(), unknown()).optional()
|
|
59483
59980
|
});
|
|
59484
59981
|
AudioContentSchema = object2({
|
|
59485
59982
|
type: literal("audio"),
|
|
59486
59983
|
data: Base64Schema,
|
|
59487
59984
|
mimeType: string3(),
|
|
59488
59985
|
annotations: AnnotationsSchema.optional(),
|
|
59489
|
-
_meta:
|
|
59986
|
+
_meta: record4(string3(), unknown()).optional()
|
|
59490
59987
|
});
|
|
59491
59988
|
ToolUseContentSchema = object2({
|
|
59492
59989
|
type: literal("tool_use"),
|
|
59493
59990
|
name: string3(),
|
|
59494
59991
|
id: string3(),
|
|
59495
|
-
input:
|
|
59496
|
-
_meta:
|
|
59992
|
+
input: record4(string3(), unknown()),
|
|
59993
|
+
_meta: record4(string3(), unknown()).optional()
|
|
59497
59994
|
});
|
|
59498
59995
|
EmbeddedResourceSchema = object2({
|
|
59499
59996
|
type: literal("resource"),
|
|
59500
59997
|
resource: union2([TextResourceContentsSchema, BlobResourceContentsSchema]),
|
|
59501
59998
|
annotations: AnnotationsSchema.optional(),
|
|
59502
|
-
_meta:
|
|
59999
|
+
_meta: record4(string3(), unknown()).optional()
|
|
59503
60000
|
});
|
|
59504
60001
|
ResourceLinkSchema = ResourceSchema.extend({
|
|
59505
60002
|
type: literal("resource_link")
|
|
@@ -59539,17 +60036,17 @@ var init_types2 = __esm(() => {
|
|
|
59539
60036
|
description: string3().optional(),
|
|
59540
60037
|
inputSchema: object2({
|
|
59541
60038
|
type: literal("object"),
|
|
59542
|
-
properties:
|
|
60039
|
+
properties: record4(string3(), AssertObjectSchema).optional(),
|
|
59543
60040
|
required: array(string3()).optional()
|
|
59544
60041
|
}).catchall(unknown()),
|
|
59545
60042
|
outputSchema: object2({
|
|
59546
60043
|
type: literal("object"),
|
|
59547
|
-
properties:
|
|
60044
|
+
properties: record4(string3(), AssertObjectSchema).optional(),
|
|
59548
60045
|
required: array(string3()).optional()
|
|
59549
60046
|
}).catchall(unknown()).optional(),
|
|
59550
60047
|
annotations: ToolAnnotationsSchema.optional(),
|
|
59551
60048
|
execution: ToolExecutionSchema.optional(),
|
|
59552
|
-
_meta:
|
|
60049
|
+
_meta: record4(string3(), unknown()).optional()
|
|
59553
60050
|
});
|
|
59554
60051
|
ListToolsRequestSchema = PaginatedRequestSchema.extend({
|
|
59555
60052
|
method: literal("tools/list")
|
|
@@ -59559,7 +60056,7 @@ var init_types2 = __esm(() => {
|
|
|
59559
60056
|
});
|
|
59560
60057
|
CallToolResultSchema = ResultSchema.extend({
|
|
59561
60058
|
content: array(ContentBlockSchema).default([]),
|
|
59562
|
-
structuredContent:
|
|
60059
|
+
structuredContent: record4(string3(), unknown()).optional(),
|
|
59563
60060
|
isError: boolean2().optional()
|
|
59564
60061
|
});
|
|
59565
60062
|
CompatibilityCallToolResultSchema = CallToolResultSchema.or(ResultSchema.extend({
|
|
@@ -59567,7 +60064,7 @@ var init_types2 = __esm(() => {
|
|
|
59567
60064
|
}));
|
|
59568
60065
|
CallToolRequestParamsSchema = TaskAugmentedRequestParamsSchema.extend({
|
|
59569
60066
|
name: string3(),
|
|
59570
|
-
arguments:
|
|
60067
|
+
arguments: record4(string3(), unknown()).optional()
|
|
59571
60068
|
});
|
|
59572
60069
|
CallToolRequestSchema = RequestSchema.extend({
|
|
59573
60070
|
method: literal("tools/call"),
|
|
@@ -59616,7 +60113,7 @@ var init_types2 = __esm(() => {
|
|
|
59616
60113
|
content: array(ContentBlockSchema).default([]),
|
|
59617
60114
|
structuredContent: object2({}).loose().optional(),
|
|
59618
60115
|
isError: boolean2().optional(),
|
|
59619
|
-
_meta:
|
|
60116
|
+
_meta: record4(string3(), unknown()).optional()
|
|
59620
60117
|
});
|
|
59621
60118
|
SamplingContentSchema = discriminatedUnion("type", [TextContentSchema, ImageContentSchema, AudioContentSchema]);
|
|
59622
60119
|
SamplingMessageContentBlockSchema = discriminatedUnion("type", [
|
|
@@ -59629,7 +60126,7 @@ var init_types2 = __esm(() => {
|
|
|
59629
60126
|
SamplingMessageSchema = object2({
|
|
59630
60127
|
role: RoleSchema,
|
|
59631
60128
|
content: union2([SamplingMessageContentBlockSchema, array(SamplingMessageContentBlockSchema)]),
|
|
59632
|
-
_meta:
|
|
60129
|
+
_meta: record4(string3(), unknown()).optional()
|
|
59633
60130
|
});
|
|
59634
60131
|
CreateMessageRequestParamsSchema = TaskAugmentedRequestParamsSchema.extend({
|
|
59635
60132
|
messages: array(SamplingMessageSchema),
|
|
@@ -59742,7 +60239,7 @@ var init_types2 = __esm(() => {
|
|
|
59742
60239
|
message: string3(),
|
|
59743
60240
|
requestedSchema: object2({
|
|
59744
60241
|
type: literal("object"),
|
|
59745
|
-
properties:
|
|
60242
|
+
properties: record4(string3(), PrimitiveSchemaDefinitionSchema),
|
|
59746
60243
|
required: array(string3()).optional()
|
|
59747
60244
|
})
|
|
59748
60245
|
});
|
|
@@ -59766,7 +60263,7 @@ var init_types2 = __esm(() => {
|
|
|
59766
60263
|
});
|
|
59767
60264
|
ElicitResultSchema = ResultSchema.extend({
|
|
59768
60265
|
action: _enum(["accept", "decline", "cancel"]),
|
|
59769
|
-
content: preprocess((val) => val === null ? undefined : val,
|
|
60266
|
+
content: preprocess((val) => val === null ? undefined : val, record4(string3(), union2([string3(), number2(), boolean2(), array(string3())])).optional())
|
|
59770
60267
|
});
|
|
59771
60268
|
ResourceTemplateReferenceSchema = object2({
|
|
59772
60269
|
type: literal("ref/resource"),
|
|
@@ -59783,7 +60280,7 @@ var init_types2 = __esm(() => {
|
|
|
59783
60280
|
value: string3()
|
|
59784
60281
|
}),
|
|
59785
60282
|
context: object2({
|
|
59786
|
-
arguments:
|
|
60283
|
+
arguments: record4(string3(), string3()).optional()
|
|
59787
60284
|
}).optional()
|
|
59788
60285
|
});
|
|
59789
60286
|
CompleteRequestSchema = RequestSchema.extend({
|
|
@@ -59800,7 +60297,7 @@ var init_types2 = __esm(() => {
|
|
|
59800
60297
|
RootSchema = object2({
|
|
59801
60298
|
uri: string3().startsWith("file://"),
|
|
59802
60299
|
name: string3().optional(),
|
|
59803
|
-
_meta:
|
|
60300
|
+
_meta: record4(string3(), unknown()).optional()
|
|
59804
60301
|
});
|
|
59805
60302
|
ListRootsRequestSchema = RequestSchema.extend({
|
|
59806
60303
|
method: literal("roots/list"),
|
|
@@ -67464,8 +67961,8 @@ var require_multipleOf = __commonJS((exports) => {
|
|
|
67464
67961
|
const { gen, data, schemaCode, it } = cxt;
|
|
67465
67962
|
const prec = it.opts.multipleOfPrecision;
|
|
67466
67963
|
const res = gen.let("res");
|
|
67467
|
-
const
|
|
67468
|
-
cxt.fail$data((0, codegen_1._)`(${schemaCode} === 0 || (${res} = ${data}/${schemaCode}, ${
|
|
67964
|
+
const invalid3 = prec ? (0, codegen_1._)`Math.abs(Math.round(${res}) - ${res}) > 1e-${prec}` : (0, codegen_1._)`${res} !== parseInt(${res})`;
|
|
67965
|
+
cxt.fail$data((0, codegen_1._)`(${schemaCode} === 0 || (${res} = ${data}/${schemaCode}, ${invalid3}))`);
|
|
67469
67966
|
}
|
|
67470
67967
|
};
|
|
67471
67968
|
exports.default = def;
|
|
@@ -73542,6 +74039,107 @@ var init_storage_tools = __esm(() => {
|
|
|
73542
74039
|
init_helpers();
|
|
73543
74040
|
});
|
|
73544
74041
|
|
|
74042
|
+
// src/lib/remote-invitation-recovery.ts
|
|
74043
|
+
function invitationEmailIds(invitationId2, challengeId) {
|
|
74044
|
+
if (!uuid5(invitationId2) || !uuid5(challengeId))
|
|
74045
|
+
throw new InvitationEmailInputError;
|
|
74046
|
+
return { invitationId: invitationId2, challengeId };
|
|
74047
|
+
}
|
|
74048
|
+
function invitationEmailInput(action, input) {
|
|
74049
|
+
const keys2 = ["invitationId", "token", "challengeId", "confirm", ...action === "accept" ? ["code"] : []];
|
|
74050
|
+
if (!record6(input) || Object.keys(input).length !== keys2.length || keys2.some((key) => !Object.hasOwn(input, key)))
|
|
74051
|
+
throw new InvitationEmailInputError;
|
|
74052
|
+
const value = { ...input };
|
|
74053
|
+
const ids = invitationEmailIds(value.invitationId, value.challengeId);
|
|
74054
|
+
if (value.confirm !== true || typeof value.token !== "string" || !/^[A-Za-z0-9_-]{43}$/.test(value.token) || action === "accept" && (typeof value.code !== "string" || !/^\d{6}$/.test(value.code)))
|
|
74055
|
+
throw new InvitationEmailInputError;
|
|
74056
|
+
return { ...ids, token: value.token, confirm: true, ...action === "accept" ? { code: value.code } : {} };
|
|
74057
|
+
}
|
|
74058
|
+
async function requestInvitationEmail(origin, action, input) {
|
|
74059
|
+
const value = invitationEmailInput(action, input);
|
|
74060
|
+
let target;
|
|
74061
|
+
try {
|
|
74062
|
+
target = normalizeSkillsApiOrigin(origin);
|
|
74063
|
+
} catch {
|
|
74064
|
+
throw new InvitationEmailInputError;
|
|
74065
|
+
}
|
|
74066
|
+
const body = JSON.stringify({ invitationId: value.invitationId, token: value.token, challengeId: value.challengeId, ...action === "accept" ? { code: value.code } : {} });
|
|
74067
|
+
try {
|
|
74068
|
+
const response = await fetch(`${target}/api/v1/account/invitations/email-${action}`, {
|
|
74069
|
+
method: "POST",
|
|
74070
|
+
headers: { "Content-Type": "application/json" },
|
|
74071
|
+
body,
|
|
74072
|
+
credentials: "omit",
|
|
74073
|
+
redirect: "error",
|
|
74074
|
+
cache: "no-store",
|
|
74075
|
+
referrerPolicy: "no-referrer",
|
|
74076
|
+
signal: AbortSignal.timeout(15000)
|
|
74077
|
+
});
|
|
74078
|
+
const parsed = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(await readBoundedResponse(response, 4096)));
|
|
74079
|
+
if (!response.ok && record6(parsed) && typeof parsed.code === "string" && Object.hasOwn(refusals, parsed.code)) {
|
|
74080
|
+
const code = parsed.code;
|
|
74081
|
+
if (response.status === refusals[code][0])
|
|
74082
|
+
throw new RemoteInvitationEmailError(code);
|
|
74083
|
+
}
|
|
74084
|
+
if (!record6(parsed))
|
|
74085
|
+
throw new RemoteInvitationEmailUnconfirmedError(action);
|
|
74086
|
+
if (action === "challenge" && response.status === 202 && parsed.challengeId === value.challengeId && parsed.expiresIn === 600 && typeof parsed.message === "string" && parsed.message.length <= 256) {
|
|
74087
|
+
return { challengeId: value.challengeId, message: "If this invitation is eligible, a verification code will arrive. Delivery is not confirmed.", expiresIn: 600 };
|
|
74088
|
+
}
|
|
74089
|
+
if (action === "accept" && response.status === 200 && uuid5(parsed.organizationId) && uuid5(parsed.membershipId) && parsed.accepted === true && parsed.changed === true && parsed.signInRequired === true) {
|
|
74090
|
+
return { organizationId: parsed.organizationId, membershipId: parsed.membershipId, accepted: true, changed: true, signInRequired: true };
|
|
74091
|
+
}
|
|
74092
|
+
} catch (error2) {
|
|
74093
|
+
if (error2 instanceof RemoteInvitationEmailError)
|
|
74094
|
+
throw error2;
|
|
74095
|
+
}
|
|
74096
|
+
throw new RemoteInvitationEmailUnconfirmedError(action);
|
|
74097
|
+
}
|
|
74098
|
+
function invitationEmailCustomerError(error2) {
|
|
74099
|
+
if (error2 instanceof InvitationEmailInputError || error2 instanceof RemoteInvitationEmailError || error2 instanceof RemoteInvitationEmailUnconfirmedError)
|
|
74100
|
+
return { code: error2.code, error: error2.message };
|
|
74101
|
+
return { code: "INVITATION_EMAIL_UNAVAILABLE", error: "Unable to prepare this recovery action. Check the explicit server and stable profile. No credential was saved." };
|
|
74102
|
+
}
|
|
74103
|
+
var InvitationEmailInputError, refusals, RemoteInvitationEmailError, RemoteInvitationEmailUnconfirmedError, record6 = (v) => !!v && typeof v === "object" && !Array.isArray(v), uuid5 = (v) => typeof v === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v);
|
|
74104
|
+
var init_remote_invitation_recovery = __esm(() => {
|
|
74105
|
+
init_fleet_credentials();
|
|
74106
|
+
init_remote_files();
|
|
74107
|
+
InvitationEmailInputError = class InvitationEmailInputError extends Error {
|
|
74108
|
+
code = "INVITATION_EMAIL_INPUT_INVALID";
|
|
74109
|
+
constructor() {
|
|
74110
|
+
super("Use an explicit Skills API URL, exact invitation and retained challenge IDs, secret input, and deliberate confirmation.");
|
|
74111
|
+
this.name = "InvitationEmailInputError";
|
|
74112
|
+
}
|
|
74113
|
+
};
|
|
74114
|
+
refusals = {
|
|
74115
|
+
INVALID_REQUEST: [400, "Invitation recovery parameters were refused."],
|
|
74116
|
+
ORIGIN_REQUIRED: [403, "Invitation recovery requires the configured site origin."],
|
|
74117
|
+
INVITATION_PROOF_UNAVAILABLE: [401, "Invitation proof is unavailable. Sign in or explicitly request another recovery code."],
|
|
74118
|
+
RATE_LIMITED: [429, "Invitation verification is rate limited. Wait before another deliberate action."],
|
|
74119
|
+
INVITATION_BUSY: [503, "Invitation is busy. Sign in to check membership before another deliberate action."],
|
|
74120
|
+
INVITATION_DELIVERY_UNAVAILABLE: [503, "Invitation recovery is unavailable on this service."]
|
|
74121
|
+
};
|
|
74122
|
+
RemoteInvitationEmailError = class RemoteInvitationEmailError extends Error {
|
|
74123
|
+
code;
|
|
74124
|
+
status;
|
|
74125
|
+
constructor(code) {
|
|
74126
|
+
super(refusals[code][1]);
|
|
74127
|
+
this.code = code;
|
|
74128
|
+
this.name = "RemoteInvitationEmailError";
|
|
74129
|
+
this.status = refusals[code][0];
|
|
74130
|
+
}
|
|
74131
|
+
};
|
|
74132
|
+
RemoteInvitationEmailUnconfirmedError = class RemoteInvitationEmailUnconfirmedError extends Error {
|
|
74133
|
+
action;
|
|
74134
|
+
code = "INVITATION_EMAIL_UNCONFIRMED";
|
|
74135
|
+
constructor(action) {
|
|
74136
|
+
super(action === "challenge" ? "The recovery challenge outcome is unconfirmed. Retain the same invitation, challenge ID and server. Check your inbox; never rotate the challenge or retry automatically. No delivery is confirmed." : "Invitation acceptance is unconfirmed. Use fresh ordinary sign-in to inspect available memberships. Do not retry acceptance automatically; explicitly request another recovery code only if needed. Saved credentials are unchanged.");
|
|
74137
|
+
this.action = action;
|
|
74138
|
+
this.name = "RemoteInvitationEmailUnconfirmedError";
|
|
74139
|
+
}
|
|
74140
|
+
};
|
|
74141
|
+
});
|
|
74142
|
+
|
|
73545
74143
|
// src/lib/remote-auth.ts
|
|
73546
74144
|
async function requestAuthApi(instance, path, options) {
|
|
73547
74145
|
const url = normalizeSkillsApiOrigin(instance);
|
|
@@ -73564,10 +74162,10 @@ async function requestAuthApi(instance, path, options) {
|
|
|
73564
74162
|
const text2 = await res.text();
|
|
73565
74163
|
const body = text2 ? parseJsonBody(text2) : {};
|
|
73566
74164
|
if (!res.ok) {
|
|
73567
|
-
const
|
|
73568
|
-
const detail = typeof
|
|
73569
|
-
const error2 = typeof
|
|
73570
|
-
const code = typeof
|
|
74165
|
+
const record7 = isRecord5(body) ? body : {};
|
|
74166
|
+
const detail = typeof record7.detail === "string" ? record7.detail : undefined;
|
|
74167
|
+
const error2 = typeof record7.error === "string" ? record7.error : undefined;
|
|
74168
|
+
const code = typeof record7.code === "string" ? record7.code : undefined;
|
|
73571
74169
|
throw new HostedApiError(detail || error2 || `${res.status} ${res.statusText}`, {
|
|
73572
74170
|
status: res.status,
|
|
73573
74171
|
code,
|
|
@@ -73601,11 +74199,17 @@ class RemoteSkillsAuthClient {
|
|
|
73601
74199
|
constructor(apiUrl) {
|
|
73602
74200
|
this.apiOrigin = normalizeSkillsApiOrigin(apiUrl);
|
|
73603
74201
|
}
|
|
73604
|
-
|
|
73605
|
-
return this.
|
|
74202
|
+
requestInvitationEmailChallenge(input) {
|
|
74203
|
+
return requestInvitationEmail(this.apiOrigin, "challenge", input);
|
|
74204
|
+
}
|
|
74205
|
+
acceptInvitationEmailChallenge(input) {
|
|
74206
|
+
return requestInvitationEmail(this.apiOrigin, "accept", input);
|
|
73606
74207
|
}
|
|
73607
|
-
|
|
73608
|
-
return this.request("/api/auth/
|
|
74208
|
+
requestCode(email3) {
|
|
74209
|
+
return this.request("/api/auth/login", { method: "POST", body: JSON.stringify({ email: email3 }) });
|
|
74210
|
+
}
|
|
74211
|
+
verifyCode(email3, code) {
|
|
74212
|
+
return this.request("/api/auth/verify", { method: "POST", body: JSON.stringify({ email: email3, code }) });
|
|
73609
74213
|
}
|
|
73610
74214
|
startDevice() {
|
|
73611
74215
|
return this.request("/api/auth/device/start", { method: "POST", body: JSON.stringify({ client: "skills-sdk" }) });
|
|
@@ -73613,34 +74217,34 @@ class RemoteSkillsAuthClient {
|
|
|
73613
74217
|
pollDevice(deviceCode) {
|
|
73614
74218
|
return this.request("/api/auth/device/token", { method: "POST", body: JSON.stringify({ deviceCode }) });
|
|
73615
74219
|
}
|
|
73616
|
-
async sessionClient(
|
|
74220
|
+
async sessionClient(email3, code, context) {
|
|
73617
74221
|
if (context !== undefined) {
|
|
73618
74222
|
const target = workspaceContext(context), apiOrigin2 = this.apiOrigin;
|
|
73619
|
-
const session = await this.switchWorkspace(
|
|
74223
|
+
const session = await this.switchWorkspace(email3, code, target);
|
|
73620
74224
|
return new RemoteSkillsClient(session.token, apiOrigin2);
|
|
73621
74225
|
}
|
|
73622
74226
|
const apiOrigin = this.apiOrigin;
|
|
73623
|
-
if (!
|
|
74227
|
+
if (!email3.includes("@") || !/^\d{6}$/.test(code))
|
|
73624
74228
|
throw new Error("Fresh email and six-digit verification code are required to manage this account");
|
|
73625
|
-
const login = await this.verifyCode(
|
|
74229
|
+
const login = await this.verifyCode(email3, code);
|
|
73626
74230
|
if (!login || typeof login.token !== "string" || !login.token)
|
|
73627
74231
|
throw new Error("The server did not return an authorized account session");
|
|
73628
74232
|
return new RemoteSkillsClient(login.token, apiOrigin);
|
|
73629
74233
|
}
|
|
73630
|
-
async listAccountWorkspaces(
|
|
73631
|
-
const login = await this.workspaceLogin(
|
|
74234
|
+
async listAccountWorkspaces(email3, code, expectedUserId) {
|
|
74235
|
+
const login = await this.workspaceLogin(email3, code, expectedUserId);
|
|
73632
74236
|
const result2 = await new RemoteSkillsClient(login.token, login.apiOrigin).listAccountWorkspaces(login.userId);
|
|
73633
74237
|
return { userId: login.userId, ...result2 };
|
|
73634
74238
|
}
|
|
73635
|
-
async switchWorkspace(
|
|
74239
|
+
async switchWorkspace(email3, code, context) {
|
|
73636
74240
|
const target = workspaceContext(context);
|
|
73637
|
-
const login = await this.workspaceLogin(
|
|
74241
|
+
const login = await this.workspaceLogin(email3, code, target.userId);
|
|
73638
74242
|
return new RemoteSkillsClient(login.token, login.apiOrigin).switchWorkspace(target);
|
|
73639
74243
|
}
|
|
73640
|
-
async workspaceLogin(
|
|
74244
|
+
async workspaceLogin(email3, code, expectedUserId) {
|
|
73641
74245
|
const expected = expectedUserId === undefined ? undefined : workspaceExpectedUserId(expectedUserId);
|
|
73642
74246
|
const apiOrigin = this.apiOrigin;
|
|
73643
|
-
if (typeof
|
|
74247
|
+
if (typeof email3 !== "string" || !email3.includes("@") || typeof code !== "string" || !/^\d{6}$/.test(code))
|
|
73644
74248
|
throw new Error("Fresh email and six-digit verification code are required to manage this account");
|
|
73645
74249
|
let response;
|
|
73646
74250
|
try {
|
|
@@ -73650,7 +74254,7 @@ class RemoteSkillsAuthClient {
|
|
|
73650
74254
|
credentials: "omit",
|
|
73651
74255
|
signal: AbortSignal.timeout(15000),
|
|
73652
74256
|
headers: { "Content-Type": "application/json" },
|
|
73653
|
-
body: JSON.stringify({ email:
|
|
74257
|
+
body: JSON.stringify({ email: email3, code })
|
|
73654
74258
|
});
|
|
73655
74259
|
} catch {
|
|
73656
74260
|
throw new HostedApiError("Unable to verify the Skills account.");
|
|
@@ -73667,36 +74271,67 @@ class RemoteSkillsAuthClient {
|
|
|
73667
74271
|
}
|
|
73668
74272
|
return { ...parseWorkspaceLogin(value, expected), apiOrigin };
|
|
73669
74273
|
}
|
|
73670
|
-
async
|
|
74274
|
+
async listWorkspaceInvitations(email3, code, context, options = {}) {
|
|
74275
|
+
const target = workspaceContext(context), captured = invitationInput("list", options);
|
|
74276
|
+
return (await this.sessionClient(email3, code, target)).listWorkspaceInvitations(target, captured);
|
|
74277
|
+
}
|
|
74278
|
+
async getWorkspaceInvitation(email3, code, context, invitationId2) {
|
|
74279
|
+
const target = workspaceContext(context), captured = invitationInput("get", { invitationId: invitationId2 });
|
|
74280
|
+
return (await this.sessionClient(email3, code, target)).getWorkspaceInvitation(target, captured.invitationId);
|
|
74281
|
+
}
|
|
74282
|
+
async issueWorkspaceInvitation(email3, code, context, input) {
|
|
74283
|
+
const target = workspaceContext(context), captured = invitationInput("issue", input);
|
|
74284
|
+
return (await this.sessionClient(email3, code, target)).issueWorkspaceInvitation(target, captured);
|
|
74285
|
+
}
|
|
74286
|
+
async resendWorkspaceInvitation(email3, code, context, invitationId2, input) {
|
|
74287
|
+
const target = workspaceContext(context), captured = invitationInput("resend", { ...input, invitationId: invitationId2 });
|
|
74288
|
+
const { invitationId: id, ...options } = captured;
|
|
74289
|
+
return (await this.sessionClient(email3, code, target)).resendWorkspaceInvitation(target, id, options);
|
|
74290
|
+
}
|
|
74291
|
+
async revokeWorkspaceInvitation(email3, code, context, invitationId2, input) {
|
|
74292
|
+
const target = workspaceContext(context), captured = invitationInput("revoke", { ...input, invitationId: invitationId2 });
|
|
74293
|
+
const { invitationId: id, ...options } = captured;
|
|
74294
|
+
return (await this.sessionClient(email3, code, target)).revokeWorkspaceInvitation(target, id, options);
|
|
74295
|
+
}
|
|
74296
|
+
async acceptWorkspaceInvitation(email3, code, context, invitationId2, input) {
|
|
74297
|
+
const target = workspaceContext(context), captured = invitationInput("accept", { ...input, invitationId: invitationId2 });
|
|
74298
|
+
const { invitationId: id, ...options } = captured;
|
|
74299
|
+
return (await this.sessionClient(email3, code, target)).acceptWorkspaceInvitation(target, id, options);
|
|
74300
|
+
}
|
|
74301
|
+
async createApiKey(email3, code, name, scopes, context) {
|
|
73671
74302
|
const capturedScopes = scopes === undefined ? undefined : [...scopes];
|
|
73672
|
-
return (await this.sessionClient(
|
|
74303
|
+
return (await this.sessionClient(email3, code, context)).createApiKey(name, capturedScopes);
|
|
73673
74304
|
}
|
|
73674
|
-
async listApiKeys(
|
|
73675
|
-
return (await this.sessionClient(
|
|
74305
|
+
async listApiKeys(email3, code, context) {
|
|
74306
|
+
return (await this.sessionClient(email3, code, context)).listApiKeys();
|
|
73676
74307
|
}
|
|
73677
|
-
async revokeApiKey(
|
|
73678
|
-
return (await this.sessionClient(
|
|
74308
|
+
async revokeApiKey(email3, code, keyId, context) {
|
|
74309
|
+
return (await this.sessionClient(email3, code, context)).revokeApiKey(keyId);
|
|
73679
74310
|
}
|
|
73680
|
-
async updateProfile(
|
|
74311
|
+
async updateProfile(email3, code, input, context) {
|
|
73681
74312
|
const body = customerNamePatch(input, "displayName");
|
|
73682
|
-
return (await this.sessionClient(
|
|
74313
|
+
return (await this.sessionClient(email3, code, context)).updateProfile({ displayName: body.displayName });
|
|
73683
74314
|
}
|
|
73684
|
-
async updateCurrentWorkspace(
|
|
74315
|
+
async updateCurrentWorkspace(email3, code, input, context) {
|
|
73685
74316
|
const body = customerNamePatch(input, "name");
|
|
73686
|
-
return (await this.sessionClient(
|
|
74317
|
+
return (await this.sessionClient(email3, code, context)).updateCurrentWorkspace({ name: body.name });
|
|
73687
74318
|
}
|
|
73688
|
-
async listWorkspaceMembers(
|
|
74319
|
+
async listWorkspaceMembers(email3, code, options = {}, context) {
|
|
73689
74320
|
workspaceMembersQuery(options);
|
|
73690
74321
|
const captured = { ...options };
|
|
73691
|
-
return (await this.sessionClient(
|
|
74322
|
+
return (await this.sessionClient(email3, code, context)).listWorkspaceMembers(captured);
|
|
73692
74323
|
}
|
|
73693
|
-
async setWorkspaceMemberRole(
|
|
74324
|
+
async setWorkspaceMemberRole(email3, code, membershipId, input, context) {
|
|
73694
74325
|
const captured = workspaceMemberRoleInput(membershipId, input);
|
|
73695
|
-
return (await this.sessionClient(
|
|
74326
|
+
return (await this.sessionClient(email3, code, context)).setWorkspaceMemberRole(captured.membershipId, captured.body);
|
|
74327
|
+
}
|
|
74328
|
+
async leaveWorkspace(email3, code, context, input) {
|
|
74329
|
+
const captured = workspaceLeaveInput(context, input);
|
|
74330
|
+
return (await this.sessionClient(email3, code, captured.context)).leaveWorkspace(captured.context, captured.input);
|
|
73696
74331
|
}
|
|
73697
|
-
async removeWorkspaceMember(
|
|
74332
|
+
async removeWorkspaceMember(email3, code, membershipId, input, context) {
|
|
73698
74333
|
const captured = workspaceMemberRemovalInput(membershipId, input);
|
|
73699
|
-
return (await this.sessionClient(
|
|
74334
|
+
return (await this.sessionClient(email3, code, context)).removeWorkspaceMember(captured.membershipId, captured.body);
|
|
73700
74335
|
}
|
|
73701
74336
|
request(path, options) {
|
|
73702
74337
|
if (!["/api/auth/login", "/api/auth/verify", "/api/auth/device/start", "/api/auth/device/token", "/api/auth/keys", "/api/auth/whoami"].includes(path))
|
|
@@ -73706,6 +74341,9 @@ class RemoteSkillsAuthClient {
|
|
|
73706
74341
|
}
|
|
73707
74342
|
var MAX_ERROR_DETAIL_LENGTH = 200, HostedApiError;
|
|
73708
74343
|
var init_remote_auth = __esm(() => {
|
|
74344
|
+
init_remote_invitation_recovery();
|
|
74345
|
+
init_remote_invitations();
|
|
74346
|
+
init_remote_workspace_leave();
|
|
73709
74347
|
init_remote_workspace_selection();
|
|
73710
74348
|
init_remote_files();
|
|
73711
74349
|
init_remote_workspace();
|
|
@@ -73851,20 +74489,20 @@ async function prepareWorkspaceEnrollment(membershipId, source = process.env) {
|
|
|
73851
74489
|
return {
|
|
73852
74490
|
profile,
|
|
73853
74491
|
origin,
|
|
73854
|
-
async complete(
|
|
74492
|
+
async complete(email3, code) {
|
|
73855
74493
|
unchanged2();
|
|
73856
|
-
if (!
|
|
74494
|
+
if (!email3.includes("@") || !/^\d{6}$/.test(code))
|
|
73857
74495
|
return fail2("A fresh email and six-digit verification code are required.");
|
|
73858
|
-
if (expected && expected.user.email.toLowerCase() !==
|
|
74496
|
+
if (expected && expected.user.email.toLowerCase() !== email3.toLowerCase())
|
|
73859
74497
|
return fail2("This profile belongs to another account. Use a different profile or ordinary replacement login.");
|
|
73860
74498
|
let issued = false;
|
|
73861
74499
|
try {
|
|
73862
|
-
const result2 = await new RemoteSkillsAuthClient(origin).verifyCode(
|
|
74500
|
+
const result2 = await new RemoteSkillsAuthClient(origin).verifyCode(email3, code);
|
|
73863
74501
|
const login = parseWorkspaceLogin(result2, expected?.user.id);
|
|
73864
74502
|
if (result2.firstLogin === true)
|
|
73865
74503
|
return fail2("This sign-in created a new account using the server signup policy. Finish ordinary account login before enrolling a workspace profile.");
|
|
73866
74504
|
const session = await new RemoteSkillsClient(login.token, origin).switchWorkspace({ userId: login.userId, membershipId });
|
|
73867
|
-
if (session.user.email.toLowerCase() !==
|
|
74505
|
+
if (session.user.email.toLowerCase() !== email3.toLowerCase())
|
|
73868
74506
|
return fail2("The verified account does not match the requested email.");
|
|
73869
74507
|
if (session.user.role === "viewer")
|
|
73870
74508
|
return fail2("Viewer memberships cannot enroll API keys.");
|
|
@@ -73948,8 +74586,103 @@ var init_workspace_profile = __esm(() => {
|
|
|
73948
74586
|
};
|
|
73949
74587
|
});
|
|
73950
74588
|
|
|
74589
|
+
// src/lib/invitation-customer-action.ts
|
|
74590
|
+
function invitationProfileContext(userId, membershipId, profile) {
|
|
74591
|
+
const target = workspaceContext({ userId, membershipId });
|
|
74592
|
+
if (profile && (profile.userId !== target.userId || profile.membershipId !== target.membershipId))
|
|
74593
|
+
throw new WorkspaceIdentityMismatchError;
|
|
74594
|
+
return target;
|
|
74595
|
+
}
|
|
74596
|
+
async function invokeFreshInvitation(client, email3, code, context, action, input) {
|
|
74597
|
+
const target = workspaceContext(context), captured = invitationInput(action, input);
|
|
74598
|
+
let result2;
|
|
74599
|
+
switch (action) {
|
|
74600
|
+
case "list":
|
|
74601
|
+
result2 = await client.listWorkspaceInvitations(email3, code, target, captured);
|
|
74602
|
+
break;
|
|
74603
|
+
case "get":
|
|
74604
|
+
result2 = await client.getWorkspaceInvitation(email3, code, target, captured.invitationId);
|
|
74605
|
+
break;
|
|
74606
|
+
case "issue":
|
|
74607
|
+
result2 = await client.issueWorkspaceInvitation(email3, code, target, captured);
|
|
74608
|
+
break;
|
|
74609
|
+
case "resend": {
|
|
74610
|
+
const { invitationId: invitationId2, ...options } = captured;
|
|
74611
|
+
result2 = await client.resendWorkspaceInvitation(email3, code, target, invitationId2, options);
|
|
74612
|
+
break;
|
|
74613
|
+
}
|
|
74614
|
+
case "revoke": {
|
|
74615
|
+
const { invitationId: invitationId2, ...options } = captured;
|
|
74616
|
+
result2 = await client.revokeWorkspaceInvitation(email3, code, target, invitationId2, options);
|
|
74617
|
+
break;
|
|
74618
|
+
}
|
|
74619
|
+
case "accept": {
|
|
74620
|
+
const { invitationId: invitationId2, ...options } = captured;
|
|
74621
|
+
result2 = await client.acceptWorkspaceInvitation(email3, code, target, invitationId2, options);
|
|
74622
|
+
break;
|
|
74623
|
+
}
|
|
74624
|
+
default:
|
|
74625
|
+
throw new WorkspaceInvitationInputError;
|
|
74626
|
+
}
|
|
74627
|
+
return result2;
|
|
74628
|
+
}
|
|
74629
|
+
function invitationCustomerError(error2) {
|
|
74630
|
+
if (error2 instanceof WorkspaceInvitationInputError || error2 instanceof RemoteWorkspaceInvitationError || error2 instanceof RemoteWorkspaceInvitationUnconfirmedError || error2 instanceof RemoteWorkspaceInvitationReadError)
|
|
74631
|
+
return { code: error2.code, error: error2.message };
|
|
74632
|
+
return { code: "INVITATION_VERIFICATION_FAILED", error: "Invitation verification failed. Check the selected server, profile, exact user and current membership, then obtain a fresh code. No invitation result was confirmed; saved credentials are unchanged." };
|
|
74633
|
+
}
|
|
74634
|
+
var init_invitation_customer_action = __esm(() => {
|
|
74635
|
+
init_remote_workspace_selection();
|
|
74636
|
+
init_remote_invitations();
|
|
74637
|
+
});
|
|
74638
|
+
|
|
74639
|
+
// src/mcp/remote-invitation-tools.ts
|
|
74640
|
+
function registerRemoteInvitationTools(server) {
|
|
74641
|
+
const uuid6 = exports_external.string().regex(/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/);
|
|
74642
|
+
const verification = { userId: uuid6, membershipId: uuid6, email: exports_external.string().email().max(254), code: exports_external.string().regex(/^\d{6}$/) };
|
|
74643
|
+
const schemas4 = {
|
|
74644
|
+
list: exports_external.object({ ...verification, after: uuid6.optional() }).strict(),
|
|
74645
|
+
get: exports_external.object({ ...verification, invitationId: uuid6 }).strict(),
|
|
74646
|
+
issue: exports_external.object({ ...verification, recipient: exports_external.string().email().max(254), role: exports_external.enum(["owner", "admin", "member", "viewer"]), idempotencyKey: uuid6, confirm: exports_external.literal(true) }).strict(),
|
|
74647
|
+
resend: exports_external.object({ ...verification, invitationId: uuid6, expectedGeneration: exports_external.number().int().min(1).max(10), idempotencyKey: uuid6, confirm: exports_external.literal(true) }).strict(),
|
|
74648
|
+
revoke: exports_external.object({ ...verification, invitationId: uuid6, expectedGeneration: exports_external.number().int().min(1).max(10), confirm: exports_external.literal(true) }).strict(),
|
|
74649
|
+
accept: exports_external.object({ ...verification, invitationId: uuid6, token: exports_external.string().regex(/^[A-Za-z0-9_-]{43}$/).describe("Secret from the invitation email; supplied only in the MCP request, never returned or saved."), confirm: exports_external.literal(true) }).strict()
|
|
74650
|
+
};
|
|
74651
|
+
for (const action of ["list", "get", "issue", "resend", "revoke", "accept"]) {
|
|
74652
|
+
const read = action === "list" || action === "get";
|
|
74653
|
+
server.registerTool(action === "list" ? "list_workspace_invitations" : `${action}_workspace_invitation`, {
|
|
74654
|
+
title: `${action[0].toUpperCase() + action.slice(1)} Workspace Invitation${action === "list" ? "s" : ""}`,
|
|
74655
|
+
description: "Use fresh verification bound to the exact observed user/current membership and any selected profile. Mutations require confirm=true; issue/resend require a stable caller request key. Never retry uncertain outcomes automatically. Acceptance does not switch workspace or create credentials. Zero-membership account recovery is not supported by this flow.",
|
|
74656
|
+
annotations: { destructiveHint: !read, idempotentHint: true, readOnlyHint: read },
|
|
74657
|
+
inputSchema: schemas4[action]
|
|
74658
|
+
}, async (value) => {
|
|
74659
|
+
try {
|
|
74660
|
+
const { userId, membershipId, email: email3, code, recipient, ...rest2 } = value;
|
|
74661
|
+
const input = invitationInput(action, action === "issue" ? { ...rest2, email: recipient } : rest2);
|
|
74662
|
+
const context = invitationProfileContext(String(userId), String(membershipId));
|
|
74663
|
+
const target = await captureProfileWorkspace("Manage invitations");
|
|
74664
|
+
invitationProfileContext(context.userId, context.membershipId, target.context);
|
|
74665
|
+
target.unchanged();
|
|
74666
|
+
return mcpJson(await invokeFreshInvitation(new RemoteSkillsAuthClient(target.origin), String(email3), String(code), context, action, input));
|
|
74667
|
+
} catch (error2) {
|
|
74668
|
+
const result2 = invitationCustomerError(error2);
|
|
74669
|
+
return mcpError(result2.code, result2.error);
|
|
74670
|
+
}
|
|
74671
|
+
});
|
|
74672
|
+
}
|
|
74673
|
+
}
|
|
74674
|
+
var init_remote_invitation_tools = __esm(() => {
|
|
74675
|
+
init_zod();
|
|
74676
|
+
init_remote_auth();
|
|
74677
|
+
init_workspace_profile();
|
|
74678
|
+
init_invitation_customer_action();
|
|
74679
|
+
init_remote_invitations();
|
|
74680
|
+
init_helpers();
|
|
74681
|
+
});
|
|
74682
|
+
|
|
73951
74683
|
// src/mcp/remote-customer-tools.ts
|
|
73952
74684
|
function registerRemoteCustomerTools(server) {
|
|
74685
|
+
registerRemoteInvitationTools(server);
|
|
73953
74686
|
const memberRole = exports_external.enum(["owner", "admin", "member", "viewer"]);
|
|
73954
74687
|
const memberInput = {
|
|
73955
74688
|
membershipId: exports_external.string().regex(/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/),
|
|
@@ -73957,13 +74690,25 @@ function registerRemoteCustomerTools(server) {
|
|
|
73957
74690
|
email: exports_external.string().email(),
|
|
73958
74691
|
code: exports_external.string().regex(/^\d{6}$/)
|
|
73959
74692
|
};
|
|
74693
|
+
server.registerTool("leave_workspace", {
|
|
74694
|
+
title: "Leave Current Workspace",
|
|
74695
|
+
description: "Leave exactly the observed user and membership with confirm=true and fresh verification. The server enforces last-owner and last-workspace safeguards. Sign in again afterwards; no automatic retry or saved-profile deletion.",
|
|
74696
|
+
annotations: { destructiveHint: true, idempotentHint: false, readOnlyHint: false },
|
|
74697
|
+
inputSchema: exports_external.object({ ...memberInput, userId: memberInput.membershipId, confirm: exports_external.literal(true) }).strict()
|
|
74698
|
+
}, async ({ membershipId, userId, expectedRole, email: email3, code, confirm }) => {
|
|
74699
|
+
try {
|
|
74700
|
+
return mcpJson(await freshAccount("Leave workspace", (client, context) => client.leaveWorkspace(email3, code, workspaceLeaveProfileContext(membershipId, userId, context), { expectedRole, confirm })));
|
|
74701
|
+
} catch (error2) {
|
|
74702
|
+
return error2 instanceof RemoteWorkspaceLeaveError || error2 instanceof RemoteWorkspaceLeaveUnconfirmedError ? mcpError(error2.code, error2.message) : mcpError("WORKSPACE_LEAVE_UNCONFIRMED", "Leaving could not be confirmed. Check the selected profile and exact membership, sign in again and inspect available workspaces before another action. Do not retry automatically; saved credentials are unchanged.");
|
|
74703
|
+
}
|
|
74704
|
+
});
|
|
73960
74705
|
server.registerTool("set_workspace_member_role", {
|
|
73961
74706
|
title: "Set Current Workspace Member Role",
|
|
73962
74707
|
description: "Change exactly this membership incarnation with its observed expectedRole and fresh verification. The server enforces owner/admin policy. No automatic refresh or retry; saved credentials stay unchanged.",
|
|
73963
74708
|
inputSchema: exports_external.object({ ...memberInput, role: memberRole }).strict()
|
|
73964
|
-
}, async ({ membershipId, role:
|
|
74709
|
+
}, async ({ membershipId, role: role3, expectedRole, email: email3, code }) => {
|
|
73965
74710
|
try {
|
|
73966
|
-
return mcpJson(await freshAccount("Set workspace member role", (client, context) => client.setWorkspaceMemberRole(
|
|
74711
|
+
return mcpJson(await freshAccount("Set workspace member role", (client, context) => client.setWorkspaceMemberRole(email3, code, membershipId, { role: role3, expectedRole }, context)));
|
|
73967
74712
|
} catch (error2) {
|
|
73968
74713
|
return memberError(error2);
|
|
73969
74714
|
}
|
|
@@ -73972,9 +74717,9 @@ function registerRemoteCustomerTools(server) {
|
|
|
73972
74717
|
title: "Remove Current Workspace Member",
|
|
73973
74718
|
description: "Remove exactly this membership incarnation using its observed expectedRole and fresh verification. Self-removal is unavailable. A retry cannot remove a later replacement membership; saved credentials stay unchanged.",
|
|
73974
74719
|
inputSchema: exports_external.object(memberInput).strict()
|
|
73975
|
-
}, async ({ membershipId, expectedRole, email:
|
|
74720
|
+
}, async ({ membershipId, expectedRole, email: email3, code }) => {
|
|
73976
74721
|
try {
|
|
73977
|
-
return mcpJson(await freshAccount("Remove workspace member", (client, context) => client.removeWorkspaceMember(
|
|
74722
|
+
return mcpJson(await freshAccount("Remove workspace member", (client, context) => client.removeWorkspaceMember(email3, code, membershipId, { expectedRole }, context)));
|
|
73978
74723
|
} catch (error2) {
|
|
73979
74724
|
return memberError(error2);
|
|
73980
74725
|
}
|
|
@@ -73988,9 +74733,9 @@ function registerRemoteCustomerTools(server) {
|
|
|
73988
74733
|
limit: exports_external.number().int().min(1).max(100).optional(),
|
|
73989
74734
|
cursor: exports_external.string().regex(/^[A-Za-z0-9_-]{1,512}$/).optional()
|
|
73990
74735
|
}).strict()
|
|
73991
|
-
}, async ({ email:
|
|
74736
|
+
}, async ({ email: email3, code, limit, cursor: cursor2 }) => {
|
|
73992
74737
|
try {
|
|
73993
|
-
return mcpJson(await freshAccount("List workspace members", (client, context) => client.listWorkspaceMembers(
|
|
74738
|
+
return mcpJson(await freshAccount("List workspace members", (client, context) => client.listWorkspaceMembers(email3, code, { limit, cursor: cursor2 }, context)));
|
|
73994
74739
|
} catch {
|
|
73995
74740
|
return mcpError("WORKSPACE_MEMBERS_FAILED", "Unable to list workspace members. Check the selected server, owner/admin permissions, pagination and fresh verification code.");
|
|
73996
74741
|
}
|
|
@@ -74000,9 +74745,9 @@ function registerRemoteCustomerTools(server) {
|
|
|
74000
74745
|
title: kind === "profile" ? "Update Account Display Name" : "Update Workspace Name",
|
|
74001
74746
|
description: "Update only the name on the explicitly selected Skills server using fresh email OTP. Workspace changes require an owner/admin. Saved credentials are unchanged.",
|
|
74002
74747
|
inputSchema: exports_external.object({ name: exports_external.string().min(1), email: exports_external.string().email(), code: exports_external.string().regex(/^\d{6}$/) }).strict()
|
|
74003
|
-
}, async ({ name, email:
|
|
74748
|
+
}, async ({ name, email: email3, code }) => {
|
|
74004
74749
|
try {
|
|
74005
|
-
return mcpJson(await freshAccount("Update customer name", async (client, context) => kind === "profile" ? client.updateProfile(
|
|
74750
|
+
return mcpJson(await freshAccount("Update customer name", async (client, context) => kind === "profile" ? client.updateProfile(email3, code, { displayName: name }, context) : client.updateCurrentWorkspace(email3, code, { name }, context)));
|
|
74006
74751
|
} catch {
|
|
74007
74752
|
return mcpError("NAME_UPDATE_FAILED", "Unable to update the name. Check the selected server, name, permissions and fresh verification code.");
|
|
74008
74753
|
}
|
|
@@ -74022,9 +74767,9 @@ function registerRemoteCustomerTools(server) {
|
|
|
74022
74767
|
title: "List API Keys",
|
|
74023
74768
|
description: "List account API keys using fresh email OTP reauthentication.",
|
|
74024
74769
|
inputSchema: { email: exports_external.string().email(), code: exports_external.string().regex(/^\d{6}$/) }
|
|
74025
|
-
}, async ({ email:
|
|
74770
|
+
}, async ({ email: email3, code }) => {
|
|
74026
74771
|
try {
|
|
74027
|
-
return mcpJson(await freshAccount("List API keys", (client, context) => client.listApiKeys(
|
|
74772
|
+
return mcpJson(await freshAccount("List API keys", (client, context) => client.listApiKeys(email3, code, context)));
|
|
74028
74773
|
} catch {
|
|
74029
74774
|
return mcpError("KEY_LIST_FAILED", "Unable to list API keys. Check the selected profile, server, account and fresh verification code.");
|
|
74030
74775
|
}
|
|
@@ -74033,9 +74778,9 @@ function registerRemoteCustomerTools(server) {
|
|
|
74033
74778
|
title: "Revoke API Key",
|
|
74034
74779
|
description: "Revoke an account API key using fresh email OTP reauthentication.",
|
|
74035
74780
|
inputSchema: { key_id: exports_external.string().min(1), email: exports_external.string().email(), code: exports_external.string().regex(/^\d{6}$/) }
|
|
74036
|
-
}, async ({ key_id, email:
|
|
74781
|
+
}, async ({ key_id, email: email3, code }) => {
|
|
74037
74782
|
try {
|
|
74038
|
-
return mcpJson(await freshAccount("Revoke API key", (client, context) => client.revokeApiKey(
|
|
74783
|
+
return mcpJson(await freshAccount("Revoke API key", (client, context) => client.revokeApiKey(email3, code, key_id, context)));
|
|
74039
74784
|
} catch {
|
|
74040
74785
|
return mcpError("KEY_REVOKE_FAILED", "Unable to revoke this API key. Check the selected profile, key, account and fresh verification code.");
|
|
74041
74786
|
}
|
|
@@ -74044,10 +74789,10 @@ function registerRemoteCustomerTools(server) {
|
|
|
74044
74789
|
title: "Create API Key",
|
|
74045
74790
|
description: "Create an API key using fresh email OTP reauthentication; returns its secret once. A stored API key cannot grant this authority.",
|
|
74046
74791
|
inputSchema: { name: exports_external.string().min(1), email: exports_external.string().email(), code: exports_external.string().regex(/^\d{6}$/), scopes: exports_external.array(exports_external.string()).optional() }
|
|
74047
|
-
}, async ({ name, email:
|
|
74792
|
+
}, async ({ name, email: email3, code, scopes }) => {
|
|
74048
74793
|
const capturedScopes = scopes === undefined ? undefined : [...scopes];
|
|
74049
74794
|
try {
|
|
74050
|
-
return mcpJson(await freshAccount("Create API key", (client, context) => client.createApiKey(
|
|
74795
|
+
return mcpJson(await freshAccount("Create API key", (client, context) => client.createApiKey(email3, code, name, capturedScopes, context)));
|
|
74051
74796
|
} catch {
|
|
74052
74797
|
return mcpError("KEY_CREATION_FAILED", "API key creation could not be confirmed. Check the selected profile and workspace keys before retrying; a lost response may still have created a key.");
|
|
74053
74798
|
}
|
|
@@ -74089,15 +74834,22 @@ async function freshAccount(action, operation) {
|
|
|
74089
74834
|
return operation(new RemoteSkillsAuthClient(target.origin), target.context);
|
|
74090
74835
|
}
|
|
74091
74836
|
var init_remote_customer_tools = __esm(() => {
|
|
74837
|
+
init_remote_invitation_tools();
|
|
74092
74838
|
init_zod();
|
|
74093
74839
|
init_remote_auth();
|
|
74094
74840
|
init_workspace_profile();
|
|
74095
74841
|
init_remote_customer_operations();
|
|
74096
74842
|
init_remote_client();
|
|
74843
|
+
init_remote_workspace_leave();
|
|
74097
74844
|
init_helpers();
|
|
74098
74845
|
});
|
|
74099
74846
|
|
|
74100
74847
|
// src/mcp/server.ts
|
|
74848
|
+
var exports_server = {};
|
|
74849
|
+
__export(exports_server, {
|
|
74850
|
+
server: () => server,
|
|
74851
|
+
buildServer: () => buildServer
|
|
74852
|
+
});
|
|
74101
74853
|
function buildServer() {
|
|
74102
74854
|
const server = new McpServer({
|
|
74103
74855
|
name: "skills",
|
|
@@ -74124,371 +74876,10 @@ var init_server3 = __esm(() => {
|
|
|
74124
74876
|
server = buildServer();
|
|
74125
74877
|
});
|
|
74126
74878
|
|
|
74127
|
-
// ../../node_modules/.bun/@hono+node-server@1.19.17+2145b681a064c8e9/node_modules/@hono/node-server/dist/index.mjs
|
|
74128
|
-
import { Readable } from "stream";
|
|
74129
|
-
import crypto2 from "crypto";
|
|
74130
|
-
var GlobalRequest, Request, newHeadersFromIncoming = (incoming) => {
|
|
74131
|
-
const headerRecord = [];
|
|
74132
|
-
const rawHeaders = incoming.rawHeaders;
|
|
74133
|
-
for (let i = 0;i < rawHeaders.length; i += 2) {
|
|
74134
|
-
const { [i]: key, [i + 1]: value } = rawHeaders;
|
|
74135
|
-
if (key.charCodeAt(0) !== 58) {
|
|
74136
|
-
headerRecord.push([key, value]);
|
|
74137
|
-
}
|
|
74138
|
-
}
|
|
74139
|
-
return new Headers(headerRecord);
|
|
74140
|
-
}, wrapBodyStream, newRequestFromIncoming = (method2, url, headers, incoming, abortController) => {
|
|
74141
|
-
const init = {
|
|
74142
|
-
method: method2,
|
|
74143
|
-
headers,
|
|
74144
|
-
signal: abortController.signal
|
|
74145
|
-
};
|
|
74146
|
-
if (method2 === "TRACE") {
|
|
74147
|
-
init.method = "GET";
|
|
74148
|
-
const req = new Request(url, init);
|
|
74149
|
-
Object.defineProperty(req, "method", {
|
|
74150
|
-
get() {
|
|
74151
|
-
return "TRACE";
|
|
74152
|
-
}
|
|
74153
|
-
});
|
|
74154
|
-
return req;
|
|
74155
|
-
}
|
|
74156
|
-
if (!(method2 === "GET" || method2 === "HEAD")) {
|
|
74157
|
-
if ("rawBody" in incoming && incoming.rawBody instanceof Buffer) {
|
|
74158
|
-
init.body = new ReadableStream({
|
|
74159
|
-
start(controller) {
|
|
74160
|
-
controller.enqueue(incoming.rawBody);
|
|
74161
|
-
controller.close();
|
|
74162
|
-
}
|
|
74163
|
-
});
|
|
74164
|
-
} else if (incoming[wrapBodyStream]) {
|
|
74165
|
-
let reader;
|
|
74166
|
-
init.body = new ReadableStream({
|
|
74167
|
-
async pull(controller) {
|
|
74168
|
-
try {
|
|
74169
|
-
reader ||= Readable.toWeb(incoming).getReader();
|
|
74170
|
-
const { done, value } = await reader.read();
|
|
74171
|
-
if (done) {
|
|
74172
|
-
controller.close();
|
|
74173
|
-
} else {
|
|
74174
|
-
controller.enqueue(value);
|
|
74175
|
-
}
|
|
74176
|
-
} catch (error2) {
|
|
74177
|
-
controller.error(error2);
|
|
74178
|
-
}
|
|
74179
|
-
}
|
|
74180
|
-
});
|
|
74181
|
-
} else {
|
|
74182
|
-
init.body = Readable.toWeb(incoming);
|
|
74183
|
-
}
|
|
74184
|
-
}
|
|
74185
|
-
return new Request(url, init);
|
|
74186
|
-
}, getRequestCache, requestCache, incomingKey, urlKey, headersKey, abortControllerKey, getAbortController, requestPrototype, responseCache, getResponseCache, cacheKey, GlobalResponse, Response2, outgoingEnded, incomingDraining, MAX_DRAIN_BYTES;
|
|
74187
|
-
var init_dist = __esm(() => {
|
|
74188
|
-
GlobalRequest = global.Request;
|
|
74189
|
-
Request = class extends GlobalRequest {
|
|
74190
|
-
constructor(input, options) {
|
|
74191
|
-
if (typeof input === "object" && getRequestCache in input) {
|
|
74192
|
-
input = input[getRequestCache]();
|
|
74193
|
-
}
|
|
74194
|
-
if (typeof options?.body?.getReader !== "undefined") {
|
|
74195
|
-
options.duplex ??= "half";
|
|
74196
|
-
}
|
|
74197
|
-
super(input, options);
|
|
74198
|
-
}
|
|
74199
|
-
};
|
|
74200
|
-
wrapBodyStream = Symbol("wrapBodyStream");
|
|
74201
|
-
getRequestCache = Symbol("getRequestCache");
|
|
74202
|
-
requestCache = Symbol("requestCache");
|
|
74203
|
-
incomingKey = Symbol("incomingKey");
|
|
74204
|
-
urlKey = Symbol("urlKey");
|
|
74205
|
-
headersKey = Symbol("headersKey");
|
|
74206
|
-
abortControllerKey = Symbol("abortControllerKey");
|
|
74207
|
-
getAbortController = Symbol("getAbortController");
|
|
74208
|
-
requestPrototype = {
|
|
74209
|
-
get method() {
|
|
74210
|
-
return this[incomingKey].method || "GET";
|
|
74211
|
-
},
|
|
74212
|
-
get url() {
|
|
74213
|
-
return this[urlKey];
|
|
74214
|
-
},
|
|
74215
|
-
get headers() {
|
|
74216
|
-
return this[headersKey] ||= newHeadersFromIncoming(this[incomingKey]);
|
|
74217
|
-
},
|
|
74218
|
-
[getAbortController]() {
|
|
74219
|
-
this[getRequestCache]();
|
|
74220
|
-
return this[abortControllerKey];
|
|
74221
|
-
},
|
|
74222
|
-
[getRequestCache]() {
|
|
74223
|
-
this[abortControllerKey] ||= new AbortController;
|
|
74224
|
-
return this[requestCache] ||= newRequestFromIncoming(this.method, this[urlKey], this.headers, this[incomingKey], this[abortControllerKey]);
|
|
74225
|
-
}
|
|
74226
|
-
};
|
|
74227
|
-
[
|
|
74228
|
-
"body",
|
|
74229
|
-
"bodyUsed",
|
|
74230
|
-
"cache",
|
|
74231
|
-
"credentials",
|
|
74232
|
-
"destination",
|
|
74233
|
-
"integrity",
|
|
74234
|
-
"mode",
|
|
74235
|
-
"redirect",
|
|
74236
|
-
"referrer",
|
|
74237
|
-
"referrerPolicy",
|
|
74238
|
-
"signal",
|
|
74239
|
-
"keepalive"
|
|
74240
|
-
].forEach((k) => {
|
|
74241
|
-
Object.defineProperty(requestPrototype, k, {
|
|
74242
|
-
get() {
|
|
74243
|
-
return this[getRequestCache]()[k];
|
|
74244
|
-
}
|
|
74245
|
-
});
|
|
74246
|
-
});
|
|
74247
|
-
["arrayBuffer", "blob", "clone", "formData", "json", "text"].forEach((k) => {
|
|
74248
|
-
Object.defineProperty(requestPrototype, k, {
|
|
74249
|
-
value: function() {
|
|
74250
|
-
return this[getRequestCache]()[k]();
|
|
74251
|
-
}
|
|
74252
|
-
});
|
|
74253
|
-
});
|
|
74254
|
-
Object.defineProperty(requestPrototype, Symbol.for("nodejs.util.inspect.custom"), {
|
|
74255
|
-
value: function(depth, options, inspectFn) {
|
|
74256
|
-
const props = {
|
|
74257
|
-
method: this.method,
|
|
74258
|
-
url: this.url,
|
|
74259
|
-
headers: this.headers,
|
|
74260
|
-
nativeRequest: this[requestCache]
|
|
74261
|
-
};
|
|
74262
|
-
return `Request (lightweight) ${inspectFn(props, { ...options, depth: depth == null ? null : depth - 1 })}`;
|
|
74263
|
-
}
|
|
74264
|
-
});
|
|
74265
|
-
Object.setPrototypeOf(requestPrototype, Request.prototype);
|
|
74266
|
-
responseCache = Symbol("responseCache");
|
|
74267
|
-
getResponseCache = Symbol("getResponseCache");
|
|
74268
|
-
cacheKey = Symbol("cache");
|
|
74269
|
-
GlobalResponse = global.Response;
|
|
74270
|
-
Response2 = class _Response {
|
|
74271
|
-
#body;
|
|
74272
|
-
#init;
|
|
74273
|
-
[getResponseCache]() {
|
|
74274
|
-
delete this[cacheKey];
|
|
74275
|
-
return this[responseCache] ||= new GlobalResponse(this.#body, this.#init);
|
|
74276
|
-
}
|
|
74277
|
-
constructor(body, init) {
|
|
74278
|
-
let headers;
|
|
74279
|
-
this.#body = body;
|
|
74280
|
-
if (init instanceof _Response) {
|
|
74281
|
-
const cachedGlobalResponse = init[responseCache];
|
|
74282
|
-
if (cachedGlobalResponse) {
|
|
74283
|
-
this.#init = cachedGlobalResponse;
|
|
74284
|
-
this[getResponseCache]();
|
|
74285
|
-
return;
|
|
74286
|
-
} else {
|
|
74287
|
-
this.#init = init.#init;
|
|
74288
|
-
headers = new Headers(init.#init.headers);
|
|
74289
|
-
}
|
|
74290
|
-
} else {
|
|
74291
|
-
this.#init = init;
|
|
74292
|
-
}
|
|
74293
|
-
if (typeof body === "string" || typeof body?.getReader !== "undefined" || body instanceof Blob || body instanceof Uint8Array) {
|
|
74294
|
-
this[cacheKey] = [init?.status || 200, body, headers || init?.headers];
|
|
74295
|
-
}
|
|
74296
|
-
}
|
|
74297
|
-
get headers() {
|
|
74298
|
-
const cache3 = this[cacheKey];
|
|
74299
|
-
if (cache3) {
|
|
74300
|
-
if (!(cache3[2] instanceof Headers)) {
|
|
74301
|
-
cache3[2] = new Headers(cache3[2] || { "content-type": "text/plain; charset=UTF-8" });
|
|
74302
|
-
}
|
|
74303
|
-
return cache3[2];
|
|
74304
|
-
}
|
|
74305
|
-
return this[getResponseCache]().headers;
|
|
74306
|
-
}
|
|
74307
|
-
get status() {
|
|
74308
|
-
return this[cacheKey]?.[0] ?? this[getResponseCache]().status;
|
|
74309
|
-
}
|
|
74310
|
-
get ok() {
|
|
74311
|
-
const status = this.status;
|
|
74312
|
-
return status >= 200 && status < 300;
|
|
74313
|
-
}
|
|
74314
|
-
};
|
|
74315
|
-
["body", "bodyUsed", "redirected", "statusText", "trailers", "type", "url"].forEach((k) => {
|
|
74316
|
-
Object.defineProperty(Response2.prototype, k, {
|
|
74317
|
-
get() {
|
|
74318
|
-
return this[getResponseCache]()[k];
|
|
74319
|
-
}
|
|
74320
|
-
});
|
|
74321
|
-
});
|
|
74322
|
-
["arrayBuffer", "blob", "clone", "formData", "json", "text"].forEach((k) => {
|
|
74323
|
-
Object.defineProperty(Response2.prototype, k, {
|
|
74324
|
-
value: function() {
|
|
74325
|
-
return this[getResponseCache]()[k]();
|
|
74326
|
-
}
|
|
74327
|
-
});
|
|
74328
|
-
});
|
|
74329
|
-
Object.defineProperty(Response2.prototype, Symbol.for("nodejs.util.inspect.custom"), {
|
|
74330
|
-
value: function(depth, options, inspectFn) {
|
|
74331
|
-
const props = {
|
|
74332
|
-
status: this.status,
|
|
74333
|
-
headers: this.headers,
|
|
74334
|
-
ok: this.ok,
|
|
74335
|
-
nativeResponse: this[responseCache]
|
|
74336
|
-
};
|
|
74337
|
-
return `Response (lightweight) ${inspectFn(props, { ...options, depth: depth == null ? null : depth - 1 })}`;
|
|
74338
|
-
}
|
|
74339
|
-
});
|
|
74340
|
-
Object.setPrototypeOf(Response2, GlobalResponse);
|
|
74341
|
-
Object.setPrototypeOf(Response2.prototype, GlobalResponse.prototype);
|
|
74342
|
-
if (typeof global.crypto === "undefined") {
|
|
74343
|
-
global.crypto = crypto2;
|
|
74344
|
-
}
|
|
74345
|
-
outgoingEnded = Symbol("outgoingEnded");
|
|
74346
|
-
incomingDraining = Symbol("incomingDraining");
|
|
74347
|
-
MAX_DRAIN_BYTES = 64 * 1024 * 1024;
|
|
74348
|
-
});
|
|
74349
|
-
|
|
74350
|
-
// ../../node_modules/.bun/content-type@1.0.5/node_modules/content-type/index.js
|
|
74351
|
-
var require_content_type = __commonJS((exports) => {
|
|
74352
|
-
/*!
|
|
74353
|
-
* content-type
|
|
74354
|
-
* Copyright(c) 2015 Douglas Christopher Wilson
|
|
74355
|
-
* MIT Licensed
|
|
74356
|
-
*/
|
|
74357
|
-
var PARAM_REGEXP = /; *([!#$%&'*+.^_`|~0-9A-Za-z-]+) *= *("(?:[\u000b\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\u000b\u0020-\u00ff])*"|[!#$%&'*+.^_`|~0-9A-Za-z-]+) */g;
|
|
74358
|
-
var TEXT_REGEXP = /^[\u000b\u0020-\u007e\u0080-\u00ff]+$/;
|
|
74359
|
-
var TOKEN_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
|
|
74360
|
-
var QESC_REGEXP = /\\([\u000b\u0020-\u00ff])/g;
|
|
74361
|
-
var QUOTE_REGEXP = /([\\"])/g;
|
|
74362
|
-
var TYPE_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
|
|
74363
|
-
exports.format = format;
|
|
74364
|
-
exports.parse = parse6;
|
|
74365
|
-
function format(obj) {
|
|
74366
|
-
if (!obj || typeof obj !== "object") {
|
|
74367
|
-
throw new TypeError("argument obj is required");
|
|
74368
|
-
}
|
|
74369
|
-
var parameters = obj.parameters;
|
|
74370
|
-
var type = obj.type;
|
|
74371
|
-
if (!type || !TYPE_REGEXP.test(type)) {
|
|
74372
|
-
throw new TypeError("invalid type");
|
|
74373
|
-
}
|
|
74374
|
-
var string5 = type;
|
|
74375
|
-
if (parameters && typeof parameters === "object") {
|
|
74376
|
-
var param;
|
|
74377
|
-
var params = Object.keys(parameters).sort();
|
|
74378
|
-
for (var i = 0;i < params.length; i++) {
|
|
74379
|
-
param = params[i];
|
|
74380
|
-
if (!TOKEN_REGEXP.test(param)) {
|
|
74381
|
-
throw new TypeError("invalid parameter name");
|
|
74382
|
-
}
|
|
74383
|
-
string5 += "; " + param + "=" + qstring(parameters[param]);
|
|
74384
|
-
}
|
|
74385
|
-
}
|
|
74386
|
-
return string5;
|
|
74387
|
-
}
|
|
74388
|
-
function parse6(string5) {
|
|
74389
|
-
if (!string5) {
|
|
74390
|
-
throw new TypeError("argument string is required");
|
|
74391
|
-
}
|
|
74392
|
-
var header = typeof string5 === "object" ? getcontenttype(string5) : string5;
|
|
74393
|
-
if (typeof header !== "string") {
|
|
74394
|
-
throw new TypeError("argument string is required to be a string");
|
|
74395
|
-
}
|
|
74396
|
-
var index = header.indexOf(";");
|
|
74397
|
-
var type = index !== -1 ? header.slice(0, index).trim() : header.trim();
|
|
74398
|
-
if (!TYPE_REGEXP.test(type)) {
|
|
74399
|
-
throw new TypeError("invalid media type");
|
|
74400
|
-
}
|
|
74401
|
-
var obj = new ContentType(type.toLowerCase());
|
|
74402
|
-
if (index !== -1) {
|
|
74403
|
-
var key;
|
|
74404
|
-
var match;
|
|
74405
|
-
var value;
|
|
74406
|
-
PARAM_REGEXP.lastIndex = index;
|
|
74407
|
-
while (match = PARAM_REGEXP.exec(header)) {
|
|
74408
|
-
if (match.index !== index) {
|
|
74409
|
-
throw new TypeError("invalid parameter format");
|
|
74410
|
-
}
|
|
74411
|
-
index += match[0].length;
|
|
74412
|
-
key = match[1].toLowerCase();
|
|
74413
|
-
value = match[2];
|
|
74414
|
-
if (value.charCodeAt(0) === 34) {
|
|
74415
|
-
value = value.slice(1, -1);
|
|
74416
|
-
if (value.indexOf("\\") !== -1) {
|
|
74417
|
-
value = value.replace(QESC_REGEXP, "$1");
|
|
74418
|
-
}
|
|
74419
|
-
}
|
|
74420
|
-
obj.parameters[key] = value;
|
|
74421
|
-
}
|
|
74422
|
-
if (index !== header.length) {
|
|
74423
|
-
throw new TypeError("invalid parameter format");
|
|
74424
|
-
}
|
|
74425
|
-
}
|
|
74426
|
-
return obj;
|
|
74427
|
-
}
|
|
74428
|
-
function getcontenttype(obj) {
|
|
74429
|
-
var header;
|
|
74430
|
-
if (typeof obj.getHeader === "function") {
|
|
74431
|
-
header = obj.getHeader("content-type");
|
|
74432
|
-
} else if (typeof obj.headers === "object") {
|
|
74433
|
-
header = obj.headers && obj.headers["content-type"];
|
|
74434
|
-
}
|
|
74435
|
-
if (typeof header !== "string") {
|
|
74436
|
-
throw new TypeError("content-type header is missing from object");
|
|
74437
|
-
}
|
|
74438
|
-
return header;
|
|
74439
|
-
}
|
|
74440
|
-
function qstring(val) {
|
|
74441
|
-
var str2 = String(val);
|
|
74442
|
-
if (TOKEN_REGEXP.test(str2)) {
|
|
74443
|
-
return str2;
|
|
74444
|
-
}
|
|
74445
|
-
if (str2.length > 0 && !TEXT_REGEXP.test(str2)) {
|
|
74446
|
-
throw new TypeError("invalid parameter value");
|
|
74447
|
-
}
|
|
74448
|
-
return '"' + str2.replace(QUOTE_REGEXP, "\\$1") + '"';
|
|
74449
|
-
}
|
|
74450
|
-
function ContentType(type) {
|
|
74451
|
-
this.parameters = Object.create(null);
|
|
74452
|
-
this.type = type;
|
|
74453
|
-
}
|
|
74454
|
-
});
|
|
74455
|
-
|
|
74456
|
-
// ../../node_modules/.bun/@modelcontextprotocol+sdk@1.30.0+2b91fc17bf64bdfd/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/mediaType.js
|
|
74457
|
-
var import_content_type;
|
|
74458
|
-
var init_mediaType = __esm(() => {
|
|
74459
|
-
import_content_type = __toESM(require_content_type(), 1);
|
|
74460
|
-
});
|
|
74461
|
-
|
|
74462
|
-
// ../../node_modules/.bun/@modelcontextprotocol+sdk@1.30.0+2b91fc17bf64bdfd/node_modules/@modelcontextprotocol/sdk/dist/esm/server/sseKeepAlive.js
|
|
74463
|
-
var MAX_TIMER_DELAY_MS;
|
|
74464
|
-
var init_sseKeepAlive = __esm(() => {
|
|
74465
|
-
MAX_TIMER_DELAY_MS = 2 ** 31 - 1;
|
|
74466
|
-
});
|
|
74467
|
-
|
|
74468
|
-
// ../../node_modules/.bun/@modelcontextprotocol+sdk@1.30.0+2b91fc17bf64bdfd/node_modules/@modelcontextprotocol/sdk/dist/esm/server/webStandardStreamableHttp.js
|
|
74469
|
-
var init_webStandardStreamableHttp = __esm(() => {
|
|
74470
|
-
init_mediaType();
|
|
74471
|
-
init_sseKeepAlive();
|
|
74472
|
-
init_types2();
|
|
74473
|
-
});
|
|
74474
|
-
|
|
74475
|
-
// ../../node_modules/.bun/@modelcontextprotocol+sdk@1.30.0+2b91fc17bf64bdfd/node_modules/@modelcontextprotocol/sdk/dist/esm/server/streamableHttp.js
|
|
74476
|
-
var init_streamableHttp = __esm(() => {
|
|
74477
|
-
init_dist();
|
|
74478
|
-
init_webStandardStreamableHttp();
|
|
74479
|
-
});
|
|
74480
|
-
|
|
74481
|
-
// src/mcp/http.ts
|
|
74482
|
-
var init_http = __esm(() => {
|
|
74483
|
-
init_streamableHttp();
|
|
74484
|
-
init_server3();
|
|
74485
|
-
});
|
|
74486
|
-
|
|
74487
74879
|
// src/mcp/index.ts
|
|
74488
74880
|
var exports_mcp = {};
|
|
74489
74881
|
__export(exports_mcp, {
|
|
74490
74882
|
startMcpStdio: () => startMcpStdio,
|
|
74491
|
-
buildServer: () => buildServer,
|
|
74492
74883
|
assertSkillsMcpConfigured: () => assertSkillsMcpConfigured
|
|
74493
74884
|
});
|
|
74494
74885
|
function printHelp() {
|
|
@@ -74499,6 +74890,7 @@ MCP server for ${package_default.name}
|
|
|
74499
74890
|
Options:
|
|
74500
74891
|
-V, --version output the version number
|
|
74501
74892
|
-h, --help display help for command
|
|
74893
|
+
--invitation-recovery --stdio expose only anonymous invitation recovery tools
|
|
74502
74894
|
--stdio run newline-delimited JSON-RPC for agent hosts
|
|
74503
74895
|
--http run Streamable HTTP transport on 127.0.0.1 (default; port 8836)
|
|
74504
74896
|
--port <n> HTTP port (--http or MCP_HTTP=1)`);
|
|
@@ -74515,23 +74907,21 @@ function assertSkillsMcpConfigured(env3 = process.env) {
|
|
|
74515
74907
|
}
|
|
74516
74908
|
async function startMcpStdio() {
|
|
74517
74909
|
assertSkillsMcpConfigured();
|
|
74518
|
-
const
|
|
74910
|
+
const { buildServer: buildServer2 } = await Promise.resolve().then(() => (init_server3(), exports_server));
|
|
74911
|
+
const server2 = buildServer2();
|
|
74519
74912
|
await server2.connect(new StdioServerTransport);
|
|
74520
74913
|
}
|
|
74521
74914
|
var args;
|
|
74522
74915
|
var init_mcp2 = __esm(() => {
|
|
74523
74916
|
init_stdio2();
|
|
74524
74917
|
init_package();
|
|
74525
|
-
init_server3();
|
|
74526
|
-
init_http();
|
|
74527
74918
|
init_fleet_credentials();
|
|
74528
|
-
init_server3();
|
|
74529
74919
|
args = process.argv.slice(2);
|
|
74530
|
-
if (args.includes("--help") || args.includes("-h")) {
|
|
74920
|
+
if (!args.some((value) => value.startsWith("--invitation-recovery")) && (args.includes("--help") || args.includes("-h"))) {
|
|
74531
74921
|
printHelp();
|
|
74532
74922
|
process.exit(0);
|
|
74533
74923
|
}
|
|
74534
|
-
if (args.includes("--version") || args.includes("-V")) {
|
|
74924
|
+
if (!args.some((value) => value.startsWith("--invitation-recovery")) && (args.includes("--version") || args.includes("-V"))) {
|
|
74535
74925
|
console.log(package_default.version);
|
|
74536
74926
|
process.exit(0);
|
|
74537
74927
|
}
|
|
@@ -77403,10 +77793,10 @@ async function handleRegistrySync(options) {
|
|
|
77403
77793
|
await writeJson2(artifact, 2);
|
|
77404
77794
|
return;
|
|
77405
77795
|
}
|
|
77406
|
-
const
|
|
77796
|
+
const invalid3 = artifact.summary.invalidSkillCount ?? "not checked";
|
|
77407
77797
|
console.log(source_default.green(`Registry sync artifact written to ${options.output}`));
|
|
77408
77798
|
console.log(source_default.dim(` Skills: ${artifact.summary.skillCount}`));
|
|
77409
|
-
console.log(source_default.dim(` Invalid: ${
|
|
77799
|
+
console.log(source_default.dim(` Invalid: ${invalid3}`));
|
|
77410
77800
|
}
|
|
77411
77801
|
function registerPull(parent) {
|
|
77412
77802
|
parent.command("pull").argument("[names...]", "Skills to pull from the configured instance (name or name@version)").option("--all", "Pull every skill the instance serves", false).option("--for-machine", "Prepare this machine with the instance's full catalog (implies --all)", false).option("--json", "Output results as JSON", false).description("Fetch skills from the configured Skills instance into this machine's corpus").action(async (names, options) => {
|
|
@@ -77626,21 +78016,21 @@ async function readPublishRevision(client, slug) {
|
|
|
77626
78016
|
throw new PushSkillError("Publishing was refused because the current skill revision could not be verified.", ["Check the configured instance and connection, then retry the push. No upload was attempted."]);
|
|
77627
78017
|
}
|
|
77628
78018
|
const body = lookup.body;
|
|
77629
|
-
const
|
|
77630
|
-
const nestedError =
|
|
77631
|
-
const code = typeof
|
|
78019
|
+
const record7 = body !== null && typeof body === "object" && !Array.isArray(body) ? body : undefined;
|
|
78020
|
+
const nestedError = record7?.error;
|
|
78021
|
+
const code = typeof record7?.code === "string" ? record7.code : nestedError !== null && typeof nestedError === "object" && !Array.isArray(nestedError) ? nestedError.code : undefined;
|
|
77632
78022
|
if (lookup.status === 404 && code === "SKILL_NOT_FOUND")
|
|
77633
78023
|
return;
|
|
77634
78024
|
if (lookup.status < 200 || lookup.status >= 300) {
|
|
77635
78025
|
throw new PushSkillError(`Publishing was refused because the current skill lookup failed: HTTP ${lookup.status}.`, ["Only an explicit SKILL_NOT_FOUND response establishes an initial publish. Check access and server compatibility before retrying."]);
|
|
77636
78026
|
}
|
|
77637
|
-
const revision =
|
|
77638
|
-
if (
|
|
77639
|
-
if (
|
|
78027
|
+
const revision = record7?.revisionId;
|
|
78028
|
+
if (record7?.publicationState === "catalogue-only") {
|
|
78029
|
+
if (record7.name === slug && (record7.slug === undefined || record7.slug === slug) && revision === null)
|
|
77640
78030
|
return;
|
|
77641
78031
|
throw new PushSkillError("Publishing was refused because the catalogue-only response had contradictory identity or revision state.", ["Check the configured instance and server compatibility. No upload was attempted."]);
|
|
77642
78032
|
}
|
|
77643
|
-
if (
|
|
78033
|
+
if (record7?.slug !== slug || typeof revision !== "string" || revision.length === 0 || revision !== revision.trim() || !/^[\x21-\x7e]+$/.test(revision)) {
|
|
77644
78034
|
throw new PushSkillError("Publishing was refused because the current skill response did not contain a matching slug and valid revision.", ["Check the configured instance and server compatibility. No upload was attempted."]);
|
|
77645
78035
|
}
|
|
77646
78036
|
return revision;
|
|
@@ -78014,22 +78404,22 @@ function authIdentityPayload(authSource, live, cached2, offline = false) {
|
|
|
78014
78404
|
const data = recordField(root.data);
|
|
78015
78405
|
const user = recordField(root.user) ?? recordField(data?.user);
|
|
78016
78406
|
const organization2 = recordField(root.organization) ?? recordField(root.org) ?? recordField(data?.organization);
|
|
78017
|
-
const
|
|
78407
|
+
const email3 = stringField2(user?.email) ?? cached2?.email;
|
|
78018
78408
|
const orgSlug = stringField2(organization2?.slug) ?? cached2?.orgSlug;
|
|
78019
78409
|
const orgName = stringField2(organization2?.name);
|
|
78020
78410
|
const userId = stringField2(user?.id) ?? cached2?.userId;
|
|
78021
78411
|
const orgId = stringField2(organization2?.id) ?? cached2?.orgId;
|
|
78022
|
-
const
|
|
78412
|
+
const role3 = stringField2(user?.role);
|
|
78023
78413
|
return {
|
|
78024
78414
|
status: "authenticated",
|
|
78025
78415
|
authSource,
|
|
78026
78416
|
...offline ? { offline: true } : {},
|
|
78027
|
-
...
|
|
78417
|
+
...email3 ? { email: email3 } : {},
|
|
78028
78418
|
...orgSlug ? { organization: orgSlug } : {},
|
|
78029
78419
|
...orgName ? { organizationName: orgName } : {},
|
|
78030
78420
|
...userId ? { userId } : {},
|
|
78031
78421
|
...orgId ? { orgId } : {},
|
|
78032
|
-
...
|
|
78422
|
+
...role3 ? { role: role3 } : {}
|
|
78033
78423
|
};
|
|
78034
78424
|
}
|
|
78035
78425
|
function printWhoami(payload) {
|
|
@@ -78106,7 +78496,7 @@ function printLoginSuccess(loginResult, json) {
|
|
|
78106
78496
|
console.log(source_default.dim(` API key saved to ${getAuthFilePath()}`));
|
|
78107
78497
|
}
|
|
78108
78498
|
}
|
|
78109
|
-
async function doLogin(
|
|
78499
|
+
async function doLogin(email3, code, json) {
|
|
78110
78500
|
const env3 = { ...process.env };
|
|
78111
78501
|
let origin;
|
|
78112
78502
|
try {
|
|
@@ -78115,7 +78505,7 @@ async function doLogin(email2, code, json) {
|
|
|
78115
78505
|
writeCommandError(error2, "Configure a Skills API before signing in", json);
|
|
78116
78506
|
return;
|
|
78117
78507
|
}
|
|
78118
|
-
if (!
|
|
78508
|
+
if (!email3 || !email3.includes("@")) {
|
|
78119
78509
|
writeCommandError(new Error("Invalid email"), "Invalid email", json);
|
|
78120
78510
|
process.exitCode = 1;
|
|
78121
78511
|
return;
|
|
@@ -78127,7 +78517,7 @@ async function doLogin(email2, code, json) {
|
|
|
78127
78517
|
try {
|
|
78128
78518
|
sendRes = await apiRequest("/api/auth/login", {
|
|
78129
78519
|
method: "POST",
|
|
78130
|
-
body: JSON.stringify({ email:
|
|
78520
|
+
body: JSON.stringify({ email: email3 })
|
|
78131
78521
|
}, origin);
|
|
78132
78522
|
} catch (err) {
|
|
78133
78523
|
writeCommandError(err, "Failed to request login code", json);
|
|
@@ -78138,9 +78528,9 @@ async function doLogin(email2, code, json) {
|
|
|
78138
78528
|
return;
|
|
78139
78529
|
}
|
|
78140
78530
|
if (!json)
|
|
78141
|
-
console.log(source_default.green("\u2713 Code sent to " +
|
|
78531
|
+
console.log(source_default.green("\u2713 Code sent to " + email3));
|
|
78142
78532
|
if (json || !isTTY) {
|
|
78143
|
-
console.log(JSON.stringify({ status: "code_sent", email:
|
|
78533
|
+
console.log(JSON.stringify({ status: "code_sent", email: email3, message: "Check email for 6-digit code, then run: skills auth login --email " + email3 + " --code <CODE>" }));
|
|
78144
78534
|
return;
|
|
78145
78535
|
}
|
|
78146
78536
|
const answer = await prompt(source_default.bold("Code: "));
|
|
@@ -78152,7 +78542,7 @@ async function doLogin(email2, code, json) {
|
|
|
78152
78542
|
try {
|
|
78153
78543
|
verifyRes = await apiRequest("/api/auth/verify", {
|
|
78154
78544
|
method: "POST",
|
|
78155
|
-
body: JSON.stringify({ email:
|
|
78545
|
+
body: JSON.stringify({ email: email3, code })
|
|
78156
78546
|
}, origin);
|
|
78157
78547
|
} catch (err) {
|
|
78158
78548
|
writeCommandError(err, "Failed to verify login code", json);
|
|
@@ -78199,13 +78589,13 @@ async function doApiKeyLogin(apiKey, json) {
|
|
|
78199
78589
|
return;
|
|
78200
78590
|
}
|
|
78201
78591
|
const identity2 = authIdentityPayload("stored", whoami);
|
|
78202
|
-
const
|
|
78592
|
+
const email3 = stringField2(identity2.email);
|
|
78203
78593
|
const orgId = stringField2(identity2.orgId);
|
|
78204
78594
|
const orgSlug = stringField2(identity2.organization);
|
|
78205
78595
|
const userId = stringField2(identity2.userId);
|
|
78206
78596
|
saveAuthConfig({
|
|
78207
78597
|
apiKey: trimmed,
|
|
78208
|
-
...
|
|
78598
|
+
...email3 ? { email: email3 } : {},
|
|
78209
78599
|
...orgId ? { orgId } : {},
|
|
78210
78600
|
...orgSlug ? { orgSlug } : {},
|
|
78211
78601
|
...userId ? { userId } : {}
|
|
@@ -78375,8 +78765,8 @@ function registerAuth(parent) {
|
|
|
78375
78765
|
await doDeviceLogin(options);
|
|
78376
78766
|
return;
|
|
78377
78767
|
}
|
|
78378
|
-
let
|
|
78379
|
-
if (!
|
|
78768
|
+
let email3 = options.email;
|
|
78769
|
+
if (!email3 && isTTY && !options.json) {
|
|
78380
78770
|
const existing = authForPrompt();
|
|
78381
78771
|
if (existing) {
|
|
78382
78772
|
console.log(source_default.dim(`Already signed in as ${existing.email}`));
|
|
@@ -78387,17 +78777,17 @@ function registerAuth(parent) {
|
|
|
78387
78777
|
const answer = await prompt(source_default.bold("Email: "));
|
|
78388
78778
|
if (answer === null)
|
|
78389
78779
|
return;
|
|
78390
|
-
|
|
78780
|
+
email3 = answer;
|
|
78391
78781
|
}
|
|
78392
|
-
if (!
|
|
78782
|
+
if (!email3) {
|
|
78393
78783
|
writeCommandError(new Error("Email required. Use: skills auth login --email you@example.com"), "Email required", options.json);
|
|
78394
78784
|
return;
|
|
78395
78785
|
}
|
|
78396
|
-
await doLogin(
|
|
78786
|
+
await doLogin(email3, options.code, options.json);
|
|
78397
78787
|
});
|
|
78398
78788
|
auth.command("signup").description("Create or sign in with your email (passwordless)").option("--email <email>", "Email address (non-interactive)").option("--code <code>", "Verification code (non-interactive)").option("--json", "Output result as JSON without prompting", false).action(async (options) => {
|
|
78399
|
-
let
|
|
78400
|
-
if (!
|
|
78789
|
+
let email3 = options.email;
|
|
78790
|
+
if (!email3 && isTTY && !options.json) {
|
|
78401
78791
|
const existing = authForPrompt();
|
|
78402
78792
|
if (existing) {
|
|
78403
78793
|
console.log(source_default.dim(`Already signed in as ${existing.email}`));
|
|
@@ -78408,9 +78798,9 @@ function registerAuth(parent) {
|
|
|
78408
78798
|
const answer = await prompt(source_default.bold("Email: "));
|
|
78409
78799
|
if (answer === null)
|
|
78410
78800
|
return;
|
|
78411
|
-
|
|
78801
|
+
email3 = answer;
|
|
78412
78802
|
}
|
|
78413
|
-
if (!
|
|
78803
|
+
if (!email3) {
|
|
78414
78804
|
const error2 = "Email required. Use: skills auth signup --email you@example.com";
|
|
78415
78805
|
if (options.json)
|
|
78416
78806
|
console.log(JSON.stringify({ error: error2 }));
|
|
@@ -78419,7 +78809,7 @@ function registerAuth(parent) {
|
|
|
78419
78809
|
process.exitCode = 1;
|
|
78420
78810
|
return;
|
|
78421
78811
|
}
|
|
78422
|
-
await doLogin(
|
|
78812
|
+
await doLogin(email3, options.code, options.json);
|
|
78423
78813
|
});
|
|
78424
78814
|
auth.command("logout").description("Remove this profile's stored credentials; injected keys remain configured").option("--json", "Output as JSON", false).action((options) => {
|
|
78425
78815
|
const { stillResolves } = clearAuthConfig();
|
|
@@ -78485,6 +78875,332 @@ var init_auth = __esm(() => {
|
|
|
78485
78875
|
CONFIG_HINT_STATUSES = new Set([401, 403, 404, 405, 501]);
|
|
78486
78876
|
});
|
|
78487
78877
|
|
|
78878
|
+
// src/lib/invitation-recovery-target.ts
|
|
78879
|
+
function prepareInvitationRecoveryTarget(source = process.env) {
|
|
78880
|
+
const env3 = { ...source }, names = ["HASNA_SKILLS_API_URL", "SKILLS_API_URL"];
|
|
78881
|
+
const urls = names.map((name) => env3[name]?.trim()).filter((value) => !!value);
|
|
78882
|
+
if (!urls.length)
|
|
78883
|
+
throw new InvitationEmailInputError;
|
|
78884
|
+
let origin;
|
|
78885
|
+
try {
|
|
78886
|
+
const normalized = urls.map(normalizeSkillsApiOrigin);
|
|
78887
|
+
if (normalized.some((value) => value !== normalized[0]))
|
|
78888
|
+
throw new InvitationEmailInputError;
|
|
78889
|
+
origin = normalized[0];
|
|
78890
|
+
} catch {
|
|
78891
|
+
throw new InvitationEmailInputError;
|
|
78892
|
+
}
|
|
78893
|
+
const unchangedFiles = captureSkillsCredentialFiles(skillsProfileCredentialFiles(env3));
|
|
78894
|
+
return { origin, unchanged() {
|
|
78895
|
+
unchangedFiles();
|
|
78896
|
+
if ([...names, "HASNA_PROFILE", "HASNA_HOME", "HOME"].some((name) => source[name] !== env3[name]))
|
|
78897
|
+
throw new InvitationEmailInputError;
|
|
78898
|
+
} };
|
|
78899
|
+
}
|
|
78900
|
+
var init_invitation_recovery_target = __esm(() => {
|
|
78901
|
+
init_fleet_credentials();
|
|
78902
|
+
init_instance_credentials();
|
|
78903
|
+
init_remote_invitation_recovery();
|
|
78904
|
+
});
|
|
78905
|
+
|
|
78906
|
+
// src/cli/commands/invitation-verification.ts
|
|
78907
|
+
import { emitKeypressEvents as emitKeypressEvents2 } from "readline";
|
|
78908
|
+
async function readInvitationSecrets() {
|
|
78909
|
+
if (process.stdin.isTTY)
|
|
78910
|
+
throw new NameInputError("Pipe the six-digit code and invitation token on two separate lines with --secrets-stdin.");
|
|
78911
|
+
let text2 = "";
|
|
78912
|
+
for await (const chunk2 of process.stdin) {
|
|
78913
|
+
text2 += chunk2.toString();
|
|
78914
|
+
if (text2.length > 64)
|
|
78915
|
+
throw new NameInputError("Supply only the code and invitation token on two separate lines.");
|
|
78916
|
+
}
|
|
78917
|
+
const matched = /^(\d{6})\r?\n([A-Za-z0-9_-]{43})(?:\r?\n)?$/.exec(text2);
|
|
78918
|
+
if (!matched)
|
|
78919
|
+
throw new NameInputError("Supply only the code and invitation token on two separate lines.");
|
|
78920
|
+
return { code: matched[1], token: matched[2] };
|
|
78921
|
+
}
|
|
78922
|
+
function promptInvitationToken() {
|
|
78923
|
+
return promptInvitationProof("token");
|
|
78924
|
+
}
|
|
78925
|
+
function promptInvitationRecoveryCode() {
|
|
78926
|
+
return promptInvitationProof("code");
|
|
78927
|
+
}
|
|
78928
|
+
function promptInvitationProof(kind) {
|
|
78929
|
+
const length = kind === "token" ? 43 : 6;
|
|
78930
|
+
const label = kind === "token" ? "invitation token" : "recovery code";
|
|
78931
|
+
const character = kind === "token" ? /^[A-Za-z0-9_-]$/ : /^\d$/;
|
|
78932
|
+
const { stdin, stderr: output } = process, wasRaw = stdin.isRaw, wasFlowing = stdin.readableFlowing;
|
|
78933
|
+
return new Promise((resolve5) => {
|
|
78934
|
+
let value = "", settled = false, overflow = false;
|
|
78935
|
+
const finish = (answer) => {
|
|
78936
|
+
if (settled)
|
|
78937
|
+
return;
|
|
78938
|
+
settled = true;
|
|
78939
|
+
clearTimeout(timer);
|
|
78940
|
+
stdin.off("keypress", keypress);
|
|
78941
|
+
stdin.off("end", cancel);
|
|
78942
|
+
process.off("SIGINT", cancel);
|
|
78943
|
+
stdin.setRawMode(wasRaw);
|
|
78944
|
+
if (wasFlowing !== true)
|
|
78945
|
+
stdin.pause();
|
|
78946
|
+
output.write(`
|
|
78947
|
+
`);
|
|
78948
|
+
if (answer === null)
|
|
78949
|
+
process.exitCode = 130;
|
|
78950
|
+
resolve5(answer);
|
|
78951
|
+
};
|
|
78952
|
+
const cancel = () => finish(null);
|
|
78953
|
+
const keypress = (text2, key) => {
|
|
78954
|
+
if (key.ctrl && ["c", "d"].includes(key.name ?? "") || key.name === "escape")
|
|
78955
|
+
return cancel();
|
|
78956
|
+
if (key.name === "return" || key.name === "enter") {
|
|
78957
|
+
if (overflow) {
|
|
78958
|
+
value = "";
|
|
78959
|
+
overflow = false;
|
|
78960
|
+
output.write(`
|
|
78961
|
+
Enter exactly ${length} ${label} characters: `);
|
|
78962
|
+
return;
|
|
78963
|
+
}
|
|
78964
|
+
if (value.length === length)
|
|
78965
|
+
return finish(value);
|
|
78966
|
+
output.write(`
|
|
78967
|
+
Enter the complete ${label}: `);
|
|
78968
|
+
value = "";
|
|
78969
|
+
return;
|
|
78970
|
+
}
|
|
78971
|
+
if (overflow)
|
|
78972
|
+
return;
|
|
78973
|
+
if (key.name === "backspace") {
|
|
78974
|
+
if (value) {
|
|
78975
|
+
value = value.slice(0, -1);
|
|
78976
|
+
output.write("\b \b");
|
|
78977
|
+
}
|
|
78978
|
+
} else if (character.test(text2)) {
|
|
78979
|
+
if (value.length === length) {
|
|
78980
|
+
overflow = true;
|
|
78981
|
+
output.write(`
|
|
78982
|
+
The ${label} is too long. Press Enter to start again.`);
|
|
78983
|
+
} else {
|
|
78984
|
+
value += text2;
|
|
78985
|
+
output.write("*");
|
|
78986
|
+
}
|
|
78987
|
+
} else if (text2 && !key.ctrl && !key.meta) {
|
|
78988
|
+
overflow = true;
|
|
78989
|
+
output.write(`
|
|
78990
|
+
The ${label} contains invalid characters. Press Enter to start again.`);
|
|
78991
|
+
}
|
|
78992
|
+
};
|
|
78993
|
+
const timer = setTimeout(cancel, 5 * 60 * 1000);
|
|
78994
|
+
emitKeypressEvents2(stdin);
|
|
78995
|
+
stdin.setRawMode(true);
|
|
78996
|
+
stdin.on("keypress", keypress);
|
|
78997
|
+
stdin.once("end", cancel);
|
|
78998
|
+
process.once("SIGINT", cancel);
|
|
78999
|
+
output.write(kind === "token" ? "Enter the invitation token from your email: " : "Enter the six-digit recovery code from your email: ");
|
|
79000
|
+
stdin.resume();
|
|
79001
|
+
});
|
|
79002
|
+
}
|
|
79003
|
+
var init_invitation_verification = __esm(() => {
|
|
79004
|
+
init_customer_verification();
|
|
79005
|
+
});
|
|
79006
|
+
|
|
79007
|
+
// src/cli/commands/invitation-recovery.ts
|
|
79008
|
+
async function readToken() {
|
|
79009
|
+
if (process.stdin.isTTY)
|
|
79010
|
+
throw new InvitationEmailInputError;
|
|
79011
|
+
let value = "";
|
|
79012
|
+
for await (const chunk2 of process.stdin) {
|
|
79013
|
+
value += chunk2.toString();
|
|
79014
|
+
if (value.length > 45)
|
|
79015
|
+
throw new InvitationEmailInputError;
|
|
79016
|
+
}
|
|
79017
|
+
const matched = /^([A-Za-z0-9_-]{43})(?:\r?\n)?$/.exec(value);
|
|
79018
|
+
if (!matched)
|
|
79019
|
+
throw new InvitationEmailInputError;
|
|
79020
|
+
return matched[1];
|
|
79021
|
+
}
|
|
79022
|
+
function registerInvitationRecoveryCommands(invitations) {
|
|
79023
|
+
for (const action of ["challenge", "accept"]) {
|
|
79024
|
+
const command = invitations.createCommand(`email-${action}`).argument("<invitation-id>").allowExcessArguments(false).enablePositionalOptions().configureOutput({ writeErr: () => {
|
|
79025
|
+
process.stderr.write(`Invitation recovery arguments were refused. Supply proof only through masked input or the documented stdin flags.
|
|
79026
|
+
`);
|
|
79027
|
+
} }).description(action === "challenge" ? "Request an eligibility-neutral recovery code; does not confirm delivery" : "Accept with invitation proof; requires ordinary sign-in afterward").requiredOption("--challenge-id <id>", "Your retained challenge UUID; generate it before the request and keep the same exact context").requiredOption("--confirm", "Confirm this exact invitation recovery action").option(action === "challenge" ? "--token-stdin" : "--secrets-stdin", action === "challenge" ? "Read the invitation token from one stdin line" : "Read the recovery code then invitation token from two stdin lines").option("--json", "Output only validated results").action(async (invitationId2, options) => {
|
|
79028
|
+
try {
|
|
79029
|
+
if (options.confirm !== true)
|
|
79030
|
+
throw new InvitationEmailInputError;
|
|
79031
|
+
const ids = invitationEmailIds(invitationId2, options.challengeId), target = prepareInvitationRecoveryTarget();
|
|
79032
|
+
const piped = action === "challenge" ? options.tokenStdin : options.secretsStdin;
|
|
79033
|
+
if (!piped && (options.json || !process.stdin.isTTY || !process.stderr.isTTY))
|
|
79034
|
+
throw new InvitationEmailInputError;
|
|
79035
|
+
let token, code = null;
|
|
79036
|
+
if (piped && action === "accept")
|
|
79037
|
+
({ token, code } = await readInvitationSecrets());
|
|
79038
|
+
else if (piped)
|
|
79039
|
+
token = await readToken();
|
|
79040
|
+
else {
|
|
79041
|
+
token = await promptInvitationToken();
|
|
79042
|
+
if (token === null)
|
|
79043
|
+
return;
|
|
79044
|
+
if (action === "accept") {
|
|
79045
|
+
code = await promptInvitationRecoveryCode();
|
|
79046
|
+
if (code === null)
|
|
79047
|
+
return;
|
|
79048
|
+
}
|
|
79049
|
+
}
|
|
79050
|
+
target.unchanged();
|
|
79051
|
+
const client = new RemoteSkillsAuthClient(target.origin);
|
|
79052
|
+
const result2 = action === "challenge" ? await client.requestInvitationEmailChallenge({ ...ids, token, confirm: true }) : await client.acceptInvitationEmailChallenge({ ...ids, token, code, confirm: true });
|
|
79053
|
+
console.log(JSON.stringify(result2, null, options.json ? undefined : 2));
|
|
79054
|
+
} catch (error2) {
|
|
79055
|
+
const result2 = invitationEmailCustomerError(error2);
|
|
79056
|
+
if (options.json)
|
|
79057
|
+
console.log(JSON.stringify(result2));
|
|
79058
|
+
else
|
|
79059
|
+
console.error(result2.error);
|
|
79060
|
+
process.exitCode = 1;
|
|
79061
|
+
}
|
|
79062
|
+
});
|
|
79063
|
+
invitations.addCommand(command);
|
|
79064
|
+
}
|
|
79065
|
+
}
|
|
79066
|
+
var init_invitation_recovery = __esm(() => {
|
|
79067
|
+
init_remote_auth();
|
|
79068
|
+
init_invitation_recovery_target();
|
|
79069
|
+
init_remote_invitation_recovery();
|
|
79070
|
+
init_invitation_verification();
|
|
79071
|
+
});
|
|
79072
|
+
|
|
79073
|
+
// src/cli/commands/workspace-invitations.ts
|
|
79074
|
+
function registerWorkspaceInvitationCommands(workspace) {
|
|
79075
|
+
const invitations = workspace.command("invitations").description("Manage workspace invitations with fresh verification and unchanged saved credentials");
|
|
79076
|
+
registerInvitationRecoveryCommands(invitations);
|
|
79077
|
+
for (const action of ["list", "get", "issue", "resend", "revoke", "accept"]) {
|
|
79078
|
+
const targeted = ["get", "resend", "revoke", "accept"].includes(action), mutation = !["list", "get"].includes(action);
|
|
79079
|
+
const command = invitations.command(action + (targeted ? " <invitation-id>" : "")).allowExcessArguments(false).description(action === "accept" ? "Accept a received invitation; does not switch workspace or create credentials" : `${action} invitations in the exact observed workspace`).requiredOption("--user-id <id>", "Observed account ID from workspace list").requiredOption("--membership-id <id>", "Exact observed current membership; must match any selected profile").requiredOption("--email <email>", "Account email for fresh verification").option("--json", "Output the validated result as JSON");
|
|
79080
|
+
if (mutation)
|
|
79081
|
+
command.requiredOption("--confirm", "Confirm this exact invitation action");
|
|
79082
|
+
if (action === "list")
|
|
79083
|
+
command.option("--after <id>", "Exact nextCursor from the previous page");
|
|
79084
|
+
if (action === "issue")
|
|
79085
|
+
command.requiredOption("--recipient <email>", "Invitation recipient").requiredOption("--role <role>", "owner, admin, member or viewer");
|
|
79086
|
+
if (action === "issue" || action === "resend")
|
|
79087
|
+
command.requiredOption("--idempotency-key <id>", "Your stable request UUID; reuse only with the same original context and parameters");
|
|
79088
|
+
if (action === "resend" || action === "revoke")
|
|
79089
|
+
command.requiredOption("--expected-generation <number>", "Generation you observed before confirming");
|
|
79090
|
+
if (action === "accept")
|
|
79091
|
+
command.option("--secrets-stdin", "Read a fresh six-digit code and invitation token on two separate stdin lines");
|
|
79092
|
+
else
|
|
79093
|
+
command.option("--code-stdin", "Read a previously requested six-digit verification code from stdin");
|
|
79094
|
+
command.action(async (...args2) => {
|
|
79095
|
+
const id = targeted ? String(args2[0]) : undefined, options = args2[targeted ? 1 : 0];
|
|
79096
|
+
try {
|
|
79097
|
+
if (mutation && options.confirm !== true)
|
|
79098
|
+
throw new WorkspaceInvitationInputError;
|
|
79099
|
+
let input = action === "list" ? { ...options.after === undefined ? {} : { after: options.after } } : action === "get" ? { invitationId: id } : action === "issue" ? { email: options.recipient, role: options.role, idempotencyKey: options.idempotencyKey, confirm: true } : action === "resend" ? { invitationId: id, expectedGeneration: Number(options.expectedGeneration), idempotencyKey: options.idempotencyKey, confirm: true } : action === "revoke" ? { invitationId: id, expectedGeneration: Number(options.expectedGeneration), confirm: true } : { invitationId: id, token: "", confirm: true };
|
|
79100
|
+
if (action === "accept")
|
|
79101
|
+
invitationId(id);
|
|
79102
|
+
else
|
|
79103
|
+
input = invitationInput(action, input);
|
|
79104
|
+
const context = invitationProfileContext(options.userId, options.membershipId);
|
|
79105
|
+
if (!options.email.includes("@"))
|
|
79106
|
+
throw new NameInputError("Provide the verified account email.");
|
|
79107
|
+
const stdin = action === "accept" ? options.secretsStdin : options.codeStdin;
|
|
79108
|
+
if (!stdin && (options.json || !process.stdin.isTTY || !process.stderr.isTTY))
|
|
79109
|
+
throw new NameInputError(action === "accept" ? "Use --secrets-stdin with a fresh code and invitation token on two separate lines." : "Use --code-stdin with a fresh verification code.");
|
|
79110
|
+
const target = await prepareProfileWorkspace("Manage invitations").resolve();
|
|
79111
|
+
invitationProfileContext(context.userId, context.membershipId, target.context);
|
|
79112
|
+
const client = new RemoteSkillsAuthClient(target.origin);
|
|
79113
|
+
let code, token = null;
|
|
79114
|
+
if (action === "accept" && stdin)
|
|
79115
|
+
({ code, token } = await readInvitationSecrets());
|
|
79116
|
+
else {
|
|
79117
|
+
if (action === "accept") {
|
|
79118
|
+
token = await promptInvitationToken();
|
|
79119
|
+
if (token === null)
|
|
79120
|
+
return;
|
|
79121
|
+
}
|
|
79122
|
+
if (stdin)
|
|
79123
|
+
code = await readCode();
|
|
79124
|
+
else {
|
|
79125
|
+
await client.requestCode(options.email);
|
|
79126
|
+
code = await promptCode();
|
|
79127
|
+
}
|
|
79128
|
+
}
|
|
79129
|
+
if (code === null)
|
|
79130
|
+
return;
|
|
79131
|
+
if (action === "accept")
|
|
79132
|
+
input = invitationInput("accept", { invitationId: id, token, confirm: true });
|
|
79133
|
+
target.unchanged();
|
|
79134
|
+
const result2 = await invokeFreshInvitation(client, options.email, code, context, action, input);
|
|
79135
|
+
console.log(JSON.stringify(result2, null, options.json ? undefined : 2));
|
|
79136
|
+
} catch (error2) {
|
|
79137
|
+
const result2 = error2 instanceof NameInputError ? { code: "INVITATION_INPUT_INVALID", error: error2.message } : invitationCustomerError(error2);
|
|
79138
|
+
if (options.json)
|
|
79139
|
+
console.log(JSON.stringify(result2));
|
|
79140
|
+
else
|
|
79141
|
+
console.error(result2.error);
|
|
79142
|
+
process.exitCode = 1;
|
|
79143
|
+
}
|
|
79144
|
+
});
|
|
79145
|
+
}
|
|
79146
|
+
}
|
|
79147
|
+
var init_workspace_invitations = __esm(() => {
|
|
79148
|
+
init_invitation_recovery();
|
|
79149
|
+
init_workspace_profile();
|
|
79150
|
+
init_remote_auth();
|
|
79151
|
+
init_invitation_customer_action();
|
|
79152
|
+
init_remote_invitations();
|
|
79153
|
+
init_customer_verification();
|
|
79154
|
+
init_invitation_verification();
|
|
79155
|
+
});
|
|
79156
|
+
|
|
79157
|
+
// src/cli/commands/workspace-leave.ts
|
|
79158
|
+
function registerWorkspaceLeaveCommand(workspace) {
|
|
79159
|
+
workspace.command("leave <membership-id>").allowExcessArguments(false).description("Leave exactly this membership after fresh verification; saved profiles stay unchanged").requiredOption("--expected-role <role>", "Observed role: owner, admin, member or viewer").requiredOption("--email <email>", "Account email for fresh verification").requiredOption("--confirm", "Confirm losing access through this membership and signing in again").option("--user-id <id>", "Observed user ID; required without a named workspace profile").option("--code-stdin", "Read a previously requested six-digit verification code from stdin").option("--json", "Output the confirmed result as JSON").action(async (membershipId, options) => {
|
|
79160
|
+
try {
|
|
79161
|
+
if (options.confirm !== true)
|
|
79162
|
+
throw new WorkspaceLeaveInputError;
|
|
79163
|
+
const pending = prepareProfileWorkspace("Leave workspace");
|
|
79164
|
+
const target = await pending.resolve();
|
|
79165
|
+
const captured = workspaceLeaveInput(workspaceLeaveProfileContext(membershipId, options.userId, target.context), { expectedRole: options.expectedRole, confirm: true });
|
|
79166
|
+
if (!options.email.includes("@"))
|
|
79167
|
+
throw new NameInputError("Provide the verified account email.");
|
|
79168
|
+
if (!options.codeStdin && (options.json || !process.stdin.isTTY || !process.stderr.isTTY))
|
|
79169
|
+
throw new NameInputError("Use --code-stdin with a fresh verification code for noninteractive leave actions.");
|
|
79170
|
+
const client = new RemoteSkillsAuthClient(target.origin);
|
|
79171
|
+
let code;
|
|
79172
|
+
if (options.codeStdin)
|
|
79173
|
+
code = await readCode();
|
|
79174
|
+
else {
|
|
79175
|
+
await client.requestCode(options.email);
|
|
79176
|
+
code = await promptCode();
|
|
79177
|
+
}
|
|
79178
|
+
if (code === null)
|
|
79179
|
+
return;
|
|
79180
|
+
target.unchanged();
|
|
79181
|
+
const result2 = await client.leaveWorkspace(options.email, code, captured.context, captured.input);
|
|
79182
|
+
if (options.json)
|
|
79183
|
+
console.log(JSON.stringify(result2));
|
|
79184
|
+
else
|
|
79185
|
+
console.log("Workspace membership left. Sign in again to an available workspace. Saved credentials are unchanged; this membership's credentials no longer grant access.");
|
|
79186
|
+
} catch (error2) {
|
|
79187
|
+
const known = error2 instanceof RemoteWorkspaceLeaveError || error2 instanceof RemoteWorkspaceLeaveUnconfirmedError;
|
|
79188
|
+
const message = known || error2 instanceof WorkspaceLeaveInputError || error2 instanceof NameInputError ? error2.message : "Leaving could not be confirmed. Check the selected profile and exact membership, sign in again and inspect available workspaces before another action. Do not retry automatically; saved credentials are unchanged.";
|
|
79189
|
+
if (options.json)
|
|
79190
|
+
console.log(JSON.stringify({ error: message, ...known ? { code: error2.code } : {} }));
|
|
79191
|
+
else
|
|
79192
|
+
console.error(message);
|
|
79193
|
+
process.exitCode = 1;
|
|
79194
|
+
}
|
|
79195
|
+
});
|
|
79196
|
+
}
|
|
79197
|
+
var init_workspace_leave = __esm(() => {
|
|
79198
|
+
init_workspace_profile();
|
|
79199
|
+
init_remote_auth();
|
|
79200
|
+
init_remote_workspace_leave();
|
|
79201
|
+
init_customer_verification();
|
|
79202
|
+
});
|
|
79203
|
+
|
|
78488
79204
|
// src/cli/commands/workspace-members.ts
|
|
78489
79205
|
function registerWorkspaceMembersCommand(workspace) {
|
|
78490
79206
|
workspace.command("members").allowExcessArguments(false).description("List the current workspace roster with fresh owner/admin verification").requiredOption("--email <email>", "Account email for fresh verification").option("--code-stdin", "Read a previously requested six-digit verification code from stdin").option("--limit <count>", "Page size from 1 to 100 (server default: 50)").option("--cursor <cursor>", "Unchanged nextCursor from the preceding page").option("--json", "Output the complete page as JSON").action(async (options) => {
|
|
@@ -78609,6 +79325,8 @@ function registerCustomerProfileCommands(program2) {
|
|
|
78609
79325
|
registerWorkspaceListCommand(workspace);
|
|
78610
79326
|
registerWorkspaceMembersCommand(workspace);
|
|
78611
79327
|
registerWorkspaceMemberMutationCommands(workspace);
|
|
79328
|
+
registerWorkspaceLeaveCommand(workspace);
|
|
79329
|
+
registerWorkspaceInvitationCommands(workspace);
|
|
78612
79330
|
const commands = [
|
|
78613
79331
|
{ kind: "account", command: account.command("update") },
|
|
78614
79332
|
{ kind: "workspace", command: workspace.command("update") }
|
|
@@ -78651,10 +79369,12 @@ function registerCustomerProfileCommands(program2) {
|
|
|
78651
79369
|
}
|
|
78652
79370
|
}
|
|
78653
79371
|
var init_customer_profile = __esm(() => {
|
|
79372
|
+
init_workspace_invitations();
|
|
78654
79373
|
init_workspace_profile();
|
|
78655
79374
|
init_workspace_selection();
|
|
78656
79375
|
init_remote_auth();
|
|
78657
79376
|
init_customer_verification();
|
|
79377
|
+
init_workspace_leave();
|
|
78658
79378
|
init_workspace_members();
|
|
78659
79379
|
init_workspace_member_mutations();
|
|
78660
79380
|
});
|
|
@@ -78851,14 +79571,14 @@ function resolveCorpusRootReadOnly(options) {
|
|
|
78851
79571
|
}
|
|
78852
79572
|
return { root: join39(appDir, INSTALLED_SKILLS_DIRNAME), migrationPending: true };
|
|
78853
79573
|
}
|
|
78854
|
-
function remoteRowToSkill(
|
|
78855
|
-
const slug = typeof
|
|
79574
|
+
function remoteRowToSkill(record7) {
|
|
79575
|
+
const slug = typeof record7.slug === "string" ? record7.slug : typeof record7.name === "string" ? record7.name : undefined;
|
|
78856
79576
|
if (!slug)
|
|
78857
79577
|
return;
|
|
78858
79578
|
return {
|
|
78859
79579
|
slug,
|
|
78860
|
-
version: typeof
|
|
78861
|
-
sha256: typeof
|
|
79580
|
+
version: typeof record7.version === "string" ? record7.version : undefined,
|
|
79581
|
+
sha256: typeof record7.bundleSha256 === "string" && record7.bundleSha256 ? record7.bundleSha256 : undefined
|
|
78862
79582
|
};
|
|
78863
79583
|
}
|
|
78864
79584
|
function recheckLocalSide(plannedLocal, localDir, ops = {
|