poe-code 3.0.181 → 3.0.182

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.
Files changed (117) hide show
  1. package/dist/cli/commands/config.js +3 -4
  2. package/dist/cli/commands/config.js.map +1 -1
  3. package/dist/cli/commands/configure.js +12 -3
  4. package/dist/cli/commands/configure.js.map +1 -1
  5. package/dist/cli/commands/dashboard-loop-shared.d.ts +7 -0
  6. package/dist/cli/commands/dashboard-loop-shared.js +15 -0
  7. package/dist/cli/commands/dashboard-loop-shared.js.map +1 -1
  8. package/dist/cli/commands/experiment.js +41 -32
  9. package/dist/cli/commands/experiment.js.map +1 -1
  10. package/dist/cli/commands/mcp.js +7 -2
  11. package/dist/cli/commands/mcp.js.map +1 -1
  12. package/dist/cli/commands/pipeline.js +55 -44
  13. package/dist/cli/commands/pipeline.js.map +1 -1
  14. package/dist/cli/commands/plan.js +195 -38
  15. package/dist/cli/commands/plan.js.map +1 -1
  16. package/dist/cli/commands/ralph.js +24 -24
  17. package/dist/cli/commands/ralph.js.map +1 -1
  18. package/dist/cli/commands/shared.d.ts +3 -0
  19. package/dist/cli/commands/shared.js +27 -1
  20. package/dist/cli/commands/shared.js.map +1 -1
  21. package/dist/cli/commands/skill.js +21 -10
  22. package/dist/cli/commands/skill.js.map +1 -1
  23. package/dist/cli/commands/spawn-poe-agent.d.ts +2 -0
  24. package/dist/cli/commands/spawn-poe-agent.js +47 -0
  25. package/dist/cli/commands/spawn-poe-agent.js.map +1 -0
  26. package/dist/cli/commands/spawn.js +21 -1
  27. package/dist/cli/commands/spawn.js.map +1 -1
  28. package/dist/cli/commands/utils-symlink-agents.d.ts +6 -0
  29. package/dist/cli/commands/utils-symlink-agents.js +78 -0
  30. package/dist/cli/commands/utils-symlink-agents.js.map +1 -0
  31. package/dist/cli/commands/utils-symlink-ops.d.ts +29 -0
  32. package/dist/cli/commands/utils-symlink-ops.js +76 -0
  33. package/dist/cli/commands/utils-symlink-ops.js.map +1 -0
  34. package/dist/cli/commands/utils-symlink-skills.d.ts +15 -0
  35. package/dist/cli/commands/utils-symlink-skills.js +136 -0
  36. package/dist/cli/commands/utils-symlink-skills.js.map +1 -0
  37. package/dist/cli/commands/utils-symlink.d.ts +3 -0
  38. package/dist/cli/commands/utils-symlink.js +40 -0
  39. package/dist/cli/commands/utils-symlink.js.map +1 -0
  40. package/dist/cli/commands/utils.js +2 -0
  41. package/dist/cli/commands/utils.js.map +1 -1
  42. package/dist/cli/constants.d.ts +2 -2
  43. package/dist/cli/constants.js +1 -1
  44. package/dist/cli/constants.js.map +1 -1
  45. package/dist/cli/program.js +8 -1
  46. package/dist/cli/program.js.map +1 -1
  47. package/dist/index.d.ts +1 -0
  48. package/dist/index.js +23269 -18158
  49. package/dist/index.js.map +4 -4
  50. package/dist/plan/document-schema.d.ts +21 -0
  51. package/dist/plan/document-schema.js +16 -0
  52. package/dist/plan/document-schema.js.map +1 -0
  53. package/dist/providers/claude-code.js +31 -13
  54. package/dist/providers/claude-code.js.map +4 -4
  55. package/dist/providers/codex.js +31 -13
  56. package/dist/providers/codex.js.map +4 -4
  57. package/dist/providers/goose.js +32 -14
  58. package/dist/providers/goose.js.map +4 -4
  59. package/dist/providers/kimi.js +31 -13
  60. package/dist/providers/kimi.js.map +4 -4
  61. package/dist/providers/opencode.js +32 -14
  62. package/dist/providers/opencode.js.map +4 -4
  63. package/dist/providers/poe-agent.d.ts +5 -0
  64. package/dist/providers/poe-agent.js +19812 -4438
  65. package/dist/providers/poe-agent.js.map +4 -4
  66. package/dist/sdk/container.js +4 -0
  67. package/dist/sdk/container.js.map +1 -1
  68. package/dist/sdk/spawn.js +8 -2
  69. package/dist/sdk/spawn.js.map +1 -1
  70. package/dist/sdk/types.d.ts +5 -1
  71. package/dist/services/config.d.ts +29 -44
  72. package/dist/services/config.js +16 -25
  73. package/dist/services/config.js.map +1 -1
  74. package/dist/templates/pipeline/SKILL_plan.md +22 -8
  75. package/dist/templates/pipeline/steps.yaml.mustache +1 -1
  76. package/dist/templates/skill/poe-generate.md +47 -0
  77. package/dist/templates/skill/terminal-pilot.md +45 -0
  78. package/dist/utils/dry-run.d.ts +8 -0
  79. package/dist/utils/dry-run.js +16 -0
  80. package/dist/utils/dry-run.js.map +1 -1
  81. package/dist/utils/file-system.d.ts +4 -0
  82. package/package.json +16 -9
  83. package/packages/cmdkit/dist/cli.js +42 -22
  84. package/packages/cmdkit/dist/cli.js.map +3 -3
  85. package/packages/cmdkit/dist/index.js +52 -9
  86. package/packages/cmdkit/dist/index.js.map +2 -2
  87. package/packages/cmdkit/dist/mcp.d.ts +15 -0
  88. package/packages/cmdkit/dist/mcp.js +121 -20
  89. package/packages/cmdkit/dist/mcp.js.map +3 -3
  90. package/packages/cmdkit/dist/number-schema.d.ts +3 -0
  91. package/packages/cmdkit/dist/number-schema.js +8 -0
  92. package/packages/cmdkit/dist/schema-scope.d.ts +4 -0
  93. package/packages/cmdkit/dist/schema-scope.js +34 -0
  94. package/packages/cmdkit/dist/sdk.js +58 -3
  95. package/packages/cmdkit/dist/sdk.js.map +3 -3
  96. package/packages/cmdkit-schema/dist/index.compile-check.js +1 -0
  97. package/packages/cmdkit-schema/dist/index.d.ts +59 -16
  98. package/packages/cmdkit-schema/dist/index.js +53 -8
  99. package/packages/design-system/dist/dashboard/components/footer.js +2 -3
  100. package/packages/design-system/dist/dashboard/components/output-pane.d.ts +1 -10
  101. package/packages/design-system/dist/dashboard/components/output-pane.js +5 -74
  102. package/packages/design-system/dist/dashboard/dashboard.js +6 -26
  103. package/packages/design-system/dist/dashboard/keymap.js +4 -19
  104. package/packages/design-system/dist/dashboard/snapshot.js +1 -5
  105. package/packages/design-system/dist/dashboard/store.d.ts +1 -2
  106. package/packages/design-system/dist/dashboard/store.js +6 -62
  107. package/packages/design-system/dist/dashboard/terminal.d.ts +2 -0
  108. package/packages/design-system/dist/dashboard/terminal.js +18 -0
  109. package/packages/design-system/dist/dashboard/types.d.ts +1 -11
  110. package/packages/design-system/dist/terminal-markdown/ast.d.ts +10 -2
  111. package/packages/design-system/dist/terminal-markdown/parser/block.d.ts +2 -1
  112. package/packages/design-system/dist/terminal-markdown/parser/block.js +400 -110
  113. package/packages/design-system/dist/terminal-markdown/parser/frontmatter.d.ts +2 -0
  114. package/packages/design-system/dist/terminal-markdown/parser/frontmatter.js +28 -11
  115. package/packages/design-system/dist/terminal-markdown/parser/inline.d.ts +4 -0
  116. package/packages/design-system/dist/terminal-markdown/parser/inline.js +134 -55
  117. package/packages/design-system/dist/terminal-markdown/parser.js +36 -7
@@ -101,6 +101,52 @@ async function assertCommandRequirements(command, context, options = {}) {
101
101
  }
102
102
  }
103
103
 
104
+ // packages/cmdkit/src/number-schema.ts
105
+ function isValidNumberSchemaValue(value, schema) {
106
+ return typeof value === "number" && Number.isFinite(value) && (schema.jsonType !== "integer" || Number.isInteger(value));
107
+ }
108
+ function getExpectedNumberDescription(schema) {
109
+ return schema.jsonType === "integer" ? "an integer" : "a number";
110
+ }
111
+
112
+ // packages/cmdkit/src/schema-scope.ts
113
+ function filterSchemaForScope(schema, scope) {
114
+ if (schema.scope !== void 0 && !schema.scope.includes(scope)) {
115
+ return void 0;
116
+ }
117
+ switch (schema.kind) {
118
+ case "optional": {
119
+ const inner = filterSchemaForScope(schema.inner, scope);
120
+ if (inner === void 0) {
121
+ return void 0;
122
+ }
123
+ if (inner.requiredScopes?.includes(scope)) {
124
+ return inner;
125
+ }
126
+ return { ...schema, inner };
127
+ }
128
+ case "array": {
129
+ const item = filterSchemaForScope(schema.item, scope);
130
+ return item === void 0 ? void 0 : { ...schema, item };
131
+ }
132
+ case "string":
133
+ case "number":
134
+ case "boolean":
135
+ case "enum":
136
+ return schema;
137
+ case "object":
138
+ return {
139
+ ...schema,
140
+ shape: Object.fromEntries(
141
+ Object.entries(schema.shape).flatMap(([key, childSchema]) => {
142
+ const filtered = filterSchemaForScope(childSchema, scope);
143
+ return filtered === void 0 ? [] : [[key, filtered]];
144
+ })
145
+ )
146
+ };
147
+ }
148
+ }
149
+
104
150
  // packages/cmdkit/src/sdk.ts
105
151
  var RESERVED_SERVICE_NAMES = /* @__PURE__ */ new Set(["params", "secrets", "fetch", "fs", "env", "progress"]);
