@caplets/core 0.26.0 → 0.26.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.d.ts +5 -0
- package/dist/{completion-DaYL-XQN.js → completion-CFOJucl5.js} +2 -2
- package/dist/config-runtime.js +1 -1
- package/dist/daemon/host-path.d.ts +8 -0
- package/dist/errors.d.ts +1 -1
- package/dist/index.js +820 -172
- package/dist/native.js +1 -1
- package/dist/project-binding/errors.d.ts +1 -1
- package/dist/remote/profile-store.d.ts +2 -0
- package/dist/remote/profiles.d.ts +2 -0
- package/dist/remote/server-credential-store.d.ts +100 -1
- package/dist/remote/server-credentials.d.ts +18 -0
- package/dist/serve/http.d.ts +5 -0
- package/dist/{service-rvZ7z6FI.js → service-aBIn4nrw.js} +56 -12
- package/dist/{validation-C4tYXw6G.js → validation-GD2x5HW1.js} +1 -0
- package/package.json +1 -1
package/dist/native.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as nativeCapletPromptGuidance, F as nativeCodeModeToolName, M as nativeCapletToolName, N as nativeCapletsSystemGuidance, P as nativeCodeModeToolId, h as createSdkRemoteCapletsClient, j as nativeCapletToolDescription, m as RemoteNativeCapletsService, t as createNativeCapletsService, v as resolveNativeCapletsServiceOptions } from "./service-
|
|
1
|
+
import { A as nativeCapletPromptGuidance, F as nativeCodeModeToolName, M as nativeCapletToolName, N as nativeCapletsSystemGuidance, P as nativeCodeModeToolId, h as createSdkRemoteCapletsClient, j as nativeCapletToolDescription, m as RemoteNativeCapletsService, t as createNativeCapletsService, v as resolveNativeCapletsServiceOptions } from "./service-aBIn4nrw.js";
|
|
2
2
|
import { generatedToolInputJsonSchema, generatedToolInputSchema } from "./generated-tool-input-schema.js";
|
|
3
3
|
//#region src/native/process-cleanup.ts
|
|
4
4
|
function registerNativeCapletsProcessCleanup(service, options = {}) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CapletsError } from "../errors";
|
|
2
|
-
export declare const PROJECT_BINDING_ERROR_CODES: readonly ["cloud_auth_required", "cloud_auth_expired", "cloud_auth_revoked", "workspace_selection_required", "workspace_switch_required", "workspace_forbidden", "project_binding_forbidden", "endpoint_unavailable", "websocket_upgrade_required", "sync_required", "sync_failed", "sync_size_limit_exceeded", "lease_conflict", "lease_expired", "policy_denied", "usage_limit_reached", "billing_required", "subscription_past_due", "email_verification_required", "remote_credentials_required", "remote_auth_failed"];
|
|
2
|
+
export declare const PROJECT_BINDING_ERROR_CODES: readonly ["cloud_auth_required", "cloud_auth_expired", "cloud_auth_revoked", "workspace_selection_required", "workspace_switch_required", "workspace_forbidden", "project_binding_forbidden", "endpoint_unavailable", "websocket_upgrade_required", "sync_required", "sync_failed", "sync_size_limit_exceeded", "lease_conflict", "lease_expired", "policy_denied", "usage_limit_reached", "billing_required", "subscription_past_due", "email_verification_required", "remote_credentials_required", "remote_credentials_revoked", "remote_auth_failed"];
|
|
3
3
|
export type ProjectBindingErrorCode = (typeof PROJECT_BINDING_ERROR_CODES)[number];
|
|
4
4
|
export type ProjectBindingRecovery = {
|
|
5
5
|
code: ProjectBindingErrorCode;
|
|
@@ -16,6 +16,7 @@ export type CloudProfileLookup = {
|
|
|
16
16
|
};
|
|
17
17
|
export type SaveSelfHostedProfileInput = {
|
|
18
18
|
hostUrl: string;
|
|
19
|
+
hostIdentity?: string | undefined;
|
|
19
20
|
clientId: string;
|
|
20
21
|
clientLabel?: string | undefined;
|
|
21
22
|
credentials: RemoteProfileCredential;
|
|
@@ -23,6 +24,7 @@ export type SaveSelfHostedProfileInput = {
|
|
|
23
24
|
};
|
|
24
25
|
export type SelfHostedProfileLookup = {
|
|
25
26
|
hostUrl: string;
|
|
27
|
+
hostIdentity?: string | undefined;
|
|
26
28
|
};
|
|
27
29
|
export type RefreshSelfHostedProfileInput = SelfHostedProfileLookup & {
|
|
28
30
|
needsRefresh: (credential: RemoteProfileCredential) => boolean;
|
|
@@ -16,6 +16,7 @@ export type RemoteProfileCredential = {
|
|
|
16
16
|
export type RemoteProfileStatusInput = {
|
|
17
17
|
kind: RemoteProfileKind;
|
|
18
18
|
hostUrl: string;
|
|
19
|
+
hostIdentity?: string | undefined;
|
|
19
20
|
key?: string | undefined;
|
|
20
21
|
workspaceId?: string | undefined;
|
|
21
22
|
workspaceSlug?: string | undefined;
|
|
@@ -31,6 +32,7 @@ export type RemoteProfileStatus = {
|
|
|
31
32
|
kind: RemoteProfileKind;
|
|
32
33
|
key: string;
|
|
33
34
|
hostUrl: string;
|
|
35
|
+
hostIdentity?: string | undefined;
|
|
34
36
|
workspaceId?: string | undefined;
|
|
35
37
|
workspaceSlug?: string | undefined;
|
|
36
38
|
clientId?: string | undefined;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { type VaultEncryptedRecord } from "../vault/crypto";
|
|
2
|
+
import type { IssuedRemoteClientCredentials, RemoteClientStatus, RemotePendingLoginStatus, RemotePendingLoginState, ValidatedRemoteClient } from "./server-credentials";
|
|
2
3
|
export type RemoteServerCredentialStoreOptions = {
|
|
3
4
|
dir: string;
|
|
4
5
|
};
|
|
@@ -25,6 +26,29 @@ export type RefreshClientCredentialsInput = {
|
|
|
25
26
|
refreshToken: string;
|
|
26
27
|
now?: Date | undefined;
|
|
27
28
|
};
|
|
29
|
+
export type CreatePendingLoginInput = {
|
|
30
|
+
hostUrl: string;
|
|
31
|
+
hostIdentity?: string | undefined;
|
|
32
|
+
clientLabel?: string | undefined;
|
|
33
|
+
clientFingerprint?: string | undefined;
|
|
34
|
+
sourceHint?: string | undefined;
|
|
35
|
+
now?: Date | undefined;
|
|
36
|
+
};
|
|
37
|
+
export type PendingLoginPossessionInput = {
|
|
38
|
+
flowId: string;
|
|
39
|
+
pendingCompletionSecret: string;
|
|
40
|
+
now?: Date | undefined;
|
|
41
|
+
};
|
|
42
|
+
export type RefreshPendingLoginInput = PendingLoginPossessionInput & {
|
|
43
|
+
pendingRefreshSecret: string;
|
|
44
|
+
};
|
|
45
|
+
export type ApprovePendingLoginInput = {
|
|
46
|
+
operatorCode: string;
|
|
47
|
+
now?: Date | undefined;
|
|
48
|
+
};
|
|
49
|
+
export type CompletePendingLoginInput = PendingLoginPossessionInput & {
|
|
50
|
+
hostUrl: string;
|
|
51
|
+
};
|
|
28
52
|
type StoredPairingCode = {
|
|
29
53
|
codeId: string;
|
|
30
54
|
hostUrl: string;
|
|
@@ -49,18 +73,91 @@ type StoredRemoteClient = {
|
|
|
49
73
|
lastUsedAt?: string | undefined;
|
|
50
74
|
revokedAt?: string | undefined;
|
|
51
75
|
};
|
|
76
|
+
type PendingLoginStatus = RemotePendingLoginState;
|
|
77
|
+
type StoredPendingLogin = {
|
|
78
|
+
flowId: string;
|
|
79
|
+
hostUrl: string;
|
|
80
|
+
hostIdentity?: string | undefined;
|
|
81
|
+
operatorCodeHash: string;
|
|
82
|
+
pendingRefreshHash: string;
|
|
83
|
+
supersededPendingRefreshHashes: SupersededRefreshToken[];
|
|
84
|
+
pendingRefreshReplay?: PendingRefreshReplay | undefined;
|
|
85
|
+
pendingCompletionHash: string;
|
|
86
|
+
completionReplay?: CompletionReplay | undefined;
|
|
87
|
+
clientLabel: string;
|
|
88
|
+
clientFingerprint?: string | undefined;
|
|
89
|
+
sourceHint?: string | undefined;
|
|
90
|
+
createdAt: string;
|
|
91
|
+
codeExpiresAt: string;
|
|
92
|
+
flowExpiresAt: string;
|
|
93
|
+
status: PendingLoginStatus;
|
|
94
|
+
operatorCodeFingerprint?: string | undefined;
|
|
95
|
+
approvedAt?: string | undefined;
|
|
96
|
+
deniedAt?: string | undefined;
|
|
97
|
+
cancelledAt?: string | undefined;
|
|
98
|
+
exchangedAt?: string | undefined;
|
|
99
|
+
};
|
|
52
100
|
type SupersededRefreshToken = {
|
|
53
101
|
hash: string;
|
|
54
102
|
supersededAt: string;
|
|
55
103
|
};
|
|
104
|
+
type PendingRefreshReplay = {
|
|
105
|
+
refreshHash: string;
|
|
106
|
+
expiresAt: string;
|
|
107
|
+
encryptedResponse: VaultEncryptedRecord;
|
|
108
|
+
};
|
|
109
|
+
type CompletionReplay = {
|
|
110
|
+
expiresAt: string;
|
|
111
|
+
encryptedCredentials: VaultEncryptedRecord;
|
|
112
|
+
};
|
|
56
113
|
type RemoteServerCredentialState = {
|
|
57
114
|
version: 1;
|
|
58
115
|
pairingCodes: StoredPairingCode[];
|
|
116
|
+
pendingLogins: StoredPendingLogin[];
|
|
59
117
|
clients: StoredRemoteClient[];
|
|
60
118
|
};
|
|
61
119
|
export declare class RemoteServerCredentialStore {
|
|
62
120
|
readonly dir: string;
|
|
63
121
|
constructor(options: RemoteServerCredentialStoreOptions);
|
|
122
|
+
createPendingLogin(input: CreatePendingLoginInput): {
|
|
123
|
+
flowId: string;
|
|
124
|
+
operatorCode: string;
|
|
125
|
+
operatorCodeFingerprint: string;
|
|
126
|
+
pendingRefreshSecret: string;
|
|
127
|
+
pendingCompletionSecret: string;
|
|
128
|
+
codeExpiresAt: string;
|
|
129
|
+
flowExpiresAt: string;
|
|
130
|
+
intervalSeconds: number;
|
|
131
|
+
};
|
|
132
|
+
pollPendingLogin(input: PendingLoginPossessionInput): {
|
|
133
|
+
flowId: string;
|
|
134
|
+
status: PendingLoginStatus;
|
|
135
|
+
};
|
|
136
|
+
refreshPendingLogin(input: RefreshPendingLoginInput): {
|
|
137
|
+
flowId: string;
|
|
138
|
+
operatorCode: string;
|
|
139
|
+
operatorCodeFingerprint: string;
|
|
140
|
+
pendingRefreshSecret: string;
|
|
141
|
+
codeExpiresAt: string;
|
|
142
|
+
flowExpiresAt: string;
|
|
143
|
+
intervalSeconds: number;
|
|
144
|
+
};
|
|
145
|
+
denyPendingLogin(input: ApprovePendingLoginInput): {
|
|
146
|
+
flowId: string;
|
|
147
|
+
status: "denied";
|
|
148
|
+
};
|
|
149
|
+
cancelPendingLogin(input: PendingLoginPossessionInput): {
|
|
150
|
+
flowId: string;
|
|
151
|
+
status: "cancelled";
|
|
152
|
+
};
|
|
153
|
+
approvePendingLogin(input: ApprovePendingLoginInput): {
|
|
154
|
+
flowId: string;
|
|
155
|
+
status: "approved";
|
|
156
|
+
clientLabel: string;
|
|
157
|
+
clientFingerprint?: string | undefined;
|
|
158
|
+
sourceHint?: string | undefined;
|
|
159
|
+
};
|
|
160
|
+
completePendingLogin(input: CompletePendingLoginInput): IssuedRemoteClientCredentials;
|
|
64
161
|
createPairingCode(input: CreatePairingCodeInput): {
|
|
65
162
|
codeId: string;
|
|
66
163
|
code: string;
|
|
@@ -68,6 +165,7 @@ export declare class RemoteServerCredentialStore {
|
|
|
68
165
|
};
|
|
69
166
|
exchangePairingCode(input: ExchangePairingCodeInput): IssuedRemoteClientCredentials;
|
|
70
167
|
listClients(): RemoteClientStatus[];
|
|
168
|
+
listPendingLogins(now?: Date): RemotePendingLoginStatus[];
|
|
71
169
|
revokeClient(clientId: string, now?: Date): boolean;
|
|
72
170
|
validateAccessToken(input: ValidateAccessTokenInput): ValidatedRemoteClient;
|
|
73
171
|
refreshClientCredentials(input: RefreshClientCredentialsInput): IssuedRemoteClientCredentials;
|
|
@@ -80,5 +178,6 @@ export declare class RemoteServerCredentialStore {
|
|
|
80
178
|
private acquireLock;
|
|
81
179
|
private releaseLock;
|
|
82
180
|
private clearStaleLock;
|
|
181
|
+
private pendingLoginForCompletion;
|
|
83
182
|
}
|
|
84
183
|
export {};
|
|
@@ -16,6 +16,24 @@ export type RemoteClientStatus = {
|
|
|
16
16
|
lastUsedAt?: string | undefined;
|
|
17
17
|
revokedAt?: string | undefined;
|
|
18
18
|
};
|
|
19
|
+
export type RemotePendingLoginState = "pending" | "approved" | "denied" | "cancelled" | "expired" | "exchanged";
|
|
20
|
+
export type RemotePendingLoginStatus = {
|
|
21
|
+
flowId: string;
|
|
22
|
+
hostUrl: string;
|
|
23
|
+
hostIdentity?: string | undefined;
|
|
24
|
+
status: RemotePendingLoginState;
|
|
25
|
+
operatorCodeFingerprint?: string | undefined;
|
|
26
|
+
clientLabel: string;
|
|
27
|
+
clientFingerprint?: string | undefined;
|
|
28
|
+
sourceHint?: string | undefined;
|
|
29
|
+
createdAt: string;
|
|
30
|
+
codeExpiresAt: string;
|
|
31
|
+
flowExpiresAt: string;
|
|
32
|
+
approvedAt?: string | undefined;
|
|
33
|
+
deniedAt?: string | undefined;
|
|
34
|
+
cancelledAt?: string | undefined;
|
|
35
|
+
exchangedAt?: string | undefined;
|
|
36
|
+
};
|
|
19
37
|
export type ValidatedRemoteClient = RemoteClientStatus & {
|
|
20
38
|
tokenType: "Bearer";
|
|
21
39
|
};
|
package/dist/serve/http.d.ts
CHANGED
|
@@ -35,6 +35,11 @@ export declare function servicePaths(base: string): {
|
|
|
35
35
|
attachInvoke: string;
|
|
36
36
|
projectBindings: string;
|
|
37
37
|
pairingExchange: string;
|
|
38
|
+
remoteLoginStart: string;
|
|
39
|
+
remoteLoginPoll: string;
|
|
40
|
+
remoteLoginRefresh: string;
|
|
41
|
+
remoteLoginComplete: string;
|
|
42
|
+
remoteLoginCancel: string;
|
|
38
43
|
remoteRefresh: string;
|
|
39
44
|
remoteClient: string;
|
|
40
45
|
health: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { A as safeParseAsync$1, C as toJSONSchema, D as parse$3, E as $ZodType, F as NEVER, M as defineLazy, N as normalizeParams, O as parseAsync, P as $constructor, S as datetime, T as $ZodObject, _ as record, a as any, b as unknown, c as custom, d as literal, f as looseObject, g as preprocess, h as optional, i as _null, j as clone, k as safeParse$1, l as discriminatedUnion, m as object$1, o as array, p as number$1, r as _enum, s as boolean, t as ZodNumber$1, u as intersection, v as string, w as _coercedNumber, x as url, y as union } from "./schemas-BoqMu4MG.js";
|
|
2
|
-
import { a as isAllowedHttpBaseUrl, c as validateHttpActionHeaders, d as errorResult, f as redactSecrets, i as SERVER_ID_PATTERN, n as HEADER_NAME_PATTERN, o as isAllowedRemoteUrl, p as toSafeError, r as HTTP_BASE_URL_PATTERN, s as isUrl, t as FORBIDDEN_HEADERS, u as CapletsError } from "./validation-
|
|
2
|
+
import { a as isAllowedHttpBaseUrl, c as validateHttpActionHeaders, d as errorResult, f as redactSecrets, i as SERVER_ID_PATTERN, n as HEADER_NAME_PATTERN, o as isAllowedRemoteUrl, p as toSafeError, r as HTTP_BASE_URL_PATTERN, s as isUrl, t as FORBIDDEN_HEADERS, u as CapletsError } from "./validation-GD2x5HW1.js";
|
|
3
3
|
import { generatedToolInputJsonSchema, generatedToolInputJsonSchemaForCaplet, generatedToolInputSchemaForCaplet, mcpOperations, operations } from "./generated-tool-input-schema.js";
|
|
4
4
|
import { f as observedOutputShapeKey, i as observeOutputShape, r as normalizedObservableValue, t as usefulOutputSchema, u as FileObservedOutputShapeStore } from "./observed-output-shapes-DuP7mJQf.js";
|
|
5
5
|
import { createRequire } from "node:module";
|
|
@@ -64028,7 +64028,7 @@ var CapletsEngine = class {
|
|
|
64028
64028
|
}
|
|
64029
64029
|
}
|
|
64030
64030
|
async completeCliWords(words) {
|
|
64031
|
-
const { completeCliWords } = await import("./completion-
|
|
64031
|
+
const { completeCliWords } = await import("./completion-CFOJucl5.js").then((n) => n.r);
|
|
64032
64032
|
return await completeCliWords(words, {
|
|
64033
64033
|
config: this.registry.config,
|
|
64034
64034
|
managers: {
|
|
@@ -81700,13 +81700,16 @@ function isAuthFailure(error) {
|
|
|
81700
81700
|
}
|
|
81701
81701
|
function isPermanentRemoteCredentialsError(error) {
|
|
81702
81702
|
const candidate = error;
|
|
81703
|
-
if (candidate?.projectBindingCode
|
|
81703
|
+
if (isPermanentRemoteCredentialsCode(candidate?.projectBindingCode)) return true;
|
|
81704
81704
|
if (isPlainObject(candidate?.details)) {
|
|
81705
81705
|
const code = candidate.details.code;
|
|
81706
|
-
if (code
|
|
81706
|
+
if (isPermanentRemoteCredentialsCode(code)) return true;
|
|
81707
81707
|
}
|
|
81708
81708
|
return isAuthFailure(error);
|
|
81709
81709
|
}
|
|
81710
|
+
function isPermanentRemoteCredentialsCode(code) {
|
|
81711
|
+
return code === "remote_credentials_required" || code === "remote_credentials_revoked" || code === "remote_auth_failed";
|
|
81712
|
+
}
|
|
81710
81713
|
//#endregion
|
|
81711
81714
|
//#region src/cloud-auth/errors.ts
|
|
81712
81715
|
const SECRET_PATTERN = /(cap_access_[a-z0-9._~+/=-]+|cap_refresh_[a-z0-9._~+/=-]+|one_time_code_[a-z0-9._~+/=-]+|Bearer\s+)[^\s"]*/giu;
|
|
@@ -81869,6 +81872,7 @@ const PROJECT_BINDING_ERROR_CODES = [
|
|
|
81869
81872
|
"subscription_past_due",
|
|
81870
81873
|
"email_verification_required",
|
|
81871
81874
|
"remote_credentials_required",
|
|
81875
|
+
"remote_credentials_revoked",
|
|
81872
81876
|
"remote_auth_failed"
|
|
81873
81877
|
];
|
|
81874
81878
|
var ProjectBindingError = class extends CapletsError {
|
|
@@ -81902,6 +81906,7 @@ function recoveryCommandFor(code) {
|
|
|
81902
81906
|
case "workspace_switch_required": return "caplets remote login <cloud-url> --workspace <workspace>";
|
|
81903
81907
|
case "sync_size_limit_exceeded": return "Add exclusions to .capletsignore or upgrade the workspace plan.";
|
|
81904
81908
|
case "remote_credentials_required":
|
|
81909
|
+
case "remote_credentials_revoked":
|
|
81905
81910
|
case "remote_auth_failed": return "caplets remote login <url>";
|
|
81906
81911
|
case "endpoint_unavailable":
|
|
81907
81912
|
case "websocket_upgrade_required": return "caplets doctor";
|
|
@@ -82079,6 +82084,7 @@ function remoteProfileStatus(input) {
|
|
|
82079
82084
|
kind: input.kind,
|
|
82080
82085
|
key,
|
|
82081
82086
|
hostUrl,
|
|
82087
|
+
...input.hostIdentity ? { hostIdentity: input.hostIdentity } : {},
|
|
82082
82088
|
...input.workspaceId ? { workspaceId: input.workspaceId } : {},
|
|
82083
82089
|
...input.workspaceSlug ? { workspaceSlug: input.workspaceSlug } : {},
|
|
82084
82090
|
...input.clientId ? { clientId: input.clientId } : {},
|
|
@@ -82136,7 +82142,9 @@ var FileRemoteProfileStore = class {
|
|
|
82136
82142
|
kind: "self-hosted",
|
|
82137
82143
|
hostUrl: normalizeRemoteProfileHostUrl(input.hostUrl)
|
|
82138
82144
|
});
|
|
82139
|
-
|
|
82145
|
+
const status = await this.statusByKey(key, false);
|
|
82146
|
+
assertHostIdentityMatches(status, input.hostIdentity);
|
|
82147
|
+
return status;
|
|
82140
82148
|
}
|
|
82141
82149
|
async logoutSelfHostedProfile(input) {
|
|
82142
82150
|
return await this.withMutationLock(async () => {
|
|
@@ -82205,7 +82213,7 @@ var FileRemoteProfileStore = class {
|
|
|
82205
82213
|
}
|
|
82206
82214
|
const selected = this.readSelectedWorkspace(hostUrl);
|
|
82207
82215
|
if (selected) return this.statusByKey(selected.profileKey, true);
|
|
82208
|
-
if (this.listProfilesForHost(hostUrl).length > 0) throw
|
|
82216
|
+
if (this.listProfilesForHost(hostUrl).length > 0) throw cloudWorkspaceAmbiguityError();
|
|
82209
82217
|
return this.migrateLegacyCloudProfile(hostUrl);
|
|
82210
82218
|
}
|
|
82211
82219
|
async listCloudProfileStatuses(hostUrlInput) {
|
|
@@ -82233,7 +82241,7 @@ var FileRemoteProfileStore = class {
|
|
|
82233
82241
|
let key;
|
|
82234
82242
|
if (workspace) key = this.listProfilesForHost(hostUrl).find((profile) => profileMatchesWorkspace(profile, workspace))?.key;
|
|
82235
82243
|
else if (selected) key = selected.profileKey;
|
|
82236
|
-
else if (this.listProfilesForHost(hostUrl).length > 0) throw
|
|
82244
|
+
else if (this.listProfilesForHost(hostUrl).length > 0) throw cloudWorkspaceAmbiguityError();
|
|
82237
82245
|
if (!key) return false;
|
|
82238
82246
|
const profile = this.readProfile(key);
|
|
82239
82247
|
await this.credentials.delete(key);
|
|
@@ -82273,7 +82281,7 @@ var FileRemoteProfileStore = class {
|
|
|
82273
82281
|
else {
|
|
82274
82282
|
const selected = this.readSelectedWorkspace(hostUrl);
|
|
82275
82283
|
if (selected) status = await this.statusByKey(selected.profileKey, true);
|
|
82276
|
-
else if (this.listProfilesForHost(hostUrl).length > 0) throw
|
|
82284
|
+
else if (this.listProfilesForHost(hostUrl).length > 0) throw cloudWorkspaceAmbiguityError();
|
|
82277
82285
|
}
|
|
82278
82286
|
if (!status) return void 0;
|
|
82279
82287
|
const credential = await this.credentials.load(status.key);
|
|
@@ -82326,6 +82334,7 @@ var FileRemoteProfileStore = class {
|
|
|
82326
82334
|
kind: profile.kind,
|
|
82327
82335
|
key: profile.key,
|
|
82328
82336
|
hostUrl: profile.hostUrl,
|
|
82337
|
+
hostIdentity: profile.hostIdentity,
|
|
82329
82338
|
workspaceId: profile.workspaceId,
|
|
82330
82339
|
workspaceSlug: profile.workspaceSlug,
|
|
82331
82340
|
clientId: profile.clientId,
|
|
@@ -82346,11 +82355,13 @@ var FileRemoteProfileStore = class {
|
|
|
82346
82355
|
});
|
|
82347
82356
|
const now = (input.now ?? /* @__PURE__ */ new Date()).toISOString();
|
|
82348
82357
|
const existing = this.readProfile(key);
|
|
82358
|
+
const hostIdentity = input.hostIdentity ?? existing?.hostIdentity;
|
|
82349
82359
|
const profile = {
|
|
82350
82360
|
version: 1,
|
|
82351
82361
|
kind: "self-hosted",
|
|
82352
82362
|
key,
|
|
82353
82363
|
hostUrl,
|
|
82364
|
+
...hostIdentity ? { hostIdentity } : {},
|
|
82354
82365
|
clientId: input.clientId,
|
|
82355
82366
|
...input.clientLabel ? { clientLabel: input.clientLabel } : {},
|
|
82356
82367
|
createdAt: existing?.createdAt ?? now,
|
|
@@ -82523,6 +82534,14 @@ function legacyCredential(credentials) {
|
|
|
82523
82534
|
...credentials.tokenType ? { tokenType: credentials.tokenType } : {}
|
|
82524
82535
|
};
|
|
82525
82536
|
}
|
|
82537
|
+
function assertHostIdentityMatches(status, expectedHostIdentity) {
|
|
82538
|
+
if (!status || !expectedHostIdentity || !status.hostIdentity) return;
|
|
82539
|
+
if (status.hostIdentity === expectedHostIdentity) return;
|
|
82540
|
+
throw new CapletsError("AUTH_FAILED", "Remote Profile belongs to a different host identity.");
|
|
82541
|
+
}
|
|
82542
|
+
function cloudWorkspaceAmbiguityError() {
|
|
82543
|
+
return new CapletsError("REQUEST_INVALID", "Cloud Remote Profile requires a selected or explicit workspace.", { reason: "cloud_workspace_ambiguous" });
|
|
82544
|
+
}
|
|
82526
82545
|
function parseStoredRemoteProfile(value) {
|
|
82527
82546
|
if (!isRecord$1(value)) return void 0;
|
|
82528
82547
|
if (value.version !== 1) return void 0;
|
|
@@ -82535,6 +82554,7 @@ function parseStoredRemoteProfile(value) {
|
|
|
82535
82554
|
kind: value.kind,
|
|
82536
82555
|
key: value.key,
|
|
82537
82556
|
hostUrl: value.hostUrl,
|
|
82557
|
+
...typeof value.hostIdentity === "string" ? { hostIdentity: value.hostIdentity } : {},
|
|
82538
82558
|
...typeof value.workspaceId === "string" ? { workspaceId: value.workspaceId } : {},
|
|
82539
82559
|
...typeof value.workspaceSlug === "string" ? { workspaceSlug: value.workspaceSlug } : {},
|
|
82540
82560
|
...typeof value.clientId === "string" ? { clientId: value.clientId } : {},
|
|
@@ -82621,11 +82641,11 @@ async function resolveRemoteSelection(input = {}, env = process.env) {
|
|
|
82621
82641
|
const explicitWorkspace = input.workspace ?? (workspaceFromRemoteUrl ? void 0 : env.CAPLETS_REMOTE_WORKSPACE);
|
|
82622
82642
|
const profileWorkspace = workspaceFromRemoteUrl ?? explicitWorkspace;
|
|
82623
82643
|
const normalizedRemoteUrl = normalizeRemoteProfileHostUrl(remoteUrl);
|
|
82624
|
-
let status = await store
|
|
82644
|
+
let status = await getCloudProfileStatusForSelection(store, {
|
|
82625
82645
|
hostUrl: normalizedRemoteUrl,
|
|
82626
82646
|
workspace: profileWorkspace
|
|
82627
82647
|
});
|
|
82628
|
-
if (!status && profileWorkspace) status = await store
|
|
82648
|
+
if (!status && profileWorkspace) status = await getCloudProfileStatusForSelection(store, { hostUrl: normalizedRemoteUrl });
|
|
82629
82649
|
let credential = status ? await store.credentials.load(status.key) : void 0;
|
|
82630
82650
|
if (!status || !credential?.accessToken) throw projectBindingError("cloud_auth_required");
|
|
82631
82651
|
let credentials = cloudCredentialsFromRemoteProfile(status, credential);
|
|
@@ -82703,7 +82723,7 @@ async function refreshSelfHostedCredentials(remoteUrl, refreshToken, options) {
|
|
|
82703
82723
|
}
|
|
82704
82724
|
async function selfHostedRefreshError(remoteUrl, response) {
|
|
82705
82725
|
const summary = await parseSelfHostedRefreshError(response);
|
|
82706
|
-
if (response.status === 401 || summary?.code === "AUTH_FAILED") return remoteLoginRequired(remoteUrl);
|
|
82726
|
+
if (response.status === 401 || summary?.code === "AUTH_FAILED" || summary?.code === "REMOTE_CREDENTIALS_REVOKED") return selfHostedRefreshLooksRevoked(summary) ? remoteLoginRevoked(remoteUrl) : remoteLoginRequired(remoteUrl);
|
|
82707
82727
|
if (response.status === 503 || summary?.code === "SERVER_UNAVAILABLE") return new CapletsError("SERVER_UNAVAILABLE", summary?.message ?? "Remote credential refresh is temporarily unavailable.");
|
|
82708
82728
|
return new CapletsError("AUTH_REFRESH_FAILED", summary?.message ?? `Remote credential refresh failed with HTTP ${response.status}.`);
|
|
82709
82729
|
}
|
|
@@ -82749,6 +82769,30 @@ function remoteLoginRequired(remoteUrl) {
|
|
|
82749
82769
|
recoveryCommand: `caplets remote login ${normalizeRemoteProfileHostUrl(remoteUrl)}`
|
|
82750
82770
|
});
|
|
82751
82771
|
}
|
|
82772
|
+
function remoteLoginRevoked(remoteUrl) {
|
|
82773
|
+
const normalizedUrl = normalizeRemoteProfileHostUrl(remoteUrl);
|
|
82774
|
+
return new ProjectBindingError({
|
|
82775
|
+
code: "remote_credentials_revoked",
|
|
82776
|
+
message: `Remote credentials for ${normalizedUrl} were revoked or rejected. Run Remote Login again and ask the server operator to approve the pending login.`,
|
|
82777
|
+
recoveryCommand: `caplets remote login ${normalizedUrl}`
|
|
82778
|
+
});
|
|
82779
|
+
}
|
|
82780
|
+
function selfHostedRefreshLooksRevoked(summary) {
|
|
82781
|
+
if (summary?.code === "REMOTE_CREDENTIALS_REVOKED") return true;
|
|
82782
|
+
return /revoked|rejected|stale/iu.test(summary?.message ?? "");
|
|
82783
|
+
}
|
|
82784
|
+
async function getCloudProfileStatusForSelection(store, input) {
|
|
82785
|
+
try {
|
|
82786
|
+
return await store.getCloudProfileStatus(input);
|
|
82787
|
+
} catch (error) {
|
|
82788
|
+
if (isCloudWorkspaceAmbiguity(error)) throw projectBindingError("workspace_switch_required", "Cloud Remote Profile requires a selected or explicit workspace.");
|
|
82789
|
+
throw error;
|
|
82790
|
+
}
|
|
82791
|
+
}
|
|
82792
|
+
function isCloudWorkspaceAmbiguity(error) {
|
|
82793
|
+
const details = error instanceof CapletsError ? error.details : void 0;
|
|
82794
|
+
return error instanceof CapletsError && error.code === "REQUEST_INVALID" && typeof details === "object" && details !== null && !Array.isArray(details) && details.reason === "cloud_workspace_ambiguous";
|
|
82795
|
+
}
|
|
82752
82796
|
async function parseSelfHostedRefreshCredentials(response) {
|
|
82753
82797
|
const parsed = await response.json();
|
|
82754
82798
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new CapletsError("DOWNSTREAM_PROTOCOL_ERROR", "Remote refresh response must be an object.");
|
|
@@ -83547,4 +83591,4 @@ function errorMessage(error) {
|
|
|
83547
83591
|
return error instanceof Error ? error.message : String(error);
|
|
83548
83592
|
}
|
|
83549
83593
|
//#endregion
|
|
83550
|
-
export { resolveExposure as $,
|
|
83594
|
+
export { resolveExposure as $, mergeCapabilities as $t, nativeCapletPromptGuidance as A, isJSONRPCRequest as An, runOAuthFlow as At, CodeModeSessionManager as B, safeParse as Bn, defaultConfigBaseDir as Bt, resolveHostedCloudRemote as C, ReadResourceRequestSchema as Cn, validateCapletFile as Ct, isLoopbackHost as D, assertCompleteRequestResourceTemplate as Dn, markdownStructuredContent as Dt, controlUrlForBase as E, assertCompleteRequestPrompt as En, markdownCallToolResultContent as Et, nativeCodeModeToolName as F, getSchemaDescription as Fn, readTokenBundle as Ft, CodeModeJournalStore as G, resolveProjectCapletsRoot as Gt, diagnoseCodeModeTypeScript as H, __exportAll as Hn, defaultStateBaseDir as Ht, codeModeRunInputSchema as I, isSchemaOptional as In, DEFAULT_AUTH_DIR as It, codeModeDeclarationHash as J, serializeMessage as Jt, CodeModeLogStore as K, resolveProjectConfigPath as Kt, codeModeRunParamsSchema as L, isZ4Schema as Ln, DEFAULT_COMPLETION_CACHE_DIR as Lt, nativeCapletToolName as M, getLiteralValue as Mn, startOAuthFlow as Mt, nativeCapletsSystemGuidance as N, getObjectShape as Nn, deleteTokenBundle as Nt, parseServerBaseUrl as O, isInitializeRequest as On, refreshOAuthTokenBundle as Ot, nativeCodeModeToolId as P, getParseErrorMessage as Pn, isTokenBundleExpired as Pt, CapletsEngine as Q, Protocol as Qt, emptyCodeModeRunMeta as R, normalizeObjectSchema as Rn, DEFAULT_OBSERVED_OUTPUT_SHAPE_CACHE_DIR as Rt, resolveCapletsRemote as S, McpError as Sn, discoverCapletFiles as St, appendBasePath as T, SetLevelRequestSchema as Tn, hasRenderableStructuredContent as Tt, createCodeModeCapletsApi as U, resolveCapletsRoot as Ut, QuickJsCodeModeSandbox as V, safeParseAsync as Vn, defaultConfigPath as Vt, listCodeModeCallableCaplets as W, resolveConfigPath as Wt, generateCodeModeRunToolDescription as X, assertToolsCallTaskCapability as Xt, generateCodeModeDeclarations as Y, assertClientRequestTaskCapability as Yt, minifyCodeModeDeclarationText as Z, AjvJsonSchemaValidator as Zt, CapletsCloudClient as _, ListResourceTemplatesRequestSchema as _n, FileVaultStore as _t, CloudAuthStore as a, CreateMessageResultWithToolsSchema as an, ServerRegistry as at, isCapletsCloudUrl as b, ListToolsRequestSchema as bn, decryptVaultValue as bt, redactedCloudAuthStatus as c, ElicitResultSchema as cn, loadConfig as ct, projectBindingError as d, GetPromptRequestSchema as dn, loadLocalOverlayConfigWithSources as dt, toJsonSchemaCompat as en, decodeDirectResourceUri as et, projectBindingRecovery as f, InitializeRequestSchema as fn, loadProjectConfig as ft, buildProjectSyncManifest as g, ListPromptsRequestSchema as gn, vaultStoreForAuthDir as gt, createSdkRemoteCapletsClient as h, LATEST_PROTOCOL_VERSION as hn, vaultResolverForAuthDir as ht, createRemoteProfileStore as i, CreateMessageResultSchema as in, handleServerTool as it, nativeCapletToolDescription as j, isJSONRPCResultResponse as jn, startGenericOAuthFlow as jt, resolveCapletsServer as k, isJSONRPCErrorResponse as kn, runGenericOAuthFlow as kt, PROJECT_BINDING_ERROR_CODES as l, EmptyResultSchema as ln, loadConfigWithSources as lt, RemoteNativeCapletsService as m, JSONRPCMessageSchema as mn, vaultBootstrapResolver as mt, resolveRemoteSelection as n, CallToolResultSchema as nn, findProjectRoot as nt, cloudAuthPath as o, CreateTaskResultSchema as on, capabilityDescription as ot, CloudAuthClient as p, InitializedNotificationSchema as pn, parseConfig as pt, redactCodeModeLogText as q, ReadBuffer as qt, cloudCredentialsFromRemoteProfile as r, CompleteRequestSchema as rn, fingerprintProjectRoot as rt, migrateCredentials as s, DEFAULT_NEGOTIATED_PROTOCOL_VERSION as sn, GoogleDiscoveryManager as st, createNativeCapletsService as t, CallToolRequestSchema as tn, directResourceUriMatchesTemplate as tt, ProjectBindingError as u, ErrorCode as un, loadGlobalConfig as ut, resolveNativeCapletsServiceOptions as v, ListResourcesRequestSchema as vn, VAULT_MAX_VALUE_BYTES as vt, resolveRemoteMode as w, SUPPORTED_PROTOCOL_VERSIONS as wn, loadCapletFilesFromMap as wt, normalizeRemoteProfileHostUrl as x, LoggingLevelSchema as xn, encryptVaultValue as xt, hostedCloudWorkspaceFromRemoteUrl as y, ListRootsResultSchema as yn, validateVaultKeyName as yt, runCodeMode as z, objectFromShape as zn, defaultCacheBaseDir as zt };
|