Files
zeekay 062741569f Serve every route under /v1
The API mounted its routers at /api/auth and /api/v1/*; one /v1 app now
holds them all and nothing answers under /api. The web client, OG
fetchers, CLI route table and its tests follow. IAM is reached at the
/v1/iam/oauth endpoints its discovery document names; the old
/api/userinfo and /api/login/oauth/access_token paths answer hanzo.id's
SPA, so sign-in could not complete.

v1-prefix.test.ts fails if an /api path is served or called again.

Claude-Session: https://claude.ai/code/session_01TUxvfuta1Z44KVNYuAz71F
2026-09-24 15:05:07 -07:00

257 lines
6.6 KiB
JavaScript

import { type } from 'arktype';
export const GlobalConfigSchema = type({
registry: 'string',
token: 'string?',
});
export const WellKnownConfigSchema = type({
apiBase: 'string',
authBase: 'string?',
minCliVersion: 'string?',
}).or({
registry: 'string',
authBase: 'string?',
minCliVersion: 'string?',
});
export const LockfileSchema = type({
version: '1',
skills: {
'[string]': {
version: 'string|null',
installedAt: 'number',
},
},
});
export const ApiCliWhoamiResponseSchema = type({
user: {
handle: 'string|null',
},
});
export const ApiSearchResponseSchema = type({
results: type({
slug: 'string?',
displayName: 'string?',
version: 'string|null?',
score: 'number',
}).array(),
});
export const ApiSkillMetaResponseSchema = type({
latestVersion: type({
version: 'string',
}).optional(),
skill: 'unknown|null?',
});
export const ApiCliUploadUrlResponseSchema = type({
uploadUrl: 'string',
});
export const ApiUploadFileResponseSchema = type({
storageId: 'string',
});
export const CliPublishFileSchema = type({
path: 'string',
size: 'number',
storageId: 'string',
sha256: 'string',
contentType: 'string?',
});
export const PublishSourceSchema = type({
kind: '"github"',
url: 'string',
repo: 'string',
ref: 'string',
commit: 'string',
path: 'string',
importedAt: 'number',
});
export const CliPublishRequestSchema = type({
slug: 'string',
displayName: 'string',
version: 'string',
changelog: 'string',
tags: 'string[]?',
source: PublishSourceSchema.optional(),
forkOf: type({
slug: 'string',
version: 'string?',
}).optional(),
files: CliPublishFileSchema.array(),
});
export const ApiCliPublishResponseSchema = type({
ok: 'true',
skillId: 'string',
versionId: 'string',
});
export const CliSkillDeleteRequestSchema = type({
slug: 'string',
});
export const ApiCliSkillDeleteResponseSchema = type({
ok: 'true',
});
export const ApiSkillResolveResponseSchema = type({
match: type({ version: 'string' }).or('null'),
latestVersion: type({ version: 'string' }).or('null'),
});
export const CliTelemetrySyncRequestSchema = type({
roots: type({
rootId: 'string',
label: 'string',
skills: type({
slug: 'string',
version: 'string|null?',
}).array(),
}).array(),
});
export const ApiCliTelemetrySyncResponseSchema = type({
ok: 'true',
});
export const ApiV1WhoamiResponseSchema = type({
user: {
handle: 'string|null',
displayName: 'string|null?',
image: 'string|null?',
},
});
export const ApiV1UserSearchResponseSchema = type({
items: type({
userId: 'string',
handle: 'string|null',
displayName: 'string|null?',
name: 'string|null?',
role: '"admin"|"moderator"|"user"|null?',
}).array(),
total: 'number',
});
export const ApiV1SearchResponseSchema = type({
results: type({
slug: 'string?',
displayName: 'string?',
summary: 'string|null?',
version: 'string|null?',
score: 'number',
updatedAt: 'number?',
}).array(),
});
export const ApiV1SkillListResponseSchema = type({
items: type({
slug: 'string',
displayName: 'string',
summary: 'string|null?',
tags: 'unknown',
stats: 'unknown',
createdAt: 'number',
updatedAt: 'number',
latestVersion: type({
version: 'string',
createdAt: 'number',
changelog: 'string',
}).optional(),
}).array(),
nextCursor: 'string|null',
});
export const ApiV1SkillResponseSchema = type({
skill: type({
slug: 'string',
displayName: 'string',
summary: 'string|null?',
tags: 'unknown',
stats: 'unknown',
createdAt: 'number',
updatedAt: 'number',
}).or('null'),
latestVersion: type({
version: 'string',
createdAt: 'number',
changelog: 'string',
}).or('null'),
owner: type({
handle: 'string|null',
displayName: 'string|null?',
image: 'string|null?',
}).or('null'),
});
export const ApiV1SkillVersionListResponseSchema = type({
items: type({
version: 'string',
createdAt: 'number',
changelog: 'string',
changelogSource: '"auto"|"user"|null?',
}).array(),
nextCursor: 'string|null',
});
export const ApiV1SkillVersionResponseSchema = type({
version: type({
version: 'string',
createdAt: 'number',
changelog: 'string',
changelogSource: '"auto"|"user"|null?',
files: 'unknown?',
}).or('null'),
skill: type({
slug: 'string',
displayName: 'string',
}).or('null'),
});
export const ApiV1SkillResolveResponseSchema = type({
match: type({ version: 'string' }).or('null'),
latestVersion: type({ version: 'string' }).or('null'),
});
export const ApiV1PublishResponseSchema = type({
ok: 'true',
skillId: 'string',
versionId: 'string',
});
export const ApiV1DeleteResponseSchema = type({
ok: 'true',
});
export const ApiV1SetRoleResponseSchema = type({
ok: 'true',
role: '"admin"|"moderator"|"user"',
});
export const ApiV1StarResponseSchema = type({
ok: 'true',
starred: 'boolean',
alreadyStarred: 'boolean',
});
export const ApiV1UnstarResponseSchema = type({
ok: 'true',
unstarred: 'boolean',
alreadyUnstarred: 'boolean',
});
export const SkillInstallSpecSchema = type({
id: 'string?',
kind: '"brew"|"node"|"go"|"uv"',
label: 'string?',
bins: 'string[]?',
formula: 'string?',
tap: 'string?',
package: 'string?',
module: 'string?',
});
export const NixPluginSpecSchema = type({
plugin: 'string',
systems: 'string[]?',
});
export const ClawdbotConfigSpecSchema = type({
requiredEnv: 'string[]?',
stateDirs: 'string[]?',
example: 'string?',
});
export const ClawdisRequiresSchema = type({
bins: 'string[]?',
anyBins: 'string[]?',
env: 'string[]?',
config: 'string[]?',
});
export const ClawdisSkillMetadataSchema = type({
always: 'boolean?',
skillKey: 'string?',
primaryEnv: 'string?',
emoji: 'string?',
homepage: 'string?',
os: 'string[]?',
cliHelp: 'string?',
requires: ClawdisRequiresSchema.optional(),
install: SkillInstallSpecSchema.array().optional(),
nix: NixPluginSpecSchema.optional(),
config: ClawdbotConfigSpecSchema.optional(),
});
//# sourceMappingURL=schemas.js.map