@shipstatic/ship 2.0.0-beta.7 → 2.0.0-beta.9

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/index.d.cts CHANGED
@@ -276,6 +276,10 @@ interface DnsLookup {
276
276
  /** The provider serving this domain's DNS, absent when unidentified */
277
277
  provider?: DnsProvider;
278
278
  }
279
+ /**
280
+ * A report: it answers a question and carries only the answer (`CLAUDE.md`,
281
+ * "A report answers a question").
282
+ */
279
283
  interface DomainDnsResponse {
280
284
  /** The domain name */
281
285
  domain: string;
@@ -288,6 +292,9 @@ interface DomainDnsResponse {
288
292
  *
289
293
  * `/admin/domains/:domain/share` answers the same shape, which is the admin
290
294
  * law working: the operator surface is the public grammar with a prefix.
295
+ *
296
+ * A report: it answers a question and carries only the answer (`CLAUDE.md`,
297
+ * "A report answers a question").
291
298
  */
292
299
  interface DomainShareResponse {
293
300
  /** The domain the setup link is for */
@@ -297,6 +304,9 @@ interface DomainShareResponse {
297
304
  }
298
305
  /**
299
306
  * Response for domain DNS records
307
+ *
308
+ * A report: it answers a question and carries only the answer (`CLAUDE.md`,
309
+ * "A report answers a question").
300
310
  */
301
311
  interface DomainRecordsResponse {
302
312
  /** The domain name */
@@ -332,6 +342,9 @@ declare function validateIdempotencyKey(value: unknown): string | undefined;
332
342
  * no identity, no row and no `created`, so there is nothing for a keyset
333
343
  * cursor to resume after, and its consumer is an autocomplete that wants the
334
344
  * whole set. Bounded by `PAGINATION.GLOBAL_LIMIT` rather than paginated.
345
+ *
346
+ * A report: it answers a question and carries only the answer (`CLAUDE.md`,
347
+ * "A report answers a question").
335
348
  */
336
349
  interface LabelsResponse {
337
350
  readonly labels: string[];
@@ -342,8 +355,13 @@ interface LabelsResponse {
342
355
  *
343
356
  * `custom` is the provider-specific walkthrough when the provider is known;
344
357
  * `generic` always answers, so a caller never has nothing to show.
358
+ *
359
+ * A report: it answers a question and carries only the answer (`CLAUDE.md`,
360
+ * "A report answers a question").
345
361
  */
346
362
  interface SetupInstructionsResponse {
363
+ /** The domain the instructions are for — a report names its subject */
364
+ readonly domain: string;
347
365
  /** One-line summary of what to do */
348
366
  readonly tldr: string;
349
367
  /** Provider-specific instructions, null when the provider is unknown */
@@ -354,7 +372,14 @@ interface SetupInstructionsResponse {
354
372
  readonly provider: string | null;
355
373
  }
356
374
  /**
357
- * Response for domain validation
375
+ * `POST /domains/validate` a report answering "is this name usable, and if
376
+ * not, why".
377
+ *
378
+ * An unusable name is a legitimate ANSWER, not a failure, so this is a 200 and
379
+ * the verdict rides the body. `reason` was named `error` until 2026-07-29,
380
+ * which collided with {@link ErrorResponse}'s reserved key — there `error` is
381
+ * an `ErrorType` a client branches on, here it is prose a client displays, and
382
+ * one key cannot mean both. See {@link DeploymentDeleteResponse} for the law.
358
383
  */
359
384
  interface DomainValidateResponse {
360
385
  /** Whether the domain is valid */
@@ -363,8 +388,8 @@ interface DomainValidateResponse {
363
388
  normalized: string | null;
364
389
  /** Whether the domain is available, null when invalid */
365
390
  available: boolean | null;
366
- /** Error message, null when valid */
367
- error: string | null;
391
+ /** Why the name is unusable, null when valid — displayed verbatim. */
392
+ reason: string | null;
368
393
  }
369
394
  /**
370
395
  * Core deploy token object - used in both API responses and SDK.
@@ -521,6 +546,9 @@ interface AccountDeleteResponse {
521
546
  * (`Account.hint`), and the plaintext exists exactly once, in this response.
522
547
  * The raw credential is `secret` on every surface that mints one — the same
523
548
  * field `TokenCreateResponse` carries — because one concept gets one name.
549
+ *
550
+ * A report: it answers a question and carries only the answer (`CLAUDE.md`,
551
+ * "A report answers a question").
524
552
  */
525
553
  interface AccountKeyResponse {
526
554
  /** The raw API key (shown once at mint, then never again) */
@@ -711,6 +739,9 @@ declare function isShipError(error: unknown): error is ShipError;
711
739
  *
712
740
  * These are the *platform's* posted caps for the current account — server
713
741
  * truth delivered at runtime, never hard-coded on the client.
742
+ *
743
+ * A report: it answers a question and carries only the answer (`CLAUDE.md`,
744
+ * "A report answers a question").
714
745
  */
715
746
  interface PlatformLimits {
716
747
  /** Maximum size in bytes for a single file. */
@@ -781,13 +812,20 @@ declare const UNBUILT_PROJECT_MARKERS: ReadonlySet<string>;
781
812
  */
782
813
  declare function hasUnbuiltMarker(filePath: string): boolean;
783
814
  /**
784
- * Simple ping response for health checks
815
+ * `GET /ping` a report of the server clock.
816
+ *
817
+ * Liveness is the STATUS CODE's answer, not a field's: a 200 means reachable,
818
+ * and any other outcome throws before a body is read. So the body carries the
819
+ * one thing a status code cannot — the server's own clock, which is what lets a
820
+ * client detect skew against a token expiry. It read `{ success: true,
821
+ * timestamp? }` until 2026-07-29, where `success` was a literal constant in the
822
+ * route (zero bits, and the platform's own named anti-pattern) while the field
823
+ * that IS the payload was optional. See {@link DeploymentDeleteResponse} for
824
+ * the law, and `tests/response-shapes.test.ts` for the fence that holds it.
785
825
  */
786
826
  interface PingResponse {
787
- /** Always true if service is healthy */
788
- success: boolean;
789
827
  /** Server time in unix seconds — the one wire unit for timestamps. */
790
- timestamp?: number;
828
+ readonly timestamp: number;
791
829
  }
792
830
  /**
793
831
  * Where human identity is mounted on the API host. The API mounts Better
@@ -992,6 +1030,10 @@ interface SPACheckDebug {
992
1030
  /** The reason for the detection result */
993
1031
  reason: string;
994
1032
  }
1033
+ /**
1034
+ * A report: it answers a question and carries only the answer (`CLAUDE.md`,
1035
+ * "A report answers a question").
1036
+ */
995
1037
  interface SPACheckResponse {
996
1038
  /** Whether the project is detected as a Single Page Application */
997
1039
  isSPA: boolean;
@@ -1150,7 +1192,7 @@ interface DeploymentResource<UploadOptions extends DeploymentUploadOptions = Dep
1150
1192
  list: (options?: ListOptions) => Promise<DeploymentListResponse>;
1151
1193
  get: (id: string) => Promise<Deployment>;
1152
1194
  set: (id: string, options: DeploymentSetOptions) => Promise<Deployment>;
1153
- remove: (id: string) => Promise<DeploymentDeleteResponse>;
1195
+ delete: (id: string) => Promise<DeploymentDeleteResponse>;
1154
1196
  }
1155
1197
  /**
1156
1198
  * Domain resource interface - the contract all implementations must follow
@@ -1159,7 +1201,7 @@ interface DomainResource {
1159
1201
  set: (name: string, options?: DomainSetOptions) => Promise<DomainSetResult>;
1160
1202
  list: (options?: ListOptions) => Promise<DomainListResponse>;
1161
1203
  get: (name: string) => Promise<Domain>;
1162
- remove: (name: string) => Promise<DomainDeleteResponse>;
1204
+ delete: (name: string) => Promise<DomainDeleteResponse>;
1163
1205
  verify: (name: string) => Promise<DomainVerifyResponse>;
1164
1206
  validate: (name: string) => Promise<DomainValidateResponse>;
1165
1207
  dns: (name: string) => Promise<DomainDnsResponse>;
@@ -1179,7 +1221,7 @@ interface TokenResource {
1179
1221
  create: (options?: TokenCreateOptions) => Promise<TokenCreateResponse>;
1180
1222
  list: (options?: ListOptions) => Promise<TokenListResponse>;
1181
1223
  get: (token: string) => Promise<Token>;
1182
- remove: (token: string) => Promise<TokenDeleteResponse>;
1224
+ delete: (token: string) => Promise<TokenDeleteResponse>;
1183
1225
  }
1184
1226
  /**
1185
1227
  * Billing status response from GET /billing/status
@@ -1199,6 +1241,25 @@ interface BillingStatus {
1199
1241
  /** Link to Creem customer portal for billing management, null if unavailable */
1200
1242
  portal: string | null;
1201
1243
  }
1244
+ /**
1245
+ * Acknowledgement of `POST /billing/cancel`.
1246
+ *
1247
+ * Cancelling leaves no billing entity to return, so it answers with the
1248
+ * account and the one field of the account the call changed — the plan it
1249
+ * landed on. See {@link DeploymentDeleteResponse} for the law.
1250
+ *
1251
+ * This read `{ success: true, message: 'Subscription canceled successfully…' }`
1252
+ * until 2026-07-29, an anonymous shape that `web/my` redeclared inline and
1253
+ * whose prose no surface ever displayed: both callers await the promise and
1254
+ * discard the body, then compose their own toast. The message was written,
1255
+ * serialized, and thrown away on every cancellation.
1256
+ */
1257
+ interface BillingCancelResponse {
1258
+ /** The account whose subscription was cancelled */
1259
+ readonly account: string;
1260
+ /** The plan the account now holds — `free` on a successful cancellation */
1261
+ readonly plan: AccountPlanType;
1262
+ }
1202
1263
  /**
1203
1264
  * Checkout session response from POST /billing/checkout
1204
1265
  */
@@ -1723,11 +1784,11 @@ declare class ApiHttp extends SimpleEvents {
1723
1784
  listDeployments(options?: ListOptions): Promise<DeploymentListResponse>;
1724
1785
  getDeployment(id: string): Promise<Deployment>;
1725
1786
  updateDeploymentLabels(id: string, labels: string[]): Promise<Deployment>;
1726
- removeDeployment(id: string): Promise<DeploymentDeleteResponse>;
1787
+ deleteDeployment(id: string): Promise<DeploymentDeleteResponse>;
1727
1788
  setDomain(name: string, deployment?: string, labels?: string[]): Promise<DomainSetResult>;
1728
1789
  listDomains(options?: ListOptions): Promise<DomainListResponse>;
1729
1790
  getDomain(name: string): Promise<Domain>;
1730
- removeDomain(name: string): Promise<DomainDeleteResponse>;
1791
+ deleteDomain(name: string): Promise<DomainDeleteResponse>;
1731
1792
  verifyDomain(name: string): Promise<DomainVerifyResponse>;
1732
1793
  getDomainDns(name: string): Promise<DomainDnsResponse>;
1733
1794
  getDomainRecords(name: string): Promise<DomainRecordsResponse>;
@@ -1735,11 +1796,11 @@ declare class ApiHttp extends SimpleEvents {
1735
1796
  validateDomain(name: string): Promise<DomainValidateResponse>;
1736
1797
  createToken(ttl?: number, labels?: string[]): Promise<TokenCreateResponse>;
1737
1798
  listTokens(options?: ListOptions): Promise<TokenListResponse>;
1738
- removeToken(token: string): Promise<TokenDeleteResponse>;
1799
+ deleteToken(token: string): Promise<TokenDeleteResponse>;
1739
1800
  getToken(token: string): Promise<Token>;
1740
1801
  getAccount(): Promise<AccountGetResponse>;
1741
1802
  getLimits(): Promise<PlatformLimits>;
1742
- ping(): Promise<boolean>;
1803
+ ping(): Promise<PingResponse>;
1743
1804
  checkSPA(files: StaticFile[], _options?: ApiDeployOptions): Promise<boolean>;
1744
1805
  }
1745
1806
 
@@ -1809,9 +1870,16 @@ declare abstract class Ship$1 {
1809
1870
  protected ensureInitialized(): Promise<void>;
1810
1871
  private fetchPlatformLimits;
1811
1872
  /**
1812
- * Ping the API server to check connectivity.
1873
+ * Ping the API server, resolving its answer: `{ success, timestamp }`, where
1874
+ * `timestamp` is the server clock in unix SECONDS.
1875
+ *
1876
+ * It resolves the response rather than a bare `true` because every other
1877
+ * method here does — narrowing to a boolean discarded the one thing ping
1878
+ * carries beyond liveness, and made `success` mean a boolean on the wire and
1879
+ * something else by the time it reached a caller. A non-OK response throws in
1880
+ * transport, so a resolved value always means the API answered.
1813
1881
  */
1814
- ping(): Promise<boolean>;
1882
+ ping(): Promise<PingResponse>;
1815
1883
  /**
1816
1884
  * Deploy project (convenience shortcut to `ship.deployments.upload()`).
1817
1885
  */
@@ -2172,6 +2240,6 @@ declare class Ship extends Ship$1 {
2172
2240
  }
2173
2241
 
2174
2242
  declare namespace Ship {
2175
- export { API_KEY, API_PATHS, AUTH_BASE_PATH, Account, AccountDeleteResponse, AccountGetResponse, AccountKeyResponse, AccountOverrides, AccountPlan, AccountPlanType, AccountResource, AccountUsage, Activity, ActivityEvent, ActivityListResponse, ActivityMeta, ApiDeployOptions, ApiHttp, ApiHttpOptions, AuthMethod, AuthMethodType, BLOCKED_EXTENSIONS, BillingStatus, CALLER, CheckoutSession, DEFAULT_API, DEPLOYMENT_CONFIG_FILENAME, DEPLOY_TOKEN, DeployBody, DeployBodyContext, DeployBodyCreator, DeployFile, DeployInput, Deployment, DeploymentCreateResponse, DeploymentDeleteResponse, DeploymentListResponse, DeploymentOptions, DeploymentResource, DeploymentResourceContext, DeploymentSetOptions, DeploymentStatus, DeploymentStatusType, DeploymentUploadOptions, DnsLookup, DnsProvider, DnsRecord, DnsRecordType, Domain, DomainDeleteResponse, DomainDnsResponse, DomainListResponse, DomainRecordsResponse, DomainResource, DomainSetOptions, DomainSetResult, DomainShareResponse, DomainStatus, DomainStatusType, DomainValidateResponse, DomainVerifyResponse, ErrorResponse, ErrorType, ExecutionEnvironment, FileValidationStatus as FILE_VALIDATION_STATUS, Fetch, FileValidationResult, FileValidationStatus, FileValidationStatusType, IDEMPOTENCY_KEY_CONSTRAINTS, JUNK_DIRECTORIES, LABEL_CONSTRAINTS, LABEL_PATTERN, LabelsResponse, ListOptions, ListResponse, MD5Result, OAuthScope, OAuthScopeType, PASSWORD_CONSTRAINTS, PingResponse, PlatformLimits, ResourceContext, SPACheckDebug, SPACheckRequest, SPACheckResponse, SPA_DEFAULT_CONFIG, SetupInstructionsResponse, ShipClientOptions, ShipError, ShipEvents, StaticFile, Token, TokenCreateOptions, TokenCreateResponse, TokenDeleteResponse, TokenKind, TokenKindType, TokenListResponse, TokenProvider, TokenResource, UNBUILT_PROJECT_MARKERS, UNSAFE_FILENAME_CHARS, UploadedFile, UserVisibleActivityEvent, ValidatableFile, ValidationIssue, __setTestEnvironment, allValidFilesReady, assertShipJsonSyntax, calculateMD5, classifyToken, createAccountResource, createDeploymentResource, createDomainResource, createTokenResource, deserializeLabels, extractSubdomain, filterJunk, formatFileSize, generateDeploymentUrl, generateDomainUrl, getENV, getValidFiles, hasUnbuiltMarker, hasUnsafeChars, isBlockedExtension, isCustomDomain, isDeployment, isPlatformDomain, isShipError, optimizeDeployPaths, pluralize, processFilesForNode, serializeLabels, validateApiKey, validateApiUrl, validateCaller, validateDeployFile, validateDeployPath, validateDeployToken, validateFileName, validateFiles, validateIdempotencyKey, validatePassword, validateToken };
2243
+ export { API_KEY, API_PATHS, AUTH_BASE_PATH, Account, AccountDeleteResponse, AccountGetResponse, AccountKeyResponse, AccountOverrides, AccountPlan, AccountPlanType, AccountResource, AccountUsage, Activity, ActivityEvent, ActivityListResponse, ActivityMeta, ApiDeployOptions, ApiHttp, ApiHttpOptions, AuthMethod, AuthMethodType, BLOCKED_EXTENSIONS, BillingCancelResponse, BillingStatus, CALLER, CheckoutSession, DEFAULT_API, DEPLOYMENT_CONFIG_FILENAME, DEPLOY_TOKEN, DeployBody, DeployBodyContext, DeployBodyCreator, DeployFile, DeployInput, Deployment, DeploymentCreateResponse, DeploymentDeleteResponse, DeploymentListResponse, DeploymentOptions, DeploymentResource, DeploymentResourceContext, DeploymentSetOptions, DeploymentStatus, DeploymentStatusType, DeploymentUploadOptions, DnsLookup, DnsProvider, DnsRecord, DnsRecordType, Domain, DomainDeleteResponse, DomainDnsResponse, DomainListResponse, DomainRecordsResponse, DomainResource, DomainSetOptions, DomainSetResult, DomainShareResponse, DomainStatus, DomainStatusType, DomainValidateResponse, DomainVerifyResponse, ErrorResponse, ErrorType, ExecutionEnvironment, FileValidationStatus as FILE_VALIDATION_STATUS, Fetch, FileValidationResult, FileValidationStatus, FileValidationStatusType, IDEMPOTENCY_KEY_CONSTRAINTS, JUNK_DIRECTORIES, LABEL_CONSTRAINTS, LABEL_PATTERN, LabelsResponse, ListOptions, ListResponse, MD5Result, OAuthScope, OAuthScopeType, PASSWORD_CONSTRAINTS, PingResponse, PlatformLimits, ResourceContext, SPACheckDebug, SPACheckRequest, SPACheckResponse, SPA_DEFAULT_CONFIG, SetupInstructionsResponse, ShipClientOptions, ShipError, ShipEvents, StaticFile, Token, TokenCreateOptions, TokenCreateResponse, TokenDeleteResponse, TokenKind, TokenKindType, TokenListResponse, TokenProvider, TokenResource, UNBUILT_PROJECT_MARKERS, UNSAFE_FILENAME_CHARS, UploadedFile, UserVisibleActivityEvent, ValidatableFile, ValidationIssue, __setTestEnvironment, allValidFilesReady, assertShipJsonSyntax, calculateMD5, classifyToken, createAccountResource, createDeploymentResource, createDomainResource, createTokenResource, deserializeLabels, extractSubdomain, filterJunk, formatFileSize, generateDeploymentUrl, generateDomainUrl, getENV, getValidFiles, hasUnbuiltMarker, hasUnsafeChars, isBlockedExtension, isCustomDomain, isDeployment, isPlatformDomain, isShipError, optimizeDeployPaths, pluralize, processFilesForNode, serializeLabels, validateApiKey, validateApiUrl, validateCaller, validateDeployFile, validateDeployPath, validateDeployToken, validateFileName, validateFiles, validateIdempotencyKey, validatePassword, validateToken };
2176
2244
  }
2177
2245
  export = Ship;
package/dist/index.d.ts CHANGED
@@ -276,6 +276,10 @@ interface DnsLookup {
276
276
  /** The provider serving this domain's DNS, absent when unidentified */
277
277
  provider?: DnsProvider;
278
278
  }
279
+ /**
280
+ * A report: it answers a question and carries only the answer (`CLAUDE.md`,
281
+ * "A report answers a question").
282
+ */
279
283
  interface DomainDnsResponse {
280
284
  /** The domain name */
281
285
  domain: string;
@@ -288,6 +292,9 @@ interface DomainDnsResponse {
288
292
  *
289
293
  * `/admin/domains/:domain/share` answers the same shape, which is the admin
290
294
  * law working: the operator surface is the public grammar with a prefix.
295
+ *
296
+ * A report: it answers a question and carries only the answer (`CLAUDE.md`,
297
+ * "A report answers a question").
291
298
  */
292
299
  interface DomainShareResponse {
293
300
  /** The domain the setup link is for */
@@ -297,6 +304,9 @@ interface DomainShareResponse {
297
304
  }
298
305
  /**
299
306
  * Response for domain DNS records
307
+ *
308
+ * A report: it answers a question and carries only the answer (`CLAUDE.md`,
309
+ * "A report answers a question").
300
310
  */
301
311
  interface DomainRecordsResponse {
302
312
  /** The domain name */
@@ -332,6 +342,9 @@ declare function validateIdempotencyKey(value: unknown): string | undefined;
332
342
  * no identity, no row and no `created`, so there is nothing for a keyset
333
343
  * cursor to resume after, and its consumer is an autocomplete that wants the
334
344
  * whole set. Bounded by `PAGINATION.GLOBAL_LIMIT` rather than paginated.
345
+ *
346
+ * A report: it answers a question and carries only the answer (`CLAUDE.md`,
347
+ * "A report answers a question").
335
348
  */
336
349
  interface LabelsResponse {
337
350
  readonly labels: string[];
@@ -342,8 +355,13 @@ interface LabelsResponse {
342
355
  *
343
356
  * `custom` is the provider-specific walkthrough when the provider is known;
344
357
  * `generic` always answers, so a caller never has nothing to show.
358
+ *
359
+ * A report: it answers a question and carries only the answer (`CLAUDE.md`,
360
+ * "A report answers a question").
345
361
  */
346
362
  interface SetupInstructionsResponse {
363
+ /** The domain the instructions are for — a report names its subject */
364
+ readonly domain: string;
347
365
  /** One-line summary of what to do */
348
366
  readonly tldr: string;
349
367
  /** Provider-specific instructions, null when the provider is unknown */
@@ -354,7 +372,14 @@ interface SetupInstructionsResponse {
354
372
  readonly provider: string | null;
355
373
  }
356
374
  /**
357
- * Response for domain validation
375
+ * `POST /domains/validate` a report answering "is this name usable, and if
376
+ * not, why".
377
+ *
378
+ * An unusable name is a legitimate ANSWER, not a failure, so this is a 200 and
379
+ * the verdict rides the body. `reason` was named `error` until 2026-07-29,
380
+ * which collided with {@link ErrorResponse}'s reserved key — there `error` is
381
+ * an `ErrorType` a client branches on, here it is prose a client displays, and
382
+ * one key cannot mean both. See {@link DeploymentDeleteResponse} for the law.
358
383
  */
359
384
  interface DomainValidateResponse {
360
385
  /** Whether the domain is valid */
@@ -363,8 +388,8 @@ interface DomainValidateResponse {
363
388
  normalized: string | null;
364
389
  /** Whether the domain is available, null when invalid */
365
390
  available: boolean | null;
366
- /** Error message, null when valid */
367
- error: string | null;
391
+ /** Why the name is unusable, null when valid — displayed verbatim. */
392
+ reason: string | null;
368
393
  }
369
394
  /**
370
395
  * Core deploy token object - used in both API responses and SDK.
@@ -521,6 +546,9 @@ interface AccountDeleteResponse {
521
546
  * (`Account.hint`), and the plaintext exists exactly once, in this response.
522
547
  * The raw credential is `secret` on every surface that mints one — the same
523
548
  * field `TokenCreateResponse` carries — because one concept gets one name.
549
+ *
550
+ * A report: it answers a question and carries only the answer (`CLAUDE.md`,
551
+ * "A report answers a question").
524
552
  */
525
553
  interface AccountKeyResponse {
526
554
  /** The raw API key (shown once at mint, then never again) */
@@ -711,6 +739,9 @@ declare function isShipError(error: unknown): error is ShipError;
711
739
  *
712
740
  * These are the *platform's* posted caps for the current account — server
713
741
  * truth delivered at runtime, never hard-coded on the client.
742
+ *
743
+ * A report: it answers a question and carries only the answer (`CLAUDE.md`,
744
+ * "A report answers a question").
714
745
  */
715
746
  interface PlatformLimits {
716
747
  /** Maximum size in bytes for a single file. */
@@ -781,13 +812,20 @@ declare const UNBUILT_PROJECT_MARKERS: ReadonlySet<string>;
781
812
  */
782
813
  declare function hasUnbuiltMarker(filePath: string): boolean;
783
814
  /**
784
- * Simple ping response for health checks
815
+ * `GET /ping` a report of the server clock.
816
+ *
817
+ * Liveness is the STATUS CODE's answer, not a field's: a 200 means reachable,
818
+ * and any other outcome throws before a body is read. So the body carries the
819
+ * one thing a status code cannot — the server's own clock, which is what lets a
820
+ * client detect skew against a token expiry. It read `{ success: true,
821
+ * timestamp? }` until 2026-07-29, where `success` was a literal constant in the
822
+ * route (zero bits, and the platform's own named anti-pattern) while the field
823
+ * that IS the payload was optional. See {@link DeploymentDeleteResponse} for
824
+ * the law, and `tests/response-shapes.test.ts` for the fence that holds it.
785
825
  */
786
826
  interface PingResponse {
787
- /** Always true if service is healthy */
788
- success: boolean;
789
827
  /** Server time in unix seconds — the one wire unit for timestamps. */
790
- timestamp?: number;
828
+ readonly timestamp: number;
791
829
  }
792
830
  /**
793
831
  * Where human identity is mounted on the API host. The API mounts Better
@@ -992,6 +1030,10 @@ interface SPACheckDebug {
992
1030
  /** The reason for the detection result */
993
1031
  reason: string;
994
1032
  }
1033
+ /**
1034
+ * A report: it answers a question and carries only the answer (`CLAUDE.md`,
1035
+ * "A report answers a question").
1036
+ */
995
1037
  interface SPACheckResponse {
996
1038
  /** Whether the project is detected as a Single Page Application */
997
1039
  isSPA: boolean;
@@ -1150,7 +1192,7 @@ interface DeploymentResource<UploadOptions extends DeploymentUploadOptions = Dep
1150
1192
  list: (options?: ListOptions) => Promise<DeploymentListResponse>;
1151
1193
  get: (id: string) => Promise<Deployment>;
1152
1194
  set: (id: string, options: DeploymentSetOptions) => Promise<Deployment>;
1153
- remove: (id: string) => Promise<DeploymentDeleteResponse>;
1195
+ delete: (id: string) => Promise<DeploymentDeleteResponse>;
1154
1196
  }
1155
1197
  /**
1156
1198
  * Domain resource interface - the contract all implementations must follow
@@ -1159,7 +1201,7 @@ interface DomainResource {
1159
1201
  set: (name: string, options?: DomainSetOptions) => Promise<DomainSetResult>;
1160
1202
  list: (options?: ListOptions) => Promise<DomainListResponse>;
1161
1203
  get: (name: string) => Promise<Domain>;
1162
- remove: (name: string) => Promise<DomainDeleteResponse>;
1204
+ delete: (name: string) => Promise<DomainDeleteResponse>;
1163
1205
  verify: (name: string) => Promise<DomainVerifyResponse>;
1164
1206
  validate: (name: string) => Promise<DomainValidateResponse>;
1165
1207
  dns: (name: string) => Promise<DomainDnsResponse>;
@@ -1179,7 +1221,7 @@ interface TokenResource {
1179
1221
  create: (options?: TokenCreateOptions) => Promise<TokenCreateResponse>;
1180
1222
  list: (options?: ListOptions) => Promise<TokenListResponse>;
1181
1223
  get: (token: string) => Promise<Token>;
1182
- remove: (token: string) => Promise<TokenDeleteResponse>;
1224
+ delete: (token: string) => Promise<TokenDeleteResponse>;
1183
1225
  }
1184
1226
  /**
1185
1227
  * Billing status response from GET /billing/status
@@ -1199,6 +1241,25 @@ interface BillingStatus {
1199
1241
  /** Link to Creem customer portal for billing management, null if unavailable */
1200
1242
  portal: string | null;
1201
1243
  }
1244
+ /**
1245
+ * Acknowledgement of `POST /billing/cancel`.
1246
+ *
1247
+ * Cancelling leaves no billing entity to return, so it answers with the
1248
+ * account and the one field of the account the call changed — the plan it
1249
+ * landed on. See {@link DeploymentDeleteResponse} for the law.
1250
+ *
1251
+ * This read `{ success: true, message: 'Subscription canceled successfully…' }`
1252
+ * until 2026-07-29, an anonymous shape that `web/my` redeclared inline and
1253
+ * whose prose no surface ever displayed: both callers await the promise and
1254
+ * discard the body, then compose their own toast. The message was written,
1255
+ * serialized, and thrown away on every cancellation.
1256
+ */
1257
+ interface BillingCancelResponse {
1258
+ /** The account whose subscription was cancelled */
1259
+ readonly account: string;
1260
+ /** The plan the account now holds — `free` on a successful cancellation */
1261
+ readonly plan: AccountPlanType;
1262
+ }
1202
1263
  /**
1203
1264
  * Checkout session response from POST /billing/checkout
1204
1265
  */
@@ -1723,11 +1784,11 @@ declare class ApiHttp extends SimpleEvents {
1723
1784
  listDeployments(options?: ListOptions): Promise<DeploymentListResponse>;
1724
1785
  getDeployment(id: string): Promise<Deployment>;
1725
1786
  updateDeploymentLabels(id: string, labels: string[]): Promise<Deployment>;
1726
- removeDeployment(id: string): Promise<DeploymentDeleteResponse>;
1787
+ deleteDeployment(id: string): Promise<DeploymentDeleteResponse>;
1727
1788
  setDomain(name: string, deployment?: string, labels?: string[]): Promise<DomainSetResult>;
1728
1789
  listDomains(options?: ListOptions): Promise<DomainListResponse>;
1729
1790
  getDomain(name: string): Promise<Domain>;
1730
- removeDomain(name: string): Promise<DomainDeleteResponse>;
1791
+ deleteDomain(name: string): Promise<DomainDeleteResponse>;
1731
1792
  verifyDomain(name: string): Promise<DomainVerifyResponse>;
1732
1793
  getDomainDns(name: string): Promise<DomainDnsResponse>;
1733
1794
  getDomainRecords(name: string): Promise<DomainRecordsResponse>;
@@ -1735,11 +1796,11 @@ declare class ApiHttp extends SimpleEvents {
1735
1796
  validateDomain(name: string): Promise<DomainValidateResponse>;
1736
1797
  createToken(ttl?: number, labels?: string[]): Promise<TokenCreateResponse>;
1737
1798
  listTokens(options?: ListOptions): Promise<TokenListResponse>;
1738
- removeToken(token: string): Promise<TokenDeleteResponse>;
1799
+ deleteToken(token: string): Promise<TokenDeleteResponse>;
1739
1800
  getToken(token: string): Promise<Token>;
1740
1801
  getAccount(): Promise<AccountGetResponse>;
1741
1802
  getLimits(): Promise<PlatformLimits>;
1742
- ping(): Promise<boolean>;
1803
+ ping(): Promise<PingResponse>;
1743
1804
  checkSPA(files: StaticFile[], _options?: ApiDeployOptions): Promise<boolean>;
1744
1805
  }
1745
1806
 
@@ -1809,9 +1870,16 @@ declare abstract class Ship$1 {
1809
1870
  protected ensureInitialized(): Promise<void>;
1810
1871
  private fetchPlatformLimits;
1811
1872
  /**
1812
- * Ping the API server to check connectivity.
1873
+ * Ping the API server, resolving its answer: `{ success, timestamp }`, where
1874
+ * `timestamp` is the server clock in unix SECONDS.
1875
+ *
1876
+ * It resolves the response rather than a bare `true` because every other
1877
+ * method here does — narrowing to a boolean discarded the one thing ping
1878
+ * carries beyond liveness, and made `success` mean a boolean on the wire and
1879
+ * something else by the time it reached a caller. A non-OK response throws in
1880
+ * transport, so a resolved value always means the API answered.
1813
1881
  */
1814
- ping(): Promise<boolean>;
1882
+ ping(): Promise<PingResponse>;
1815
1883
  /**
1816
1884
  * Deploy project (convenience shortcut to `ship.deployments.upload()`).
1817
1885
  */
@@ -2171,4 +2239,4 @@ declare class Ship extends Ship$1 {
2171
2239
  protected getDeployBodyCreator(): DeployBodyCreator;
2172
2240
  }
2173
2241
 
2174
- export { API_KEY, API_PATHS, AUTH_BASE_PATH, type Account, type AccountDeleteResponse, type AccountGetResponse, type AccountKeyResponse, type AccountOverrides, AccountPlan, type AccountPlanType, type AccountResource, type AccountUsage, type Activity, type ActivityEvent, type ActivityListResponse, type ActivityMeta, type ApiDeployOptions, ApiHttp, type ApiHttpOptions, AuthMethod, type AuthMethodType, BLOCKED_EXTENSIONS, type BillingStatus, CALLER, type CheckoutSession, DEFAULT_API, DEPLOYMENT_CONFIG_FILENAME, DEPLOY_TOKEN, type DeployBody, type DeployBodyContext, type DeployBodyCreator, type DeployFile, type DeployInput, type Deployment, type DeploymentCreateResponse, type DeploymentDeleteResponse, type DeploymentListResponse, type DeploymentOptions, type DeploymentResource, type DeploymentResourceContext, type DeploymentSetOptions, DeploymentStatus, type DeploymentStatusType, type DeploymentUploadOptions, type DnsLookup, type DnsProvider, type DnsRecord, type DnsRecordType, type Domain, type DomainDeleteResponse, type DomainDnsResponse, type DomainListResponse, type DomainRecordsResponse, type DomainResource, type DomainSetOptions, type DomainSetResult, type DomainShareResponse, DomainStatus, type DomainStatusType, type DomainValidateResponse, type DomainVerifyResponse, type ErrorResponse, ErrorType, type ExecutionEnvironment, FileValidationStatus as FILE_VALIDATION_STATUS, type Fetch, type FileValidationResult, FileValidationStatus, type FileValidationStatusType, IDEMPOTENCY_KEY_CONSTRAINTS, JUNK_DIRECTORIES, LABEL_CONSTRAINTS, LABEL_PATTERN, type LabelsResponse, type ListOptions, type ListResponse, type MD5Result, OAuthScope, type OAuthScopeType, PASSWORD_CONSTRAINTS, type PingResponse, type PlatformLimits, type ResourceContext, type SPACheckDebug, type SPACheckRequest, type SPACheckResponse, SPA_DEFAULT_CONFIG, type SetupInstructionsResponse, Ship, type ShipClientOptions, ShipError, type ShipEvents, type StaticFile, type Token, type TokenCreateOptions, type TokenCreateResponse, type TokenDeleteResponse, TokenKind, type TokenKindType, type TokenListResponse, type TokenProvider, type TokenResource, UNBUILT_PROJECT_MARKERS, UNSAFE_FILENAME_CHARS, type UploadedFile, type UserVisibleActivityEvent, type ValidatableFile, type ValidationIssue, __setTestEnvironment, allValidFilesReady, assertShipJsonSyntax, calculateMD5, classifyToken, createAccountResource, createDeploymentResource, createDomainResource, createTokenResource, Ship as default, deserializeLabels, extractSubdomain, filterJunk, formatFileSize, generateDeploymentUrl, generateDomainUrl, getENV, getValidFiles, hasUnbuiltMarker, hasUnsafeChars, isBlockedExtension, isCustomDomain, isDeployment, isPlatformDomain, isShipError, optimizeDeployPaths, pluralize, processFilesForNode, serializeLabels, validateApiKey, validateApiUrl, validateCaller, validateDeployFile, validateDeployPath, validateDeployToken, validateFileName, validateFiles, validateIdempotencyKey, validatePassword, validateToken };
2242
+ export { API_KEY, API_PATHS, AUTH_BASE_PATH, type Account, type AccountDeleteResponse, type AccountGetResponse, type AccountKeyResponse, type AccountOverrides, AccountPlan, type AccountPlanType, type AccountResource, type AccountUsage, type Activity, type ActivityEvent, type ActivityListResponse, type ActivityMeta, type ApiDeployOptions, ApiHttp, type ApiHttpOptions, AuthMethod, type AuthMethodType, BLOCKED_EXTENSIONS, type BillingCancelResponse, type BillingStatus, CALLER, type CheckoutSession, DEFAULT_API, DEPLOYMENT_CONFIG_FILENAME, DEPLOY_TOKEN, type DeployBody, type DeployBodyContext, type DeployBodyCreator, type DeployFile, type DeployInput, type Deployment, type DeploymentCreateResponse, type DeploymentDeleteResponse, type DeploymentListResponse, type DeploymentOptions, type DeploymentResource, type DeploymentResourceContext, type DeploymentSetOptions, DeploymentStatus, type DeploymentStatusType, type DeploymentUploadOptions, type DnsLookup, type DnsProvider, type DnsRecord, type DnsRecordType, type Domain, type DomainDeleteResponse, type DomainDnsResponse, type DomainListResponse, type DomainRecordsResponse, type DomainResource, type DomainSetOptions, type DomainSetResult, type DomainShareResponse, DomainStatus, type DomainStatusType, type DomainValidateResponse, type DomainVerifyResponse, type ErrorResponse, ErrorType, type ExecutionEnvironment, FileValidationStatus as FILE_VALIDATION_STATUS, type Fetch, type FileValidationResult, FileValidationStatus, type FileValidationStatusType, IDEMPOTENCY_KEY_CONSTRAINTS, JUNK_DIRECTORIES, LABEL_CONSTRAINTS, LABEL_PATTERN, type LabelsResponse, type ListOptions, type ListResponse, type MD5Result, OAuthScope, type OAuthScopeType, PASSWORD_CONSTRAINTS, type PingResponse, type PlatformLimits, type ResourceContext, type SPACheckDebug, type SPACheckRequest, type SPACheckResponse, SPA_DEFAULT_CONFIG, type SetupInstructionsResponse, Ship, type ShipClientOptions, ShipError, type ShipEvents, type StaticFile, type Token, type TokenCreateOptions, type TokenCreateResponse, type TokenDeleteResponse, TokenKind, type TokenKindType, type TokenListResponse, type TokenProvider, type TokenResource, UNBUILT_PROJECT_MARKERS, UNSAFE_FILENAME_CHARS, type UploadedFile, type UserVisibleActivityEvent, type ValidatableFile, type ValidationIssue, __setTestEnvironment, allValidFilesReady, assertShipJsonSyntax, calculateMD5, classifyToken, createAccountResource, createDeploymentResource, createDomainResource, createTokenResource, Ship as default, deserializeLabels, extractSubdomain, filterJunk, formatFileSize, generateDeploymentUrl, generateDomainUrl, getENV, getValidFiles, hasUnbuiltMarker, hasUnsafeChars, isBlockedExtension, isCustomDomain, isDeployment, isPlatformDomain, isShipError, optimizeDeployPaths, pluralize, processFilesForNode, serializeLabels, validateApiKey, validateApiUrl, validateCaller, validateDeployFile, validateDeployPath, validateDeployToken, validateFileName, validateFiles, validateIdempotencyKey, validatePassword, validateToken };