opctl 0.1.6 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -4
- package/dist/cli.js +640 -62
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","names":[],"sources":["../src/client/auth.ts","../src/client/errors.ts","../src/output/json.ts","../src/client/hal.ts","../src/output/text.ts","../src/client/pagination.ts","../src/client/openProjectClient.ts","../src/config/envFile.ts","../src/config/profiles.ts","../src/config.ts","../src/commands/context.ts","../src/commands/apiRoot.ts","../src/commands/me.ts","../src/output/table.ts","../src/commands/projects.ts","../scripts/pull-openapi-spec.ts","../src/commands/spec.ts","../src/output/fields.ts","../src/commands/workPackages.ts","../src/commands/profile.ts","../package.json","../src/cli.ts"],"sourcesContent":["import type { AuthMode } from \"../config.js\";\n\nexport function createAuthorizationHeader(mode: AuthMode, token: string): string {\n if (mode === \"basic\") {\n return `Basic ${Buffer.from(`apikey:${token}`, \"utf8\").toString(\"base64\")}`;\n }\n return `Bearer ${token}`;\n}\n\nexport function redactSecrets(value: string, token?: string): string {\n let redacted = value.replace(/Authorization:\\s*(Bearer|Basic)\\s+[^\\s,}]+/gi, \"Authorization: <redacted>\");\n redacted = redacted.replace(/\"Authorization\"\\s*:\\s*\"[^\"]+\"/gi, '\"Authorization\":\"<redacted>\"');\n if (token && token !== \"\") redacted = redacted.split(token).join(\"<redacted>\");\n return redacted;\n}\n","export const EXIT_CODES = {\n success: 0,\n general: 1,\n config: 2,\n auth: 3,\n notFound: 4,\n validation: 5,\n writeBlocked: 6,\n network: 7,\n openapi: 8,\n} as const;\n\nexport type ExitCode = (typeof EXIT_CODES)[keyof typeof EXIT_CODES];\n\nexport class OpctlError extends Error {\n public readonly exitCode: ExitCode;\n public readonly details: unknown;\n\n public constructor(message: string, exitCode: ExitCode = EXIT_CODES.general, details?: unknown) {\n super(message);\n this.name = \"OpctlError\";\n this.exitCode = exitCode;\n this.details = details;\n }\n}\n\nexport class ConfigurationError extends OpctlError {\n public constructor(message: string) {\n super(message, EXIT_CODES.config);\n this.name = \"ConfigurationError\";\n }\n}\n\nexport class WriteBlockedError extends OpctlError {\n public constructor() {\n super(\"OpenProject write blocked: set OPENPROJECT_ALLOW_WRITE=1 to enable write commands\", EXIT_CODES.writeBlocked);\n this.name = \"WriteBlockedError\";\n }\n}\n\nexport class NetworkError extends OpctlError {\n public constructor(message: string) {\n super(message, EXIT_CODES.network);\n this.name = \"NetworkError\";\n }\n}\n\nexport class OpenApiGenerationError extends OpctlError {\n public constructor(message: string) {\n super(message, EXIT_CODES.openapi);\n this.name = \"OpenApiGenerationError\";\n }\n}\n\nexport class OpenProjectHttpError extends OpctlError {\n public readonly status: number;\n public readonly responseBody: unknown;\n\n public constructor(status: number, responseBody: unknown) {\n super(httpStatusMessage(status, responseBody), exitCodeForStatus(status), responseBody);\n this.name = \"OpenProjectHttpError\";\n this.status = status;\n this.responseBody = responseBody;\n }\n}\n\nexport function exitCodeForStatus(status: number): ExitCode {\n if (status === 401 || status === 403) return EXIT_CODES.auth;\n if (status === 404) return EXIT_CODES.notFound;\n if (status === 422) return EXIT_CODES.validation;\n return EXIT_CODES.general;\n}\n\nexport function httpStatusMessage(status: number, body: unknown): string {\n if (status === 401) return \"authentication failed\";\n if (status === 403) return \"authenticated OpenProject user lacks permission\";\n if (status === 404) return \"resource not found or not visible to this user\";\n if (status === 409) return \"possible stale lockVersion or concurrent modification\";\n if (status === 422) return `validation failed${validationDetail(body)}`;\n return `OpenProject request failed with HTTP ${status}`;\n}\n\nfunction validationDetail(body: unknown): string {\n if (!body || typeof body !== \"object\") return \"\";\n const message = \"message\" in body && typeof body.message === \"string\" ? body.message : undefined;\n const errorIdentifier = \"errorIdentifier\" in body && typeof body.errorIdentifier === \"string\" ? body.errorIdentifier : undefined;\n const errors = \"_embedded\" in body ? body._embedded : undefined;\n const parts = [message, errorIdentifier, typeof errors === \"object\" && errors !== null ? JSON.stringify(errors) : undefined].filter(Boolean);\n return parts.length === 0 ? \"\" : `: ${parts.join(\"; \")}`;\n}\n\nexport function toOpctlError(error: unknown): OpctlError {\n if (error instanceof OpctlError) return error;\n if (error instanceof Error) return new OpctlError(error.message);\n return new OpctlError(\"unexpected failure\");\n}\n","import { redactSecrets } from \"../client/auth.js\";\n\nexport function stableJson(value: unknown, token?: string): string {\n return `${redactSecrets(JSON.stringify(sortForJson(value), null, 2), token)}\\n`;\n}\n\nfunction sortForJson(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(sortForJson);\n if (!value || typeof value !== \"object\") return value;\n const sorted: Record<string, unknown> = {};\n for (const key of Object.keys(value).sort()) sorted[key] = sortForJson((value as Record<string, unknown>)[key]);\n return sorted;\n}\n","import type { LinkSummary, ProjectSummary, UserSummary, WorkPackageDetail, WorkPackageSummary } from \"../types/domain.js\";\n\ntype HalObject = Record<string, unknown>;\n\nexport function asObject(value: unknown): HalObject | undefined {\n return value && typeof value === \"object\" ? (value as HalObject) : undefined;\n}\n\nexport function getLink(resource: unknown, name: string): LinkSummary | undefined {\n const object = asObject(resource);\n const links = asObject(object?._links);\n const raw = links?.[name];\n const link = Array.isArray(raw) ? asObject(raw[0]) : asObject(raw);\n if (!link) return undefined;\n const href = typeof link.href === \"string\" ? link.href : undefined;\n const title = typeof link.title === \"string\" ? link.title : undefined;\n const method = typeof link.method === \"string\" ? link.method : undefined;\n if (!href && !title && !method) return undefined;\n return { ...(href ? { href } : {}), ...(title ? { title } : {}), ...(method ? { method } : {}) };\n}\n\nexport function requireLinkHref(resource: unknown, name: string): string | undefined {\n return getLink(resource, name)?.href;\n}\n\nexport function collectionElements(resource: unknown): unknown[] {\n const embedded = asObject(asObject(resource)?._embedded);\n const elements = embedded?.elements;\n return Array.isArray(elements) ? elements : [];\n}\n\nexport function collectionTotal(resource: unknown): number | undefined {\n const total = asObject(resource)?.total;\n return typeof total === \"number\" ? total : undefined;\n}\n\nexport function normalizeUser(resource: unknown): UserSummary {\n const object = asObject(resource) ?? {};\n return {\n id: numberField(object.id),\n name: stringField(object.name),\n login: stringField(object.login),\n email: stringField(object.email),\n href: getLink(object, \"self\")?.href,\n };\n}\n\nexport function normalizeProject(resource: unknown): ProjectSummary {\n const object = asObject(resource) ?? {};\n return {\n id: numberField(object.id),\n identifier: stringField(object.identifier),\n name: stringField(object.name),\n href: getLink(object, \"self\")?.href,\n };\n}\n\nexport function normalizeWorkPackageSummary(resource: unknown): WorkPackageSummary {\n const object = asObject(resource) ?? {};\n return {\n id: numberField(object.id),\n subject: stringField(object.subject),\n status: getLink(object, \"status\")?.title,\n assignee: getLink(object, \"assignee\")?.title,\n project: getLink(object, \"project\")?.title,\n type: getLink(object, \"type\")?.title,\n href: getLink(object, \"self\")?.href,\n updatedAt: stringField(object.updatedAt),\n shortDescription: shortDescription(extractDescription(object.description)),\n attachmentsCount: attachmentsCount(object),\n };\n}\n\nexport function normalizeWorkPackageDetail(resource: unknown): WorkPackageDetail {\n const object = asObject(resource) ?? {};\n return {\n ...normalizeWorkPackageSummary(object),\n description: extractDescription(object.description),\n shortDescription: shortDescription(extractDescription(object.description)),\n attachmentsCount: attachmentsCount(object),\n lockVersion: numberField(object.lockVersion),\n actions: actionLinks(object),\n };\n}\n\nexport function actionLinks(resource: unknown): Record<string, LinkSummary> {\n const links = asObject(asObject(resource)?._links) ?? {};\n const actions: Record<string, LinkSummary> = {};\n for (const [name, value] of Object.entries(links)) {\n const link = Array.isArray(value) ? asObject(value[0]) : asObject(value);\n if (!link) continue;\n const method = typeof link.method === \"string\" ? link.method : undefined;\n if (!method && !name.startsWith(\"add\") && !name.includes(\"update\") && !name.includes(\"delete\")) continue;\n const summary = getLink(resource, name);\n if (summary) actions[name] = summary;\n }\n return actions;\n}\n\nexport function extractDescription(value: unknown): string | undefined {\n if (typeof value === \"string\") return value;\n const object = asObject(value);\n const raw = typeof object?.raw === \"string\" ? object.raw : undefined;\n const html = typeof object?.html === \"string\" ? object.html : undefined;\n return raw ?? (html ? html.replace(/<[^>]+>/g, \" \").replace(/\\s+/g, \" \").trim() : undefined);\n}\n\nfunction shortDescription(description: string | undefined): string | undefined {\n if (!description) return undefined;\n const compact = description.replace(/\\s+/g, \" \").trim();\n if (compact === \"\") return undefined;\n return compact.length <= 160 ? compact : `${compact.slice(0, 157)}...`;\n}\n\nfunction attachmentsCount(resource: HalObject): number | undefined {\n const embeddedAttachments = asObject(asObject(resource._embedded)?.attachments);\n const total = numberField(embeddedAttachments?.total) ?? numberField(embeddedAttachments?.count);\n if (total !== undefined) return total;\n const elements = embeddedAttachments?.elements;\n if (Array.isArray(elements)) return elements.length;\n const direct = asObject(resource.attachments);\n const directTotal = numberField(direct?.total) ?? numberField(direct?.count);\n if (directTotal !== undefined) return directTotal;\n const directElements = direct?.elements;\n if (Array.isArray(directElements)) return directElements.length;\n return undefined;\n}\n\nfunction stringField(value: unknown): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction numberField(value: unknown): number | undefined {\n return typeof value === \"number\" ? value : undefined;\n}\n","export function renderKeyValue(value: Record<string, unknown>): string {\n return `${Object.entries(value)\n .filter(([, item]) => item !== undefined)\n .map(([key, item]) => `${key}: ${String(item)}`)\n .join(\"\\n\")}\\n`;\n}\n","import { collectionElements, collectionTotal } from \"./hal.js\";\n\nexport interface PageOptions {\n readonly pageSize?: number;\n}\n\nexport interface NormalizedCollection<T> {\n readonly elements: readonly T[];\n readonly total?: number;\n readonly count: number;\n}\n\nexport function normalizePageSize(value: unknown, fallback = 25): number {\n if (value === undefined || value === null || value === \"\") return fallback;\n const parsed = typeof value === \"number\" ? value : Number(value);\n if (!Number.isInteger(parsed) || parsed < 1 || parsed > 100) throw new Error(\"page size must be an integer between 1 and 100\");\n return parsed;\n}\n\nexport function normalizeCollection<T>(resource: unknown, mapper: (value: unknown) => T): NormalizedCollection<T> {\n const elements = collectionElements(resource).map(mapper);\n const total = collectionTotal(resource);\n return { elements, ...(total === undefined ? {} : { total }), count: elements.length };\n}\n","import createClient, { type Client } from \"openapi-fetch\";\nimport { createAuthorizationHeader } from \"./auth.js\";\nimport { OpenProjectHttpError, NetworkError, WriteBlockedError, OpctlError, EXIT_CODES } from \"./errors.js\";\nimport { normalizeCollection, normalizePageSize, type NormalizedCollection } from \"./pagination.js\";\nimport { getLink, normalizeProject, normalizeUser, normalizeWorkPackageDetail, normalizeWorkPackageSummary, requireLinkHref } from \"./hal.js\";\nimport type { OpctlConfig } from \"../config.js\";\nimport type { paths } from \"../generated/openproject.js\";\nimport type { CommentResult, ProjectSummary, UserSummary, WorkPackageDetail, WorkPackageSummary } from \"../types/domain.js\";\n\nexport interface SearchWorkPackagesOptions {\n readonly project?: string;\n readonly subject?: string;\n readonly assigneeMe?: boolean;\n readonly status?: string;\n readonly open?: boolean;\n readonly pageSize?: number;\n}\n\nexport interface OpenProjectClientOptions {\n readonly config: OpctlConfig;\n readonly fetchImpl?: typeof fetch;\n readonly timeoutMs?: number;\n}\n\nexport class OpenProjectClient {\n private readonly config: OpctlConfig;\n private readonly fetchImpl: typeof fetch;\n private readonly timeoutMs: number;\n private readonly typedClient: Client<paths>;\n\n public constructor(options: OpenProjectClientOptions) {\n this.config = options.config;\n this.fetchImpl = options.fetchImpl ?? fetch;\n this.timeoutMs = options.timeoutMs ?? 30_000;\n this.typedClient = createClient<paths>({ baseUrl: `${this.config.baseUrl}/api/v3` });\n void this.typedClient;\n }\n\n public async getApiRoot(): Promise<unknown> {\n return this.request(\"GET\", \"/api/v3\");\n }\n\n public async getMe(): Promise<UserSummary> {\n return normalizeUser(await this.request(\"GET\", \"/api/v3/users/me\"));\n }\n\n public async listProjects(options: { readonly pageSize?: number } = {}): Promise<NormalizedCollection<ProjectSummary>> {\n const params = new URLSearchParams({ pageSize: String(normalizePageSize(options.pageSize)) });\n return normalizeCollection(await this.request(\"GET\", `/api/v3/projects?${params}`), normalizeProject);\n }\n\n public async getWorkPackageRaw(id: number): Promise<unknown> {\n return this.request(\"GET\", `/api/v3/work_packages/${encodeURIComponent(String(id))}`);\n }\n\n public async getWorkPackage(id: number): Promise<WorkPackageDetail> {\n return normalizeWorkPackageDetail(await this.getWorkPackageRaw(id));\n }\n\n public async searchWorkPackages(options: SearchWorkPackagesOptions): Promise<NormalizedCollection<WorkPackageSummary>> {\n const effectiveProject = options.project ?? this.config.defaultProject;\n const basePath = effectiveProject\n ? `/api/v3/projects/${encodeURIComponent(effectiveProject)}/work_packages`\n : \"/api/v3/work_packages\";\n const params = new URLSearchParams({ pageSize: String(normalizePageSize(options.pageSize)) });\n const filters = buildWorkPackageFilters(options);\n if (filters.length > 0) params.set(\"filters\", JSON.stringify(filters));\n return normalizeCollection(await this.request(\"GET\", `${basePath}?${params}`), normalizeWorkPackageSummary);\n }\n\n public async mine(options: Omit<SearchWorkPackagesOptions, \"assigneeMe\" | \"open\">): Promise<NormalizedCollection<WorkPackageSummary>> {\n await this.getMe();\n return this.searchWorkPackages({ ...options, assigneeMe: true, open: true });\n }\n\n public async commentWorkPackage(id: number, message: string, dryRun: boolean): Promise<CommentResult> {\n if (!this.config.allowWrite) throw new WriteBlockedError();\n if (message.trim() === \"\") throw new OpctlError(\"comment message must not be empty\", EXIT_CODES.validation);\n const raw = await this.getWorkPackageRaw(id);\n const detail = normalizeWorkPackageDetail(raw);\n const commentHref = findCommentHref(raw);\n if (!commentHref) {\n throw new OpctlError(\"commenting this work package is unsupported by the current OpenProject response/spec; no documented comment action link was found\", EXIT_CODES.validation);\n }\n const payload = { comment: { raw: message } };\n if (dryRun) {\n return { id, subject: detail.subject, status: \"dry-run\", request: { method: \"POST\", path: commentHref, payload } };\n }\n const response = await this.request(\"POST\", commentHref, payload);\n return { id, subject: detail.subject, status: \"comment posted\", link: getLink(response, \"self\")?.href ?? requireLinkHref(raw, \"self\") };\n }\n\n private async request(method: \"GET\" | \"POST\" | \"PATCH\", pathOrHref: string, body?: unknown): Promise<unknown> {\n const url = pathOrHref.startsWith(\"http://\") || pathOrHref.startsWith(\"https://\")\n ? pathOrHref\n : `${this.config.baseUrl}${pathOrHref.startsWith(\"/\") ? \"\" : \"/\"}${pathOrHref}`;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), this.timeoutMs);\n try {\n const response = await this.fetchImpl(url, {\n method,\n signal: controller.signal,\n headers: {\n Accept: \"application/hal+json, application/json\",\n ...(body === undefined ? {} : { \"Content-Type\": \"application/json\" }),\n Authorization: createAuthorizationHeader(this.config.authMode, this.config.token),\n },\n ...(body === undefined ? {} : { body: JSON.stringify(body) }),\n });\n const parsed = await parseResponse(response);\n if (!response.ok) throw new OpenProjectHttpError(response.status, parsed);\n return parsed;\n } catch (error) {\n if (error instanceof OpenProjectHttpError || error instanceof OpctlError) throw error;\n if (error instanceof Error && error.name === \"AbortError\") throw new NetworkError(\"OpenProject request timed out\");\n throw new NetworkError(error instanceof Error ? error.message : \"OpenProject network request failed\");\n } finally {\n clearTimeout(timeout);\n }\n }\n}\n\nexport function buildWorkPackageFilters(options: Pick<SearchWorkPackagesOptions, \"subject\" | \"assigneeMe\" | \"status\" | \"open\">): unknown[] {\n const filters: unknown[] = [];\n if (options.subject && options.subject.trim() !== \"\") filters.push({ subject: { operator: \"~\", values: [options.subject] } });\n if (options.assigneeMe) filters.push({ assignee: { operator: \"=\", values: [\"me\"] } });\n const status = options.status?.trim();\n if (options.open || status === \"open\") filters.push({ status: { operator: \"o\", values: [] } });\n else if (status) filters.push({ status: { operator: \"=\", values: [status] } });\n return filters;\n}\n\nfunction findCommentHref(resource: unknown): string | undefined {\n for (const name of [\"addComment\", \"addCommentImmediately\", \"comment\", \"addWorkPackageComment\"]) {\n const link = getLink(resource, name);\n if (link?.href && (!link.method || link.method.toUpperCase() === \"POST\")) return link.href;\n }\n return undefined;\n}\n\nasync function parseResponse(response: Response): Promise<unknown> {\n if (response.status === 204) return undefined;\n const text = await response.text();\n if (text.trim() === \"\") return undefined;\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n if (contentType.includes(\"json\") || contentType.includes(\"hal\")) {\n try {\n return JSON.parse(text);\n } catch {\n return { message: \"OpenProject returned invalid JSON\" };\n }\n }\n return { message: text };\n}\n","import { readFileSync } from \"node:fs\";\nimport { ConfigurationError } from \"../client/errors.js\";\nimport type { EnvReader } from \"../config.js\";\n\nconst ALLOWED_ENV_KEYS: Record<string, true> = {\n OPENPROJECT_AUTH_MODE: true,\n OPENPROJECT_DEFAULT_PROJECT: true,\n OPENPROJECT_TOKEN: true,\n OPENPROJECT_URL: true,\n};\n\nexport function loadEnvFile(path: string): EnvReader {\n return parseEnvFile(readFileSync(path, \"utf8\"));\n}\n\nexport function parseEnvFile(content: string): EnvReader {\n const env: Record<string, string> = {};\n const lines = content.split(/\\r?\\n/);\n for (let index = 0; index < lines.length; index += 1) {\n const parsed = parseLine(lines[index] ?? \"\", index + 1);\n if (!parsed) continue;\n if (ALLOWED_ENV_KEYS[parsed.key] !== true) continue;\n env[parsed.key] = parsed.value;\n }\n return env;\n}\n\nfunction parseLine(line: string, lineNumber: number): { readonly key: string; readonly value: string } | undefined {\n const trimmed = line.trim();\n if (trimmed === \"\" || trimmed.startsWith(\"#\")) return undefined;\n const equals = trimmed.indexOf(\"=\");\n if (equals <= 0) throw new ConfigurationError(`invalid .env line ${lineNumber}`);\n const key = trimmed.slice(0, equals).trim();\n if (!/^OPENPROJECT_[A-Z_]+$/.test(key)) return undefined;\n const rawValue = trimmed.slice(equals + 1).trim();\n return { key, value: unquoteValue(rawValue, lineNumber) };\n}\n\nfunction unquoteValue(value: string, lineNumber: number): string {\n if (value.startsWith('\"')) {\n if (!value.endsWith('\"') || value.length === 1) throw new ConfigurationError(`unterminated quoted value on .env line ${lineNumber}`);\n return value.slice(1, -1).replace(/\\\\n/g, \"\\n\").replace(/\\\\\"/g, '\"').replace(/\\\\\\\\/g, \"\\\\\");\n }\n if (value.startsWith(\"'\")) {\n if (!value.endsWith(\"'\") || value.length === 1) throw new ConfigurationError(`unterminated quoted value on .env line ${lineNumber}`);\n return value.slice(1, -1);\n }\n const hash = value.indexOf(\" #\");\n return (hash >= 0 ? value.slice(0, hash) : value).trim();\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync, chmodSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { ConfigurationError } from \"../client/errors.js\";\nimport type { EnvReader } from \"../config.js\";\n\nexport interface Profile {\n readonly url?: string;\n readonly authMode?: string;\n readonly defaultProject?: string;\n readonly token?: string;\n}\n\ninterface ProfileStore {\n readonly activeProfile?: string;\n readonly profiles: Record<string, Profile>;\n}\n\nconst EMPTY_STORE: ProfileStore = { profiles: {} };\n\nexport function profilesPath(env: NodeJS.ProcessEnv = process.env): string {\n const configHome = env.XDG_CONFIG_HOME && env.XDG_CONFIG_HOME.trim() !== \"\" ? env.XDG_CONFIG_HOME : join(homedir(), \".config\");\n return join(configHome, \"opctl\", \"profiles.json\");\n}\n\nexport function loadProfileStore(path = profilesPath()): ProfileStore {\n if (!existsSync(path)) return EMPTY_STORE;\n const parsed = JSON.parse(readFileSync(path, \"utf8\")) as unknown;\n if (!parsed || typeof parsed !== \"object\") throw new ConfigurationError(\"profile store is invalid\");\n const object = parsed as Record<string, unknown>;\n const profiles = object.profiles;\n if (!profiles || typeof profiles !== \"object\" || Array.isArray(profiles)) throw new ConfigurationError(\"profile store is invalid\");\n return {\n ...(typeof object.activeProfile === \"string\" ? { activeProfile: object.activeProfile } : {}),\n profiles: profiles as Record<string, Profile>,\n };\n}\n\nexport function saveProfileStore(store: ProfileStore, path = profilesPath()): void {\n mkdirSync(dirname(path), { recursive: true, mode: 0o700 });\n try { chmodSync(dirname(path), 0o700); } catch { /* best effort on platforms without chmod */ }\n writeFileSync(path, `${JSON.stringify(store, null, 2)}\\n`, { mode: 0o600 });\n try { chmodSync(path, 0o600); } catch { /* best effort on platforms without chmod */ }\n}\n\nexport function profileToEnv(profile: Profile | undefined): EnvReader {\n if (!profile) return {};\n return {\n ...(profile.url ? { OPENPROJECT_URL: profile.url } : {}),\n ...(profile.authMode ? { OPENPROJECT_AUTH_MODE: profile.authMode } : {}),\n ...(profile.defaultProject ? { OPENPROJECT_DEFAULT_PROJECT: profile.defaultProject } : {}),\n ...(profile.token ? { OPENPROJECT_TOKEN: profile.token } : {}),\n };\n}\n\nexport function getProfileEnv(name: string | undefined, env: NodeJS.ProcessEnv = process.env): EnvReader {\n const store = loadProfileStore(profilesPath(env));\n const selected = name ?? store.activeProfile;\n if (!selected) return {};\n const profile = store.profiles[selected];\n if (!profile) throw new ConfigurationError(`profile '${selected}' does not exist`);\n return profileToEnv(profile);\n}\n\nexport function listProfiles(env: NodeJS.ProcessEnv = process.env): ReadonlyArray<{ readonly name: string; readonly active: boolean; readonly profile: Profile }> {\n const store = loadProfileStore(profilesPath(env));\n return Object.entries(store.profiles).sort(([left], [right]) => left.localeCompare(right)).map(([name, profile]) => ({ name, active: name === store.activeProfile, profile }));\n}\n\nexport function setProfile(name: string, profile: Profile, env: NodeJS.ProcessEnv = process.env): void {\n validateProfileName(name);\n const path = profilesPath(env);\n const store = loadProfileStore(path);\n saveProfileStore({ ...store, profiles: { ...store.profiles, [name]: cleanProfile(profile) } }, path);\n}\n\nexport function useProfile(name: string, env: NodeJS.ProcessEnv = process.env): void {\n validateProfileName(name);\n const path = profilesPath(env);\n const store = loadProfileStore(path);\n if (!store.profiles[name]) throw new ConfigurationError(`profile '${name}' does not exist`);\n saveProfileStore({ ...store, activeProfile: name }, path);\n}\n\nexport function unsetProfile(name: string, env: NodeJS.ProcessEnv = process.env): void {\n validateProfileName(name);\n const path = profilesPath(env);\n const store = loadProfileStore(path);\n const { [name]: _removed, ...profiles } = store.profiles;\n saveProfileStore({ ...(store.activeProfile === name ? {} : { activeProfile: store.activeProfile }), profiles }, path);\n}\n\nexport function showProfile(name: string | undefined, env: NodeJS.ProcessEnv = process.env): { readonly name?: string; readonly profile?: Profile } {\n const store = loadProfileStore(profilesPath(env));\n const selected = name ?? store.activeProfile;\n if (!selected) return {};\n const profile = store.profiles[selected];\n if (!profile) throw new ConfigurationError(`profile '${selected}' does not exist`);\n return { name: selected, profile };\n}\n\nexport function redactProfile(profile: Profile): Profile & { readonly token?: string } {\n return { ...profile, ...(profile.token ? { token: \"<redacted>\" } : {}) };\n}\n\nfunction validateProfileName(name: string): void {\n if (!/^[A-Za-z0-9_.-]+$/.test(name)) throw new ConfigurationError(\"profile name may contain only letters, numbers, '.', '_', and '-'\");\n}\n\nfunction cleanProfile(profile: Profile): Profile {\n return {\n ...(profile.url && profile.url.trim() !== \"\" ? { url: profile.url.trim() } : {}),\n ...(profile.authMode && profile.authMode.trim() !== \"\" ? { authMode: profile.authMode.trim() } : {}),\n ...(profile.defaultProject && profile.defaultProject.trim() !== \"\" ? { defaultProject: profile.defaultProject.trim() } : {}),\n ...(profile.token && profile.token.trim() !== \"\" ? { token: profile.token } : {}),\n };\n}\n","import { ConfigurationError } from \"./client/errors.js\";\nimport { existsSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport { loadEnvFile } from \"./config/envFile.js\";\nimport { getProfileEnv } from \"./config/profiles.js\";\n\nexport type AuthMode = \"bearer\" | \"basic\";\n\nexport interface OpctlConfig {\n readonly baseUrl: string;\n readonly token: string;\n readonly authMode: AuthMode;\n readonly allowWrite: boolean;\n readonly defaultProject?: string;\n}\n\nexport interface EnvReader {\n readonly OPENPROJECT_URL?: string;\n readonly OPENPROJECT_TOKEN?: string;\n readonly OPENPROJECT_AUTH_MODE?: string;\n readonly OPENPROJECT_ALLOW_WRITE?: string;\n readonly OPENPROJECT_DEFAULT_PROJECT?: string;\n}\n\nexport interface ConfigResolutionOptions {\n readonly cwd?: string;\n readonly envFile?: string;\n readonly autoEnv?: boolean;\n readonly profile?: string;\n}\n\nexport function loadConfig(env: EnvReader = process.env): OpctlConfig {\n return loadConfigFromEnv(env);\n}\n\nexport function resolveConfigEnv(processEnv: NodeJS.ProcessEnv, options: ConfigResolutionOptions = {}): EnvReader {\n const cwd = options.cwd ?? process.cwd();\n const autoEnvPath = join(cwd, \".env\");\n const autoEnv = options.autoEnv === false || !existsSync(autoEnvPath) ? {} : loadEnvFile(autoEnvPath);\n const activeProfile = options.profile ? {} : getProfileEnv(undefined, processEnv);\n const selectedProfile = options.profile ? getProfileEnv(options.profile, processEnv) : {};\n const explicitEnv = options.envFile ? loadEnvFile(resolve(cwd, options.envFile)) : {};\n return mergeEnv(autoEnv, activeProfile, selectedProfile, explicitEnv, processEnv);\n}\n\nexport function loadResolvedConfig(processEnv: NodeJS.ProcessEnv, options: ConfigResolutionOptions = {}): OpctlConfig {\n return loadConfigFromEnv(resolveConfigEnv(processEnv, options));\n}\n\nexport function mergeEnv(...layers: readonly EnvReader[]): EnvReader {\n const merged: Record<string, string> = {};\n for (const layer of layers) {\n for (const key of [\"OPENPROJECT_URL\", \"OPENPROJECT_TOKEN\", \"OPENPROJECT_AUTH_MODE\", \"OPENPROJECT_ALLOW_WRITE\", \"OPENPROJECT_DEFAULT_PROJECT\"] as const) {\n const value = layer[key];\n if (value !== undefined) merged[key] = value;\n }\n }\n return merged;\n}\n\nfunction loadConfigFromEnv(env: EnvReader): OpctlConfig {\n const rawUrl = env.OPENPROJECT_URL;\n const rawToken = env.OPENPROJECT_TOKEN;\n if (!rawUrl || rawUrl.trim() === \"\") throw new ConfigurationError(\"OPENPROJECT_URL is required\");\n if (!rawToken || rawToken.trim() === \"\") throw new ConfigurationError(\"OPENPROJECT_TOKEN is required\");\n\n const authMode = parseAuthMode(env.OPENPROJECT_AUTH_MODE);\n const defaultProject = cleanOptional(env.OPENPROJECT_DEFAULT_PROJECT);\n return {\n baseUrl: normalizeBaseUrl(rawUrl),\n token: rawToken,\n authMode,\n allowWrite: env.OPENPROJECT_ALLOW_WRITE === \"1\",\n ...(defaultProject ? { defaultProject } : {}),\n };\n}\n\nexport function normalizeBaseUrl(rawUrl: string): string {\n let parsed: URL;\n try {\n parsed = new URL(rawUrl.trim());\n } catch {\n throw new ConfigurationError(\"OPENPROJECT_URL must be an absolute URL\");\n }\n if (parsed.protocol !== \"https:\" && parsed.protocol !== \"http:\") {\n throw new ConfigurationError(\"OPENPROJECT_URL must use http or https\");\n }\n parsed.hash = \"\";\n parsed.search = \"\";\n const withoutTrailing = parsed.toString().replace(/\\/+$/, \"\");\n return withoutTrailing;\n}\n\nfunction parseAuthMode(raw: string | undefined): AuthMode {\n if (!raw || raw.trim() === \"\") return \"bearer\";\n const normalized = raw.trim().toLowerCase();\n if (normalized === \"bearer\" || normalized === \"basic\") return normalized;\n throw new ConfigurationError(\"OPENPROJECT_AUTH_MODE must be bearer or basic\");\n}\n\nfunction cleanOptional(raw: string | undefined): string | undefined {\n if (!raw) return undefined;\n const value = raw.trim();\n return value === \"\" ? undefined : value;\n}\n","import type { Command } from \"commander\";\nimport { OpenProjectClient } from \"../client/openProjectClient.js\";\nimport { loadResolvedConfig, resolveConfigEnv, type ConfigResolutionOptions } from \"../config.js\";\nimport { stableJson } from \"../output/json.js\";\n\nexport interface CommandContext {\n readonly stdout: Pick<NodeJS.WriteStream, \"write\">;\n readonly stderr: Pick<NodeJS.WriteStream, \"write\">;\n readonly env: NodeJS.ProcessEnv;\n readonly fetchImpl?: typeof fetch;\n readonly cwd?: string;\n}\n\nexport function globalConfigOptions(command: Command): ConfigResolutionOptions {\n const opts = rootCommand(command).opts<Record<string, unknown>>();\n return {\n ...(typeof opts.env === \"string\" ? { envFile: opts.env } : {}),\n ...(opts.env === false ? { autoEnv: false } : {}),\n ...(typeof opts.profile === \"string\" ? { profile: opts.profile } : {}),\n };\n}\n\nexport function resolvedEnv(context: CommandContext, command: Command): NodeJS.ProcessEnv {\n return resolveConfigEnv(context.env, configOptions(context, command)) as NodeJS.ProcessEnv;\n}\n\nexport function createClient(context: CommandContext, command?: Command): OpenProjectClient {\n const config = loadResolvedConfig(context.env, command ? configOptions(context, command) : configOptions(context));\n return new OpenProjectClient({\n config,\n ...(context.fetchImpl ? { fetchImpl: context.fetchImpl } : {}),\n });\n}\n\nexport function writeOutput(context: CommandContext, value: unknown, json: boolean, renderText: () => string, token?: string): void {\n context.stdout.write(json ? stableJson(value, token ?? context.env.OPENPROJECT_TOKEN) : renderText());\n}\n\nfunction configOptions(context: CommandContext, command?: Command): ConfigResolutionOptions {\n return {\n ...(context.cwd ? { cwd: context.cwd } : {}),\n ...(command ? globalConfigOptions(command) : {}),\n };\n}\n\nfunction rootCommand(command: Command): Command {\n let current = command;\n while (current.parent) current = current.parent;\n return current;\n}\n\nexport function booleanOption(command: Command, name: string): boolean {\n return Boolean(command.opts<Record<string, unknown>>()[name]);\n}\n","import type { Command } from \"commander\";\nimport { asObject } from \"../client/hal.js\";\nimport { stableJson } from \"../output/json.js\";\nimport { renderKeyValue } from \"../output/text.js\";\nimport { createClient, resolvedEnv, type CommandContext } from \"./context.js\";\n\nexport function registerApiRoot(program: Command, context: CommandContext): void {\n program\n .command(\"api-root\")\n .description(\"Show compact OpenProject API root links\")\n .option(\"--json\", \"emit JSON\")\n .action(async (options: { json?: boolean }, command: Command) => {\n const root = await createClient(context, command).getApiRoot();\n const links = compactLinks(root);\n context.stdout.write(options.json ? stableJson(links, resolvedEnv(context, command).OPENPROJECT_TOKEN) : renderKeyValue(links));\n });\n}\n\nexport function compactLinks(root: unknown): Record<string, string> {\n const links = asObject(asObject(root)?._links) ?? {};\n const output: Record<string, string> = {};\n for (const [name, raw] of Object.entries(links)) {\n const link = Array.isArray(raw) ? asObject(raw[0]) : asObject(raw);\n if (typeof link?.href === \"string\") output[name] = link.href;\n }\n return output;\n}\n","import type { Command } from \"commander\";\nimport { createClient, type CommandContext, writeOutput } from \"./context.js\";\nimport { renderKeyValue } from \"../output/text.js\";\n\nexport function registerMe(program: Command, context: CommandContext): void {\n program\n .command(\"me\")\n .description(\"Show the authenticated OpenProject user\")\n .option(\"--json\", \"emit JSON\")\n .action(async (options: { json?: boolean }, command: Command) => {\n const me = await createClient(context, command).getMe();\n writeOutput(context, me, Boolean(options.json), () => renderKeyValue(me as unknown as Record<string, unknown>));\n });\n}\n","export function renderTable(rows: readonly object[], columns: readonly string[]): string {\n const widths = columns.map((column) => Math.max(column.length, ...rows.map((row) => cell((row as Record<string, unknown>)[column]).length)));\n const header = columns.map((column, index) => column.padEnd(widths[index] ?? column.length)).join(\" \");\n const divider = widths.map((width) => \"-\".repeat(width)).join(\" \");\n const body = rows.map((row) => columns.map((column, index) => cell((row as Record<string, unknown>)[column]).padEnd(widths[index] ?? 0)).join(\" \"));\n return `${[header, divider, ...body].join(\"\\n\")}\\n`;\n}\n\nfunction cell(value: unknown): string {\n if (value === undefined || value === null) return \"\";\n return String(value);\n}\n","import type { Command } from \"commander\";\nimport { renderTable } from \"../output/table.js\";\nimport { createClient, type CommandContext, writeOutput } from \"./context.js\";\n\nexport function registerProjects(program: Command, context: CommandContext): void {\n program\n .command(\"projects\")\n .description(\"List visible OpenProject projects\")\n .option(\"--json\", \"emit JSON\")\n .option(\"--page-size <n>\", \"page size\", Number)\n .action(async (options: { json?: boolean; pageSize?: number }, command: Command) => {\n const projects = await createClient(context, command).listProjects(options.pageSize === undefined ? {} : { pageSize: options.pageSize });\n writeOutput(context, projects, Boolean(options.json), () => renderTable(projects.elements, [\"id\", \"identifier\", \"name\", \"href\"]));\n });\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport { createAuthorizationHeader, redactSecrets } from \"../src/client/auth.js\";\nimport { OpenApiGenerationError } from \"../src/client/errors.js\";\nimport { normalizeBaseUrl, type AuthMode } from \"../src/config.js\";\n\nexport const PUBLIC_SPEC_BASE = \"https://community.openproject.org\";\n\nexport interface PullSpecOptions {\n readonly env?: NodeJS.ProcessEnv;\n readonly fetchImpl?: typeof fetch;\n readonly outputPath?: string;\n readonly sourceBaseUrl?: string;\n readonly timeoutMs?: number;\n readonly stdout?: Pick<typeof process.stdout, \"write\">;\n}\n\nexport interface PullSpecResult {\n readonly sourceHost: string;\n readonly outputPath: string;\n readonly title: string;\n readonly version: string;\n}\n\nexport async function pullOpenApiSpec(options: PullSpecOptions = {}): Promise<PullSpecResult> {\n const env = options.env ?? process.env;\n const outputPath = options.outputPath ?? \"openapi/openproject.json\";\n const fetchImpl = options.fetchImpl ?? fetch;\n\n // Source selection: explicit option > OPENPROJECT_SPEC_URL > public default.\n // OPENPROJECT_URL is intentionally ignored to prevent accidental private-instance leakage.\n const rawUrl = options.sourceBaseUrl ?? env.OPENPROJECT_SPEC_URL ?? PUBLIC_SPEC_BASE;\n const baseUrl = normalizeBaseUrl(rawUrl);\n\n // Auth: only use the spec-dedicated token, never OPENPROJECT_TOKEN.\n const specToken = env.OPENPROJECT_SPEC_TOKEN;\n const authMode = parseAuthMode(env.OPENPROJECT_SPEC_AUTH_MODE);\n const headers: Record<string, string> = { Accept: \"application/json\" };\n if (specToken && specToken.trim() !== \"\") {\n headers.Authorization = createAuthorizationHeader(authMode, specToken);\n }\n\n const specUrl = `${baseUrl}/api/v3/spec.json`;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), options.timeoutMs ?? 15_000);\n let response: Response;\n try {\n response = await fetchImpl(specUrl, { headers, signal: controller.signal });\n } catch (error) {\n throw new OpenApiGenerationError(`failed to download OpenProject spec from ${new URL(baseUrl).host}: ${error instanceof Error ? redactSecrets(error.message, specToken) : \"network error\"}`);\n } finally {\n clearTimeout(timeout);\n }\n\n if (!response.ok) {\n throw new OpenApiGenerationError(`failed to download OpenProject spec from ${new URL(baseUrl).host}: HTTP ${response.status}`);\n }\n\n const text = await response.text();\n let spec: unknown;\n try {\n spec = JSON.parse(text);\n } catch {\n throw new OpenApiGenerationError(\"OpenProject spec response was not valid JSON; spec.yml is not supported by this downloader\");\n }\n if (!spec || typeof spec !== \"object\") throw new OpenApiGenerationError(\"OpenProject spec response was not an object\");\n const info = \"info\" in spec && typeof spec.info === \"object\" && spec.info !== null ? spec.info : undefined;\n const title = info && \"title\" in info && typeof info.title === \"string\" ? info.title : \"OpenProject API\";\n const version = info && \"version\" in info && typeof info.version === \"string\" ? info.version : \"unknown\";\n\n await mkdir(dirname(outputPath), { recursive: true });\n await writeFile(outputPath, `${JSON.stringify(spec, null, 2)}\\n`, \"utf8\");\n const result = { sourceHost: new URL(baseUrl).host, outputPath, title, version };\n options.stdout?.write(`Downloaded OpenProject spec from ${result.sourceHost} to ${result.outputPath} (${result.title} ${result.version})\\n`);\n return result;\n}\n\nfunction parseAuthMode(raw: string | undefined): AuthMode {\n const normalized = raw?.trim().toLowerCase() ?? \"\";\n if (normalized === \"\" || normalized === \"bearer\") return \"bearer\";\n if (normalized === \"basic\") return \"basic\";\n throw new OpenApiGenerationError(\"OPENPROJECT_SPEC_AUTH_MODE must be bearer or basic\");\n}\n\nif (import.meta.url === `file://${process.argv[1]}`) {\n pullOpenApiSpec({ stdout: process.stdout }).catch((error: unknown) => {\n const message = error instanceof Error ? error.message : \"failed to pull OpenProject spec\";\n process.stderr.write(`${redactSecrets(message, process.env.OPENPROJECT_SPEC_TOKEN)}\\n`);\n process.exitCode = 8;\n });\n}\n","import type { Command } from \"commander\";\nimport { pullOpenApiSpec } from \"../../scripts/pull-openapi-spec.js\";\nimport type { CommandContext } from \"./context.js\";\n\nexport interface SpecPullOptions {\n readonly url?: string;\n readonly output?: string;\n}\n\nexport function registerSpec(program: Command, context: CommandContext): void {\n const spec = program.command(\"spec\").description(\"OpenAPI spec utilities\");\n spec.command(\"pull\")\n .description(\"Download OpenProject /api/v3/spec.json (defaults to the public community spec)\")\n .option(\"--url <url>\", \"spec source base URL (overrides OPENPROJECT_SPEC_URL)\")\n .option(\"--output <path>\", \"output file path\")\n .action(async (opts: SpecPullOptions) => {\n await pullOpenApiSpec({\n env: context.env,\n stdout: context.stdout,\n ...(context.fetchImpl ? { fetchImpl: context.fetchImpl } : {}),\n ...(opts.url ? { sourceBaseUrl: opts.url } : {}),\n ...(opts.output ? { outputPath: opts.output } : {}),\n });\n });\n}\n","import { OpctlError, EXIT_CODES } from \"../client/errors.js\";\n\nexport type WorkPackageField = \"id\" | \"subject\" | \"status\" | \"type\" | \"assignee\" | \"project\" | \"href\" | \"updatedAt\" | \"description\" | \"shortDescription\" | \"attachmentsCount\" | \"lockVersion\";\nexport type OutputMode = \"text\" | \"table\" | \"compact\" | \"json\" | \"jsonl\" | \"rawJson\";\n\nexport const DEFAULT_COMPACT_FIELDS: readonly WorkPackageField[] = [\"id\", \"subject\", \"status\", \"assignee\", \"updatedAt\"];\nexport const DEFAULT_TABLE_FIELDS: readonly WorkPackageField[] = [\"id\", \"subject\", \"status\", \"assignee\", \"project\", \"updatedAt\"];\nexport const DEFAULT_CHECK_FIELDS: readonly WorkPackageField[] = [\"id\", \"subject\", \"status\", \"assignee\", \"shortDescription\", \"attachmentsCount\"];\nexport const DETAIL_FIELDS: readonly WorkPackageField[] = [\"id\", \"subject\", \"status\", \"type\", \"assignee\", \"project\", \"href\", \"updatedAt\", \"description\", \"shortDescription\", \"attachmentsCount\", \"lockVersion\"];\n\nconst SUPPORTED_FIELDS: Record<WorkPackageField, true> = {\n assignee: true,\n attachmentsCount: true,\n description: true,\n href: true,\n id: true,\n lockVersion: true,\n project: true,\n shortDescription: true,\n status: true,\n subject: true,\n type: true,\n updatedAt: true,\n};\n\nconst FIELD_ALIASES: Record<string, WorkPackageField> = {\n title: \"subject\",\n url: \"href\",\n};\n\nexport interface OutputFlagOptions {\n readonly json?: boolean;\n readonly jsonl?: boolean;\n readonly table?: boolean;\n readonly compact?: boolean;\n readonly rawJson?: boolean;\n}\n\nexport function parseOutputMode(options: OutputFlagOptions): OutputMode {\n const enabled = [options.json, options.jsonl, options.table, options.compact, options.rawJson].filter(Boolean).length;\n if (enabled > 1) throw new OpctlError(\"choose only one output mode flag\", EXIT_CODES.validation);\n if (options.rawJson) return \"rawJson\";\n if (options.json) return \"json\";\n if (options.jsonl) return \"jsonl\";\n if (options.compact) return \"compact\";\n if (options.table) return \"table\";\n return \"text\";\n}\n\nexport function parseFields(raw: string | undefined, defaults: readonly WorkPackageField[]): readonly WorkPackageField[] {\n if (!raw || raw.trim() === \"\") return defaults;\n const fields: WorkPackageField[] = [];\n for (const part of raw.split(\",\")) {\n const trimmed = part.trim();\n if (trimmed === \"\") continue;\n const field = FIELD_ALIASES[trimmed] ?? trimmed;\n if (!isSupportedField(field)) throw new OpctlError(`unknown work package field '${trimmed}'. Supported fields: ${Object.keys(SUPPORTED_FIELDS).join(\",\")}`, EXIT_CODES.validation);\n fields.push(field);\n }\n if (fields.length === 0) throw new OpctlError(\"--fields must include at least one field\", EXIT_CODES.validation);\n return fields;\n}\n\nexport function projectFields<T extends Record<string, unknown>>(value: T, fields: readonly WorkPackageField[]): Record<string, unknown> {\n const projected: Record<string, unknown> = {};\n for (const field of fields) projected[field] = value[field];\n return projected;\n}\n\nexport function projectRows<T extends Record<string, unknown>>(rows: readonly T[], fields: readonly WorkPackageField[]): Record<string, unknown>[] {\n return rows.map((row) => projectFields(row, fields));\n}\n\nfunction isSupportedField(field: string): field is WorkPackageField {\n return SUPPORTED_FIELDS[field as WorkPackageField] === true;\n}\n","import type { Command } from \"commander\";\nimport { OpctlError, EXIT_CODES } from \"../client/errors.js\";\nimport { stableJson } from \"../output/json.js\";\nimport { renderKeyValue } from \"../output/text.js\";\nimport { renderTable } from \"../output/table.js\";\nimport { DEFAULT_CHECK_FIELDS, DEFAULT_COMPACT_FIELDS, DEFAULT_TABLE_FIELDS, DETAIL_FIELDS, parseFields, parseOutputMode, projectFields, projectRows, type OutputFlagOptions, type WorkPackageField } from \"../output/fields.js\";\nimport type { NormalizedCollection } from \"../client/pagination.js\";\nimport type { WorkPackageDetail, WorkPackageSummary } from \"../types/domain.js\";\nimport { createClient, resolvedEnv, type CommandContext, writeOutput } from \"./context.js\";\n\ninterface SearchOptions extends OutputFlagOptions {\n readonly fields?: string;\n readonly project?: string;\n readonly subject?: string;\n readonly assigneeMe?: boolean;\n readonly status?: string;\n readonly open?: boolean;\n readonly pageSize?: number;\n}\n\ninterface GetOptions extends OutputFlagOptions {\n readonly ids?: string;\n readonly fields?: string;\n}\n\nexport function registerWorkPackages(program: Command, context: CommandContext): void {\n const wp = program.command(\"wp\").description(\"Work package commands\");\n\n wp.command(\"get\")\n .description(\"Get one or more work packages\")\n .argument(\"[ids...]\", \"work package ids\")\n .option(\"--ids <csv>\", \"comma-separated work package ids\")\n .option(\"--fields <csv>\", \"comma-separated output fields\")\n .option(\"--table\", \"emit table output\")\n .option(\"--compact\", \"emit compact triage table output\")\n .option(\"--json\", \"emit normalized JSON\")\n .option(\"--jsonl\", \"emit one JSON object per line\")\n .option(\"--raw-json\", \"emit raw OpenProject JSON; single work package only\")\n .action(async (ids: string[], options: GetOptions, command: Command) => {\n const numericIds = parseIds(ids, options.ids);\n if (numericIds.length === 0) throw new OpctlError(\"at least one work package id is required\", EXIT_CODES.validation);\n const mode = parseOutputMode(options);\n if (mode === \"rawJson\" && numericIds.length !== 1) throw new OpctlError(\"--raw-json supports exactly one work package id\", EXIT_CODES.validation);\n if (mode !== \"rawJson\") parseFields(options.fields, mode === \"compact\" ? DEFAULT_COMPACT_FIELDS : DETAIL_FIELDS);\n const client = createClient(context, command);\n const token = resolvedEnv(context, command).OPENPROJECT_TOKEN;\n if (mode === \"rawJson\") {\n context.stdout.write(stableJson(await client.getWorkPackageRaw(numericIds[0] as number), token));\n return;\n }\n const workPackages: WorkPackageDetail[] = [];\n for (const id of numericIds) workPackages.push(await client.getWorkPackage(id));\n writeWorkPackageOutput(context, workPackages, options, mode, numericIds.length === 1 && !options.ids, DETAIL_FIELDS, token);\n });\n\n wp.command(\"check\")\n .description(\"Read a triage-oriented issue list for one or more work packages\")\n .argument(\"[ids...]\", \"work package ids\")\n .option(\"--ids <csv>\", \"comma-separated work package ids\")\n .option(\"--fields <csv>\", \"comma-separated output fields\")\n .option(\"--table\", \"emit table output\")\n .option(\"--compact\", \"emit compact table output\")\n .option(\"--json\", \"emit JSON\")\n .option(\"--jsonl\", \"emit one JSON object per line\")\n .action(async (ids: string[], options: Omit<GetOptions, \"rawJson\">, command: Command) => {\n const numericIds = parseIds(ids, options.ids);\n if (numericIds.length === 0) throw new OpctlError(\"at least one work package id is required\", EXIT_CODES.validation);\n const mode = parseOutputMode(options);\n parseFields(options.fields, mode === \"compact\" ? DEFAULT_COMPACT_FIELDS : DEFAULT_CHECK_FIELDS);\n const client = createClient(context, command);\n const workPackages: WorkPackageDetail[] = [];\n for (const id of numericIds) workPackages.push(await client.getWorkPackage(id));\n writeWorkPackageOutput(context, workPackages, options, mode, false, DEFAULT_CHECK_FIELDS, resolvedEnv(context, command).OPENPROJECT_TOKEN);\n });\n\n wp.command(\"search\")\n .description(\"Search work packages\")\n .option(\"--json\", \"emit JSON\")\n .option(\"--jsonl\", \"emit one JSON object per line\")\n .option(\"--table\", \"emit table output\")\n .option(\"--compact\", \"emit compact table output\")\n .option(\"--fields <csv>\", \"comma-separated output fields\")\n .option(\"--project <identifier-or-id>\", \"project identifier or id\")\n .option(\"--subject <text>\", \"subject contains text\")\n .option(\"--assignee-me\", \"filter to current user\")\n .option(\"--status <id-or-open>\", \"status id, or open\")\n .option(\"--open\", \"filter to open work packages\")\n .option(\"--page-size <n>\", \"page size\", Number)\n .action(async (options: SearchOptions, command: Command) => {\n const result = await createClient(context, command).searchWorkPackages(options);\n writeCollectionOutput(context, result, options, resolvedEnv(context, command).OPENPROJECT_TOKEN);\n });\n\n wp.command(\"mine\")\n .description(\"List open work packages assigned to the authenticated user\")\n .option(\"--json\", \"emit JSON\")\n .option(\"--jsonl\", \"emit one JSON object per line\")\n .option(\"--table\", \"emit table output\")\n .option(\"--compact\", \"emit compact table output\")\n .option(\"--fields <csv>\", \"comma-separated output fields\")\n .option(\"--project <identifier-or-id>\", \"project identifier or id\")\n .option(\"--open\", \"filter to open work packages\")\n .option(\"--page-size <n>\", \"page size\", Number)\n .action(async (options: Pick<SearchOptions, \"json\" | \"jsonl\" | \"table\" | \"compact\" | \"fields\" | \"project\" | \"open\" | \"pageSize\">, command: Command) => {\n const result = await createClient(context, command).mine(options);\n writeCollectionOutput(context, result, options, resolvedEnv(context, command).OPENPROJECT_TOKEN);\n });\n\n wp.command(\"comment\")\n .description(\"Add a comment to a work package; requires OPENPROJECT_ALLOW_WRITE=1\")\n .argument(\"<id>\", \"work package id\")\n .argument(\"[message...]\", \"comment message\")\n .option(\"--dry-run\", \"print intended mutation without posting\")\n .option(\"--json\", \"emit JSON\")\n .action(async (id: string, messageParts: string[], options: { dryRun?: boolean; json?: boolean }, command: Command) => {\n const result = await createClient(context, command).commentWorkPackage(parseId(id), messageParts.join(\" \"), Boolean(options.dryRun));\n writeOutput(context, result, Boolean(options.json), () => renderKeyValue(result as unknown as Record<string, unknown>), resolvedEnv(context, command).OPENPROJECT_TOKEN);\n });\n}\n\nfunction writeCollectionOutput(context: CommandContext, result: NormalizedCollection<WorkPackageSummary>, options: SearchOptions | Pick<SearchOptions, \"json\" | \"jsonl\" | \"table\" | \"compact\" | \"fields\" | \"project\" | \"open\" | \"pageSize\">, token: string | undefined): void {\n const mode = parseOutputMode(options);\n const defaults = mode === \"compact\" ? DEFAULT_COMPACT_FIELDS : DEFAULT_TABLE_FIELDS;\n const fields = parseFields(options.fields, defaults);\n const elements = projectRows(result.elements as unknown as Record<string, unknown>[], fields);\n if (mode === \"jsonl\") {\n context.stdout.write(elements.map((element) => JSON.stringify(element)).join(\"\\n\") + (elements.length > 0 ? \"\\n\" : \"\"));\n return;\n }\n if (mode === \"json\") {\n const output = options.fields ? { ...result, elements } : result;\n context.stdout.write(stableJson(output, token));\n return;\n }\n context.stdout.write(renderTable(elements, fields));\n}\n\nfunction writeWorkPackageOutput(context: CommandContext, workPackages: readonly WorkPackageDetail[], options: GetOptions | Omit<GetOptions, \"rawJson\">, mode: string, singleObject: boolean, defaultFields: readonly WorkPackageField[], token: string | undefined): void {\n const fields = parseFields(options.fields, mode === \"compact\" ? DEFAULT_COMPACT_FIELDS : defaultFields);\n const projected = options.fields || mode === \"table\" || mode === \"compact\" || mode === \"jsonl\" ? projectRows(workPackages as unknown as Record<string, unknown>[], fields) : workPackages;\n if (mode === \"jsonl\") {\n const rows = projectRows(workPackages as unknown as Record<string, unknown>[], fields);\n context.stdout.write(rows.map((row) => JSON.stringify(row)).join(\"\\n\") + (rows.length > 0 ? \"\\n\" : \"\"));\n return;\n }\n if (mode === \"json\") {\n context.stdout.write(stableJson(singleObject ? projected[0] : projected, token));\n return;\n }\n if (singleObject && mode === \"text\" && !options.fields) {\n context.stdout.write(renderKeyValue(workPackages[0] as unknown as Record<string, unknown>));\n return;\n }\n context.stdout.write(renderTable(projectRows(workPackages as unknown as Record<string, unknown>[], fields), fields));\n}\n\nfunction parseIds(positionals: readonly string[], csv: string | undefined): number[] {\n const seen = new Set<number>();\n const ids: number[] = [];\n for (const raw of [...positionals, ...splitCsv(csv)]) {\n const id = parseId(raw);\n if (seen.has(id)) continue;\n seen.add(id);\n ids.push(id);\n }\n return ids;\n}\n\nfunction splitCsv(csv: string | undefined): string[] {\n if (!csv) return [];\n return csv.split(\",\").map((part) => part.trim()).filter((part) => part !== \"\");\n}\n\nfunction parseId(id: string): number {\n const parsed = Number(id);\n if (!Number.isInteger(parsed) || parsed < 1) throw new OpctlError(\"work package id must be a positive integer\", EXIT_CODES.validation);\n return parsed;\n}\n","import type { Command } from \"commander\";\nimport { stableJson } from \"../output/json.js\";\nimport { renderKeyValue } from \"../output/text.js\";\nimport { renderTable } from \"../output/table.js\";\nimport { listProfiles, redactProfile, setProfile, showProfile, unsetProfile, useProfile, type Profile } from \"../config/profiles.js\";\nimport type { CommandContext } from \"./context.js\";\n\ninterface SetProfileOptions {\n readonly url?: string;\n readonly authMode?: string;\n readonly defaultProject?: string;\n readonly token?: string;\n readonly json?: boolean;\n}\n\nexport function registerProfile(program: Command, context: CommandContext): void {\n const profile = program.command(\"profile\").description(\"Saved non-write OpenProject connection profiles\");\n\n profile.command(\"list\")\n .description(\"List saved profiles\")\n .option(\"--json\", \"emit JSON\")\n .action((options: { readonly json?: boolean }) => {\n const rows = listProfiles(context.env).map((entry) => ({ name: entry.name, active: entry.active ? \"yes\" : \"\", ...redactProfile(entry.profile) }));\n context.stdout.write(options.json ? stableJson(rows) : renderTable(rows, [\"name\", \"active\", \"url\", \"authMode\", \"defaultProject\", \"token\"]));\n });\n\n profile.command(\"show\")\n .description(\"Show a saved profile with secrets redacted\")\n .argument(\"[name]\", \"profile name; defaults to active profile\")\n .option(\"--json\", \"emit JSON\")\n .action((name: string | undefined, options: { readonly json?: boolean }) => {\n const result = showProfile(name, context.env);\n const output = result.profile ? { name: result.name, ...redactProfile(result.profile) } : { name: undefined };\n context.stdout.write(options.json ? stableJson(output) : renderKeyValue(output));\n });\n\n profile.command(\"set\")\n .description(\"Create or replace a saved profile\")\n .argument(\"<name>\", \"profile name\")\n .option(\"--url <url>\", \"OpenProject base URL\")\n .option(\"--auth-mode <mode>\", \"auth mode: bearer or basic\")\n .option(\"--default-project <id>\", \"default project identifier or id\")\n .option(\"--token <token>\", \"OpenProject API token; stored in a 0600 profile file\")\n .option(\"--json\", \"emit JSON\")\n .action((name: string, options: SetProfileOptions) => {\n const profileValue: Profile = {\n ...(options.url ? { url: options.url } : {}),\n ...(options.authMode ? { authMode: options.authMode } : {}),\n ...(options.defaultProject ? { defaultProject: options.defaultProject } : {}),\n ...(options.token ? { token: options.token } : {}),\n };\n setProfile(name, profileValue, context.env);\n const output = { name, ...redactProfile(profileValue) };\n context.stdout.write(options.json ? stableJson(output) : `${name}\\n`);\n });\n\n profile.command(\"use\")\n .description(\"Set the active profile\")\n .argument(\"<name>\", \"profile name\")\n .option(\"--json\", \"emit JSON\")\n .action((name: string, options: { readonly json?: boolean }) => {\n useProfile(name, context.env);\n const output = { activeProfile: name };\n context.stdout.write(options.json ? stableJson(output) : `active profile: ${name}\\n`);\n });\n\n profile.command(\"unset\")\n .description(\"Delete a saved profile\")\n .argument(\"<name>\", \"profile name\")\n .option(\"--json\", \"emit JSON\")\n .action((name: string, options: { readonly json?: boolean }) => {\n unsetProfile(name, context.env);\n const output = { unset: name };\n context.stdout.write(options.json ? stableJson(output) : `unset profile: ${name}\\n`);\n });\n}\n","{\n \"name\": \"opctl\",\n \"version\": \"0.1.6\",\n \"description\": \"Conservative local CLI bridge for OpenProject API v3\",\n \"type\": \"module\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/hewel/op-cli.git\"\n },\n \"bin\": {\n \"opctl\": \"dist/cli.js\"\n },\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"dev\": \"tsx src/cli.ts\",\n \"build\": \"npm run typecheck && vite build\",\n \"typecheck\": \"tsc --noEmit\",\n \"test\": \"vitest run\",\n \"openapi:pull\": \"tsx scripts/pull-openapi-spec.ts\",\n \"openapi:generate\": \"tsx scripts/generate-openapi-types.ts\",\n \"openapi:update\": \"npm run openapi:pull && npm run openapi:generate\"\n },\n \"keywords\": [\n \"openproject\",\n \"cli\"\n ],\n \"author\": \"\",\n \"license\": \"ISC\",\n \"dependencies\": {\n \"commander\": \"latest\",\n \"openapi-fetch\": \"latest\"\n },\n \"devDependencies\": {\n \"@types/node\": \"latest\",\n \"openapi-typescript\": \"latest\",\n \"tsx\": \"latest\",\n \"typescript\": \"latest\",\n \"vite\": \"latest\",\n \"vitest\": \"latest\",\n \"yaml\": \"^2.9.0\"\n },\n \"packageManager\": \"pnpm@11.1.3\"\n}\n","#!/usr/bin/env node\nimport { realpathSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { Command } from \"commander\";\nimport { redactSecrets } from \"./client/auth.js\";\nimport { EXIT_CODES, toOpctlError } from \"./client/errors.js\";\nimport { stableJson } from \"./output/json.js\";\nimport { registerApiRoot } from \"./commands/apiRoot.js\";\nimport { registerMe } from \"./commands/me.js\";\nimport { registerProjects } from \"./commands/projects.js\";\nimport { registerSpec } from \"./commands/spec.js\";\nimport { registerWorkPackages } from \"./commands/workPackages.js\";\nimport { registerProfile } from \"./commands/profile.js\";\nimport type { CommandContext } from \"./commands/context.js\";\nimport pkg from \"../package.json\" with { type: \"json\" };\n\nexport function buildProgram(context: CommandContext): Command {\n const program = new Command();\n program\n .name(\"opctl\")\n .description(\"Conservative local CLI bridge for OpenProject API v3\")\n .version(pkg.version)\n .option(\"--env <path>\", \"load OpenProject configuration from dotenv-style file\")\n .option(\"--no-env\", \"disable automatic .env loading from the current working directory\")\n .option(\"--profile <name>\", \"use a saved profile for this invocation\")\n .showHelpAfterError()\n .configureOutput({\n writeOut: (text) => context.stdout.write(text),\n writeErr: (text) => context.stderr.write(text),\n });\n registerMe(program, context);\n registerApiRoot(program, context);\n registerProjects(program, context);\n registerWorkPackages(program, context);\n registerProfile(program, context);\n registerSpec(program, context);\n return program;\n}\n\nexport async function run(argv: readonly string[], context: CommandContext): Promise<number> {\n try {\n await buildProgram(context).parseAsync(argv, { from: \"node\" });\n return EXIT_CODES.success;\n } catch (error) {\n const opctlError = toOpctlError(error);\n const wantsJson = argv.includes(\"--json\");\n if (wantsJson) context.stderr.write(stableJson({ error: opctlError.message, exitCode: opctlError.exitCode }, context.env.OPENPROJECT_TOKEN));\n else context.stderr.write(`${redactSecrets(opctlError.message, context.env.OPENPROJECT_TOKEN)}\\n`);\n return opctlError.exitCode;\n }\n}\n\nexport function isCliEntrypoint(metaUrl: string, argvPath: string | undefined = process.argv[1]): boolean {\n if (!argvPath) return false;\n try {\n return realpathSync(fileURLToPath(metaUrl)) === realpathSync(argvPath);\n } catch {\n return false;\n }\n}\n\nif (isCliEntrypoint(import.meta.url)) {\n const exitCode = await run(process.argv, { stdout: process.stdout, stderr: process.stderr, env: process.env });\n process.exitCode = exitCode;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","names":[],"sources":["../src/client/auth.ts","../src/client/errors.ts","../src/output/json.ts","../src/client/hal.ts","../src/output/text.ts","../src/client/pagination.ts","../src/client/urls.ts","../src/client/openProjectClient.ts","../src/config/envFile.ts","../src/config/profiles.ts","../src/config.ts","../src/commands/context.ts","../src/commands/apiRoot.ts","../package.json","../src/commands/doctor.ts","../src/output/table.ts","../src/commands/lookups.ts","../src/commands/me.ts","../src/commands/projects.ts","../scripts/pull-openapi-spec.ts","../src/commands/spec.ts","../src/output/fields.ts","../src/commands/workPackages.ts","../src/commands/profile.ts","../src/cli.ts"],"sourcesContent":["import type { AuthMode } from \"../config.js\";\n\nexport function createAuthorizationHeader(mode: AuthMode, token: string): string {\n if (mode === \"basic\") {\n return `Basic ${Buffer.from(`apikey:${token}`, \"utf8\").toString(\"base64\")}`;\n }\n return `Bearer ${token}`;\n}\n\nexport function redactSecrets(value: string, token?: string): string {\n let redacted = value.replace(/Authorization:\\s*(Bearer|Basic)\\s+[^\\s,}]+/gi, \"Authorization: <redacted>\");\n redacted = redacted.replace(/\"Authorization\"\\s*:\\s*\"[^\"]+\"/gi, '\"Authorization\":\"<redacted>\"');\n if (token && token !== \"\") redacted = redacted.split(token).join(\"<redacted>\");\n return redacted;\n}\n","export const EXIT_CODES = {\n success: 0,\n general: 1,\n config: 2,\n auth: 3,\n notFound: 4,\n validation: 5,\n writeBlocked: 6,\n network: 7,\n openapi: 8,\n} as const;\n\nexport type ExitCode = (typeof EXIT_CODES)[keyof typeof EXIT_CODES];\n\nexport class OpctlError extends Error {\n public readonly exitCode: ExitCode;\n public readonly details: unknown;\n\n public constructor(message: string, exitCode: ExitCode = EXIT_CODES.general, details?: unknown) {\n super(message);\n this.name = \"OpctlError\";\n this.exitCode = exitCode;\n this.details = details;\n }\n}\n\nexport class ConfigurationError extends OpctlError {\n public constructor(message: string) {\n super(message, EXIT_CODES.config);\n this.name = \"ConfigurationError\";\n }\n}\n\nexport class WriteBlockedError extends OpctlError {\n public constructor() {\n super(\"OpenProject write blocked: set OPENPROJECT_ALLOW_WRITE=1 to enable write commands\", EXIT_CODES.writeBlocked);\n this.name = \"WriteBlockedError\";\n }\n}\n\nexport class NetworkError extends OpctlError {\n public constructor(message: string) {\n super(message, EXIT_CODES.network);\n this.name = \"NetworkError\";\n }\n}\n\nexport class OpenApiGenerationError extends OpctlError {\n public constructor(message: string) {\n super(message, EXIT_CODES.openapi);\n this.name = \"OpenApiGenerationError\";\n }\n}\n\nexport class OpenProjectHttpError extends OpctlError {\n public readonly status: number;\n public readonly responseBody: unknown;\n\n public constructor(status: number, responseBody: unknown) {\n super(httpStatusMessage(status, responseBody), exitCodeForStatus(status), responseBody);\n this.name = \"OpenProjectHttpError\";\n this.status = status;\n this.responseBody = responseBody;\n }\n}\n\nexport function exitCodeForStatus(status: number): ExitCode {\n if (status === 401 || status === 403) return EXIT_CODES.auth;\n if (status === 404) return EXIT_CODES.notFound;\n if (status === 422) return EXIT_CODES.validation;\n return EXIT_CODES.general;\n}\n\nexport function httpStatusMessage(status: number, body: unknown): string {\n if (status === 401) return \"authentication failed\";\n if (status === 403) return \"authenticated OpenProject user lacks permission\";\n if (status === 404) return \"resource not found or not visible to this user\";\n if (status === 409) return \"possible stale lockVersion or concurrent modification\";\n if (status === 422) return `validation failed${validationDetail(body)}`;\n return `OpenProject request failed with HTTP ${status}`;\n}\n\nfunction validationDetail(body: unknown): string {\n if (!body || typeof body !== \"object\") return \"\";\n const message = \"message\" in body && typeof body.message === \"string\" ? body.message : undefined;\n const errorIdentifier = \"errorIdentifier\" in body && typeof body.errorIdentifier === \"string\" ? body.errorIdentifier : undefined;\n const errors = \"_embedded\" in body ? body._embedded : undefined;\n const parts = [message, errorIdentifier, typeof errors === \"object\" && errors !== null ? JSON.stringify(errors) : undefined].filter(Boolean);\n return parts.length === 0 ? \"\" : `: ${parts.join(\"; \")}`;\n}\n\nexport function toOpctlError(error: unknown): OpctlError {\n if (error instanceof OpctlError) return error;\n if (error instanceof Error) return new OpctlError(error.message);\n return new OpctlError(\"unexpected failure\");\n}\n","import { redactSecrets } from \"../client/auth.js\";\n\nexport function stableJson(value: unknown, token?: string): string {\n return `${redactSecrets(JSON.stringify(sortForJson(value), null, 2), token)}\\n`;\n}\n\nfunction sortForJson(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(sortForJson);\n if (!value || typeof value !== \"object\") return value;\n const sorted: Record<string, unknown> = {};\n for (const key of Object.keys(value).sort()) sorted[key] = sortForJson((value as Record<string, unknown>)[key]);\n return sorted;\n}\n","import type { AttachmentSummary, LinkSummary, PrioritySummary, ProjectSummary, StatusSummary, TypeSummary, UserSummary, WorkPackageDetail, WorkPackageSummary } from \"../types/domain.js\";\n\ntype HalObject = Record<string, unknown>;\n\nexport function asObject(value: unknown): HalObject | undefined {\n return value && typeof value === \"object\" ? (value as HalObject) : undefined;\n}\n\nexport function getLink(resource: unknown, name: string): LinkSummary | undefined {\n const object = asObject(resource);\n const links = asObject(object?._links);\n const raw = links?.[name];\n const link = Array.isArray(raw) ? asObject(raw[0]) : asObject(raw);\n if (!link) return undefined;\n const href = typeof link.href === \"string\" ? link.href : undefined;\n const title = typeof link.title === \"string\" ? link.title : undefined;\n const method = typeof link.method === \"string\" ? link.method : undefined;\n if (!href && !title && !method) return undefined;\n return { ...(href ? { href } : {}), ...(title ? { title } : {}), ...(method ? { method } : {}) };\n}\n\nexport function requireLinkHref(resource: unknown, name: string): string | undefined {\n return getLink(resource, name)?.href;\n}\n\nexport function collectionElements(resource: unknown): unknown[] {\n const embedded = asObject(asObject(resource)?._embedded);\n const elements = embedded?.elements;\n return Array.isArray(elements) ? elements : [];\n}\n\nexport function collectionTotal(resource: unknown): number | undefined {\n const total = asObject(resource)?.total;\n return typeof total === \"number\" ? total : undefined;\n}\n\nexport function normalizeUser(resource: unknown): UserSummary {\n const object = asObject(resource) ?? {};\n return {\n id: numberField(object.id),\n name: stringField(object.name),\n login: stringField(object.login),\n email: stringField(object.email),\n href: getLink(object, \"self\")?.href,\n };\n}\n\nexport function normalizeProject(resource: unknown): ProjectSummary {\n const object = asObject(resource) ?? {};\n return {\n id: numberField(object.id),\n identifier: stringField(object.identifier),\n name: stringField(object.name),\n href: getLink(object, \"self\")?.href,\n };\n}\n\nexport function normalizeWorkPackageSummary(resource: unknown): WorkPackageSummary {\n const object = asObject(resource) ?? {};\n return {\n id: numberField(object.id),\n subject: stringField(object.subject),\n status: getLink(object, \"status\")?.title,\n assignee: getLink(object, \"assignee\")?.title,\n responsible: getLink(object, \"responsible\")?.title,\n project: getLink(object, \"project\")?.title,\n type: getLink(object, \"type\")?.title,\n priority: getLink(object, \"priority\")?.title,\n href: getLink(object, \"self\")?.href,\n updatedAt: stringField(object.updatedAt),\n shortDescription: shortDescription(extractDescription(object.description)),\n attachmentsCount: attachmentsCount(object),\n };\n}\n\nexport function normalizeWorkPackageDetail(resource: unknown): WorkPackageDetail {\n const object = asObject(resource) ?? {};\n return {\n ...normalizeWorkPackageSummary(object),\n description: extractDescription(object.description),\n shortDescription: shortDescription(extractDescription(object.description)),\n attachmentsCount: attachmentsCount(object),\n lockVersion: numberField(object.lockVersion),\n actions: actionLinks(object),\n };\n}\n\nexport function normalizeAttachment(resource: unknown): AttachmentSummary {\n const object = asObject(resource) ?? {};\n return {\n id: numberField(object.id),\n fileName: stringField(object.fileName),\n contentType: stringField(object.contentType),\n fileSize: numberField(object.fileSize) ?? numberField(object.filesize),\n description: extractDescription(object.description),\n href: getLink(object, \"self\")?.href,\n downloadHref: getLink(object, \"staticDownloadLocation\")?.href ?? getLink(object, \"downloadLocation\")?.href,\n containerHref: getLink(object, \"container\")?.href,\n author: getLink(object, \"author\")?.title,\n createdAt: stringField(object.createdAt),\n };\n}\n\nexport function actionLinks(resource: unknown): Record<string, LinkSummary> {\n const links = asObject(asObject(resource)?._links) ?? {};\n const actions: Record<string, LinkSummary> = {};\n for (const [name, value] of Object.entries(links)) {\n const link = Array.isArray(value) ? asObject(value[0]) : asObject(value);\n if (!link) continue;\n const method = typeof link.method === \"string\" ? link.method : undefined;\n if (!method && !name.startsWith(\"add\") && !name.includes(\"update\") && !name.includes(\"delete\")) continue;\n const summary = getLink(resource, name);\n if (summary) actions[name] = summary;\n }\n return actions;\n}\n\nexport function extractDescription(value: unknown): string | undefined {\n if (typeof value === \"string\") return value;\n const object = asObject(value);\n const raw = typeof object?.raw === \"string\" ? object.raw : undefined;\n const html = typeof object?.html === \"string\" ? object.html : undefined;\n return raw ?? (html ? html.replace(/<[^>]+>/g, \" \").replace(/\\s+/g, \" \").trim() : undefined);\n}\n\nfunction shortDescription(description: string | undefined): string | undefined {\n if (!description) return undefined;\n const compact = description.replace(/\\s+/g, \" \").trim();\n if (compact === \"\") return undefined;\n return compact.length <= 160 ? compact : `${compact.slice(0, 157)}...`;\n}\n\nfunction attachmentsCount(resource: HalObject): number | undefined {\n const embeddedAttachments = asObject(asObject(resource._embedded)?.attachments);\n const total = numberField(embeddedAttachments?.total) ?? numberField(embeddedAttachments?.count);\n if (total !== undefined) return total;\n const elements = embeddedAttachments?.elements;\n if (Array.isArray(elements)) return elements.length;\n const direct = asObject(resource.attachments);\n const directTotal = numberField(direct?.total) ?? numberField(direct?.count);\n if (directTotal !== undefined) return directTotal;\n const directElements = direct?.elements;\n if (Array.isArray(directElements)) return directElements.length;\n return undefined;\n}\n\nfunction stringField(value: unknown): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction numberField(value: unknown): number | undefined {\n return typeof value === \"number\" ? value : undefined;\n}\n\nexport function normalizeType(resource: unknown): TypeSummary {\n const object = asObject(resource) ?? {};\n return {\n id: numberField(object.id),\n name: stringField(object.name),\n href: requireLinkHref(resource, \"self\"),\n position: numberField(object.position),\n isDefault: booleanField(object.isDefault),\n isMilestone: booleanField(object.isMilestone),\n };\n}\n\nexport function normalizeStatus(resource: unknown): StatusSummary {\n const object = asObject(resource) ?? {};\n return {\n id: numberField(object.id),\n name: stringField(object.name),\n href: requireLinkHref(resource, \"self\"),\n position: numberField(object.position),\n isClosed: booleanField(object.isClosed),\n isDefault: booleanField(object.isDefault),\n isReadonly: booleanField(object.isReadonly),\n };\n}\n\nexport function normalizePriority(resource: unknown): PrioritySummary {\n const object = asObject(resource) ?? {};\n return {\n id: numberField(object.id),\n name: stringField(object.name),\n href: requireLinkHref(resource, \"self\"),\n position: numberField(object.position),\n isDefault: booleanField(object.isDefault),\n isActive: booleanField(object.isActive),\n };\n}\n\nfunction booleanField(value: unknown): boolean | undefined {\n return typeof value === \"boolean\" ? value : undefined;\n}\n","export function renderKeyValue(value: Record<string, unknown>): string {\n return `${Object.entries(value)\n .filter(([, item]) => item !== undefined)\n .map(([key, item]) => `${key}: ${String(item)}`)\n .join(\"\\n\")}\\n`;\n}\n","import { collectionElements, collectionTotal } from \"./hal.js\";\n\nexport interface PageOptions {\n readonly pageSize?: number;\n}\n\nexport interface NormalizedCollection<T> {\n readonly elements: readonly T[];\n readonly total?: number;\n readonly count: number;\n}\n\nexport function normalizePageSize(value: unknown, fallback = 25): number {\n if (value === undefined || value === null || value === \"\") return fallback;\n const parsed = typeof value === \"number\" ? value : Number(value);\n if (!Number.isInteger(parsed) || parsed < 1 || parsed > 100) throw new Error(\"page size must be an integer between 1 and 100\");\n return parsed;\n}\n\nexport function normalizeCollection<T>(resource: unknown, mapper: (value: unknown) => T): NormalizedCollection<T> {\n const elements = collectionElements(resource).map(mapper);\n const total = collectionTotal(resource);\n return { elements, ...(total === undefined ? {} : { total }), count: elements.length };\n}\n","/**\n * Convert an API href like `/api/v3/work_packages/23732` (or with instance\n * prefix `/openproject/api/v3/work_packages/23732`) into a browser-facing URL\n * by stripping the `/api/v3` segment and combining with the instance base URL.\n */\nexport function apiHrefToBrowserUrl(baseUrl: string, href: string | undefined): string | undefined {\n if (!href) return undefined;\n const apiMarker = \"/api/v3/\";\n const markerIndex = href.indexOf(apiMarker);\n if (markerIndex === -1) return undefined;\n const afterApi = href.slice(markerIndex + apiMarker.length);\n // Drop query and hash from the remaining path\n const pathAfterApi = afterApi.split(\"?\")[0]!.split(\"#\")[0]!;\n // Determine the base: baseUrl minus any trailing slash\n const base = baseUrl.replace(/\\/+$/, \"\");\n return `${base}/${pathAfterApi}`;\n}\n","import createClient, { type Client } from \"openapi-fetch\";\nimport { createAuthorizationHeader } from \"./auth.js\";\nimport { OpenProjectHttpError, NetworkError, WriteBlockedError, OpctlError, EXIT_CODES } from \"./errors.js\";\nimport { getLink, normalizeAttachment, normalizePriority, normalizeProject, normalizeStatus, normalizeType, normalizeUser, normalizeWorkPackageDetail, normalizeWorkPackageSummary, requireLinkHref } from \"./hal.js\";\nimport { normalizeCollection, normalizePageSize, type NormalizedCollection } from \"./pagination.js\";\nimport { apiHrefToBrowserUrl } from \"./urls.js\";\nimport type { OpctlConfig } from \"../config.js\";\nimport type { paths } from \"../generated/openproject.js\";\nimport type { AttachmentSummary, CommentResult, PrioritySummary, ProjectSummary, StatusSummary, TypeSummary, UserSummary, WorkPackageCreateResult, WorkPackageDetail, WorkPackageSummary } from \"../types/domain.js\";\n\nexport interface SearchWorkPackagesOptions {\n readonly project?: string;\n readonly subject?: string;\n readonly assigneeMe?: boolean;\n readonly responsibleMe?: boolean;\n readonly responsible?: string;\n readonly status?: string;\n readonly notStatus?: readonly string[];\n readonly open?: boolean;\n readonly filters?: readonly GenericFilter[];\n readonly sort?: readonly SortCriterion[];\n readonly pageSize?: number;\n}\n\nexport interface GenericFilter {\n readonly field: string;\n readonly operator: string;\n readonly values: readonly string[];\n}\n\nexport interface SortCriterion {\n readonly field: string;\n readonly direction: \"asc\" | \"desc\";\n}\n\nexport interface ListTypesOptions {\n readonly project?: string | undefined;\n}\n\nexport interface CreateWorkPackageOptions {\n readonly project: string;\n readonly type: string;\n readonly subject: string;\n readonly description?: string | undefined;\n readonly status?: string | undefined;\n readonly priority?: string | undefined;\n readonly dryRun: boolean;\n}\n\nexport interface OpenProjectClientOptions {\n readonly config: OpctlConfig;\n readonly fetchImpl?: typeof fetch;\n readonly timeoutMs?: number;\n}\n\nexport class OpenProjectClient {\n private readonly config: OpctlConfig;\n private readonly fetchImpl: typeof fetch;\n private readonly timeoutMs: number;\n private readonly typedClient: Client<paths>;\n\n public constructor(options: OpenProjectClientOptions) {\n this.config = options.config;\n this.fetchImpl = options.fetchImpl ?? fetch;\n this.timeoutMs = options.timeoutMs ?? 30_000;\n this.typedClient = createClient<paths>({ baseUrl: `${this.config.baseUrl}/api/v3` });\n void this.typedClient;\n }\n\n public async getApiRoot(): Promise<unknown> {\n return this.request(\"GET\", \"/api/v3\");\n }\n\n public async getMe(): Promise<UserSummary> {\n return normalizeUser(await this.request(\"GET\", \"/api/v3/users/me\"));\n }\n\n public async listProjects(options: { readonly pageSize?: number } = {}): Promise<NormalizedCollection<ProjectSummary>> {\n const params = new URLSearchParams({ pageSize: String(normalizePageSize(options.pageSize)) });\n return normalizeCollection(await this.request(\"GET\", `/api/v3/projects?${params}`), normalizeProject);\n }\n\n public async getWorkPackageRaw(id: number): Promise<unknown> {\n return this.request(\"GET\", `/api/v3/work_packages/${encodeURIComponent(String(id))}`);\n }\n\n public async getWorkPackage(id: number): Promise<WorkPackageDetail> {\n const detail = normalizeWorkPackageDetail(await this.getWorkPackageRaw(id));\n return { ...detail, browserUrl: apiHrefToBrowserUrl(this.config.baseUrl, detail.href) };\n }\n\n public async searchWorkPackages(options: SearchWorkPackagesOptions): Promise<NormalizedCollection<WorkPackageSummary>> {\n const effectiveProject = options.project ?? this.config.defaultProject;\n const basePath = effectiveProject\n ? `/api/v3/projects/${encodeURIComponent(effectiveProject)}/work_packages`\n : \"/api/v3/work_packages\";\n const params = new URLSearchParams({ pageSize: String(normalizePageSize(options.pageSize)) });\n const filters = await this.buildResolvedWorkPackageFilters(options);\n if (filters.length > 0) params.set(\"filters\", JSON.stringify(filters));\n const sortBy = buildSortBy(options.sort);\n if (sortBy.length > 0) params.set(\"sortBy\", JSON.stringify(sortBy));\n const baseUrl = this.config.baseUrl;\n return normalizeCollection(await this.request(\"GET\", `${basePath}?${params}`), (raw) => {\n const wp = normalizeWorkPackageSummary(raw);\n return { ...wp, browserUrl: apiHrefToBrowserUrl(baseUrl, wp.href) };\n });\n }\n\n public async mine(options: Omit<SearchWorkPackagesOptions, \"assigneeMe\" | \"open\">): Promise<NormalizedCollection<WorkPackageSummary>> {\n await this.getMe();\n return this.searchWorkPackages({ ...options, assigneeMe: true, open: true });\n }\n\n public async accountable(options: Omit<SearchWorkPackagesOptions, \"responsibleMe\" | \"open\">): Promise<NormalizedCollection<WorkPackageSummary>> {\n await this.getMe();\n return this.searchWorkPackages({ ...options, responsibleMe: true, open: true });\n }\n\n public async listWorkPackageAttachments(id: number): Promise<NormalizedCollection<AttachmentSummary>> {\n const raw = await this.request(\"GET\", `/api/v3/work_packages/${encodeURIComponent(String(id))}/attachments`);\n return normalizeCollection(raw, normalizeAttachment);\n }\n\n public async downloadAttachment(attachment: AttachmentSummary): Promise<ArrayBuffer> {\n if (!attachment.downloadHref) throw new OpctlError(`attachment ${attachment.id ?? attachment.fileName ?? \"unknown\"} has no download href`, EXIT_CODES.validation);\n const response = await this.fetchRaw(\"GET\", attachment.downloadHref);\n return response.arrayBuffer();\n }\n\n public async commentWorkPackage(id: number, message: string, dryRun: boolean): Promise<CommentResult> {\n if (!this.config.allowWrite) throw new WriteBlockedError();\n if (message.trim() === \"\") throw new OpctlError(\"comment message must not be empty\", EXIT_CODES.validation);\n const raw = await this.getWorkPackageRaw(id);\n const detail = normalizeWorkPackageDetail(raw);\n const commentHref = findCommentHref(raw);\n if (!commentHref) {\n throw new OpctlError(\"commenting this work package is unsupported by the current OpenProject response/spec; no documented comment action link was found\", EXIT_CODES.validation);\n }\n const payload = { comment: { raw: message } };\n if (dryRun) {\n return { id, subject: detail.subject, status: \"dry-run\", request: { method: \"POST\", path: commentHref, payload } };\n }\n const response = await this.request(\"POST\", commentHref, payload);\n return { id, subject: detail.subject, status: \"comment posted\", link: getLink(response, \"self\")?.href ?? requireLinkHref(raw, \"self\") };\n }\n\n public async listTypes(options: ListTypesOptions = {}): Promise<NormalizedCollection<TypeSummary>> {\n const path = options.project\n ? `/api/v3/projects/${encodeURIComponent(options.project)}/types`\n : \"/api/v3/types\";\n return normalizeCollection(await this.request(\"GET\", path), normalizeType);\n }\n\n public async listStatuses(): Promise<NormalizedCollection<StatusSummary>> {\n return normalizeCollection(await this.request(\"GET\", \"/api/v3/statuses\"), normalizeStatus);\n }\n\n public async listPriorities(): Promise<NormalizedCollection<PrioritySummary>> {\n return normalizeCollection(await this.request(\"GET\", \"/api/v3/priorities\"), normalizePriority);\n }\n\n public async createWorkPackage(options: CreateWorkPackageOptions): Promise<WorkPackageCreateResult> {\n if (!this.config.allowWrite) throw new WriteBlockedError();\n\n const project = options.project.trim();\n const subject = options.subject.trim();\n if (!project) throw new OpctlError(\"project must not be empty\", EXIT_CODES.validation);\n if (!options.type || !options.type.trim()) throw new OpctlError(\"type must not be empty\", EXIT_CODES.validation);\n if (!subject) throw new OpctlError(\"subject must not be empty\", EXIT_CODES.validation);\n\n const typeCollection = await this.listTypes({ project });\n const resolvedTypeHref = resolveResourceHref(\"type\", options.type, typeCollection.elements, \"opctl types [--project <project>]\");\n\n let resolvedStatusHref: string | undefined;\n if (options.status && options.status.trim()) {\n const statusCollection = await this.listStatuses();\n resolvedStatusHref = resolveResourceHref(\"status\", options.status, statusCollection.elements, \"opctl statuses\");\n }\n\n let resolvedPriorityHref: string | undefined;\n if (options.priority && options.priority.trim()) {\n const priorityCollection = await this.listPriorities();\n resolvedPriorityHref = resolveResourceHref(\"priority\", options.priority, priorityCollection.elements, \"opctl priorities\");\n }\n\n const payload = {\n subject,\n ...(options.description !== undefined ? { description: { format: \"markdown\", raw: options.description } } : {}),\n _links: {\n project: { href: `/api/v3/projects/${project}` },\n type: { href: resolvedTypeHref },\n ...(resolvedStatusHref ? { status: { href: resolvedStatusHref } } : {}),\n ...(resolvedPriorityHref ? { priority: { href: resolvedPriorityHref } } : {}),\n },\n };\n\n const form = await this.request(\"POST\", \"/api/v3/work_packages/form\", payload);\n const validationErrors = extractFormValidationErrors(form);\n const errorKeys = Object.keys(validationErrors);\n if (errorKeys.length > 0) {\n const formatted = errorKeys.map((key) => `${key}: ${validationErrors[key]}`).join(\"; \");\n throw new OpctlError(`work package create validation failed: ${formatted}`, EXIT_CODES.validation, validationErrors);\n }\n\n if (options.dryRun) {\n return { subject, status: \"dry-run\", request: { method: \"POST\", path: \"/api/v3/work_packages\", payload } };\n }\n\n const created = await this.request(\"POST\", \"/api/v3/work_packages\", payload);\n const detail = normalizeWorkPackageDetail(created);\n return {\n id: detail.id,\n subject: detail.subject,\n status: \"created\",\n href: detail.href,\n browserUrl: apiHrefToBrowserUrl(this.config.baseUrl, detail.href),\n };\n }\n\n private async buildResolvedWorkPackageFilters(options: SearchWorkPackagesOptions): Promise<unknown[]> {\n const filters = [...buildWorkPackageFilters(options)];\n if (options.notStatus) {\n for (const status of options.notStatus) {\n filters.push({ status: { operator: \"!\", values: [await this.resolveStatusFilterValue(status)] } });\n }\n }\n if (options.filters) {\n for (const filter of options.filters) filters.push({ [filter.field]: { operator: filter.operator, values: filter.values } });\n }\n return filters;\n }\n\n private async resolveStatusFilterValue(raw: string): Promise<string> {\n const trimmed = raw.trim();\n if (!trimmed) throw new OpctlError(\"status filter value must not be empty\", EXIT_CODES.validation);\n const idFromHref = idFromApiHref(trimmed, \"/api/v3/statuses/\");\n if (idFromHref) return idFromHref;\n if (/^\\d+$/.test(trimmed)) return trimmed;\n const statuses = await this.listStatuses();\n const lower = trimmed.toLowerCase();\n const matches = statuses.elements.filter((status) => status.name?.toLowerCase() === lower);\n if (matches.length === 0) throw new OpctlError(`unknown status '${trimmed}'; run opctl statuses to list valid values`, EXIT_CODES.validation);\n if (matches.length > 1) {\n const list = matches.map((status) => `${status.name} (${status.href})`).join(\", \");\n throw new OpctlError(`ambiguous status '${trimmed}'; matches: ${list}`, EXIT_CODES.validation);\n }\n const href = matches[0]?.href;\n const id = idFromApiHref(href, \"/api/v3/statuses/\");\n if (!id) throw new OpctlError(`status '${trimmed}' has no usable href`, EXIT_CODES.validation);\n return id;\n }\n\n private async request(method: \"GET\" | \"POST\" | \"PATCH\", pathOrHref: string, body?: unknown): Promise<unknown> {\n const response = await this.fetchRaw(method, pathOrHref, body);\n return parseResponse(response);\n }\n\n private async fetchRaw(method: \"GET\" | \"POST\" | \"PATCH\", pathOrHref: string, body?: unknown): Promise<Response> {\n const url = pathOrHref.startsWith(\"http://\") || pathOrHref.startsWith(\"https://\")\n ? pathOrHref\n : `${this.config.baseUrl}${pathOrHref.startsWith(\"/\") ? \"\" : \"/\"}${pathOrHref}`;\n const includeAuthorization = !pathOrHref.startsWith(\"http://\") && !pathOrHref.startsWith(\"https://\")\n || url.startsWith(`${this.config.baseUrl}/`)\n || url === this.config.baseUrl;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), this.timeoutMs);\n try {\n const response = await this.fetchImpl(url, {\n method,\n signal: controller.signal,\n headers: {\n Accept: \"application/hal+json, application/json\",\n ...(body === undefined ? {} : { \"Content-Type\": \"application/json\" }),\n ...(includeAuthorization ? { Authorization: createAuthorizationHeader(this.config.authMode, this.config.token) } : {}),\n },\n ...(body === undefined ? {} : { body: JSON.stringify(body) }),\n });\n if (!response.ok) throw new OpenProjectHttpError(response.status, await parseResponse(response));\n return response;\n } catch (error) {\n if (error instanceof OpenProjectHttpError || error instanceof OpctlError) throw error;\n if (error instanceof Error && error.name === \"AbortError\") throw new NetworkError(\"OpenProject request timed out\");\n throw new NetworkError(error instanceof Error ? error.message : \"OpenProject network request failed\");\n } finally {\n clearTimeout(timeout);\n }\n }\n}\n\nexport function buildWorkPackageFilters(options: Pick<SearchWorkPackagesOptions, \"subject\" | \"assigneeMe\" | \"responsibleMe\" | \"responsible\" | \"status\" | \"open\">): unknown[] {\n const filters: unknown[] = [];\n if (options.subject && options.subject.trim() !== \"\") filters.push({ subject: { operator: \"~\", values: [options.subject] } });\n if (options.assigneeMe) filters.push({ assignee: { operator: \"=\", values: [\"me\"] } });\n if (options.responsibleMe) filters.push({ responsible: { operator: \"=\", values: [\"me\"] } });\n if (options.responsible && options.responsible.trim() !== \"\") filters.push({ responsible: { operator: \"=\", values: [normalizeUserFilterValue(options.responsible)] } });\n const status = options.status?.trim();\n if (options.open || status === \"open\") filters.push({ status: { operator: \"o\", values: [] } });\n else if (status) filters.push({ status: { operator: \"=\", values: [status] } });\n return filters;\n}\n\nexport function buildSortBy(sort: readonly SortCriterion[] | undefined): unknown[] {\n return (sort ?? []).map((criterion) => [criterion.field, criterion.direction]);\n}\n\nexport function normalizeUserFilterValue(raw: string): string {\n const trimmed = raw.trim();\n if (!trimmed) throw new OpctlError(\"user filter value must not be empty\", EXIT_CODES.validation);\n if (trimmed === \"me\") return \"me\";\n const id = idFromApiHref(trimmed, \"/api/v3/users/\");\n if (id) return id;\n if (/^\\d+$/.test(trimmed)) return trimmed;\n throw new OpctlError(\"--responsible supports me, numeric user ids, or /api/v3/users/<id> hrefs\", EXIT_CODES.validation);\n}\n\nfunction findCommentHref(resource: unknown): string | undefined {\n for (const name of [\"addComment\", \"addCommentImmediately\", \"comment\", \"addWorkPackageComment\"]) {\n const link = getLink(resource, name);\n if (link?.href && (!link.method || link.method.toUpperCase() === \"POST\")) return link.href;\n }\n return undefined;\n}\n\nasync function parseResponse(response: Response): Promise<unknown> {\n if (response.status === 204) return undefined;\n const text = await response.text();\n if (text.trim() === \"\") return undefined;\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n if (contentType.includes(\"json\") || contentType.includes(\"hal\")) {\n try {\n return JSON.parse(text);\n } catch {\n return { message: \"OpenProject returned invalid JSON\" };\n }\n }\n return { message: text };\n}\n\nfunction resolveResourceHref(kind: string, raw: string, collection: readonly { readonly name?: string | undefined; readonly href?: string | undefined; readonly id?: number | undefined }[], commandHint: string): string {\n const trimmed = raw.trim();\n if (!trimmed) throw new OpctlError(`${kind} must not be empty`, EXIT_CODES.validation);\n if (trimmed.startsWith(\"/api/v3/\") || trimmed.startsWith(\"http://\") || trimmed.startsWith(\"https://\")) return trimmed;\n if (/^\\d+$/.test(trimmed)) {\n const apiPrefix = kind === \"type\" ? \"/api/v3/types\" : kind === \"status\" ? \"/api/v3/statuses\" : \"/api/v3/priorities\";\n return `${apiPrefix}/${trimmed}`;\n }\n const lowerName = trimmed.toLowerCase();\n const matches = collection.filter((item) => item.name?.toLowerCase() === lowerName);\n if (matches.length === 0) throw new OpctlError(`unknown ${kind} '${trimmed}'; run ${commandHint} to list valid values`, EXIT_CODES.validation);\n if (matches.length > 1) {\n const list = matches.map((m) => `${m.name} (${m.href})`).join(\", \");\n throw new OpctlError(`ambiguous ${kind} '${trimmed}'; matches: ${list}`, EXIT_CODES.validation);\n }\n return matches[0]!.href!;\n}\n\nfunction extractFormValidationErrors(form: unknown): Record<string, string> {\n const embedded = typeof form === \"object\" && form !== null ? (form as Record<string, unknown>)._embedded : undefined;\n const raw = typeof embedded === \"object\" && embedded !== null ? (embedded as Record<string, unknown>).validationErrors : undefined;\n if (!raw || typeof raw !== \"object\") return {};\n const result: Record<string, string> = {};\n for (const [key, value] of Object.entries(raw as Record<string, unknown>)) {\n if (typeof value === \"object\" && value !== null && \"message\" in value && typeof (value as Record<string, unknown>).message === \"string\") {\n result[key] = (value as Record<string, unknown>).message as string;\n } else {\n result[key] = JSON.stringify(value);\n }\n }\n return result;\n}\n\nfunction idFromApiHref(value: string | undefined, prefix: string): string | undefined {\n if (!value) return undefined;\n const index = value.indexOf(prefix);\n if (index === -1) return undefined;\n const rest = value.slice(index + prefix.length).split(/[/?#]/)[0];\n return rest && /^\\d+$/.test(rest) ? rest : undefined;\n}\n","import { readFileSync } from \"node:fs\";\nimport { ConfigurationError } from \"../client/errors.js\";\nimport type { EnvReader } from \"../config.js\";\n\nconst ALLOWED_ENV_KEYS: Record<string, true> = {\n OPENPROJECT_AUTH_MODE: true,\n OPENPROJECT_DEFAULT_PROJECT: true,\n OPENPROJECT_TOKEN: true,\n OPENPROJECT_URL: true,\n};\n\nexport function loadEnvFile(path: string): EnvReader {\n return parseEnvFile(readFileSync(path, \"utf8\"));\n}\n\nexport function parseEnvFile(content: string): EnvReader {\n const env: Record<string, string> = {};\n const lines = content.split(/\\r?\\n/);\n for (let index = 0; index < lines.length; index += 1) {\n const parsed = parseLine(lines[index] ?? \"\", index + 1);\n if (!parsed) continue;\n if (ALLOWED_ENV_KEYS[parsed.key] !== true) continue;\n env[parsed.key] = parsed.value;\n }\n return env;\n}\n\nfunction parseLine(line: string, lineNumber: number): { readonly key: string; readonly value: string } | undefined {\n const trimmed = line.trim();\n if (trimmed === \"\" || trimmed.startsWith(\"#\")) return undefined;\n const equals = trimmed.indexOf(\"=\");\n if (equals <= 0) throw new ConfigurationError(`invalid .env line ${lineNumber}`);\n const key = trimmed.slice(0, equals).trim();\n if (!/^OPENPROJECT_[A-Z_]+$/.test(key)) return undefined;\n const rawValue = trimmed.slice(equals + 1).trim();\n return { key, value: unquoteValue(rawValue, lineNumber) };\n}\n\nfunction unquoteValue(value: string, lineNumber: number): string {\n if (value.startsWith('\"')) {\n if (!value.endsWith('\"') || value.length === 1) throw new ConfigurationError(`unterminated quoted value on .env line ${lineNumber}`);\n return value.slice(1, -1).replace(/\\\\n/g, \"\\n\").replace(/\\\\\"/g, '\"').replace(/\\\\\\\\/g, \"\\\\\");\n }\n if (value.startsWith(\"'\")) {\n if (!value.endsWith(\"'\") || value.length === 1) throw new ConfigurationError(`unterminated quoted value on .env line ${lineNumber}`);\n return value.slice(1, -1);\n }\n const hash = value.indexOf(\" #\");\n return (hash >= 0 ? value.slice(0, hash) : value).trim();\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync, chmodSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { ConfigurationError } from \"../client/errors.js\";\nimport type { EnvReader } from \"../config.js\";\n\nexport interface Profile {\n readonly url?: string;\n readonly authMode?: string;\n readonly defaultProject?: string;\n readonly token?: string;\n}\n\ninterface ProfileStore {\n readonly activeProfile?: string;\n readonly profiles: Record<string, Profile>;\n}\n\nconst EMPTY_STORE: ProfileStore = { profiles: {} };\n\nexport function profilesPath(env: NodeJS.ProcessEnv = process.env): string {\n const configHome = env.XDG_CONFIG_HOME && env.XDG_CONFIG_HOME.trim() !== \"\" ? env.XDG_CONFIG_HOME : join(homedir(), \".config\");\n return join(configHome, \"opctl\", \"profiles.json\");\n}\n\nexport function loadProfileStore(path = profilesPath()): ProfileStore {\n if (!existsSync(path)) return EMPTY_STORE;\n const parsed = JSON.parse(readFileSync(path, \"utf8\")) as unknown;\n if (!parsed || typeof parsed !== \"object\") throw new ConfigurationError(\"profile store is invalid\");\n const object = parsed as Record<string, unknown>;\n const profiles = object.profiles;\n if (!profiles || typeof profiles !== \"object\" || Array.isArray(profiles)) throw new ConfigurationError(\"profile store is invalid\");\n return {\n ...(typeof object.activeProfile === \"string\" ? { activeProfile: object.activeProfile } : {}),\n profiles: profiles as Record<string, Profile>,\n };\n}\n\nexport function saveProfileStore(store: ProfileStore, path = profilesPath()): void {\n mkdirSync(dirname(path), { recursive: true, mode: 0o700 });\n try { chmodSync(dirname(path), 0o700); } catch { /* best effort on platforms without chmod */ }\n writeFileSync(path, `${JSON.stringify(store, null, 2)}\\n`, { mode: 0o600 });\n try { chmodSync(path, 0o600); } catch { /* best effort on platforms without chmod */ }\n}\n\nexport function profileToEnv(profile: Profile | undefined): EnvReader {\n if (!profile) return {};\n return {\n ...(profile.url ? { OPENPROJECT_URL: profile.url } : {}),\n ...(profile.authMode ? { OPENPROJECT_AUTH_MODE: profile.authMode } : {}),\n ...(profile.defaultProject ? { OPENPROJECT_DEFAULT_PROJECT: profile.defaultProject } : {}),\n ...(profile.token ? { OPENPROJECT_TOKEN: profile.token } : {}),\n };\n}\n\nexport function getProfileEnv(name: string | undefined, env: NodeJS.ProcessEnv = process.env): EnvReader {\n const store = loadProfileStore(profilesPath(env));\n const selected = name ?? store.activeProfile;\n if (!selected) return {};\n const profile = store.profiles[selected];\n if (!profile) throw new ConfigurationError(`profile '${selected}' does not exist`);\n return profileToEnv(profile);\n}\n\nexport function listProfiles(env: NodeJS.ProcessEnv = process.env): ReadonlyArray<{ readonly name: string; readonly active: boolean; readonly profile: Profile }> {\n const store = loadProfileStore(profilesPath(env));\n return Object.entries(store.profiles).sort(([left], [right]) => left.localeCompare(right)).map(([name, profile]) => ({ name, active: name === store.activeProfile, profile }));\n}\n\nexport function setProfile(name: string, profile: Profile, env: NodeJS.ProcessEnv = process.env): void {\n validateProfileName(name);\n const path = profilesPath(env);\n const store = loadProfileStore(path);\n saveProfileStore({ ...store, profiles: { ...store.profiles, [name]: cleanProfile(profile) } }, path);\n}\n\nexport function useProfile(name: string, env: NodeJS.ProcessEnv = process.env): void {\n validateProfileName(name);\n const path = profilesPath(env);\n const store = loadProfileStore(path);\n if (!store.profiles[name]) throw new ConfigurationError(`profile '${name}' does not exist`);\n saveProfileStore({ ...store, activeProfile: name }, path);\n}\n\nexport function unsetProfile(name: string, env: NodeJS.ProcessEnv = process.env): void {\n validateProfileName(name);\n const path = profilesPath(env);\n const store = loadProfileStore(path);\n const { [name]: _removed, ...profiles } = store.profiles;\n saveProfileStore({ ...(store.activeProfile === name ? {} : { activeProfile: store.activeProfile }), profiles }, path);\n}\n\nexport function showProfile(name: string | undefined, env: NodeJS.ProcessEnv = process.env): { readonly name?: string; readonly profile?: Profile } {\n const store = loadProfileStore(profilesPath(env));\n const selected = name ?? store.activeProfile;\n if (!selected) return {};\n const profile = store.profiles[selected];\n if (!profile) throw new ConfigurationError(`profile '${selected}' does not exist`);\n return { name: selected, profile };\n}\n\nexport function redactProfile(profile: Profile): Profile & { readonly token?: string } {\n return { ...profile, ...(profile.token ? { token: \"<redacted>\" } : {}) };\n}\n\nfunction validateProfileName(name: string): void {\n if (!/^[A-Za-z0-9_.-]+$/.test(name)) throw new ConfigurationError(\"profile name may contain only letters, numbers, '.', '_', and '-'\");\n}\n\nfunction cleanProfile(profile: Profile): Profile {\n return {\n ...(profile.url && profile.url.trim() !== \"\" ? { url: profile.url.trim() } : {}),\n ...(profile.authMode && profile.authMode.trim() !== \"\" ? { authMode: profile.authMode.trim() } : {}),\n ...(profile.defaultProject && profile.defaultProject.trim() !== \"\" ? { defaultProject: profile.defaultProject.trim() } : {}),\n ...(profile.token && profile.token.trim() !== \"\" ? { token: profile.token } : {}),\n };\n}\n","import { ConfigurationError } from \"./client/errors.js\";\nimport { existsSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport { loadEnvFile } from \"./config/envFile.js\";\nimport { getProfileEnv } from \"./config/profiles.js\";\n\nexport type AuthMode = \"bearer\" | \"basic\";\n\nexport interface OpctlConfig {\n readonly baseUrl: string;\n readonly token: string;\n readonly authMode: AuthMode;\n readonly allowWrite: boolean;\n readonly defaultProject?: string;\n}\n\nexport interface EnvReader {\n readonly OPENPROJECT_URL?: string;\n readonly OPENPROJECT_TOKEN?: string;\n readonly OPENPROJECT_AUTH_MODE?: string;\n readonly OPENPROJECT_ALLOW_WRITE?: string;\n readonly OPENPROJECT_DEFAULT_PROJECT?: string;\n}\n\nexport interface ConfigResolutionOptions {\n readonly cwd?: string;\n readonly envFile?: string;\n readonly autoEnv?: boolean;\n readonly profile?: string;\n}\n\nexport function loadConfig(env: EnvReader = process.env): OpctlConfig {\n return loadConfigFromEnv(env);\n}\n\nexport function resolveConfigEnv(processEnv: NodeJS.ProcessEnv, options: ConfigResolutionOptions = {}): EnvReader {\n const cwd = options.cwd ?? process.cwd();\n const autoEnvPath = join(cwd, \".env\");\n const autoEnv = options.autoEnv === false || !existsSync(autoEnvPath) ? {} : loadEnvFile(autoEnvPath);\n const activeProfile = options.profile ? {} : getProfileEnv(undefined, processEnv);\n const selectedProfile = options.profile ? getProfileEnv(options.profile, processEnv) : {};\n const explicitEnv = options.envFile ? loadEnvFile(resolve(cwd, options.envFile)) : {};\n return mergeEnv(autoEnv, activeProfile, selectedProfile, explicitEnv, processEnv);\n}\n\nexport function loadResolvedConfig(processEnv: NodeJS.ProcessEnv, options: ConfigResolutionOptions = {}): OpctlConfig {\n return loadConfigFromEnv(resolveConfigEnv(processEnv, options));\n}\n\nexport function mergeEnv(...layers: readonly EnvReader[]): EnvReader {\n const merged: Record<string, string> = {};\n for (const layer of layers) {\n for (const key of [\"OPENPROJECT_URL\", \"OPENPROJECT_TOKEN\", \"OPENPROJECT_AUTH_MODE\", \"OPENPROJECT_ALLOW_WRITE\", \"OPENPROJECT_DEFAULT_PROJECT\"] as const) {\n const value = layer[key];\n if (value !== undefined) merged[key] = value;\n }\n }\n return merged;\n}\n\nfunction loadConfigFromEnv(env: EnvReader): OpctlConfig {\n const rawUrl = env.OPENPROJECT_URL;\n const rawToken = env.OPENPROJECT_TOKEN;\n if (!rawUrl || rawUrl.trim() === \"\") throw new ConfigurationError(\"OPENPROJECT_URL is required\");\n if (!rawToken || rawToken.trim() === \"\") throw new ConfigurationError(\"OPENPROJECT_TOKEN is required\");\n\n const authMode = parseAuthMode(env.OPENPROJECT_AUTH_MODE);\n const defaultProject = cleanOptional(env.OPENPROJECT_DEFAULT_PROJECT);\n return {\n baseUrl: normalizeBaseUrl(rawUrl),\n token: rawToken,\n authMode,\n allowWrite: env.OPENPROJECT_ALLOW_WRITE === \"1\",\n ...(defaultProject ? { defaultProject } : {}),\n };\n}\n\nexport function normalizeBaseUrl(rawUrl: string): string {\n let parsed: URL;\n try {\n parsed = new URL(rawUrl.trim());\n } catch {\n throw new ConfigurationError(\"OPENPROJECT_URL must be an absolute URL\");\n }\n if (parsed.protocol !== \"https:\" && parsed.protocol !== \"http:\") {\n throw new ConfigurationError(\"OPENPROJECT_URL must use http or https\");\n }\n parsed.hash = \"\";\n parsed.search = \"\";\n const withoutTrailing = parsed.toString().replace(/\\/+$/, \"\");\n return withoutTrailing;\n}\n\nfunction parseAuthMode(raw: string | undefined): AuthMode {\n if (!raw || raw.trim() === \"\") return \"bearer\";\n const normalized = raw.trim().toLowerCase();\n if (normalized === \"bearer\" || normalized === \"basic\") return normalized;\n throw new ConfigurationError(\"OPENPROJECT_AUTH_MODE must be bearer or basic\");\n}\n\nfunction cleanOptional(raw: string | undefined): string | undefined {\n if (!raw) return undefined;\n const value = raw.trim();\n return value === \"\" ? undefined : value;\n}\n","import type { Command } from \"commander\";\nimport { OpenProjectClient } from \"../client/openProjectClient.js\";\nimport { loadResolvedConfig, resolveConfigEnv, type ConfigResolutionOptions } from \"../config.js\";\nimport { stableJson } from \"../output/json.js\";\n\nexport interface CommandContext {\n readonly stdout: Pick<NodeJS.WriteStream, \"write\">;\n readonly stderr: Pick<NodeJS.WriteStream, \"write\">;\n readonly env: NodeJS.ProcessEnv;\n readonly fetchImpl?: typeof fetch;\n readonly cwd?: string;\n readonly stdin?: AsyncIterable<Buffer | string> & { readonly isTTY?: boolean | undefined };\n}\n\nexport function globalConfigOptions(command: Command): ConfigResolutionOptions {\n const opts = rootCommand(command).opts<Record<string, unknown>>();\n return {\n ...(typeof opts.env === \"string\" ? { envFile: opts.env } : {}),\n ...(opts.env === false ? { autoEnv: false } : {}),\n ...(typeof opts.profile === \"string\" ? { profile: opts.profile } : {}),\n };\n}\n\nexport function resolvedEnv(context: CommandContext, command: Command): NodeJS.ProcessEnv {\n return resolveConfigEnv(context.env, configOptions(context, command)) as NodeJS.ProcessEnv;\n}\n\nexport function createClient(context: CommandContext, command?: Command): OpenProjectClient {\n const config = loadResolvedConfig(context.env, command ? configOptions(context, command) : configOptions(context));\n return new OpenProjectClient({\n config,\n ...(context.fetchImpl ? { fetchImpl: context.fetchImpl } : {}),\n });\n}\n\nexport function writeOutput(context: CommandContext, value: unknown, json: boolean, renderText: () => string, token?: string): void {\n context.stdout.write(json ? stableJson(value, token ?? context.env.OPENPROJECT_TOKEN) : renderText());\n}\n\nfunction configOptions(context: CommandContext, command?: Command): ConfigResolutionOptions {\n return {\n ...(context.cwd ? { cwd: context.cwd } : {}),\n ...(command ? globalConfigOptions(command) : {}),\n };\n}\n\nfunction rootCommand(command: Command): Command {\n let current = command;\n while (current.parent) current = current.parent;\n return current;\n}\n\nexport function booleanOption(command: Command, name: string): boolean {\n return Boolean(command.opts<Record<string, unknown>>()[name]);\n}\n","import type { Command } from \"commander\";\nimport { asObject } from \"../client/hal.js\";\nimport { stableJson } from \"../output/json.js\";\nimport { renderKeyValue } from \"../output/text.js\";\nimport { createClient, resolvedEnv, type CommandContext } from \"./context.js\";\n\nexport function registerApiRoot(program: Command, context: CommandContext): void {\n program\n .command(\"api-root\")\n .description(\"Show compact OpenProject API root links\")\n .option(\"--json\", \"emit JSON\")\n .action(async (options: { json?: boolean }, command: Command) => {\n const root = await createClient(context, command).getApiRoot();\n const links = compactLinks(root);\n context.stdout.write(options.json ? stableJson(links, resolvedEnv(context, command).OPENPROJECT_TOKEN) : renderKeyValue(links));\n });\n}\n\nexport function compactLinks(root: unknown): Record<string, string> {\n const links = asObject(asObject(root)?._links) ?? {};\n const output: Record<string, string> = {};\n for (const [name, raw] of Object.entries(links)) {\n const link = Array.isArray(raw) ? asObject(raw[0]) : asObject(raw);\n if (typeof link?.href === \"string\") output[name] = link.href;\n }\n return output;\n}\n","{\n \"name\": \"opctl\",\n \"version\": \"0.1.7\",\n \"description\": \"Conservative local CLI bridge for OpenProject API v3\",\n \"type\": \"module\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/hewel/op-cli.git\"\n },\n \"bin\": {\n \"opctl\": \"dist/cli.js\"\n },\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"dev\": \"tsx src/cli.ts\",\n \"build\": \"npm run typecheck && vite build\",\n \"typecheck\": \"tsc --noEmit\",\n \"test\": \"vitest run\",\n \"openapi:pull\": \"tsx scripts/pull-openapi-spec.ts\",\n \"openapi:generate\": \"tsx scripts/generate-openapi-types.ts\",\n \"openapi:update\": \"npm run openapi:pull && npm run openapi:generate\"\n },\n \"keywords\": [\n \"openproject\",\n \"cli\"\n ],\n \"author\": \"\",\n \"license\": \"ISC\",\n \"dependencies\": {\n \"commander\": \"latest\",\n \"openapi-fetch\": \"latest\"\n },\n \"devDependencies\": {\n \"@types/node\": \"latest\",\n \"openapi-typescript\": \"latest\",\n \"tsx\": \"latest\",\n \"typescript\": \"latest\",\n \"vite\": \"latest\",\n \"vitest\": \"latest\",\n \"yaml\": \"^2.9.0\"\n },\n \"packageManager\": \"pnpm@11.1.3\"\n}\n","import type { Command } from \"commander\";\nimport { loadResolvedConfig } from \"../config.js\";\nimport { OpctlError } from \"../client/errors.js\";\nimport { stableJson } from \"../output/json.js\";\nimport { renderKeyValue } from \"../output/text.js\";\nimport { createClient, globalConfigOptions, type CommandContext } from \"./context.js\";\nimport pkg from \"../../package.json\" with { type: \"json\" };\n\ninterface DoctorOptions {\n readonly json?: boolean;\n}\n\nexport function registerDoctor(program: Command, context: CommandContext): void {\n program.command(\"doctor\")\n .description(\"Show redacted OpenProject and opctl diagnostics\")\n .option(\"--json\", \"emit JSON\")\n .action(async (options: DoctorOptions, command: Command) => {\n const configOptions = globalConfigOptions(command);\n let currentUser: unknown;\n let currentUserError: string | undefined;\n let configSummary: Record<string, unknown>;\n try {\n const config = loadResolvedConfig(context.env, { ...configOptions, ...(context.cwd ? { cwd: context.cwd } : {}) });\n configSummary = {\n url: config.baseUrl,\n authMode: config.authMode,\n defaultProject: config.defaultProject,\n writeEnabled: config.allowWrite,\n hasToken: true,\n };\n try {\n currentUser = await createClient(context, command).getMe();\n } catch (error) {\n const opctlError = error instanceof OpctlError ? error : new OpctlError(error instanceof Error ? error.message : \"current user lookup failed\");\n currentUserError = opctlError.message;\n }\n } catch (error) {\n const opctlError = error instanceof OpctlError ? error : new OpctlError(error instanceof Error ? error.message : \"doctor failed\");\n configSummary = { error: opctlError.message, hasToken: Boolean(context.env.OPENPROJECT_TOKEN) };\n }\n\n const payload = {\n version: pkg.version,\n config: configSummary,\n currentUser,\n currentUserError,\n commands: listCommandNames(program),\n wpCommands: listCommandNames(program.commands.find((child) => child.name() === \"wp\")),\n };\n if (options.json) {\n context.stdout.write(stableJson(payload, context.env.OPENPROJECT_TOKEN));\n return;\n }\n context.stdout.write(renderKeyValue({\n version: payload.version,\n url: payload.config.url,\n authMode: payload.config.authMode,\n defaultProject: payload.config.defaultProject,\n writeEnabled: payload.config.writeEnabled,\n hasToken: payload.config.hasToken,\n currentUser: userLabel(currentUser),\n currentUserError: payload.currentUserError,\n commands: payload.commands.join(\",\"),\n wpCommands: payload.wpCommands.join(\",\"),\n error: payload.config.error,\n }));\n });\n}\n\nfunction listCommandNames(command: Command | undefined): string[] {\n return command?.commands.map((child) => child.name()).sort() ?? [];\n}\n\nfunction userLabel(value: unknown): string | undefined {\n if (!value || typeof value !== \"object\") return undefined;\n const user = value as Record<string, unknown>;\n return [user.name, user.login, user.id].filter((part) => part !== undefined).join(\" \");\n}\n","export function renderTable(rows: readonly object[], columns: readonly string[]): string {\n const widths = columns.map((column) => Math.max(column.length, ...rows.map((row) => cell((row as Record<string, unknown>)[column]).length)));\n const header = columns.map((column, index) => column.padEnd(widths[index] ?? column.length)).join(\" \");\n const divider = widths.map((width) => \"-\".repeat(width)).join(\" \");\n const body = rows.map((row) => columns.map((column, index) => cell((row as Record<string, unknown>)[column]).padEnd(widths[index] ?? 0)).join(\" \"));\n return `${[header, divider, ...body].join(\"\\n\")}\\n`;\n}\n\nfunction cell(value: unknown): string {\n if (value === undefined || value === null) return \"\";\n return String(value);\n}\n","import type { Command } from \"commander\";\nimport { renderTable } from \"../output/table.js\";\nimport { createClient, type CommandContext, writeOutput } from \"./context.js\";\n\nexport function registerLookups(program: Command, context: CommandContext): void {\n program\n .command(\"types\")\n .description(\"List work package types\")\n .option(\"--project <identifier-or-id>\", \"project to scope types\")\n .option(\"--json\", \"emit JSON\")\n .action(async (options: { project?: string; json?: boolean }, command: Command) => {\n const result = await createClient(context, command).listTypes(options.project ? { project: options.project } : {});\n writeOutput(context, result, Boolean(options.json), () => renderTable(result.elements as unknown as object[], [\"id\", \"name\", \"href\", \"isDefault\", \"isMilestone\"]));\n });\n\n program\n .command(\"statuses\")\n .description(\"List work package statuses\")\n .option(\"--json\", \"emit JSON\")\n .action(async (options: { json?: boolean }, command: Command) => {\n const result = await createClient(context, command).listStatuses();\n writeOutput(context, result, Boolean(options.json), () => renderTable(result.elements as unknown as object[], [\"id\", \"name\", \"href\", \"isClosed\", \"isDefault\", \"isReadonly\"]));\n });\n\n program\n .command(\"priorities\")\n .description(\"List work package priorities\")\n .option(\"--json\", \"emit JSON\")\n .action(async (options: { json?: boolean }, command: Command) => {\n const result = await createClient(context, command).listPriorities();\n writeOutput(context, result, Boolean(options.json), () => renderTable(result.elements as unknown as object[], [\"id\", \"name\", \"href\", \"isDefault\", \"isActive\"]));\n });\n}\n","import type { Command } from \"commander\";\nimport { createClient, type CommandContext, writeOutput } from \"./context.js\";\nimport { renderKeyValue } from \"../output/text.js\";\n\nexport function registerMe(program: Command, context: CommandContext): void {\n program\n .command(\"me\")\n .description(\"Show the authenticated OpenProject user\")\n .option(\"--json\", \"emit JSON\")\n .action(async (options: { json?: boolean }, command: Command) => {\n const me = await createClient(context, command).getMe();\n writeOutput(context, me, Boolean(options.json), () => renderKeyValue(me as unknown as Record<string, unknown>));\n });\n}\n","import type { Command } from \"commander\";\nimport { renderTable } from \"../output/table.js\";\nimport { createClient, type CommandContext, writeOutput } from \"./context.js\";\n\nexport function registerProjects(program: Command, context: CommandContext): void {\n program\n .command(\"projects\")\n .description(\"List visible OpenProject projects\")\n .option(\"--json\", \"emit JSON\")\n .option(\"--page-size <n>\", \"page size\", Number)\n .action(async (options: { json?: boolean; pageSize?: number }, command: Command) => {\n const projects = await createClient(context, command).listProjects(options.pageSize === undefined ? {} : { pageSize: options.pageSize });\n writeOutput(context, projects, Boolean(options.json), () => renderTable(projects.elements, [\"id\", \"identifier\", \"name\", \"href\"]));\n });\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport { createAuthorizationHeader, redactSecrets } from \"../src/client/auth.js\";\nimport { OpenApiGenerationError } from \"../src/client/errors.js\";\nimport { normalizeBaseUrl, type AuthMode } from \"../src/config.js\";\n\nexport const PUBLIC_SPEC_BASE = \"https://community.openproject.org\";\n\nexport interface PullSpecOptions {\n readonly env?: NodeJS.ProcessEnv;\n readonly fetchImpl?: typeof fetch;\n readonly outputPath?: string;\n readonly sourceBaseUrl?: string;\n readonly timeoutMs?: number;\n readonly stdout?: Pick<typeof process.stdout, \"write\">;\n}\n\nexport interface PullSpecResult {\n readonly sourceHost: string;\n readonly outputPath: string;\n readonly title: string;\n readonly version: string;\n}\n\nexport async function pullOpenApiSpec(options: PullSpecOptions = {}): Promise<PullSpecResult> {\n const env = options.env ?? process.env;\n const outputPath = options.outputPath ?? \"openapi/openproject.json\";\n const fetchImpl = options.fetchImpl ?? fetch;\n\n // Source selection: explicit option > OPENPROJECT_SPEC_URL > public default.\n // OPENPROJECT_URL is intentionally ignored to prevent accidental private-instance leakage.\n const rawUrl = options.sourceBaseUrl ?? env.OPENPROJECT_SPEC_URL ?? PUBLIC_SPEC_BASE;\n const baseUrl = normalizeBaseUrl(rawUrl);\n\n // Auth: only use the spec-dedicated token, never OPENPROJECT_TOKEN.\n const specToken = env.OPENPROJECT_SPEC_TOKEN;\n const authMode = parseAuthMode(env.OPENPROJECT_SPEC_AUTH_MODE);\n const headers: Record<string, string> = { Accept: \"application/json\" };\n if (specToken && specToken.trim() !== \"\") {\n headers.Authorization = createAuthorizationHeader(authMode, specToken);\n }\n\n const specUrl = `${baseUrl}/api/v3/spec.json`;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), options.timeoutMs ?? 15_000);\n let response: Response;\n try {\n response = await fetchImpl(specUrl, { headers, signal: controller.signal });\n } catch (error) {\n throw new OpenApiGenerationError(`failed to download OpenProject spec from ${new URL(baseUrl).host}: ${error instanceof Error ? redactSecrets(error.message, specToken) : \"network error\"}`);\n } finally {\n clearTimeout(timeout);\n }\n\n if (!response.ok) {\n throw new OpenApiGenerationError(`failed to download OpenProject spec from ${new URL(baseUrl).host}: HTTP ${response.status}`);\n }\n\n const text = await response.text();\n let spec: unknown;\n try {\n spec = JSON.parse(text);\n } catch {\n throw new OpenApiGenerationError(\"OpenProject spec response was not valid JSON; spec.yml is not supported by this downloader\");\n }\n if (!spec || typeof spec !== \"object\") throw new OpenApiGenerationError(\"OpenProject spec response was not an object\");\n const info = \"info\" in spec && typeof spec.info === \"object\" && spec.info !== null ? spec.info : undefined;\n const title = info && \"title\" in info && typeof info.title === \"string\" ? info.title : \"OpenProject API\";\n const version = info && \"version\" in info && typeof info.version === \"string\" ? info.version : \"unknown\";\n\n await mkdir(dirname(outputPath), { recursive: true });\n await writeFile(outputPath, `${JSON.stringify(spec, null, 2)}\\n`, \"utf8\");\n const result = { sourceHost: new URL(baseUrl).host, outputPath, title, version };\n options.stdout?.write(`Downloaded OpenProject spec from ${result.sourceHost} to ${result.outputPath} (${result.title} ${result.version})\\n`);\n return result;\n}\n\nfunction parseAuthMode(raw: string | undefined): AuthMode {\n const normalized = raw?.trim().toLowerCase() ?? \"\";\n if (normalized === \"\" || normalized === \"bearer\") return \"bearer\";\n if (normalized === \"basic\") return \"basic\";\n throw new OpenApiGenerationError(\"OPENPROJECT_SPEC_AUTH_MODE must be bearer or basic\");\n}\n\nif (import.meta.url === `file://${process.argv[1]}`) {\n pullOpenApiSpec({ stdout: process.stdout }).catch((error: unknown) => {\n const message = error instanceof Error ? error.message : \"failed to pull OpenProject spec\";\n process.stderr.write(`${redactSecrets(message, process.env.OPENPROJECT_SPEC_TOKEN)}\\n`);\n process.exitCode = 8;\n });\n}\n","import type { Command } from \"commander\";\nimport { pullOpenApiSpec } from \"../../scripts/pull-openapi-spec.js\";\nimport type { CommandContext } from \"./context.js\";\n\nexport interface SpecPullOptions {\n readonly url?: string;\n readonly output?: string;\n}\n\nexport function registerSpec(program: Command, context: CommandContext): void {\n const spec = program.command(\"spec\").description(\"OpenAPI spec utilities\");\n spec.command(\"pull\")\n .description(\"Download OpenProject /api/v3/spec.json (defaults to the public community spec)\")\n .option(\"--url <url>\", \"spec source base URL (overrides OPENPROJECT_SPEC_URL)\")\n .option(\"--output <path>\", \"output file path\")\n .action(async (opts: SpecPullOptions) => {\n await pullOpenApiSpec({\n env: context.env,\n stdout: context.stdout,\n ...(context.fetchImpl ? { fetchImpl: context.fetchImpl } : {}),\n ...(opts.url ? { sourceBaseUrl: opts.url } : {}),\n ...(opts.output ? { outputPath: opts.output } : {}),\n });\n });\n}\n","import { OpctlError, EXIT_CODES } from \"../client/errors.js\";\n\nexport type WorkPackageField = \"id\" | \"subject\" | \"status\" | \"type\" | \"assignee\" | \"responsible\" | \"project\" | \"href\" | \"browserUrl\" | \"updatedAt\" | \"description\" | \"shortDescription\" | \"attachmentsCount\" | \"lockVersion\" | \"priority\";\nexport type OutputMode = \"text\" | \"table\" | \"compact\" | \"json\" | \"jsonl\" | \"rawJson\";\n\nexport const DEFAULT_COMPACT_FIELDS: readonly WorkPackageField[] = [\"id\", \"subject\", \"status\", \"assignee\", \"updatedAt\"];\nexport const DEFAULT_TABLE_FIELDS: readonly WorkPackageField[] = [\"id\", \"subject\", \"status\", \"assignee\", \"project\", \"updatedAt\"];\nexport const DEFAULT_CHECK_FIELDS: readonly WorkPackageField[] = [\"id\", \"subject\", \"status\", \"assignee\", \"responsible\", \"shortDescription\", \"attachmentsCount\"];\nexport const DETAIL_FIELDS: readonly WorkPackageField[] = [\"id\", \"subject\", \"status\", \"type\", \"assignee\", \"responsible\", \"project\", \"href\", \"browserUrl\", \"updatedAt\", \"description\", \"shortDescription\", \"attachmentsCount\", \"lockVersion\"];\n\nconst SUPPORTED_FIELDS: Record<WorkPackageField, true> = {\n assignee: true,\n attachmentsCount: true,\n browserUrl: true,\n description: true,\n href: true,\n id: true,\n lockVersion: true,\n priority: true,\n project: true,\n responsible: true,\n shortDescription: true,\n status: true,\n subject: true,\n type: true,\n updatedAt: true,\n};\n\nconst FIELD_ALIASES: Record<string, WorkPackageField> = {\n title: \"subject\",\n url: \"href\",\n};\n\nexport interface OutputFlagOptions {\n readonly json?: boolean;\n readonly jsonl?: boolean;\n readonly table?: boolean;\n readonly compact?: boolean;\n readonly rawJson?: boolean;\n}\n\nexport function parseOutputMode(options: OutputFlagOptions): OutputMode {\n const enabled = [options.json, options.jsonl, options.table, options.compact, options.rawJson].filter(Boolean).length;\n if (enabled > 1) throw new OpctlError(\"choose only one output mode flag\", EXIT_CODES.validation);\n if (options.rawJson) return \"rawJson\";\n if (options.json) return \"json\";\n if (options.jsonl) return \"jsonl\";\n if (options.compact) return \"compact\";\n if (options.table) return \"table\";\n return \"text\";\n}\n\nexport function parseFields(raw: string | undefined, defaults: readonly WorkPackageField[]): readonly WorkPackageField[] {\n if (!raw || raw.trim() === \"\") return defaults;\n const fields: WorkPackageField[] = [];\n for (const part of raw.split(\",\")) {\n const trimmed = part.trim();\n if (trimmed === \"\") continue;\n const field = FIELD_ALIASES[trimmed] ?? trimmed;\n if (!isSupportedField(field)) throw new OpctlError(`unknown work package field '${trimmed}'. Supported fields: ${Object.keys(SUPPORTED_FIELDS).join(\",\")}`, EXIT_CODES.validation);\n fields.push(field);\n }\n if (fields.length === 0) throw new OpctlError(\"--fields must include at least one field\", EXIT_CODES.validation);\n return fields;\n}\n\nexport function projectFields<T extends Record<string, unknown>>(value: T, fields: readonly WorkPackageField[]): Record<string, unknown> {\n const projected: Record<string, unknown> = {};\n for (const field of fields) projected[field] = value[field];\n return projected;\n}\n\nexport function projectRows<T extends Record<string, unknown>>(rows: readonly T[], fields: readonly WorkPackageField[]): Record<string, unknown>[] {\n return rows.map((row) => projectFields(row, fields));\n}\n\nfunction isSupportedField(field: string): field is WorkPackageField {\n return SUPPORTED_FIELDS[field as WorkPackageField] === true;\n}\n","import type { Command } from \"commander\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { basename, join, resolve } from \"node:path\";\nimport { redactSecrets } from \"../client/auth.js\";\nimport { normalizeUserFilterValue, type GenericFilter, type SearchWorkPackagesOptions, type SortCriterion } from \"../client/openProjectClient.js\";\nimport { OpctlError, EXIT_CODES } from \"../client/errors.js\";\nimport { stableJson } from \"../output/json.js\";\nimport { renderKeyValue } from \"../output/text.js\";\nimport { renderTable } from \"../output/table.js\";\nimport { DEFAULT_CHECK_FIELDS, DEFAULT_COMPACT_FIELDS, DEFAULT_TABLE_FIELDS, DETAIL_FIELDS, parseFields, parseOutputMode, projectFields, projectRows, type OutputFlagOptions, type WorkPackageField } from \"../output/fields.js\";\nimport type { NormalizedCollection } from \"../client/pagination.js\";\nimport type { AttachmentDownloadResult, AttachmentSummary, WorkPackageCreateResult, WorkPackageDetail, WorkPackageSummary } from \"../types/domain.js\";\nimport { createClient, resolvedEnv, type CommandContext, writeOutput } from \"./context.js\";\n\ninterface SearchOptions extends OutputFlagOptions {\n readonly fields?: string;\n readonly project?: string;\n readonly subject?: string;\n readonly assigneeMe?: boolean;\n readonly responsibleMe?: boolean;\n readonly responsible?: string;\n readonly status?: string;\n readonly notStatus?: string[];\n readonly open?: boolean;\n readonly filter?: string[];\n readonly sort?: string[];\n readonly pageSize?: number;\n}\n\ninterface GetOptions extends OutputFlagOptions {\n readonly ids?: string;\n readonly fields?: string;\n}\n\ninterface CreateOptions {\n readonly dryRun?: boolean;\n readonly json?: boolean;\n readonly project?: string;\n readonly type?: string;\n readonly subject?: string;\n readonly description?: string;\n readonly descriptionFile?: string;\n readonly status?: string;\n readonly priority?: string;\n readonly template?: string;\n}\n\ninterface AttachmentListOptions {\n readonly json?: boolean;\n readonly jsonl?: boolean;\n readonly table?: boolean;\n}\n\ninterface AttachmentDownloadOptions {\n readonly dir?: string;\n readonly overwrite?: boolean;\n readonly json?: boolean;\n}\n\nexport function registerWorkPackages(program: Command, context: CommandContext): void {\n const wp = program.command(\"wp\").description(\"Work package commands\");\n\n wp.command(\"get\")\n .description(\"Get one or more work packages\")\n .argument(\"[ids...]\", \"work package ids\")\n .option(\"--ids <csv>\", \"comma-separated work package ids\")\n .option(\"--fields <csv>\", \"comma-separated output fields\")\n .option(\"--table\", \"emit table output\")\n .option(\"--compact\", \"emit compact triage table output\")\n .option(\"--json\", \"emit normalized JSON\")\n .option(\"--jsonl\", \"emit one JSON object per line\")\n .option(\"--raw-json\", \"emit raw OpenProject JSON; JSONL for multiple ids\")\n .action(async (ids: string[], options: GetOptions, command: Command) => {\n const numericIds = parseIds(ids, options.ids);\n if (numericIds.length === 0) throw new OpctlError(\"at least one work package id is required\", EXIT_CODES.validation);\n const mode = parseOutputMode(options);\n if (mode !== \"rawJson\") parseFields(options.fields, mode === \"compact\" ? DEFAULT_COMPACT_FIELDS : DETAIL_FIELDS);\n const client = createClient(context, command);\n const token = resolvedEnv(context, command).OPENPROJECT_TOKEN;\n if (mode === \"rawJson\") {\n const rawWorkPackages = [];\n for (const id of numericIds) rawWorkPackages.push(await client.getWorkPackageRaw(id));\n if (rawWorkPackages.length === 1) context.stdout.write(stableJson(rawWorkPackages[0], token));\n else context.stdout.write(rawWorkPackages.map((wp) => redactSecrets(JSON.stringify(wp), token)).join(\"\\n\") + \"\\n\");\n return;\n }\n const workPackages: WorkPackageDetail[] = [];\n for (const id of numericIds) workPackages.push(await client.getWorkPackage(id));\n writeWorkPackageOutput(context, workPackages, options, mode, numericIds.length === 1 && !options.ids, DETAIL_FIELDS, token);\n });\n\n wp.command(\"check\")\n .description(\"Read a triage-oriented issue list for one or more work packages\")\n .argument(\"[ids...]\", \"work package ids\")\n .option(\"--ids <csv>\", \"comma-separated work package ids\")\n .option(\"--fields <csv>\", \"comma-separated output fields\")\n .option(\"--table\", \"emit table output\")\n .option(\"--compact\", \"emit compact table output\")\n .option(\"--json\", \"emit JSON\")\n .option(\"--jsonl\", \"emit one JSON object per line\")\n .action(async (ids: string[], options: Omit<GetOptions, \"rawJson\">, command: Command) => {\n const numericIds = parseIds(ids, options.ids);\n if (numericIds.length === 0) throw new OpctlError(\"at least one work package id is required\", EXIT_CODES.validation);\n const mode = parseOutputMode(options);\n parseFields(options.fields, mode === \"compact\" ? DEFAULT_COMPACT_FIELDS : DEFAULT_CHECK_FIELDS);\n const client = createClient(context, command);\n const workPackages: WorkPackageDetail[] = [];\n for (const id of numericIds) workPackages.push(await client.getWorkPackage(id));\n writeWorkPackageOutput(context, workPackages, options, mode, false, DEFAULT_CHECK_FIELDS, resolvedEnv(context, command).OPENPROJECT_TOKEN);\n });\n\n wp.command(\"search\")\n .description(\"Search work packages\")\n .option(\"--json\", \"emit JSON\")\n .option(\"--jsonl\", \"emit one JSON object per line\")\n .option(\"--table\", \"emit table output\")\n .option(\"--compact\", \"emit compact table output\")\n .option(\"--fields <csv>\", \"comma-separated output fields\")\n .option(\"--project <identifier-or-id>\", \"project identifier or id\")\n .option(\"--subject <text>\", \"subject contains text\")\n .option(\"--assignee-me\", \"filter to current user\")\n .option(\"--responsible-me\", \"filter to work packages responsible to current user\")\n .option(\"--responsible <me-or-id-or-href>\", \"filter by responsible user; supports me, numeric ids, or /api/v3/users/<id>\")\n .option(\"--status <id-or-open>\", \"status id, or open\")\n .option(\"--not-status <name-or-id-or-href>\", \"exclude status by name, id, or href\", collect)\n .option(\"--open\", \"filter to open work packages\")\n .option(\"--filter <field=operator:value>\", \"generic OpenProject filter; field=value means equals, field=o means unary operator o\", collect)\n .option(\"--sort <field:asc|desc>\", \"sort criterion, repeatable\", collect)\n .option(\"--page-size <n>\", \"page size\", Number)\n .action(async (options: SearchOptions, command: Command) => {\n const result = await createClient(context, command).searchWorkPackages(resolveSearchOptions(options));\n writeCollectionOutput(context, result, options, resolvedEnv(context, command).OPENPROJECT_TOKEN);\n });\n\n wp.command(\"mine\")\n .description(\"List open work packages assigned to the authenticated user\")\n .option(\"--json\", \"emit JSON\")\n .option(\"--jsonl\", \"emit one JSON object per line\")\n .option(\"--table\", \"emit table output\")\n .option(\"--compact\", \"emit compact table output\")\n .option(\"--fields <csv>\", \"comma-separated output fields\")\n .option(\"--project <identifier-or-id>\", \"project identifier or id\")\n .option(\"--open\", \"filter to open work packages\")\n .option(\"--page-size <n>\", \"page size\", Number)\n .action(async (options: Pick<SearchOptions, \"json\" | \"jsonl\" | \"table\" | \"compact\" | \"fields\" | \"project\" | \"open\" | \"pageSize\">, command: Command) => {\n const result = await createClient(context, command).mine(options);\n writeCollectionOutput(context, result, options, resolvedEnv(context, command).OPENPROJECT_TOKEN);\n });\n\n wp.command(\"accountable\")\n .description(\"List open work packages responsible to the authenticated user\")\n .option(\"--json\", \"emit JSON\")\n .option(\"--jsonl\", \"emit one JSON object per line\")\n .option(\"--table\", \"emit table output\")\n .option(\"--compact\", \"emit compact table output\")\n .option(\"--fields <csv>\", \"comma-separated output fields\")\n .option(\"--project <identifier-or-id>\", \"project identifier or id\")\n .option(\"--open\", \"filter to open work packages\")\n .option(\"--page-size <n>\", \"page size\", Number)\n .action(async (options: Pick<SearchOptions, \"json\" | \"jsonl\" | \"table\" | \"compact\" | \"fields\" | \"project\" | \"open\" | \"pageSize\">, command: Command) => {\n const result = await createClient(context, command).accountable(options);\n writeCollectionOutput(context, result, options, resolvedEnv(context, command).OPENPROJECT_TOKEN);\n });\n\n wp.command(\"attachments\")\n .description(\"List attachment metadata for a work package\")\n .argument(\"<id>\", \"work package id\")\n .option(\"--json\", \"emit JSON\")\n .option(\"--jsonl\", \"emit one JSON object per line\")\n .option(\"--table\", \"emit table output\")\n .action(async (id: string, options: AttachmentListOptions, command: Command) => {\n const mode = parseAttachmentOutputMode(options);\n const result = await createClient(context, command).listWorkPackageAttachments(parseId(id));\n writeAttachmentOutput(context, result.elements, mode, resolvedEnv(context, command).OPENPROJECT_TOKEN);\n });\n\n wp.command(\"download-attachments\")\n .description(\"Download all attachments for a work package\")\n .argument(\"<id>\", \"work package id\")\n .requiredOption(\"--dir <path>\", \"directory to save attachments into\")\n .option(\"--overwrite\", \"replace files that already exist\")\n .option(\"--json\", \"emit JSON\")\n .action(async (id: string, options: AttachmentDownloadOptions, command: Command) => {\n if (!options.dir || options.dir.trim() === \"\") throw new OpctlError(\"--dir is required\", EXIT_CODES.validation);\n const client = createClient(context, command);\n const outputDir = resolve(context.cwd ?? process.cwd(), options.dir);\n mkdirSync(outputDir, { recursive: true });\n const attachments = (await client.listWorkPackageAttachments(parseId(id))).elements;\n const saved: AttachmentDownloadResult[] = [];\n for (const attachment of attachments) {\n const fileName = safeAttachmentFileName(attachment, saved.length + 1);\n const savedPath = uniqueAttachmentPath(outputDir, fileName, Boolean(options.overwrite));\n const content = await client.downloadAttachment(attachment);\n writeFileSync(savedPath, Buffer.from(content));\n saved.push({ ...attachment, savedPath });\n }\n if (options.json) {\n context.stdout.write(stableJson({ workPackageId: parseId(id), directory: outputDir, attachments: saved }, resolvedEnv(context, command).OPENPROJECT_TOKEN));\n return;\n }\n context.stdout.write(renderTable(saved as unknown as Record<string, unknown>[], [\"id\", \"fileName\", \"contentType\", \"fileSize\", \"savedPath\"]));\n });\n\n wp.command(\"create\")\n .description(\"Create a work package; requires OPENPROJECT_ALLOW_WRITE=1\")\n .option(\"--project <identifier-or-id>\", \"project identifier or id; defaults to OPENPROJECT_DEFAULT_PROJECT\")\n .option(\"--type <name-or-id-or-href>\", \"work package type name, id, or href\")\n .option(\"--subject <text>\", \"work package subject\")\n .option(\"--description <text>\", \"inline multiline description\")\n .option(\"--description-file <path>\", \"read description from UTF-8 file; - for stdin\")\n .option(\"--status <name-or-id-or-href>\", \"status name, id, or href\")\n .option(\"--priority <name-or-id-or-href>\", \"priority name, id, or href\")\n .option(\"--template <name>\", \"use a description template (user-story)\")\n .option(\"--dry-run\", \"validate and print intended mutation without creating\")\n .option(\"--json\", \"emit JSON\")\n .action(async (options: CreateOptions, command: Command) => {\n const template = options.template?.trim();\n if (template && template !== \"user-story\") {\n throw new OpctlError(`unknown template '${template}'. Supported templates: user-story`, EXIT_CODES.validation);\n }\n\n const templateText = `# User story\\n\\nAs a <user>\\nI want <capability>\\nSo that <outcome>\\n\\n## Acceptance criteria\\n\\n- [ ]`;\n\n const hasCreateFields = options.project || options.type || options.subject || options.description || options.descriptionFile || options.status || options.priority;\n\n // Template-only mode: no create fields, just print template\n if (template === \"user-story\" && !hasCreateFields) {\n context.stdout.write(`${templateText}\\n`);\n return;\n }\n\n // Determine description\n let description: string | undefined;\n if (options.description !== undefined && options.descriptionFile !== undefined) {\n throw new OpctlError(\"--description and --description-file cannot both be provided\", EXIT_CODES.validation);\n }\n if (template && (options.description !== undefined || options.descriptionFile !== undefined)) {\n throw new OpctlError(\"--template cannot be combined with --description or --description-file\", EXIT_CODES.validation);\n }\n\n if (options.description !== undefined) {\n description = options.description;\n } else if (options.descriptionFile !== undefined) {\n if (options.descriptionFile === \"-\") {\n description = await readStdin(context);\n } else {\n const filePath = resolve(context.cwd ?? process.cwd(), options.descriptionFile);\n try {\n description = readFileSync(filePath, \"utf-8\");\n } catch (err) {\n throw new OpctlError(`unable to read --description-file '${options.descriptionFile}': ${(err as Error).message}`, EXIT_CODES.validation);\n }\n }\n } else if (template === \"user-story\") {\n description = templateText;\n } else if (context.stdin && context.stdin.isTTY === false) {\n description = await readStdin(context);\n }\n\n const env = resolvedEnv(context, command);\n const project = options.project?.trim() || env.OPENPROJECT_DEFAULT_PROJECT?.trim();\n if (!project) throw new OpctlError(\"--project is required when OPENPROJECT_DEFAULT_PROJECT is not set\", EXIT_CODES.validation);\n if (!options.type || !options.type.trim()) throw new OpctlError(\"--type is required\", EXIT_CODES.validation);\n if (!options.subject || !options.subject.trim()) throw new OpctlError(\"--subject is required\", EXIT_CODES.validation);\n\n const token = env.OPENPROJECT_TOKEN;\n const result = await createClient(context, command).createWorkPackage({\n project,\n type: options.type,\n subject: options.subject,\n description,\n status: options.status,\n priority: options.priority,\n dryRun: Boolean(options.dryRun),\n });\n\n if (options.json) {\n context.stdout.write(stableJson(result, token));\n return;\n }\n\n // Text output\n if (result.status === \"dry-run\") {\n const lines = [\n `status: dry-run`,\n `method: POST`,\n `path: /api/v3/work_packages`,\n `payload: ${JSON.stringify(result.request?.payload)}`,\n ];\n if (result.subject) lines.splice(1, 0, `subject: ${result.subject}`);\n context.stdout.write(`${lines.join(\"\\n\")}\\n`);\n return;\n }\n\n // Created output\n const output: Record<string, unknown> = {};\n if (result.id !== undefined) output.id = result.id;\n if (result.subject !== undefined) output.subject = result.subject;\n output.status = result.status;\n if (result.href !== undefined) output.href = result.href;\n if (result.browserUrl !== undefined) output.browserUrl = result.browserUrl;\n context.stdout.write(renderKeyValue(output));\n });\n\n wp.command(\"comment\")\n .description(\"Add a comment to a work package; requires OPENPROJECT_ALLOW_WRITE=1\")\n .argument(\"<id>\", \"work package id\")\n .argument(\"[message...]\", \"comment message\")\n .option(\"--dry-run\", \"print intended mutation without posting\")\n .option(\"--json\", \"emit JSON\")\n .action(async (id: string, messageParts: string[], options: { dryRun?: boolean; json?: boolean }, command: Command) => {\n const result = await createClient(context, command).commentWorkPackage(parseId(id), messageParts.join(\" \"), Boolean(options.dryRun));\n writeOutput(context, result, Boolean(options.json), () => renderKeyValue(result as unknown as Record<string, unknown>), resolvedEnv(context, command).OPENPROJECT_TOKEN);\n });\n}\n\nfunction writeCollectionOutput(context: CommandContext, result: NormalizedCollection<WorkPackageSummary>, options: SearchOptions | Pick<SearchOptions, \"json\" | \"jsonl\" | \"table\" | \"compact\" | \"fields\" | \"project\" | \"open\" | \"pageSize\">, token: string | undefined): void {\n const mode = parseOutputMode(options);\n const defaults = mode === \"compact\" ? DEFAULT_COMPACT_FIELDS : DEFAULT_TABLE_FIELDS;\n const fields = parseFields(options.fields, defaults);\n const elements = projectRows(result.elements as unknown as Record<string, unknown>[], fields);\n if (mode === \"jsonl\") {\n context.stdout.write(elements.map((element) => JSON.stringify(element)).join(\"\\n\") + (elements.length > 0 ? \"\\n\" : \"\"));\n return;\n }\n if (mode === \"json\") {\n const output = options.fields ? { ...result, elements } : result;\n context.stdout.write(stableJson(output, token));\n return;\n }\n context.stdout.write(renderTable(elements, fields));\n}\n\nfunction writeAttachmentOutput(context: CommandContext, attachments: readonly AttachmentSummary[], mode: \"table\" | \"json\" | \"jsonl\", token: string | undefined): void {\n const fields = [\"id\", \"fileName\", \"contentType\", \"fileSize\", \"description\", \"downloadHref\"] as const;\n if (mode === \"json\") {\n context.stdout.write(stableJson({ total: attachments.length, elements: attachments }, token));\n return;\n }\n if (mode === \"jsonl\") {\n context.stdout.write(attachments.map((attachment) => redactSecrets(JSON.stringify(attachment), token)).join(\"\\n\") + (attachments.length > 0 ? \"\\n\" : \"\"));\n return;\n }\n context.stdout.write(renderTable(attachments as unknown as Record<string, unknown>[], fields));\n}\n\nfunction parseAttachmentOutputMode(options: AttachmentListOptions): \"table\" | \"json\" | \"jsonl\" {\n const enabled = [options.json, options.jsonl, options.table].filter(Boolean).length;\n if (enabled > 1) throw new OpctlError(\"choose only one output mode flag\", EXIT_CODES.validation);\n if (options.json) return \"json\";\n if (options.jsonl) return \"jsonl\";\n return \"table\";\n}\n\nfunction resolveSearchOptions(options: SearchOptions): SearchWorkPackagesOptions {\n const filters = parseGenericFilters(options.filter);\n const sort = parseSortCriteria(options.sort);\n return {\n ...(options.project !== undefined ? { project: options.project } : {}),\n ...(options.subject !== undefined ? { subject: options.subject } : {}),\n ...(options.assigneeMe !== undefined ? { assigneeMe: options.assigneeMe } : {}),\n ...(options.responsibleMe !== undefined ? { responsibleMe: options.responsibleMe } : {}),\n ...(options.responsible !== undefined ? { responsible: options.responsible } : {}),\n ...(options.status !== undefined ? { status: options.status } : {}),\n ...(options.notStatus !== undefined ? { notStatus: options.notStatus } : {}),\n ...(options.open !== undefined ? { open: options.open } : {}),\n ...(filters.length > 0 ? { filters } : {}),\n ...(sort.length > 0 ? { sort } : {}),\n ...(options.pageSize !== undefined ? { pageSize: options.pageSize } : {}),\n };\n}\n\nconst UNARY_FILTER_OPERATORS = new Set([\"o\", \"c\", \"*\", \"!*\"]);\n\nfunction parseGenericFilters(rawFilters: readonly string[] | undefined): GenericFilter[] {\n return (rawFilters ?? []).map((raw) => {\n const eqIndex = raw.indexOf(\"=\");\n if (eqIndex <= 0) throw new OpctlError(`invalid --filter '${raw}'. Expected field=value or field=operator:value`, EXIT_CODES.validation);\n const field = raw.slice(0, eqIndex).trim();\n const expression = raw.slice(eqIndex + 1).trim();\n if (!field || !/^[A-Za-z][A-Za-z0-9_]*$/.test(field)) throw new OpctlError(`invalid --filter field '${field}'`, EXIT_CODES.validation);\n if (!expression) throw new OpctlError(`invalid --filter '${raw}'. Filter value must not be empty`, EXIT_CODES.validation);\n const colonIndex = expression.indexOf(\":\");\n if (colonIndex > 0) {\n const operator = expression.slice(0, colonIndex).trim();\n const values = splitCsv(expression.slice(colonIndex + 1)).map((value) => normalizeFilterValue(field, value));\n return { field, operator, values };\n }\n if (UNARY_FILTER_OPERATORS.has(expression)) return { field, operator: expression, values: [] };\n return { field, operator: \"=\", values: [normalizeFilterValue(field, expression)] };\n });\n}\n\nfunction normalizeFilterValue(field: string, value: string): string {\n return field === \"responsible\" || field === \"assignee\" ? normalizeUserFilterValue(value) : value;\n}\n\nfunction parseSortCriteria(rawSort: readonly string[] | undefined): SortCriterion[] {\n return (rawSort ?? []).map((raw) => {\n const [field, direction, extra] = raw.split(\":\");\n if (!field || !direction || extra !== undefined) throw new OpctlError(`invalid --sort '${raw}'. Expected field:asc or field:desc`, EXIT_CODES.validation);\n const normalizedDirection = direction.toLowerCase();\n if (normalizedDirection !== \"asc\" && normalizedDirection !== \"desc\") throw new OpctlError(`invalid --sort direction '${direction}'. Expected asc or desc`, EXIT_CODES.validation);\n if (!/^[A-Za-z][A-Za-z0-9_]*$/.test(field)) throw new OpctlError(`invalid --sort field '${field}'`, EXIT_CODES.validation);\n return { field, direction: normalizedDirection };\n });\n}\n\nfunction safeAttachmentFileName(attachment: AttachmentSummary, index: number): string {\n const fallback = attachment.id ? `attachment-${attachment.id}` : `attachment-${index}`;\n const name = basename(attachment.fileName || fallback).replace(/[\\\\/:*?\"<>|\\u0000-\\u001F]/g, \"_\").trim();\n return name || fallback;\n}\n\nfunction uniqueAttachmentPath(dir: string, fileName: string, overwrite: boolean): string {\n const first = join(dir, fileName);\n if (overwrite || !existsSync(first)) return first;\n const dot = fileName.lastIndexOf(\".\");\n const stem = dot > 0 ? fileName.slice(0, dot) : fileName;\n const ext = dot > 0 ? fileName.slice(dot) : \"\";\n for (let i = 2; i < 10_000; i += 1) {\n const candidate = join(dir, `${stem}-${i}${ext}`);\n if (!existsSync(candidate)) return candidate;\n }\n throw new OpctlError(`unable to choose a unique filename for '${fileName}'`, EXIT_CODES.validation);\n}\n\nfunction collect(value: string, previous: string[] | undefined): string[] {\n return [...(previous ?? []), value];\n}\n\nfunction writeWorkPackageOutput(context: CommandContext, workPackages: readonly WorkPackageDetail[], options: GetOptions | Omit<GetOptions, \"rawJson\">, mode: string, singleObject: boolean, defaultFields: readonly WorkPackageField[], token: string | undefined): void {\n const fields = parseFields(options.fields, mode === \"compact\" ? DEFAULT_COMPACT_FIELDS : defaultFields);\n const projected = options.fields || mode === \"table\" || mode === \"compact\" || mode === \"jsonl\" ? projectRows(workPackages as unknown as Record<string, unknown>[], fields) : workPackages;\n if (mode === \"jsonl\") {\n const rows = projectRows(workPackages as unknown as Record<string, unknown>[], fields);\n context.stdout.write(rows.map((row) => JSON.stringify(row)).join(\"\\n\") + (rows.length > 0 ? \"\\n\" : \"\"));\n return;\n }\n if (mode === \"json\") {\n context.stdout.write(stableJson(singleObject ? projected[0] : projected, token));\n return;\n }\n if (singleObject && mode === \"text\" && !options.fields) {\n context.stdout.write(renderKeyValue(workPackages[0] as unknown as Record<string, unknown>));\n return;\n }\n context.stdout.write(renderTable(projectRows(workPackages as unknown as Record<string, unknown>[], fields), fields));\n}\n\nfunction parseIds(positionals: readonly string[], csv: string | undefined): number[] {\n const seen = new Set<number>();\n const ids: number[] = [];\n for (const raw of [...positionals, ...splitCsv(csv)]) {\n const id = parseId(raw);\n if (seen.has(id)) continue;\n seen.add(id);\n ids.push(id);\n }\n return ids;\n}\n\nfunction splitCsv(csv: string | undefined): string[] {\n if (!csv) return [];\n return csv.split(\",\").map((part) => part.trim()).filter((part) => part !== \"\");\n}\n\nfunction parseId(id: string): number {\n const parsed = Number(id);\n if (!Number.isInteger(parsed) || parsed < 1) throw new OpctlError(\"work package id must be a positive integer\", EXIT_CODES.validation);\n return parsed;\n}\n\nasync function readStdin(context: CommandContext): Promise<string> {\n const chunks: string[] = [];\n for await (const chunk of context.stdin!) {\n chunks.push(typeof chunk === \"string\" ? chunk : new TextDecoder().decode(chunk));\n }\n return chunks.join(\"\");\n}\n","import type { Command } from \"commander\";\nimport { stableJson } from \"../output/json.js\";\nimport { renderKeyValue } from \"../output/text.js\";\nimport { renderTable } from \"../output/table.js\";\nimport { listProfiles, redactProfile, setProfile, showProfile, unsetProfile, useProfile, type Profile } from \"../config/profiles.js\";\nimport type { CommandContext } from \"./context.js\";\n\ninterface SetProfileOptions {\n readonly url?: string;\n readonly authMode?: string;\n readonly defaultProject?: string;\n readonly token?: string;\n readonly json?: boolean;\n}\n\nexport function registerProfile(program: Command, context: CommandContext): void {\n const profile = program.command(\"profile\").description(\"Saved non-write OpenProject connection profiles\");\n\n profile.command(\"list\")\n .description(\"List saved profiles\")\n .option(\"--json\", \"emit JSON\")\n .action((options: { readonly json?: boolean }) => {\n const rows = listProfiles(context.env).map((entry) => ({ name: entry.name, active: entry.active ? \"yes\" : \"\", ...redactProfile(entry.profile) }));\n context.stdout.write(options.json ? stableJson(rows) : renderTable(rows, [\"name\", \"active\", \"url\", \"authMode\", \"defaultProject\", \"token\"]));\n });\n\n profile.command(\"show\")\n .description(\"Show a saved profile with secrets redacted\")\n .argument(\"[name]\", \"profile name; defaults to active profile\")\n .option(\"--json\", \"emit JSON\")\n .action((name: string | undefined, options: { readonly json?: boolean }) => {\n const result = showProfile(name, context.env);\n const output = result.profile ? { name: result.name, ...redactProfile(result.profile) } : { name: undefined };\n context.stdout.write(options.json ? stableJson(output) : renderKeyValue(output));\n });\n\n profile.command(\"set\")\n .description(\"Create or replace a saved profile\")\n .argument(\"<name>\", \"profile name\")\n .option(\"--url <url>\", \"OpenProject base URL\")\n .option(\"--auth-mode <mode>\", \"auth mode: bearer or basic\")\n .option(\"--default-project <id>\", \"default project identifier or id\")\n .option(\"--token <token>\", \"OpenProject API token; stored in a 0600 profile file\")\n .option(\"--json\", \"emit JSON\")\n .action((name: string, options: SetProfileOptions) => {\n const profileValue: Profile = {\n ...(options.url ? { url: options.url } : {}),\n ...(options.authMode ? { authMode: options.authMode } : {}),\n ...(options.defaultProject ? { defaultProject: options.defaultProject } : {}),\n ...(options.token ? { token: options.token } : {}),\n };\n setProfile(name, profileValue, context.env);\n const output = { name, ...redactProfile(profileValue) };\n context.stdout.write(options.json ? stableJson(output) : `${name}\\n`);\n });\n\n profile.command(\"use\")\n .description(\"Set the active profile\")\n .argument(\"<name>\", \"profile name\")\n .option(\"--json\", \"emit JSON\")\n .action((name: string, options: { readonly json?: boolean }) => {\n useProfile(name, context.env);\n const output = { activeProfile: name };\n context.stdout.write(options.json ? stableJson(output) : `active profile: ${name}\\n`);\n });\n\n profile.command(\"unset\")\n .description(\"Delete a saved profile\")\n .argument(\"<name>\", \"profile name\")\n .option(\"--json\", \"emit JSON\")\n .action((name: string, options: { readonly json?: boolean }) => {\n unsetProfile(name, context.env);\n const output = { unset: name };\n context.stdout.write(options.json ? stableJson(output) : `unset profile: ${name}\\n`);\n });\n}\n","#!/usr/bin/env node\nimport { realpathSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { Command } from \"commander\";\nimport { redactSecrets } from \"./client/auth.js\";\nimport { EXIT_CODES, toOpctlError } from \"./client/errors.js\";\nimport { stableJson } from \"./output/json.js\";\nimport { registerApiRoot } from \"./commands/apiRoot.js\";\nimport { registerDoctor } from \"./commands/doctor.js\";\nimport { registerLookups } from \"./commands/lookups.js\";\nimport { registerMe } from \"./commands/me.js\";\nimport { registerProjects } from \"./commands/projects.js\";\nimport { registerSpec } from \"./commands/spec.js\";\nimport { registerWorkPackages } from \"./commands/workPackages.js\";\nimport { registerProfile } from \"./commands/profile.js\";\nimport type { CommandContext } from \"./commands/context.js\";\nimport pkg from \"../package.json\" with { type: \"json\" };\n\nexport function buildProgram(context: CommandContext): Command {\n const program = new Command();\n program\n .name(\"opctl\")\n .description(\"Conservative local CLI bridge for OpenProject API v3\")\n .version(pkg.version)\n .option(\"--env <path>\", \"load OpenProject configuration from dotenv-style file\")\n .option(\"--no-env\", \"disable automatic .env loading from the current working directory\")\n .option(\"--profile <name>\", \"use a saved profile for this invocation\")\n .showHelpAfterError()\n .configureOutput({\n writeOut: (text) => context.stdout.write(text),\n writeErr: (text) => context.stderr.write(text),\n });\n registerMe(program, context);\n registerApiRoot(program, context);\n registerProjects(program, context);\n registerWorkPackages(program, context);\n registerLookups(program, context);\n registerProfile(program, context);\n registerSpec(program, context);\n registerDoctor(program, context);\n return program;\n}\n\nexport async function run(argv: readonly string[], context: CommandContext): Promise<number> {\n try {\n await buildProgram(context).parseAsync(argv, { from: \"node\" });\n return EXIT_CODES.success;\n } catch (error) {\n const opctlError = toOpctlError(error);\n const wantsJson = argv.includes(\"--json\");\n if (wantsJson) {\n const payload: Record<string, unknown> = { error: opctlError.message, exitCode: opctlError.exitCode };\n if (opctlError.details !== undefined) payload.details = opctlError.details;\n context.stderr.write(stableJson(payload, context.env.OPENPROJECT_TOKEN));\n } else {\n context.stderr.write(`${redactSecrets(opctlError.message, context.env.OPENPROJECT_TOKEN)}\\n`);\n }\n return opctlError.exitCode;\n }\n}\n\nexport function isCliEntrypoint(metaUrl: string, argvPath: string | undefined = process.argv[1]): boolean {\n if (!argvPath) return false;\n try {\n return realpathSync(fileURLToPath(metaUrl)) === realpathSync(argvPath);\n } catch {\n return false;\n }\n}\n\nif (isCliEntrypoint(import.meta.url)) {\n const exitCode = await run(process.argv, { stdout: process.stdout, stderr: process.stderr, env: process.env, stdin: process.stdin });\n process.exitCode = exitCode;\n}\n"],"mappings":"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"}
|