import { HelixApi, uploadToTicket } from './api'; import { loadVendoredValidator } from './ability'; import { type BuildItemPayloadInput } from './item'; import { type AchievementCriteria, type AchievementRegistrationFields, type AchievementRegistrationInput, type AchievementUpdateInput } from './achievement'; import { type ProductGrant, type ProductRegistrationFields, type ProductRegistrationInput, type ProductUpdateInput } from './product'; import { type ItemDistributionInput, type ItemDistributionUpdateInput, type ItemEditionMode } from './distribution'; import { CliCredentials } from './config'; import { type RealizabilityDeps } from './realizability'; export { ApiError, HelixApi, uploadToTicket } from './api'; export { DEVICE_FILENAME, createDeviceProject, readDeviceGlbNodeNames, testDeviceProject, validateDeviceProject, type DeviceTestReport, type DeviceValidationReport, } from './device'; export { checkBundle, PLATFORM_THREE_VERSION, multiplayerConfigBundleFile, MULTIPLAYER_CONFIG_FILENAME, type BundleCheck, type BundleFile, } from './bundle'; export { checkPackageBundle, type PackageBundleCheck } from './package'; export { addInteractable, composeInteractableModuleManifest, composeInteractableManifest, interactableModuleId, instanceOrdinalOf, moduleInteractableFragment, namespaceInteractableFragment, parseInteractablePosition, subtractInteractableContribution, updateInteractable, type AddInteractableDeps, type AddInteractableResult, type InteractableCapsReport, type InteractableModuleContribution, type InteractablePlacementTransform, type UpdateInteractableResult, } from './interactable'; export { labelModuleValidationErrors } from './module-validation'; export { compileSceneElements } from './sceneElements/compiler'; export type { ArchitecturalElement, BoxElement, BuildingElement, CascadingElementProperties, ContainerElement, ElementMaterial, ElementStreamPolicy, GroupElement, LegacyBuildingElement, LevelElement, LightElement, PointLightElement, SceneElement, SceneElementRole, SceneElementsDocument, SlabElement, SpaceElement, SpotLightElement, WallElement, } from './sceneElements/types'; export { collectSourceFiles, createSourceArchive, formatArchiveSize, isSourceExcluded, parseGitignore, SOURCE_ARCHIVE_FILENAME, SOURCE_CONTENT_TYPE, SOURCE_HARD_EXCLUDES, SOURCE_MAX_BYTES, type IgnoreRule, type SourceArchive, type SourceEntry, } from './source-archive'; export { assertCcGenders, assertCcSlot, assertLooksLikeGlb, buildItemPayload, CC_GENDERS, CC_WEARABLE_SLOTS, CC_WEARABLE_SLOT_GROUPS, ccGendersAreAllowedForKind, ccGendersAreRequiredForKind, ccSlotIsAllowedForKind, ccSlotIsRequiredForKind, isCcGender, isCcWearableSlot, describeUploadableItemKinds, isUploadableItemKind, meshContentTypeFromExtension, meshSizeWarning, normalizeItemKind, parseJsonArrayOrFile, parseJsonObjectOrFile, parseJsonOrFile, parseGenders, parseTags, renderCcGenderList, renderCcSlotTable, thumbnailContentTypeFromExtension, UPLOADABLE_ITEM_KINDS, type BuildItemPayloadInput, type CcGender, type CcWearableSlot, type UploadableItemKind, } from './item'; export { DISTRIBUTION_KEY_PATTERN, ITEM_DISTRIBUTION_CHANNELS, ITEM_EDITION_MODES, buildItemDistribution, buildItemDistributionUpdate, editionFields, type ItemDistributionChannel, type ItemDistributionFields, type ItemDistributionInput, type ItemDistributionPatch, type ItemDistributionUpdateInput, type ItemEditionMode, } from './distribution'; export { ACHIEVEMENT_CRITERIA_METRICS, ACHIEVEMENT_CRITERIA_OPS, ACHIEVEMENT_CRITERIA_SIGNALS, ACHIEVEMENT_ICON_MAX_BYTES, ACHIEVEMENT_KEY_PATTERN, ACHIEVEMENT_TROPHY_MAX_BYTES, ACHIEVEMENT_UNLOCK_MODES, DATA_STORE_CRITERIA_KEY_TEMPLATES, buildAchievementCriteria, buildAchievementRegistration, buildAchievementUpdate, formatAchievementCriteria, iconContentTypeFromExtension, isAchievementKey, resolveUnlockMode, type AchievementCriteria, type AchievementCriteriaInput, type AchievementCriteriaMetric, type AchievementCriteriaOp, type AchievementCriteriaSignal, type AchievementRegistrationFields, type AchievementRegistrationInput, type AchievementUnlockMode, type AchievementUpdateInput, } from './achievement'; export { GRANT_CODE_MAX, GRANT_CODE_PATTERN, MAX_GRANT_CURRENCY_AMOUNT, MAX_GRANT_EFFECTS, MAX_GRANT_ITEM_QUANTITY, MAX_PASS_DURATION_SECONDS, PRODUCT_DESCRIPTION_MAX, PRODUCT_KEY_MAX, PRODUCT_KEY_PATTERN, PRODUCT_TITLE_MAX, WORLD_PRODUCT_TYPES, buildProductRegistration, buildProductUpdate, isProductKey, productTypeGrantsItem, type ProductGrant, type ProductGrantDisplay, type ProductPatch, type ProductRegistrationFields, type ProductRegistrationInput, type ProductUpdateInput, type WorldProductType, } from './product'; export { checkAbilityBundle, installLocalAbility, loadVendoredValidator, loadInstalledIndexValidator, type AbilityValidator, } from './ability'; export { normalizePinRange, resolvePins, type PinMap, type ResolveDeps, type ResolvedPackage, type ResolvedPins, type VersionDetail, type WorldPins, } from './resolve'; export { installWorld, INSTALLED_INDEX, LOCKFILE, MODULES_DIR, WORLD_MANIFEST_LOCATIONS, type InstalledEntry, type InstallDeps, type InstallWorldOptions, type InstallWorldResult, type WorldLock, } from './install'; export { assessInteractables, assessPlatformDelivery, assessThreeCurrency, assessVaultAssets, assessWeaponPins, assessWorldCurrency, ADVISORY_SYSTEMS, type CatalogClient, type InteractableFinding, type InteractableRow, type PlatformDeliveryStatus, type ThreeCurrency, type ThreeCurrencyFinding, type ThreeCurrencyRow, type VaultAssetFinding, type VaultAssetRow, type VaultResolveApi, type WeaponPinFinding, type WeaponPinRow, type WeaponPinsCurrency, type WorldCurrency, type WorldSystemFinding, type WorldSystemRow, } from './currency'; export { apiUrlMatchesEnv, credsEnvMismatchWarning, DEFAULT_API_URL, DEFAULT_WEB_URL, HELIX_ENV, HELIX_SCOPE, loadCredentials, saveCredentials, clearCredentials, jwtExpiresAtIso, type CliCredentials, } from './config'; export { browserLogin, defaultClientTokenName, type BrowserLoginResult } from './browserLogin'; export { initTemplate, slugify, type InitOptions, type InitResult, type WorldKind, } from './init'; export { initAbilityTemplate } from './initAbility'; export { checkRealizability, registryRealizabilityDeps, renderRealizabilityRefusal, TICK_NODE_CEILING, type RealizabilityDeps, type RealizabilityFailure, } from './realizability'; export { getLixBalance, listJobs, formatJobs, type JobSummary, type JobState, quoteGeneration, normalizeQuote, formatBalance, formatQuote, formatLix, formatReceipt, formatWaitState, receiptLix, roundLix, type GenerationQuote, type LixBalance, type LixHold, type QuoteComponent, } from './money'; export { verifySubPath, formatSubPathResult, DEFAULT_MOUNT_PREFIX, type SubPathFinding, type VerifySubPathOptions, type VerifySubPathResult, } from './verifySubPath'; export { approveDreamerGate, describeGateAdvance, extensionFor, formatStrandedJob, generateAndPublishAsset, generateAndPublishAssetFromReference, generateAudio, generateImage, generateStandaloneAsset, getDreamerAssetGenerationJob, getStandaloneAssetGenerationJob, getVaultAsset, getVaultAssetUsage, getVaultAssetVersions, installVaultAsset, listDreamerVoices, listMaterials, MATERIAL_RENDITION_SELECTIONS, resolveMaterial, resumeAndPublishAsset, retryDreamerJob, reviseDreamerGate, saveGeneratedAsset, StrandedJobError, searchVaultAssets, startDreamerAssetGeneration, startDreamerAssetGenerationFromReference, startStandaloneAssetGeneration, updateVaultAssetMetadata, UnavailableCapabilityError, VAULT_ASSET_KINDS, type DreamerApprovalGate, type DreamerAssetJob, type DreamerAssetKind, type DreamerAwaitingApproval, type DreamerGateOption, type DreamerJobStage, type DreamerRecovery, type DreamerRecoveryAction, type DreamerAudioMode, type DreamerAudioVoiceSettings, type DreamerCatalogVoice, type DreamerPipeline, type DreamerVoiceCatalogQuery, type DreamerVoiceCatalogResponse, type DreamerVoiceCategory, type DreamerVoiceLanguage, type GenerateAssetInput, type GenerateAssetFromReferenceInput, type GenerateAssetOptions, type GenerateAudioInput, type GenerateStandaloneAssetInput, type InstalledVaultAsset, type StandaloneGeneratedAsset, type StandaloneAssetKind, type MaterialCatalogEntry, type MaterialCatalogResult, type MaterialRenditionSelection, type MaterialMaps, type MaterialResolutionOption, type MaterialResolutionReport, type MaterialResolutionVariant, type ResolvedMaterial, DEFAULT_RESOLUTION_KEY, materialDefaultResolutionKey, materialResolutionOptions, matchMaterialResolution, type VaultAssetDetail, type VaultAssetKind, type VaultAssetSearch, type VaultAssetSummary, type VaultAssetUsage, type VaultAssetVersion, type VaultMetadataUpdate, type VaultRelatedArtifact, type VaultSelectionExplanation, } from './assets'; export type { ImportCharacterClipResult, ImportCharacterOptions, ImportCharacterResult, } from './character/importCharacter'; export type { CapturePose, CaptureScreenshotsOptions, CaptureScreenshotsResult } from './screenshot/captureScreenshots'; export type { EncodeImagePreviewResult } from './screenshot/encodeImagePreview'; export type { InspectOptions, InspectResult, InspectAttachSpec, AttachmentReadback, AttachmentPlacement, BoneReadback, MotionReadback, AxisRow, AxisRangeRow } from './gesture/inspect'; export type { CaptureGestureOptions, CaptureGestureResult } from './gesture/capture'; export type { BoneAxisReference } from './gesture/axisReference'; export type { ColliderInfo, ColliderSource, Quat, SnapshotObject, SnapshotOptions, Vec3, WorldSnapshot } from './world/snapshotTypes'; export type { AnalysisResult, Confidence, Finding, Severity } from './world/analyze'; export type { ReportSection } from './world/format'; export type { MovedObject, WorldDiff } from './world/diff'; export type { SnapshotWorldOptions } from './world/snapshotWorld'; export type { ZoneAnalysis, ZoneConfig, ZoneReport } from './world/zones'; export type { WorldMetricsTable } from './world/readWorldMetrics'; export { auditCookScope, candidateArtifactDigest, defaultIdempotencyKey, planSharedRuntimePublish, UnrealCandidateError, verifyUnrealCandidate, type BackendArtifactRole, type CandidateManifest, type CandidateRole, type CookScopeReport, type PlannedUpload, type SharedRuntimeCreateRequest, type SharedRuntimeNetworkMode, type SharedRuntimePublishPlan, type VerifiedCandidate, } from './unrealCandidate'; export { assertClientDeliveryMatchesPlan, assertCreateResponseMatchesPlan, assertReceipt, publishUnrealBuild, renderPublishFailure, resolveWorldId, uploadArtifact, type SharedRuntimeBuildReceipt, type SharedRuntimeCreateResponse, type SharedRuntimeUploadTicket, type UnrealPublishOptions, type UnrealPublishResult, } from './unrealPublish'; export { formatUnrealValidationReport, HELIX_UNREAL_CONTRACT_VERSION, HELIX_UNREAL_ENGINE_VERSION, initUnrealManifest, packageUnrealProject, validateUnrealProject, type UnrealProjectValidationReport, } from './unreal'; import type { ImportCharacterOptions, ImportCharacterResult } from './character/importCharacter'; import type { CaptureScreenshotsOptions, CaptureScreenshotsResult } from './screenshot/captureScreenshots'; import type { EncodeImagePreviewResult } from './screenshot/encodeImagePreview'; import type { InspectOptions, InspectResult } from './gesture/inspect'; import type { CaptureGestureOptions, CaptureGestureResult } from './gesture/capture'; import type { WorldSnapshot } from './world/snapshotTypes'; import type { SnapshotWorldOptions } from './world/snapshotWorld'; import type { InspectNpcOptions } from './npc/inspect'; import type { CaptureNpcOptions, CaptureNpcResult } from './npc/capture'; import type { NpcInspection } from './npc/metrics'; export declare function importCharacter(opts: ImportCharacterOptions): Promise; export declare function captureScreenshots(opts: CaptureScreenshotsOptions): Promise; export declare function encodeImagePreview(file: string, maxWidth: number): Promise; export declare function inspectGesture(opts: InspectOptions): Promise; export declare function formatGestureInspection(result: InspectResult, opts?: { motionWindow?: [number, number] | null; }): Promise; export declare function captureGesture(opts: CaptureGestureOptions): Promise; export { analyzeWorld, sortFindings } from './world/analyze'; export { formatWorldInspection, DEFAULT_REPORT } from './world/format'; export { diffWorldSnapshots, formatWorldDiff } from './world/diff'; export { analyzeZones } from './world/zones'; export { formatWorldFocus, resolveFocus } from './world/focus'; export type { FocusQuery } from './world/focus'; export { detectInspectWiring, detectNpcWiring } from './world/wiring'; export type { InspectWiring, NpcWiring } from './world/wiring'; export { canonicalizeSnapshot } from './world/canonicalize'; export { applyBaseline, buildBaseline, parseBaseline, anchorOf, BASELINE_FILENAME } from './world/baseline'; export type { BaselineEntry, BaselineResult, WorldBaseline } from './world/baseline'; export declare function snapshotWorld(opts: SnapshotWorldOptions): Promise; export declare function inspectNpc(opts: InspectNpcOptions): Promise; export declare function formatNpcInspection(result: NpcInspection): Promise; export declare function captureNpc(opts: CaptureNpcOptions): Promise; export type { InspectNpcOptions } from './npc/inspect'; export type { CaptureNpcOptions, CaptureNpcResult, NpcFrame } from './npc/capture'; export type { NpcInspection, NpcMetrics, NpcSample, StuckWindow, TargetProgress, Transition } from './npc/metrics'; export declare function readWorldMetrics(worldDir: string): Promise; export declare function renderWorldMetricsText(metrics: import('./world/readWorldMetrics').WorldMetricsTable): Promise; export declare const WORLD_METRICS_UNSUPPORTED: string; /** The bone axis table, read from a world's OWN pinned system — the engine holds the only authored copy. */ export declare function readAxisTable(worldDir: string): Promise<{ markdown: string; json: unknown; } | null>; export type PublishResult = { slug: string; title: string; buildId: string; buildNumber: number; playUrl: string | null; worldUrl: string; worldId: string; hasCustomThumbnail: boolean; thumbnailUrl: string | null; thumbnailSource: 'option' | 'bundle' | 'existing' | 'generated'; thumbnailWarning: string | null; /** What happened on the opt-in source channel. Always present; `skipped` unless the creator asked. */ source: PublishSourceOutcome; }; /** * Outcome of the opt-in source upload (CH-1457 spec §9). * * `failed` rather than a thrown error on purpose: by the time the source * channel runs, the world's build is already published and active. Throwing * would exit `helix publish` non-zero and tell a creator their publish failed * when it did not. The one failure that DOES throw is the archive itself * (too big, missing directory) — that happens before any network call, so * nothing has happened yet and refusing outright is honest. */ export type PublishSourceOutcome = { state: 'skipped'; } | { state: 'uploaded'; sizeBytes: number; fileCount: number; /** The version id the server recorded — the human-readable handle for this snapshot. */ version: string; projectId: string; } | { state: 'failed'; message: string; }; export type PublishProgress = (message: string) => void; export declare const WORLD_DESCRIPTION_MAX = 1000; export type PublishWorldOptions = { thumbnail?: string; /** * Catalog description. Sent as a separate PATCH because the manifest schema cannot carry it — * `@hypersoniclabs/helix-manifest` is `additionalProperties: false` at every version, so a * `description` key in helix.json is REJECTED by validate. The backend has had the field all * along; nothing was writing it, so every published world's catalog entry showed a title and * nothing else. Declarative support needs a helix-manifest release; this needs neither. */ description?: string; /** * Opt-in, OFF BY DEFAULT (CH-1457 spec §9.1). Also upload this project's * source, through a separate private channel, so the world can be opened and * edited on the website later. Nothing about the build upload changes; a * publish without this is byte-for-byte the publish it has always been. */ uploadSource?: boolean; /** * Directory the source archive is built from. Defaults to the PARENT of the * bundle directory, because `helix publish [directory]` points at the BUILT * bundle (`dist/`) and the source is not in there. */ sourceDir?: string; /** * Skip the pre-publish server-realizability gate. The gate refuses to publish a module-v1 world * whose declared banks the server cannot resolve; skipping it lets you publish a world that will * fail to start for every player. Off by default and deliberately awkward to reach. */ skipRealizabilityCheck?: boolean; /** Test/backend-resolver seam; ordinary callers should leave this unset. */ realizabilityDeps?: RealizabilityDeps; }; type WorldSummary = { id: string; slug: string; title: string; status: string; hasActiveBuild: boolean; }; export declare function publishWorld(root: string, creds: CliCredentials, onProgress?: PublishProgress, options?: PublishWorldOptions): Promise; /** Who may stand up a persistent server for a world (backend `ServerCreationPermission`). */ export declare const SERVER_CREATION_PERMISSIONS: readonly ["creator", "collaborators", "anyone"]; export type ServerCreationPermission = (typeof SERVER_CREATION_PERMISSIONS)[number]; /** The slice of HelixApi world creation needs — the seam the specs fake. */ export type WorldApi = { request(method: string, path: string, body?: unknown): Promise; }; export type CreateWorldOptions = { title: string; slug: string; description?: string; serverCreationPermission?: ServerCreationPermission; }; /** `created: false` means the slug was already one of yours and nothing was sent. */ export type CreateWorldResult = { id: string; slug: string; status: string; created: boolean; }; /** * Mint a world ROW without publishing a build — the identity products and * achievements register against. * * Idempotency is CLIENT-side and lookup-first, exactly as publishWorld resolves * a world: the backend 409s a duplicate slug even for its owner (its only * server-side idempotency is keyed on projectId, which the public route's * whitelisting ValidationPipe strips), so a bare re-POST is not an option. A * slug owned by someone else surfaces the backend's 409 verbatim. */ export declare function createWorld(api: WorldApi, options: CreateWorldOptions): Promise; export type WorldSourceUploadTicket = { key: string; url: string; contentType: string; cacheControl: string; projectId: string; version: string; expiresInSeconds: number; }; export type WorldSourceVersion = { versionId: string; projectId: string; key: string; version: string; sizeBytes: number; createdAt: string; }; /** * Upload one source archive against an already-published world. * * ONE byte length is computed once and sent to BOTH calls. Finalize asserts that * the stored object's size equals the declared size — the presign binds * ContentLength into the signature, so a mismatch means a different object was * finalized than was declared. Reading the length twice from two places is * exactly how that assertion starts failing for no reason. */ export declare function uploadWorldSource(api: HelixApi, worldId: string, bytes: Buffer): Promise; /** * One plain sentence for a source-channel failure — never a stack trace. * * The case this exists for: a deployment with no source bucket answers 503 with * a message naming the missing variable. That is operational information, and a * creator should read it as a sentence, not as an `✖ Service Unavailable (503)` * block stapled onto an otherwise successful publish. Pure, so every shape can * be asserted without a server. */ export declare function describeSourceFailure(err: unknown): string; /** * The website host a creator would edit this world on, for the environment the * credentials point at. Production reads `helixgame.com`, which is the string * spec §9.3 writes out; staging and helix3 read their own hosts instead of * pointing a staging creator at production. Same idiom `helix login` uses. */ export declare function editSiteHost(apiUrl: string): string; /** * The single creator-facing line about source, per spec §9.3. A FACT, printed * once — not a warning, not repeated. * * Lives here rather than in the CLI's command layer because MCP renders the * same outcome to an agent and the two must not drift; `howToEnable` is the * only part that differs (a CLI flag vs a tool argument). */ export declare function sourceOutcomeLine(outcome: PublishSourceOutcome, apiUrl: string, howToEnable?: string): string; export type WorldMediaKind = 'thumbnail' | 'preview'; export type WorldMediaDetail = { id: string; thumbnailUrl: string; hasCustomThumbnail: boolean; previewMediaUrl: string | null; }; export declare function mediaContentTypeFromExtension(file: string): string; export declare function findBundleThumbnail(root: string): string | undefined; export declare function assertMediaSizeOk(size: number, kind: WorldMediaKind): void; export declare function assertMediaSlotWritable(world: WorldMediaDetail, kind: WorldMediaKind, overwrite: boolean): void; export declare function setWorldMedia(slug: string, file: string, opts?: { kind?: WorldMediaKind; overwrite?: boolean; }): Promise; export declare function clearWorldMedia(slug: string, kind: WorldMediaKind): Promise; export type ItemVerification = { ok: boolean; warnings: string[]; rig: string | null; summary: Record; }; export type PublishItemResult = { id: string; slug: string; title: string; kind: string; slot: string | null; /** * The genders the SERVER stored, echoed back. Always an array, never null — * "no genders" has exactly one representation there and must have exactly one * here too, or a caller starts writing `genders ?? []` and a stale/rejected * value reads as a deliberate empty one. */ genders: string[]; status: string; editionMode: ItemEditionMode; collectibleSupply: number | null; creatorSerial: number | null; publishFeeLix: number; initialDistribution: ItemDistribution | null; verification: ItemVerification; }; export type ItemPublishQuote = { publishFeeLix: number; /** Moderation component; normally non-refundable after submission. */ reviewFeeLix?: number; /** Refundable component held against policy abuse. */ complianceBondLix?: number; /** Good-standing period before an approved item's bond can return. */ complianceBondReleaseDays?: number; /** Present only when the server applies an issuance allowance. */ includedCollectibleUnits?: number; /** Present only when the server applies an issuance allowance. */ chargeableCollectibleUnits?: number; /** Present only when issuance carries a separate authorization charge. */ issuanceAuthorizationFeeLix?: number; totalDueLix: number; editionMode: ItemEditionMode; collectibleSupply: number | null; creatorSerial: number | null; distribution: { channel: 'marketplace' | 'world'; priceLix: number; priceFloorLix: number; } | null; creatorRoyaltyPercent: number; sellerPlatformFeePercentByTier: { free: number; plus: number; gold: number; diamond: number; }; buyerSurchargePercent: 0; selfPurchaseAllowed: false; resaleCooldownHours: number; payoutHoldBaseDays: number; payoutHoldMaxDays: number; resaleEligibility: { basic: 'email'; verified: 'unique_mobile_and_good_standing'; identityVerified: 'reserved_high_risk'; businessVerifiedSupported: boolean; }; }; /** Everything `publishItem` needs, and everything `--dry-run` can check offline. */ export type PublishItemOptions = BuildItemPayloadInput & { /** Path to the .glb. */ mesh: string; /** Optional thumbnail image; the server renders one when omitted (required for avatars). */ thumbnail?: string; }; export type ItemFilePart = { file: string; contentType: string; sizeBytes: number; }; /** What `publishItem` is about to send. Produced without touching the network. */ export type ItemPublishPlan = { endpoint: string; payload: Record; mesh: ItemFilePart; thumbnail: ItemFilePart | null; warnings: string[]; meshBytes: Buffer; thumbnailBytes: Buffer | null; }; export declare const ITEM_UPLOAD_PATH = "/api/v1/universal-items/upload"; export declare const ITEM_PUBLISH_QUOTE_PATH = "/api/v1/universal-items/publish-quote"; /** * Validate + read everything the upload needs, with NO network access — the * whole of `--dry-run`, and the first half of a real publish, so a dry run * exercises the code path it is predicting rather than a parallel one. */ export declare function planItemPublish(opts: PublishItemOptions): ItemPublishPlan; /** The slice of HelixApi the item upload needs — the seam the specs fake. */ export type ItemPublishApi = { postMultipart(path: string, form: FormData): Promise; request?(method: string, path: string, body?: unknown): Promise; }; /** Server-owned fee/allowance/floor quote. No upload or charge occurs. */ export declare function quoteItemPublish(opts: PublishItemOptions, creds: CliCredentials, deps?: { api?: ItemPublishApi; }): Promise; /** * Publish a universal item from a local mesh: validate locally → multipart POST * → return the created item plus the server's inline verification verdict. * Throws ApiError (render()-able) on any server rejection. */ export declare function publishItem(opts: PublishItemOptions, creds: CliCredentials, deps?: { api?: ItemPublishApi; onProgress?: PublishProgress; }): Promise; /** The slice of a delisted item's response this command reads. */ export type DelistedItem = { id: string; slug: string; title: string; status: string; }; /** The slice of HelixApi `delistItem` needs — the seam the specs fake. */ export type ItemDelistApi = { requestItem(method: string, path: string, body?: unknown): Promise; }; /** * Delist a published universal item you own (CH-1671). Existing owners keep * what they own; the item stops appearing on browse/marketplace and can no * longer be newly acquired. This does NOT delete anything — `helix item * publish` never made a delete path safe once anyone (including your own * auto-granted copy) owns an instance, and delist is the actual way out. * Only legal from a currently-published item; the server rejects a draft or * an already-delisted one with a clear error (surfaced as ApiError). */ export declare function delistItem(itemId: string, creds: CliCredentials, opts?: { reason?: string; }, deps?: { api?: ItemDelistApi; }): Promise; export declare const achievementsWorldPath: (worldId: string) => string; /** The subset of the backend's AchievementResponse these commands read. */ export type Achievement = { id: string; itemId: string; worldId: string | null; key: string; name: string; description: string | null; hidden: boolean; points: number; active: boolean; unlockMode: string; criteria: AchievementCriteria | null; iconUrl: string | null; meshUrl: string | null; hasCustomTrophy: boolean; earnedCount: number; earnPct: number | null; rarityTier: string; unranked: boolean; createdAt: string; }; export type AchievementFilePart = { file: string; contentType: string; sizeBytes: number; }; export type AchievementRegistrationPlan = { worldSlug: string; fields: AchievementRegistrationFields; icon: AchievementFilePart; trophy: AchievementFilePart | null; warnings: string[]; iconBytes: Buffer; trophyBytes: Buffer | null; }; export type RegisterAchievementOptions = AchievementRegistrationInput & { worldSlug: string; /** The 2D badge graphic. REQUIRED — the backend refuses an achievement without one. */ icon: string; /** Optional bespoke GLB trophy; omitted, the backend bakes the icon onto the default plaque. */ trophy?: string; }; /** * Everything `--dry-run` checks: the field rules, both files read and sniffed, * and the icon proven to be a real, non-blank graphic. No network and no login, * so an agent can verify a registration before asking a human to sign in. */ export declare function planAchievementRegistration(opts: RegisterAchievementOptions): Promise; /** The slice of HelixApi the achievement flows need — the seam the specs fake. */ export type AchievementApi = { request(method: string, path: string, body?: unknown): Promise; requestItem(method: string, path: string, body?: unknown): Promise; sendMultipart(method: string, path: string, form: FormData): Promise; }; /** * Register (and mint the soulbound item for) a world achievement. Validate * locally → resolve the slug → one multipart POST. Throws ApiError * (render()-able) on any server rejection — a duplicate key included. */ export declare function registerAchievement(opts: RegisterAchievementOptions, creds: CliCredentials, deps?: { api?: AchievementApi; onProgress?: PublishProgress; }): Promise<{ achievement: Achievement; warnings: string[]; }>; /** Every achievement registered to a world, newest rollup data included. */ export declare function listAchievements(worldSlug: string, creds: CliCredentials, deps?: { api?: AchievementApi; }): Promise; /** * Patch a registered achievement. `key`, `unlockMode` and `criteria` are NOT * patchable by design — a key is the identifier rules name, and re-declaring * how a badge is earned would silently re-label every copy already granted. */ export declare function updateAchievement(worldSlug: string, key: string, patch: AchievementUpdateInput, creds: CliCredentials, deps?: { api?: AchievementApi; }): Promise; /** * Replace the 2D graphic. This endpoint exists because creators were driving the * generic universal-items presign route instead, which SUSPENDS the achievement; * it also re-bakes the default plaque, so the change reaches the 3D badge too. */ export declare function setAchievementIcon(worldSlug: string, key: string, file: string, creds: CliCredentials, deps?: { api?: AchievementApi; }): Promise; export declare const ITEM_DISTRIBUTIONS_PATH = "/api/v1/item-distributions"; export declare const ITEM_DISTRIBUTIONS_CREATOR_PATH = "/api/v1/item-distributions/creator"; export type ItemDistribution = { id: string; itemId: string; issuerId: string; channel: 'marketplace' | 'world'; worldId: string | null; worldSlug?: string | null; key: string | null; priceLix: number; isFree: boolean; active: boolean; maxPerPlayer: number | null; maxClaims: number | null; startsAt: string | null; endsAt: string | null; createdAt: string; updatedAt: string; }; export type DistributionApi = { request(method: string, path: string, body?: unknown): Promise; }; export type CreateItemDistributionOptions = Omit & { itemId: string; }; /** Resolve an optional creator world slug, then create one canonical route. */ export declare function createItemDistribution(options: CreateItemDistributionOptions, creds: CliCredentials, deps?: { api?: DistributionApi; onProgress?: PublishProgress; }): Promise; export declare function listItemDistributions(itemId: string, creds: CliCredentials, deps?: { api?: DistributionApi; }): Promise; export declare function updateItemDistribution(distributionId: string, input: ItemDistributionUpdateInput, creds: CliCredentials, deps?: { api?: DistributionApi; }): Promise; export declare function disableItemDistribution(distributionId: string, creds: CliCredentials, deps?: { api?: DistributionApi; }): Promise; export declare const PRODUCTS_PATH = "/api/v1/iwp/products"; export declare const CREATOR_WORLDS_PATH = "/api/v1/iwp/creator/worlds"; export declare const productsWorldPath: (worldId: string) => string; /** The backend's product DTO (`toProductDtoShape`) — `name` is an alias of `title`. */ export type WorldProduct = { id: string; key: string | null; worldId: string; worldSlug: string | null; worldTitle: string | null; worldDetailPath: string | null; name: string; title: string; description: string | null; priceLix: number; isFree: boolean; type: string; itemId: string | null; /** The authored effect list; null on a legacy product, whose effects derive from type/itemId. */ grants: ProductGrant[] | null; maxPerUser: number | null; active: boolean; createdAt: string; updatedAt: string; }; /** A Published world plus its registry — what the creator-worlds route returns. */ export type ProductWorld = { id: string; slug: string; title: string; description: string | null; status: string; detailPath: string | null; products: WorldProduct[]; }; export type RegisterProductOptions = ProductRegistrationInput & { worldSlug: string; }; export type ProductRegistrationPlan = { worldSlug: string; fields: ProductRegistrationFields; warnings: string[]; }; /** * Everything `--dry-run` checks: the field rules and the type/item coherence. * No network and no login, so an agent can verify a registration before asking * a human to sign in. */ export declare function planProductRegistration(opts: RegisterProductOptions): ProductRegistrationPlan; /** The slice of HelixApi the product flows need — the seam the specs fake. */ export type ProductApi = { request(method: string, path: string, body?: unknown): Promise; }; /** * Register a purchasable product on a world: validate locally → resolve the slug * → one JSON POST. Throws ApiError (render()-able) on any server rejection — a * duplicate key, an unpublished linked item, or a non-owned world included. */ export declare function registerProduct(opts: RegisterProductOptions, creds: CliCredentials, deps?: { api?: ProductApi; onProgress?: PublishProgress; }): Promise<{ product: WorldProduct; warnings: string[]; }>; /** Every product registered to a world, active or not. */ export declare function listProducts(worldSlug: string, creds: CliCredentials, deps?: { api?: ProductApi; }): Promise; /** Every PUBLISHED world of the caller's with its registry — the "where can I sell?" view. */ export declare function listProductWorlds(creds: CliCredentials, deps?: { api?: ProductApi; }): Promise; /** * Patch a registered product. `key` and `type` are NOT patchable by design — a * key is what world code buys (`pkey:`), and changing what a purchase * hands over would re-label every copy already sold. */ export declare function updateProduct(worldSlug: string, ref: string, patch: ProductUpdateInput, creds: CliCredentials, deps?: { api?: ProductApi; }): Promise; /** * Take a product off sale (or put it back). Deactivating is the only way to * retire one: the row stays, so past purchases and their grants still resolve. */ export declare function setProductActive(worldSlug: string, ref: string, active: boolean, creds: CliCredentials, deps?: { api?: ProductApi; }): Promise; export type PublishPackageResult = { kind: string; slug: string; version: string; revision: number; codeBaseUrl: string; assetBaseUrl: string | null; checksumSha256: string | null; }; export type PackagePublishApi = Pick; export type PublishPackageDeps = { api?: PackagePublishApi; validator?: Awaited>; upload?: typeof uploadToTicket; }; export declare function publishPackage(root: string, creds: CliCredentials, onProgress?: PublishProgress, deps?: PublishPackageDeps): Promise; export type PublishInteractableResult = PublishPackageResult & { item: { id: string; slug: string; title: string; }; distribution: { id: string; priceLix: string; active: boolean; }; bundle: { kind: 'interactable-bundle'; id: string; version: string; checksumSha256: string; }; }; export declare function publishInteractable(root: string, creds: CliCredentials, onProgress?: PublishProgress, deps?: PublishPackageDeps & { publishPackage?: typeof publishPackage; }): Promise; export type CatalogPackage = { kind: string; slug: string; title: string; description: string | null; latestVersion: string | null; targetSystem: { id: string; range: string | null; } | null; }; export type CatalogList = { data: CatalogPackage[]; pageInfo: { hasNextPage: boolean; nextCursor: string | null; }; }; export declare function listPackages(apiUrl: string, kind?: string, system?: string): Promise; export declare function getPackageManifest(apiUrl: string, slug: string, version?: string): Promise>; export declare function authStatus(): { loggedIn: boolean; username?: string; apiUrl?: string; expiresAt?: string; }; export type WhoAmI = { id: string; username: string; }; export declare function whoAmI(api: HelixApi): Promise; export declare function listMyWorlds(creds: CliCredentials): Promise; export type PreviewVideoResult = { slug: string; title: string; previewYoutubeId: string | null; previewYoutubeUrl: string | null; }; /** * Set a world's preview video from a YouTube link. * * Video is REFERENCED, not uploaded: the world detail carousel embeds it via * youtube-nocookie, and YouTube handles transcoding, streaming and moderation. * There is deliberately no way to upload an mp4 — the preview slot takes images * only, and video files were removed from it precisely because nothing could * play them. * * The URL is normalised SERVER-side to an 11-char video id (watch?v=, youtu.be, * /embed/, /shorts/, /live/, or a bare id all resolve; anything non-YouTube is * rejected). We deliberately do not re-implement that check here: one authority * for "what is a valid YouTube link" means the CLI cannot drift from the API, * and the API is the one that matters — its output ends up in an iframe src. */ export declare function setWorldPreviewVideo(slug: string, url: string, creds: CliCredentials): Promise; /** Remove a world's preview video. Idempotent — clearing an unset slot is fine. */ export declare function clearWorldPreviewVideo(slug: string, creds: CliCredentials): Promise; export declare const TOOLCHAIN_PACKAGES: string[]; export type ToolchainStatus = { name: string; installed: string | null; latest: string | null; status: 'current' | 'update-available' | 'unknown'; updateHint: string; }; export declare function compareVersions(a: string, b: string): number; export declare function cliVersion(): string; export declare function latestOnNpm(name: string, opts?: { timeoutMs?: number; }): Promise; export declare function installHint(slot: string, scope: string): string; export declare function checkForUpdates(opts?: { projectDir?: string; installed?: Record; scope?: string; }): Promise;