@hasna/skills 0.8.10 → 0.8.12
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 +62 -1
- package/bin/index.js +1558 -591
- package/bin/mcp.js +389 -82
- package/bin/migrate.js +6 -5
- package/bin/server.js +12312 -73626
- package/bin/worker.js +7635 -60520
- package/dist/index.d.ts +5 -1
- package/dist/index.js +1058 -267
- package/dist/lib/agent-discovery.d.ts +1 -1
- package/dist/lib/claude-marketplace-registry.d.ts +17 -0
- package/dist/lib/claude-settings-witness.d.ts +19 -0
- package/dist/lib/fleet-credentials.d.ts +18 -0
- package/dist/lib/hook-diagnostics.d.ts +7 -0
- package/dist/lib/recurring-recovery.d.ts +2 -2
- package/dist/lib/recurring-surface.d.ts +1 -1
- package/dist/lib/remote-client.d.ts +10 -3
- package/dist/lib/remote-credit-checkout.d.ts +22 -0
- package/dist/lib/remote-customer-operations.d.ts +2 -3
- package/dist/lib/selection-cache.d.ts +32 -0
- package/dist/lib/selection-resolver.d.ts +3 -1
- package/dist/lib/session-reconciliation.d.ts +100 -0
- package/dist/sdk/index.d.ts +3 -1
- package/dist/sdk/index.js +13419 -73945
- package/docs/plugin-admission.md +90 -0
- package/package.json +6 -5
package/bin/mcp.js
CHANGED
|
@@ -20019,7 +20019,7 @@ var package_default;
|
|
|
20019
20019
|
var init_package = __esm(() => {
|
|
20020
20020
|
package_default = {
|
|
20021
20021
|
name: "@hasna/skills",
|
|
20022
|
-
version: "0.8.
|
|
20022
|
+
version: "0.8.12",
|
|
20023
20023
|
description: "Skills library for AI coding agents",
|
|
20024
20024
|
type: "module",
|
|
20025
20025
|
bin: {
|
|
@@ -20081,10 +20081,11 @@ var init_package = __esm(() => {
|
|
|
20081
20081
|
typecheck: "tsc --noEmit",
|
|
20082
20082
|
"verify:release": "bun run scripts/release-guard.ts",
|
|
20083
20083
|
"verify:consumer-types": "bun run scripts/consumer-types.ts",
|
|
20084
|
-
|
|
20085
|
-
prepack: "bun run build && bun run verify:release && bun run verify:consumer-types",
|
|
20084
|
+
prepack: "bun run verify:generated && bun run verify:release && bun run verify:consumer-types",
|
|
20086
20085
|
prepublishOnly: "bun run verify:producer && bun run typecheck && bun run test",
|
|
20087
|
-
"verify:producer": "bun run scripts/release-dependencies.ts"
|
|
20086
|
+
"verify:producer": "bun run scripts/release-dependencies.ts",
|
|
20087
|
+
"verify:generated": "HASNA_SKILLS_RELEASE_ARTIFACT_TEST=1 bun test src/lib/release-artifacts.test.ts",
|
|
20088
|
+
"verify:consumer-credentials": "bun run scripts/consumer-credentials.ts"
|
|
20088
20089
|
},
|
|
20089
20090
|
keywords: [
|
|
20090
20091
|
"skills",
|
|
@@ -20106,7 +20107,6 @@ var init_package = __esm(() => {
|
|
|
20106
20107
|
license: "Apache-2.0",
|
|
20107
20108
|
devDependencies: {
|
|
20108
20109
|
"@hasna/contracts": "1.1.0",
|
|
20109
|
-
"@hasna/secrets": "0.4.2",
|
|
20110
20110
|
"@types/bun": "1.3.14",
|
|
20111
20111
|
"@types/node": "25.2.3",
|
|
20112
20112
|
"@types/react": "^18.2.0",
|
|
@@ -20119,6 +20119,7 @@ var init_package = __esm(() => {
|
|
|
20119
20119
|
"@aws-sdk/client-ecs": "^3.1079.0",
|
|
20120
20120
|
"@aws-sdk/client-s3": "^3.1079.0",
|
|
20121
20121
|
"@hasna/events": "0.1.18",
|
|
20122
|
+
"@hasna/secrets": "0.4.2",
|
|
20122
20123
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
20123
20124
|
chalk: "^5.3.0",
|
|
20124
20125
|
commander: "^12.1.0",
|
|
@@ -21107,6 +21108,7 @@ __export(exports_fleet_credentials, {
|
|
|
21107
21108
|
SKILLS_API_URL_ENV: () => SKILLS_API_URL_ENV,
|
|
21108
21109
|
SKILLS_API_KEY_ENV_KEYS: () => SKILLS_API_KEY_ENV_KEYS,
|
|
21109
21110
|
SKILLS_API_KEY_ENV: () => SKILLS_API_KEY_ENV,
|
|
21111
|
+
REDACTED_VAULT_REFERENCE: () => REDACTED_VAULT_REFERENCE,
|
|
21110
21112
|
MissingSkillsFleetError: () => MissingSkillsFleetError
|
|
21111
21113
|
});
|
|
21112
21114
|
function isCredentialResolutionError(error61) {
|
|
@@ -21115,10 +21117,15 @@ function isCredentialResolutionError(error61) {
|
|
|
21115
21117
|
function isSkillsFleetCredentialError(error61) {
|
|
21116
21118
|
return error61 instanceof SkillsFleetCredentialError || typeof error61 === "object" && error61 !== null && error61.name === "SkillsFleetCredentialError";
|
|
21117
21119
|
}
|
|
21118
|
-
function
|
|
21120
|
+
function redactVaultReference(message, vaultReference) {
|
|
21121
|
+
if (!vaultReference)
|
|
21122
|
+
return message;
|
|
21123
|
+
return message.split(vaultReference).join(REDACTED_VAULT_REFERENCE);
|
|
21124
|
+
}
|
|
21125
|
+
function asSkillsFleetCredentialError(error61, vaultReference) {
|
|
21119
21126
|
if (!isCredentialResolutionError(error61))
|
|
21120
21127
|
return null;
|
|
21121
|
-
return new SkillsFleetCredentialError(error61.message, "MISSING_API_CREDENTIAL");
|
|
21128
|
+
return new SkillsFleetCredentialError(redactVaultReference(error61.message, vaultReference), "MISSING_API_CREDENTIAL");
|
|
21122
21129
|
}
|
|
21123
21130
|
function normalizeSkillsApiOrigin(apiUrl) {
|
|
21124
21131
|
const url2 = new URL(apiUrl);
|
|
@@ -21305,7 +21312,7 @@ async function resolveSkillsConnection(env = process.env, options = {}) {
|
|
|
21305
21312
|
try {
|
|
21306
21313
|
completed = await completePointerCredential(SKILLS_APP, pointer, env);
|
|
21307
21314
|
} catch (error61) {
|
|
21308
|
-
const translated = asSkillsFleetCredentialError(error61);
|
|
21315
|
+
const translated = asSkillsFleetCredentialError(error61, pointer.pointerVaultKey);
|
|
21309
21316
|
if (translated)
|
|
21310
21317
|
throw translated;
|
|
21311
21318
|
throw error61;
|
|
@@ -21361,7 +21368,7 @@ function requireSkillsFleet(action = "This command", env = process.env, options
|
|
|
21361
21368
|
return fleet;
|
|
21362
21369
|
throw new MissingSkillsFleetError(action);
|
|
21363
21370
|
}
|
|
21364
|
-
var SKILLS_APP = "skills", ENV_KEYS, SKILLS_API_URL_ENV_KEYS, SKILLS_API_KEY_ENV_KEYS, SKILLS_API_URL_ENV, SKILLS_API_KEY_ENV, SkillsFleetCredentialError, localNoticePrinted = false, MissingSkillsFleetError;
|
|
21371
|
+
var SKILLS_APP = "skills", ENV_KEYS, SKILLS_API_URL_ENV_KEYS, SKILLS_API_KEY_ENV_KEYS, SKILLS_API_URL_ENV, SKILLS_API_KEY_ENV, SkillsFleetCredentialError, REDACTED_VAULT_REFERENCE = "[redacted vault reference]", localNoticePrinted = false, MissingSkillsFleetError;
|
|
21365
21372
|
var init_fleet_credentials = __esm(() => {
|
|
21366
21373
|
init_transport();
|
|
21367
21374
|
init_instance_credentials();
|
|
@@ -39490,14 +39497,15 @@ function profileSelectionSnapshot(selections) {
|
|
|
39490
39497
|
var MAX_PROFILE_SELECTIONS = 4096, MAX_PROFILE_DOCUMENT_BYTES, MAX_SKILL_SESSION_ID_CHARS = 256, PROFILE_SESSION_ENVELOPE_BYTES, MAX_RESOLVED_PROFILE_BYTES, LEGACY_PROFILE_SELECTIONS = 256, LEGACY_PROFILE_DOCUMENT_BYTES = 1e6;
|
|
39491
39498
|
var init_profile_limits = __esm(() => {
|
|
39492
39499
|
MAX_PROFILE_DOCUMENT_BYTES = 8 * 1024 * 1024;
|
|
39493
|
-
PROFILE_SESSION_ENVELOPE_BYTES = MAX_PROFILE_SELECTIONS * 67 + MAX_SKILL_SESSION_ID_CHARS *
|
|
39500
|
+
PROFILE_SESSION_ENVELOPE_BYTES = MAX_PROFILE_SELECTIONS * 67 + MAX_SKILL_SESSION_ID_CHARS * 12 + 512;
|
|
39494
39501
|
MAX_RESOLVED_PROFILE_BYTES = MAX_PROFILE_DOCUMENT_BYTES - PROFILE_SESSION_ENVELOPE_BYTES;
|
|
39495
39502
|
});
|
|
39496
39503
|
|
|
39497
39504
|
// src/lib/selection-cache.ts
|
|
39498
39505
|
import { createHash as createHash3, randomUUID } from "crypto";
|
|
39499
|
-
import { closeSync as closeSync5, constants as constants2, fstatSync as fstatSync5, lstatSync as lstatSync5, mkdirSync as mkdirSync4, openSync as openSync5, readSync as readSync2, renameSync as renameSync2, unlinkSync, writeFileSync as writeFileSync4 } from "fs";
|
|
39506
|
+
import { closeSync as closeSync5, constants as constants2, fstatSync as fstatSync5, fsyncSync, lstatSync as lstatSync5, mkdirSync as mkdirSync4, openSync as openSync5, readSync as readSync2, renameSync as renameSync2, unlinkSync, writeFileSync as writeFileSync4 } from "fs";
|
|
39500
39507
|
import { dirname as dirname5, join as join13, parse as parse6, resolve as resolve3 } from "path";
|
|
39508
|
+
import { isDeepStrictEqual } from "util";
|
|
39501
39509
|
function selectionCacheRoot(options = {}) {
|
|
39502
39510
|
return resolve3(options.cacheDir ?? join13(getDataDirReadOnly(), "selection-cache"));
|
|
39503
39511
|
}
|
|
@@ -39601,12 +39609,21 @@ function writeSelectionJson(path, value) {
|
|
|
39601
39609
|
throw new SkillSelectionError("RECEIPT_TOO_LARGE", "The Skills selection receipt exceeds its size limit.");
|
|
39602
39610
|
atomicWrite(path, bytes, 384);
|
|
39603
39611
|
}
|
|
39604
|
-
function atomicWrite(path, bytes, mode) {
|
|
39612
|
+
function atomicWrite(path, bytes, mode, durable = false) {
|
|
39605
39613
|
assertRegularPath(path, true);
|
|
39606
39614
|
const temporary = join13(dirname5(path), `.selection-${randomUUID()}.tmp`);
|
|
39607
39615
|
try {
|
|
39608
|
-
|
|
39616
|
+
const fd = openSync5(temporary, constants2.O_WRONLY | constants2.O_CREAT | constants2.O_EXCL | constants2.O_NOFOLLOW, mode);
|
|
39617
|
+
try {
|
|
39618
|
+
writeFileSync4(fd, bytes);
|
|
39619
|
+
if (durable)
|
|
39620
|
+
fsyncSync(fd);
|
|
39621
|
+
} finally {
|
|
39622
|
+
closeSync5(fd);
|
|
39623
|
+
}
|
|
39609
39624
|
renameSync2(temporary, path);
|
|
39625
|
+
if (durable)
|
|
39626
|
+
syncDirectory(dirname5(path));
|
|
39610
39627
|
} finally {
|
|
39611
39628
|
try {
|
|
39612
39629
|
unlinkSync(temporary);
|
|
@@ -39719,16 +39736,130 @@ function sessionReceiptPath(sessionId, options = {}) {
|
|
|
39719
39736
|
throw new SkillSelectionError("INVALID_SESSION", `A Skills session id must contain 1\u2013${MAX_SKILL_SESSION_ID_CHARS} characters.`);
|
|
39720
39737
|
return join13(selectionCacheRoot(options), "sessions", `${hash2(sessionId)}.json`);
|
|
39721
39738
|
}
|
|
39722
|
-
function
|
|
39723
|
-
|
|
39724
|
-
|
|
39725
|
-
|
|
39726
|
-
|
|
39727
|
-
|
|
39728
|
-
|
|
39739
|
+
function skillSessionGeneration(receipt) {
|
|
39740
|
+
return receipt.generation ?? 0;
|
|
39741
|
+
}
|
|
39742
|
+
function validateSkillSessionBinding(binding) {
|
|
39743
|
+
if (!binding || typeof binding.sessionId !== "string" || !binding.sessionId.trim() || binding.sessionId.length > MAX_SKILL_SESSION_ID_CHARS || !Number.isSafeInteger(binding.generation) || binding.generation < 0 || !/^[a-f0-9]{64}$/.test(binding.receiptSha256)) {
|
|
39744
|
+
throw new SkillSelectionError("INVALID_RECEIPT", "The Skills session receipt contains an invalid parent snapshot binding.");
|
|
39745
|
+
}
|
|
39746
|
+
}
|
|
39747
|
+
function validateSkillSessionReceipt(receipt, sessionId) {
|
|
39748
|
+
validateSelectionReceipt(receipt);
|
|
39749
|
+
const keys = new Set(receipt.profile.selections.map(selectionKey));
|
|
39750
|
+
if (receipt.sessionId !== sessionId || !Array.isArray(receipt.loaded) || receipt.loaded.length > keys.size || new Set(receipt.loaded).size !== receipt.loaded.length || !receipt.loaded.every((key) => keys.has(key)) || receipt.generation !== undefined && (!Number.isSafeInteger(receipt.generation) || receipt.generation < 1)) {
|
|
39751
|
+
throw new SkillSelectionError("INVALID_RECEIPT", "The Skills session receipt is invalid.");
|
|
39752
|
+
}
|
|
39753
|
+
if (receipt.parent) {
|
|
39754
|
+
validateSkillSessionBinding(receipt.parent);
|
|
39755
|
+
if (receipt.parent.sessionId === sessionId)
|
|
39756
|
+
throw new SkillSelectionError("INVALID_RECEIPT", "A Skills child session cannot name itself as its parent.");
|
|
39757
|
+
}
|
|
39758
|
+
}
|
|
39759
|
+
function readSkillSessionSnapshotIfExists(sessionId, options = {}) {
|
|
39760
|
+
const path = sessionReceiptPath(sessionId, options), bytes = readRegularFile(path, MAX_PROFILE_DOCUMENT_BYTES);
|
|
39761
|
+
if (!bytes)
|
|
39762
|
+
return null;
|
|
39763
|
+
let receipt;
|
|
39764
|
+
try {
|
|
39765
|
+
receipt = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
|
|
39766
|
+
} catch {
|
|
39767
|
+
throw new SkillSelectionError("INVALID_RECEIPT", "The Skills session receipt is unreadable.");
|
|
39768
|
+
}
|
|
39769
|
+
validateSkillSessionReceipt(receipt, sessionId);
|
|
39770
|
+
const sha256 = sha256Hex(bytes);
|
|
39771
|
+
return { path, bytes, receipt, sha256, sessionId, generation: skillSessionGeneration(receipt), receiptSha256: sha256 };
|
|
39772
|
+
}
|
|
39773
|
+
function skillSessionSnapshotBinding(snapshot) {
|
|
39774
|
+
return { sessionId: snapshot.sessionId, generation: snapshot.generation, receiptSha256: snapshot.receiptSha256 };
|
|
39775
|
+
}
|
|
39776
|
+
function withSessionWriteLocks(sessionIds, options, action) {
|
|
39777
|
+
const operationId = randomUUID();
|
|
39778
|
+
const locks = [...new Set(sessionIds)].map((sessionId) => ({ sessionId, path: `${sessionReceiptPath(sessionId, options)}.write-lock` })).sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
|
|
39779
|
+
const owned = [];
|
|
39780
|
+
const assertOwned = () => {
|
|
39781
|
+
for (const lock of owned) {
|
|
39782
|
+
const current = lstatSync5(lock.path, { throwIfNoEntry: false });
|
|
39783
|
+
if (!current?.isFile() || current.dev !== lock.dev || current.ino !== lock.ino) {
|
|
39784
|
+
throw new SkillSelectionError("SESSION_WRITE_LOCK_CHANGED", "A session write lock changed during the operation; no replacement is permitted.");
|
|
39785
|
+
}
|
|
39786
|
+
}
|
|
39787
|
+
};
|
|
39788
|
+
try {
|
|
39789
|
+
for (const lock of locks) {
|
|
39790
|
+
assertRegularPath(lock.path, true);
|
|
39791
|
+
let fd;
|
|
39792
|
+
try {
|
|
39793
|
+
fd = openSync5(lock.path, constants2.O_WRONLY | constants2.O_CREAT | constants2.O_EXCL | constants2.O_NOFOLLOW, 384);
|
|
39794
|
+
} catch (error61) {
|
|
39795
|
+
if (error61.code === "EEXIST")
|
|
39796
|
+
throw new SkillSelectionError("SESSION_WRITE_LOCKED", "Another Skills process owns a required session write lock; retry after it completes. A surviving lock requires explicit recovery review.");
|
|
39797
|
+
throw error61;
|
|
39798
|
+
}
|
|
39799
|
+
const stat = fstatSync5(fd);
|
|
39800
|
+
owned.push({ path: lock.path, fd, dev: stat.dev, ino: stat.ino });
|
|
39801
|
+
writeFileSync4(fd, `${JSON.stringify({ schemaVersion: 1, operationId, sessionId: lock.sessionId, pid: process.pid })}
|
|
39802
|
+
`);
|
|
39803
|
+
}
|
|
39804
|
+
return action(assertOwned);
|
|
39805
|
+
} finally {
|
|
39806
|
+
for (const lock of owned.reverse()) {
|
|
39807
|
+
closeSync5(lock.fd);
|
|
39808
|
+
const current = lstatSync5(lock.path, { throwIfNoEntry: false });
|
|
39809
|
+
if (current?.isFile() && current.dev === lock.dev && current.ino === lock.ino)
|
|
39810
|
+
unlinkSync(lock.path);
|
|
39729
39811
|
}
|
|
39730
39812
|
}
|
|
39731
|
-
|
|
39813
|
+
}
|
|
39814
|
+
function sameSnapshot(actual, expected) {
|
|
39815
|
+
return actual === null ? expected === null : expected !== null && actual.sessionId === expected.sessionId && actual.generation === expected.generation && actual.receiptSha256 === expected.receiptSha256;
|
|
39816
|
+
}
|
|
39817
|
+
function nextSkillSessionGeneration(generation) {
|
|
39818
|
+
if (!Number.isSafeInteger(generation) || generation < 0 || generation >= Number.MAX_SAFE_INTEGER) {
|
|
39819
|
+
throw new SkillSelectionError("SESSION_GENERATION_EXHAUSTED", "The Skills session generation cannot advance safely; preserve the receipt and review recovery before continuing.");
|
|
39820
|
+
}
|
|
39821
|
+
return generation + 1;
|
|
39822
|
+
}
|
|
39823
|
+
function parentChanged() {
|
|
39824
|
+
throw new SkillSelectionError("SESSION_PARENT_CHANGED", "The parent Skills session changed while the child was resolving; resolve the child again from the current parent pin.");
|
|
39825
|
+
}
|
|
39826
|
+
function writeSkillSession(receipt, expected, options = {}) {
|
|
39827
|
+
validateSkillSessionReceipt(receipt, receipt.sessionId);
|
|
39828
|
+
if (expected.parent)
|
|
39829
|
+
validateSkillSessionBinding(expected.parent);
|
|
39830
|
+
if (expected.parent?.sessionId === receipt.sessionId)
|
|
39831
|
+
throw new SkillSelectionError("INVALID_RECEIPT", "A Skills child session cannot name itself as its parent.");
|
|
39832
|
+
const lockIds = expected.parent ? [receipt.sessionId, expected.parent.sessionId] : [receipt.sessionId];
|
|
39833
|
+
withSessionWriteLocks(lockIds, options, (assertOwned) => {
|
|
39834
|
+
const current = readSkillSessionSnapshotIfExists(receipt.sessionId, options);
|
|
39835
|
+
if (!sameSnapshot(current, expected.current) || current && !isDeepStrictEqual(current.receipt.profile, receipt.profile)) {
|
|
39836
|
+
throw new SkillSelectionError("SESSION_RECEIPT_CHANGED", "The Skills session receipt changed while context was loading; resolve context again without replacing the current pin.");
|
|
39837
|
+
}
|
|
39838
|
+
let parent = null;
|
|
39839
|
+
if (expected.parent) {
|
|
39840
|
+
parent = readSkillSessionSnapshotIfExists(expected.parent.sessionId, options);
|
|
39841
|
+
if (!sameSnapshot(parent, expected.parent) || !parent || !isDeepStrictEqual(parent.receipt.profile, receipt.profile))
|
|
39842
|
+
parentChanged();
|
|
39843
|
+
}
|
|
39844
|
+
const generation = nextSkillSessionGeneration(current?.generation ?? 0);
|
|
39845
|
+
const next = current ? { ...current.receipt, generation, loaded: [...new Set([...current.receipt.loaded, ...receipt.loaded])] } : { ...receipt, generation, ...expected.parent ? { parent: expected.parent } : {} };
|
|
39846
|
+
assertOwned();
|
|
39847
|
+
if (expected.parent) {
|
|
39848
|
+
parent = readSkillSessionSnapshotIfExists(expected.parent.sessionId, options);
|
|
39849
|
+
if (!sameSnapshot(parent, expected.parent))
|
|
39850
|
+
parentChanged();
|
|
39851
|
+
}
|
|
39852
|
+
writeSelectionJson(sessionReceiptPath(receipt.sessionId, options), next);
|
|
39853
|
+
});
|
|
39854
|
+
}
|
|
39855
|
+
function syncDirectory(path) {
|
|
39856
|
+
assertRegularPath(path);
|
|
39857
|
+
const fd = openSync5(path, constants2.O_RDONLY | constants2.O_DIRECTORY | constants2.O_NOFOLLOW);
|
|
39858
|
+
try {
|
|
39859
|
+
fsyncSync(fd);
|
|
39860
|
+
} finally {
|
|
39861
|
+
closeSync5(fd);
|
|
39862
|
+
}
|
|
39732
39863
|
}
|
|
39733
39864
|
var SkillSelectionError, MAX_CACHED_PROFILE_AGE_MS, SELECTION_LOCK_FILE = "selection.lock.json";
|
|
39734
39865
|
var init_selection_cache = __esm(() => {
|
|
@@ -39748,6 +39879,7 @@ var init_selection_cache = __esm(() => {
|
|
|
39748
39879
|
});
|
|
39749
39880
|
|
|
39750
39881
|
// src/lib/agent-policy-limits.ts
|
|
39882
|
+
import { basename as basename4, isAbsolute as isAbsolute4, resolve as resolve4 } from "path";
|
|
39751
39883
|
function object4(value) {
|
|
39752
39884
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
39753
39885
|
}
|
|
@@ -39812,7 +39944,11 @@ function assertAgentPolicyCollections(policy) {
|
|
|
39812
39944
|
text(source.path);
|
|
39813
39945
|
requireBound(source.sha256 === null || typeof source.sha256 === "string" && /^[a-f0-9]{64}$/.test(source.sha256));
|
|
39814
39946
|
if (source.hashMode !== undefined)
|
|
39815
|
-
requireBound(["bytes", "path-bytes", "claude-plugin-registry"].includes(source.hashMode) && source.format === undefined && source.fields === undefined && (source.hashMode === "bytes" || source.sha256 !== null));
|
|
39947
|
+
requireBound(["bytes", "path-bytes", "claude-plugin-registry", "claude-marketplace-registry", "claude-settings-v1"].includes(source.hashMode) && source.format === undefined && source.fields === undefined && (source.hashMode === "bytes" || source.sha256 !== null));
|
|
39948
|
+
if (source.hashMode === "claude-settings-v1")
|
|
39949
|
+
requireBound(agent === "claude" && value.agent === "claude" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute4(source.path) && resolve4(source.path) === source.path && basename4(source.path) === "settings.json");
|
|
39950
|
+
if (source.hashMode === "claude-marketplace-registry")
|
|
39951
|
+
requireBound(agent === "claude" && value.agent === "claude" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute4(source.path) && resolve4(source.path) === source.path && basename4(source.path) === "known_marketplaces.json");
|
|
39816
39952
|
if (source.hashMode === "claude-plugin-registry") {
|
|
39817
39953
|
requireBound(agent === "claude");
|
|
39818
39954
|
const managed = array3(source.managedPlugins, 64);
|
|
@@ -47400,7 +47536,7 @@ var init_plugin_projection = __esm(() => {
|
|
|
47400
47536
|
});
|
|
47401
47537
|
|
|
47402
47538
|
// src/lib/plugin-projection-store.ts
|
|
47403
|
-
import { constants as constants5, closeSync as closeSync8, fchmodSync, fstatSync as fstatSync8, fsyncSync, linkSync, lstatSync as lstatSync8, mkdirSync as mkdirSync6, openSync as openSync8, opendirSync, readSync as readSync4, renameSync as renameSync3, rmdirSync as rmdirSync2, rmSync as rmSync2, unlinkSync as unlinkSync3, writeSync as writeSync2 } from "fs";
|
|
47539
|
+
import { constants as constants5, closeSync as closeSync8, fchmodSync, fstatSync as fstatSync8, fsyncSync as fsyncSync2, linkSync, lstatSync as lstatSync8, mkdirSync as mkdirSync6, openSync as openSync8, opendirSync, readSync as readSync4, renameSync as renameSync3, rmdirSync as rmdirSync2, rmSync as rmSync2, unlinkSync as unlinkSync3, writeSync as writeSync2 } from "fs";
|
|
47404
47540
|
var READ_FLAGS, WRITE_FLAGS;
|
|
47405
47541
|
var init_plugin_projection_store = __esm(() => {
|
|
47406
47542
|
init_plugin_projection();
|
|
@@ -47452,6 +47588,69 @@ var init_plugin_discovery = __esm(() => {
|
|
|
47452
47588
|
init_plugin_projection_store();
|
|
47453
47589
|
});
|
|
47454
47590
|
|
|
47591
|
+
// src/lib/claude-marketplace-registry.ts
|
|
47592
|
+
var CLAUDE_MARKETPLACE_REGISTRY_LIMITS;
|
|
47593
|
+
var init_claude_marketplace_registry = __esm(() => {
|
|
47594
|
+
CLAUDE_MARKETPLACE_REGISTRY_LIMITS = Object.freeze({ bytes: 1024 * 1024, rows: 1024, depth: 32, nodes: 65536, stringCharacters: 16384, pathCharacters: 4096 });
|
|
47595
|
+
});
|
|
47596
|
+
|
|
47597
|
+
// src/lib/claude-settings-witness.ts
|
|
47598
|
+
var CLAUDE_SETTINGS_WITNESS_LIMITS, BOOLEAN_PREFERENCES, ENUM_PREFERENCES, BUILTIN_MODEL_SELECTIONS;
|
|
47599
|
+
var init_claude_settings_witness = __esm(() => {
|
|
47600
|
+
CLAUDE_SETTINGS_WITNESS_LIMITS = Object.freeze({ bytes: 1024 * 1024, rows: 1024, depth: 32, nodes: 65536, stringCharacters: 16384, pathCharacters: 4096 });
|
|
47601
|
+
BOOLEAN_PREFERENCES = new Set([
|
|
47602
|
+
"autoScrollEnabled",
|
|
47603
|
+
"axScreenReader",
|
|
47604
|
+
"emojiCompletionEnabled",
|
|
47605
|
+
"prefersReducedMotion",
|
|
47606
|
+
"showTurnDuration",
|
|
47607
|
+
"spinnerTipsEnabled",
|
|
47608
|
+
"syntaxHighlightingDisabled",
|
|
47609
|
+
"terminalProgressBarEnabled",
|
|
47610
|
+
"terminalTitleFromRename",
|
|
47611
|
+
"verbose",
|
|
47612
|
+
"wheelScrollAccelerationEnabled"
|
|
47613
|
+
]);
|
|
47614
|
+
ENUM_PREFERENCES = Object.freeze({
|
|
47615
|
+
editorMode: ["normal", "vim"],
|
|
47616
|
+
tui: ["default", "fullscreen"],
|
|
47617
|
+
viewMode: ["default", "verbose", "focus"]
|
|
47618
|
+
});
|
|
47619
|
+
BUILTIN_MODEL_SELECTIONS = new Set([
|
|
47620
|
+
"default",
|
|
47621
|
+
"best",
|
|
47622
|
+
"fable",
|
|
47623
|
+
"fable[1m]",
|
|
47624
|
+
"sonnet",
|
|
47625
|
+
"sonnet[1m]",
|
|
47626
|
+
"opus",
|
|
47627
|
+
"opus[1m]",
|
|
47628
|
+
"haiku",
|
|
47629
|
+
"opusplan",
|
|
47630
|
+
"claude-fable-5-1",
|
|
47631
|
+
"claude-fable-5",
|
|
47632
|
+
"claude-fable-5[1m]",
|
|
47633
|
+
"claude-opus-5",
|
|
47634
|
+
"claude-sonnet-5",
|
|
47635
|
+
"claude-haiku-4-5-20251001",
|
|
47636
|
+
"claude-opus-4-6",
|
|
47637
|
+
"claude-sonnet-4-5",
|
|
47638
|
+
"claude-sonnet-4-5-20250929",
|
|
47639
|
+
"claude-opus-4-8",
|
|
47640
|
+
"claude-opus-4-8[1m]",
|
|
47641
|
+
"claude-opus-4-7",
|
|
47642
|
+
"claude-sonnet-4-6",
|
|
47643
|
+
"claude-opus-4-5-20251101",
|
|
47644
|
+
"claude-opus-4-5",
|
|
47645
|
+
"claude-haiku-4-5",
|
|
47646
|
+
"claude-fable-5-1[1m]",
|
|
47647
|
+
"claude-opus-5[1m]",
|
|
47648
|
+
"claude-opus-4-7[1m]",
|
|
47649
|
+
"claude-opus-4-6[1m]",
|
|
47650
|
+
"claude-sonnet-4-6[1m]"
|
|
47651
|
+
]);
|
|
47652
|
+
});
|
|
47653
|
+
|
|
47455
47654
|
// src/lib/agent-discovery.ts
|
|
47456
47655
|
var init_agent_discovery = __esm(() => {
|
|
47457
47656
|
init_agent_policy_limits();
|
|
@@ -47461,6 +47660,8 @@ var init_agent_discovery = __esm(() => {
|
|
|
47461
47660
|
init_agent_discovery_path_bytes();
|
|
47462
47661
|
init_plugin_discovery();
|
|
47463
47662
|
init_plugin_admission();
|
|
47663
|
+
init_claude_marketplace_registry();
|
|
47664
|
+
init_claude_settings_witness();
|
|
47464
47665
|
init_agent_discovery_directories();
|
|
47465
47666
|
});
|
|
47466
47667
|
|
|
@@ -48024,11 +48225,18 @@ var init_selected_document = __esm(() => {
|
|
|
48024
48225
|
|
|
48025
48226
|
// src/lib/selection-resolver.ts
|
|
48026
48227
|
async function resolveSelectionContext(profileId, options = {}) {
|
|
48027
|
-
const
|
|
48028
|
-
const
|
|
48228
|
+
const sessionState = options.sessionId ? readSkillSessionSnapshotIfExists(options.sessionId, options) : null;
|
|
48229
|
+
const session = sessionState?.receipt ?? null;
|
|
48230
|
+
const parentState = !session && options.parentSessionId ? readSkillSessionSnapshotIfExists(options.parentSessionId, options) : null;
|
|
48231
|
+
if (!session && options.parentSessionId && !parentState) {
|
|
48232
|
+
throw new SkillSelectionError("SESSION_PARENT_NOT_FOUND", "A child Skills session requires an existing parent receipt so its inherited pin can be bound exactly.");
|
|
48233
|
+
}
|
|
48234
|
+
const parentSession = parentState?.receipt ?? null;
|
|
48235
|
+
const sessionSnapshot = sessionState ? skillSessionSnapshotBinding(sessionState) : null;
|
|
48236
|
+
const parentSnapshot = parentState ? skillSessionSnapshotBinding(parentState) : undefined;
|
|
48029
48237
|
const project = options.projectDir ? readProjectSelection(options.projectDir) : null;
|
|
48030
48238
|
if (session && session.profile.profileId !== profileId || parentSession && parentSession.profile.profileId !== profileId || project && project.profile.profileId !== profileId) {
|
|
48031
|
-
throw new SkillSelectionError("PROFILE_LOCK_MISMATCH", "The session or project is pinned to a different Skills profile. Select
|
|
48239
|
+
throw new SkillSelectionError("PROFILE_LOCK_MISMATCH", "The session or project is pinned to a different Skills profile. Select the pinned profile, or review skills sessions reconcile for an intentional session change and explicit project sync for a project change.");
|
|
48032
48240
|
}
|
|
48033
48241
|
if (options.cached) {
|
|
48034
48242
|
const receipt2 = session ?? parentSession ?? project ?? readSelectionProfile(profileId, options);
|
|
@@ -48036,7 +48244,7 @@ async function resolveSelectionContext(profileId, options = {}) {
|
|
|
48036
48244
|
throw new SkillSelectionError("CACHED_PROFILE_MISSING", "No verified Skills profile is cached; authenticate and sync it first.");
|
|
48037
48245
|
assertFreshCachedProfile(receipt2, options);
|
|
48038
48246
|
assertBinding(receipt2.profile, options);
|
|
48039
|
-
return { receipt: receipt2, session, inheritedLoaded: parentSession?.loaded };
|
|
48247
|
+
return { receipt: receipt2, session, sessionSnapshot, parentSnapshot, inheritedLoaded: parentSession?.loaded };
|
|
48040
48248
|
}
|
|
48041
48249
|
const client = options.client ?? await createProfileClient();
|
|
48042
48250
|
const current = await client.resolveProfile(profileId);
|
|
@@ -48049,7 +48257,7 @@ async function resolveSelectionContext(profileId, options = {}) {
|
|
|
48049
48257
|
throw new SkillSelectionError("PROFILE_IDENTITY_MISMATCH", "The pinned selection belongs to another Skills authority or workspace.");
|
|
48050
48258
|
}
|
|
48051
48259
|
const receipt = locked ?? { schemaVersion: 1, verifiedAt: new Date((options.now ?? Date.now)()).toISOString(), profile: current };
|
|
48052
|
-
return { receipt, session, client, inheritedLoaded: parentSession?.loaded };
|
|
48260
|
+
return { receipt, session, sessionSnapshot, parentSnapshot, client, inheritedLoaded: parentSession?.loaded };
|
|
48053
48261
|
}
|
|
48054
48262
|
function assertBinding(profile, options) {
|
|
48055
48263
|
if (options.authority !== undefined && profile.authority !== options.authority || options.workspaceId !== undefined && profile.workspaceId !== options.workspaceId) {
|
|
@@ -48088,7 +48296,7 @@ async function loadSelectedSkill(spec, profileId, options = {}) {
|
|
|
48088
48296
|
sessionId: options.sessionId,
|
|
48089
48297
|
loaded: [...new Set([...context.session?.loaded ?? [], selectionKey(selection)])]
|
|
48090
48298
|
};
|
|
48091
|
-
|
|
48299
|
+
writeSkillSession(session, { current: context.sessionSnapshot, parent: context.parentSnapshot }, options);
|
|
48092
48300
|
}
|
|
48093
48301
|
return { content, selection, receipt };
|
|
48094
48302
|
}
|
|
@@ -48132,6 +48340,14 @@ var init_skill_context = __esm(() => {
|
|
|
48132
48340
|
init_selected_document();
|
|
48133
48341
|
});
|
|
48134
48342
|
|
|
48343
|
+
// src/lib/session-reconciliation.ts
|
|
48344
|
+
var SESSION_RECONCILIATION_PLAN_TTL_MS;
|
|
48345
|
+
var init_session_reconciliation = __esm(() => {
|
|
48346
|
+
init_profile_client();
|
|
48347
|
+
init_selection_cache();
|
|
48348
|
+
SESSION_RECONCILIATION_PLAN_TTL_MS = 5 * 60 * 1000;
|
|
48349
|
+
});
|
|
48350
|
+
|
|
48135
48351
|
// src/cli/commands/context.ts
|
|
48136
48352
|
function selectedProfileId(explicit) {
|
|
48137
48353
|
return explicit ?? process.env.HASNA_SKILLS_SELECTION_PROFILE ?? readManagedSkillPolicy()?.profileId ?? "default";
|
|
@@ -48142,6 +48358,7 @@ var init_context = __esm(() => {
|
|
|
48142
48358
|
init_selection_resolver();
|
|
48143
48359
|
init_selection_cache();
|
|
48144
48360
|
init_managed_policy();
|
|
48361
|
+
init_session_reconciliation();
|
|
48145
48362
|
});
|
|
48146
48363
|
|
|
48147
48364
|
// src/lib/remote-customer-operations.ts
|
|
@@ -48153,7 +48370,7 @@ var init_remote_customer_operations = __esm(() => {
|
|
|
48153
48370
|
{ name: "list_remote_skills", title: "List Remote Skills", parameter: null, mutates: false, invoke: (client) => client.listSkills() },
|
|
48154
48371
|
{ name: "get_billing_status", title: "Get Billing Status", parameter: null, mutates: false, invoke: (client) => client.getBillingStatus() },
|
|
48155
48372
|
{ name: "list_credit_packs", title: "List Credit Packs", parameter: null, mutates: false, invoke: (client) => client.listCreditPacks() },
|
|
48156
|
-
{ name: "create_credit_checkout", title: "Create Credit Checkout", parameter: "pack_id", mutates: true, invoke: (client, value) => client.createCreditCheckout(value) },
|
|
48373
|
+
{ name: "create_credit_checkout", title: "Create Credit Checkout", parameter: "pack_id", mutates: true, invoke: (client, value, options) => client.createCreditCheckout(value, options) },
|
|
48157
48374
|
{ name: "get_billing_usage", title: "Get Billing Usage", parameter: null, mutates: false, invoke: (client) => client.getUsage() },
|
|
48158
48375
|
{ name: "list_invoices", title: "List Invoices", parameter: null, mutates: false, invoke: (client) => client.listInvoices() },
|
|
48159
48376
|
{ name: "create_billing_checkout", title: "Create Billing Checkout", parameter: null, mutates: true, invoke: (client) => client.createBillingCheckout() },
|
|
@@ -48961,13 +49178,13 @@ var init_remote_workspace_leave = __esm(() => {
|
|
|
48961
49178
|
|
|
48962
49179
|
// src/lib/auth-store.ts
|
|
48963
49180
|
import { chmodSync, existsSync as existsSync13, mkdirSync as mkdirSync8, readFileSync as readFileSync15, renameSync as renameSync4, statSync as statSync8, unlinkSync as unlinkSync4, writeFileSync as writeFileSync6 } from "fs";
|
|
48964
|
-
import { basename as
|
|
49181
|
+
import { basename as basename5, dirname as dirname6, join as join19 } from "path";
|
|
48965
49182
|
function getAuthFilePath(env = process.env) {
|
|
48966
49183
|
return skillsCredentialFilePath(env);
|
|
48967
49184
|
}
|
|
48968
49185
|
function getIdentityFilePath(env = process.env) {
|
|
48969
49186
|
const file2 = skillsCredentialFilePath(env);
|
|
48970
|
-
return join19(dirname6(file2),
|
|
49187
|
+
return join19(dirname6(file2), basename5(file2).replace(/^credentials/, "identity") + ".json");
|
|
48971
49188
|
}
|
|
48972
49189
|
function getApiUrl(action, env = process.env, options = {}) {
|
|
48973
49190
|
return requireSkillsApiOrigin(action, env, options);
|
|
@@ -49121,6 +49338,35 @@ var init_remote_account = __esm(() => {
|
|
|
49121
49338
|
};
|
|
49122
49339
|
});
|
|
49123
49340
|
|
|
49341
|
+
// src/lib/remote-credit-checkout.ts
|
|
49342
|
+
function creditCheckoutRequestKey(value) {
|
|
49343
|
+
if (value === undefined)
|
|
49344
|
+
return crypto.randomUUID();
|
|
49345
|
+
if (typeof value !== "string" || !creditCheckoutKeyPattern.test(value))
|
|
49346
|
+
throw new Error("Checkout idempotency key must be 8-255 URL-safe characters");
|
|
49347
|
+
return value;
|
|
49348
|
+
}
|
|
49349
|
+
function creditCheckoutFailure(value, status, key) {
|
|
49350
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
49351
|
+
return { code: "CREDIT_CHECKOUT_UNCONFIRMED" };
|
|
49352
|
+
const row = value;
|
|
49353
|
+
if (row.requestIdempotencyKey !== undefined && row.requestIdempotencyKey !== key)
|
|
49354
|
+
return { code: "CREDIT_CHECKOUT_UNCONFIRMED" };
|
|
49355
|
+
const code = status === 409 && row.error === "credit checkout in_progress" ? "CREDIT_CHECKOUT_IN_PROGRESS" : status === 409 && row.error === "credit checkout expired" && row.requestIdempotencyKey === key ? "CREDIT_CHECKOUT_EXPIRED" : status === 409 && row.error === "credit checkout fulfilled" && row.requestIdempotencyKey === key ? "CREDIT_CHECKOUT_FULFILLED" : "CREDIT_CHECKOUT_UNCONFIRMED";
|
|
49356
|
+
const delay = row.retryAfterSeconds;
|
|
49357
|
+
return { code, ...code === "CREDIT_CHECKOUT_IN_PROGRESS" || status === 503 && row.error === "credit checkout creation unresolved" ? typeof delay === "number" && Number.isSafeInteger(delay) && delay > 0 && delay <= 3600 ? { retryAfterSeconds: delay } : {} : {} };
|
|
49358
|
+
}
|
|
49359
|
+
var creditCheckoutKeyPattern, creditCheckoutMessages;
|
|
49360
|
+
var init_remote_credit_checkout = __esm(() => {
|
|
49361
|
+
creditCheckoutKeyPattern = /^[A-Za-z0-9._:-]{8,255}$/;
|
|
49362
|
+
creditCheckoutMessages = {
|
|
49363
|
+
CREDIT_CHECKOUT_UNCONFIRMED: "Checkout creation could not be confirmed. Keep the request idempotency key, inspect billing, and use the same key for an explicit retry on the same server, account and pack. No automatic retry was made.",
|
|
49364
|
+
CREDIT_CHECKOUT_IN_PROGRESS: "This checkout is still being created. Wait before explicitly retrying the same server, account and pack with the same request idempotency key. No automatic retry was made.",
|
|
49365
|
+
CREDIT_CHECKOUT_EXPIRED: "This checkout has expired. Inspect billing before deliberately starting a new purchase with a new request idempotency key. Do not retry this checkout automatically.",
|
|
49366
|
+
CREDIT_CHECKOUT_FULFILLED: "This checkout is already fulfilled. Inspect the account balance; do not create another checkout to recover this purchase."
|
|
49367
|
+
};
|
|
49368
|
+
});
|
|
49369
|
+
|
|
49124
49370
|
// src/lib/remote-profile.ts
|
|
49125
49371
|
function customerNamePatch(input2, field) {
|
|
49126
49372
|
if (!isRecord4(input2) || Object.keys(input2).length !== 1 || !Object.hasOwn(input2, field))
|
|
@@ -49166,10 +49412,10 @@ async function readQuoteUnavailableCode(response) {
|
|
|
49166
49412
|
let timer;
|
|
49167
49413
|
let deadlineExceeded = false;
|
|
49168
49414
|
const expired = Symbol("quote body deadline");
|
|
49169
|
-
const deadline = new Promise((
|
|
49415
|
+
const deadline = new Promise((resolve5) => {
|
|
49170
49416
|
timer = setTimeout(() => {
|
|
49171
49417
|
deadlineExceeded = true;
|
|
49172
|
-
|
|
49418
|
+
resolve5(expired);
|
|
49173
49419
|
reader.cancel().catch(() => {});
|
|
49174
49420
|
}, 1500);
|
|
49175
49421
|
});
|
|
@@ -49284,6 +49530,7 @@ __export(exports_remote_client, {
|
|
|
49284
49530
|
RemoteRouteUnsupportedError: () => RemoteRouteUnsupportedError,
|
|
49285
49531
|
RemoteRequestError: () => RemoteRequestError,
|
|
49286
49532
|
RemoteQuoteUnavailableError: () => RemoteQuoteUnavailableError,
|
|
49533
|
+
RemoteCreditCheckoutError: () => RemoteCreditCheckoutError,
|
|
49287
49534
|
RemoteCapabilityUnavailableError: () => RemoteCapabilityUnavailableError
|
|
49288
49535
|
});
|
|
49289
49536
|
|
|
@@ -49734,14 +49981,43 @@ class RemoteSkillsClient {
|
|
|
49734
49981
|
async listCreditPacks() {
|
|
49735
49982
|
return parseRemoteCreditPacks(await (await this.requestNewRoute("/api/v1/billing/credits")).json());
|
|
49736
49983
|
}
|
|
49737
|
-
async createCreditCheckout(packId) {
|
|
49984
|
+
async createCreditCheckout(packId, options = {}) {
|
|
49985
|
+
const requestIdempotencyKey = creditCheckoutRequestKey(options.idempotencyKey);
|
|
49738
49986
|
const packs = await this.listCreditPacks();
|
|
49739
49987
|
if (!packs.some((pack) => pack.id === packId))
|
|
49740
49988
|
throw new Error("Choose a credit pack returned by skills credits packs");
|
|
49741
|
-
|
|
49742
|
-
|
|
49743
|
-
|
|
49744
|
-
|
|
49989
|
+
let response;
|
|
49990
|
+
try {
|
|
49991
|
+
response = await this.request("/api/v1/billing/credits", {
|
|
49992
|
+
method: "POST",
|
|
49993
|
+
body: JSON.stringify({ packId, idempotencyKey: requestIdempotencyKey })
|
|
49994
|
+
});
|
|
49995
|
+
} catch {
|
|
49996
|
+
throw new RemoteCreditCheckoutError("CREDIT_CHECKOUT_UNCONFIRMED", 0, requestIdempotencyKey);
|
|
49997
|
+
}
|
|
49998
|
+
if (response.status === 404 || response.status === 405) {
|
|
49999
|
+
response.body?.cancel().catch(() => {});
|
|
50000
|
+
throw new RemoteRouteUnsupportedError("/api/v1/billing/credits", response.status, this.apiUrl);
|
|
50001
|
+
}
|
|
50002
|
+
let value;
|
|
50003
|
+
try {
|
|
50004
|
+
value = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(await readBoundedResponse(response, 4096)));
|
|
50005
|
+
} catch {
|
|
50006
|
+
throw new RemoteCreditCheckoutError("CREDIT_CHECKOUT_UNCONFIRMED", response.status, requestIdempotencyKey);
|
|
50007
|
+
}
|
|
50008
|
+
if (!response.ok) {
|
|
50009
|
+
const failure = creditCheckoutFailure(value, response.status, requestIdempotencyKey);
|
|
50010
|
+
throw new RemoteCreditCheckoutError(failure.code, response.status, requestIdempotencyKey, failure.retryAfterSeconds);
|
|
50011
|
+
}
|
|
50012
|
+
try {
|
|
50013
|
+
const checkout = parseRemoteCheckout(value);
|
|
50014
|
+
const echo = value.requestIdempotencyKey;
|
|
50015
|
+
if (echo !== undefined && echo !== requestIdempotencyKey)
|
|
50016
|
+
throw new Error("checkout request key changed");
|
|
50017
|
+
return { ...checkout, requestIdempotencyKey };
|
|
50018
|
+
} catch {
|
|
50019
|
+
throw new RemoteCreditCheckoutError("CREDIT_CHECKOUT_UNCONFIRMED", response.status, requestIdempotencyKey);
|
|
50020
|
+
}
|
|
49745
50021
|
}
|
|
49746
50022
|
async getUsage() {
|
|
49747
50023
|
return this.arrayResponse("/api/v1/billing/usage");
|
|
@@ -50111,7 +50387,7 @@ async function createRemoteSkillsClient(env = process.env) {
|
|
|
50111
50387
|
function createRemoteSkillsClientReadOnly(env = process.env) {
|
|
50112
50388
|
return createRemoteSkillsClient(env);
|
|
50113
50389
|
}
|
|
50114
|
-
var RemoteRouteUnsupportedError, RemoteRequestError, RemoteQuoteUnavailableError, RemoteWorkspaceMemberError, RemoteWorkspaceSelectionError, RemoteCapabilityUnavailableError, INVALID_SKILL_VERSION_RESPONSE = "Remote skill version payload did not match the expected contract.";
|
|
50390
|
+
var RemoteRouteUnsupportedError, RemoteRequestError, RemoteCreditCheckoutError, RemoteQuoteUnavailableError, RemoteWorkspaceMemberError, RemoteWorkspaceSelectionError, RemoteCapabilityUnavailableError, INVALID_SKILL_VERSION_RESPONSE = "Remote skill version payload did not match the expected contract.";
|
|
50115
50391
|
var init_remote_client = __esm(() => {
|
|
50116
50392
|
init_remote_recurring();
|
|
50117
50393
|
init_remote_invitations();
|
|
@@ -50123,6 +50399,7 @@ var init_remote_client = __esm(() => {
|
|
|
50123
50399
|
init_fleet_credentials();
|
|
50124
50400
|
init_remote_account();
|
|
50125
50401
|
init_remote_files();
|
|
50402
|
+
init_remote_credit_checkout();
|
|
50126
50403
|
init_remote_quote_errors();
|
|
50127
50404
|
init_remote_permissions();
|
|
50128
50405
|
RemoteRouteUnsupportedError = class RemoteRouteUnsupportedError extends Error {
|
|
@@ -50147,6 +50424,19 @@ var init_remote_client = __esm(() => {
|
|
|
50147
50424
|
this.name = "RemoteRequestError";
|
|
50148
50425
|
}
|
|
50149
50426
|
};
|
|
50427
|
+
RemoteCreditCheckoutError = class RemoteCreditCheckoutError extends RemoteRequestError {
|
|
50428
|
+
code;
|
|
50429
|
+
requestIdempotencyKey;
|
|
50430
|
+
retryAfterSeconds;
|
|
50431
|
+
constructor(code, status, requestIdempotencyKey, retryAfterSeconds) {
|
|
50432
|
+
super("/api/v1/billing/credits", status);
|
|
50433
|
+
this.code = code;
|
|
50434
|
+
this.requestIdempotencyKey = requestIdempotencyKey;
|
|
50435
|
+
this.retryAfterSeconds = retryAfterSeconds;
|
|
50436
|
+
this.name = "RemoteCreditCheckoutError";
|
|
50437
|
+
this.message = creditCheckoutMessages[code];
|
|
50438
|
+
}
|
|
50439
|
+
};
|
|
50150
50440
|
RemoteQuoteUnavailableError = class RemoteQuoteUnavailableError extends RemoteRequestError {
|
|
50151
50441
|
code;
|
|
50152
50442
|
constructor(path, code) {
|
|
@@ -50533,12 +50823,12 @@ class RemotePrivatePublicationsClient {
|
|
|
50533
50823
|
previous = view;
|
|
50534
50824
|
if (!["queued", "verifying"].includes(view.state) || Date.now() >= until)
|
|
50535
50825
|
return view;
|
|
50536
|
-
await new Promise((
|
|
50826
|
+
await new Promise((resolve5) => {
|
|
50537
50827
|
const timer = setTimeout(done, Math.min(1000, until - Date.now()));
|
|
50538
50828
|
function done() {
|
|
50539
50829
|
clearTimeout(timer);
|
|
50540
50830
|
options.signal?.removeEventListener("abort", done);
|
|
50541
|
-
|
|
50831
|
+
resolve5();
|
|
50542
50832
|
}
|
|
50543
50833
|
options.signal?.addEventListener("abort", done, { once: true });
|
|
50544
50834
|
});
|
|
@@ -51058,8 +51348,8 @@ var init_recurring_customer = __esm(() => {
|
|
|
51058
51348
|
});
|
|
51059
51349
|
|
|
51060
51350
|
// src/lib/recurring-recovery.ts
|
|
51061
|
-
import { constants as constants7, closeSync as closeSync10, fsyncSync as
|
|
51062
|
-
import { dirname as dirname7, isAbsolute as
|
|
51351
|
+
import { constants as constants7, closeSync as closeSync10, fsyncSync as fsyncSync3, fstatSync as fstatSync10, lstatSync as lstatSync10, mkdirSync as mkdirSync10, openSync as openSync10, readSync as readSync5, realpathSync as realpathSync4, renameSync as renameSync6, unlinkSync as unlinkSync5, writeFileSync as writeFileSync8 } from "fs";
|
|
51352
|
+
import { dirname as dirname7, isAbsolute as isAbsolute5, join as join20, resolve as resolve5 } from "path";
|
|
51063
51353
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
51064
51354
|
|
|
51065
51355
|
class RecoveryOwner {
|
|
@@ -51067,7 +51357,7 @@ class RecoveryOwner {
|
|
|
51067
51357
|
parents = [];
|
|
51068
51358
|
constructor(directory) {
|
|
51069
51359
|
this.directory = directory;
|
|
51070
|
-
if (!
|
|
51360
|
+
if (!isAbsolute5(directory) || resolve5(directory) !== directory || realpathSync4(directory) !== directory)
|
|
51071
51361
|
invalid5();
|
|
51072
51362
|
for (let path = directory;; path = dirname7(path)) {
|
|
51073
51363
|
const stat2 = lstatSync10(path);
|
|
@@ -51122,7 +51412,7 @@ class RecoveryOwner {
|
|
|
51122
51412
|
const fd = openSync10(join20(this.directory, name), constants7.O_WRONLY | constants7.O_CREAT | constants7.O_EXCL | constants7.O_NOFOLLOW, 384);
|
|
51123
51413
|
try {
|
|
51124
51414
|
writeFileSync8(fd, bytes);
|
|
51125
|
-
|
|
51415
|
+
fsyncSync3(fd);
|
|
51126
51416
|
} finally {
|
|
51127
51417
|
closeSync10(fd);
|
|
51128
51418
|
}
|
|
@@ -51133,7 +51423,7 @@ class RecoveryOwner {
|
|
|
51133
51423
|
this.assert();
|
|
51134
51424
|
const fd = openSync10(this.directory, constants7.O_RDONLY | constants7.O_NOFOLLOW);
|
|
51135
51425
|
try {
|
|
51136
|
-
|
|
51426
|
+
fsyncSync3(fd);
|
|
51137
51427
|
} finally {
|
|
51138
51428
|
closeSync10(fd);
|
|
51139
51429
|
}
|
|
@@ -51160,7 +51450,7 @@ class RecoveryOwner {
|
|
|
51160
51450
|
const owner = fstatSync10(fd);
|
|
51161
51451
|
try {
|
|
51162
51452
|
writeFileSync8(fd, JSON.stringify({ pid: process.pid }));
|
|
51163
|
-
|
|
51453
|
+
fsyncSync3(fd);
|
|
51164
51454
|
this.sync();
|
|
51165
51455
|
return await action();
|
|
51166
51456
|
} finally {
|
|
@@ -51202,7 +51492,7 @@ function base(customer, organizationId) {
|
|
|
51202
51492
|
};
|
|
51203
51493
|
}
|
|
51204
51494
|
function create(directory, intent) {
|
|
51205
|
-
if (!
|
|
51495
|
+
if (!isAbsolute5(directory) || resolve5(directory) !== directory || realpathSync4(dirname7(directory)) !== dirname7(directory))
|
|
51206
51496
|
invalid5();
|
|
51207
51497
|
mkdirSync10(directory, { mode: 448 });
|
|
51208
51498
|
const owner = new RecoveryOwner(directory), checked = intentSchema.parse(intent), intentSha256 = canonicalJsonSha256(checked);
|
|
@@ -51365,7 +51655,7 @@ var init_recurring_recovery = __esm(() => {
|
|
|
51365
51655
|
});
|
|
51366
51656
|
|
|
51367
51657
|
// src/lib/recurring-surface.ts
|
|
51368
|
-
import { isAbsolute as
|
|
51658
|
+
import { isAbsolute as isAbsolute6 } from "path";
|
|
51369
51659
|
function recurringMcpSchema(action) {
|
|
51370
51660
|
return action === "activate" ? recurringSurfaceSchemas.activate.extend({ code, confirm: exports_external.literal(true) }) : recurringSurfaceSchemas[action];
|
|
51371
51661
|
}
|
|
@@ -51470,7 +51760,7 @@ var init_recurring_surface = __esm(() => {
|
|
|
51470
51760
|
uuid13 = exports_external.string().regex(/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/);
|
|
51471
51761
|
context = { userId: uuid13.optional(), membershipId: uuid13.optional() };
|
|
51472
51762
|
page2 = { limit: exports_external.number().int().min(1).max(100).optional(), cursor: exports_external.string().min(1).max(2048).optional() };
|
|
51473
|
-
directory = exports_external.string().max(4096).refine(
|
|
51763
|
+
directory = exports_external.string().max(4096).refine(isAbsolute6, "Use an absolute recovery directory");
|
|
51474
51764
|
email4 = exports_external.string().trim().toLowerCase().email().max(254);
|
|
51475
51765
|
code = exports_external.string().regex(/^\d{6}$/);
|
|
51476
51766
|
recurringSurfaceSchemas = {
|
|
@@ -52439,11 +52729,11 @@ var init_mcp_contracts = __esm(() => {
|
|
|
52439
52729
|
name: operation.name,
|
|
52440
52730
|
title: operation.title,
|
|
52441
52731
|
description: `${operation.title} on the configured server; unavailable capabilities fail explicitly.`,
|
|
52442
|
-
params: operation.parameter ? [operation.parameter] : [],
|
|
52732
|
+
params: operation.parameter ? [operation.parameter, ...operation.name === "create_credit_checkout" ? ["idempotency_key?"] : []] : [],
|
|
52443
52733
|
category: "execution",
|
|
52444
52734
|
sideEffects: operation.mutates ? "local-process-or-remote-run" : "none",
|
|
52445
52735
|
stable: true,
|
|
52446
|
-
inputSchema: objectSchema(operation.parameter ? { [operation.parameter]: stringSchema("Server resource identifier.") } : {}, operation.parameter ? [operation.parameter] : []),
|
|
52736
|
+
inputSchema: objectSchema(operation.parameter ? { [operation.parameter]: stringSchema("Server resource identifier."), ...operation.name === "create_credit_checkout" ? { idempotency_key: { type: "string", pattern: "^[A-Za-z0-9._:-]{8,255}$", description: "Caller-owned key retained before submission; reuse only for explicit recovery of the same server/account/pack." } } : {} } : {}, operation.parameter ? [operation.parameter] : []),
|
|
52447
52737
|
outputSchema: { oneOf: [objectSchema({}, [], "Server response.", true), { type: "array", items: objectSchema({}, [], "Server record.", true) }] }
|
|
52448
52738
|
}));
|
|
52449
52739
|
remoteCustomerContracts.push({
|
|
@@ -53535,7 +53825,7 @@ import { closeSync as closeSync11, fstatSync as fstatSync11, openSync as openSyn
|
|
|
53535
53825
|
import { O_NOFOLLOW as O_NOFOLLOW3, O_NONBLOCK as O_NONBLOCK3, O_RDONLY as O_RDONLY3 } from "constants";
|
|
53536
53826
|
import { createRequire as createRequire2 } from "module";
|
|
53537
53827
|
import { hostname as osHostname2 } from "os";
|
|
53538
|
-
import { isAbsolute as
|
|
53828
|
+
import { isAbsolute as isAbsolute7, join as join22 } from "path";
|
|
53539
53829
|
import { createRequire as createRequire22 } from "module";
|
|
53540
53830
|
function envToken2(name) {
|
|
53541
53831
|
return name.toUpperCase().replace(/-/g, "_");
|
|
@@ -53559,7 +53849,7 @@ function homeDir2(env) {
|
|
|
53559
53849
|
}
|
|
53560
53850
|
function absoluteOverride2(env, key) {
|
|
53561
53851
|
const value = env[key]?.trim();
|
|
53562
|
-
return value &&
|
|
53852
|
+
return value && isAbsolute7(value) ? value : null;
|
|
53563
53853
|
}
|
|
53564
53854
|
function hasnaHomeDir2(env) {
|
|
53565
53855
|
const override = absoluteOverride2(env, HASNA_HOME_ENV_KEY2);
|
|
@@ -54696,7 +54986,7 @@ function createSecretsClientFromEnv(env = process.env, overrides = {}) {
|
|
|
54696
54986
|
});
|
|
54697
54987
|
return new SecretsClient({ ...clientOverrides, baseUrl, apiKey });
|
|
54698
54988
|
}
|
|
54699
|
-
var __esm2 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), CREDENTIAL_PROFILE_ENV_KEY2 = "HASNA_PROFILE", CredentialResolutionError2, CredentialFileUnsafeError2, HASNA_HOME_ENV_KEY2 = "HASNA_HOME", HASNA_CONFIG_HOME_ENV_KEY2 = "HASNA_CONFIG_HOME", KEYCHAIN_STATION_ENV_KEY2 = "HASNA_STATION", HASNA_HOME_DIR2 = ".hasna", CONFIG_SUBDIR2 = "config", CREDENTIALS_FILE2 = "credentials", KEYCHAIN_SECURITY_BIN2 = "/usr/bin/security", KEYCHAIN_SERVICE_PREFIX2 = "hasna.credentials", KEYCHAIN_ITEM_NOT_FOUND_STATUS2 = 44, KEYCHAIN_SPAWN_TIMEOUT_MS2 = 1e4, MAX_CREDENTIAL_FILE_BYTES2, SAFE_APP_SLUG2, SAFE_PROFILE2, ILLEGAL_IN_HEADER_VALUE2, VAULT_POINTER_SHAPE2, CREDENTIAL_SHAPED_KEY2, INSPECT_CUSTOM2, CREDENTIAL_SEAL2, CALLER_SUPPLIED_CREDENTIAL_PROVIDER_SOURCE = "caller-supplied CredentialProvider", AMBIENT_ENVIRONMENT2, SECRETS_PACKAGE_SPECIFIER, requireSecretsSdk2, DEFAULT_FLEET_GATEWAY_ORIGIN2 = "https://api.hasna.com", DEFAULT_AUTHORITY_SOURCE = "default", ASCII_CONTROL_PATTERN2, DNS_LABEL_PATTERN2, ClientTransportConfigurationError2, HasnaHttpError, DEFAULT_RETRY_STATUSES, IDEMPOTENT_METHODS2, AUTHORITY_OVERRIDE_HEADERS2, defaultSleep = (ms) => new Promise((
|
|
54989
|
+
var __esm2 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), CREDENTIAL_PROFILE_ENV_KEY2 = "HASNA_PROFILE", CredentialResolutionError2, CredentialFileUnsafeError2, HASNA_HOME_ENV_KEY2 = "HASNA_HOME", HASNA_CONFIG_HOME_ENV_KEY2 = "HASNA_CONFIG_HOME", KEYCHAIN_STATION_ENV_KEY2 = "HASNA_STATION", HASNA_HOME_DIR2 = ".hasna", CONFIG_SUBDIR2 = "config", CREDENTIALS_FILE2 = "credentials", KEYCHAIN_SECURITY_BIN2 = "/usr/bin/security", KEYCHAIN_SERVICE_PREFIX2 = "hasna.credentials", KEYCHAIN_ITEM_NOT_FOUND_STATUS2 = 44, KEYCHAIN_SPAWN_TIMEOUT_MS2 = 1e4, MAX_CREDENTIAL_FILE_BYTES2, SAFE_APP_SLUG2, SAFE_PROFILE2, ILLEGAL_IN_HEADER_VALUE2, VAULT_POINTER_SHAPE2, CREDENTIAL_SHAPED_KEY2, INSPECT_CUSTOM2, CREDENTIAL_SEAL2, CALLER_SUPPLIED_CREDENTIAL_PROVIDER_SOURCE = "caller-supplied CredentialProvider", AMBIENT_ENVIRONMENT2, SECRETS_PACKAGE_SPECIFIER, requireSecretsSdk2, DEFAULT_FLEET_GATEWAY_ORIGIN2 = "https://api.hasna.com", DEFAULT_AUTHORITY_SOURCE = "default", ASCII_CONTROL_PATTERN2, DNS_LABEL_PATTERN2, ClientTransportConfigurationError2, HasnaHttpError, DEFAULT_RETRY_STATUSES, IDEMPOTENT_METHODS2, AUTHORITY_OVERRIDE_HEADERS2, defaultSleep = (ms) => new Promise((resolve6) => setTimeout(resolve6, ms)), init_transport2, MAX_CREDENTIAL_FILE_BYTES22, INSPECT_CUSTOM22, CREDENTIAL_SEAL22, AMBIENT_ENVIRONMENT22, SECRETS_PACKAGE_SPECIFIER2, requireSecretsSdk22, IDEMPOTENT_METHODS22, AUTHORITY_OVERRIDE_HEADERS22, init_storage, PATHS_RESOLVER_APP_SLUG_RE2, SQLITE_SIDECAR_FILES, LEGACY_SERVICE_FILES, init_data_dir, SecretsTestIsolationError, TEST_ENTRYPOINT_RE, init_test_isolation, init_client, ApiError;
|
|
54700
54990
|
var init_sdk = __esm(() => {
|
|
54701
54991
|
init_transport2 = __esm2(() => {
|
|
54702
54992
|
CredentialResolutionError2 = class CredentialResolutionError3 extends Error {
|
|
@@ -55011,7 +55301,7 @@ var init_execution_grants = __esm(() => {
|
|
|
55011
55301
|
});
|
|
55012
55302
|
|
|
55013
55303
|
// src/lib/execution-grant-client.ts
|
|
55014
|
-
import { isDeepStrictEqual } from "util";
|
|
55304
|
+
import { isDeepStrictEqual as isDeepStrictEqual2 } from "util";
|
|
55015
55305
|
function id(value) {
|
|
55016
55306
|
if (!grantIdentifier(value))
|
|
55017
55307
|
throw new Error("Invalid execution grant profile or revision identifier.");
|
|
@@ -55054,7 +55344,7 @@ async function resolveExecutionGrant(input2) {
|
|
|
55054
55344
|
if (!grantRecord(value) || Object.keys(value).length !== 3 || !grantIdentifier(value.policyRevision) || !grantIdentifier(value.grantId) || !grantRecord(value.bindings)) {
|
|
55055
55345
|
throw new SkillSelectionError("INVALID_EXECUTION_GRANT", "The Skills API returned an invalid execution grant.");
|
|
55056
55346
|
}
|
|
55057
|
-
if (!
|
|
55347
|
+
if (!isDeepStrictEqual2(value.bindings.selection, snapshot.selection) || !isDeepStrictEqual2(value.bindings.consumer, snapshot.consumer)) {
|
|
55058
55348
|
throw new SkillSelectionError("EXECUTION_GRANT_SCOPE_MISMATCH", "The Skills API returned a grant for a different selection or consumer.");
|
|
55059
55349
|
}
|
|
55060
55350
|
return value;
|
|
@@ -55076,7 +55366,7 @@ __export(exports_selected_run, {
|
|
|
55076
55366
|
import { createHash as createHash9 } from "crypto";
|
|
55077
55367
|
import { spawn } from "child_process";
|
|
55078
55368
|
import { mkdirSync as mkdirSync12, mkdtempSync as mkdtempSync3, writeFileSync as writeFileSync10, realpathSync as realpathSync6 } from "fs";
|
|
55079
|
-
import { dirname as dirname8, join as join23, resolve as
|
|
55369
|
+
import { dirname as dirname8, join as join23, resolve as resolve6 } from "path";
|
|
55080
55370
|
import { tmpdir, hostname as stationHostname2 } from "os";
|
|
55081
55371
|
async function resolveSelectedRun(spec, profileId, options = {}) {
|
|
55082
55372
|
const context2 = await resolveSelectionContext(profileId, options);
|
|
@@ -55169,7 +55459,7 @@ async function executeSelectedLocal(selected, options = {}) {
|
|
|
55169
55459
|
writeFileSync10(destination, entry.bytes, { flag: "wx", mode: entry.mode & 511 });
|
|
55170
55460
|
}
|
|
55171
55461
|
env.SKILLS_INPUT_JSON = input2;
|
|
55172
|
-
env.SKILLS_WORKSPACE_DIR =
|
|
55462
|
+
env.SKILLS_WORKSPACE_DIR = resolve6(options.cwd ?? process.cwd());
|
|
55173
55463
|
env.SKILLS_RUN_DIR = runDirectory;
|
|
55174
55464
|
if (runtime.version) {
|
|
55175
55465
|
const version2 = await subprocess([executable, ...runtimeName === "bun" ? ["--no-env-file"] : [], "--version"], runDirectory, env, "", Math.min(timeoutMs, 5000));
|
|
@@ -56930,11 +57220,11 @@ var init_private_publication_customer = __esm(() => {
|
|
|
56930
57220
|
});
|
|
56931
57221
|
|
|
56932
57222
|
// src/lib/private-publication-recovery.ts
|
|
56933
|
-
import { constants as constants9, closeSync as closeSync13, fsyncSync as
|
|
56934
|
-
import { dirname as dirname11, isAbsolute as
|
|
57223
|
+
import { constants as constants9, closeSync as closeSync13, fsyncSync as fsyncSync4, fstatSync as fstatSync13, lstatSync as lstatSync11, mkdirSync as mkdirSync16, openSync as openSync13, readSync as readSync7, realpathSync as realpathSync7, renameSync as renameSync7, unlinkSync as unlinkSync6, writeFileSync as writeFileSync13 } from "fs";
|
|
57224
|
+
import { dirname as dirname11, isAbsolute as isAbsolute8, join as join28, resolve as resolve7 } from "path";
|
|
56935
57225
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
56936
57226
|
function safeDirectory(directory2) {
|
|
56937
|
-
if (!
|
|
57227
|
+
if (!isAbsolute8(directory2) || directory2 !== resolve7(directory2) || realpathSync7(directory2) !== directory2)
|
|
56938
57228
|
return fail2();
|
|
56939
57229
|
for (let path = directory2;; path = dirname11(path)) {
|
|
56940
57230
|
const stat2 = lstatSync11(path);
|
|
@@ -56981,7 +57271,7 @@ function writeOwned(directory2, name, bytes) {
|
|
|
56981
57271
|
const fd = openSync13(join28(directory2, name), constants9.O_WRONLY | constants9.O_CREAT | constants9.O_EXCL | constants9.O_NOFOLLOW, 384);
|
|
56982
57272
|
try {
|
|
56983
57273
|
writeFileSync13(fd, bytes);
|
|
56984
|
-
|
|
57274
|
+
fsyncSync4(fd);
|
|
56985
57275
|
} finally {
|
|
56986
57276
|
closeSync13(fd);
|
|
56987
57277
|
}
|
|
@@ -56994,7 +57284,7 @@ function save(directory2, value) {
|
|
|
56994
57284
|
renameSync7(join28(directory2, temporary), join28(directory2, "receipt.json"));
|
|
56995
57285
|
const fd = openSync13(directory2, constants9.O_RDONLY | constants9.O_NOFOLLOW);
|
|
56996
57286
|
try {
|
|
56997
|
-
|
|
57287
|
+
fsyncSync4(fd);
|
|
56998
57288
|
} finally {
|
|
56999
57289
|
closeSync13(fd);
|
|
57000
57290
|
}
|
|
@@ -57015,7 +57305,7 @@ async function locked(directory2, action) {
|
|
|
57015
57305
|
try {
|
|
57016
57306
|
writeFileSync13(fd, JSON.stringify({ pid: process.pid }) + `
|
|
57017
57307
|
`);
|
|
57018
|
-
|
|
57308
|
+
fsyncSync4(fd);
|
|
57019
57309
|
return await action();
|
|
57020
57310
|
} finally {
|
|
57021
57311
|
closeSync13(fd);
|
|
@@ -57072,13 +57362,13 @@ async function preparePrivatePublication(client, sourceDirectory, recoveryDirect
|
|
|
57072
57362
|
phase: "prepared",
|
|
57073
57363
|
intent: null
|
|
57074
57364
|
};
|
|
57075
|
-
if (!
|
|
57365
|
+
if (!isAbsolute8(recoveryDirectory) || resolve7(recoveryDirectory) !== recoveryDirectory || realpathSync7(dirname11(recoveryDirectory)) !== dirname11(recoveryDirectory))
|
|
57076
57366
|
return fail2();
|
|
57077
57367
|
mkdirSync16(recoveryDirectory, { mode: 448 });
|
|
57078
57368
|
safeDirectory(recoveryDirectory);
|
|
57079
57369
|
const parent = openSync13(dirname11(recoveryDirectory), constants9.O_RDONLY | constants9.O_NOFOLLOW);
|
|
57080
57370
|
try {
|
|
57081
|
-
|
|
57371
|
+
fsyncSync4(parent);
|
|
57082
57372
|
} finally {
|
|
57083
57373
|
closeSync13(parent);
|
|
57084
57374
|
}
|
|
@@ -57173,10 +57463,10 @@ var init_private_publication_recovery = __esm(() => {
|
|
|
57173
57463
|
});
|
|
57174
57464
|
|
|
57175
57465
|
// src/mcp/private-publication-tools.ts
|
|
57176
|
-
import { isAbsolute as
|
|
57466
|
+
import { isAbsolute as isAbsolute9 } from "path";
|
|
57177
57467
|
function registerPrivatePublicationTools(server) {
|
|
57178
57468
|
const uuid9 = exports_external.string().regex(/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/);
|
|
57179
|
-
const directory2 = exports_external.string().max(4096).refine(
|
|
57469
|
+
const directory2 = exports_external.string().max(4096).refine(isAbsolute9, "Use an absolute local directory");
|
|
57180
57470
|
const verification2 = { email: exports_external.string().email().max(254), code: exports_external.string().regex(/^\d{6}$/), userId: uuid9, membershipId: uuid9, recoveryDirectory: directory2 };
|
|
57181
57471
|
const description = "Manage a private source publication using fresh workspace-bound verification and a host-local recovery directory. Publishing requires explicit UUID current-version comparison and upload consent. Resume reuses immutable saved bytes and intent; an uncertain PUT is finalized for server verification, never uploaded twice. Sessions and signed URLs are not returned or persisted. Private execution is unavailable. Host request history may contain the supplied verification code.";
|
|
57182
57472
|
const handler = (action) => async (value) => {
|
|
@@ -57331,6 +57621,14 @@ function registerRemoteCustomerTools(server) {
|
|
|
57331
57621
|
});
|
|
57332
57622
|
}
|
|
57333
57623
|
for (const operation of REMOTE_CUSTOMER_OPERATIONS) {
|
|
57624
|
+
if (operation.name === "create_credit_checkout") {
|
|
57625
|
+
server.registerTool(operation.name, {
|
|
57626
|
+
title: operation.title,
|
|
57627
|
+
description: "Create one external checkout link on the selected Skills server. Retain an idempotency_key before calling and reuse it only for explicit recovery on the same server, account and pack. No automatic retries; payment requires customer confirmation.",
|
|
57628
|
+
inputSchema: { pack_id: exports_external.string().min(1), idempotency_key: exports_external.string().regex(/^[A-Za-z0-9._:-]{8,255}$/).optional() }
|
|
57629
|
+
}, ({ pack_id, idempotency_key }) => callRemote((client) => operation.invoke(client, pack_id, { idempotencyKey: idempotency_key })));
|
|
57630
|
+
continue;
|
|
57631
|
+
}
|
|
57334
57632
|
const inputSchema = {};
|
|
57335
57633
|
if (operation.parameter)
|
|
57336
57634
|
inputSchema[operation.parameter] = exports_external.string().min(1);
|
|
@@ -57407,6 +57705,15 @@ async function callRemote(action) {
|
|
|
57407
57705
|
return mcpError("AUTH_REQUIRED", "Configure a Skills API and sign in with skills auth login");
|
|
57408
57706
|
return mcpJson(await action(client));
|
|
57409
57707
|
} catch (error61) {
|
|
57708
|
+
if (error61 instanceof RemoteCreditCheckoutError) {
|
|
57709
|
+
return { ...mcpJson({
|
|
57710
|
+
code: error61.code,
|
|
57711
|
+
message: error61.message,
|
|
57712
|
+
status: error61.status,
|
|
57713
|
+
requestIdempotencyKey: error61.requestIdempotencyKey,
|
|
57714
|
+
...error61.retryAfterSeconds === undefined ? {} : { retryAfterSeconds: error61.retryAfterSeconds }
|
|
57715
|
+
}), isError: true };
|
|
57716
|
+
}
|
|
57410
57717
|
if (error61 instanceof RemoteCapabilityUnavailableError) {
|
|
57411
57718
|
return { ...mcpJson({ code: error61.code, message: error61.message, status: error61.status }), isError: true };
|
|
57412
57719
|
}
|
|
@@ -57871,7 +58178,7 @@ var RequestError, nonJoinedHeaders, validHeaderName, isHttpWhitespace = (code2)
|
|
|
57871
58178
|
request2[bodyBufferKey] = buffered;
|
|
57872
58179
|
return Promise.resolve(buffered);
|
|
57873
58180
|
}
|
|
57874
|
-
const promise3 = new Promise((
|
|
58181
|
+
const promise3 = new Promise((resolve8, reject) => {
|
|
57875
58182
|
const chunks = [];
|
|
57876
58183
|
let settled = false;
|
|
57877
58184
|
const finish = (callback) => {
|
|
@@ -57893,7 +58200,7 @@ var RequestError, nonJoinedHeaders, validHeaderName, isHttpWhitespace = (code2)
|
|
|
57893
58200
|
reject(error61 ?? normalizeAbortError(request2, incoming));
|
|
57894
58201
|
else {
|
|
57895
58202
|
request2[bodyBufferKey] = recovered;
|
|
57896
|
-
|
|
58203
|
+
resolve8(recovered);
|
|
57897
58204
|
}
|
|
57898
58205
|
});
|
|
57899
58206
|
return true;
|
|
@@ -57905,7 +58212,7 @@ var RequestError, nonJoinedHeaders, validHeaderName, isHttpWhitespace = (code2)
|
|
|
57905
58212
|
finish(() => {
|
|
57906
58213
|
const buffer = chunks.length === 1 ? chunks[0] : Buffer.concat(chunks);
|
|
57907
58214
|
request2[bodyBufferKey] = buffer;
|
|
57908
|
-
|
|
58215
|
+
resolve8(buffer);
|
|
57909
58216
|
});
|
|
57910
58217
|
};
|
|
57911
58218
|
const onError = (error61) => {
|
|
@@ -58179,7 +58486,7 @@ var RequestError, nonJoinedHeaders, validHeaderName, isHttpWhitespace = (code2)
|
|
|
58179
58486
|
});
|
|
58180
58487
|
if (!chunk) {
|
|
58181
58488
|
if (i === 1) {
|
|
58182
|
-
await new Promise((
|
|
58489
|
+
await new Promise((resolve8) => setTimeout(resolve8));
|
|
58183
58490
|
maxReadCount = 3;
|
|
58184
58491
|
continue;
|
|
58185
58492
|
}
|
|
@@ -59409,9 +59716,9 @@ data:
|
|
|
59409
59716
|
const initRequest = messages.find((m) => isInitializeRequest(m));
|
|
59410
59717
|
const clientProtocolVersion = initRequest ? initRequest.params.protocolVersion : req.headers.get("mcp-protocol-version") ?? DEFAULT_NEGOTIATED_PROTOCOL_VERSION;
|
|
59411
59718
|
if (this._enableJsonResponse) {
|
|
59412
|
-
return new Promise((
|
|
59719
|
+
return new Promise((resolve8) => {
|
|
59413
59720
|
this._streamMapping.set(streamId, {
|
|
59414
|
-
resolveJson:
|
|
59721
|
+
resolveJson: resolve8,
|
|
59415
59722
|
cleanup: () => {
|
|
59416
59723
|
this._streamMapping.delete(streamId);
|
|
59417
59724
|
}
|
|
@@ -59780,19 +60087,19 @@ async function connectMcpForNode() {
|
|
|
59780
60087
|
return { server: server2, transport };
|
|
59781
60088
|
}
|
|
59782
60089
|
function readBody(req) {
|
|
59783
|
-
return new Promise((
|
|
60090
|
+
return new Promise((resolve8, reject) => {
|
|
59784
60091
|
const chunks = [];
|
|
59785
60092
|
req.on("data", (chunk) => chunks.push(Buffer.from(chunk)));
|
|
59786
60093
|
req.on("end", () => {
|
|
59787
60094
|
const raw = Buffer.concat(chunks).toString("utf-8");
|
|
59788
60095
|
if (!raw.trim()) {
|
|
59789
|
-
|
|
60096
|
+
resolve8(undefined);
|
|
59790
60097
|
return;
|
|
59791
60098
|
}
|
|
59792
60099
|
try {
|
|
59793
|
-
|
|
60100
|
+
resolve8(JSON.parse(raw));
|
|
59794
60101
|
} catch {
|
|
59795
|
-
|
|
60102
|
+
resolve8(undefined);
|
|
59796
60103
|
}
|
|
59797
60104
|
});
|
|
59798
60105
|
req.on("error", reject);
|
|
@@ -59834,9 +60141,9 @@ async function startSkillsMcpHttpServer(options = {}) {
|
|
|
59834
60141
|
}
|
|
59835
60142
|
}
|
|
59836
60143
|
});
|
|
59837
|
-
await new Promise((
|
|
60144
|
+
await new Promise((resolve8, reject) => {
|
|
59838
60145
|
httpServer.once("error", reject);
|
|
59839
|
-
httpServer.listen(port, hostname3, () =>
|
|
60146
|
+
httpServer.listen(port, hostname3, () => resolve8());
|
|
59840
60147
|
});
|
|
59841
60148
|
const address = httpServer.address();
|
|
59842
60149
|
const listenPort = typeof address === "object" && address ? address.port : port;
|