@runcofactor/cli 0.10.0

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 (150) hide show
  1. package/README.md +125 -0
  2. package/dist/api-catalog-GFGCLVS4.js +401 -0
  3. package/dist/api-catalog-GFGCLVS4.js.map +1 -0
  4. package/dist/attachment-SJC7D7FY.js +276 -0
  5. package/dist/attachment-SJC7D7FY.js.map +1 -0
  6. package/dist/auth-EN6NQCJY.js +31 -0
  7. package/dist/auth-EN6NQCJY.js.map +1 -0
  8. package/dist/bin.js +7 -0
  9. package/dist/bin.js.map +1 -0
  10. package/dist/chunk-3CZU7XCS.js +272 -0
  11. package/dist/chunk-3CZU7XCS.js.map +1 -0
  12. package/dist/chunk-4NRDONSC.js +1048 -0
  13. package/dist/chunk-4NRDONSC.js.map +1 -0
  14. package/dist/chunk-4PNOV7OV.js +51980 -0
  15. package/dist/chunk-4PNOV7OV.js.map +1 -0
  16. package/dist/chunk-52IO7ACJ.js +2941 -0
  17. package/dist/chunk-52IO7ACJ.js.map +1 -0
  18. package/dist/chunk-6LEZCKKV.js +663 -0
  19. package/dist/chunk-6LEZCKKV.js.map +1 -0
  20. package/dist/chunk-A4OFTUVV.js +170 -0
  21. package/dist/chunk-A4OFTUVV.js.map +1 -0
  22. package/dist/chunk-B2VISN2V.js +2459 -0
  23. package/dist/chunk-B2VISN2V.js.map +1 -0
  24. package/dist/chunk-CLAWT7BJ.js +271 -0
  25. package/dist/chunk-CLAWT7BJ.js.map +1 -0
  26. package/dist/chunk-GKY2KXO5.js +281 -0
  27. package/dist/chunk-GKY2KXO5.js.map +1 -0
  28. package/dist/chunk-I4QLI3JO.js +413 -0
  29. package/dist/chunk-I4QLI3JO.js.map +1 -0
  30. package/dist/chunk-IMPZAX6L.js +180 -0
  31. package/dist/chunk-IMPZAX6L.js.map +1 -0
  32. package/dist/chunk-J6SH7GQT.js +241 -0
  33. package/dist/chunk-J6SH7GQT.js.map +1 -0
  34. package/dist/chunk-JDBCZ3Z2.js +298 -0
  35. package/dist/chunk-JDBCZ3Z2.js.map +1 -0
  36. package/dist/chunk-JICSYFRJ.js +46 -0
  37. package/dist/chunk-JICSYFRJ.js.map +1 -0
  38. package/dist/chunk-JWHYXEA2.js +32 -0
  39. package/dist/chunk-JWHYXEA2.js.map +1 -0
  40. package/dist/chunk-N7HFALX3.js +88 -0
  41. package/dist/chunk-N7HFALX3.js.map +1 -0
  42. package/dist/chunk-Q4BO4Z5V.js +178 -0
  43. package/dist/chunk-Q4BO4Z5V.js.map +1 -0
  44. package/dist/chunk-QFDOWABX.js +195 -0
  45. package/dist/chunk-QFDOWABX.js.map +1 -0
  46. package/dist/chunk-SJJW77WN.js +605 -0
  47. package/dist/chunk-SJJW77WN.js.map +1 -0
  48. package/dist/chunk-VKVL7WBN.js +50 -0
  49. package/dist/chunk-VKVL7WBN.js.map +1 -0
  50. package/dist/chunk-WOHL4FTB.js +353 -0
  51. package/dist/chunk-WOHL4FTB.js.map +1 -0
  52. package/dist/chunk-XQXVG7RA.js +426 -0
  53. package/dist/chunk-XQXVG7RA.js.map +1 -0
  54. package/dist/chunk-ZD3KHESI.js +94 -0
  55. package/dist/chunk-ZD3KHESI.js.map +1 -0
  56. package/dist/credential-COLTBV6D.js +450 -0
  57. package/dist/credential-COLTBV6D.js.map +1 -0
  58. package/dist/credential-template-EEPYFG7R.js +291 -0
  59. package/dist/credential-template-EEPYFG7R.js.map +1 -0
  60. package/dist/debug-workflow-KOVH5GOP.js +259 -0
  61. package/dist/debug-workflow-KOVH5GOP.js.map +1 -0
  62. package/dist/dist-44PZR7BQ.js +423 -0
  63. package/dist/dist-44PZR7BQ.js.map +1 -0
  64. package/dist/docs-3SSORHB5.js +366 -0
  65. package/dist/docs-3SSORHB5.js.map +1 -0
  66. package/dist/doctor-OTSIWV6G.js +132 -0
  67. package/dist/doctor-OTSIWV6G.js.map +1 -0
  68. package/dist/feature-flag-T2LRZME3.js +283 -0
  69. package/dist/feature-flag-T2LRZME3.js.map +1 -0
  70. package/dist/file-type-S3UUBVCT.js +4205 -0
  71. package/dist/file-type-S3UUBVCT.js.map +1 -0
  72. package/dist/index.d.ts +3 -0
  73. package/dist/index.js +982 -0
  74. package/dist/index.js.map +1 -0
  75. package/dist/init-TGWRECT2.js +208 -0
  76. package/dist/init-TGWRECT2.js.map +1 -0
  77. package/dist/install-DXSNWZKO.js +295 -0
  78. package/dist/install-DXSNWZKO.js.map +1 -0
  79. package/dist/issues-XIZOPX6T.js +564 -0
  80. package/dist/issues-XIZOPX6T.js.map +1 -0
  81. package/dist/knobs-NBINZIUB.js +295 -0
  82. package/dist/knobs-NBINZIUB.js.map +1 -0
  83. package/dist/list-3TDHK637.js +59 -0
  84. package/dist/list-3TDHK637.js.map +1 -0
  85. package/dist/local-HICVD6PU.js +100 -0
  86. package/dist/local-HICVD6PU.js.map +1 -0
  87. package/dist/login-UOIUXVUK.js +315 -0
  88. package/dist/login-UOIUXVUK.js.map +1 -0
  89. package/dist/mcp-54IJEOUA.js +1956 -0
  90. package/dist/mcp-54IJEOUA.js.map +1 -0
  91. package/dist/pdf-extract-ABWV3L5X.js +13 -0
  92. package/dist/pdf-extract-ABWV3L5X.js.map +1 -0
  93. package/dist/pdfjs-DQ2YA5S3.js +41561 -0
  94. package/dist/pdfjs-DQ2YA5S3.js.map +1 -0
  95. package/dist/property-UXLOLPTD.js +701 -0
  96. package/dist/property-UXLOLPTD.js.map +1 -0
  97. package/dist/property-skill-guide.md +189 -0
  98. package/dist/psql-BYUUNLGG.js +115 -0
  99. package/dist/psql-BYUUNLGG.js.map +1 -0
  100. package/dist/record-4TR2UIIS.js +233 -0
  101. package/dist/record-4TR2UIIS.js.map +1 -0
  102. package/dist/redis-35VBUYW7.js +116 -0
  103. package/dist/redis-35VBUYW7.js.map +1 -0
  104. package/dist/release-OOLTUBUT.js +354 -0
  105. package/dist/release-OOLTUBUT.js.map +1 -0
  106. package/dist/sandbox-XGSUU6G7.js +2046 -0
  107. package/dist/sandbox-XGSUU6G7.js.map +1 -0
  108. package/dist/scenarios-GWLJEGHA.js +280 -0
  109. package/dist/scenarios-GWLJEGHA.js.map +1 -0
  110. package/dist/session-MYFNZPRP.js +2414 -0
  111. package/dist/session-MYFNZPRP.js.map +1 -0
  112. package/dist/skill-KM34LDMO.js +1839 -0
  113. package/dist/skill-KM34LDMO.js.map +1 -0
  114. package/dist/skills/debug-run/SKILL.md +262 -0
  115. package/dist/skills/debug-run/history/1.0.0.md +244 -0
  116. package/dist/skills/debug-run/history/1.0.1.md +245 -0
  117. package/dist/skills/debug-run/history/1.0.2.md +254 -0
  118. package/dist/skills/debug-run/history/1.1.0.md +262 -0
  119. package/dist/skills/debug-run/version.json +3 -0
  120. package/dist/spec-RA3CFEKG.js +951 -0
  121. package/dist/spec-RA3CFEKG.js.map +1 -0
  122. package/dist/src-LB4HBTJQ.js +1516 -0
  123. package/dist/src-LB4HBTJQ.js.map +1 -0
  124. package/dist/src-N3TPKGTY.js +244 -0
  125. package/dist/src-N3TPKGTY.js.map +1 -0
  126. package/dist/src-UVDX5UP6.js +17 -0
  127. package/dist/src-UVDX5UP6.js.map +1 -0
  128. package/dist/start-PSEQSQA3.js +151 -0
  129. package/dist/start-PSEQSQA3.js.map +1 -0
  130. package/dist/tag-YY6YAABQ.js +22 -0
  131. package/dist/tag-YY6YAABQ.js.map +1 -0
  132. package/dist/task-IQC3YR5K.js +922 -0
  133. package/dist/task-IQC3YR5K.js.map +1 -0
  134. package/dist/test-suite-DZNJFXDW.js +394 -0
  135. package/dist/test-suite-DZNJFXDW.js.map +1 -0
  136. package/dist/trace-HXIW7U2D.js +14 -0
  137. package/dist/trace-HXIW7U2D.js.map +1 -0
  138. package/dist/triage-ORG45R5W.js +16 -0
  139. package/dist/triage-ORG45R5W.js.map +1 -0
  140. package/dist/upgrade-L2VYMP2V.js +61 -0
  141. package/dist/upgrade-L2VYMP2V.js.map +1 -0
  142. package/dist/workflow-XYFH5LTP.js +3708 -0
  143. package/dist/workflow-XYFH5LTP.js.map +1 -0
  144. package/dist/workflow-cache-NQJQFWMV.js +253 -0
  145. package/dist/workflow-cache-NQJQFWMV.js.map +1 -0
  146. package/dist/workflow-debug-BGD4UIXU.js +927 -0
  147. package/dist/workflow-debug-BGD4UIXU.js.map +1 -0
  148. package/dist/workflow-proposals-MTUDX46O.js +382 -0
  149. package/dist/workflow-proposals-MTUDX46O.js.map +1 -0
  150. package/package.json +61 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/property.ts","../src/property-skill.ts"],"sourcesContent":["/**\n * CLI Property Management\n *\n * List properties and their linked GitHub repos.\n */\n\nimport process from 'node:process';\nimport { resolveConfig, hasFlag, getArgValue } from './auth.js';\nimport { fetchProperties, apiRequest, getApplicationArg } from './cli-helpers.js';\nimport { runPropertySkill } from './property-skill.js';\n\nfunction pad(s: string, n: number): string {\n return s.padEnd(n);\n}\n\nfunction printHelp(): void {\n console.log(\n [\n 'canary application: Manage applications (alias: canary property)',\n '',\n 'Sub-commands:',\n ' list List all applications',\n ' create [options] Create a new application',\n ' repo link [options] Link a GitHub repo to an application',\n ' repo update [options] Update an existing repo link',\n ' repo unlink [options] Unlink a GitHub repo from an application',\n ' skill <action> [options] Manage the application\\'s app skill (run `canary application skill help` for details)',\n '',\n 'Create options:',\n ' --name <name> Application name (required)',\n ' --base-url <url> Application base URL (required)',\n ' --description <text> Optional description',\n ' --agent-context <text> Optional agent context (max 8000 chars)',\n ' --env-var <NAME[:sensitive]> Declare a per-environment variable (repeatable); values set per-environment, injected as $var.ENV.<NAME>',\n '',\n 'Repo link/update/unlink options:',\n ' --application <app_xxx|uuid> Application ID (required; alias: --property)',\n ' --repo <owner/name> Repo full name (required for link/unlink)',\n ' --repo-id <uuid> Repo link UUID (required for update)',\n ' --role <frontend|backend|...> Conventional role (free-form)',\n ' --root-dir <path> Monorepo subdirectory hint',\n ' --agent-hint <text> Free-form hint for the planner agent',\n '',\n 'Common options:',\n ' --json Output as JSON',\n ].join('\\n')\n );\n}\n\ntype GitHubRepo = {\n id: string;\n repoFullName: string;\n repoName: string;\n defaultBranch: string;\n rootDir: string | null;\n role: string | null;\n};\n\nasync function handleList(argv: string[], apiUrl: string, token: string): Promise<void> {\n const json = hasFlag(argv, '--json');\n const properties = await fetchProperties(apiUrl, token);\n\n if (json) {\n console.log(JSON.stringify(properties, null, 2));\n return;\n }\n\n if (properties.length === 0) {\n console.log('No applications found.');\n return;\n }\n\n console.log(`${pad('Name', 30)} ${pad('Base URL', 40)} ID`);\n for (const p of properties) {\n console.log(`${pad(p.name, 30)} ${pad(p.baseUrl, 40)} ${p.id}`);\n }\n\n // Show linked repos for each property\n console.log('');\n for (const p of properties) {\n const reposRes = await apiRequest<{ ok: boolean; items: GitHubRepo[] }>(\n apiUrl, token, 'GET', `/org/properties/${p.id}/github-repos`\n );\n const repos = reposRes.ok ? (reposRes.items ?? []) : [];\n if (repos.length > 0) {\n console.log(`${p.name} repos:`);\n for (const r of repos) {\n const dir = r.rootDir && r.rootDir !== '/' ? ` (${r.rootDir})` : '';\n const role = r.role ? ` [${r.role}]` : '';\n console.log(` ${r.repoFullName}:${r.defaultBranch}${role}${dir}`);\n }\n }\n }\n}\n\n/**\n * Parse repeatable `--env-var NAME[:sensitive]` flags into env-var definitions.\n * Examples: `--env-var API_URL`, `--env-var API_TOKEN:sensitive`.\n */\nfunction parseEnvVarDefinitions(\n argv: string[]\n): Array<{ name: string; sensitive?: boolean }> {\n const defs: Array<{ name: string; sensitive?: boolean }> = [];\n for (let i = 0; i < argv.length; i++) {\n if (argv[i] !== '--env-var') continue;\n const raw = argv[i + 1];\n if (!raw || raw.startsWith('-')) continue;\n const [name, modifier] = raw.split(':');\n if (!name) continue;\n // Accept `NAME` or `NAME:sensitive`; ignore-with-no-effect any other suffix.\n defs.push({ name, ...(modifier === 'sensitive' ? { sensitive: true } : {}) });\n }\n return defs;\n}\n\nasync function handleCreate(argv: string[], apiUrl: string, token: string): Promise<void> {\n const json = hasFlag(argv, '--json');\n const name = getArgValue(argv, '--name');\n const baseUrl = getArgValue(argv, '--base-url');\n const description = getArgValue(argv, '--description');\n const agentContext = getArgValue(argv, '--agent-context');\n const envVarDefinitions = parseEnvVarDefinitions(argv);\n\n if (!name || !baseUrl) {\n console.error('Error: --name and --base-url are required.');\n console.error('Usage: canary application create --name <name> --base-url <url>');\n process.exit(1);\n }\n\n const body: Record<string, unknown> = { name, baseUrl };\n if (description !== undefined) body.description = description;\n if (agentContext !== undefined) body.agentContext = agentContext;\n if (envVarDefinitions.length > 0) body.envVarDefinitions = envVarDefinitions;\n\n const result = await apiRequest<{ ok: boolean; id?: string; error?: string }>(\n apiUrl,\n token,\n 'POST',\n '/org/properties',\n body\n );\n\n if (!result.ok) {\n if (json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n console.error(`Error: ${result.error ?? 'Unknown error'}`);\n }\n process.exit(1);\n }\n\n if (json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n console.log(`Created application \"${name}\" (${result.id})`);\n}\n\nasync function handleRepoLink(argv: string[], apiUrl: string, token: string): Promise<void> {\n const json = hasFlag(argv, '--json');\n const propertyId = getApplicationArg(argv);\n const repo = getArgValue(argv, '--repo');\n const role = getArgValue(argv, '--role');\n const rootDir = getArgValue(argv, '--root-dir');\n const agentHint = getArgValue(argv, '--agent-hint');\n\n if (!propertyId || !repo) {\n console.error('Error: --application and --repo are required.');\n process.exit(1);\n }\n\n const body: Record<string, unknown> = { repoFullName: repo };\n if (role !== undefined) body.role = role;\n if (rootDir !== undefined) body.rootDir = rootDir;\n if (agentHint !== undefined) body.agentHint = agentHint;\n\n const result = await apiRequest<{ ok: boolean; id?: string; error?: string }>(\n apiUrl,\n token,\n 'POST',\n `/org/properties/${propertyId}/github-repos`,\n body\n );\n\n if (!result.ok) {\n if (json) console.log(JSON.stringify(result, null, 2));\n else console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n\n if (json) console.log(JSON.stringify(result, null, 2));\n else console.log(`Linked ${repo} to application ${propertyId} (${result.id})`);\n}\n\nasync function handleRepoUpdate(argv: string[], apiUrl: string, token: string): Promise<void> {\n const json = hasFlag(argv, '--json');\n const propertyId = getApplicationArg(argv);\n const repoId = getArgValue(argv, '--repo-id');\n const role = getArgValue(argv, '--role');\n const rootDir = getArgValue(argv, '--root-dir');\n const agentHint = getArgValue(argv, '--agent-hint');\n\n if (!propertyId || !repoId) {\n console.error('Error: --application and --repo-id are required.');\n process.exit(1);\n }\n\n const body: Record<string, unknown> = {};\n if (role !== undefined) body.role = role;\n if (rootDir !== undefined) body.rootDir = rootDir;\n if (agentHint !== undefined) body.agentHint = agentHint;\n\n const result = await apiRequest<{ ok: boolean; id?: string; error?: string }>(\n apiUrl,\n token,\n 'PATCH',\n `/org/properties/${propertyId}/github-repos/${repoId}`,\n body\n );\n\n if (!result.ok) {\n if (json) console.log(JSON.stringify(result, null, 2));\n else console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n\n if (json) console.log(JSON.stringify(result, null, 2));\n else console.log(`Updated repo link ${repoId}`);\n}\n\nasync function handleRepoUnlink(argv: string[], apiUrl: string, token: string): Promise<void> {\n const json = hasFlag(argv, '--json');\n const propertyId = getApplicationArg(argv);\n const repo = getArgValue(argv, '--repo');\n\n if (!propertyId || !repo) {\n console.error('Error: --application and --repo are required.');\n process.exit(1);\n }\n\n const result = await apiRequest<{ ok: boolean; error?: string }>(\n apiUrl,\n token,\n 'DELETE',\n `/org/properties/${propertyId}/github-repos/${encodeURIComponent(repo)}`\n );\n\n if (!result.ok) {\n if (json) console.log(JSON.stringify(result, null, 2));\n else console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n\n if (json) console.log(JSON.stringify(result, null, 2));\n else console.log(`Unlinked ${repo} from application ${propertyId}`);\n}\n\nasync function handleRepo(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [action, ...rest] = argv;\n switch (action) {\n case 'link':\n await handleRepoLink(rest, apiUrl, token);\n break;\n case 'update':\n await handleRepoUpdate(rest, apiUrl, token);\n break;\n case 'unlink':\n await handleRepoUnlink(rest, apiUrl, token);\n break;\n default:\n console.error(`Unknown repo action: ${action ?? '(none)'}`);\n printHelp();\n process.exit(1);\n }\n}\n\nexport async function runProperty(argv: string[]): Promise<void> {\n const [subCommand, ...rest] = argv;\n\n if (!subCommand || subCommand === 'help' || hasFlag(argv, '--help', '-h')) {\n printHelp();\n return;\n }\n\n // `skill guide` and `skill help` are doc-only; skip auth resolution so\n // unauthenticated agents can discover the methodology before logging in.\n if (subCommand === 'skill') {\n const skillAction = rest[0];\n if (!skillAction || skillAction === 'help' || skillAction === 'guide') {\n await runPropertySkill(rest, '', '');\n return;\n }\n }\n\n const { apiUrl, token } = await resolveConfig(argv);\n\n const globalFlags = new Set(['--env', '--api-url', '--token']);\n const args = rest.filter((arg, i) => {\n if (globalFlags.has(arg)) return false;\n if (i > 0 && globalFlags.has(rest[i - 1])) return false;\n return true;\n });\n\n switch (subCommand) {\n case 'list':\n await handleList(args, apiUrl, token);\n break;\n case 'create':\n await handleCreate(args, apiUrl, token);\n break;\n case 'repo':\n await handleRepo(args, apiUrl, token);\n break;\n case 'skill':\n await runPropertySkill(args, apiUrl, token);\n break;\n default:\n console.error(`Unknown sub-command: ${subCommand}`);\n printHelp();\n process.exit(1);\n }\n}\n","/**\n * CLI: `canary property skill` — manage a property's app skill\n *\n * App skill = the per-property knowledge base injected into the cloud workflow\n * browser agent's system prompt. CLI is a thin client over the existing\n * /org/properties/:id/context endpoints. Source defaults to 'cli' so authored\n * items are distinguishable from browser-bootstrap or human-manual edits.\n */\n\nimport { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport process from 'node:process';\nimport { getArgValue, hasFlag } from './auth.js';\nimport { apiRequest, getApplicationArg } from './cli-helpers.js';\n\nconst HERE = dirname(fileURLToPath(import.meta.url));\nconst GUIDE_PATH = join(HERE, 'property-skill-guide.md');\n\nconst SECTIONS = [\n 'general',\n 'technology',\n 'product',\n 'ui',\n 'tenancy',\n 'auth',\n 'roles_permissions',\n 'navigation',\n 'feature_gating',\n 'environments',\n 'data_lifecycle',\n 'async_realtime',\n 'localization',\n 'feedback_errors',\n 'idiosyncrasies',\n] as const;\ntype Section = (typeof SECTIONS)[number];\n\ntype ContextItem = {\n id: string;\n propertyId: string;\n section: Section;\n itemKey: string;\n itemLabel: string;\n content: string;\n version: number;\n source: 'bootstrap' | 'workflow' | 'manual' | 'cli';\n sourceId: string | null;\n createdBy: string | null;\n createdAt: string;\n};\n\ntype ListResponse = {\n ok: boolean;\n error?: string;\n data?: { items: ContextItem[]; grouped: Record<string, ContextItem[]> };\n};\n\nfunction printSkillHelp(): void {\n console.log(\n [\n 'canary application skill: Manage an application\\'s app skill (per-application knowledge for QA browser agents). Alias: canary property skill. (--property accepted as an alias for --application.)',\n '',\n 'Sub-commands:',\n ' guide Print the full authoring methodology (start here)',\n ' list [--application <id>] [--section S] [--format json|table]',\n ' get --application <id> --section S --key K [--version N] [--format json|md]',\n ' set --application <id> --section S --key K --label L --content @file|\"text\" [--source-id <repo@sha>]',\n ' delete --application <id> --section S --key K',\n ' history --application <id> --section S --key K [--format json|table]',\n ' export --application <id> [--format md|json]',\n ' import --application <id> --file <bundle.json> [--source-id <repo@sha>]',\n '',\n 'New to app skills? Run `canary application skill guide` for the authoring methodology.',\n '',\n 'Sections:',\n ' ' + SECTIONS.join(', '),\n '',\n 'Notes:',\n ' --content @path reads content from a file (preferred for multi-line markdown)',\n ' --content \"text\" literal content string',\n ' Source defaults to \"cli\". Provide --source-id <repo@sha> for provenance.',\n '',\n 'Bundle.json shape for import:',\n ' { \"items\": [ { \"section\": S, \"itemKey\": K, \"itemLabel\": L, \"content\": \"...\" }, ... ] }',\n ].join('\\n')\n );\n}\n\nfunction readContent(value: string): string {\n if (value.startsWith('@')) {\n const path = value.slice(1);\n return readFileSync(path, 'utf8');\n }\n return value;\n}\n\nfunction isSection(s: string | undefined): s is Section {\n return !!s && (SECTIONS as readonly string[]).includes(s);\n}\n\nasync function handleList(argv: string[], apiUrl: string, token: string): Promise<void> {\n const propertyId = getApplicationArg(argv);\n const section = getArgValue(argv, '--section');\n const format = getArgValue(argv, '--format') ?? (hasFlag(argv, '--json') ? 'json' : 'table');\n\n if (!propertyId) {\n console.error('Error: --application is required (alias: --property).');\n process.exit(1);\n }\n\n const result = await apiRequest<ListResponse>(\n apiUrl,\n token,\n 'GET',\n `/org/properties/${propertyId}/context`\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n\n let items = result.data?.items ?? [];\n if (section) items = items.filter((i) => i.section === section);\n\n if (format === 'json') {\n console.log(JSON.stringify(items, null, 2));\n return;\n }\n\n if (items.length === 0) {\n console.log('(no items)');\n return;\n }\n\n const grouped = new Map<string, ContextItem[]>();\n for (const item of items) {\n const arr = grouped.get(item.section) ?? [];\n arr.push(item);\n grouped.set(item.section, arr);\n }\n\n for (const sec of SECTIONS) {\n const arr = grouped.get(sec);\n if (!arr || arr.length === 0) continue;\n console.log(`\\n[${sec}]`);\n for (const item of arr) {\n const provenance = item.source === 'cli' && item.sourceId ? ` (${item.sourceId})` : item.source !== 'cli' ? ` (${item.source})` : '';\n console.log(` ${item.itemKey} — ${item.itemLabel}${provenance}`);\n }\n }\n}\n\nasync function handleGet(argv: string[], apiUrl: string, token: string): Promise<void> {\n const propertyId = getApplicationArg(argv);\n const section = getArgValue(argv, '--section');\n const itemKey = getArgValue(argv, '--key');\n const versionArg = getArgValue(argv, '--version');\n const format = getArgValue(argv, '--format') ?? 'md';\n\n if (!propertyId || !section || !itemKey) {\n console.error('Error: --application, --section, --key are required.');\n process.exit(1);\n }\n if (!isSection(section)) {\n console.error(`Error: invalid section \"${section}\". One of: ${SECTIONS.join(', ')}`);\n process.exit(1);\n }\n\n // Current value comes from list; specific version from history.\n if (versionArg) {\n const v = Number(versionArg);\n const result = await apiRequest<{ ok: boolean; error?: string; data?: ContextItem[] }>(\n apiUrl,\n token,\n 'GET',\n `/org/properties/${propertyId}/context/history?section=${section}&itemKey=${encodeURIComponent(itemKey)}`\n );\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n const item = (result.data ?? []).find((i) => i.version === v);\n if (!item) {\n console.error(`Error: no version ${v} for ${section}/${itemKey}`);\n process.exit(1);\n }\n printItem(item, format);\n return;\n }\n\n const result = await apiRequest<ListResponse>(\n apiUrl,\n token,\n 'GET',\n `/org/properties/${propertyId}/context`\n );\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n const item = (result.data?.items ?? []).find(\n (i) => i.section === section && i.itemKey === itemKey\n );\n if (!item) {\n console.error(`Error: no item ${section}/${itemKey}`);\n process.exit(1);\n }\n printItem(item, format);\n}\n\nfunction printItem(item: ContextItem, format: string): void {\n if (format === 'json') {\n console.log(JSON.stringify(item, null, 2));\n return;\n }\n console.log(`# ${item.itemLabel}`);\n console.log(`section: ${item.section}`);\n console.log(`key: ${item.itemKey}`);\n console.log(`version: ${item.version}`);\n console.log(`source: ${item.source}${item.sourceId ? ` (${item.sourceId})` : ''}`);\n console.log('');\n console.log(item.content);\n}\n\nasync function handleSet(argv: string[], apiUrl: string, token: string): Promise<void> {\n const propertyId = getApplicationArg(argv);\n const section = getArgValue(argv, '--section');\n const itemKey = getArgValue(argv, '--key');\n const itemLabel = getArgValue(argv, '--label');\n const contentArg = getArgValue(argv, '--content');\n const sourceId = getArgValue(argv, '--source-id');\n\n if (!propertyId || !section || !itemKey || !itemLabel || contentArg === undefined) {\n console.error('Error: --application, --section, --key, --label, --content are required.');\n process.exit(1);\n }\n if (!isSection(section)) {\n console.error(`Error: invalid section \"${section}\". One of: ${SECTIONS.join(', ')}`);\n process.exit(1);\n }\n\n const content = readContent(contentArg);\n\n const body: Record<string, unknown> = {\n section,\n itemKey,\n itemLabel,\n content,\n source: 'cli',\n };\n if (sourceId !== undefined) body.sourceId = sourceId;\n\n const result = await apiRequest<{ ok: boolean; error?: string; data?: ContextItem }>(\n apiUrl,\n token,\n 'PUT',\n `/org/properties/${propertyId}/context/items`,\n body\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n\n console.log(`Set [${section}] ${itemKey} (v${result.data?.version ?? '?'})`);\n}\n\nasync function handleDelete(argv: string[], apiUrl: string, token: string): Promise<void> {\n const propertyId = getApplicationArg(argv);\n const section = getArgValue(argv, '--section');\n const itemKey = getArgValue(argv, '--key');\n\n if (!propertyId || !section || !itemKey) {\n console.error('Error: --application, --section, --key are required.');\n process.exit(1);\n }\n if (!isSection(section)) {\n console.error(`Error: invalid section \"${section}\". One of: ${SECTIONS.join(', ')}`);\n process.exit(1);\n }\n\n const result = await apiRequest<{ ok: boolean; error?: string }>(\n apiUrl,\n token,\n 'DELETE',\n `/org/properties/${propertyId}/context/items`,\n { section, itemKey }\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n\n console.log(`Deleted [${section}] ${itemKey}`);\n}\n\nasync function handleHistory(argv: string[], apiUrl: string, token: string): Promise<void> {\n const propertyId = getApplicationArg(argv);\n const section = getArgValue(argv, '--section');\n const itemKey = getArgValue(argv, '--key');\n const format = getArgValue(argv, '--format') ?? 'table';\n\n if (!propertyId || !section || !itemKey) {\n console.error('Error: --application, --section, --key are required.');\n process.exit(1);\n }\n if (!isSection(section)) {\n console.error(`Error: invalid section \"${section}\". One of: ${SECTIONS.join(', ')}`);\n process.exit(1);\n }\n\n const result = await apiRequest<{ ok: boolean; error?: string; data?: ContextItem[] }>(\n apiUrl,\n token,\n 'GET',\n `/org/properties/${propertyId}/context/history?section=${section}&itemKey=${encodeURIComponent(itemKey)}`\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n\n const versions = result.data ?? [];\n if (format === 'json') {\n console.log(JSON.stringify(versions, null, 2));\n return;\n }\n if (versions.length === 0) {\n console.log('(no history)');\n return;\n }\n for (const v of versions) {\n const provenance = v.sourceId ? ` (${v.sourceId})` : '';\n console.log(`v${v.version} ${v.source}${provenance} ${v.createdAt}`);\n }\n}\n\nasync function handleExport(argv: string[], apiUrl: string, token: string): Promise<void> {\n const propertyId = getApplicationArg(argv);\n const format = getArgValue(argv, '--format') ?? 'md';\n\n if (!propertyId) {\n console.error('Error: --application is required (alias: --property).');\n process.exit(1);\n }\n\n const result = await apiRequest<ListResponse>(\n apiUrl,\n token,\n 'GET',\n `/org/properties/${propertyId}/context`\n );\n\n if (!result.ok) {\n console.error(`Error: ${result.error ?? 'Unknown error'}`);\n process.exit(1);\n }\n\n const items = result.data?.items ?? [];\n if (format === 'json') {\n console.log(JSON.stringify({ items }, null, 2));\n return;\n }\n\n const grouped = new Map<string, ContextItem[]>();\n for (const item of items) {\n const arr = grouped.get(item.section) ?? [];\n arr.push(item);\n grouped.set(item.section, arr);\n }\n for (const sec of SECTIONS) {\n const arr = grouped.get(sec);\n if (!arr || arr.length === 0) continue;\n console.log(`## ${sec}`);\n console.log('');\n for (const item of arr) {\n console.log(`### ${item.itemLabel} (\\`${item.itemKey}\\`)`);\n console.log('');\n console.log(item.content);\n console.log('');\n }\n }\n}\n\ntype BundleItem = { section: string; itemKey: string; itemLabel: string; content: string };\ntype Bundle = { items: BundleItem[] };\n\nasync function handleImport(argv: string[], apiUrl: string, token: string): Promise<void> {\n const propertyId = getApplicationArg(argv);\n const file = getArgValue(argv, '--file');\n const sourceId = getArgValue(argv, '--source-id');\n\n if (!propertyId || !file) {\n console.error('Error: --application and --file are required.');\n process.exit(1);\n }\n\n let bundle: Bundle;\n try {\n bundle = JSON.parse(readFileSync(file, 'utf8')) as Bundle;\n } catch (err) {\n console.error(`Error parsing ${file}: ${(err as Error).message}`);\n process.exit(1);\n return;\n }\n\n if (!bundle.items || !Array.isArray(bundle.items)) {\n console.error('Error: bundle.json must have an \"items\" array.');\n process.exit(1);\n }\n\n let ok = 0;\n let fail = 0;\n for (const item of bundle.items) {\n if (!isSection(item.section)) {\n console.error(` ✗ [${item.section}] ${item.itemKey}: invalid section`);\n fail++;\n continue;\n }\n const body: Record<string, unknown> = {\n section: item.section,\n itemKey: item.itemKey,\n itemLabel: item.itemLabel,\n content: item.content,\n source: 'cli',\n };\n if (sourceId) body.sourceId = sourceId;\n\n const result = await apiRequest<{ ok: boolean; error?: string; data?: ContextItem }>(\n apiUrl,\n token,\n 'PUT',\n `/org/properties/${propertyId}/context/items`,\n body\n );\n\n if (result.ok) {\n console.log(` ✓ [${item.section}] ${item.itemKey} (v${result.data?.version ?? '?'})`);\n ok++;\n } else {\n console.error(` ✗ [${item.section}] ${item.itemKey}: ${result.error ?? 'Unknown error'}`);\n fail++;\n }\n }\n\n console.log(`\\nImported ${ok}/${ok + fail} items${fail ? ` (${fail} failed)` : ''}.`);\n if (fail > 0) process.exit(1);\n}\n\nfunction handleGuide(): void {\n try {\n const guide = readFileSync(GUIDE_PATH, 'utf8');\n process.stdout.write(guide);\n if (!guide.endsWith('\\n')) process.stdout.write('\\n');\n } catch (err) {\n console.error(`Error: could not read authoring guide at ${GUIDE_PATH}`);\n console.error((err as Error).message);\n process.exit(1);\n }\n}\n\nexport async function runPropertySkill(argv: string[], apiUrl: string, token: string): Promise<void> {\n const [action, ...rest] = argv;\n\n if (!action || action === 'help' || hasFlag(argv, '--help', '-h')) {\n printSkillHelp();\n return;\n }\n\n switch (action) {\n case 'guide':\n handleGuide();\n return;\n case 'list':\n await handleList(rest, apiUrl, token);\n break;\n case 'get':\n await handleGet(rest, apiUrl, token);\n break;\n case 'set':\n await handleSet(rest, apiUrl, token);\n break;\n case 'delete':\n await handleDelete(rest, apiUrl, token);\n break;\n case 'history':\n await handleHistory(rest, apiUrl, token);\n break;\n case 'export':\n await handleExport(rest, apiUrl, token);\n break;\n case 'import':\n await handleImport(rest, apiUrl, token);\n break;\n default:\n console.error(`Unknown skill action: ${action}`);\n printSkillHelp();\n process.exit(1);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAMA,OAAOA,cAAa;;;ACGpB,SAAS,oBAAoB;AAC7B,SAAS,SAAS,YAAY;AAC9B,SAAS,qBAAqB;AAC9B,OAAO,aAAa;AAIpB,IAAM,OAAO,QAAQ,cAAc,YAAY,GAAG,CAAC;AACnD,IAAM,aAAa,KAAK,MAAM,yBAAyB;AAEvD,IAAM,WAAW;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAuBA,SAAS,iBAAuB;AAC9B,UAAQ;AAAA,IACN;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,OAAO,SAAS,KAAK,IAAI;AAAA,MACzB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb;AACF;AAEA,SAAS,YAAY,OAAuB;AAC1C,MAAI,MAAM,WAAW,GAAG,GAAG;AACzB,UAAM,OAAO,MAAM,MAAM,CAAC;AAC1B,WAAO,aAAa,MAAM,MAAM;AAAA,EAClC;AACA,SAAO;AACT;AAEA,SAAS,UAAU,GAAqC;AACtD,SAAO,CAAC,CAAC,KAAM,SAA+B,SAAS,CAAC;AAC1D;AAEA,eAAe,WAAW,MAAgB,QAAgB,OAA8B;AACtF,QAAM,aAAa,kBAAkB,IAAI;AACzC,QAAM,UAAU,YAAY,MAAM,WAAW;AAC7C,QAAM,SAAS,YAAY,MAAM,UAAU,MAAM,QAAQ,MAAM,QAAQ,IAAI,SAAS;AAEpF,MAAI,CAAC,YAAY;AACf,YAAQ,MAAM,uDAAuD;AACrE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA,mBAAmB,UAAU;AAAA,EAC/B;AAEA,MAAI,CAAC,OAAO,IAAI;AACd,YAAQ,MAAM,UAAU,OAAO,SAAS,eAAe,EAAE;AACzD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,QAAQ,OAAO,MAAM,SAAS,CAAC;AACnC,MAAI,QAAS,SAAQ,MAAM,OAAO,CAAC,MAAM,EAAE,YAAY,OAAO;AAE9D,MAAI,WAAW,QAAQ;AACrB,YAAQ,IAAI,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AAC1C;AAAA,EACF;AAEA,MAAI,MAAM,WAAW,GAAG;AACtB,YAAQ,IAAI,YAAY;AACxB;AAAA,EACF;AAEA,QAAM,UAAU,oBAAI,IAA2B;AAC/C,aAAW,QAAQ,OAAO;AACxB,UAAM,MAAM,QAAQ,IAAI,KAAK,OAAO,KAAK,CAAC;AAC1C,QAAI,KAAK,IAAI;AACb,YAAQ,IAAI,KAAK,SAAS,GAAG;AAAA,EAC/B;AAEA,aAAW,OAAO,UAAU;AAC1B,UAAM,MAAM,QAAQ,IAAI,GAAG;AAC3B,QAAI,CAAC,OAAO,IAAI,WAAW,EAAG;AAC9B,YAAQ,IAAI;AAAA,GAAM,GAAG,GAAG;AACxB,eAAW,QAAQ,KAAK;AACtB,YAAM,aAAa,KAAK,WAAW,SAAS,KAAK,WAAW,KAAK,KAAK,QAAQ,MAAM,KAAK,WAAW,QAAQ,KAAK,KAAK,MAAM,MAAM;AAClI,cAAQ,IAAI,KAAK,KAAK,OAAO,WAAM,KAAK,SAAS,GAAG,UAAU,EAAE;AAAA,IAClE;AAAA,EACF;AACF;AAEA,eAAe,UAAU,MAAgB,QAAgB,OAA8B;AACrF,QAAM,aAAa,kBAAkB,IAAI;AACzC,QAAM,UAAU,YAAY,MAAM,WAAW;AAC7C,QAAM,UAAU,YAAY,MAAM,OAAO;AACzC,QAAM,aAAa,YAAY,MAAM,WAAW;AAChD,QAAM,SAAS,YAAY,MAAM,UAAU,KAAK;AAEhD,MAAI,CAAC,cAAc,CAAC,WAAW,CAAC,SAAS;AACvC,YAAQ,MAAM,sDAAsD;AACpE,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,MAAI,CAAC,UAAU,OAAO,GAAG;AACvB,YAAQ,MAAM,2BAA2B,OAAO,cAAc,SAAS,KAAK,IAAI,CAAC,EAAE;AACnF,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,MAAI,YAAY;AACd,UAAM,IAAI,OAAO,UAAU;AAC3B,UAAMC,UAAS,MAAM;AAAA,MACnB;AAAA,MACA;AAAA,MACA;AAAA,MACA,mBAAmB,UAAU,4BAA4B,OAAO,YAAY,mBAAmB,OAAO,CAAC;AAAA,IACzG;AACA,QAAI,CAACA,QAAO,IAAI;AACd,cAAQ,MAAM,UAAUA,QAAO,SAAS,eAAe,EAAE;AACzD,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,UAAMC,SAAQD,QAAO,QAAQ,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,YAAY,CAAC;AAC5D,QAAI,CAACC,OAAM;AACT,cAAQ,MAAM,qBAAqB,CAAC,QAAQ,OAAO,IAAI,OAAO,EAAE;AAChE,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,cAAUA,OAAM,MAAM;AACtB;AAAA,EACF;AAEA,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA,mBAAmB,UAAU;AAAA,EAC/B;AACA,MAAI,CAAC,OAAO,IAAI;AACd,YAAQ,MAAM,UAAU,OAAO,SAAS,eAAe,EAAE;AACzD,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,QAAM,QAAQ,OAAO,MAAM,SAAS,CAAC,GAAG;AAAA,IACtC,CAAC,MAAM,EAAE,YAAY,WAAW,EAAE,YAAY;AAAA,EAChD;AACA,MAAI,CAAC,MAAM;AACT,YAAQ,MAAM,kBAAkB,OAAO,IAAI,OAAO,EAAE;AACpD,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,YAAU,MAAM,MAAM;AACxB;AAEA,SAAS,UAAU,MAAmB,QAAsB;AAC1D,MAAI,WAAW,QAAQ;AACrB,YAAQ,IAAI,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;AACzC;AAAA,EACF;AACA,UAAQ,IAAI,KAAK,KAAK,SAAS,EAAE;AACjC,UAAQ,IAAI,YAAY,KAAK,OAAO,EAAE;AACtC,UAAQ,IAAI,QAAQ,KAAK,OAAO,EAAE;AAClC,UAAQ,IAAI,YAAY,KAAK,OAAO,EAAE;AACtC,UAAQ,IAAI,WAAW,KAAK,MAAM,GAAG,KAAK,WAAW,KAAK,KAAK,QAAQ,MAAM,EAAE,EAAE;AACjF,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,KAAK,OAAO;AAC1B;AAEA,eAAe,UAAU,MAAgB,QAAgB,OAA8B;AACrF,QAAM,aAAa,kBAAkB,IAAI;AACzC,QAAM,UAAU,YAAY,MAAM,WAAW;AAC7C,QAAM,UAAU,YAAY,MAAM,OAAO;AACzC,QAAM,YAAY,YAAY,MAAM,SAAS;AAC7C,QAAM,aAAa,YAAY,MAAM,WAAW;AAChD,QAAM,WAAW,YAAY,MAAM,aAAa;AAEhD,MAAI,CAAC,cAAc,CAAC,WAAW,CAAC,WAAW,CAAC,aAAa,eAAe,QAAW;AACjF,YAAQ,MAAM,0EAA0E;AACxF,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,MAAI,CAAC,UAAU,OAAO,GAAG;AACvB,YAAQ,MAAM,2BAA2B,OAAO,cAAc,SAAS,KAAK,IAAI,CAAC,EAAE;AACnF,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,UAAU,YAAY,UAAU;AAEtC,QAAM,OAAgC;AAAA,IACpC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,EACV;AACA,MAAI,aAAa,OAAW,MAAK,WAAW;AAE5C,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA,mBAAmB,UAAU;AAAA,IAC7B;AAAA,EACF;AAEA,MAAI,CAAC,OAAO,IAAI;AACd,YAAQ,MAAM,UAAU,OAAO,SAAS,eAAe,EAAE;AACzD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,IAAI,QAAQ,OAAO,KAAK,OAAO,MAAM,OAAO,MAAM,WAAW,GAAG,GAAG;AAC7E;AAEA,eAAe,aAAa,MAAgB,QAAgB,OAA8B;AACxF,QAAM,aAAa,kBAAkB,IAAI;AACzC,QAAM,UAAU,YAAY,MAAM,WAAW;AAC7C,QAAM,UAAU,YAAY,MAAM,OAAO;AAEzC,MAAI,CAAC,cAAc,CAAC,WAAW,CAAC,SAAS;AACvC,YAAQ,MAAM,sDAAsD;AACpE,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,MAAI,CAAC,UAAU,OAAO,GAAG;AACvB,YAAQ,MAAM,2BAA2B,OAAO,cAAc,SAAS,KAAK,IAAI,CAAC,EAAE;AACnF,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA,mBAAmB,UAAU;AAAA,IAC7B,EAAE,SAAS,QAAQ;AAAA,EACrB;AAEA,MAAI,CAAC,OAAO,IAAI;AACd,YAAQ,MAAM,UAAU,OAAO,SAAS,eAAe,EAAE;AACzD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,IAAI,YAAY,OAAO,KAAK,OAAO,EAAE;AAC/C;AAEA,eAAe,cAAc,MAAgB,QAAgB,OAA8B;AACzF,QAAM,aAAa,kBAAkB,IAAI;AACzC,QAAM,UAAU,YAAY,MAAM,WAAW;AAC7C,QAAM,UAAU,YAAY,MAAM,OAAO;AACzC,QAAM,SAAS,YAAY,MAAM,UAAU,KAAK;AAEhD,MAAI,CAAC,cAAc,CAAC,WAAW,CAAC,SAAS;AACvC,YAAQ,MAAM,sDAAsD;AACpE,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,MAAI,CAAC,UAAU,OAAO,GAAG;AACvB,YAAQ,MAAM,2BAA2B,OAAO,cAAc,SAAS,KAAK,IAAI,CAAC,EAAE;AACnF,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA,mBAAmB,UAAU,4BAA4B,OAAO,YAAY,mBAAmB,OAAO,CAAC;AAAA,EACzG;AAEA,MAAI,CAAC,OAAO,IAAI;AACd,YAAQ,MAAM,UAAU,OAAO,SAAS,eAAe,EAAE;AACzD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,WAAW,OAAO,QAAQ,CAAC;AACjC,MAAI,WAAW,QAAQ;AACrB,YAAQ,IAAI,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAC7C;AAAA,EACF;AACA,MAAI,SAAS,WAAW,GAAG;AACzB,YAAQ,IAAI,cAAc;AAC1B;AAAA,EACF;AACA,aAAW,KAAK,UAAU;AACxB,UAAM,aAAa,EAAE,WAAW,KAAK,EAAE,QAAQ,MAAM;AACrD,YAAQ,IAAI,IAAI,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,UAAU,KAAK,EAAE,SAAS,EAAE;AAAA,EACvE;AACF;AAEA,eAAe,aAAa,MAAgB,QAAgB,OAA8B;AACxF,QAAM,aAAa,kBAAkB,IAAI;AACzC,QAAM,SAAS,YAAY,MAAM,UAAU,KAAK;AAEhD,MAAI,CAAC,YAAY;AACf,YAAQ,MAAM,uDAAuD;AACrE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA,mBAAmB,UAAU;AAAA,EAC/B;AAEA,MAAI,CAAC,OAAO,IAAI;AACd,YAAQ,MAAM,UAAU,OAAO,SAAS,eAAe,EAAE;AACzD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,QAAQ,OAAO,MAAM,SAAS,CAAC;AACrC,MAAI,WAAW,QAAQ;AACrB,YAAQ,IAAI,KAAK,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;AAC9C;AAAA,EACF;AAEA,QAAM,UAAU,oBAAI,IAA2B;AAC/C,aAAW,QAAQ,OAAO;AACxB,UAAM,MAAM,QAAQ,IAAI,KAAK,OAAO,KAAK,CAAC;AAC1C,QAAI,KAAK,IAAI;AACb,YAAQ,IAAI,KAAK,SAAS,GAAG;AAAA,EAC/B;AACA,aAAW,OAAO,UAAU;AAC1B,UAAM,MAAM,QAAQ,IAAI,GAAG;AAC3B,QAAI,CAAC,OAAO,IAAI,WAAW,EAAG;AAC9B,YAAQ,IAAI,MAAM,GAAG,EAAE;AACvB,YAAQ,IAAI,EAAE;AACd,eAAW,QAAQ,KAAK;AACtB,cAAQ,IAAI,OAAO,KAAK,SAAS,OAAO,KAAK,OAAO,KAAK;AACzD,cAAQ,IAAI,EAAE;AACd,cAAQ,IAAI,KAAK,OAAO;AACxB,cAAQ,IAAI,EAAE;AAAA,IAChB;AAAA,EACF;AACF;AAKA,eAAe,aAAa,MAAgB,QAAgB,OAA8B;AACxF,QAAM,aAAa,kBAAkB,IAAI;AACzC,QAAM,OAAO,YAAY,MAAM,QAAQ;AACvC,QAAM,WAAW,YAAY,MAAM,aAAa;AAEhD,MAAI,CAAC,cAAc,CAAC,MAAM;AACxB,YAAQ,MAAM,+CAA+C;AAC7D,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,aAAa,MAAM,MAAM,CAAC;AAAA,EAChD,SAAS,KAAK;AACZ,YAAQ,MAAM,iBAAiB,IAAI,KAAM,IAAc,OAAO,EAAE;AAChE,YAAQ,KAAK,CAAC;AACd;AAAA,EACF;AAEA,MAAI,CAAC,OAAO,SAAS,CAAC,MAAM,QAAQ,OAAO,KAAK,GAAG;AACjD,YAAQ,MAAM,gDAAgD;AAC9D,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,KAAK;AACT,MAAI,OAAO;AACX,aAAW,QAAQ,OAAO,OAAO;AAC/B,QAAI,CAAC,UAAU,KAAK,OAAO,GAAG;AAC5B,cAAQ,MAAM,aAAQ,KAAK,OAAO,KAAK,KAAK,OAAO,mBAAmB;AACtE;AACA;AAAA,IACF;AACA,UAAM,OAAgC;AAAA,MACpC,SAAS,KAAK;AAAA,MACd,SAAS,KAAK;AAAA,MACd,WAAW,KAAK;AAAA,MAChB,SAAS,KAAK;AAAA,MACd,QAAQ;AAAA,IACV;AACA,QAAI,SAAU,MAAK,WAAW;AAE9B,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,MACA;AAAA,MACA;AAAA,MACA,mBAAmB,UAAU;AAAA,MAC7B;AAAA,IACF;AAEA,QAAI,OAAO,IAAI;AACb,cAAQ,IAAI,aAAQ,KAAK,OAAO,KAAK,KAAK,OAAO,MAAM,OAAO,MAAM,WAAW,GAAG,GAAG;AACrF;AAAA,IACF,OAAO;AACL,cAAQ,MAAM,aAAQ,KAAK,OAAO,KAAK,KAAK,OAAO,KAAK,OAAO,SAAS,eAAe,EAAE;AACzF;AAAA,IACF;AAAA,EACF;AAEA,UAAQ,IAAI;AAAA,WAAc,EAAE,IAAI,KAAK,IAAI,SAAS,OAAO,KAAK,IAAI,aAAa,EAAE,GAAG;AACpF,MAAI,OAAO,EAAG,SAAQ,KAAK,CAAC;AAC9B;AAEA,SAAS,cAAoB;AAC3B,MAAI;AACF,UAAM,QAAQ,aAAa,YAAY,MAAM;AAC7C,YAAQ,OAAO,MAAM,KAAK;AAC1B,QAAI,CAAC,MAAM,SAAS,IAAI,EAAG,SAAQ,OAAO,MAAM,IAAI;AAAA,EACtD,SAAS,KAAK;AACZ,YAAQ,MAAM,4CAA4C,UAAU,EAAE;AACtE,YAAQ,MAAO,IAAc,OAAO;AACpC,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAEA,eAAsB,iBAAiB,MAAgB,QAAgB,OAA8B;AACnG,QAAM,CAAC,QAAQ,GAAG,IAAI,IAAI;AAE1B,MAAI,CAAC,UAAU,WAAW,UAAU,QAAQ,MAAM,UAAU,IAAI,GAAG;AACjE,mBAAe;AACf;AAAA,EACF;AAEA,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,kBAAY;AACZ;AAAA,IACF,KAAK;AACH,YAAM,WAAW,MAAM,QAAQ,KAAK;AACpC;AAAA,IACF,KAAK;AACH,YAAM,UAAU,MAAM,QAAQ,KAAK;AACnC;AAAA,IACF,KAAK;AACH,YAAM,UAAU,MAAM,QAAQ,KAAK;AACnC;AAAA,IACF,KAAK;AACH,YAAM,aAAa,MAAM,QAAQ,KAAK;AACtC;AAAA,IACF,KAAK;AACH,YAAM,cAAc,MAAM,QAAQ,KAAK;AACvC;AAAA,IACF,KAAK;AACH,YAAM,aAAa,MAAM,QAAQ,KAAK;AACtC;AAAA,IACF,KAAK;AACH,YAAM,aAAa,MAAM,QAAQ,KAAK;AACtC;AAAA,IACF;AACE,cAAQ,MAAM,yBAAyB,MAAM,EAAE;AAC/C,qBAAe;AACf,cAAQ,KAAK,CAAC;AAAA,EAClB;AACF;;;AD7eA,SAAS,IAAI,GAAW,GAAmB;AACzC,SAAO,EAAE,OAAO,CAAC;AACnB;AAEA,SAAS,YAAkB;AACzB,UAAQ;AAAA,IACN;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb;AACF;AAWA,eAAeC,YAAW,MAAgB,QAAgB,OAA8B;AACtF,QAAM,OAAO,QAAQ,MAAM,QAAQ;AACnC,QAAM,aAAa,MAAM,gBAAgB,QAAQ,KAAK;AAEtD,MAAI,MAAM;AACR,YAAQ,IAAI,KAAK,UAAU,YAAY,MAAM,CAAC,CAAC;AAC/C;AAAA,EACF;AAEA,MAAI,WAAW,WAAW,GAAG;AAC3B,YAAQ,IAAI,wBAAwB;AACpC;AAAA,EACF;AAEA,UAAQ,IAAI,GAAG,IAAI,QAAQ,EAAE,CAAC,IAAI,IAAI,YAAY,EAAE,CAAC,KAAK;AAC1D,aAAW,KAAK,YAAY;AAC1B,YAAQ,IAAI,GAAG,IAAI,EAAE,MAAM,EAAE,CAAC,IAAI,IAAI,EAAE,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE;AAAA,EAChE;AAGA,UAAQ,IAAI,EAAE;AACd,aAAW,KAAK,YAAY;AAC1B,UAAM,WAAW,MAAM;AAAA,MACrB;AAAA,MAAQ;AAAA,MAAO;AAAA,MAAO,mBAAmB,EAAE,EAAE;AAAA,IAC/C;AACA,UAAM,QAAQ,SAAS,KAAM,SAAS,SAAS,CAAC,IAAK,CAAC;AACtD,QAAI,MAAM,SAAS,GAAG;AACpB,cAAQ,IAAI,GAAG,EAAE,IAAI,SAAS;AAC9B,iBAAW,KAAK,OAAO;AACrB,cAAM,MAAM,EAAE,WAAW,EAAE,YAAY,MAAM,KAAK,EAAE,OAAO,MAAM;AACjE,cAAM,OAAO,EAAE,OAAO,KAAK,EAAE,IAAI,MAAM;AACvC,gBAAQ,IAAI,KAAK,EAAE,YAAY,IAAI,EAAE,aAAa,GAAG,IAAI,GAAG,GAAG,EAAE;AAAA,MACnE;AAAA,IACF;AAAA,EACF;AACF;AAMA,SAAS,uBACP,MAC8C;AAC9C,QAAM,OAAqD,CAAC;AAC5D,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,QAAI,KAAK,CAAC,MAAM,YAAa;AAC7B,UAAM,MAAM,KAAK,IAAI,CAAC;AACtB,QAAI,CAAC,OAAO,IAAI,WAAW,GAAG,EAAG;AACjC,UAAM,CAAC,MAAM,QAAQ,IAAI,IAAI,MAAM,GAAG;AACtC,QAAI,CAAC,KAAM;AAEX,SAAK,KAAK,EAAE,MAAM,GAAI,aAAa,cAAc,EAAE,WAAW,KAAK,IAAI,CAAC,EAAG,CAAC;AAAA,EAC9E;AACA,SAAO;AACT;AAEA,eAAe,aAAa,MAAgB,QAAgB,OAA8B;AACxF,QAAM,OAAO,QAAQ,MAAM,QAAQ;AACnC,QAAM,OAAO,YAAY,MAAM,QAAQ;AACvC,QAAM,UAAU,YAAY,MAAM,YAAY;AAC9C,QAAM,cAAc,YAAY,MAAM,eAAe;AACrD,QAAM,eAAe,YAAY,MAAM,iBAAiB;AACxD,QAAM,oBAAoB,uBAAuB,IAAI;AAErD,MAAI,CAAC,QAAQ,CAAC,SAAS;AACrB,YAAQ,MAAM,4CAA4C;AAC1D,YAAQ,MAAM,iEAAiE;AAC/E,IAAAC,SAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,OAAgC,EAAE,MAAM,QAAQ;AACtD,MAAI,gBAAgB,OAAW,MAAK,cAAc;AAClD,MAAI,iBAAiB,OAAW,MAAK,eAAe;AACpD,MAAI,kBAAkB,SAAS,EAAG,MAAK,oBAAoB;AAE3D,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,CAAC,OAAO,IAAI;AACd,QAAI,MAAM;AACR,cAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,IAC7C,OAAO;AACL,cAAQ,MAAM,UAAU,OAAO,SAAS,eAAe,EAAE;AAAA,IAC3D;AACA,IAAAA,SAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,MAAM;AACR,YAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAC3C;AAAA,EACF;AAEA,UAAQ,IAAI,wBAAwB,IAAI,MAAM,OAAO,EAAE,GAAG;AAC5D;AAEA,eAAe,eAAe,MAAgB,QAAgB,OAA8B;AAC1F,QAAM,OAAO,QAAQ,MAAM,QAAQ;AACnC,QAAM,aAAa,kBAAkB,IAAI;AACzC,QAAM,OAAO,YAAY,MAAM,QAAQ;AACvC,QAAM,OAAO,YAAY,MAAM,QAAQ;AACvC,QAAM,UAAU,YAAY,MAAM,YAAY;AAC9C,QAAM,YAAY,YAAY,MAAM,cAAc;AAElD,MAAI,CAAC,cAAc,CAAC,MAAM;AACxB,YAAQ,MAAM,+CAA+C;AAC7D,IAAAA,SAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,OAAgC,EAAE,cAAc,KAAK;AAC3D,MAAI,SAAS,OAAW,MAAK,OAAO;AACpC,MAAI,YAAY,OAAW,MAAK,UAAU;AAC1C,MAAI,cAAc,OAAW,MAAK,YAAY;AAE9C,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA,mBAAmB,UAAU;AAAA,IAC7B;AAAA,EACF;AAEA,MAAI,CAAC,OAAO,IAAI;AACd,QAAI,KAAM,SAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,QAChD,SAAQ,MAAM,UAAU,OAAO,SAAS,eAAe,EAAE;AAC9D,IAAAA,SAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,KAAM,SAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,MAChD,SAAQ,IAAI,UAAU,IAAI,mBAAmB,UAAU,KAAK,OAAO,EAAE,GAAG;AAC/E;AAEA,eAAe,iBAAiB,MAAgB,QAAgB,OAA8B;AAC5F,QAAM,OAAO,QAAQ,MAAM,QAAQ;AACnC,QAAM,aAAa,kBAAkB,IAAI;AACzC,QAAM,SAAS,YAAY,MAAM,WAAW;AAC5C,QAAM,OAAO,YAAY,MAAM,QAAQ;AACvC,QAAM,UAAU,YAAY,MAAM,YAAY;AAC9C,QAAM,YAAY,YAAY,MAAM,cAAc;AAElD,MAAI,CAAC,cAAc,CAAC,QAAQ;AAC1B,YAAQ,MAAM,kDAAkD;AAChE,IAAAA,SAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,OAAgC,CAAC;AACvC,MAAI,SAAS,OAAW,MAAK,OAAO;AACpC,MAAI,YAAY,OAAW,MAAK,UAAU;AAC1C,MAAI,cAAc,OAAW,MAAK,YAAY;AAE9C,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA,mBAAmB,UAAU,iBAAiB,MAAM;AAAA,IACpD;AAAA,EACF;AAEA,MAAI,CAAC,OAAO,IAAI;AACd,QAAI,KAAM,SAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,QAChD,SAAQ,MAAM,UAAU,OAAO,SAAS,eAAe,EAAE;AAC9D,IAAAA,SAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,KAAM,SAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,MAChD,SAAQ,IAAI,qBAAqB,MAAM,EAAE;AAChD;AAEA,eAAe,iBAAiB,MAAgB,QAAgB,OAA8B;AAC5F,QAAM,OAAO,QAAQ,MAAM,QAAQ;AACnC,QAAM,aAAa,kBAAkB,IAAI;AACzC,QAAM,OAAO,YAAY,MAAM,QAAQ;AAEvC,MAAI,CAAC,cAAc,CAAC,MAAM;AACxB,YAAQ,MAAM,+CAA+C;AAC7D,IAAAA,SAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA,mBAAmB,UAAU,iBAAiB,mBAAmB,IAAI,CAAC;AAAA,EACxE;AAEA,MAAI,CAAC,OAAO,IAAI;AACd,QAAI,KAAM,SAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,QAChD,SAAQ,MAAM,UAAU,OAAO,SAAS,eAAe,EAAE;AAC9D,IAAAA,SAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,KAAM,SAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,MAChD,SAAQ,IAAI,YAAY,IAAI,qBAAqB,UAAU,EAAE;AACpE;AAEA,eAAe,WAAW,MAAgB,QAAgB,OAA8B;AACtF,QAAM,CAAC,QAAQ,GAAG,IAAI,IAAI;AAC1B,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,YAAM,eAAe,MAAM,QAAQ,KAAK;AACxC;AAAA,IACF,KAAK;AACH,YAAM,iBAAiB,MAAM,QAAQ,KAAK;AAC1C;AAAA,IACF,KAAK;AACH,YAAM,iBAAiB,MAAM,QAAQ,KAAK;AAC1C;AAAA,IACF;AACE,cAAQ,MAAM,wBAAwB,UAAU,QAAQ,EAAE;AAC1D,gBAAU;AACV,MAAAA,SAAQ,KAAK,CAAC;AAAA,EAClB;AACF;AAEA,eAAsB,YAAY,MAA+B;AAC/D,QAAM,CAAC,YAAY,GAAG,IAAI,IAAI;AAE9B,MAAI,CAAC,cAAc,eAAe,UAAU,QAAQ,MAAM,UAAU,IAAI,GAAG;AACzE,cAAU;AACV;AAAA,EACF;AAIA,MAAI,eAAe,SAAS;AAC1B,UAAM,cAAc,KAAK,CAAC;AAC1B,QAAI,CAAC,eAAe,gBAAgB,UAAU,gBAAgB,SAAS;AACrE,YAAM,iBAAiB,MAAM,IAAI,EAAE;AACnC;AAAA,IACF;AAAA,EACF;AAEA,QAAM,EAAE,QAAQ,MAAM,IAAI,MAAM,cAAc,IAAI;AAElD,QAAM,cAAc,oBAAI,IAAI,CAAC,SAAS,aAAa,SAAS,CAAC;AAC7D,QAAM,OAAO,KAAK,OAAO,CAAC,KAAK,MAAM;AACnC,QAAI,YAAY,IAAI,GAAG,EAAG,QAAO;AACjC,QAAI,IAAI,KAAK,YAAY,IAAI,KAAK,IAAI,CAAC,CAAC,EAAG,QAAO;AAClD,WAAO;AAAA,EACT,CAAC;AAED,UAAQ,YAAY;AAAA,IAClB,KAAK;AACH,YAAMD,YAAW,MAAM,QAAQ,KAAK;AACpC;AAAA,IACF,KAAK;AACH,YAAM,aAAa,MAAM,QAAQ,KAAK;AACtC;AAAA,IACF,KAAK;AACH,YAAM,WAAW,MAAM,QAAQ,KAAK;AACpC;AAAA,IACF,KAAK;AACH,YAAM,iBAAiB,MAAM,QAAQ,KAAK;AAC1C;AAAA,IACF;AACE,cAAQ,MAAM,wBAAwB,UAAU,EAAE;AAClD,gBAAU;AACV,MAAAC,SAAQ,KAAK,CAAC;AAAA,EAClB;AACF;","names":["process","result","item","handleList","process"]}
@@ -0,0 +1,189 @@
1
+ # Authoring an App Skill
2
+
3
+ You're a coding agent working in the repository of an application that is tested by our cloud QA browser agent. Your job: produce a **skill** — a per-property knowledge base — so that when the QA agent runs workflows against this app, it has the institutional knowledge it can't infer from the DOM alone.
4
+
5
+ You are the primary author of this skill. You have everything you need: the source, your existing memory/notes about the app, and your judgment about what actually matters for end-to-end testing. This guide tells you *what to produce*, not how to investigate — you already know how to do that.
6
+
7
+ ## The critical constraint
8
+
9
+ **The skill is consumed by a runtime browser agent that has only the DOM, `page.*` actions, and `page.request`. It has no source code, no repo, no file system, no access to anything you can read.**
10
+
11
+ Every item you write must be useful in that world. Your repo is the *source* you read; the skill content is the *translation* into runtime-actionable knowledge.
12
+
13
+ ✅ "Org switching is reflected in the URL: paths under `/o/<slug>/…` are tenant-scoped, and navigating directly to a path with a different `<slug>` is the canonical way to switch."
14
+ ❌ "See the org middleware in the auth package for how tenant context is set."
15
+
16
+ ✅ "When a feature is gated off, the most common signal is the action button being absent from the DOM (not disabled). Less commonly, the route renders a 'requires upgrade' empty state, or a mutation returns a typed error like `FEATURE_DISABLED`."
17
+ ❌ "The feature-flag service exposes a `useFlag()` hook checked by the `<Gate>` component."
18
+
19
+ **The translation check, for every item:** *if all I had was a browser, would this sentence help me?* If it names a file, internal class, hook, middleware, package, or private symbol — rewrite as observable behavior or drop it.
20
+
21
+ This applies to *examples too*. Don't write "the `/api/v2/widgets` endpoint" if it's just a plausible-sounding example you invented — the QA agent will look for that exact path and be confused if it doesn't exist. Either it's real and stable, or omit it.
22
+
23
+ ## Prerequisite: the property must be linked to this repo
24
+
25
+ The skill is attached to a Canary **property** — the abstraction for "the app under test." Before you start authoring, confirm the property you're targeting is linked to the repository you're working in. If it isn't, link it first or ask the user which property to target:
26
+
27
+ ```bash
28
+ canary property list # find the property
29
+ canary property repo link --property <id> --repo <owner/name> # link if needed
30
+ ```
31
+
32
+ Once linked, every write you do via `canary property skill set/import` lands on the right property.
33
+
34
+ ## Sections
35
+
36
+ Each section captures a *model* the QA agent can reason from. Sections cover what generalizes across web apps; specific instances (every flag name, every URL) go stale within weeks and aren't worth enumerating. Aim for the runtime agent to be able to *speculate* a correct diagnosis from your model, even for situations you didn't explicitly cover.
37
+
38
+ For each section, ask: "what does the runtime agent need to understand to make pass/fail judgments correctly?"
39
+
40
+ **Volume.** Aim for 3–6 items per section where the app has something to say. If a section legitimately doesn't apply (e.g. a single-locale app's `localization`), still ship one short item that says so — a brief "N/A and why" is more useful than an absent section.
41
+
42
+ ### `general` — Overview
43
+
44
+ What the app is, who uses it, what it's for. One or two short items — enough that the QA agent has a frame for everything else.
45
+
46
+ ### `product` — Domain Model
47
+
48
+ The entities the user works with and how they relate. Lifecycle states at a high level. Not a schema dump — the relationships and concepts a tester needs to make sense of what they're looking at.
49
+
50
+ ✅ "Projects contain Tasks. Tasks belong to one Project; reassignment moves them between Projects. Completed Tasks are kept (not deleted) and visible via a 'Completed' filter."
51
+
52
+ ### `technology` — Tech Stack
53
+
54
+ Framework family, component library family, API shape — only the parts that inform locator strategy or interaction patterns. The runtime agent uses this to pick the right way to interact (native form submit vs client-side router, virtualized lists, etc.).
55
+
56
+ ✅ "Single-page app rendered client-side; routes update the URL without full page loads. Wait for hydration completion before interacting on first load."
57
+
58
+ ### `navigation` — Navigation Model
59
+
60
+ **How to get places**, not a list of every route. The runtime agent should be able to navigate to a concept (a settings page, a list of an entity type, a detail view) without you having pre-enumerated every URL.
61
+
62
+ Cover: URL grammar (path-segment patterns, ID prefixes, query params with semantic effect), public-vs-authed routing, modal-as-route, how redirects behave, what an unknown route does (404 vs redirect home), how the back button behaves.
63
+
64
+ ✅ "URLs follow `/{entity-type-plural}/{id}` for list and detail. IDs are prefixed (e.g. `xyz_…`), which makes them recognizable in URLs. Deep-linking to a detail page works without going through the list — the page fetches its own data."
65
+
66
+ ### `tenancy` — Tenancy & Workspaces
67
+
68
+ How the multi-tenant world works, if it does. Whether tenant context lives in the URL, a cookie, or a header. How to switch. What cross-tenant references look like (or whether they're forbidden). What the agent sees if it lands on a resource belonging to a different tenant than its current session.
69
+
70
+ If the app is single-tenant, say so — that's the most useful answer.
71
+
72
+ ### `auth` — Authentication & Sessions
73
+
74
+ Login as a flow: what mechanisms exist (password, magic link, OAuth, SSO), where the login page lives, what success looks like (redirect to where?), what session expiry looks like (silent refresh vs bounce to login), how logout behaves, whether there's MFA. The agent should be able to recover when it gets unexpectedly logged out.
75
+
76
+ ### `roles_permissions` — Roles & Permissions
77
+
78
+ The roles a user can have, in their *displayed* form (the casing and wording the runtime agent will actually see in the UI). What each role can and can't do, in terms of observable UI affordances (buttons present/absent, routes accessible vs forbidden). What "access denied" looks like — a full-page error, a redirect, a toast, an HTTP response code.
79
+
80
+ The runtime agent needs to distinguish "this button is missing because I'm the wrong role" (correct gating, not a bug) from "this button should be here but isn't" (real bug).
81
+
82
+ ### `feature_gating` — Feature Gating
83
+
84
+ How features are turned on or off, *as a mechanism* — not a list of every gate. The runtime agent should be able to recognize a gated-off feature when it sees one, and not confuse it with a bug.
85
+
86
+ Cover: how gating typically manifests (button absent, route 404, gated empty state, typed error from a mutation, etc.), whether gating is per-tenant / per-user / per-environment / experiment-bucketed, whether there's an admin surface that reveals current gate state, and any specific error codes a mutation might return when it's gate-blocked.
87
+
88
+ ✅ "When a feature is gated off for a tenant, the most common UI signal is the action button being absent (not disabled, not hidden — fully removed from the DOM). Less common: the destination route renders a 'requires upgrade' empty state with a CTA to billing. Mutation endpoints reject gated calls with `403` and an error body like `{ code: 'FEATURE_DISABLED', feature: '<slug>' }`."
89
+
90
+ Do **not** ship a list of every flag in the system. Flag inventories go stale within weeks. The runtime agent doesn't need to know which flags exist; it needs to recognize the signal when it sees one.
91
+
92
+ ### `environments` — Environments
93
+
94
+ How environments differ in ways the agent can observe. Different base URLs (and naming conventions for them — prod, staging, sandbox, etc.). Which third-party integrations are stubbed vs real in non-prod (the agent should not expect a real charge to fire in sandbox). Any env-only UI surfaces (debug panels, sandbox banners, "you are in test mode" indicators).
95
+
96
+ ### `data_lifecycle` — Entity Lifecycle
97
+
98
+ For meaningful entities (the ones a tester would interact with): the states they can be in, how the user moves them between states, what's reversible vs not, what's soft-deleted vs hard-deleted. Whether creation kicks off async processing and how the user sees "processing" vs "ready." Typical timing windows for that processing, so the agent doesn't time out.
99
+
100
+ ### `async_realtime` — Async & Realtime
101
+
102
+ Which surfaces update in real time vs require a refresh. The wait signal the agent should use (a polling cadence, a websocket/SSE message, a status pill changing) — *something concrete* to watch for. Optimistic UI patterns and what their failure-rollback looks like. Typical end-to-end latency for common flows.
103
+
104
+ ### `localization` — Localization
105
+
106
+ If the app is single-locale, say so. Otherwise: how locale is determined, how it's switched, what changes between locales (currency formatting, decimal separators, date formats, RTL), and which surfaces are user-locale vs server-locale (e.g. timestamps).
107
+
108
+ ### `ui` — UI Patterns
109
+
110
+ Inventory of UI primitives the agent will encounter, by *behavior* not implementation. Custom combobox vs native select. Modal vs drawer vs popover. Date picker behavior. Table interactions (clickable rows? action buttons in last column? virtualized?). Whether destructive actions use native `confirm()` or custom dialogs. Keyboard shortcuts the agent might trigger accidentally. Empty-state vs loading-state appearance.
111
+
112
+ For each pattern: what does the agent click, what happens, how does it dismiss.
113
+
114
+ ### `feedback_errors` — Feedback & Error Signals
115
+
116
+ **The highest-leverage section.** This is what the QA agent uses to make pass/fail judgments.
117
+
118
+ Describe the *signal model* the runtime agent will use to detect outcomes:
119
+
120
+ - **Success signal per surface.** For each common operation (create, update, delete, submit a form), what's the canonical "this worked" signal? A toast? A route change? A status pill flipping? The modal closing? Be specific about *which* signal is canonical so the agent doesn't watch for the wrong one.
121
+ - **Error surfaces.** Where do errors appear? Toast, banner, inline field, page-level, modal, native `alert()`? When does each surface fire (form validation vs server rejection vs network failure)?
122
+ - **Error response shape.** When the API rejects a request, what does the agent see in the network response — a typed error code, a plain string, an HTTP status code? Knowing the shape lets the agent classify failures even when it didn't anticipate them.
123
+ - **Validation timing.** On-change, on-blur, on-submit, async/server? Different forms may differ; if so, describe the pattern.
124
+ - **Loading indicators.** What does "in progress" look like — spinner, skeleton, disabled button, progress bar? What's the agent supposed to wait *on*?
125
+ - **Destructive action confirmation.** Native `confirm()` or a custom dialog? The agent handles each differently.
126
+
127
+ The goal: the runtime agent should be able to look at any unexpected state and *speculate* — "no toast appeared and there's red inline text → the form rejected on validation" — without you having pre-enumerated every error case.
128
+
129
+ ### `idiosyncrasies` — Idiosyncrasies
130
+
131
+ Narrow scope: known runtime-observable gotchas. First-login interrupts, banners that appear conditionally, intentional delays > 500ms that look like hangs, retry/backoff windows, redirects that surprise the agent, flows that look broken but aren't.
132
+
133
+ Each item should answer: "what will I see, when, and how should I respond?" Reject vague "be careful" entries.
134
+
135
+ ## Procedure
136
+
137
+ 1. **Confirm the target.**
138
+ ```bash
139
+ canary property list
140
+ canary property skill list --property <id> # see what's already authored, if anything
141
+ ```
142
+ If the property isn't linked to this repo (or to no repo at all), stop and link it first (see prerequisite above).
143
+
144
+ 2. **Capture provenance.** Grab the current commit SHA so the items carry "authored from `<repo>@<sha>`":
145
+ ```bash
146
+ SHA=$(git rev-parse HEAD)
147
+ SOURCE_ID="$(gh repo view --json nameWithOwner -q .nameWithOwner)@$SHA"
148
+ ```
149
+
150
+ 3. **Author in your editor, not in shell.** Assemble a `bundle.json`:
151
+ ```json
152
+ {
153
+ "items": [
154
+ { "section": "navigation", "itemKey": "url_grammar", "itemLabel": "URL grammar",
155
+ "content": "URLs follow /<entity-type>/<id> for list and detail…" },
156
+ …
157
+ ]
158
+ }
159
+ ```
160
+ Keep item content as plain prose — it ships verbatim into the runtime agent's system prompt.
161
+
162
+ 4. **Diff before write.** Compare against what's already there so you don't churn identical content:
163
+ ```bash
164
+ canary property skill list --property <id> --format json
165
+ ```
166
+
167
+ 5. **Import.** One call writes the whole bundle:
168
+ ```bash
169
+ canary property skill import --property <id> --file bundle.json --source-id "$SOURCE_ID"
170
+ ```
171
+ Append-only versioning makes re-runs safe.
172
+
173
+ 6. **Verify.** Skim the result and re-apply the translation check on three random items:
174
+ ```bash
175
+ canary property skill list --property <id>
176
+ canary property skill export --property <id> --format md
177
+ ```
178
+
179
+ ## Anti-patterns
180
+
181
+ - **Citing implementation.** No file paths, internal symbols, hook/component/middleware names, table names, or design-system component conventions (e.g. "DataTable", "Sheet", "PageHeader"). The runtime agent sees DOM, not your library. Library *families* are OK in `technology` ("React with a react-aria-based UI kit") because they inform interaction patterns; named internal components in any other section are not. If you're tempted to write "see X," ask what X *does* and write that.
182
+ - **Enumeration that goes stale.** Every flag. Every URL. Every error code. The runtime agent doesn't need the inventory; it needs the model.
183
+ - **Speculation.** If you can't observe it and the code doesn't show it, don't write it. Empty is better than wrong.
184
+ - **Vague gotchas.** "Be careful with X" without a concrete cue is useless. Either describe what the agent sees and when, or drop it.
185
+ - **One mega-item.** Each item is one focused topic with one stable key. Six small items beat one sprawling one.
186
+
187
+ ## What good looks like
188
+
189
+ A reviewer reading your output should be able to predict, for a specific QA scenario, exactly which observable signals the runtime agent will use to make pass/fail judgments — and what the agent should do when something looks off — without ever opening the repo. If a section reads like a README, it failed. If it reads like a field guide for someone using the app blind, it's right.
@@ -0,0 +1,115 @@
1
+ import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);
2
+ import {
3
+ fetchOrExit
4
+ } from "./chunk-3CZU7XCS.js";
5
+ import {
6
+ resolveConfig
7
+ } from "./chunk-A4OFTUVV.js";
8
+ import "./chunk-VKVL7WBN.js";
9
+
10
+ // src/psql.ts
11
+ import process from "process";
12
+ var MAX_QUERY_SIZE = 1e4;
13
+ function getArgValue(argv, key) {
14
+ const index = argv.indexOf(key);
15
+ if (index === -1 || index >= argv.length - 1) return void 0;
16
+ return argv[index + 1];
17
+ }
18
+ function hasFlag(argv, ...flags) {
19
+ return flags.some((flag) => argv.includes(flag));
20
+ }
21
+ function formatTable(data) {
22
+ if (data.length === 0) return "(0 rows)";
23
+ const columns = Object.keys(data[0]);
24
+ const widths = columns.map(
25
+ (col) => Math.max(col.length, ...data.map((row) => String(row[col] ?? "").length))
26
+ );
27
+ const header = columns.map((col, i) => col.padEnd(widths[i])).join(" | ");
28
+ const separator = widths.map((w) => "-".repeat(w)).join("-+-");
29
+ const rows = data.map(
30
+ (row) => columns.map((col, i) => String(row[col] ?? "").padEnd(widths[i])).join(" | ")
31
+ );
32
+ return [header, separator, ...rows, `(${data.length} rows)`].join("\n");
33
+ }
34
+ async function runPsql(argv) {
35
+ const { apiUrl, token } = await resolveConfig(argv);
36
+ const jsonOutput = hasFlag(argv, "--json");
37
+ let query = getArgValue(argv, "--query");
38
+ if (!query) {
39
+ const flagsWithValues = ["--api-url", "--token", "--query", "--env"];
40
+ const queryParts = [];
41
+ for (let i = 0; i < argv.length; i++) {
42
+ if (flagsWithValues.includes(argv[i])) {
43
+ i++;
44
+ continue;
45
+ }
46
+ if (argv[i].startsWith("--")) continue;
47
+ queryParts.push(argv[i]);
48
+ }
49
+ query = queryParts.join(" ");
50
+ }
51
+ if (!query) {
52
+ console.error("Error: No query provided.");
53
+ console.error("");
54
+ console.error("Usage: canary psql <query> [--json]");
55
+ console.error(' canary psql --query "SELECT * FROM users LIMIT 10"');
56
+ console.error("");
57
+ console.error("Examples:");
58
+ console.error(" canary psql SELECT id, status FROM jobs LIMIT 5");
59
+ console.error(` canary psql "SELECT * FROM jobs WHERE status = 'running'" --json`);
60
+ process.exit(1);
61
+ }
62
+ if (query.length > MAX_QUERY_SIZE) {
63
+ console.error(`Error: Query too large (${query.length} chars, max ${MAX_QUERY_SIZE})`);
64
+ console.error("For large queries, consider using psql directly with appropriate credentials.");
65
+ process.exit(1);
66
+ }
67
+ try {
68
+ const res = await fetchOrExit(`${apiUrl}/superadmin/psql`, {
69
+ method: "POST",
70
+ headers: {
71
+ Authorization: `Bearer ${token}`,
72
+ "Content-Type": "application/json"
73
+ },
74
+ token,
75
+ body: JSON.stringify({ query })
76
+ });
77
+ if (!res.ok) {
78
+ const text = await res.text();
79
+ if (res.status === 404) {
80
+ console.error("Error: Endpoint not found. The psql feature may not be deployed to this environment.");
81
+ process.exit(1);
82
+ }
83
+ try {
84
+ const errorJson = JSON.parse(text);
85
+ console.error(`Error: ${errorJson.error ?? text}`);
86
+ } catch {
87
+ console.error(`Error (${res.status}): ${text || res.statusText}`);
88
+ }
89
+ process.exit(1);
90
+ }
91
+ const json = await res.json();
92
+ if (!json.ok) {
93
+ console.error(`Error: ${json.error}`);
94
+ process.exit(1);
95
+ }
96
+ if (jsonOutput) {
97
+ console.log(JSON.stringify(json.data, null, 2));
98
+ } else {
99
+ console.log(formatTable(json.data ?? []));
100
+ if (json.truncated) {
101
+ console.log(`
102
+ Note: Results truncated to ${json.rowCount} rows`);
103
+ }
104
+ console.log(`
105
+ Time: ${json.durationMs}ms`);
106
+ }
107
+ } catch (err) {
108
+ console.error(`Failed to execute query: ${err}`);
109
+ process.exit(1);
110
+ }
111
+ }
112
+ export {
113
+ runPsql
114
+ };
115
+ //# sourceMappingURL=psql-BYUUNLGG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/psql.ts"],"sourcesContent":["/**\n * CLI PSQL Passthrough\n *\n * Allows superadmins to execute read-only SQL queries against the production database.\n */\n\nimport process from \"node:process\";\nimport { resolveConfig } from \"./auth.js\";\nimport { fetchOrExit } from \"./api-fetch.js\";\n\nconst MAX_QUERY_SIZE = 10_000; // 10KB - reasonable for interactive use\n\ntype PsqlResponse = {\n ok: boolean;\n data?: Record<string, unknown>[];\n rowCount?: number;\n truncated?: boolean;\n durationMs?: number;\n error?: string;\n};\n\nfunction getArgValue(argv: string[], key: string): string | undefined {\n const index = argv.indexOf(key);\n if (index === -1 || index >= argv.length - 1) return undefined;\n return argv[index + 1];\n}\n\nfunction hasFlag(argv: string[], ...flags: string[]): boolean {\n return flags.some((flag) => argv.includes(flag));\n}\n\n/**\n * Formats query results as a psql-style table.\n */\nfunction formatTable(data: Record<string, unknown>[]): string {\n if (data.length === 0) return \"(0 rows)\";\n\n const columns = Object.keys(data[0]);\n\n // Calculate column widths\n const widths = columns.map((col) =>\n Math.max(col.length, ...data.map((row) => String(row[col] ?? \"\").length))\n );\n\n // Build header\n const header = columns.map((col, i) => col.padEnd(widths[i])).join(\" | \");\n const separator = widths.map((w) => \"-\".repeat(w)).join(\"-+-\");\n\n // Build rows\n const rows = data.map((row) =>\n columns.map((col, i) => String(row[col] ?? \"\").padEnd(widths[i])).join(\" | \")\n );\n\n return [header, separator, ...rows, `(${data.length} rows)`].join(\"\\n\");\n}\n\nexport async function runPsql(argv: string[]): Promise<void> {\n const { apiUrl, token } = await resolveConfig(argv);\n\n const jsonOutput = hasFlag(argv, \"--json\");\n\n // Get query: either --query value or remaining args joined\n let query = getArgValue(argv, \"--query\");\n if (!query) {\n // Filter out flags and their values\n const flagsWithValues = [\"--api-url\", \"--token\", \"--query\", \"--env\"];\n const queryParts: string[] = [];\n for (let i = 0; i < argv.length; i++) {\n if (flagsWithValues.includes(argv[i])) {\n i++; // Skip flag value\n continue;\n }\n if (argv[i].startsWith(\"--\")) continue;\n queryParts.push(argv[i]);\n }\n query = queryParts.join(\" \");\n }\n\n if (!query) {\n console.error(\"Error: No query provided.\");\n console.error(\"\");\n console.error(\"Usage: canary psql <query> [--json]\");\n console.error(' canary psql --query \"SELECT * FROM users LIMIT 10\"');\n console.error(\"\");\n console.error(\"Examples:\");\n console.error(\" canary psql SELECT id, status FROM jobs LIMIT 5\");\n console.error(' canary psql \"SELECT * FROM jobs WHERE status = \\'running\\'\" --json');\n process.exit(1);\n }\n\n if (query.length > MAX_QUERY_SIZE) {\n console.error(`Error: Query too large (${query.length} chars, max ${MAX_QUERY_SIZE})`);\n console.error(\"For large queries, consider using psql directly with appropriate credentials.\");\n process.exit(1);\n }\n\n try {\n const res = await fetchOrExit(`${apiUrl}/superadmin/psql`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n token,\n body: JSON.stringify({ query }),\n });\n\n // Handle HTTP errors before parsing JSON\n if (!res.ok) {\n const text = await res.text();\n\n if (res.status === 404) {\n console.error(\"Error: Endpoint not found. The psql feature may not be deployed to this environment.\");\n process.exit(1);\n }\n\n // Try to parse error as JSON, fallback to raw text\n try {\n const errorJson = JSON.parse(text) as { error?: string };\n console.error(`Error: ${errorJson.error ?? text}`);\n } catch {\n console.error(`Error (${res.status}): ${text || res.statusText}`);\n }\n process.exit(1);\n }\n\n const json = (await res.json()) as PsqlResponse;\n\n if (!json.ok) {\n console.error(`Error: ${json.error}`);\n process.exit(1);\n }\n\n if (jsonOutput) {\n console.log(JSON.stringify(json.data, null, 2));\n } else {\n console.log(formatTable(json.data ?? []));\n if (json.truncated) {\n console.log(`\\nNote: Results truncated to ${json.rowCount} rows`);\n }\n console.log(`\\nTime: ${json.durationMs}ms`);\n }\n } catch (err) {\n console.error(`Failed to execute query: ${err}`);\n process.exit(1);\n }\n}\n"],"mappings":"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","names":[]}