@runcofactor/cli 0.10.0 → 0.15.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.
- package/dist/account-22LMP5PX.js +255 -0
- package/dist/account-22LMP5PX.js.map +1 -0
- package/dist/{api-catalog-GFGCLVS4.js → api-catalog-WTFQNLK6.js} +5 -4
- package/dist/{api-catalog-GFGCLVS4.js.map → api-catalog-WTFQNLK6.js.map} +1 -1
- package/dist/{attachment-SJC7D7FY.js → attachment-U3NKVPEY.js} +5 -4
- package/dist/{attachment-SJC7D7FY.js.map → attachment-U3NKVPEY.js.map} +1 -1
- package/dist/augmentor-5GMNAX4M.js +198 -0
- package/dist/augmentor-5GMNAX4M.js.map +1 -0
- package/dist/{auth-EN6NQCJY.js → auth-VQG2CDUD.js} +3 -2
- package/dist/{chunk-A4OFTUVV.js → chunk-3X3NW7QA.js} +7 -4
- package/dist/chunk-3X3NW7QA.js.map +1 -0
- package/dist/{chunk-N7HFALX3.js → chunk-46IUJXSD.js} +2 -2
- package/dist/{chunk-IMPZAX6L.js → chunk-5GD47G2D.js} +37 -1
- package/dist/{chunk-IMPZAX6L.js.map → chunk-5GD47G2D.js.map} +1 -1
- package/dist/{chunk-B2VISN2V.js → chunk-7VMO2WOZ.js} +238 -68
- package/dist/chunk-7VMO2WOZ.js.map +1 -0
- package/dist/{chunk-QFDOWABX.js → chunk-CMGI7UZD.js} +6 -3
- package/dist/chunk-CMGI7UZD.js.map +1 -0
- package/dist/{chunk-XQXVG7RA.js → chunk-FNPMWDUQ.js} +3 -3
- package/dist/chunk-G4UYGRZR.js +2 -0
- package/dist/{chunk-I4QLI3JO.js → chunk-HDFYUFBI.js} +2 -2
- package/dist/chunk-JMJVGMXI.js +92 -0
- package/dist/chunk-JMJVGMXI.js.map +1 -0
- package/dist/{chunk-SJJW77WN.js → chunk-JYGNMKZ5.js} +129 -38
- package/dist/chunk-JYGNMKZ5.js.map +1 -0
- package/dist/{chunk-52IO7ACJ.js → chunk-KCHKFYVX.js} +68 -10
- package/dist/{chunk-52IO7ACJ.js.map → chunk-KCHKFYVX.js.map} +1 -1
- package/dist/{chunk-ZD3KHESI.js → chunk-KRWRUU6R.js} +27 -7
- package/dist/chunk-KRWRUU6R.js.map +1 -0
- package/dist/{chunk-CLAWT7BJ.js → chunk-NHTEKEYE.js} +3 -3
- package/dist/{chunk-WOHL4FTB.js → chunk-PRBRSIZP.js} +16 -10
- package/dist/chunk-PRBRSIZP.js.map +1 -0
- package/dist/{chunk-GKY2KXO5.js → chunk-UETBLPKM.js} +154 -37
- package/dist/chunk-UETBLPKM.js.map +1 -0
- package/dist/{chunk-4PNOV7OV.js → chunk-VGYN2KU2.js} +9284 -1421
- package/dist/chunk-VGYN2KU2.js.map +1 -0
- package/dist/{chunk-Q4BO4Z5V.js → chunk-XJ5YYYGC.js} +4 -4
- package/dist/{credential-COLTBV6D.js → credential-E6KUHRGU.js} +24 -20
- package/dist/credential-E6KUHRGU.js.map +1 -0
- package/dist/{credential-template-EEPYFG7R.js → credential-template-4GPOPBGD.js} +30 -28
- package/dist/credential-template-4GPOPBGD.js.map +1 -0
- package/dist/{debug-workflow-KOVH5GOP.js → debug-workflow-XCLCY6S7.js} +5 -4
- package/dist/{debug-workflow-KOVH5GOP.js.map → debug-workflow-XCLCY6S7.js.map} +1 -1
- package/dist/{docs-3SSORHB5.js → docs-COCZYMW6.js} +95 -10
- package/dist/docs-COCZYMW6.js.map +1 -0
- package/dist/{doctor-OTSIWV6G.js → doctor-ERIVTCQS.js} +9 -5
- package/dist/doctor-ERIVTCQS.js.map +1 -0
- package/dist/environment-7Y4BV6XY.js +221 -0
- package/dist/environment-7Y4BV6XY.js.map +1 -0
- package/dist/{feature-flag-T2LRZME3.js → feature-flag-MHONEX6T.js} +164 -16
- package/dist/feature-flag-MHONEX6T.js.map +1 -0
- package/dist/index.js +123 -58
- package/dist/index.js.map +1 -1
- package/dist/{init-TGWRECT2.js → init-OROOM4HF.js} +5 -4
- package/dist/{init-TGWRECT2.js.map → init-OROOM4HF.js.map} +1 -1
- package/dist/{install-DXSNWZKO.js → install-OJFXHY6U.js} +7 -7
- package/dist/{issues-XIZOPX6T.js → issues-32GONR6C.js} +5 -4
- package/dist/{issues-XIZOPX6T.js.map → issues-32GONR6C.js.map} +1 -1
- package/dist/{knobs-NBINZIUB.js → knobs-UQGGY3CP.js} +7 -5
- package/dist/knobs-UQGGY3CP.js.map +1 -0
- package/dist/{list-3TDHK637.js → list-ZMIKEC5P.js} +5 -4
- package/dist/{list-3TDHK637.js.map → list-ZMIKEC5P.js.map} +1 -1
- package/dist/{local-HICVD6PU.js → local-PUD24GGQ.js} +7 -6
- package/dist/{local-HICVD6PU.js.map → local-PUD24GGQ.js.map} +1 -1
- package/dist/{login-UOIUXVUK.js → login-BSO7YX2D.js} +5 -4
- package/dist/{login-UOIUXVUK.js.map → login-BSO7YX2D.js.map} +1 -1
- package/dist/{mcp-54IJEOUA.js → mcp-4LS7OJUT.js} +24 -25
- package/dist/mcp-4LS7OJUT.js.map +1 -0
- package/dist/{pdf-extract-ABWV3L5X.js → pdf-extract-YHE54XU4.js} +2 -2
- package/dist/product-3JKSJCBC.js +346 -0
- package/dist/product-3JKSJCBC.js.map +1 -0
- package/dist/{property-UXLOLPTD.js → property-K5DBL4UE.js} +76 -4
- package/dist/property-K5DBL4UE.js.map +1 -0
- package/dist/{psql-BYUUNLGG.js → psql-PQFUFTSE.js} +3 -2
- package/dist/{psql-BYUUNLGG.js.map → psql-PQFUFTSE.js.map} +1 -1
- package/dist/{record-4TR2UIIS.js → record-EIIYLFJ4.js} +16 -17
- package/dist/record-EIIYLFJ4.js.map +1 -0
- package/dist/{redis-35VBUYW7.js → redis-BU36EZZI.js} +3 -2
- package/dist/redis-BU36EZZI.js.map +1 -0
- package/dist/{release-OOLTUBUT.js → release-LYC2P7DZ.js} +5 -4
- package/dist/{release-OOLTUBUT.js.map → release-LYC2P7DZ.js.map} +1 -1
- package/dist/{sandbox-XGSUU6G7.js → sandbox-CKHXXZHU.js} +55 -10
- package/dist/sandbox-CKHXXZHU.js.map +1 -0
- package/dist/{scenarios-GWLJEGHA.js → scenarios-2XJ2G3KR.js} +5 -4
- package/dist/{scenarios-GWLJEGHA.js.map → scenarios-2XJ2G3KR.js.map} +1 -1
- package/dist/{session-MYFNZPRP.js → session-UTOD5ZYH.js} +77 -10
- package/dist/session-UTOD5ZYH.js.map +1 -0
- package/dist/{skill-KM34LDMO.js → skill-GMAERMQL.js} +220 -70
- package/dist/skill-GMAERMQL.js.map +1 -0
- package/dist/skills/debug-run/SKILL.md +40 -23
- package/dist/skills/debug-run/history/1.2.0.md +262 -0
- package/dist/skills/debug-run/history/1.3.0.md +273 -0
- package/dist/skills/debug-run/history/1.3.1.md +279 -0
- package/dist/skills/debug-run/version.json +1 -1
- package/dist/skills/optimize-cache/SKILL.md +233 -0
- package/dist/{spec-RA3CFEKG.js → spec-2NP36U3Y.js} +54 -25
- package/dist/spec-2NP36U3Y.js.map +1 -0
- package/dist/{src-LB4HBTJQ.js → src-4T6GHXVO.js} +19 -11
- package/dist/src-4T6GHXVO.js.map +1 -0
- package/dist/{src-N3TPKGTY.js → src-CG52HEE7.js} +10 -7
- package/dist/{src-UVDX5UP6.js → src-PK5OZXCM.js} +4 -2
- package/dist/src-UEOOC425.js +5941 -0
- package/dist/src-UEOOC425.js.map +1 -0
- package/dist/{start-PSEQSQA3.js → start-3C7EEFW2.js} +5 -4
- package/dist/{start-PSEQSQA3.js.map → start-3C7EEFW2.js.map} +1 -1
- package/dist/{tag-YY6YAABQ.js → tag-JSHOMLBR.js} +6 -5
- package/dist/{task-IQC3YR5K.js → task-YGWVYTBJ.js} +5 -4
- package/dist/{task-IQC3YR5K.js.map → task-YGWVYTBJ.js.map} +1 -1
- package/dist/{test-suite-DZNJFXDW.js → test-suite-LI7ZH367.js} +12 -7
- package/dist/{test-suite-DZNJFXDW.js.map → test-suite-LI7ZH367.js.map} +1 -1
- package/dist/trace-UMLOSIIR.js +16 -0
- package/dist/{triage-ORG45R5W.js → triage-ZWJG4NBJ.js} +6 -5
- package/dist/triage-ZWJG4NBJ.js.map +1 -0
- package/dist/{upgrade-L2VYMP2V.js → upgrade-S7CGEK6H.js} +3 -3
- package/dist/{workflow-XYFH5LTP.js → workflow-T4HSAOGW.js} +316 -241
- package/dist/workflow-T4HSAOGW.js.map +1 -0
- package/dist/{workflow-cache-NQJQFWMV.js → workflow-cache-XVEZ36KF.js} +140 -7
- package/dist/workflow-cache-XVEZ36KF.js.map +1 -0
- package/dist/{workflow-debug-BGD4UIXU.js → workflow-debug-T2BULXZ7.js} +9 -8
- package/dist/{workflow-debug-BGD4UIXU.js.map → workflow-debug-T2BULXZ7.js.map} +1 -1
- package/dist/{workflow-proposals-MTUDX46O.js → workflow-proposals-XXEZICN2.js} +5 -6
- package/dist/workflow-proposals-XXEZICN2.js.map +1 -0
- package/package.json +2 -1
- package/dist/chunk-4PNOV7OV.js.map +0 -1
- package/dist/chunk-A4OFTUVV.js.map +0 -1
- package/dist/chunk-B2VISN2V.js.map +0 -1
- package/dist/chunk-GKY2KXO5.js.map +0 -1
- package/dist/chunk-JICSYFRJ.js +0 -46
- package/dist/chunk-JICSYFRJ.js.map +0 -1
- package/dist/chunk-QFDOWABX.js.map +0 -1
- package/dist/chunk-SJJW77WN.js.map +0 -1
- package/dist/chunk-WOHL4FTB.js.map +0 -1
- package/dist/chunk-ZD3KHESI.js.map +0 -1
- package/dist/credential-COLTBV6D.js.map +0 -1
- package/dist/credential-template-EEPYFG7R.js.map +0 -1
- package/dist/docs-3SSORHB5.js.map +0 -1
- package/dist/doctor-OTSIWV6G.js.map +0 -1
- package/dist/feature-flag-T2LRZME3.js.map +0 -1
- package/dist/knobs-NBINZIUB.js.map +0 -1
- package/dist/mcp-54IJEOUA.js.map +0 -1
- package/dist/property-UXLOLPTD.js.map +0 -1
- package/dist/record-4TR2UIIS.js.map +0 -1
- package/dist/redis-35VBUYW7.js.map +0 -1
- package/dist/sandbox-XGSUU6G7.js.map +0 -1
- package/dist/session-MYFNZPRP.js.map +0 -1
- package/dist/skill-KM34LDMO.js.map +0 -1
- package/dist/spec-RA3CFEKG.js.map +0 -1
- package/dist/src-LB4HBTJQ.js.map +0 -1
- package/dist/trace-HXIW7U2D.js +0 -14
- package/dist/workflow-XYFH5LTP.js.map +0 -1
- package/dist/workflow-cache-NQJQFWMV.js.map +0 -1
- package/dist/workflow-proposals-MTUDX46O.js.map +0 -1
- /package/dist/{auth-EN6NQCJY.js.map → auth-VQG2CDUD.js.map} +0 -0
- /package/dist/{chunk-N7HFALX3.js.map → chunk-46IUJXSD.js.map} +0 -0
- /package/dist/{chunk-XQXVG7RA.js.map → chunk-FNPMWDUQ.js.map} +0 -0
- /package/dist/{pdf-extract-ABWV3L5X.js.map → chunk-G4UYGRZR.js.map} +0 -0
- /package/dist/{chunk-I4QLI3JO.js.map → chunk-HDFYUFBI.js.map} +0 -0
- /package/dist/{chunk-CLAWT7BJ.js.map → chunk-NHTEKEYE.js.map} +0 -0
- /package/dist/{chunk-Q4BO4Z5V.js.map → chunk-XJ5YYYGC.js.map} +0 -0
- /package/dist/{install-DXSNWZKO.js.map → install-OJFXHY6U.js.map} +0 -0
- /package/dist/{src-N3TPKGTY.js.map → pdf-extract-YHE54XU4.js.map} +0 -0
- /package/dist/{src-UVDX5UP6.js.map → src-CG52HEE7.js.map} +0 -0
- /package/dist/{tag-YY6YAABQ.js.map → src-PK5OZXCM.js.map} +0 -0
- /package/dist/{trace-HXIW7U2D.js.map → tag-JSHOMLBR.js.map} +0 -0
- /package/dist/{triage-ORG45R5W.js.map → trace-UMLOSIIR.js.map} +0 -0
- /package/dist/{upgrade-L2VYMP2V.js.map → upgrade-S7CGEK6H.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/login.ts"],"sourcesContent":["import process from \"node:process\";\nimport readline from \"node:readline\";\nimport { spawn } from \"node:child_process\";\nimport { saveAuth, ENV_URLS, envToProfile, getArgValue } from \"./auth\";\nimport { readBrandEnv } from \"./brand.js\";\n\nexport type StartResponse = {\n ok: boolean;\n deviceCode?: string;\n userCode?: string;\n verificationUrl?: string;\n expiresAt?: string;\n intervalSeconds?: number;\n error?: string;\n};\n\nexport type PollResponse = {\n ok: boolean;\n status?: \"pending\" | \"approved\" | \"rejected\" | \"expired\";\n accessToken?: string;\n orgId?: string;\n error?: string;\n};\n\nexport type OrgsResponse = {\n ok: boolean;\n currentOrgId?: string;\n organizations?: Array<{ id: string; name: string; role: string }>;\n error?: string;\n};\n\nexport type SwitchOrgResponse = {\n ok: boolean;\n accessToken?: string;\n orgId?: string;\n orgName?: string;\n role?: string;\n error?: string;\n};\n\nfunction shouldOpenBrowser(argv: string[]): boolean {\n return !argv.includes(\"--no-open\");\n}\n\nexport function openUrl(url: string) {\n const platform = process.platform;\n if (platform === \"darwin\") {\n spawn(\"open\", [url], { stdio: \"ignore\" });\n return;\n }\n if (platform === \"win32\") {\n spawn(\"cmd\", [\"/c\", \"start\", \"\", url], { stdio: \"ignore\" });\n return;\n }\n spawn(\"xdg-open\", [url], { stdio: \"ignore\" });\n}\n\nfunction promptChoice(question: string): Promise<string> {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\nexport async function fetchOrgs(apiUrl: string, token: string): Promise<OrgsResponse | null> {\n try {\n const res = await fetch(`${apiUrl}/cli-login/orgs`, {\n headers: { Authorization: `Bearer ${token}` },\n });\n if (!res.ok) return null;\n return (await res.json()) as OrgsResponse;\n } catch {\n return null;\n }\n}\n\nexport async function switchOrg(apiUrl: string, token: string, orgId: string): Promise<SwitchOrgResponse> {\n const res = await fetch(`${apiUrl}/cli-login/switch-org`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ orgId }),\n });\n return (await res.json()) as SwitchOrgResponse;\n}\n\nexport async function runLogin(argv: string[]) {\n const env = getArgValue(argv, \"--env\");\n const envUrls = env ? ENV_URLS[env] : undefined;\n\n if (env && !envUrls) {\n console.error(`Unknown environment: ${env}`);\n console.error(\"Valid environments: prod, dev, local\");\n process.exit(1);\n }\n\n const apiUrl =\n getArgValue(argv, \"--api-url\") ??\n envUrls?.api ??\n readBrandEnv(\"CANARY_API_URL\") ??\n \"https://api.trycanary.ai\";\n const appUrl =\n getArgValue(argv, \"--app-url\") ??\n envUrls?.app ??\n process.env.CANARY_APP_URL ??\n \"https://app.trycanary.ai\";\n\n const orgFlag = getArgValue(argv, \"--org\");\n\n const startRes = await fetch(`${apiUrl}/cli-login/start`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ appUrl }),\n });\n\n const startJson = (await startRes.json()) as StartResponse;\n if (!startRes.ok || !startJson.ok || !startJson.deviceCode || !startJson.userCode) {\n console.error(\"Login start failed\", startJson.error ?? startRes.statusText);\n process.exit(1);\n }\n\n console.log(\"Login required.\");\n console.log(`User code: ${startJson.userCode}`);\n if (startJson.verificationUrl) {\n console.log(`Open: ${startJson.verificationUrl}`);\n if (shouldOpenBrowser(argv)) {\n try {\n openUrl(startJson.verificationUrl);\n } catch {\n console.log(\"Unable to open browser automatically. Please open the URL manually.\");\n }\n }\n }\n\n const intervalMs = (startJson.intervalSeconds ?? 3) * 1000;\n const expiresAt = startJson.expiresAt ? new Date(startJson.expiresAt).getTime() : null;\n\n let token: string | undefined;\n let initialOrgId: string | undefined;\n\n while (true) {\n if (expiresAt && Date.now() > expiresAt) {\n console.error(\"Login code expired.\");\n process.exit(1);\n }\n\n await new Promise((resolve) => setTimeout(resolve, intervalMs));\n\n const pollRes = await fetch(`${apiUrl}/cli-login/poll`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ deviceCode: startJson.deviceCode }),\n });\n\n const pollJson = (await pollRes.json()) as PollResponse;\n if (!pollRes.ok || !pollJson.ok) {\n console.error(\"Login poll failed\", pollJson.error ?? pollRes.statusText);\n process.exit(1);\n }\n\n if (pollJson.status === \"approved\" && pollJson.accessToken) {\n token = pollJson.accessToken;\n initialOrgId = pollJson.orgId;\n break;\n }\n\n if (pollJson.status === \"rejected\") {\n console.error(\"Login rejected.\");\n process.exit(1);\n }\n\n if (pollJson.status === \"expired\") {\n console.error(\"Login expired.\");\n process.exit(1);\n }\n }\n\n // Fetch user's organizations (gracefully skip if endpoint not available)\n const orgsData = await fetchOrgs(apiUrl, token);\n const orgs = orgsData?.organizations ?? [];\n\n let finalToken = token;\n let finalOrgId = initialOrgId;\n let finalOrgName: string | undefined;\n\n if (orgs.length <= 1) {\n // Single org (or none) — use as-is\n finalOrgName = orgs[0]?.name;\n } else {\n // Multiple orgs — determine which one to use\n let selectedOrg: (typeof orgs)[number] | undefined;\n\n if (orgFlag) {\n // Match --org flag by name (case-insensitive) or ID\n selectedOrg = orgs.find(\n (o) => o.name.toLowerCase() === orgFlag.toLowerCase() || o.id === orgFlag\n );\n if (!selectedOrg) {\n console.error(`Organization \"${orgFlag}\" not found. Available orgs:`);\n for (const o of orgs) {\n console.error(` - ${o.name} (${o.id})`);\n }\n process.exit(1);\n }\n } else if (process.stdin.isTTY) {\n // Interactive prompt\n console.log(\"\\nYou belong to multiple organizations. Select one:\");\n for (let i = 0; i < orgs.length; i++) {\n const marker = orgs[i].id === initialOrgId ? \" (current)\" : \"\";\n console.log(` ${i + 1}. ${orgs[i].name}${marker}`);\n }\n\n const answer = await promptChoice(`\\nChoice [1-${orgs.length}]: `);\n const idx = parseInt(answer, 10) - 1;\n if (isNaN(idx) || idx < 0 || idx >= orgs.length) {\n console.error(\"Invalid selection.\");\n process.exit(1);\n }\n selectedOrg = orgs[idx];\n } else {\n // Non-interactive — use default from JWT\n const defaultOrg = orgs.find((o) => o.id === initialOrgId);\n console.log(\n `Warning: Multiple organizations available but running non-interactively. Using \"${defaultOrg?.name ?? initialOrgId}\".`\n );\n console.log('Tip: Use --org <name> to select a specific organization.');\n selectedOrg = defaultOrg;\n }\n\n if (selectedOrg && selectedOrg.id !== initialOrgId) {\n // Switch to selected org\n const switchRes = await switchOrg(apiUrl, token, selectedOrg.id);\n if (!switchRes.ok || !switchRes.accessToken) {\n console.error(\"Failed to switch organization:\", switchRes.error ?? \"Unknown error\");\n process.exit(1);\n }\n finalToken = switchRes.accessToken;\n finalOrgId = switchRes.orgId;\n finalOrgName = switchRes.orgName;\n } else if (selectedOrg) {\n finalOrgName = selectedOrg.name;\n }\n }\n\n const profileName = env ? envToProfile(env) : undefined;\n const filePath = await saveAuth({ token: finalToken, apiUrl, orgId: finalOrgId, orgName: finalOrgName }, profileName);\n const displayName = finalOrgName ? ` to ${finalOrgName}` : \"\";\n const profileLabel = profileName ? ` (profile: ${profileName})` : \"\";\n console.log(`Login successful${displayName}${profileLabel}. Token saved to ${filePath}`);\n console.log(\"Set CANARY_API_TOKEN to use the CLI without re-login.\");\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
apiRequest
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-PRBRSIZP.js";
|
|
5
5
|
import {
|
|
6
6
|
getArgValue,
|
|
7
7
|
hasFlag,
|
|
8
8
|
resolveConfig
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-3X3NW7QA.js";
|
|
10
10
|
|
|
11
11
|
// src/tag.ts
|
|
12
12
|
import process from "process";
|
|
@@ -423,4 +423,4 @@ export {
|
|
|
423
423
|
applyWorkflowTagFlags,
|
|
424
424
|
runTag
|
|
425
425
|
};
|
|
426
|
-
//# sourceMappingURL=chunk-
|
|
426
|
+
//# sourceMappingURL=chunk-FNPMWDUQ.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
PlaywrightClient
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-VGYN2KU2.js";
|
|
5
5
|
|
|
6
6
|
// src/local-browser/host.ts
|
|
7
7
|
var HEARTBEAT_INTERVAL_MS = 3e4;
|
|
@@ -410,4 +410,4 @@ export {
|
|
|
410
410
|
LocalBrowserHost,
|
|
411
411
|
USER_PAUSED_ERROR
|
|
412
412
|
};
|
|
413
|
-
//# sourceMappingURL=chunk-
|
|
413
|
+
//# sourceMappingURL=chunk-HDFYUFBI.js.map
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);
|
|
2
|
+
|
|
3
|
+
// src/brand.ts
|
|
4
|
+
import { createRequire } from "module";
|
|
5
|
+
import path from "path";
|
|
6
|
+
import process from "process";
|
|
7
|
+
var require2 = createRequire(import.meta.url);
|
|
8
|
+
var pkg = require2("../package.json");
|
|
9
|
+
function resolveBrandFromArgv(argv1) {
|
|
10
|
+
if (argv1) {
|
|
11
|
+
const base = path.basename(argv1).replace(/\.[^./\\]+$/, "").toLowerCase();
|
|
12
|
+
if (base.includes("cofactor")) return "cofactor";
|
|
13
|
+
}
|
|
14
|
+
return "canary";
|
|
15
|
+
}
|
|
16
|
+
var command = resolveBrandFromArgv(process.argv[1]);
|
|
17
|
+
var packageName = pkg.name;
|
|
18
|
+
var version = pkg.version;
|
|
19
|
+
var INVOCATION_RE = /(^|[^\w-])canary(?= [a-z])/g;
|
|
20
|
+
var PROSE_RE = /\bCanary\b/g;
|
|
21
|
+
function brandTextFor(text, brand) {
|
|
22
|
+
if (brand === "canary") return text;
|
|
23
|
+
const display = brand === "cofactor" ? "Cofactor" : "Canary";
|
|
24
|
+
return text.replace(INVOCATION_RE, (_m, prefix) => `${prefix}${brand}`).replace(PROSE_RE, display);
|
|
25
|
+
}
|
|
26
|
+
function brandText(text) {
|
|
27
|
+
return brandTextFor(text, command);
|
|
28
|
+
}
|
|
29
|
+
function brandSkillContentFor(content, brand) {
|
|
30
|
+
const base = brandTextFor(content, brand);
|
|
31
|
+
if (brand !== "cofactor") return base;
|
|
32
|
+
return base.replace(/`canary`/g, "`cofactor`").replace(/@canaryai\/cli/g, "@runcofactor/cli").replace(/\bCANARY_/g, "COFACTOR_").replace(/trycanary\.ai/g, "runcofactor.com");
|
|
33
|
+
}
|
|
34
|
+
function readBrandEnvFor(canaryName, brand, env = process.env) {
|
|
35
|
+
const cofactorName = canaryName.replace(/^CANARY_/, "COFACTOR_");
|
|
36
|
+
const order = brand === "cofactor" ? [cofactorName, canaryName] : [canaryName, cofactorName];
|
|
37
|
+
for (const name of order) {
|
|
38
|
+
const value = env[name];
|
|
39
|
+
if (value !== null && value !== void 0 && value !== "") return value;
|
|
40
|
+
}
|
|
41
|
+
return void 0;
|
|
42
|
+
}
|
|
43
|
+
function readBrandEnv(canaryName, env = process.env) {
|
|
44
|
+
return readBrandEnvFor(canaryName, command, env);
|
|
45
|
+
}
|
|
46
|
+
var SPEC_EXTENSIONS = [".cofactor.md", ".canary.md"];
|
|
47
|
+
var SPEC_DIRS = ["cofactor", "canary"];
|
|
48
|
+
function specExtensionFor(brand) {
|
|
49
|
+
return brand === "cofactor" ? ".cofactor.md" : ".canary.md";
|
|
50
|
+
}
|
|
51
|
+
function specDirFor(brand) {
|
|
52
|
+
return path.join(brand === "cofactor" ? "cofactor" : "canary", "specs");
|
|
53
|
+
}
|
|
54
|
+
var specExtension = specExtensionFor(command);
|
|
55
|
+
var specDir = specDirFor(command);
|
|
56
|
+
function readableSpecDirs() {
|
|
57
|
+
return SPEC_DIRS.map((root) => path.join(root, "specs"));
|
|
58
|
+
}
|
|
59
|
+
function isSpecFile(name) {
|
|
60
|
+
return SPEC_EXTENSIONS.some((ext) => name.endsWith(ext));
|
|
61
|
+
}
|
|
62
|
+
function splitSpecExtension(name) {
|
|
63
|
+
for (const ext of SPEC_EXTENSIONS) {
|
|
64
|
+
if (name.endsWith(ext)) return { base: name.slice(0, -ext.length), ext };
|
|
65
|
+
}
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
function installConsoleBranding() {
|
|
69
|
+
if (command === "canary") return;
|
|
70
|
+
const methods = ["log", "error", "warn", "info"];
|
|
71
|
+
for (const method of methods) {
|
|
72
|
+
const original = console[method].bind(console);
|
|
73
|
+
console[method] = (...args) => {
|
|
74
|
+
original(...args.map((arg) => typeof arg === "string" ? brandText(arg) : arg));
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export {
|
|
80
|
+
command,
|
|
81
|
+
packageName,
|
|
82
|
+
version,
|
|
83
|
+
brandSkillContentFor,
|
|
84
|
+
readBrandEnv,
|
|
85
|
+
specExtension,
|
|
86
|
+
specDir,
|
|
87
|
+
readableSpecDirs,
|
|
88
|
+
isSpecFile,
|
|
89
|
+
splitSpecExtension,
|
|
90
|
+
installConsoleBranding
|
|
91
|
+
};
|
|
92
|
+
//# sourceMappingURL=chunk-JMJVGMXI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/brand.ts"],"sourcesContent":["/**\n * Brand resolution for the dual-published CLI.\n *\n * We ship a single build to two npm packages:\n * - `@canaryai/cli` → binary `canary` (legacy brand)\n * - `@runcofactor/cli` → binary `cofactor` (new brand)\n *\n * Both packages contain the identical artifact; they differ only in their\n * `name` and `bin` map (rewritten at publish time — see\n * `.github/workflows/publish-canary-cli.yml`). Everything brand-specific is\n * therefore derived at runtime:\n *\n * - `command` comes from the invoked binary name (`basename(process.argv[1])`),\n * so output reflects how the user called it (`brandText` rewrites legacy\n * `canary` display strings to the active brand).\n * - `packageName` comes from the installed package's own `package.json`, so\n * self-upgrade and the update check target whatever package was installed.\n *\n * The legacy `canary` brand is the default for every non-`cofactor` invocation\n * (`node dist/index.js`, dev scripts, tests), which keeps existing behaviour\n * byte-for-byte unchanged.\n *\n * @module\n */\n\nimport { createRequire } from 'node:module';\nimport path from 'node:path';\nimport process from 'node:process';\n\nconst require = createRequire(import.meta.url);\nconst pkg = require('../package.json') as { name: string; version: string };\n\nexport type Brand = 'canary' | 'cofactor';\n\n/**\n * Resolve the brand from the invoked binary path (`process.argv[1]`). The\n * global-install shim is named `canary` or `cofactor` (npm/bun/pnpm bin link),\n * so the basename is the brand. Everything else (`node dist/index.js`, dev\n * scripts, tests) defaults to the legacy `canary` brand. Pure for testing.\n */\nexport function resolveBrandFromArgv(argv1: string | undefined): Brand {\n if (argv1) {\n const base = path.basename(argv1).replace(/\\.[^./\\\\]+$/, '').toLowerCase();\n if (base.includes('cofactor')) return 'cofactor';\n }\n return 'canary';\n}\n\n/** The invoked command / binary name, e.g. `canary` or `cofactor`. */\nexport const command: Brand = resolveBrandFromArgv(process.argv[1]);\n\n/** npm package name of the installed CLI, read from its own package.json. */\nexport const packageName: string = pkg.name;\n\n/** CLI version, read from package.json. */\nexport const version: string = pkg.version;\n\n/**\n * Rewrite display strings authored against the legacy `canary` brand to the\n * active brand. Identity for the `canary` brand (so legacy output never\n * changes). Two precise, word-anchored rules:\n *\n * 1. The invocation token `canary ` followed by a lowercase letter (i.e. a\n * sub-command or `canary v1.2.3`). Anchored on a non-word, non-hyphen\n * boundary so it never touches `trycanary.ai`, `x-canary-request-id`,\n * `canary-cli`, or `CANARY_API_TOKEN`.\n * 2. The prose noun `Canary` (capitalized, standalone word) → display name.\n */\nconst INVOCATION_RE = /(^|[^\\w-])canary(?= [a-z])/g;\nconst PROSE_RE = /\\bCanary\\b/g;\n\n/** Pure brand rewrite for a given target brand. Identity for `canary`. */\nexport function brandTextFor(text: string, brand: Brand): string {\n if (brand === 'canary') return text;\n const display = brand === 'cofactor' ? 'Cofactor' : 'Canary';\n return text\n .replace(INVOCATION_RE, (_m, prefix: string) => `${prefix}${brand}`)\n .replace(PROSE_RE, display);\n}\n\nfunction brandText(text: string): string {\n return brandTextFor(text, command);\n}\n\n/**\n * Rewrite a bundled skill template's content to the target brand for the\n * `canary skill install` / `canary skill <name>` output. Builds on\n * {@link brandTextFor} (invocation tokens + the prose noun) and additionally\n * maps the brand-specific identifiers that {@link brandTextFor} deliberately\n * leaves intact for console output — but which a distributed skill file must\n * carry per brand:\n *\n * - inline binary: `` `canary` `` → `` `cofactor` `` (a backtick-wrapped bare\n * binary reference, e.g. \"the `canary` CLI\" — `brandTextFor` only rewrites\n * `canary <subcommand>` invocations, not the standalone binary name)\n * - npm package: `@canaryai/cli` → `@runcofactor/cli`\n * - env prefix: `CANARY_*` → `COFACTOR_*`\n * - domains: `*.trycanary.ai` → `*.runcofactor.com`\n *\n * Identity for the `canary` brand, so legacy skill text installs byte-for-byte\n * unchanged. The skill's frontmatter `name:` is never an invocation/prose/token\n * match (it's `canary-basic`, hyphenated), so the install directory key is\n * preserved. Trigger keywords in prose (e.g. \"mentions canary, canary CLI\")\n * intentionally keep the legacy term so the skill still activates for users who\n * say \"canary\". Pure (brand injectable).\n */\nexport function brandSkillContentFor(content: string, brand: Brand): string {\n const base = brandTextFor(content, brand);\n if (brand !== 'cofactor') return base;\n return base\n .replace(/`canary`/g, '`cofactor`')\n .replace(/@canaryai\\/cli/g, '@runcofactor/cli')\n .replace(/\\bCANARY_/g, 'COFACTOR_')\n .replace(/trycanary\\.ai/g, 'runcofactor.com');\n}\n\n/**\n * Read a brand-prefixed environment variable, accepting EITHER brand's prefix.\n *\n * The two published brands historically diverged: the binary only ever read the\n * legacy `CANARY_*` names, but the cofactor docs tell users to set `COFACTOR_*`\n * (e.g. `COFACTOR_API_TOKEN`). This bridges that gap — a value set under either\n * prefix is honoured regardless of which binary (`canary` / `cofactor`) was\n * invoked. When both are set, the active brand's prefix wins.\n *\n * `canaryName` is the legacy `CANARY_`-prefixed name; the `COFACTOR_` variant is\n * derived from it. Empty strings are treated as unset so a blank value can't\n * shadow a real one set under the other prefix. Pure (brand + env injectable).\n */\nexport function readBrandEnvFor(\n canaryName: string,\n brand: Brand,\n env: NodeJS.ProcessEnv = process.env,\n): string | undefined {\n const cofactorName = canaryName.replace(/^CANARY_/, 'COFACTOR_');\n const order = brand === 'cofactor' ? [cofactorName, canaryName] : [canaryName, cofactorName];\n for (const name of order) {\n const value = env[name];\n if (value !== null && value !== undefined && value !== '') return value;\n }\n return undefined;\n}\n\n/** Read a brand-prefixed env var for the active brand. See {@link readBrandEnvFor}. */\nexport function readBrandEnv(\n canaryName: string,\n env: NodeJS.ProcessEnv = process.env,\n): string | undefined {\n return readBrandEnvFor(canaryName, command, env);\n}\n\n/**\n * Workflow spec file convention — brand-aware, backwards compatible.\n *\n * The spec extension and default directory follow the active brand: the\n * `cofactor` binary writes `.cofactor.md` into `cofactor/specs`, the legacy\n * `canary` binary writes `.canary.md` into `canary/specs` (byte-for-byte\n * unchanged). Reading/discovery always accepts BOTH — {@link SPEC_EXTENSIONS}\n * and {@link SPEC_DIRS} list every recognized variant (newest brand first), so\n * an existing `.canary.md` repo keeps working under either binary.\n */\nexport const SPEC_EXTENSIONS = ['.cofactor.md', '.canary.md'] as const;\n\n/**\n * Default spec-directory roots, newest brand first. Each is used as\n * `<root>/specs`. The ordering is a precedence contract: consumers that merge\n * across roots (e.g. `pull --all`) must treat earlier entries as higher\n * priority, so the active/new brand's copy wins over a legacy one.\n */\nexport const SPEC_DIRS = ['cofactor', 'canary'] as const;\n\n/** Spec-file extension to WRITE for a given brand. See {@link SPEC_EXTENSIONS}. */\nexport function specExtensionFor(brand: Brand): string {\n return brand === 'cofactor' ? '.cofactor.md' : '.canary.md';\n}\n\n/** Default spec directory (`<root>/specs`) to WRITE into for a given brand. */\nexport function specDirFor(brand: Brand): string {\n return path.join(brand === 'cofactor' ? 'cofactor' : 'canary', 'specs');\n}\n\n/** Spec-file extension to WRITE for the active brand. See {@link specExtensionFor}. */\nexport const specExtension: string = specExtensionFor(command);\n\n/** Default spec directory to WRITE into for the active brand. See {@link specDirFor}. */\nexport const specDir: string = specDirFor(command);\n\n/**\n * Every spec directory to READ from, highest precedence first — `<root>/specs`\n * for each {@link SPEC_DIRS} root. This is the single source of the spec-dir\n * convention for discovery; consumers merge across these in order (first-seen\n * wins) so the active brand's copy beats a legacy one. Brand-independent: a\n * `cofactor` run still discovers an existing `canary/specs` repo, and vice\n * versa.\n */\nexport function readableSpecDirs(): string[] {\n return SPEC_DIRS.map((root) => path.join(root, 'specs'));\n}\n\n/** True if `name` ends with any recognized spec extension (either brand). */\nexport function isSpecFile(name: string): boolean {\n return SPEC_EXTENSIONS.some((ext) => name.endsWith(ext));\n}\n\n/**\n * Split a recognized spec extension off `name`, returning `{ base, ext }` for\n * the first matching {@link SPEC_EXTENSIONS} entry, or `null` if none match.\n * Lets callers derive sibling names (e.g. `.stamped`) without assuming a brand.\n */\nexport function splitSpecExtension(name: string): { base: string; ext: string } | null {\n for (const ext of SPEC_EXTENSIONS) {\n if (name.endsWith(ext)) return { base: name.slice(0, -ext.length), ext };\n }\n return null;\n}\n\n/**\n * Install brand rewriting over the `console` methods used for human-readable\n * output. No-op for the `canary` brand. Skipped by the caller for machine\n * output (`--json`/`--format`) and the `mcp` JSON-RPC transport, where rewriting\n * could corrupt structured payloads — display branding only.\n */\nexport function installConsoleBranding(): void {\n if (command === 'canary') return;\n const methods = ['log', 'error', 'warn', 'info'] as const;\n for (const method of methods) {\n const original = console[method].bind(console);\n console[method] = (...args: unknown[]) => {\n original(...args.map((arg) => (typeof arg === 'string' ? brandText(arg) : arg)));\n };\n }\n}\n"],"mappings":"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","names":["require"]}
|
|
@@ -3,7 +3,7 @@ import { createRequire as __cr } from "module"; const require = __cr(import.meta
|
|
|
3
3
|
// ../types/src/workflows.ts
|
|
4
4
|
var USER_SETTABLE_WORKFLOW_STATUSES = [
|
|
5
5
|
"draft",
|
|
6
|
-
"
|
|
6
|
+
"approved"
|
|
7
7
|
];
|
|
8
8
|
|
|
9
9
|
// ../types/src/sandbox-instance-size.ts
|
|
@@ -86,6 +86,7 @@ var NODE_TYPE_LABEL = {
|
|
|
86
86
|
notification: "Notification",
|
|
87
87
|
audio: "Audio input",
|
|
88
88
|
"audio-assertion": "Audio assertion",
|
|
89
|
+
sandbox_action: "Sandbox action",
|
|
89
90
|
end: "End"
|
|
90
91
|
};
|
|
91
92
|
function normalizeNodeType(input) {
|
|
@@ -94,7 +95,7 @@ function normalizeNodeType(input) {
|
|
|
94
95
|
}
|
|
95
96
|
|
|
96
97
|
// ../types/src/index.ts
|
|
97
|
-
import { z as
|
|
98
|
+
import { z as z6 } from "zod";
|
|
98
99
|
|
|
99
100
|
// ../types/src/credentials.ts
|
|
100
101
|
import { z } from "zod";
|
|
@@ -171,11 +172,6 @@ var TLDR_LIMIT = 512;
|
|
|
171
172
|
var URL_LIMIT = 2048;
|
|
172
173
|
var STORAGE_KEY_LIMIT = 1024;
|
|
173
174
|
var DIAGNOSTIC_LIMIT = 4e3;
|
|
174
|
-
var NarrationTranscriptSegmentSchema = z2.object({
|
|
175
|
-
startMs: z2.number().int().min(0),
|
|
176
|
-
endMs: z2.number().int().min(1),
|
|
177
|
-
text: z2.string().min(1)
|
|
178
|
-
});
|
|
179
175
|
var RecordIssueOccurrencePayloadSchema = z2.object({
|
|
180
176
|
orgId: UUID,
|
|
181
177
|
propertyId: UUID,
|
|
@@ -205,8 +201,6 @@ var RecordIssueOccurrencePayloadSchema = z2.object({
|
|
|
205
201
|
videoStorageKey: optionalLimitedString(STORAGE_KEY_LIMIT),
|
|
206
202
|
/** Action timeline for video overlay synchronization */
|
|
207
203
|
videoTimelineJson: z2.unknown().optional().nullable(),
|
|
208
|
-
/** Timed narration transcript for video overlay */
|
|
209
|
-
narrationTranscriptJson: z2.array(NarrationTranscriptSegmentSchema).optional().nullable(),
|
|
210
204
|
consoleLogExcerpt: optionalLimitedString(DIAGNOSTIC_LIMIT),
|
|
211
205
|
networkFailureUrl: optionalLimitedString(URL_LIMIT),
|
|
212
206
|
networkFailureStatus: z2.number().int().optional().nullable().transform((value) => value ?? null),
|
|
@@ -231,6 +225,21 @@ var benchmarkWorkflowSuiteConfigSchema = z3.object({
|
|
|
231
225
|
sendSlackSummary: z3.boolean().optional()
|
|
232
226
|
});
|
|
233
227
|
|
|
228
|
+
// ../types/src/api-sequence.ts
|
|
229
|
+
import { z as z4 } from "zod";
|
|
230
|
+
var ValidationOperatorSchema = z4.enum([
|
|
231
|
+
"equals",
|
|
232
|
+
"not_equals",
|
|
233
|
+
"gt",
|
|
234
|
+
"lt",
|
|
235
|
+
"gte",
|
|
236
|
+
"lte",
|
|
237
|
+
"contains",
|
|
238
|
+
"not_contains",
|
|
239
|
+
"is_set",
|
|
240
|
+
"is_not_set"
|
|
241
|
+
]);
|
|
242
|
+
|
|
234
243
|
// ../types/src/sandbox-tasks.ts
|
|
235
244
|
var CHECKLIST_ITEMS = [
|
|
236
245
|
{
|
|
@@ -439,13 +448,14 @@ var MACRO_CATALOG = [
|
|
|
439
448
|
];
|
|
440
449
|
var VALID_MACRO_NAMES = new Set(MACRO_CATALOG.map((m) => m.name));
|
|
441
450
|
var MACRO_ARG_COUNTS = new Map(MACRO_CATALOG.map((m) => [m.name, m.args.length]));
|
|
451
|
+
var MACRO_PATTERN = /(?<!\\)\$([A-Z_]+)\(([^)]*)\)/g;
|
|
442
452
|
|
|
443
453
|
// ../types/src/workflow-node-schemas.ts
|
|
444
|
-
import { z as
|
|
445
|
-
var FormFieldSchema =
|
|
446
|
-
name:
|
|
447
|
-
label:
|
|
448
|
-
type:
|
|
454
|
+
import { z as z5 } from "zod";
|
|
455
|
+
var FormFieldSchema = z5.object({
|
|
456
|
+
name: z5.string().describe('Unique field identifier (snake_case, e.g., "search_query", "recipient_email")'),
|
|
457
|
+
label: z5.string().describe('Human-friendly label (e.g., "Search Query", "Recipient Email")'),
|
|
458
|
+
type: z5.enum([
|
|
449
459
|
"text",
|
|
450
460
|
"email",
|
|
451
461
|
"password",
|
|
@@ -456,16 +466,38 @@ var FormFieldSchema = z4.object({
|
|
|
456
466
|
"multiselect",
|
|
457
467
|
"file"
|
|
458
468
|
]).optional().describe('Input type, defaults to "text"'),
|
|
459
|
-
required:
|
|
460
|
-
value:
|
|
461
|
-
options:
|
|
469
|
+
required: z5.boolean().optional().describe("Whether this field is required"),
|
|
470
|
+
value: z5.string().describe("The value to use for this field"),
|
|
471
|
+
options: z5.array(z5.object({ value: z5.string(), label: z5.string() })).optional().describe("If type is select/multiselect, provide allowed options here")
|
|
472
|
+
});
|
|
473
|
+
var AssertionSeverityEnum = z5.enum(["warn", "fail", "fatal"]);
|
|
474
|
+
var InlineAssertionSchema = z5.object({
|
|
475
|
+
condition: z5.string().describe("What to verify after the action"),
|
|
476
|
+
severity: AssertionSeverityEnum.describe(
|
|
477
|
+
"fatal = stop the test immediately on failure, fail = mark the run failed but keep going, warn = log a warning and continue (run still passes)"
|
|
478
|
+
),
|
|
479
|
+
agentic: z5.boolean().optional().describe("true if requires visual/complex evaluation that cannot be cached")
|
|
462
480
|
});
|
|
463
|
-
var
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
481
|
+
var ConditionSubjectSchema = z5.discriminatedUnion("kind", [
|
|
482
|
+
z5.object({
|
|
483
|
+
kind: z5.literal("variable"),
|
|
484
|
+
name: z5.string().describe('Input/variable name, e.g. "count" for $var.count')
|
|
485
|
+
}),
|
|
486
|
+
z5.object({
|
|
487
|
+
kind: z5.literal("acting_as")
|
|
488
|
+
})
|
|
489
|
+
]);
|
|
490
|
+
var ConditionPredicateSchema = z5.object({
|
|
491
|
+
subject: ConditionSubjectSchema,
|
|
492
|
+
operator: ValidationOperatorSchema,
|
|
493
|
+
/**
|
|
494
|
+
* Right-hand operand. For a `variable` subject this is a literal (or `$var`
|
|
495
|
+
* reference); for `acting_as` it is a credential template id. Omitted for the
|
|
496
|
+
* unary operators `is_set` / `is_not_set`.
|
|
497
|
+
*/
|
|
498
|
+
value: z5.string().optional()
|
|
467
499
|
});
|
|
468
|
-
var NodeTypeEnum =
|
|
500
|
+
var NodeTypeEnum = z5.enum([
|
|
469
501
|
"login",
|
|
470
502
|
"navigate",
|
|
471
503
|
"action",
|
|
@@ -478,7 +510,8 @@ var NodeTypeEnum = z4.enum([
|
|
|
478
510
|
"end",
|
|
479
511
|
"notification",
|
|
480
512
|
"audio",
|
|
481
|
-
"audio-assertion"
|
|
513
|
+
"audio-assertion",
|
|
514
|
+
"sandbox_action"
|
|
482
515
|
]);
|
|
483
516
|
|
|
484
517
|
// ../types/src/browser-viewport.ts
|
|
@@ -493,6 +526,60 @@ var BROWSER_VIEWPORT_PRESET_KEYS = Object.keys(
|
|
|
493
526
|
BROWSER_VIEWPORT_PRESETS
|
|
494
527
|
);
|
|
495
528
|
|
|
529
|
+
// ../types/src/identifier-stability.ts
|
|
530
|
+
var FRAMEWORK_PREFIX_RE = /^(?::r[0-9a-z]+:?$|radix-|headlessui-|mantine-|react-aria-|react-select-|rc-|menu-v-\d)/i;
|
|
531
|
+
var BARE_HASH_RE = /^[a-f0-9]{8,}$/i;
|
|
532
|
+
var PREFIX_HASH_RE = /^[a-z]+-[0-9a-f]{6,}$/i;
|
|
533
|
+
var UUID_RE = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i;
|
|
534
|
+
var ULID_RE = /\b[0-9A-HJKMNP-TV-Z]{26}\b/i;
|
|
535
|
+
var DIGIT_RUN_RE = /(?:^|[^0-9A-Za-z])(\d{6,})(?![0-9A-Za-z])/;
|
|
536
|
+
var TRAILING_COUNTER_RE = /[-_](\d{3,})$/;
|
|
537
|
+
var MIN_PREFIX_LEN = 3;
|
|
538
|
+
function usablePrefix(prefix) {
|
|
539
|
+
return prefix.length >= MIN_PREFIX_LEN && /[a-z]/i.test(prefix);
|
|
540
|
+
}
|
|
541
|
+
function earliestVolatileTokenIndex(value) {
|
|
542
|
+
let best = null;
|
|
543
|
+
const consider = (idx) => {
|
|
544
|
+
if (idx !== void 0 && idx >= 0 && (best === null || idx < best)) best = idx;
|
|
545
|
+
};
|
|
546
|
+
consider(UUID_RE.exec(value)?.index);
|
|
547
|
+
consider(ULID_RE.exec(value)?.index);
|
|
548
|
+
const digit = DIGIT_RUN_RE.exec(value);
|
|
549
|
+
if (digit) consider(digit.index + (digit[0].length - digit[1].length));
|
|
550
|
+
const counter = TRAILING_COUNTER_RE.exec(value);
|
|
551
|
+
if (counter) consider(counter.index + 1);
|
|
552
|
+
return best;
|
|
553
|
+
}
|
|
554
|
+
function classifyIdentifier(value) {
|
|
555
|
+
if (!value) return { kind: "volatile" };
|
|
556
|
+
if (FRAMEWORK_PREFIX_RE.test(value) || BARE_HASH_RE.test(value) || PREFIX_HASH_RE.test(value)) {
|
|
557
|
+
return { kind: "volatile" };
|
|
558
|
+
}
|
|
559
|
+
const tokenIdx = earliestVolatileTokenIndex(value);
|
|
560
|
+
if (tokenIdx !== null) {
|
|
561
|
+
const prefix = value.slice(0, tokenIdx);
|
|
562
|
+
return usablePrefix(prefix) ? { kind: "stable-prefix", prefix } : { kind: "volatile" };
|
|
563
|
+
}
|
|
564
|
+
return { kind: "stable" };
|
|
565
|
+
}
|
|
566
|
+
function isVolatileIdentifier(value) {
|
|
567
|
+
return classifyIdentifier(value).kind !== "stable";
|
|
568
|
+
}
|
|
569
|
+
function stableIdentifierPrefix(value) {
|
|
570
|
+
const c = classifyIdentifier(value);
|
|
571
|
+
return c.kind === "stable-prefix" ? c.prefix : null;
|
|
572
|
+
}
|
|
573
|
+
function escapeCssAttrValue(value) {
|
|
574
|
+
return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
575
|
+
}
|
|
576
|
+
function stableAttrSelector(attr, value) {
|
|
577
|
+
const c = classifyIdentifier(value);
|
|
578
|
+
if (c.kind === "stable") return `[${attr}="${escapeCssAttrValue(value)}"]`;
|
|
579
|
+
if (c.kind === "stable-prefix") return `[${attr}^="${escapeCssAttrValue(c.prefix)}"]`;
|
|
580
|
+
return null;
|
|
581
|
+
}
|
|
582
|
+
|
|
496
583
|
// ../types/src/index.ts
|
|
497
584
|
var PLAYBOOK_STEP_ACTIONS = [
|
|
498
585
|
"click",
|
|
@@ -520,24 +607,24 @@ function isPositiveIntegerString(value) {
|
|
|
520
607
|
if (!value || !/^\d+$/.test(value)) return false;
|
|
521
608
|
return Number(value) > 0;
|
|
522
609
|
}
|
|
523
|
-
var playbookStepAgentSchema =
|
|
524
|
-
order:
|
|
525
|
-
action:
|
|
610
|
+
var playbookStepAgentSchema = z6.object({
|
|
611
|
+
order: z6.number().describe("Step number (1-based)."),
|
|
612
|
+
action: z6.enum(PLAYBOOK_STEP_ACTIONS).describe(
|
|
526
613
|
'The type of browser interaction. PREFER DETERMINISTIC VERBS even when verbose \u2014 three deterministic steps beat one agentic step, because deterministic steps replay via Playwright with no agent dispatch. Each replayable playbook step must be 1:1 with an exposed browser tool you actually used and must correspond to zero or one recorded actionRef. If you cannot accomplish the intent with the browser tools you have, do not add a playbook step for it; report the limitation outside playbookSteps. Do not summarize several recorded actions into one "other" step; report the same 1:1 browser primitives you actually used. The only multi-field exception is one fill_form step for one browser_fill_form action. Use "verify" for assertion checks \u2014 both inline assertions and completion assertions proving the action succeeded. Use "verify" for inspection language such as "inspect whether", "confirm", "observe", or "check" when the result is visible in the DOM. Use "capture" instead only when the observed value is needed by later steps. Use "fill" for single-field inputs. Use "fill_form" when browser_fill_form was called to fill multiple fields at once \u2014 one fill_form step per call. Use "click" for checkboxes, switches, toggle buttons, and click-to-focus interactions. There is no separate "toggle" or "focus" action. Use "upload" for file upload actions, including generated CSV/file, attach file, choose file, import file, and document/image attachment intents (browser_action action="upload"). Set params.path to the staged attachment handle, generated file variable, or filename reference used by the upload tool (e.g. {path: "$var.csv_file"}), and include actionRefs pointing to the recorded file_upload action. Do NOT use "other" for file attachment/upload/import intents. Use "scroll" only when scrolling is the user-visible action being tested; routine browser_scroll calls for visibility, inspection, or video framing are observation steps and should usually be omitted from playbookSteps. Use "press_key" for keyboard actions (Enter, Escape, Tab, arrows). Use "press_key" with params.key="Escape" to dismiss a popover, dropdown, panel, or modal when Escape was the recorded action; use "click" if the recorded action clicked a close button or outside target. There is no separate "dismiss" action. Use "drag" for drag-and-drop interactions. Use "resize" when browser_resize was used to resize the viewport. Set params.width and params.height to positive integer pixel values and include the actionRef pointing to the recorded resize action. Use "capture" to extract app-generated values (IDs, codes, URLs) for later steps via $var.name, but only from a visible DOM target or the current URL. Do not capture from performance/network timing, storage, hidden DOM, or app-global state. Use "screenshot" only when browser_screenshot itself is the requested evidence capture. Set params.label when a label was used, optionally params.fullPage="true". Do not use screenshot for routine visual checks after actions; use verify when a browser_assert proves visible state. Use "extract_table" when browser_extract_table was used to extract tabular data from the page. Use "python_execute" when python_execute was used with cache_label to run a data validation script. Use "verify_download" when browser_download(action="list") / browser_list_downloads proves that a file matching some pattern was downloaded. Set params.pattern to a glob (supports *, ?) or substring; optionally params.timeoutMs. This is currently agent-only at replay, so do not set actionRefs. Use "verify_download_content" when browser_download(action="read") / browser_read_download content proves CSV headers, PDF text, exported rows, or similar downloaded-file content. Set params.contains or params.pattern to the expected content predicate. This is currently agent-only at replay, so do not set actionRefs. Use "agent_loop" ONLY when the action set is genuinely unknown until runtime \u2014 variable count of items (e.g. "toggle row checkboxes until 3 selected"), conditional retry that depends on UI state, or a runtime predicate over non-DOM state. Set params.goal to a one-sentence checkable predicate (e.g. params.goal = "3 grid row checkboxes are selected"). DO NOT use agent_loop for: known-N iteration (write N deterministic steps), single click that might double-fire (use "click"), retry-on-flake (the runtime handles that). agent_loop steps replay via a Playwright override authored after first run; they are non-deterministic on first run, so the bar is high. Network/devtools/API inspections and unsupported browser environment mutations are diagnostic-only unless there is an exposed browser tool for the action. If visible page state proves the condition, record that as "verify"; otherwise omit the diagnostic observation from playbookSteps. Do not use "other". If no concrete browser-tool-backed action above fits, omit the observation from playbookSteps and report the limitation outside the playbook.'
|
|
527
614
|
),
|
|
528
|
-
target:
|
|
615
|
+
target: z6.string().describe(
|
|
529
616
|
`Human-readable element description using visible labels, placeholders, or aria-labels. Examples: "'Submit' button", "'Email' input field", "'Status' dropdown". For upload actions, describe the file input and include the attachment name (e.g. "CSV file input for 'testing-checklist.csv'"). Never use coordinates, ref IDs, or internal identifiers.`
|
|
530
617
|
),
|
|
531
|
-
params:
|
|
618
|
+
params: z6.record(z6.string(), z6.string()).optional().describe(
|
|
532
619
|
'Data values using $var.name references and $MACRO() expressions \u2014 NEVER hard-coded literals. Common keys: value (for fill: {value: "$EMAIL()"}), option (for select: {option: "Admin"} \u2014 fixed app constants like dropdown options are allowed as literals), url (for navigate: {url: "$var.target_url"}), path (for upload: {path: "$var.file_path"}), key (for press_key: {key: "Enter"}, {key: "Escape"}), width and height (for resize: {width: "390", height: "844"}), label and fullPage (for screenshot: {label: "seats-table", fullPage: "true"}), pattern or contains (for download verification: {pattern: "report-*.csv"} or {contains: "Expected Header"}), expression + saveAs (for capture: prefer a visible DOM ref expression or "() => window.location.href"; do not use performance.getEntries() or other network/storage/global state; e.g. {saveAs: "order_confirmation_id"}). For fill_form: keys are field names from the fill_form call, values are $var.name or $MACRO() (e.g. {company: "$var.company", email: "$EMAIL()"}). Available macros: $UUID(), $EMAIL(), $FIRST_NAME(), $LAST_NAME(), $PHONE(), $RANDOM_STRING(n), $RANDOM_INT(min,max), $TODAY(), $DATE(days), $NOW(), $TIMESTAMP(), $SEQUENCE("name").'
|
|
533
620
|
),
|
|
534
|
-
note:
|
|
621
|
+
note: z6.string().optional().describe(
|
|
535
622
|
'Timing or quirk notes ONLY (e.g. "Wait 1s for modal animation", "Scroll into view first"). Do NOT put data values, optional markers, or verification notes here.'
|
|
536
623
|
),
|
|
537
|
-
actionRefs:
|
|
624
|
+
actionRefs: z6.array(z6.number()).max(1).optional().describe(
|
|
538
625
|
'Zero or one recorded browser action index that corresponds to this playbook step. Interaction tools, browser_resize, capture evaluates (browser_evaluate with saveAs), and browser_assert produce [Action #N] tags \u2014 collect those indices here. Read-only browser_snapshot and plain browser_evaluate without saveAs do NOT produce action indices. browser_scroll and browser_screenshot may produce action indices when they are the primary requested tool call; omit actionRefs when no action tag was emitted. If you took multiple cacheable UI actions, report multiple 1:1 playbook steps instead of putting multiple refs on one step or summarizing them as "other". A fill_form call is a single action \u2014 use one fill_form playbook step with one actionRef. For a click that triggers a native dialog, keep one click actionRef on the click step and set expectedDialogs rather than adding a separate dialog actionRef. Actions not referenced by any playbook step are considered exploratory and will be discarded by the cache compiler.'
|
|
539
626
|
),
|
|
540
|
-
expectedDialogs:
|
|
627
|
+
expectedDialogs: z6.enum(["accept", "dismiss"]).optional().describe(
|
|
541
628
|
'Set when this step is known to fire a native browser dialog (alert/confirm/prompt) \u2014 e.g. clicking a "Delete" button that prompts "Are you sure?". On replay the runtime pre-arms the dialog handler with this action automatically. In free-form runs, you should call the dialog tool (browser_dialog for consolidated tools, browser_handle_dialog for legacy tools) with this action immediately before the step. Do not add a separate dialog step \u2014 keeping the pre-arm on the triggering step keeps the pre-arm and the triggering action in one place.'
|
|
542
629
|
)
|
|
543
630
|
}).superRefine((step, ctx) => {
|
|
@@ -545,7 +632,7 @@ var playbookStepAgentSchema = z5.object({
|
|
|
545
632
|
const goal = step.params?.goal;
|
|
546
633
|
if (!goal || goal.trim().length === 0) {
|
|
547
634
|
ctx.addIssue({
|
|
548
|
-
code:
|
|
635
|
+
code: z6.ZodIssueCode.custom,
|
|
549
636
|
path: ["params", "goal"],
|
|
550
637
|
message: 'agent_loop steps must set params.goal to a one-sentence checkable predicate (e.g. "3 grid row checkboxes are selected").'
|
|
551
638
|
});
|
|
@@ -555,7 +642,7 @@ var playbookStepAgentSchema = z5.object({
|
|
|
555
642
|
const pattern = step.params?.pattern;
|
|
556
643
|
if (!pattern || pattern.trim().length === 0) {
|
|
557
644
|
ctx.addIssue({
|
|
558
|
-
code:
|
|
645
|
+
code: z6.ZodIssueCode.custom,
|
|
559
646
|
path: ["params", "pattern"],
|
|
560
647
|
message: "verify_download steps must set params.pattern to a glob (supports *, ?) or substring matching the expected filename."
|
|
561
648
|
});
|
|
@@ -566,7 +653,7 @@ var playbookStepAgentSchema = z5.object({
|
|
|
566
653
|
const contains = step.params?.contains;
|
|
567
654
|
if ((!pattern || pattern.trim().length === 0) && (!contains || contains.trim().length === 0)) {
|
|
568
655
|
ctx.addIssue({
|
|
569
|
-
code:
|
|
656
|
+
code: z6.ZodIssueCode.custom,
|
|
570
657
|
path: ["params"],
|
|
571
658
|
message: "verify_download_content steps must set params.contains or params.pattern for the expected downloaded content."
|
|
572
659
|
});
|
|
@@ -577,14 +664,14 @@ var playbookStepAgentSchema = z5.object({
|
|
|
577
664
|
const height = step.params?.height;
|
|
578
665
|
if (!isPositiveIntegerString(width)) {
|
|
579
666
|
ctx.addIssue({
|
|
580
|
-
code:
|
|
667
|
+
code: z6.ZodIssueCode.custom,
|
|
581
668
|
path: ["params", "width"],
|
|
582
669
|
message: "resize steps must set params.width to a positive integer pixel value."
|
|
583
670
|
});
|
|
584
671
|
}
|
|
585
672
|
if (!isPositiveIntegerString(height)) {
|
|
586
673
|
ctx.addIssue({
|
|
587
|
-
code:
|
|
674
|
+
code: z6.ZodIssueCode.custom,
|
|
588
675
|
path: ["params", "height"],
|
|
589
676
|
message: "resize steps must set params.height to a positive integer pixel value."
|
|
590
677
|
});
|
|
@@ -598,8 +685,12 @@ export {
|
|
|
598
685
|
INSTANCE_SIZE_SPEC,
|
|
599
686
|
parseInstanceSize,
|
|
600
687
|
VALID_MACRO_NAMES,
|
|
688
|
+
MACRO_PATTERN,
|
|
601
689
|
InlineAssertionSchema,
|
|
602
690
|
NODE_TYPE_LABEL,
|
|
603
|
-
normalizeNodeType
|
|
691
|
+
normalizeNodeType,
|
|
692
|
+
isVolatileIdentifier,
|
|
693
|
+
stableIdentifierPrefix,
|
|
694
|
+
stableAttrSelector
|
|
604
695
|
};
|
|
605
|
-
//# sourceMappingURL=chunk-
|
|
696
|
+
//# sourceMappingURL=chunk-JYGNMKZ5.js.map
|