106
152
  function splitWords(value) {
@@ -190,6 +236,9 @@ function validateEnum(value, schema, label) {
190
236
  }
191
237
  function validateSchemaValue(schema, value, label) {
192
238
  const unwrappedSchema = unwrapOptional(schema);
239
+ if (value === null && unwrappedSchema.nullable === true) {
240
+ return null;
241
+ }
193
242
  switch (unwrappedSchema.kind) {
194
243
  case "string":
195
244
  if (typeof value !== "string") {
@@ -197,8 +246,10 @@ function validateSchemaValue(schema, value, label) {
197
246
  }
198
247
  return value;
199
248
  case "number":
200
- if (typeof value !== "number" || !Number.isFinite(value)) {
201
- throw new UserError(`Invalid value for "${label}". Expected a number.`);
249
+ if (!isValidNumberSchemaValue(value, unwrappedSchema)) {
250
+ throw new UserError(
251
+ `Invalid value for "${label}". Expected ${getExpectedNumberDescription(unwrappedSchema)}.`
252
+ );
202
253
  }
203
254
  return value;
204
255
  case "boolean":
@@ -283,7 +334,11 @@ function createSDK(root, options = {}) {
283
334
  }
284
335
  };
285
336
  await assertCommandRequirements(node, { ...baseContext, params: void 0 });
286
- const validatedParams = validateSDKArguments(node.params, params);
337
+ const paramsSchema = filterSchemaForScope(node.params, "sdk");
338
+ if (paramsSchema === void 0 || paramsSchema.kind !== "object") {
339
+ throw new Error(`Bug: command "${node.name}" must define an object params schema for SDK.`);
340
+ }
341
+ const validatedParams = validateSDKArguments(paramsSchema, params);
287
342
  return node.handler({
288
343
  ...baseContext,
289
344
  params: validatedParams
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/sdk.ts", "../src/index.ts"],
4
- "sourcesContent": ["import { access, readFile, writeFile } from \"node:fs/promises\";\nimport type { AnySchema, ObjectSchema, Static } from \"@poe-code/cmdkit-schema\";\nimport type { Command, Group, HandlerEnv, HandlerFs, Scope } from \"./index.js\";\nimport { UserError, assertCommandRequirements, resolveCommandSecrets } from \"./index.js\";\n\nconst RESERVED_SERVICE_NAMES = new Set([\"params\", \"secrets\", \"fetch\", \"fs\", \"env\", \"progress\"]);\n\ntype ScopeInput = readonly Scope[] | undefined;\ntype Primitive = string | number | boolean | bigint | symbol | null | undefined;\ntype EmptyRecord = Record<never, never>;\n\ntype EffectiveCommandScope<\n TOwnScope extends ScopeInput,\n TInheritedScope extends ScopeInput,\n> = TOwnScope extends readonly Scope[]\n ? TOwnScope\n : TInheritedScope extends readonly Scope[]\n ? TInheritedScope\n : readonly [\"cli\", \"sdk\"];\n\ntype EffectiveGroupScope<\n TOwnScope extends ScopeInput,\n TInheritedScope extends ScopeInput,\n> = TOwnScope extends readonly Scope[]\n ? TOwnScope\n : TInheritedScope extends readonly Scope[]\n ? TInheritedScope\n : undefined;\n\ntype IncludesSDK<TScope> = TScope extends readonly Scope[]\n ? \"sdk\" extends TScope[number]\n ? true\n : false\n : false;\n\ntype Separator = \"-\" | \"_\" | \" \" | \".\";\n\ntype IsUppercase<TValue extends string> = TValue extends Uppercase<TValue>\n ? TValue extends Lowercase<TValue>\n ? false\n : true\n : false;\n\ntype IsLowercase<TValue extends string> = TValue extends Lowercase<TValue>\n ? TValue extends Uppercase<TValue>\n ? false\n : true\n : false;\n\ntype LastCharacter<TValue extends string> = TValue extends `${infer THead}${infer TTail}`\n ? TTail extends \"\"\n ? THead\n : LastCharacter<TTail>\n : never;\n\ntype PushCurrentWord<\n TCurrent extends string,\n TWords extends readonly string[],\n> = TCurrent extends \"\" ? TWords : [...TWords, Lowercase<TCurrent>];\n\ntype SplitCamelWords<\n TValue extends string,\n TCurrent extends string = \"\",\n TWords extends readonly string[] = [],\n> = TValue extends `${infer TChar}${infer TRest}`\n ? TChar extends Separator\n ? SplitCamelWords<TRest, \"\", PushCurrentWord<TCurrent, TWords>>\n : IsUppercase<TChar> extends true\n ? TCurrent extends \"\"\n ? SplitCamelWords<TRest, TChar, TWords>\n : TRest extends `${infer TNext}${string}`\n ? IsLowercase<LastCharacter<TCurrent>> extends true\n ? SplitCamelWords<TRest, TChar, PushCurrentWord<TCurrent, TWords>>\n : IsLowercase<TNext> extends true\n ? SplitCamelWords<TRest, TChar, PushCurrentWord<TCurrent, TWords>>\n : SplitCamelWords<TRest, `${TCurrent}${TChar}`, TWords>\n : SplitCamelWords<TRest, `${TCurrent}${TChar}`, TWords>\n : SplitCamelWords<TRest, `${TCurrent}${TChar}`, TWords>\n : PushCurrentWord<TCurrent, TWords>;\n\ntype JoinCamelWords<TWords extends readonly string[]> = TWords extends readonly [\n infer THead extends string,\n ...infer TTail extends readonly string[],\n]\n ? `${THead}${CapitalizeJoinCamelWords<TTail>}`\n : \"\";\n\ntype CapitalizeJoinCamelWords<TWords extends readonly string[]> = TWords extends readonly [\n infer THead extends string,\n ...infer TTail extends readonly string[],\n]\n ? `${Capitalize<THead>}${CapitalizeJoinCamelWords<TTail>}`\n : \"\";\n\ntype CamelCase<TValue extends string> = JoinCamelWords<SplitCamelWords<TValue>>;\n\ntype Camelize<TValue> = TValue extends Primitive\n ? TValue\n : TValue extends readonly (infer TItem)[]\n ? Array<Camelize<TItem>>\n : TValue extends object\n ? {\n [TKey in keyof TValue as TKey extends string ? CamelCase<TKey> : TKey]: Camelize<TValue[TKey]>;\n }\n : TValue;\n\ntype SDKMethod<TParamsSchema extends ObjectSchema<any>, TResult> = (\n params: Camelize<Static<TParamsSchema>>\n) => Promise<TResult>;\n\ntype UnionToIntersection<TValue> = (\n TValue extends unknown ? (value: TValue) => void : never\n) extends (value: infer TResult) => void\n ? TResult\n : never;\n\ntype Simplify<TValue> = { [TKey in keyof TValue]: TValue[TKey] };\n\ntype RawChildrenValue<TChildren> = TChildren extends readonly unknown[] ? TChildren[number] : never;\n\ntype SDKNodeShape<TNode, TInheritedScope extends ScopeInput> =\n TNode extends {\n kind: \"command\";\n readonly __cmdkitCommandTypeInfo: {\n name: infer TName extends string;\n params: infer TParamsSchema extends ObjectSchema<any>;\n result: infer TResult;\n ownScope: infer TOwnScope extends ScopeInput;\n };\n }\n ? IncludesSDK<EffectiveCommandScope<TOwnScope, TInheritedScope>> extends true\n ? { [TKey in CamelCase<TName>]: SDKMethod<TParamsSchema, TResult> }\n : EmptyRecord\n : TNode extends {\n kind: \"group\";\n readonly __cmdkitGroupTypeInfo: {\n name: infer TName extends string;\n children: infer TChildren extends readonly unknown[];\n ownScope: infer TOwnScope extends ScopeInput;\n };\n }\n ? SDKChildrenShape<TChildren, EffectiveGroupScope<TOwnScope, TInheritedScope>> extends infer TChildShape extends object\n ? keyof TChildShape extends never\n ? EmptyRecord\n : { [TKey in CamelCase<TName>]: TChildShape }\n : never\n : EmptyRecord;\n\ntype SDKChildrenShape<TChildren, TInheritedScope extends ScopeInput> = Simplify<\n UnionToIntersection<SDKNodeShape<RawChildrenValue<TChildren>, TInheritedScope>>\n>;\n\nexport interface CreateSDKOptions<TServices extends object = Record<string, unknown>> {\n services?: TServices;\n casing?: \"camel\";\n}\n\nfunction splitWords(value: string): string[] {\n const words: string[] = [];\n let current = \"\";\n\n for (let index = 0; index < value.length; index += 1) {\n const char = value[index] ?? \"\";\n const lower = char.toLowerCase();\n const upper = char.toUpperCase();\n const isSeparator = char === \"-\" || char === \"_\" || char === \" \" || char === \".\";\n\n if (isSeparator) {\n if (current.length > 0) {\n words.push(current.toLowerCase());\n current = \"\";\n }\n continue;\n }\n\n const isUppercase = char !== lower && char === upper;\n const previous = value[index - 1];\n const next = value[index + 1];\n const previousIsLowercase =\n previous !== undefined && previous === previous.toLowerCase() && previous !== previous.toUpperCase();\n const nextIsLowercase =\n next !== undefined && next === next.toLowerCase() && next !== next.toUpperCase();\n\n if (isUppercase && current.length > 0 && (previousIsLowercase || nextIsLowercase)) {\n words.push(current.toLowerCase());\n current = char;\n continue;\n }\n\n current += char;\n }\n\n if (current.length > 0) {\n words.push(current.toLowerCase());\n }\n\n return words;\n}\n\nfunction formatSegment(segment: string): string {\n return splitWords(segment)\n .map((word, index) => (index === 0 ? word : `${word[0]?.toUpperCase() ?? \"\"}${word.slice(1)}`))\n .join(\"\");\n}\n\nfunction unwrapOptional(schema: AnySchema): AnySchema {\n if (schema.kind === \"optional\") {\n return unwrapOptional(schema.inner);\n }\n\n return schema;\n}\n\nfunction isOptional(schema: AnySchema): boolean {\n return schema.kind === \"optional\";\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction createFs(): HandlerFs {\n return {\n readFile: async (path: string, encoding = \"utf8\") => readFile(path, { encoding }),\n writeFile: async (path: string, contents: string) => {\n await writeFile(path, contents);\n },\n exists: async (path: string) => {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n },\n };\n}\n\nfunction createEnv(values: Record<string, string | undefined> = process.env): HandlerEnv {\n return {\n get(key: string): string | undefined {\n return values[key];\n },\n };\n}\n\nfunction validateServices(services: Record<string, unknown>): void {\n for (const name of Object.keys(services)) {\n if (RESERVED_SERVICE_NAMES.has(name)) {\n throw new Error(`Service name \"${name}\" is reserved. Choose a different name.`);\n }\n }\n}\n\nfunction validateEnum(value: unknown, schema: Extract<AnySchema, { kind: \"enum\" }>, label: string): string | number | boolean {\n if (!schema.values.includes(value as never)) {\n throw new UserError(\n `Invalid value for \"${label}\". Expected one of: ${schema.values.map((candidate) => String(candidate)).join(\", \")}.`\n );\n }\n\n return value as string | number | boolean;\n}\n\nfunction validateSchemaValue(schema: AnySchema, value: unknown, label: string): unknown {\n const unwrappedSchema = unwrapOptional(schema);\n\n switch (unwrappedSchema.kind) {\n case \"string\":\n if (typeof value !== \"string\") {\n throw new UserError(`Invalid value for \"${label}\". Expected a string.`);\n }\n return value;\n\n case \"number\":\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new UserError(`Invalid value for \"${label}\". Expected a number.`);\n }\n return value;\n\n case \"boolean\":\n if (typeof value !== \"boolean\") {\n throw new UserError(`Invalid value for \"${label}\". Expected a boolean.`);\n }\n return value;\n\n case \"enum\":\n return validateEnum(value, unwrappedSchema, label);\n\n case \"array\":\n if (!Array.isArray(value)) {\n throw new UserError(`Invalid value for \"${label}\". Expected an array.`);\n }\n return value.map((item, index) => validateSchemaValue(unwrappedSchema.item, item, `${label}[${index}]`));\n\n case \"object\":\n return validateObjectSchema(unwrappedSchema, value, label);\n }\n}\n\nfunction validateObjectSchema(\n schema: ObjectSchema<any>,\n value: unknown,\n label: string\n): Record<string, unknown> {\n if (!isPlainObject(value)) {\n throw new UserError(`Invalid value for \"${label}\". Expected an object.`);\n }\n\n const result: Record<string, unknown> = {};\n const expectedKeys = new Map<string, [string, AnySchema]>();\n\n for (const [key, childSchema] of Object.entries(schema.shape) as Array<[string, AnySchema]>) {\n expectedKeys.set(formatSegment(key), [key, childSchema]);\n }\n\n for (const key of Object.keys(value)) {\n if (!expectedKeys.has(key)) {\n const fieldLabel = label.length === 0 ? key : `${label}.${key}`;\n throw new UserError(`Unexpected parameter \"${fieldLabel}\".`);\n }\n }\n\n for (const [inputKey, [outputKey, rawChildSchema]] of expectedKeys.entries()) {\n const childSchema = unwrapOptional(rawChildSchema);\n const hasValue = Object.prototype.hasOwnProperty.call(value, inputKey);\n const fieldLabel = label.length === 0 ? inputKey : `${label}.${inputKey}`;\n\n if (!hasValue) {\n if (childSchema.default !== undefined) {\n result[outputKey] = childSchema.default;\n continue;\n }\n\n if (isOptional(rawChildSchema)) {\n continue;\n }\n\n throw new UserError(`Missing required parameter \"${fieldLabel}\".`);\n }\n\n result[outputKey] = validateSchemaValue(rawChildSchema, value[inputKey], fieldLabel);\n }\n\n return result;\n}\n\nfunction validateSDKArguments(\n schema: ObjectSchema<any>,\n argumentsValue: Record<string, unknown> | undefined\n): Record<string, unknown> {\n return validateObjectSchema(schema, argumentsValue ?? {}, \"\");\n}\n\nfunction defineMember(target: Record<string, unknown>, key: string, value: unknown): void {\n if (Object.prototype.hasOwnProperty.call(target, key)) {\n throw new Error(`Duplicate SDK member \"${key}\".`);\n }\n\n Object.defineProperty(target, key, {\n value,\n enumerable: true,\n configurable: false,\n writable: false,\n });\n}\n\nexport function createSDK<\n TRootInfo,\n TServices extends object = Record<string, unknown>,\n>(\n root: Group<any> & {\n readonly __cmdkitGroupTypeInfo: TRootInfo;\n },\n options?: CreateSDKOptions<TServices>\n): TRootInfo extends { children: infer TChildren extends readonly unknown[] }\n ? SDKChildrenShape<TChildren, undefined>\n : EmptyRecord;\nexport function createSDK(\n root: Group<any>,\n options: CreateSDKOptions<any> = {}\n): Record<string, unknown> {\n const services = options.services ?? {};\n void options.casing;\n validateServices(services as Record<string, unknown>);\n\n function build(node: Group<any> | Command<any, any, any, any>): unknown {\n if (node.kind === \"command\") {\n return async (params: Record<string, unknown> | undefined) => {\n const secrets = resolveCommandSecrets(node);\n const baseContext = {\n ...services,\n secrets,\n fetch: globalThis.fetch,\n fs: createFs(),\n env: createEnv(),\n progress(): void {\n return undefined;\n },\n };\n\n await assertCommandRequirements(node, { ...baseContext, params: undefined });\n\n const validatedParams = validateSDKArguments(node.params, params);\n return node.handler({\n ...baseContext,\n params: validatedParams,\n } as Parameters<typeof node.handler>[0]);\n };\n }\n\n const output: Record<string, unknown> = {};\n\n for (const child of node.children) {\n if (child.kind === \"command\") {\n if (!child.scope.includes(\"sdk\")) {\n continue;\n }\n\n defineMember(output, formatSegment(child.name), build(child));\n continue;\n }\n\n const childValue = build(child);\n if (isPlainObject(childValue) && Object.keys(childValue).length > 0) {\n defineMember(output, formatSegment(child.name), childValue);\n }\n }\n\n return output;\n }\n\n return build(root) as Record<string, unknown>;\n}\n", "import { fileURLToPath } from \"node:url\";\nimport type { ObjectSchema, Static } from \"@poe-code/cmdkit-schema\";\nimport type { LoggerOutput, RenderTableOptions, ThemePalette } from \"@poe-code/design-system\";\n\nconst commandConfigSymbol = Symbol(\"cmdkit.command.config\");\nconst groupConfigSymbol = Symbol(\"cmdkit.group.config\");\nconst commandSourcePathSymbol = Symbol(\"cmdkit.command.sourcePath\");\n\ntype ScopeValue = \"cli\" | \"mcp\" | \"sdk\";\ntype AnyObjectSchema = ObjectSchema<Record<string, never>>;\ntype EmptyServices = Record<string, never>;\ntype ScopeInput = readonly Scope[] | undefined;\n\nexport type Scope = ScopeValue;\n\nexport interface SecretDefinition {\n env: string;\n description?: string;\n optional?: boolean;\n}\n\nexport type SecretDeclarations = Record<string, SecretDefinition>;\n\ntype OptionalSecretKeys<TSecrets extends SecretDeclarations> = {\n [TKey in keyof TSecrets]: TSecrets[TKey] extends { optional: true } ? TKey : never;\n}[keyof TSecrets];\n\ntype RequiredSecretKeys<TSecrets extends SecretDeclarations> = Exclude<\n keyof TSecrets,\n OptionalSecretKeys<TSecrets>\n>;\n\nexport type InferSecrets<TSecrets extends SecretDeclarations | undefined> =\n TSecrets extends SecretDeclarations\n ? { [TKey in RequiredSecretKeys<TSecrets>]: string } & {\n [TKey in OptionalSecretKeys<TSecrets>]?: string;\n }\n : Record<string, never>;\n\nexport interface HandlerFs {\n readFile(path: string, encoding?: BufferEncoding): Promise<string>;\n writeFile(path: string, contents: string): Promise<void>;\n exists(path: string): Promise<boolean>;\n}\n\nexport interface HandlerEnv {\n get(key: string): string | undefined;\n}\n\nexport interface RenderPrimitives {\n logger: LoggerOutput;\n renderTable(options: RenderTableOptions): string;\n getTheme(): ThemePalette;\n note(message: string, title?: string): void;\n}\n\nexport interface CheckResult {\n ok: boolean;\n message?: string;\n}\n\nexport type GroupCheckContext<TServices extends object = EmptyServices> = TServices & {\n params?: unknown;\n secrets?: Record<string, string | undefined>;\n fetch: typeof globalThis.fetch;\n fs: HandlerFs;\n env: HandlerEnv;\n progress(message: string): void;\n};\n\nexport type CommandCheckContext<\n TParamsSchema extends ObjectSchema<any> = AnyObjectSchema,\n TSecrets extends SecretDeclarations | undefined = undefined,\n TServices extends object = EmptyServices,\n> = TServices & {\n params?: Static<TParamsSchema>;\n secrets?: InferSecrets<TSecrets>;\n fetch: typeof globalThis.fetch;\n fs: HandlerFs;\n env: HandlerEnv;\n progress(message: string): void;\n};\n\nexport interface Requires<TContext = unknown> {\n auth?: boolean;\n apiVersion?: string;\n check?: (ctx: TContext) => Promise<CheckResult>;\n}\n\nexport interface Renderers<TResult> {\n rich?: (result: TResult, primitives: RenderPrimitives) => void;\n markdown?: (result: TResult, primitives: RenderPrimitives) => string;\n json?: (result: TResult, primitives: RenderPrimitives) => unknown;\n}\n\nexport type HandlerContext<\n TParamsSchema extends ObjectSchema<any> = AnyObjectSchema,\n TSecrets extends SecretDeclarations | undefined = undefined,\n TServices extends object = EmptyServices,\n> = TServices & {\n params: Static<TParamsSchema>;\n secrets: InferSecrets<TSecrets>;\n fetch: typeof globalThis.fetch;\n fs: HandlerFs;\n env: HandlerEnv;\n progress(message: string): void;\n};\n\nexport interface CommandConfig<\n TServices extends object,\n TParamsSchema extends ObjectSchema<any>,\n TSecrets extends SecretDeclarations | undefined,\n TResult,\n> {\n name: string;\n description?: string;\n aliases?: string[];\n positional?: string[];\n params: TParamsSchema;\n secrets?: TSecrets;\n scope?: Scope[];\n confirm?: boolean;\n requires?: Requires<CommandCheckContext<TParamsSchema, TSecrets, TServices>>;\n handler: (ctx: HandlerContext<TParamsSchema, TSecrets, TServices>) => Promise<TResult>;\n render?: Renderers<TResult>;\n}\n\nexport interface Command<\n TServices extends object = EmptyServices,\n TParamsSchema extends ObjectSchema<any> = AnyObjectSchema,\n TSecrets extends SecretDeclarations | undefined = undefined,\n TResult = unknown,\n> {\n kind: \"command\";\n name: string;\n description?: string;\n aliases: string[];\n positional: string[];\n params: TParamsSchema;\n secrets: SecretDeclarations;\n scope: Scope[];\n confirm: boolean;\n requires?: Requires<any>;\n handler: (ctx: HandlerContext<TParamsSchema, TSecrets, TServices>) => Promise<TResult>;\n render?: Renderers<TResult>;\n}\n\nexport interface GroupConfig<TServices extends object> {\n name: string;\n description?: string;\n aliases?: string[];\n scope?: Scope[];\n secrets?: SecretDeclarations;\n requires?: Requires<GroupCheckContext<TServices>>;\n children: Array<CommandNode<TServices>>;\n default?: Command<TServices, any, any, any>;\n}\n\nexport interface Group<TServices extends object = EmptyServices> {\n kind: \"group\";\n name: string;\n description?: string;\n aliases: string[];\n scope?: Scope[];\n secrets: SecretDeclarations;\n requires?: Requires<any>;\n children: Array<CommandNode<TServices>>;\n default?: Command<TServices, any, any, any>;\n}\n\nexport type CommandNode<TServices extends object = EmptyServices> =\n | Command<TServices, any, any, any>\n | Group<TServices>;\n\nexport interface CommandTypeInfo<\n TName extends string = string,\n TParamsSchema extends ObjectSchema<any> = AnyObjectSchema,\n TResult = unknown,\n TOwnScope extends ScopeInput = ScopeInput,\n> {\n name: TName;\n params: TParamsSchema;\n result: TResult;\n ownScope: TOwnScope;\n}\n\nexport interface GroupTypeInfo<\n TServices extends object = EmptyServices,\n TName extends string = string,\n TChildren extends readonly unknown[] = readonly CommandNode<TServices>[],\n TOwnScope extends ScopeInput = ScopeInput,\n> {\n name: TName;\n children: TChildren;\n ownScope: TOwnScope;\n}\n\ntype TypedCommandMetadata<\n TName extends string,\n TParamsSchema extends ObjectSchema<any>,\n TResult,\n TOwnScope extends ScopeInput,\n> = {\n readonly __cmdkitCommandTypeInfo: CommandTypeInfo<TName, TParamsSchema, TResult, TOwnScope>;\n};\n\ntype TypedGroupMetadata<\n TServices extends object,\n TName extends string,\n TChildren extends readonly unknown[],\n TOwnScope extends ScopeInput,\n> = {\n readonly __cmdkitGroupTypeInfo: GroupTypeInfo<TServices, TName, TChildren, TOwnScope>;\n};\n\ninterface InternalCommandConfig {\n scope?: Scope[];\n secrets: SecretDeclarations;\n requires?: Requires<any>;\n sourcePath?: string;\n}\n\ninterface InternalGroupConfig<TServices extends object> {\n scope?: Scope[];\n secrets: SecretDeclarations;\n requires?: Requires<any>;\n children: Array<CommandNode<TServices>>;\n default?: Command<TServices, any, any, any>;\n}\n\ninterface InheritedMetadata {\n scope?: Scope[];\n secrets: SecretDeclarations;\n requires?: Requires<any>;\n}\n\nexport class UserError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"UserError\";\n }\n}\n\nexport interface CommandRequirementOptions {\n apiVersion?: string;\n authEnvVar?: string;\n env?: Record<string, string | undefined>;\n}\n\nfunction cloneScope(scope: Scope[] | undefined): Scope[] | undefined {\n return scope === undefined ? undefined : [...scope];\n}\n\nfunction cloneSecretDefinition(secret: SecretDefinition): SecretDefinition {\n return {\n env: secret.env,\n description: secret.description,\n optional: secret.optional,\n };\n}\n\nfunction cloneSecrets(secrets: SecretDeclarations | undefined): SecretDeclarations {\n if (secrets === undefined) {\n return {};\n }\n\n return Object.fromEntries(\n Object.entries(secrets).map(([key, secret]) => [key, cloneSecretDefinition(secret)])\n );\n}\n\nfunction cloneRequires<TContext>(requires: Requires<TContext> | undefined): Requires<TContext> | undefined {\n if (requires === undefined) {\n return undefined;\n }\n\n return {\n auth: requires.auth,\n apiVersion: requires.apiVersion,\n check: requires.check,\n };\n}\n\nfunction parseStackPath(candidate: string): string | undefined {\n if (candidate.startsWith(\"file://\")) {\n try {\n return fileURLToPath(candidate);\n } catch {\n return undefined;\n }\n }\n\n if (candidate.startsWith(\"/\")) {\n return candidate;\n }\n\n return undefined;\n}\n\nfunction extractStackPath(line: string): string | undefined {\n const trimmed = line.trim();\n const fileIndex = trimmed.indexOf(\"file://\");\n\n if (fileIndex >= 0) {\n const location = trimmed.slice(fileIndex);\n const separatorIndex = location.lastIndexOf(\":\");\n const previousSeparatorIndex = separatorIndex >= 0 ? location.lastIndexOf(\":\", separatorIndex - 1) : -1;\n const candidate =\n separatorIndex >= 0 && previousSeparatorIndex >= 0\n ? location.slice(0, previousSeparatorIndex)\n : location;\n\n return parseStackPath(candidate);\n }\n\n const slashIndex = trimmed.indexOf(\"/\");\n if (slashIndex < 0) {\n return undefined;\n }\n\n const location = trimmed.slice(slashIndex);\n const separatorIndex = location.lastIndexOf(\":\");\n const previousSeparatorIndex = separatorIndex >= 0 ? location.lastIndexOf(\":\", separatorIndex - 1) : -1;\n const candidate =\n separatorIndex >= 0 && previousSeparatorIndex >= 0\n ? location.slice(0, previousSeparatorIndex)\n : location;\n\n return parseStackPath(candidate);\n}\n\nfunction inferCommandSourcePath(): string | undefined {\n const stack = new Error().stack;\n\n if (typeof stack !== \"string\") {\n return undefined;\n }\n\n for (const line of stack.split(\"\\n\").slice(1)) {\n const candidate = extractStackPath(line);\n\n if (candidate === undefined) {\n continue;\n }\n\n if (\n candidate.includes(\"/packages/cmdkit/src/index.ts\") ||\n candidate.includes(\"/packages/cmdkit/dist/index.js\")\n ) {\n continue;\n }\n\n return candidate;\n }\n\n return undefined;\n}\n\nfunction composeChecks(\n parentCheck: Requires<any>[\"check\"] | undefined,\n childCheck: Requires<any>[\"check\"] | undefined\n): Requires<any>[\"check\"] | undefined {\n if (parentCheck === undefined) {\n return childCheck;\n }\n\n if (childCheck === undefined) {\n return parentCheck;\n }\n\n return async (ctx) => {\n const parentResult = await parentCheck(ctx);\n if (!parentResult.ok) {\n return parentResult;\n }\n\n return childCheck(ctx);\n };\n}\n\nfunction mergeRequires(parent: Requires<any> | undefined, child: Requires<any> | undefined): Requires<any> | undefined {\n if (parent === undefined && child === undefined) {\n return undefined;\n }\n\n const merged: Requires<any> = {\n auth: child?.auth ?? parent?.auth,\n apiVersion: child?.apiVersion ?? parent?.apiVersion,\n check: composeChecks(parent?.check, child?.check),\n };\n\n if (\n merged.auth === undefined &&\n merged.apiVersion === undefined &&\n merged.check === undefined\n ) {\n return undefined;\n }\n\n return merged;\n}\n\nfunction parseSimpleSemver(value: string): [number, number, number] | undefined {\n const parts = value.split(\".\");\n if (parts.length !== 3) {\n return undefined;\n }\n\n const parsed = parts.map((part) => {\n if (part.length === 0) {\n return Number.NaN;\n }\n\n for (const char of part) {\n if (char < \"0\" || char > \"9\") {\n return Number.NaN;\n }\n }\n\n return Number(part);\n });\n\n if (parsed.some((part) => !Number.isInteger(part) || part < 0)) {\n return undefined;\n }\n\n return parsed as [number, number, number];\n}\n\nfunction parseMinimumApiVersion(requirement: string): [number, number, number] | undefined {\n if (!requirement.startsWith(\">=\")) {\n return undefined;\n }\n\n return parseSimpleSemver(requirement.slice(2).trim());\n}\n\nfunction compareSemver(left: [number, number, number], right: [number, number, number]): number {\n for (let index = 0; index < left.length; index += 1) {\n if (left[index] === right[index]) {\n continue;\n }\n\n return left[index]! > right[index]! ? 1 : -1;\n }\n\n return 0;\n}\n\nexport function resolveCommandSecrets(\n command: Command<any, any, any, any>,\n env: Record<string, string | undefined> = process.env\n): Record<string, string | undefined> {\n const secrets: Record<string, string | undefined> = {};\n\n for (const [name, secret] of Object.entries(command.secrets)) {\n const value = env[secret.env];\n\n if (value === undefined && secret.optional !== true) {\n const details = secret.description ? `\\n ${secret.description}` : \"\";\n throw new UserError(`Error: Missing required secret ${secret.env}${details}`);\n }\n\n secrets[name] = value;\n }\n\n return secrets;\n}\n\nexport async function assertCommandRequirements(\n command: Command<any, any, any, any>,\n context: GroupCheckContext<any>,\n options: CommandRequirementOptions = {}\n): Promise<void> {\n const requires = command.requires;\n if (requires === undefined) {\n return;\n }\n\n const env = options.env ?? process.env;\n const authEnvVar = options.authEnvVar ?? \"POE_API_KEY\";\n\n if (requires.auth === true && env[authEnvVar] === undefined) {\n throw new UserError(\n `Error: Command \"${command.name}\" requires authentication.\\n Run 'poe-code login' first.`\n );\n }\n\n if (requires.apiVersion !== undefined) {\n const minimumVersion = parseMinimumApiVersion(requires.apiVersion);\n if (minimumVersion === undefined) {\n throw new UserError(\n `Error: Command \"${command.name}\" has invalid apiVersion requirement \"${requires.apiVersion}\". Expected format \">=X.Y.Z\".`\n );\n }\n\n if (options.apiVersion === undefined) {\n throw new UserError(\n `Error: Command \"${command.name}\" requires API version ${requires.apiVersion}, but no runner API version was provided.`\n );\n }\n\n const runnerVersion = parseSimpleSemver(options.apiVersion);\n if (runnerVersion === undefined) {\n throw new UserError(\n `Error: Command \"${command.name}\" requires API version ${requires.apiVersion}, but runner API version \"${options.apiVersion}\" is not valid semver.`\n );\n }\n\n if (compareSemver(runnerVersion, minimumVersion) < 0) {\n throw new UserError(\n `Error: Command \"${command.name}\" requires API version ${requires.apiVersion}, but runner API version is ${options.apiVersion}.`\n );\n }\n }\n\n const checkResult = await requires.check?.(context);\n if (checkResult && !checkResult.ok) {\n throw new UserError(checkResult.message ?? \"Command precondition failed.\");\n }\n}\n\nfunction mergeSecrets(parent: SecretDeclarations, child: SecretDeclarations): SecretDeclarations {\n return cloneSecrets({\n ...parent,\n ...child,\n });\n}\n\nfunction resolveCommandScope(ownScope: Scope[] | undefined, inheritedScope: Scope[] | undefined): Scope[] {\n return cloneScope(ownScope ?? inheritedScope) ?? [\"cli\", \"sdk\"];\n}\n\nfunction resolveGroupScope(ownScope: Scope[] | undefined, inheritedScope: Scope[] | undefined): Scope[] | undefined {\n return cloneScope(ownScope ?? inheritedScope);\n}\n\nfunction createBaseCommand<\n TServices extends object,\n TParamsSchema extends ObjectSchema<any>,\n TSecrets extends SecretDeclarations | undefined,\n TResult,\n>(\n config: CommandConfig<TServices, TParamsSchema, TSecrets, TResult>\n): Command<TServices, TParamsSchema, TSecrets, TResult> {\n const command: Command<TServices, TParamsSchema, TSecrets, TResult> = {\n kind: \"command\",\n name: config.name,\n description: config.description,\n aliases: [...(config.aliases ?? [])],\n positional: [...(config.positional ?? [])],\n params: config.params,\n secrets: cloneSecrets(config.secrets),\n scope: resolveCommandScope(config.scope, undefined),\n confirm: config.confirm ?? false,\n requires: cloneRequires(config.requires),\n handler: config.handler,\n render: config.render,\n };\n\n Object.defineProperty(command, commandConfigSymbol, {\n value: {\n scope: cloneScope(config.scope),\n secrets: cloneSecrets(config.secrets),\n requires: cloneRequires(config.requires),\n sourcePath: inferCommandSourcePath(),\n } satisfies InternalCommandConfig,\n });\n\n return command;\n}\n\nfunction createBaseGroup<TServices extends object>(config: GroupConfig<TServices>): Group<TServices> {\n const group: Group<TServices> = {\n kind: \"group\",\n name: config.name,\n description: config.description,\n aliases: [...(config.aliases ?? [])],\n scope: resolveGroupScope(config.scope, undefined),\n secrets: cloneSecrets(config.secrets),\n requires: cloneRequires(config.requires),\n children: [],\n default: undefined,\n };\n\n Object.defineProperty(group, groupConfigSymbol, {\n value: {\n scope: cloneScope(config.scope),\n secrets: cloneSecrets(config.secrets),\n requires: cloneRequires(config.requires),\n children: [...config.children],\n default: config.default,\n } satisfies InternalGroupConfig<TServices>,\n });\n\n return group;\n}\n\nfunction getInternalCommandConfig(command: Command<any, any, any, any>): InternalCommandConfig {\n return (command as Command<any, any, any, any> & { [commandConfigSymbol]: InternalCommandConfig })[\n commandConfigSymbol\n ];\n}\n\nfunction getInternalGroupConfig<TServices extends object>(group: Group<TServices>): InternalGroupConfig<TServices> {\n return (group as Group<TServices> & { [groupConfigSymbol]: InternalGroupConfig<TServices> })[\n groupConfigSymbol\n ];\n}\n\nfunction materializeCommand<\n TServices extends object,\n TParamsSchema extends ObjectSchema<any>,\n TSecrets extends SecretDeclarations | undefined,\n TResult,\n>(\n command: Command<TServices, TParamsSchema, TSecrets, TResult>,\n inherited: InheritedMetadata\n): Command<TServices, TParamsSchema, TSecrets, TResult> {\n const internal = getInternalCommandConfig(command);\n\n const materialized: Command<TServices, TParamsSchema, TSecrets, TResult> = {\n kind: \"command\",\n name: command.name,\n description: command.description,\n aliases: [...command.aliases],\n positional: [...command.positional],\n params: command.params,\n secrets: mergeSecrets(inherited.secrets, internal.secrets),\n scope: resolveCommandScope(internal.scope, inherited.scope),\n confirm: command.confirm,\n requires: mergeRequires(inherited.requires, internal.requires),\n handler: command.handler,\n render: command.render,\n };\n\n Object.defineProperty(materialized, commandConfigSymbol, {\n value: {\n scope: cloneScope(internal.scope),\n secrets: cloneSecrets(internal.secrets),\n requires: cloneRequires(internal.requires),\n sourcePath: internal.sourcePath,\n } satisfies InternalCommandConfig,\n });\n\n Object.defineProperty(materialized, commandSourcePathSymbol, {\n value: internal.sourcePath,\n });\n\n return materialized;\n}\n\nfunction materializeGroup<TServices extends object>(\n group: Group<TServices>,\n inherited: InheritedMetadata\n): Group<TServices> {\n const internal = getInternalGroupConfig(group);\n const scope = resolveGroupScope(internal.scope, inherited.scope);\n const secrets = mergeSecrets(inherited.secrets, internal.secrets);\n const requires = mergeRequires(inherited.requires, internal.requires);\n const materializedChildren = internal.children.map((child) =>\n materializeNode(child, {\n scope,\n secrets,\n requires,\n })\n );\n\n let defaultChild: Command<TServices, any, any, any> | undefined;\n\n if (internal.default !== undefined) {\n const defaultIndex = internal.children.indexOf(internal.default);\n\n if (defaultIndex === -1) {\n throw new UserError(`Default command \"${internal.default.name}\" must be listed in children.`);\n }\n\n const resolvedDefault = materializedChildren[defaultIndex];\n if (resolvedDefault?.kind !== \"command\") {\n throw new UserError(`Default child \"${internal.default.name}\" must be a command.`);\n }\n\n defaultChild = resolvedDefault;\n }\n\n const materialized: Group<TServices> = {\n kind: \"group\",\n name: group.name,\n description: group.description,\n aliases: [...group.aliases],\n scope,\n secrets,\n requires,\n children: materializedChildren,\n default: defaultChild,\n };\n\n Object.defineProperty(materialized, groupConfigSymbol, {\n value: {\n scope: cloneScope(internal.scope),\n secrets: cloneSecrets(internal.secrets),\n requires: cloneRequires(internal.requires),\n children: [...internal.children],\n default: internal.default,\n } satisfies InternalGroupConfig<TServices>,\n });\n\n return materialized;\n}\n\nfunction materializeNode<TServices extends object>(\n node: CommandNode<TServices>,\n inherited: InheritedMetadata\n): CommandNode<TServices> {\n if (node.kind === \"command\") {\n return materializeCommand(node, inherited);\n }\n\n return materializeGroup(node, inherited);\n}\n\nexport function defineCommand<\n TServices extends object = EmptyServices,\n TName extends string = string,\n TParamsSchema extends ObjectSchema<any> = AnyObjectSchema,\n TSecrets extends SecretDeclarations | undefined = undefined,\n TResult = unknown,\n TOwnScope extends ScopeInput = undefined,\n>(\n config: Omit<CommandConfig<TServices, TParamsSchema, TSecrets, TResult>, \"name\" | \"scope\"> & {\n name: TName;\n scope?: TOwnScope;\n }\n): Command<TServices, TParamsSchema, TSecrets, TResult> &\n TypedCommandMetadata<TName, TParamsSchema, TResult, TOwnScope> {\n return materializeCommand(createBaseCommand(config as CommandConfig<TServices, TParamsSchema, TSecrets, TResult>), {\n scope: undefined,\n secrets: {},\n requires: undefined,\n }) as Command<TServices, TParamsSchema, TSecrets, TResult> &\n TypedCommandMetadata<TName, TParamsSchema, TResult, TOwnScope>;\n}\n\nexport function defineGroup<\n TServices extends object = EmptyServices,\n TName extends string = string,\n TChildren extends readonly unknown[] = readonly CommandNode<TServices>[],\n TOwnScope extends ScopeInput = undefined,\n>(\n config: Omit<GroupConfig<TServices>, \"name\" | \"children\" | \"scope\"> & {\n name: TName;\n children: TChildren & readonly CommandNode<TServices>[];\n scope?: TOwnScope;\n }\n): Group<TServices> & TypedGroupMetadata<TServices, TName, TChildren, TOwnScope> {\n return materializeGroup(createBaseGroup(config as unknown as GroupConfig<TServices>), {\n scope: undefined,\n secrets: {},\n requires: undefined,\n }) as Group<TServices> & TypedGroupMetadata<TServices, TName, TChildren, TOwnScope>;\n}\n\nexport function getCommandSourcePath(command: Command<any, any, any, any>): string | undefined {\n return (command as Command<any, any, any, any> & { [commandSourcePathSymbol]?: string })[\n commandSourcePathSymbol\n ];\n}\n\nexport { S, toJsonSchema } from \"@poe-code/cmdkit-schema\";\nexport type { AnySchema, ArraySchema, BooleanSchema, EnumSchema, JsonSchema, NumberSchema, ObjectSchema, OptionalSchema, Static, StringSchema } from \"@poe-code/cmdkit-schema\";\n"],
5
- "mappings": "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",
3
+ "sources": ["../src/sdk.ts", "../src/index.ts", "../src/number-schema.ts", "../src/schema-scope.ts"],
4
+ "sourcesContent": ["import { access, readFile, writeFile } from \"node:fs/promises\";\nimport type { AnySchema, ObjectSchema, Static } from \"@poe-code/cmdkit-schema\";\nimport type { Command, Group, HandlerEnv, HandlerFs, Scope } from \"./index.js\";\nimport { UserError, assertCommandRequirements, resolveCommandSecrets } from \"./index.js\";\nimport { getExpectedNumberDescription, isValidNumberSchemaValue } from \"./number-schema.js\";\nimport { filterSchemaForScope } from \"./schema-scope.js\";\n\nconst RESERVED_SERVICE_NAMES = new Set([\"params\", \"secrets\", \"fetch\", \"fs\", \"env\", \"progress\"]);\n\ntype ScopeInput = readonly Scope[] | undefined;\ntype Primitive = string | number | boolean | bigint | symbol | null | undefined;\ntype EmptyRecord = Record<never, never>;\n\ntype EffectiveCommandScope<\n TOwnScope extends ScopeInput,\n TInheritedScope extends ScopeInput,\n> = TOwnScope extends readonly Scope[]\n ? TOwnScope\n : TInheritedScope extends readonly Scope[]\n ? TInheritedScope\n : readonly [\"cli\", \"sdk\"];\n\ntype EffectiveGroupScope<\n TOwnScope extends ScopeInput,\n TInheritedScope extends ScopeInput,\n> = TOwnScope extends readonly Scope[]\n ? TOwnScope\n : TInheritedScope extends readonly Scope[]\n ? TInheritedScope\n : undefined;\n\ntype IncludesSDK<TScope> = TScope extends readonly Scope[]\n ? \"sdk\" extends TScope[number]\n ? true\n : false\n : false;\n\ntype Separator = \"-\" | \"_\" | \" \" | \".\";\n\ntype IsUppercase<TValue extends string> = TValue extends Uppercase<TValue>\n ? TValue extends Lowercase<TValue>\n ? false\n : true\n : false;\n\ntype IsLowercase<TValue extends string> = TValue extends Lowercase<TValue>\n ? TValue extends Uppercase<TValue>\n ? false\n : true\n : false;\n\ntype LastCharacter<TValue extends string> = TValue extends `${infer THead}${infer TTail}`\n ? TTail extends \"\"\n ? THead\n : LastCharacter<TTail>\n : never;\n\ntype PushCurrentWord<\n TCurrent extends string,\n TWords extends readonly string[],\n> = TCurrent extends \"\" ? TWords : [...TWords, Lowercase<TCurrent>];\n\ntype SplitCamelWords<\n TValue extends string,\n TCurrent extends string = \"\",\n TWords extends readonly string[] = [],\n> = TValue extends `${infer TChar}${infer TRest}`\n ? TChar extends Separator\n ? SplitCamelWords<TRest, \"\", PushCurrentWord<TCurrent, TWords>>\n : IsUppercase<TChar> extends true\n ? TCurrent extends \"\"\n ? SplitCamelWords<TRest, TChar, TWords>\n : TRest extends `${infer TNext}${string}`\n ? IsLowercase<LastCharacter<TCurrent>> extends true\n ? SplitCamelWords<TRest, TChar, PushCurrentWord<TCurrent, TWords>>\n : IsLowercase<TNext> extends true\n ? SplitCamelWords<TRest, TChar, PushCurrentWord<TCurrent, TWords>>\n : SplitCamelWords<TRest, `${TCurrent}${TChar}`, TWords>\n : SplitCamelWords<TRest, `${TCurrent}${TChar}`, TWords>\n : SplitCamelWords<TRest, `${TCurrent}${TChar}`, TWords>\n : PushCurrentWord<TCurrent, TWords>;\n\ntype JoinCamelWords<TWords extends readonly string[]> = TWords extends readonly [\n infer THead extends string,\n ...infer TTail extends readonly string[],\n]\n ? `${THead}${CapitalizeJoinCamelWords<TTail>}`\n : \"\";\n\ntype CapitalizeJoinCamelWords<TWords extends readonly string[]> = TWords extends readonly [\n infer THead extends string,\n ...infer TTail extends readonly string[],\n]\n ? `${Capitalize<THead>}${CapitalizeJoinCamelWords<TTail>}`\n : \"\";\n\ntype CamelCase<TValue extends string> = JoinCamelWords<SplitCamelWords<TValue>>;\n\ntype Camelize<TValue> = TValue extends Primitive\n ? TValue\n : TValue extends readonly (infer TItem)[]\n ? Array<Camelize<TItem>>\n : TValue extends object\n ? {\n [TKey in keyof TValue as TKey extends string ? CamelCase<TKey> : TKey]: Camelize<TValue[TKey]>;\n }\n : TValue;\n\ntype SDKMethod<TParamsSchema extends ObjectSchema<any>, TResult> = (\n params: Camelize<Static<TParamsSchema>>\n) => Promise<TResult>;\n\ntype UnionToIntersection<TValue> = (\n TValue extends unknown ? (value: TValue) => void : never\n) extends (value: infer TResult) => void\n ? TResult\n : never;\n\ntype Simplify<TValue> = { [TKey in keyof TValue]: TValue[TKey] };\n\ntype RawChildrenValue<TChildren> = TChildren extends readonly unknown[] ? TChildren[number] : never;\n\ntype SDKNodeShape<TNode, TInheritedScope extends ScopeInput> =\n TNode extends {\n kind: \"command\";\n readonly __cmdkitCommandTypeInfo: {\n name: infer TName extends string;\n params: infer TParamsSchema extends ObjectSchema<any>;\n result: infer TResult;\n ownScope: infer TOwnScope extends ScopeInput;\n };\n }\n ? IncludesSDK<EffectiveCommandScope<TOwnScope, TInheritedScope>> extends true\n ? { [TKey in CamelCase<TName>]: SDKMethod<TParamsSchema, TResult> }\n : EmptyRecord\n : TNode extends {\n kind: \"group\";\n readonly __cmdkitGroupTypeInfo: {\n name: infer TName extends string;\n children: infer TChildren extends readonly unknown[];\n ownScope: infer TOwnScope extends ScopeInput;\n };\n }\n ? SDKChildrenShape<TChildren, EffectiveGroupScope<TOwnScope, TInheritedScope>> extends infer TChildShape extends object\n ? keyof TChildShape extends never\n ? EmptyRecord\n : { [TKey in CamelCase<TName>]: TChildShape }\n : never\n : EmptyRecord;\n\ntype SDKChildrenShape<TChildren, TInheritedScope extends ScopeInput> = Simplify<\n UnionToIntersection<SDKNodeShape<RawChildrenValue<TChildren>, TInheritedScope>>\n>;\n\nexport interface CreateSDKOptions<TServices extends object = Record<string, unknown>> {\n services?: TServices;\n casing?: \"camel\";\n}\n\nfunction splitWords(value: string): string[] {\n const words: string[] = [];\n let current = \"\";\n\n for (let index = 0; index < value.length; index += 1) {\n const char = value[index] ?? \"\";\n const lower = char.toLowerCase();\n const upper = char.toUpperCase();\n const isSeparator = char === \"-\" || char === \"_\" || char === \" \" || char === \".\";\n\n if (isSeparator) {\n if (current.length > 0) {\n words.push(current.toLowerCase());\n current = \"\";\n }\n continue;\n }\n\n const isUppercase = char !== lower && char === upper;\n const previous = value[index - 1];\n const next = value[index + 1];\n const previousIsLowercase =\n previous !== undefined && previous === previous.toLowerCase() && previous !== previous.toUpperCase();\n const nextIsLowercase =\n next !== undefined && next === next.toLowerCase() && next !== next.toUpperCase();\n\n if (isUppercase && current.length > 0 && (previousIsLowercase || nextIsLowercase)) {\n words.push(current.toLowerCase());\n current = char;\n continue;\n }\n\n current += char;\n }\n\n if (current.length > 0) {\n words.push(current.toLowerCase());\n }\n\n return words;\n}\n\nfunction formatSegment(segment: string): string {\n return splitWords(segment)\n .map((word, index) => (index === 0 ? word : `${word[0]?.toUpperCase() ?? \"\"}${word.slice(1)}`))\n .join(\"\");\n}\n\nfunction unwrapOptional(schema: AnySchema): AnySchema {\n if (schema.kind === \"optional\") {\n return unwrapOptional(schema.inner);\n }\n\n return schema;\n}\n\nfunction isOptional(schema: AnySchema): boolean {\n return schema.kind === \"optional\";\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction createFs(): HandlerFs {\n return {\n readFile: async (path: string, encoding = \"utf8\") => readFile(path, { encoding }),\n writeFile: async (path: string, contents: string) => {\n await writeFile(path, contents);\n },\n exists: async (path: string) => {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n },\n };\n}\n\nfunction createEnv(values: Record<string, string | undefined> = process.env): HandlerEnv {\n return {\n get(key: string): string | undefined {\n return values[key];\n },\n };\n}\n\nfunction validateServices(services: Record<string, unknown>): void {\n for (const name of Object.keys(services)) {\n if (RESERVED_SERVICE_NAMES.has(name)) {\n throw new Error(`Service name \"${name}\" is reserved. Choose a different name.`);\n }\n }\n}\n\nfunction validateEnum(value: unknown, schema: Extract<AnySchema, { kind: \"enum\" }>, label: string): string | number | boolean {\n if (!schema.values.includes(value as never)) {\n throw new UserError(\n `Invalid value for \"${label}\". Expected one of: ${schema.values.map((candidate) => String(candidate)).join(\", \")}.`\n );\n }\n\n return value as string | number | boolean;\n}\n\nfunction validateSchemaValue(schema: AnySchema, value: unknown, label: string): unknown {\n const unwrappedSchema = unwrapOptional(schema);\n\n if (value === null && unwrappedSchema.nullable === true) {\n return null;\n }\n\n switch (unwrappedSchema.kind) {\n case \"string\":\n if (typeof value !== \"string\") {\n throw new UserError(`Invalid value for \"${label}\". Expected a string.`);\n }\n return value;\n\n case \"number\":\n if (!isValidNumberSchemaValue(value, unwrappedSchema)) {\n throw new UserError(\n `Invalid value for \"${label}\". Expected ${getExpectedNumberDescription(unwrappedSchema)}.`\n );\n }\n return value;\n\n case \"boolean\":\n if (typeof value !== \"boolean\") {\n throw new UserError(`Invalid value for \"${label}\". Expected a boolean.`);\n }\n return value;\n\n case \"enum\":\n return validateEnum(value, unwrappedSchema, label);\n\n case \"array\":\n if (!Array.isArray(value)) {\n throw new UserError(`Invalid value for \"${label}\". Expected an array.`);\n }\n return value.map((item, index) => validateSchemaValue(unwrappedSchema.item, item, `${label}[${index}]`));\n\n case \"object\":\n return validateObjectSchema(unwrappedSchema, value, label);\n }\n}\n\nfunction validateObjectSchema(\n schema: ObjectSchema<any>,\n value: unknown,\n label: string\n): Record<string, unknown> {\n if (!isPlainObject(value)) {\n throw new UserError(`Invalid value for \"${label}\". Expected an object.`);\n }\n\n const result: Record<string, unknown> = {};\n const expectedKeys = new Map<string, [string, AnySchema]>();\n\n for (const [key, childSchema] of Object.entries(schema.shape) as Array<[string, AnySchema]>) {\n expectedKeys.set(formatSegment(key), [key, childSchema]);\n }\n\n for (const key of Object.keys(value)) {\n if (!expectedKeys.has(key)) {\n const fieldLabel = label.length === 0 ? key : `${label}.${key}`;\n throw new UserError(`Unexpected parameter \"${fieldLabel}\".`);\n }\n }\n\n for (const [inputKey, [outputKey, rawChildSchema]] of expectedKeys.entries()) {\n const childSchema = unwrapOptional(rawChildSchema);\n const hasValue = Object.prototype.hasOwnProperty.call(value, inputKey);\n const fieldLabel = label.length === 0 ? inputKey : `${label}.${inputKey}`;\n\n if (!hasValue) {\n if (childSchema.default !== undefined) {\n result[outputKey] = childSchema.default;\n continue;\n }\n\n if (isOptional(rawChildSchema)) {\n continue;\n }\n\n throw new UserError(`Missing required parameter \"${fieldLabel}\".`);\n }\n\n result[outputKey] = validateSchemaValue(rawChildSchema, value[inputKey], fieldLabel);\n }\n\n return result;\n}\n\nfunction validateSDKArguments(\n schema: ObjectSchema<any>,\n argumentsValue: Record<string, unknown> | undefined\n): Record<string, unknown> {\n return validateObjectSchema(schema, argumentsValue ?? {}, \"\");\n}\n\nfunction defineMember(target: Record<string, unknown>, key: string, value: unknown): void {\n if (Object.prototype.hasOwnProperty.call(target, key)) {\n throw new Error(`Duplicate SDK member \"${key}\".`);\n }\n\n Object.defineProperty(target, key, {\n value,\n enumerable: true,\n configurable: false,\n writable: false,\n });\n}\n\nexport function createSDK<\n TRootInfo,\n TServices extends object = Record<string, unknown>,\n>(\n root: Group<any> & {\n readonly __cmdkitGroupTypeInfo: TRootInfo;\n },\n options?: CreateSDKOptions<TServices>\n): TRootInfo extends { children: infer TChildren extends readonly unknown[] }\n ? SDKChildrenShape<TChildren, undefined>\n : EmptyRecord;\nexport function createSDK(\n root: Group<any>,\n options: CreateSDKOptions<any> = {}\n): Record<string, unknown> {\n const services = options.services ?? {};\n void options.casing;\n validateServices(services as Record<string, unknown>);\n\n function build(node: Group<any> | Command<any, any, any, any>): unknown {\n if (node.kind === \"command\") {\n return async (params: Record<string, unknown> | undefined) => {\n const secrets = resolveCommandSecrets(node);\n const baseContext = {\n ...services,\n secrets,\n fetch: globalThis.fetch,\n fs: createFs(),\n env: createEnv(),\n progress(): void {\n return undefined;\n },\n };\n\n await assertCommandRequirements(node, { ...baseContext, params: undefined });\n\n const paramsSchema = filterSchemaForScope(node.params, \"sdk\");\n\n if (paramsSchema === undefined || paramsSchema.kind !== \"object\") {\n throw new Error(`Bug: command \"${node.name}\" must define an object params schema for SDK.`);\n }\n\n const validatedParams = validateSDKArguments(paramsSchema, params);\n return node.handler({\n ...baseContext,\n params: validatedParams,\n } as Parameters<typeof node.handler>[0]);\n };\n }\n\n const output: Record<string, unknown> = {};\n\n for (const child of node.children) {\n if (child.kind === \"command\") {\n if (!child.scope.includes(\"sdk\")) {\n continue;\n }\n\n defineMember(output, formatSegment(child.name), build(child));\n continue;\n }\n\n const childValue = build(child);\n if (isPlainObject(childValue) && Object.keys(childValue).length > 0) {\n defineMember(output, formatSegment(child.name), childValue);\n }\n }\n\n return output;\n }\n\n return build(root) as Record<string, unknown>;\n}\n", "import { fileURLToPath } from \"node:url\";\nimport type { ObjectSchema, Static } from \"@poe-code/cmdkit-schema\";\nimport type { LoggerOutput, RenderTableOptions, ThemePalette } from \"@poe-code/design-system\";\n\nconst commandConfigSymbol = Symbol(\"cmdkit.command.config\");\nconst groupConfigSymbol = Symbol(\"cmdkit.group.config\");\nconst commandSourcePathSymbol = Symbol(\"cmdkit.command.sourcePath\");\n\ntype ScopeValue = \"cli\" | \"mcp\" | \"sdk\";\ntype AnyObjectSchema = ObjectSchema<Record<string, never>>;\ntype EmptyServices = Record<string, never>;\ntype ScopeInput = readonly Scope[] | undefined;\n\nexport type Scope = ScopeValue;\n\nexport interface SecretDefinition {\n env: string;\n description?: string;\n optional?: boolean;\n}\n\nexport type SecretDeclarations = Record<string, SecretDefinition>;\n\ntype OptionalSecretKeys<TSecrets extends SecretDeclarations> = {\n [TKey in keyof TSecrets]: TSecrets[TKey] extends { optional: true } ? TKey : never;\n}[keyof TSecrets];\n\ntype RequiredSecretKeys<TSecrets extends SecretDeclarations> = Exclude<\n keyof TSecrets,\n OptionalSecretKeys<TSecrets>\n>;\n\nexport type InferSecrets<TSecrets extends SecretDeclarations | undefined> =\n TSecrets extends SecretDeclarations\n ? { [TKey in RequiredSecretKeys<TSecrets>]: string } & {\n [TKey in OptionalSecretKeys<TSecrets>]?: string;\n }\n : Record<string, never>;\n\nexport interface HandlerFs {\n readFile(path: string, encoding?: BufferEncoding): Promise<string>;\n writeFile(path: string, contents: string): Promise<void>;\n exists(path: string): Promise<boolean>;\n}\n\nexport interface HandlerEnv {\n get(key: string): string | undefined;\n}\n\nexport interface RenderPrimitives {\n logger: LoggerOutput;\n renderTable(options: RenderTableOptions): string;\n getTheme(): ThemePalette;\n note(message: string, title?: string): void;\n}\n\nexport interface CheckResult {\n ok: boolean;\n message?: string;\n}\n\nexport type GroupCheckContext<TServices extends object = EmptyServices> = TServices & {\n params?: unknown;\n secrets?: Record<string, string | undefined>;\n fetch: typeof globalThis.fetch;\n fs: HandlerFs;\n env: HandlerEnv;\n progress(message: string): void;\n};\n\nexport type CommandCheckContext<\n TParamsSchema extends ObjectSchema<any> = AnyObjectSchema,\n TSecrets extends SecretDeclarations | undefined = undefined,\n TServices extends object = EmptyServices,\n> = TServices & {\n params?: Static<TParamsSchema>;\n secrets?: InferSecrets<TSecrets>;\n fetch: typeof globalThis.fetch;\n fs: HandlerFs;\n env: HandlerEnv;\n progress(message: string): void;\n};\n\nexport interface Requires<TContext = unknown> {\n auth?: boolean;\n apiVersion?: string;\n check?: (ctx: TContext) => Promise<CheckResult>;\n}\n\nexport interface Renderers<TResult> {\n rich?: (result: TResult, primitives: RenderPrimitives) => void;\n markdown?: (result: TResult, primitives: RenderPrimitives) => string;\n json?: (result: TResult, primitives: RenderPrimitives) => unknown;\n}\n\nexport type HandlerContext<\n TParamsSchema extends ObjectSchema<any> = AnyObjectSchema,\n TSecrets extends SecretDeclarations | undefined = undefined,\n TServices extends object = EmptyServices,\n> = TServices & {\n params: Static<TParamsSchema>;\n secrets: InferSecrets<TSecrets>;\n fetch: typeof globalThis.fetch;\n fs: HandlerFs;\n env: HandlerEnv;\n progress(message: string): void;\n};\n\nexport interface CommandConfig<\n TServices extends object,\n TParamsSchema extends ObjectSchema<any>,\n TSecrets extends SecretDeclarations | undefined,\n TResult,\n> {\n name: string;\n description?: string;\n aliases?: string[];\n positional?: string[];\n params: TParamsSchema;\n secrets?: TSecrets;\n scope?: Scope[];\n confirm?: boolean;\n requires?: Requires<CommandCheckContext<TParamsSchema, TSecrets, TServices>>;\n handler: (ctx: HandlerContext<TParamsSchema, TSecrets, TServices>) => Promise<TResult>;\n render?: Renderers<TResult>;\n}\n\nexport interface Command<\n TServices extends object = EmptyServices,\n TParamsSchema extends ObjectSchema<any> = AnyObjectSchema,\n TSecrets extends SecretDeclarations | undefined = undefined,\n TResult = unknown,\n> {\n kind: \"command\";\n name: string;\n description?: string;\n aliases: string[];\n positional: string[];\n params: TParamsSchema;\n secrets: SecretDeclarations;\n scope: Scope[];\n confirm: boolean;\n requires?: Requires<any>;\n handler: (ctx: HandlerContext<TParamsSchema, TSecrets, TServices>) => Promise<TResult>;\n render?: Renderers<TResult>;\n}\n\nexport interface GroupConfig<TServices extends object> {\n name: string;\n description?: string;\n aliases?: string[];\n scope?: Scope[];\n secrets?: SecretDeclarations;\n requires?: Requires<GroupCheckContext<TServices>>;\n children: Array<CommandNode<TServices>>;\n default?: Command<TServices, any, any, any>;\n}\n\nexport interface Group<TServices extends object = EmptyServices> {\n kind: \"group\";\n name: string;\n description?: string;\n aliases: string[];\n scope?: Scope[];\n secrets: SecretDeclarations;\n requires?: Requires<any>;\n children: Array<CommandNode<TServices>>;\n default?: Command<TServices, any, any, any>;\n}\n\nexport type CommandNode<TServices extends object = EmptyServices> =\n | Command<TServices, any, any, any>\n | Group<TServices>;\n\nexport interface CommandTypeInfo<\n TName extends string = string,\n TParamsSchema extends ObjectSchema<any> = AnyObjectSchema,\n TResult = unknown,\n TOwnScope extends ScopeInput = ScopeInput,\n> {\n name: TName;\n params: TParamsSchema;\n result: TResult;\n ownScope: TOwnScope;\n}\n\nexport interface GroupTypeInfo<\n TServices extends object = EmptyServices,\n TName extends string = string,\n TChildren extends readonly unknown[] = readonly CommandNode<TServices>[],\n TOwnScope extends ScopeInput = ScopeInput,\n> {\n name: TName;\n children: TChildren;\n ownScope: TOwnScope;\n}\n\ntype TypedCommandMetadata<\n TName extends string,\n TParamsSchema extends ObjectSchema<any>,\n TResult,\n TOwnScope extends ScopeInput,\n> = {\n readonly __cmdkitCommandTypeInfo: CommandTypeInfo<TName, TParamsSchema, TResult, TOwnScope>;\n};\n\ntype TypedGroupMetadata<\n TServices extends object,\n TName extends string,\n TChildren extends readonly unknown[],\n TOwnScope extends ScopeInput,\n> = {\n readonly __cmdkitGroupTypeInfo: GroupTypeInfo<TServices, TName, TChildren, TOwnScope>;\n};\n\ninterface InternalCommandConfig {\n scope?: Scope[];\n secrets: SecretDeclarations;\n requires?: Requires<any>;\n sourcePath?: string;\n}\n\ninterface InternalGroupConfig<TServices extends object> {\n scope?: Scope[];\n secrets: SecretDeclarations;\n requires?: Requires<any>;\n children: Array<CommandNode<TServices>>;\n default?: Command<TServices, any, any, any>;\n}\n\ninterface InheritedMetadata {\n scope?: Scope[];\n secrets: SecretDeclarations;\n requires?: Requires<any>;\n}\n\nexport class UserError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"UserError\";\n }\n}\n\nexport interface CommandRequirementOptions {\n apiVersion?: string;\n authEnvVar?: string;\n env?: Record<string, string | undefined>;\n}\n\nfunction cloneScope(scope: Scope[] | undefined): Scope[] | undefined {\n return scope === undefined ? undefined : [...scope];\n}\n\nfunction cloneSecretDefinition(secret: SecretDefinition): SecretDefinition {\n return {\n env: secret.env,\n description: secret.description,\n optional: secret.optional,\n };\n}\n\nfunction cloneSecrets(secrets: SecretDeclarations | undefined): SecretDeclarations {\n if (secrets === undefined) {\n return {};\n }\n\n return Object.fromEntries(\n Object.entries(secrets).map(([key, secret]) => [key, cloneSecretDefinition(secret)])\n );\n}\n\nfunction cloneRequires<TContext>(requires: Requires<TContext> | undefined): Requires<TContext> | undefined {\n if (requires === undefined) {\n return undefined;\n }\n\n return {\n auth: requires.auth,\n apiVersion: requires.apiVersion,\n check: requires.check,\n };\n}\n\nfunction parseStackPath(candidate: string): string | undefined {\n if (candidate.startsWith(\"file://\")) {\n try {\n return fileURLToPath(candidate);\n } catch {\n return undefined;\n }\n }\n\n if (candidate.startsWith(\"/\")) {\n return candidate;\n }\n\n return undefined;\n}\n\nfunction extractStackPath(line: string): string | undefined {\n const trimmed = line.trim();\n const fileIndex = trimmed.indexOf(\"file://\");\n\n if (fileIndex >= 0) {\n const location = trimmed.slice(fileIndex);\n const separatorIndex = location.lastIndexOf(\":\");\n const previousSeparatorIndex = separatorIndex >= 0 ? location.lastIndexOf(\":\", separatorIndex - 1) : -1;\n const candidate =\n separatorIndex >= 0 && previousSeparatorIndex >= 0\n ? location.slice(0, previousSeparatorIndex)\n : location;\n\n return parseStackPath(candidate);\n }\n\n const slashIndex = trimmed.indexOf(\"/\");\n if (slashIndex < 0) {\n return undefined;\n }\n\n const location = trimmed.slice(slashIndex);\n const separatorIndex = location.lastIndexOf(\":\");\n const previousSeparatorIndex = separatorIndex >= 0 ? location.lastIndexOf(\":\", separatorIndex - 1) : -1;\n const candidate =\n separatorIndex >= 0 && previousSeparatorIndex >= 0\n ? location.slice(0, previousSeparatorIndex)\n : location;\n\n return parseStackPath(candidate);\n}\n\nfunction inferCommandSourcePath(): string | undefined {\n const stack = new Error().stack;\n\n if (typeof stack !== \"string\") {\n return undefined;\n }\n\n for (const line of stack.split(\"\\n\").slice(1)) {\n const candidate = extractStackPath(line);\n\n if (candidate === undefined) {\n continue;\n }\n\n if (\n candidate.includes(\"/packages/cmdkit/src/index.ts\") ||\n candidate.includes(\"/packages/cmdkit/dist/index.js\")\n ) {\n continue;\n }\n\n return candidate;\n }\n\n return undefined;\n}\n\nfunction composeChecks(\n parentCheck: Requires<any>[\"check\"] | undefined,\n childCheck: Requires<any>[\"check\"] | undefined\n): Requires<any>[\"check\"] | undefined {\n if (parentCheck === undefined) {\n return childCheck;\n }\n\n if (childCheck === undefined) {\n return parentCheck;\n }\n\n return async (ctx) => {\n const parentResult = await parentCheck(ctx);\n if (!parentResult.ok) {\n return parentResult;\n }\n\n return childCheck(ctx);\n };\n}\n\nfunction mergeRequires(parent: Requires<any> | undefined, child: Requires<any> | undefined): Requires<any> | undefined {\n if (parent === undefined && child === undefined) {\n return undefined;\n }\n\n const merged: Requires<any> = {\n auth: child?.auth ?? parent?.auth,\n apiVersion: child?.apiVersion ?? parent?.apiVersion,\n check: composeChecks(parent?.check, child?.check),\n };\n\n if (\n merged.auth === undefined &&\n merged.apiVersion === undefined &&\n merged.check === undefined\n ) {\n return undefined;\n }\n\n return merged;\n}\n\nfunction parseSimpleSemver(value: string): [number, number, number] | undefined {\n const parts = value.split(\".\");\n if (parts.length !== 3) {\n return undefined;\n }\n\n const parsed = parts.map((part) => {\n if (part.length === 0) {\n return Number.NaN;\n }\n\n for (const char of part) {\n if (char < \"0\" || char > \"9\") {\n return Number.NaN;\n }\n }\n\n return Number(part);\n });\n\n if (parsed.some((part) => !Number.isInteger(part) || part < 0)) {\n return undefined;\n }\n\n return parsed as [number, number, number];\n}\n\nfunction parseMinimumApiVersion(requirement: string): [number, number, number] | undefined {\n if (!requirement.startsWith(\">=\")) {\n return undefined;\n }\n\n return parseSimpleSemver(requirement.slice(2).trim());\n}\n\nfunction compareSemver(left: [number, number, number], right: [number, number, number]): number {\n for (let index = 0; index < left.length; index += 1) {\n if (left[index] === right[index]) {\n continue;\n }\n\n return left[index]! > right[index]! ? 1 : -1;\n }\n\n return 0;\n}\n\nexport function resolveCommandSecrets(\n command: Command<any, any, any, any>,\n env: Record<string, string | undefined> = process.env\n): Record<string, string | undefined> {\n const secrets: Record<string, string | undefined> = {};\n\n for (const [name, secret] of Object.entries(command.secrets)) {\n const value = env[secret.env];\n\n if (value === undefined && secret.optional !== true) {\n const details = secret.description ? `\\n ${secret.description}` : \"\";\n throw new UserError(`Error: Missing required secret ${secret.env}${details}`);\n }\n\n secrets[name] = value;\n }\n\n return secrets;\n}\n\nexport async function assertCommandRequirements(\n command: Command<any, any, any, any>,\n context: GroupCheckContext<any>,\n options: CommandRequirementOptions = {}\n): Promise<void> {\n const requires = command.requires;\n if (requires === undefined) {\n return;\n }\n\n const env = options.env ?? process.env;\n const authEnvVar = options.authEnvVar ?? \"POE_API_KEY\";\n\n if (requires.auth === true && env[authEnvVar] === undefined) {\n throw new UserError(\n `Error: Command \"${command.name}\" requires authentication.\\n Run 'poe-code login' first.`\n );\n }\n\n if (requires.apiVersion !== undefined) {\n const minimumVersion = parseMinimumApiVersion(requires.apiVersion);\n if (minimumVersion === undefined) {\n throw new UserError(\n `Error: Command \"${command.name}\" has invalid apiVersion requirement \"${requires.apiVersion}\". Expected format \">=X.Y.Z\".`\n );\n }\n\n if (options.apiVersion === undefined) {\n throw new UserError(\n `Error: Command \"${command.name}\" requires API version ${requires.apiVersion}, but no runner API version was provided.`\n );\n }\n\n const runnerVersion = parseSimpleSemver(options.apiVersion);\n if (runnerVersion === undefined) {\n throw new UserError(\n `Error: Command \"${command.name}\" requires API version ${requires.apiVersion}, but runner API version \"${options.apiVersion}\" is not valid semver.`\n );\n }\n\n if (compareSemver(runnerVersion, minimumVersion) < 0) {\n throw new UserError(\n `Error: Command \"${command.name}\" requires API version ${requires.apiVersion}, but runner API version is ${options.apiVersion}.`\n );\n }\n }\n\n const checkResult = await requires.check?.(context);\n if (checkResult && !checkResult.ok) {\n throw new UserError(checkResult.message ?? \"Command precondition failed.\");\n }\n}\n\nfunction mergeSecrets(parent: SecretDeclarations, child: SecretDeclarations): SecretDeclarations {\n return cloneSecrets({\n ...parent,\n ...child,\n });\n}\n\nfunction resolveCommandScope(ownScope: Scope[] | undefined, inheritedScope: Scope[] | undefined): Scope[] {\n return cloneScope(ownScope ?? inheritedScope) ?? [\"cli\", \"sdk\"];\n}\n\nfunction resolveGroupScope(ownScope: Scope[] | undefined, inheritedScope: Scope[] | undefined): Scope[] | undefined {\n return cloneScope(ownScope ?? inheritedScope);\n}\n\nfunction createBaseCommand<\n TServices extends object,\n TParamsSchema extends ObjectSchema<any>,\n TSecrets extends SecretDeclarations | undefined,\n TResult,\n>(\n config: CommandConfig<TServices, TParamsSchema, TSecrets, TResult>\n): Command<TServices, TParamsSchema, TSecrets, TResult> {\n const command: Command<TServices, TParamsSchema, TSecrets, TResult> = {\n kind: \"command\",\n name: config.name,\n description: config.description,\n aliases: [...(config.aliases ?? [])],\n positional: [...(config.positional ?? [])],\n params: config.params,\n secrets: cloneSecrets(config.secrets),\n scope: resolveCommandScope(config.scope, undefined),\n confirm: config.confirm ?? false,\n requires: cloneRequires(config.requires),\n handler: config.handler,\n render: config.render,\n };\n\n Object.defineProperty(command, commandConfigSymbol, {\n value: {\n scope: cloneScope(config.scope),\n secrets: cloneSecrets(config.secrets),\n requires: cloneRequires(config.requires),\n sourcePath: inferCommandSourcePath(),\n } satisfies InternalCommandConfig,\n });\n\n return command;\n}\n\nfunction createBaseGroup<TServices extends object>(config: GroupConfig<TServices>): Group<TServices> {\n const group: Group<TServices> = {\n kind: \"group\",\n name: config.name,\n description: config.description,\n aliases: [...(config.aliases ?? [])],\n scope: resolveGroupScope(config.scope, undefined),\n secrets: cloneSecrets(config.secrets),\n requires: cloneRequires(config.requires),\n children: [],\n default: undefined,\n };\n\n Object.defineProperty(group, groupConfigSymbol, {\n value: {\n scope: cloneScope(config.scope),\n secrets: cloneSecrets(config.secrets),\n requires: cloneRequires(config.requires),\n children: [...config.children],\n default: config.default,\n } satisfies InternalGroupConfig<TServices>,\n });\n\n return group;\n}\n\nfunction getInternalCommandConfig(command: Command<any, any, any, any>): InternalCommandConfig {\n return (command as Command<any, any, any, any> & { [commandConfigSymbol]: InternalCommandConfig })[\n commandConfigSymbol\n ];\n}\n\nfunction getInternalGroupConfig<TServices extends object>(group: Group<TServices>): InternalGroupConfig<TServices> {\n return (group as Group<TServices> & { [groupConfigSymbol]: InternalGroupConfig<TServices> })[\n groupConfigSymbol\n ];\n}\n\nfunction materializeCommand<\n TServices extends object,\n TParamsSchema extends ObjectSchema<any>,\n TSecrets extends SecretDeclarations | undefined,\n TResult,\n>(\n command: Command<TServices, TParamsSchema, TSecrets, TResult>,\n inherited: InheritedMetadata\n): Command<TServices, TParamsSchema, TSecrets, TResult> {\n const internal = getInternalCommandConfig(command);\n\n const materialized: Command<TServices, TParamsSchema, TSecrets, TResult> = {\n kind: \"command\",\n name: command.name,\n description: command.description,\n aliases: [...command.aliases],\n positional: [...command.positional],\n params: command.params,\n secrets: mergeSecrets(inherited.secrets, internal.secrets),\n scope: resolveCommandScope(internal.scope, inherited.scope),\n confirm: command.confirm,\n requires: mergeRequires(inherited.requires, internal.requires),\n handler: command.handler,\n render: command.render,\n };\n\n Object.defineProperty(materialized, commandConfigSymbol, {\n value: {\n scope: cloneScope(internal.scope),\n secrets: cloneSecrets(internal.secrets),\n requires: cloneRequires(internal.requires),\n sourcePath: internal.sourcePath,\n } satisfies InternalCommandConfig,\n });\n\n Object.defineProperty(materialized, commandSourcePathSymbol, {\n value: internal.sourcePath,\n });\n\n return materialized;\n}\n\nfunction materializeGroup<TServices extends object>(\n group: Group<TServices>,\n inherited: InheritedMetadata\n): Group<TServices> {\n const internal = getInternalGroupConfig(group);\n const scope = resolveGroupScope(internal.scope, inherited.scope);\n const secrets = mergeSecrets(inherited.secrets, internal.secrets);\n const requires = mergeRequires(inherited.requires, internal.requires);\n const materializedChildren = internal.children.map((child) =>\n materializeNode(child, {\n scope,\n secrets,\n requires,\n })\n );\n\n let defaultChild: Command<TServices, any, any, any> | undefined;\n\n if (internal.default !== undefined) {\n const defaultIndex = internal.children.indexOf(internal.default);\n\n if (defaultIndex === -1) {\n throw new UserError(`Default command \"${internal.default.name}\" must be listed in children.`);\n }\n\n const resolvedDefault = materializedChildren[defaultIndex];\n if (resolvedDefault?.kind !== \"command\") {\n throw new UserError(`Default child \"${internal.default.name}\" must be a command.`);\n }\n\n defaultChild = resolvedDefault;\n }\n\n const materialized: Group<TServices> = {\n kind: \"group\",\n name: group.name,\n description: group.description,\n aliases: [...group.aliases],\n scope,\n secrets,\n requires,\n children: materializedChildren,\n default: defaultChild,\n };\n\n Object.defineProperty(materialized, groupConfigSymbol, {\n value: {\n scope: cloneScope(internal.scope),\n secrets: cloneSecrets(internal.secrets),\n requires: cloneRequires(internal.requires),\n children: [...internal.children],\n default: internal.default,\n } satisfies InternalGroupConfig<TServices>,\n });\n\n return materialized;\n}\n\nfunction materializeNode<TServices extends object>(\n node: CommandNode<TServices>,\n inherited: InheritedMetadata\n): CommandNode<TServices> {\n if (node.kind === \"command\") {\n return materializeCommand(node, inherited);\n }\n\n return materializeGroup(node, inherited);\n}\n\nexport function defineCommand<\n TServices extends object = EmptyServices,\n TName extends string = string,\n TParamsSchema extends ObjectSchema<any> = AnyObjectSchema,\n TSecrets extends SecretDeclarations | undefined = undefined,\n TResult = unknown,\n TOwnScope extends ScopeInput = undefined,\n>(\n config: Omit<CommandConfig<TServices, TParamsSchema, TSecrets, TResult>, \"name\" | \"scope\"> & {\n name: TName;\n scope?: TOwnScope;\n }\n): Command<TServices, TParamsSchema, TSecrets, TResult> &\n TypedCommandMetadata<TName, TParamsSchema, TResult, TOwnScope> {\n return materializeCommand(createBaseCommand(config as CommandConfig<TServices, TParamsSchema, TSecrets, TResult>), {\n scope: undefined,\n secrets: {},\n requires: undefined,\n }) as Command<TServices, TParamsSchema, TSecrets, TResult> &\n TypedCommandMetadata<TName, TParamsSchema, TResult, TOwnScope>;\n}\n\nexport function defineGroup<\n TServices extends object = EmptyServices,\n TName extends string = string,\n TChildren extends readonly unknown[] = readonly CommandNode<TServices>[],\n TOwnScope extends ScopeInput = undefined,\n>(\n config: Omit<GroupConfig<TServices>, \"name\" | \"children\" | \"scope\"> & {\n name: TName;\n children: TChildren & readonly CommandNode<TServices>[];\n scope?: TOwnScope;\n }\n): Group<TServices> & TypedGroupMetadata<TServices, TName, TChildren, TOwnScope> {\n return materializeGroup(createBaseGroup(config as unknown as GroupConfig<TServices>), {\n scope: undefined,\n secrets: {},\n requires: undefined,\n }) as Group<TServices> & TypedGroupMetadata<TServices, TName, TChildren, TOwnScope>;\n}\n\nexport function getCommandSourcePath(command: Command<any, any, any, any>): string | undefined {\n return (command as Command<any, any, any, any> & { [commandSourcePathSymbol]?: string })[\n commandSourcePathSymbol\n ];\n}\n\nexport { S, toJsonSchema } from \"@poe-code/cmdkit-schema\";\nexport type { AnySchema, ArraySchema, BooleanSchema, EnumSchema, JsonSchema, NumberSchema, ObjectSchema, OptionalSchema, Static, StringSchema } from \"@poe-code/cmdkit-schema\";\n", "import type { NumberSchema } from \"@poe-code/cmdkit-schema\";\n\nexport function isValidNumberSchemaValue(\n value: unknown,\n schema: NumberSchema\n): value is number {\n return (\n typeof value === \"number\" &&\n Number.isFinite(value) &&\n (schema.jsonType !== \"integer\" || Number.isInteger(value))\n );\n}\n\nexport function getExpectedNumberDescription(schema: NumberSchema): string {\n return schema.jsonType === \"integer\" ? \"an integer\" : \"a number\";\n}\n", "import type { AnySchema } from \"@poe-code/cmdkit-schema\";\n\ntype SchemaScope = \"cli\" | \"mcp\" | \"sdk\";\n\nexport function filterSchemaForScope(schema: AnySchema, scope: SchemaScope): AnySchema | undefined {\n if (schema.scope !== undefined && !schema.scope.includes(scope)) {\n return undefined;\n }\n\n switch (schema.kind) {\n case \"optional\": {\n const inner = filterSchemaForScope(schema.inner, scope);\n\n if (inner === undefined) {\n return undefined;\n }\n\n if (inner.requiredScopes?.includes(scope)) {\n return inner;\n }\n\n return { ...schema, inner };\n }\n\n case \"array\": {\n const item = filterSchemaForScope(schema.item, scope);\n return item === undefined ? undefined : { ...schema, item };\n }\n\n case \"string\":\n case \"number\":\n case \"boolean\":\n case \"enum\":\n return schema;\n\n case \"object\":\n return {\n ...schema,\n shape: Object.fromEntries(\n Object.entries(schema.shape).flatMap(([key, childSchema]) => {\n const filtered = filterSchemaForScope(childSchema, scope);\n return filtered === undefined ? [] : [[key, filtered]];\n })\n ),\n };\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -3,6 +3,7 @@ const ignoredStringSchema = S.String({ description: "Name", default: "guest" });
3
3
  const ignoredNumberSchema = S.Number({ description: "Count", default: 1 });
4
4
  const ignoredBooleanSchema = S.Boolean({ description: "Enabled", default: false });
5
5
  const ignoredEnumSchema = S.Enum(["admin", "user"], { default: "admin" });
6
+ const ignoredIntegerEnumSchema = S.Enum([1, 2], { jsonType: "integer" });
6
7
  const ignoredArraySchema = S.Array(S.String(), { default: ["a"] });
7
8
  const ignoredObjectSchema = S.Object({
8
9
  name: S.String(),
@@ -1,8 +1,28 @@
1
- type JsonSchemaType = "string" | "number" | "boolean" | "array" | "object";
1
+ type JsonSchemaType = "string" | "number" | "integer" | "boolean" | "array" | "object";
2
2
  type SchemaKind = "string" | "number" | "boolean" | "enum" | "array" | "object" | "optional";
3
3
  type EnumValue = string | number | boolean;
4
+ type JsonSchemaEnumValue = EnumValue | null;
5
+ type NumberJsonType = "number" | "integer";
4
6
  type NonEmptyReadonlyArray<T> = readonly [T, ...T[]];
5
7
  type ObjectShape = Record<string, AnySchema>;
8
+ type SchemaScope = "cli" | "mcp" | "sdk";
9
+ type StringMetadata = {
10
+ format?: string;
11
+ maxLength?: number;
12
+ minLength?: number;
13
+ pattern?: string;
14
+ };
15
+ type NumberMetadata = {
16
+ maximum?: number;
17
+ minimum?: number;
18
+ };
19
+ type ArrayMetadata = {
20
+ maxItems?: number;
21
+ minItems?: number;
22
+ };
23
+ type ObjectMetadata = {
24
+ additionalProperties?: boolean;
25
+ };
6
26
  type OptionalKeys<TShape extends ObjectShape> = {
7
27
  [TKey in keyof TShape]: TShape[TKey] extends OptionalSchema<any> ? TKey : never;
8
28
  }[keyof TShape];
@@ -16,42 +36,62 @@ type InferObject<TShape extends ObjectShape> = {
16
36
  type SchemaOptions<TDefault> = {
17
37
  description?: string;
18
38
  default?: TDefault;
39
+ nullable?: boolean;
40
+ requiredScopes?: readonly SchemaScope[];
19
41
  short?: string;
42
+ scope?: readonly SchemaScope[];
20
43
  };
21
44
  interface SchemaBase<TKind extends SchemaKind, TStatic> {
22
45
  readonly kind: TKind;
23
46
  readonly description?: string;
24
47
  readonly default?: TStatic;
48
+ readonly nullable?: boolean;
49
+ readonly requiredScopes?: readonly SchemaScope[];
25
50
  readonly short?: string;
51
+ readonly scope?: readonly SchemaScope[];
26
52
  readonly __static?: TStatic;
27
53
  }
28
54
  export interface JsonSchema {
55
+ additionalProperties?: boolean;
29
56
  type?: JsonSchemaType;
30
57
  description?: string;
31
58
  default?: unknown;
32
- enum?: ReadonlyArray<EnumValue>;
59
+ enum?: ReadonlyArray<JsonSchemaEnumValue>;
60
+ format?: string;
33
61
  items?: JsonSchema;
62
+ maxItems?: number;
63
+ maximum?: number;
64
+ maxLength?: number;
65
+ minItems?: number;
66
+ minimum?: number;
67
+ minLength?: number;
68
+ nullable?: boolean;
69
+ pattern?: string;
34
70
  properties?: Record<string, JsonSchema>;
35
71
  required?: string[];
36
72
  }
37
- export type StringSchema = SchemaBase<"string", string>;
38
- export type NumberSchema = SchemaBase<"number", number>;
73
+ export interface StringSchema extends SchemaBase<"string", string>, StringMetadata {
74
+ }
75
+ export interface NumberSchema extends SchemaBase<"number", number>, NumberMetadata {
76
+ readonly jsonType?: NumberJsonType;
77
+ }
39
78
  export type BooleanSchema = SchemaBase<"boolean", boolean>;
40
79
  export interface EnumSchema<TValues extends NonEmptyReadonlyArray<EnumValue>> extends SchemaBase<"enum", TValues[number]> {
41
80
  readonly values: TValues;
81
+ readonly jsonType?: "integer";
42
82
  readonly labels?: Partial<Record<string, string>>;
43
- readonly loadOptions?: () => Array<{
83
+ readonly loadOptions?: (() => Array<{
44
84
  label: string;
45
85
  value: string;
46
- }> | Promise<Array<{
86
+ }>) | (() => Promise<Array<{
47
87
  label: string;
48
88
  value: string;
49
- }>>;
89
+ }>>);
50
90
  }
51
- export interface ArraySchema<TItem extends AnySchema> extends SchemaBase<"array", Array<Static<TItem>>> {
91
+ export interface ArraySchema<TItem extends AnySchema> extends SchemaBase<"array", Array<Static<TItem>>>, ArrayMetadata {
52
92
  readonly item: TItem;
53
93
  }
54
- export interface ObjectSchema<TShape extends ObjectShape> extends SchemaBase<"object", InferObject<TShape>> {
94
+ export interface ObjectSchema<TShape extends ObjectShape> extends SchemaBase<"object", InferObject<TShape>>, ObjectMetadata {
55
95
  readonly shape: TShape;
56
96
  }
57
97
  export interface OptionalSchema<TInner extends AnySchema> extends SchemaBase<"optional", Static<TInner> | undefined> {
@@ -60,21 +100,24 @@ export interface OptionalSchema<TInner extends AnySchema> extends SchemaBase<"op
60
100
  export type AnySchema = StringSchema | NumberSchema | BooleanSchema | EnumSchema<NonEmptyReadonlyArray<EnumValue>> | ArraySchema<AnySchema> | ObjectSchema<ObjectShape> | OptionalSchema<AnySchema>;
61
101
  export type Static<TSchema extends AnySchema> = TSchema extends SchemaBase<any, infer TStatic> ? TStatic : never;
62
102
  export declare const S: {
63
- readonly String: (options?: SchemaOptions<string>) => StringSchema;
64
- readonly Number: (options?: SchemaOptions<number>) => NumberSchema;
103
+ readonly String: (options?: SchemaOptions<string> & StringMetadata) => StringSchema;
104
+ readonly Number: (options?: SchemaOptions<number> & NumberMetadata & {
105
+ jsonType?: NumberJsonType;
106
+ }) => NumberSchema;
65
107
  readonly Boolean: (options?: SchemaOptions<boolean>) => BooleanSchema;
66
108
  readonly Enum: <const TValues extends NonEmptyReadonlyArray<EnumValue>>(values: TValues, options?: SchemaOptions<TValues[number]> & {
109
+ jsonType?: "integer";
67
110
  labels?: Partial<Record<string, string>>;
68
- loadOptions?: () => Array<{
111
+ loadOptions?: (() => Array<{
69
112
  label: string;
70
113
  value: string;
71
- }> | Promise<Array<{
114
+ }>) | (() => Promise<Array<{
72
115
  label: string;
73
116
  value: string;
74
- }>>;
117
+ }>>);
75
118
  }) => EnumSchema<TValues>;
76
- readonly Array: <TItem extends AnySchema>(item: TItem, options?: SchemaOptions<Array<Static<TItem>>>) => ArraySchema<TItem>;
77
- readonly Object: <const TShape extends ObjectShape>(shape: TShape) => ObjectSchema<TShape>;
119
+ readonly Array: <TItem extends AnySchema>(item: TItem, options?: SchemaOptions<Array<Static<TItem>>> & ArrayMetadata) => ArraySchema<TItem>;
120
+ readonly Object: <const TShape extends ObjectShape>(shape: TShape, options?: SchemaOptions<InferObject<TShape>> & ObjectMetadata) => ObjectSchema<TShape>;
78
121
  readonly Optional: <TInner extends AnySchema>(inner: TInner) => OptionalSchema<TInner>;
79
122
  };
80
123
  export declare function toJsonSchema(schema: AnySchema): JsonSchema;
@@ -5,8 +5,50 @@ function withMetadata(schema, jsonSchema) {
5
5
  if (schema.default !== undefined) {
6
6
  jsonSchema.default = schema.default;
7
7
  }
8
+ if (schema.nullable === true) {
9
+ jsonSchema.nullable = true;
10
+ }
8
11
  return jsonSchema;
9
12
  }
13
+ function withStringMetadata(schema, jsonSchema) {
14
+ if (schema.minLength !== undefined) {
15
+ jsonSchema.minLength = schema.minLength;
16
+ }
17
+ if (schema.maxLength !== undefined) {
18
+ jsonSchema.maxLength = schema.maxLength;
19
+ }
20
+ if (schema.pattern !== undefined) {
21
+ jsonSchema.pattern = schema.pattern;
22
+ }
23
+ if (schema.format !== undefined) {
24
+ jsonSchema.format = schema.format;
25
+ }
26
+ return withMetadata(schema, jsonSchema);
27
+ }
28
+ function withNumberMetadata(schema, jsonSchema) {
29
+ if (schema.minimum !== undefined) {
30
+ jsonSchema.minimum = schema.minimum;
31
+ }
32
+ if (schema.maximum !== undefined) {
33
+ jsonSchema.maximum = schema.maximum;
34
+ }
35
+ return withMetadata(schema, jsonSchema);
36
+ }
37
+ function withArrayMetadata(schema, jsonSchema) {
38
+ if (schema.minItems !== undefined) {
39
+ jsonSchema.minItems = schema.minItems;
40
+ }
41
+ if (schema.maxItems !== undefined) {
42
+ jsonSchema.maxItems = schema.maxItems;
43
+ }
44
+ return withMetadata(schema, jsonSchema);
45
+ }
46
+ function withObjectMetadata(schema, jsonSchema) {
47
+ if (schema.additionalProperties !== undefined) {
48
+ jsonSchema.additionalProperties = schema.additionalProperties;
49
+ }
50
+ return withMetadata(schema, jsonSchema);
51
+ }
10
52
  function getEnumJsonType(values) {
11
53
  const [firstValue] = values;
12
54
  if (firstValue === undefined) {
@@ -74,10 +116,11 @@ export const S = {
74
116
  ...options,
75
117
  };
76
118
  },
77
- Object(shape) {
119
+ Object(shape, options = {}) {
78
120
  return {
79
121
  kind: "object",
80
122
  shape,
123
+ ...options,
81
124
  };
82
125
  },
83
126
  Optional(inner) {
@@ -91,23 +134,25 @@ export function toJsonSchema(schema) {
91
134
  const unwrappedSchema = unwrapOptional(schema);
92
135
  switch (unwrappedSchema.kind) {
93
136
  case "string":
94
- return withMetadata(unwrappedSchema, { type: "string" });
137
+ return withStringMetadata(unwrappedSchema, { type: "string" });
95
138
  case "number":
96
- return withMetadata(unwrappedSchema, { type: "number" });
139
+ return withNumberMetadata(unwrappedSchema, { type: unwrappedSchema.jsonType ?? "number" });
97
140
  case "boolean":
98
141
  return withMetadata(unwrappedSchema, { type: "boolean" });
99
142
  case "enum": {
100
143
  const jsonSchema = {
101
- enum: [...unwrappedSchema.values],
144
+ enum: unwrappedSchema.nullable === true
145
+ ? [...unwrappedSchema.values, null]
146
+ : [...unwrappedSchema.values],
102
147
  };
103
- const enumType = getEnumJsonType(unwrappedSchema.values);
148
+ const enumType = unwrappedSchema.jsonType ?? getEnumJsonType(unwrappedSchema.values);
104
149
  if (enumType !== undefined) {
105
150
  jsonSchema.type = enumType;
106
151
  }
107
152
  return withMetadata(unwrappedSchema, jsonSchema);
108
153
  }
109
154
  case "array":
110
- return withMetadata(unwrappedSchema, {
155
+ return withArrayMetadata(unwrappedSchema, {
111
156
  type: "array",
112
157
  items: toJsonSchema(unwrappedSchema.item),
113
158
  });
@@ -120,11 +165,11 @@ export function toJsonSchema(schema) {
120
165
  required.push(key);
121
166
  }
122
167
  }
123
- return {
168
+ return withObjectMetadata(unwrappedSchema, {
124
169
  type: "object",
125
170
  properties,
126
171
  required,
127
- };
172
+ });
128
173
  }
129
174
  }
130
175
  }
@@ -16,10 +16,9 @@ export function defaultHints() {
16
16
  return [
17
17
  { key: "q", label: "Quit" },
18
18
  { key: "e", label: "Edit" },
19
+ { key: "l", label: "Log" },
19
20
  { key: "p", label: "Pause" },
20
- { key: "r", label: "Retry" },
21
- { key: "↑↓", label: "Scroll" },
22
- { key: "F", label: "Follow" }
21
+ { key: "r", label: "Retry" }
23
22
  ];
24
23
  }
25
24
  function hintsToCells(hints) {
@@ -1,11 +1,6 @@
1
1
  import { type StyledSegment } from "../ansi.js";
2
2
  import { ScreenBuffer } from "../buffer.js";
3
3
  import type { CellStyle, OutputItem, Rect } from "../types.js";
4
- export type OutputPaneState = {
5
- items: OutputItem[];
6
- scrollOffset: number;
7
- autoFollow: boolean;
8
- };
9
4
  export type VisualLine = {
10
5
  text: string;
11
6
  style: CellStyle;
@@ -13,9 +8,5 @@ export type VisualLine = {
13
8
  prefixStyle: CellStyle;
14
9
  segments?: StyledSegment[];
15
10
  };
16
- export declare function renderOutputPane(buffer: ScreenBuffer, rect: Rect, state: OutputPaneState): void;
11
+ export declare function renderOutputPane(buffer: ScreenBuffer, rect: Rect, items: OutputItem[]): void;
17
12
  export declare function computeVisualLines(items: OutputItem[], width: number): VisualLine[];
18
- export declare function scrollUp(state: OutputPaneState, lines: number): OutputPaneState;
19
- export declare function scrollDown(state: OutputPaneState, lines: number, totalVisualLines: number): OutputPaneState;
20
- export declare function scrollToTop(state: OutputPaneState): OutputPaneState;
21
- export declare function scrollToBottom(state: OutputPaneState, totalVisualLines: number, paneHeight: number): OutputPaneState;