@tailor-platform/sdk 2.21.0 → 2.22.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 (53) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/agent-skills/tailor/SKILL.md +3 -1
  3. package/dist/application-BE4vehXW.mjs +1 -0
  4. package/dist/{application-D4913edS.mjs → application-BzO9ywXQ.mjs} +29 -29
  5. package/dist/application-BzO9ywXQ.mjs.map +1 -0
  6. package/dist/cli/commands/deploy/app-id-lock.d.mts +31 -0
  7. package/dist/cli/lib.d.mts +2 -2
  8. package/dist/cli/lib.mjs +1 -1
  9. package/dist/cli/lib.mjs.map +1 -1
  10. package/dist/cli/main.mjs +39 -39
  11. package/dist/cli/main.mjs.map +1 -1
  12. package/dist/cli/shared/logger.d.mts +9 -0
  13. package/dist/cli/shared/tailordb-namespaces.d.mts +1 -1
  14. package/dist/completion/zsh-worker.zsh +1 -1
  15. package/dist/configure/config/index.d.mts +2 -0
  16. package/dist/configure/index.mjs.map +1 -1
  17. package/dist/crashreport-CBaRJl5h.mjs +1 -0
  18. package/dist/{crashreport-BAz-ph5O.mjs → crashreport-DFpRn-LS.mjs} +4 -4
  19. package/dist/{crashreport-BAz-ph5O.mjs.map → crashreport-DFpRn-LS.mjs.map} +1 -1
  20. package/dist/{errors-sNtg2Mv3.mjs → errors-C9zGf4nz.mjs} +2 -2
  21. package/dist/{errors-sNtg2Mv3.mjs.map → errors-C9zGf4nz.mjs.map} +1 -1
  22. package/dist/guards-yDXyKC9F.mjs +2 -0
  23. package/dist/{guards-DsX7dJCP.mjs.map → guards-yDXyKC9F.mjs.map} +1 -1
  24. package/dist/logger-Db-YRTwK.mjs +9 -0
  25. package/dist/logger-Db-YRTwK.mjs.map +1 -0
  26. package/dist/{manager-C0dE7pd0.mjs → manager-8-JOvuLl.mjs} +2 -2
  27. package/dist/{manager-C0dE7pd0.mjs.map → manager-8-JOvuLl.mjs.map} +1 -1
  28. package/dist/plugin/index.mjs +1 -1
  29. package/dist/plugin/index.mjs.map +1 -1
  30. package/dist/{register-ts-hook-YtsAGTMD.mjs → register-ts-hook-z7ggXQy4.mjs} +71 -70
  31. package/dist/register-ts-hook-z7ggXQy4.mjs.map +1 -0
  32. package/dist/seed/index.mjs +7 -6
  33. package/dist/seed/index.mjs.map +1 -1
  34. package/dist/service-Bx-7Lz06.mjs +1 -0
  35. package/dist/{service-BrGSi2IQ.mjs → service-CL1Bp4It.mjs} +3 -3
  36. package/dist/{service-BrGSi2IQ.mjs.map → service-CL1Bp4It.mjs.map} +1 -1
  37. package/dist/{service-8xznUrPU.mjs → service-DHVuH7-X.mjs} +2 -2
  38. package/dist/{service-8xznUrPU.mjs.map → service-DHVuH7-X.mjs.map} +1 -1
  39. package/dist/vitest/mocks/file.d.mts +1 -1
  40. package/docs/cli-reference.md +22 -12
  41. package/docs/configuration.md +1 -1
  42. package/docs/github-actions.md +90 -24
  43. package/docs/migration/v2.md +70 -5
  44. package/docs/plugin/index.md +1 -1
  45. package/package.json +8 -8
  46. package/dist/application-D4913edS.mjs.map +0 -1
  47. package/dist/application-DBHaxmJE.mjs +0 -1
  48. package/dist/crashreport-BfOkOFgc.mjs +0 -1
  49. package/dist/guards-DsX7dJCP.mjs +0 -2
  50. package/dist/logger-Cp5U2IDI.mjs +0 -9
  51. package/dist/logger-Cp5U2IDI.mjs.map +0 -1
  52. package/dist/register-ts-hook-YtsAGTMD.mjs.map +0 -1
  53. package/dist/service-DWMm-4Vm.mjs +0 -1
@@ -1 +0,0 @@
1
- import{n as e,t}from"./application-D4913edS.mjs";export{t as defineApplication,e as generatePluginFilesIfNeeded};
@@ -1 +0,0 @@
1
- import{n as e}from"./crashreport-BAz-ph5O.mjs";export{e as reportCrash};
@@ -1,2 +0,0 @@
1
- function getRawPluginTableName(e){let t=typeof e==`object`&&e&&`name`in e?e.name:void 0;return typeof t==`string`?t:void 0}function getPluginGenerationDependencies(e){let t=/* @__PURE__ */ new Set;return e.onTailorDBReady&&t.add(`tailordb`),e.onResolverReady&&t.add(`resolver`),e.onExecutorReady&&t.add(`executor`),t}function hasGenerationHooks(e){return!!(e.onTailorDBReady||e.onResolverReady||e.onExecutorReady)}function isPluginExecutorWithFile(e){return`resolve`in e&&`context`in e}function isPluginShaped(e){return typeof e==`object`&&!!e&&typeof e.id==`string`&&typeof e.description==`string`}function pickPluginArrays(e){let t=[];for(let n of Object.values(e))Array.isArray(n)&&n.length>0&&n.every(isPluginShaped)&&t.push(n);return t}export{pickPluginArrays as a,isPluginExecutorWithFile as i,getRawPluginTableName as n,hasGenerationHooks as r,getPluginGenerationDependencies as t};
2
- //# sourceMappingURL=guards-DsX7dJCP.mjs.map
@@ -1,9 +0,0 @@
1
- import{formatWithOptions as e,stripVTControlCharacters as t,styleText as n}from"node:util";import{formatDistanceToNowStrict as r}from"date-fns";import{eastAsianWidth as i}from"get-east-asian-width";const style=e=>t=>n(e,t,{validateStream:!1}),a={bold:style(`bold`),dim:style(`dim`),italic:style(`italic`),gray:style(`gray`),white:style(`white`),red:style(`red`),green:style(`green`),yellow:style(`yellow`),cyan:style(`cyan`),magenta:style(`magenta`),redBright:style(`redBright`),greenBright:style(`greenBright`),cyanBright:style(`cyanBright`)},supportsColor=e=>{let t=process.env.FORCE_COLOR;return t===void 0?process.env.NODE_DISABLE_COLORS!==void 0||(process.env.NO_COLOR??``)!==``||process.env.TERM===`dumb`?!1:e.isTTY===!0:t!==`0`&&t!==`false`};function renderFor(e,n){return supportsColor(e)?n:t(n)}const o=/\x1b\[[0-9;]*m/g,s=/\r\n?/g,c=new Intl.Segmenter(void 0,{granularity:`grapheme`});function maxOf(e,t=0){return e.reduce((e,t)=>t>e?t:e,t)}function isStrippableControlCharacter(e){let t=e.codePointAt(0)??0;return e===`
2
- `?!1:t<=31||t===127}function normalizeControlCharacters(e){let t=e.match(o)??[];return e.split(o).map(e=>{let t=[];for(let n of e)n===` `?t.push(` `.repeat(8)):isStrippableControlCharacter(n)||t.push(n);return t.join(``)}).reduce((e,n,r)=>e+n+(t[r]??``),``)}function sanitizeCell(e){return normalizeControlCharacters(String(e??``).replace(s,`
3
- `))}const l=/^(?:\p{Default_Ignorable_Code_Point}|\p{Control}|\p{Format}|\p{Nonspacing_Mark}|\p{Enclosing_Mark}|\p{Surrogate})+$/v,u=/^\p{RGI_Emoji}$/v;function displayWidth(e){let t=0;for(let{segment:n}of c.segment(e.replace(o,``))){if(l.test(n))continue;if(u.test(n)){t+=2;continue}let e=n.codePointAt(0);t+=e===void 0?0:i(e)}return t}function toCellLines(e){return e.split(`
4
- `).map(e=>({text:e,width:displayWidth(e)}))}function padCell(e,t){return e.text+` `.repeat(Math.max(0,t-e.width))}function renderBorder(e,t,n,r){return e+r.map(e=>`─`.repeat(e+2)).join(t)+n}function validateConsistentColumnCount(e){let t=e[0]?.length;t!==void 0&&e.forEach((e,n)=>{if(e.length!==t)throw Error(`renderTable: all rows must have the same number of columns (expected ${t}, row ${n} has ${e.length}).`)})}function renderTable(e,t={}){let n=e.map(e=>e.map(sanitizeCell));validateConsistentColumnCount(n);let r=n.length,i=n[0]?.length??0;if(r===0||i===0)return``;let a=n.map(e=>Array.from({length:i},(t,n)=>toCellLines(e[n]??``))),o=Array.from({length:i},(e,t)=>maxOf(a.map(e=>maxOf((e[t]??[]).map(e=>e.width))))),shouldDrawLine=e=>t.singleLine?e===0||e===r:(t.drawHorizontalLine??(()=>!0))(e,r),s=[];return shouldDrawLine(0)&&s.push(renderBorder(`┌`,`┬`,`┐`,o)),a.forEach((e,t)=>{let n=maxOf(e.map(e=>e.length),1);for(let t=0;t<n;t++){let n=e.map((e,n)=>padCell(e[t]??{text:``,width:0},o[n]??0));s.push(`│ ${n.join(` │ `)} │`)}t<r-1&&shouldDrawLine(t+1)&&s.push(renderBorder(`├`,`┼`,`┤`,o))}),shouldDrawLine(r)&&s.push(renderBorder(`└`,`┴`,`┘`,o)),`${s.join(`
5
- `)}\n`}const d=/* @__PURE__ */ new Set([`true`,`t`,`yes`,`y`,`on`,`1`]),f=/* @__PURE__ */ new Set([`false`,`f`,`no`,`n`,`off`,`0`]);function parseBoolean(e){if(e===void 0)return;let t=e.trim().toLowerCase();if(t!==``){if(d.has(t))return!0;if(f.has(t))return!1}}var CIPromptError=class extends Error{constructor(e){super(e??`Interactive prompts are not available in this environment. Provide the required options explicitly.`),this.name=`CIPromptError`}};const p={success:a.green,error:a.red,warning:a.yellow,info:a.cyan,create:a.green,update:a.yellow,delete:a.red,replace:a.magenta,unchanged:a.gray,bold:a.bold,dim:a.gray,highlight:a.cyanBright,successBright:a.greenBright,errorBright:a.redBright,resourceType:a.bold,resourceName:a.cyan,path:a.cyan,value:a.white,placeholder:e=>a.italic(a.gray(e))},m={success:p.success(`✓`),error:p.error(`✖`),warning:p.warning(`⚠`),info:p.info(`i`),create:p.create(`+`),update:p.update(`~`),delete:p.delete(`-`),replace:p.replace(`±`),bullet:p.dim(`•`),arrow:p.dim(`→`)};let h=!1,g=!1;const _=/* @__PURE__ */ new Set,v=`<redacted>`;function buildAutomaton(e){let t={children:/* @__PURE__ */ new Map,fail:void 0,outputs:[]};t.fail=t;for(let n of e){let e=t;for(let r=0;r<n.length;r++){let i=n[r],a=e.children.get(i);a||(a={children:/* @__PURE__ */ new Map,fail:t,outputs:[]},e.children.set(i,a)),e=a}e.outputs.push(n)}let n=[...t.children.values()];for(let e=0;e<n.length;e++){let r=n[e];for(let[e,i]of r.children){let a=r.fail;for(;a!==t&&!a.children.has(e);)a=a.fail;i.fail=a.children.get(e)??t,i.outputs=i.outputs.concat(i.fail.outputs),n.push(i)}}return t}let y=null;function getAutomaton(){return y??=buildAutomaton(_),y}function findSecretSpans(e){let t=[],n=getAutomaton(),r=n;for(let i=0;i<e.length;i++){let a=e[i];for(;r!==n&&!r.children.has(a);)r=r.fail;r=r.children.get(a)??n;for(let e of r.outputs)t.push([i+1-e.length,i+1])}return t}function redactSecrets(e){if(_.size===0)return e;let t=[];for(let n=0,r;(r=e.indexOf(v,n))!==-1;)t.push([r,r+10]),n=r+10;let n=findSecretSpans(e).filter(([e,n])=>!t.some(([t,r])=>e>=t&&n<=r));if(n.length===0)return e;n.sort(([e],[t])=>e-t);let r=[];for(let e of n){let t=r.at(-1);t&&e[0]<=t[1]?t[1]=Math.max(t[1],e[1]):r.push(e)}let i=``,a=0;for(let[t,n]of r)i+=e.slice(a,t)+v,a=n;return i+e.slice(a)}const b={info:`ℹ`,success:`✔`,warn:`⚠`,error:`✖`,debug:`⚙`,trace:`→`,log:``},x={info:p.info,success:p.success,warn:p.warning,error:p.error,debug:p.dim,trace:p.dim,log:e=>e};function formatLogLine(e){let{mode:t,indent:n,type:r,message:i,timestamp:a}=e,o=n>0?` `.repeat(n):``,s=x[r]||(e=>e);if(t===`plain`)return`${o}${s(i)}\n`;let c=b[r]||``,l=s(`${c?`${c} `:``}${i}`);return`${o}${a??``}${l}\n`}function writeLog(t,n,r){let i=r?.mode??`default`,a=r?.indent??0,o={breakLength:process.stdout.columns||80},s=formatLogLine({mode:i,indent:a,type:t,message:e(o,n),timestamp:i===`stream`?`${(/* @__PURE__ */ new Date()).toLocaleTimeString()} `:``});process.stderr.write(renderFor(process.stderr,redactSecrets(s)))}const S={get jsonMode(){return h},set jsonMode(e){h=e},get verbose(){return g||parseBoolean(process.env.DEBUG)===!0||process.env.RUNNER_DEBUG===`1`},set verbose(e){g=e},info(e,t){writeLog(`info`,e,t)},success(e,t){writeLog(`success`,e,t)},warn(e,t){writeLog(`warn`,e,t)},error(e,t){writeLog(`error`,e,t)},log(e){writeLog(`log`,e,{mode:`plain`})},newline(){process.stderr.write(`
6
- `)},debug(e){S.verbose&&writeLog(`log`,p.dim(e),{mode:`plain`})},registerSecret(e){if(typeof e!=`string`||[...e].length<4)return;let t=_.size;_.add(e);let n=JSON.stringify(e).slice(1,-1);n!==e&&_.add(n);let r=new URLSearchParams([[`v`,e]]).toString().slice(2);r!==e&&_.add(r),_.size!==t&&(y=null)},out(e,t){if(typeof e==`string`){process.stdout.write(renderFor(process.stdout,e.endsWith(`
7
- `)?e:e+`
8
- `));return}if(this.jsonMode){console.log(JSON.stringify(e));return}let n=t?.display,formatValue=(e,n=!1)=>t?.showNull&&e===null?`NULL`:e==null?`N/A`:e instanceof Date?r(e,{addSuffix:!0}):typeof e==`object`?n?JSON.stringify(e,null,2):JSON.stringify(e):String(e),isExcluded=e=>n!==void 0&&e in n&&n[e]===null,transformValue=(e,t,r,i=!1)=>{if(n&&e in n){let i=n[e];if(i)return i(t,r)}return formatValue(t,i)};if(!Array.isArray(e)){let t=renderTable(Object.entries(e).filter(([e])=>!isExcluded(e)).map(([t,n])=>[t,transformValue(t,n,e,!0)]),{singleLine:!1});process.stdout.write(renderFor(process.stdout,t));return}if(e.length===0)return;let i=Array.from(new Set(e.flatMap(e=>Object.keys(e)))).filter(e=>!isExcluded(e));if(i.length===0)return;let a=renderTable([i,...e.map(e=>i.map(t=>transformValue(t,e[t],e)))],{drawHorizontalLine:(e,t)=>e===0||e===1||e===t});process.stdout.write(renderFor(process.stdout,a))}};export{m as a,renderFor as c,p as i,S as n,parseBoolean as o,redactSecrets as r,renderTable as s,CIPromptError as t};
9
- //# sourceMappingURL=logger-Cp5U2IDI.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"logger-Cp5U2IDI.mjs","names":[],"sources":["../../shared/src/color.ts","../src/cli/shared/ascii-table.ts","../src/cli/shared/parse-boolean.ts","../src/cli/shared/logger.ts"],"sourcesContent":["import { stripVTControlCharacters, styleText } from \"node:util\";\n\n/** Applies a style to text */\nexport type StyleFn = (text: string) => string;\n\ntype StyleName = Exclude<Parameters<typeof styleText>[0], readonly unknown[] | unknown[]>;\n\nconst style =\n (name: StyleName): StyleFn =>\n (text) =>\n styleText(name, text, { validateStream: false });\n\n/**\n * Style functions by name, so call sites read `color.bold(text)`. Styling is\n * always applied; `renderFor` drops it again when the destination stream has no\n * color support. Add a name here when a package needs one that is not listed.\n */\nexport const color = {\n bold: style(\"bold\"),\n dim: style(\"dim\"),\n italic: style(\"italic\"),\n gray: style(\"gray\"),\n white: style(\"white\"),\n red: style(\"red\"),\n green: style(\"green\"),\n yellow: style(\"yellow\"),\n cyan: style(\"cyan\"),\n magenta: style(\"magenta\"),\n redBright: style(\"redBright\"),\n greenBright: style(\"greenBright\"),\n cyanBright: style(\"cyanBright\"),\n};\n\n// Node's rules for whether a destination gets colors, applied by hand. Asking\n// styleText instead would be shorter but only correct on Node: Bun ignores both\n// the stream option and NO_COLOR (reproduced on 1.3.14), so it reports every\n// destination as color-capable and escapes end up in redirected output.\n//\n// FORCE_COLOR decides on its own when set, which is how CI keeps colors through\n// a pipe. NO_COLOR counts as set at any non-empty value, \"0\" included.\nconst supportsColor = (stream: NodeJS.WriteStream): boolean => {\n const forced = process.env.FORCE_COLOR;\n if (forced !== undefined) return forced !== \"0\" && forced !== \"false\";\n if (process.env.NODE_DISABLE_COLORS !== undefined) return false;\n if ((process.env.NO_COLOR ?? \"\") !== \"\") return false;\n if (process.env.TERM === \"dumb\") return false;\n return stream.isTTY === true;\n};\n\n/**\n * Prepares styled text for the stream it is written to.\n * @param stream - Stream the text is written to\n * @param text - Styled text\n * @returns Text with styling removed when the stream has no color support\n */\nexport function renderFor(stream: NodeJS.WriteStream, text: string): string {\n return supportsColor(stream) ? text : stripVTControlCharacters(text);\n}\n","import { eastAsianWidth } from \"get-east-asian-width\";\n\n// eslint-disable-next-line no-control-regex\nconst ANSI_ESCAPE_PATTERN = /\\x1b\\[[0-9;]*m/g;\nconst CARRIAGE_RETURN_PATTERN = /\\r\\n?/g;\n\nconst graphemeSegmenter = new Intl.Segmenter(undefined, { granularity: \"grapheme\" });\n\nexport interface AsciiTableConfig {\n /** Suppress horizontal lines between rows, keeping only the outer border. */\n singleLine?: boolean;\n /** Decide whether to draw the horizontal line at `lineIndex` (range `[0, rowCount]` inclusive). */\n drawHorizontalLine?: (lineIndex: number, rowCount: number) => boolean;\n}\n\ninterface CellLine {\n text: string;\n width: number;\n}\n\nfunction maxOf(values: number[], fallback = 0): number {\n return values.reduce((max, value) => (value > max ? value : max), fallback);\n}\n\nconst TAB_WIDTH = 8;\n\nfunction isStrippableControlCharacter(char: string): boolean {\n const codePoint = char.codePointAt(0) ?? 0;\n if (char === \"\\n\") {\n return false;\n }\n return codePoint <= 0x1f || codePoint === 0x7f;\n}\n\n// Only SGR (color/style) escape sequences are meant to survive; a bare ESC\n// that isn't part of a recognized SGR sequence (e.g. a screen-clear CSI\n// sequence, or a BEL-terminated OSC sequence) is treated like any other\n// control character below and stripped, rather than passed through to the\n// terminal or left with its terminator removed.\nfunction normalizeControlCharacters(value: string): string {\n const sgrSequences = value.match(ANSI_ESCAPE_PATTERN) ?? [];\n return value\n .split(ANSI_ESCAPE_PATTERN)\n .map((segment) => {\n const chars: string[] = [];\n for (const char of segment) {\n if (char === \"\\t\") {\n chars.push(\" \".repeat(TAB_WIDTH));\n } else if (!isStrippableControlCharacter(char)) {\n chars.push(char);\n }\n }\n return chars.join(\"\");\n })\n .reduce((result, segment, i) => result + segment + (sgrSequences[i] ?? \"\"), \"\");\n}\n\nfunction sanitizeCell(cell: unknown): string {\n return normalizeControlCharacters(String(cell ?? \"\").replace(CARRIAGE_RETURN_PATTERN, \"\\n\"));\n}\n\n// Clusters made up entirely of non-printing code points (lone joiners,\n// variation selectors, combining marks, etc.) render with no visible glyph.\nconst ZERO_WIDTH_CLUSTER_PATTERN =\n /^(?:\\p{Default_Ignorable_Code_Point}|\\p{Control}|\\p{Format}|\\p{Nonspacing_Mark}|\\p{Enclosing_Mark}|\\p{Surrogate})+$/v;\n// RGI_Emoji covers flags, keycaps, and VS16-forced presentation sequences,\n// which render as 2 columns in terminals even though their first code point\n// alone would measure as narrow/neutral.\nconst RGI_EMOJI_PATTERN = /^\\p{RGI_Emoji}$/v;\n\nfunction displayWidth(value: string): number {\n let width = 0;\n for (const { segment } of graphemeSegmenter.segment(value.replace(ANSI_ESCAPE_PATTERN, \"\"))) {\n if (ZERO_WIDTH_CLUSTER_PATTERN.test(segment)) {\n continue;\n }\n if (RGI_EMOJI_PATTERN.test(segment)) {\n width += 2;\n continue;\n }\n const codePoint = segment.codePointAt(0);\n width += codePoint === undefined ? 0 : eastAsianWidth(codePoint);\n }\n return width;\n}\n\nfunction toCellLines(cell: string): CellLine[] {\n return cell.split(\"\\n\").map((text) => ({ text, width: displayWidth(text) }));\n}\n\nfunction padCell(cellLine: CellLine, width: number): string {\n return cellLine.text + \" \".repeat(Math.max(0, width - cellLine.width));\n}\n\nfunction renderBorder(left: string, join: string, right: string, columnWidths: number[]): string {\n return left + columnWidths.map((width) => \"─\".repeat(width + 2)).join(join) + right;\n}\n\nfunction validateConsistentColumnCount(rows: string[][]): void {\n const columnCount = rows[0]?.length;\n if (columnCount === undefined) {\n return;\n }\n rows.forEach((row, index) => {\n if (row.length !== columnCount) {\n throw new Error(\n `renderTable: all rows must have the same number of columns (expected ${columnCount}, row ${index} has ${row.length}).`,\n );\n }\n });\n}\n\n/**\n * Renders a 2D array of values as a table using single-line Unicode box-drawing borders.\n * Column widths account for East Asian wide characters (measured per grapheme cluster,\n * so combining marks and ZWJ emoji sequences aren't overcounted, non-printing clusters\n * such as a lone joiner or combining mark measure as 0, and flags, keycaps, and\n * VS16-forced emoji presentation are measured as 2 columns) and strip ANSI SGR (color/style)\n * escape codes before measuring. Use this instead of importing a table-rendering package\n * directly.\n * @param data - Table rows; every row must have the same number of columns. Each cell is\n * stringified (`null`/`undefined` become an empty string rather than the literal text\n * \"null\"/\"undefined\"), may contain embedded newlines, has `\\r`/`\\r\\n` normalized to `\\n`,\n * has tabs expanded to spaces, and has other control characters stripped.\n * @param config - Rendering options\n * @returns The rendered table terminated with a trailing newline, or `\"\"` when there are no\n * rows or no columns to display\n */\nexport function renderTable(data: unknown[][], config: AsciiTableConfig = {}): string {\n const rows = data.map((row) => row.map(sanitizeCell));\n validateConsistentColumnCount(rows);\n\n const rowCount = rows.length;\n const columnCount = rows[0]?.length ?? 0;\n if (rowCount === 0 || columnCount === 0) {\n return \"\";\n }\n\n const rowsCellLines = rows.map((row) =>\n Array.from({ length: columnCount }, (_, col) => toCellLines(row[col] ?? \"\")),\n );\n const columnWidths = Array.from({ length: columnCount }, (_, col) =>\n maxOf(rowsCellLines.map((row) => maxOf((row[col] ?? []).map((line) => line.width)))),\n );\n\n const shouldDrawLine = (lineIndex: number): boolean =>\n config.singleLine\n ? lineIndex === 0 || lineIndex === rowCount\n : (config.drawHorizontalLine ?? (() => true))(lineIndex, rowCount);\n\n const lines: string[] = [];\n if (shouldDrawLine(0)) {\n lines.push(renderBorder(\"┌\", \"┬\", \"┐\", columnWidths));\n }\n\n rowsCellLines.forEach((cellLines, rowIndex) => {\n const rowHeight = maxOf(\n cellLines.map((columnLines) => columnLines.length),\n 1,\n );\n for (let line = 0; line < rowHeight; line++) {\n const cells = cellLines.map((columnLines, col) =>\n padCell(columnLines[line] ?? { text: \"\", width: 0 }, columnWidths[col] ?? 0),\n );\n lines.push(`│ ${cells.join(\" │ \")} │`);\n }\n if (rowIndex < rowCount - 1 && shouldDrawLine(rowIndex + 1)) {\n lines.push(renderBorder(\"├\", \"┼\", \"┤\", columnWidths));\n }\n });\n\n if (shouldDrawLine(rowCount)) {\n lines.push(renderBorder(\"└\", \"┴\", \"┘\", columnWidths));\n }\n\n return `${lines.join(\"\\n\")}\\n`;\n}\n","const TRUTHY_VALUES = new Set([\"true\", \"t\", \"yes\", \"y\", \"on\", \"1\"]);\nconst FALSY_VALUES = new Set([\"false\", \"f\", \"no\", \"n\", \"off\", \"0\"]);\n\n/**\n * Parse a string value as a boolean.\n *\n * Recognized values (case-insensitive, trimmed) follow Python's\n * `distutils.util.strtobool` convention:\n * - truthy: `true, t, yes, y, on, 1`\n * - falsy: `false, f, no, n, off, 0`\n *\n * Undefined, empty strings, and unrecognized values return `undefined` so\n * that callers can fall back to their own defaults.\n * @param value - The input string (e.g. an environment variable or CLI flag value)\n * @returns `true`, `false`, or `undefined` when the value is unset or unrecognized\n */\nexport function parseBoolean(value: string | undefined): boolean | undefined {\n if (value === undefined) return undefined;\n const normalized = value.trim().toLowerCase();\n if (normalized === \"\") return undefined;\n if (TRUTHY_VALUES.has(normalized)) return true;\n if (FALSY_VALUES.has(normalized)) return false;\n return undefined;\n}\n","import { formatWithOptions, type InspectOptions } from \"node:util\";\nimport { color, renderFor } from \"@tailor-platform/shared/color\";\nimport { formatDistanceToNowStrict } from \"date-fns\";\nimport { renderTable } from \"./ascii-table\";\nimport { parseBoolean } from \"./parse-boolean\";\n\n/**\n * Error thrown when a prompt is attempted in a non-interactive environment\n */\nexport class CIPromptError extends Error {\n constructor(message?: string) {\n super(\n message ??\n \"Interactive prompts are not available in this environment. Provide the required options explicitly.\",\n );\n this.name = \"CIPromptError\";\n }\n}\n\n/**\n * Semantic style functions for inline text styling\n */\nexport const styles = {\n // Status colors\n success: color.green,\n error: color.red,\n warning: color.yellow,\n info: color.cyan,\n\n // Action colors (for change sets)\n create: color.green,\n update: color.yellow,\n delete: color.red,\n replace: color.magenta,\n unchanged: color.gray,\n\n // Emphasis\n bold: color.bold,\n dim: color.gray,\n highlight: color.cyanBright,\n successBright: color.greenBright,\n errorBright: color.redBright,\n\n // Resource types\n resourceType: color.bold,\n resourceName: color.cyan,\n\n // File paths\n path: color.cyan,\n\n // Values\n value: color.white,\n placeholder: (text: string) => color.italic(color.gray(text)),\n};\n\n/**\n * Standardized symbols for CLI output\n */\nexport const symbols = {\n success: styles.success(\"\\u2713\"),\n error: styles.error(\"\\u2716\"),\n warning: styles.warning(\"\\u26a0\"),\n info: styles.info(\"i\"),\n create: styles.create(\"+\"),\n update: styles.update(\"~\"),\n delete: styles.delete(\"-\"),\n replace: styles.replace(\"\\u00b1\"),\n bullet: styles.dim(\"\\u2022\"),\n arrow: styles.dim(\"\\u2192\"),\n};\n\n/**\n * Log output modes\n */\nexport type LogMode = \"default\" | \"stream\" | \"plain\";\n\nexport interface LogOptions {\n /** Output mode (default: \"default\") */\n mode?: LogMode;\n /** Number of spaces to indent the entire line (default: 0) */\n indent?: number;\n}\n\n/** Field transformer function. null excludes the field from table output. */\nexport type FieldTransformer = ((value: unknown, item: object) => string) | null;\n\nexport interface OutOptions {\n /** Table display field transform/exclude settings. Only applied in table mode (not JSON). */\n display?: Record<string, FieldTransformer>;\n\n /** Show null values in table output (default: false) */\n showNull?: boolean;\n}\n\n// In JSON mode, all logs go to stderr to keep stdout clean for JSON data\nlet _jsonMode = false;\nlet _verbose = false;\n\n// Values registered via `logger.registerSecret()`, redacted from diagnostic log output\nconst _secrets = new Set<string>();\nconst REDACTED_PLACEHOLDER = \"<redacted>\";\n// Below this length, a registered value is too likely to match unrelated text.\nconst MIN_SECRET_LENGTH = 4;\n\n/**\n * Aho-Corasick trie node. Indexed by individual UTF-16 code units (not Unicode code\n * points), matching how `string.indexOf`/`.slice` already index this file's strings — a\n * surrogate-pair character occupies two nodes, same as it occupies two `string` indices.\n */\ninterface TrieNode {\n children: Map<string, TrieNode>;\n fail: TrieNode;\n /** Secrets ending at this node, including those reached via `fail` links (precomputed). */\n outputs: string[];\n}\n\n/**\n * Builds a multi-pattern matcher for every registered secret, so `findSecretSpans` below\n * can find all of their occurrences in one pass over the text (`O(text.length + matches)`)\n * instead of scanning the full text once per registered secret. Rebuilt only when\n * `registerSecret` adds a genuinely new value (see `_automaton` below), so its\n * `O(total secret length)` construction cost is amortized across every log line redacted\n * while the secret set doesn't change.\n * @param secrets - Currently registered secrets\n * @returns Root of the built trie\n */\nfunction buildAutomaton(secrets: ReadonlySet<string>): TrieNode {\n const root: TrieNode = {\n children: new Map(),\n fail: undefined as unknown as TrieNode,\n outputs: [],\n };\n root.fail = root;\n\n for (const secret of secrets) {\n let node = root;\n for (let i = 0; i < secret.length; i++) {\n const ch = secret[i] as string;\n let next = node.children.get(ch);\n if (!next) {\n next = { children: new Map(), fail: root, outputs: [] };\n node.children.set(ch, next);\n }\n node = next;\n }\n node.outputs.push(secret);\n }\n\n // A head index instead of Array#shift(): shift() re-indexes every remaining element on\n // each call, which would make this loop quadratic in the number of trie nodes rather than\n // the linear BFS this is meant to be.\n const queue: TrieNode[] = [...root.children.values()];\n for (let head = 0; head < queue.length; head++) {\n const parent = queue[head] as TrieNode;\n for (const [ch, child] of parent.children) {\n let fail = parent.fail;\n while (fail !== root && !fail.children.has(ch)) fail = fail.fail;\n child.fail = fail.children.get(ch) ?? root;\n child.outputs = child.outputs.concat(child.fail.outputs);\n queue.push(child);\n }\n }\n return root;\n}\n\n// Cached automaton for the current `_secrets` contents; `null` means rebuild on next use.\n// Invalidated only when `registerSecret` actually grows `_secrets` (Set#add on an existing\n// value is a no-op), so re-registering an already-known secret never triggers a rebuild.\nlet _automaton: TrieNode | null = null;\n\nfunction getAutomaton(): TrieNode {\n _automaton ??= buildAutomaton(_secrets);\n return _automaton;\n}\n\n/**\n * Finds every occurrence of every registered secret in `text`, including overlapping ones,\n * in a single pass over `text` via the Aho-Corasick automaton.\n * @param text - Text to search\n * @returns Match spans as `[start, end)` pairs, in the order found\n */\nfunction findSecretSpans(text: string): Array<[start: number, end: number]> {\n const spans: Array<[start: number, end: number]> = [];\n const root = getAutomaton();\n let node = root;\n for (let i = 0; i < text.length; i++) {\n const ch = text[i] as string;\n while (node !== root && !node.children.has(ch)) node = node.fail;\n node = node.children.get(ch) ?? root;\n for (const secret of node.outputs) {\n spans.push([i + 1 - secret.length, i + 1]);\n }\n }\n return spans;\n}\n\n/**\n * Redacts every registered secret from `text` in a single pass over the original text.\n *\n * Matches are found against the original text only - never against text a previous\n * replacement produced - and overlapping/adjacent matches (whether one secret contains\n * another, or two secrets merely cross, e.g. registering \"abcde\" and \"defghi\" against\n * \"abcdefghi\") are merged into one contiguous span before any substitution happens. This\n * avoids two failure modes an iterative \"replace one secret, then the next\" approach has:\n * a later secret re-matching inside a placeholder a previous replacement already inserted,\n * and a crossing (non-nested) overlap leaving a fragment of one secret unredacted.\n *\n * Idempotent: a match that falls inside an occurrence of `<redacted>` already present in\n * `text` is discarded rather than substituted again. Without this, calling this function\n * twice on the same text (which happens whenever something already redacted, such as a\n * `--json` error envelope, is later passed to a diagnostic log call) could corrupt the\n * placeholder itself if a registered secret happens to be one of its substrings (e.g. a\n * secret literally containing \"redact\").\n * @param text - Text to redact\n * @returns `text` with every registered secret occurrence replaced by `<redacted>`\n */\nexport function redactSecrets(text: string): string {\n if (_secrets.size === 0) return text;\n\n const protectedSpans: Array<[start: number, end: number]> = [];\n for (let from = 0, index: number; (index = text.indexOf(REDACTED_PLACEHOLDER, from)) !== -1;) {\n protectedSpans.push([index, index + REDACTED_PLACEHOLDER.length]);\n from = index + REDACTED_PLACEHOLDER.length;\n }\n\n // Only a match wholly inside a protected placeholder is discarded (it can only be the\n // placeholder's own text, e.g. a registered secret that is a substring of \"redacted\").\n // A match that merely overlaps one — extending outside it, e.g. a registered secret that\n // happens to be \"leak<redacted>\" — still has real secret content outside the placeholder\n // and must still be replaced.\n //\n // A registered secret wholly contained in the placeholder (up to and including a secret\n // equal to \"<redacted>\" itself) is indistinguishable from the placeholder in rendered\n // output either way: substituting REDACTED_PLACEHOLDER for text that already reads\n // REDACTED_PLACEHOLDER is a no-op. Discarding the match here (rather than \"fixing\" it to\n // substitute anyway) isn't a redaction gap — it just skips redundant work on text that's\n // already the safe, masked form.\n const spans = findSecretSpans(text).filter(\n ([start, end]) => !protectedSpans.some(([pStart, pEnd]) => start >= pStart && end <= pEnd),\n );\n if (spans.length === 0) return text;\n spans.sort(([a], [b]) => a - b);\n\n const merged: Array<[start: number, end: number]> = [];\n for (const span of spans) {\n const last = merged.at(-1);\n if (last && span[0] <= last[1]) {\n last[1] = Math.max(last[1], span[1]);\n } else {\n merged.push(span);\n }\n }\n\n let result = \"\";\n let cursor = 0;\n for (const [start, end] of merged) {\n result += text.slice(cursor, start) + REDACTED_PLACEHOLDER;\n cursor = end;\n }\n return result + text.slice(cursor);\n}\n\n/**\n * Reset the registered-secret redaction state. Used for testing.\n *\n * `_secrets` is process-lifetime, module-level state with no production unregister API\n * (a real process should never stop hiding a secret it once saw). Test files that call\n * `logger.registerSecret()` and run in a Vitest project with `isolate: false` share this\n * state across files, so a value registered in one file's test can still be redacted in an\n * unrelated later file's assertions unless cleared between tests.\n */\nexport function resetSecretRegistry(): void {\n _secrets.clear();\n _automaton = null;\n}\n\n// Type icons for log output\nconst TYPE_ICONS: Record<string, string> = {\n info: \"ℹ\",\n success: \"✔\",\n warn: \"⚠\",\n error: \"✖\",\n debug: \"⚙\",\n trace: \"→\",\n log: \"\",\n};\n\n// Color functions for icon and message text\nconst TYPE_COLORS: Record<string, (text: string) => string> = {\n info: styles.info,\n success: styles.success,\n warn: styles.warning,\n error: styles.error,\n debug: styles.dim,\n trace: styles.dim,\n log: (text) => text,\n};\n\ninterface FormatLogLineOptions {\n mode: string;\n indent: number;\n type: string;\n message: string;\n timestamp?: string;\n}\n\n/**\n * Formats a log line with the appropriate prefix and indentation\n * @param opts - Formatting options\n * @returns Formatted log line\n */\nexport function formatLogLine(opts: FormatLogLineOptions): string {\n const { mode, indent, type, message, timestamp } = opts;\n const indentPrefix = indent > 0 ? \" \".repeat(indent) : \"\";\n const colorFn = TYPE_COLORS[type] || ((text: string) => text);\n\n // Plain mode: color only, no icon, no timestamp\n if (mode === \"plain\") {\n return `${indentPrefix}${colorFn(message)}\\n`;\n }\n\n // Default/Stream mode: with icon and color\n const icon = TYPE_ICONS[type] || \"\";\n const prefix = icon ? `${icon} ` : \"\";\n const coloredOutput = colorFn(`${prefix}${message}`);\n const timestampPrefix = timestamp ?? \"\";\n\n return `${indentPrefix}${timestampPrefix}${coloredOutput}\\n`;\n}\n\n/**\n * Writes a formatted log line to stderr.\n * @param type - Log type (info, success, warn, error, log)\n * @param message - Log message\n * @param opts - Log options (mode and indent)\n */\nfunction writeLog(type: string, message: string, opts?: LogOptions): void {\n const mode = opts?.mode ?? \"default\";\n const indent = opts?.indent ?? 0;\n const inspectOpts: InspectOptions = {\n breakLength: process.stdout.columns || 80,\n };\n const formattedMessage = formatWithOptions(inspectOpts, message);\n const timestamp = mode === \"stream\" ? `${new Date().toLocaleTimeString()} ` : \"\";\n const output = formatLogLine({ mode, indent, type, message: formattedMessage, timestamp });\n process.stderr.write(renderFor(process.stderr, redactSecrets(output)));\n}\n\n/**\n * The CLI logger. Diagnostics go to stderr; `out()` writes primary output to\n * stdout as a table, or as JSON when `jsonMode` is on. `--json` and\n * `--verbose` feed the `jsonMode` / `verbose` state, which CLI plugins share\n * with the SDK code paths they call.\n */\nexport const logger = {\n get jsonMode(): boolean {\n return _jsonMode;\n },\n set jsonMode(value: boolean) {\n _jsonMode = value;\n },\n\n get verbose(): boolean {\n return _verbose || parseBoolean(process.env.DEBUG) === true || process.env.RUNNER_DEBUG === \"1\";\n },\n set verbose(value: boolean) {\n _verbose = value;\n },\n\n info(message: string, opts?: LogOptions): void {\n writeLog(\"info\", message, opts);\n },\n\n success(message: string, opts?: LogOptions): void {\n writeLog(\"success\", message, opts);\n },\n\n warn(message: string, opts?: LogOptions): void {\n writeLog(\"warn\", message, opts);\n },\n\n error(message: string, opts?: LogOptions): void {\n writeLog(\"error\", message, opts);\n },\n\n log(message: string): void {\n writeLog(\"log\", message, { mode: \"plain\" });\n },\n\n newline(): void {\n process.stderr.write(\"\\n\");\n },\n\n debug(message: string): void {\n if (logger.verbose) {\n writeLog(\"log\", styles.dim(message), { mode: \"plain\" });\n }\n },\n\n /**\n * Registers a value to be redacted from diagnostic log output (`info`/`success`/`warn`/\n * `error`/`log`/`debug`). Any occurrence of `value` — or of its JSON-string-escaped form\n * (so a value embedded in `JSON.stringify`d output, e.g. `--json` mode error envelopes, is\n * also caught) or its `application/x-www-form-urlencoded` form (so a value that reached the\n * process via a URL query string, e.g. an OAuth authorization code decoded from a callback\n * URL via `URLSearchParams`, is still caught if that same URL — still encoded — is later\n * echoed into a diagnostic message) — is replaced with `<redacted>` before it reaches\n * stderr. Does not affect `out()`, since some commands intentionally print secret values as\n * their primary result.\n *\n * Values shorter than 4 characters are ignored, since they are too likely to match\n * unrelated text. A non-string value (e.g. `undefined` from an unvalidated external\n * payload cast to a typed shape) is ignored the same way, rather than throwing, since a\n * logging call must never be what crashes the process.\n * @param value - The secret value to redact from future log output\n */\n registerSecret(value: string): void {\n // Counts Unicode code points, not UTF-16 code units, so a value made of surrogate-pair\n // characters (e.g. emoji) isn't undercounted as longer than it actually is.\n if (typeof value !== \"string\" || [...value].length < MIN_SECRET_LENGTH) return;\n const sizeBefore = _secrets.size;\n _secrets.add(value);\n const jsonEscaped = JSON.stringify(value).slice(1, -1);\n if (jsonEscaped !== value) _secrets.add(jsonEscaped);\n // Uses URLSearchParams rather than encodeURIComponent: form-urlencoding (what\n // URLSearchParams produces, and what a URL query string actually contains) encodes a\n // space as \"+\", not \"%20\", and unlike encodeURIComponent it never throws on a lone\n // surrogate (invalid UTF-16) — it substitutes U+FFFD instead, matching how the URL\n // itself would already have encoded that same malformed input.\n const formEncoded = new URLSearchParams([[\"v\", value]]).toString().slice(2);\n if (formEncoded !== value) _secrets.add(formEncoded);\n // Set#add on an already-registered value is a no-op, so this only invalidates the\n // cached automaton (see findSecretSpans) when a genuinely new secret was added.\n if (_secrets.size !== sizeBefore) _automaton = null;\n },\n\n out(data: string | object | object[], options?: OutOptions): void {\n if (typeof data === \"string\") {\n process.stdout.write(renderFor(process.stdout, data.endsWith(\"\\n\") ? data : data + \"\\n\"));\n return;\n }\n\n if (this.jsonMode) {\n // eslint-disable-next-line no-restricted-syntax\n console.log(JSON.stringify(data));\n return;\n }\n\n const display = options?.display;\n\n // Helper to format a value for table display\n const formatValue = (value: unknown, pretty = false): string => {\n if (options?.showNull && value === null) return \"NULL\";\n if (value === null || value === undefined) return \"N/A\";\n if (value instanceof Date) {\n return formatDistanceToNowStrict(value, { addSuffix: true });\n }\n if (typeof value === \"object\") {\n return pretty ? JSON.stringify(value, null, 2) : JSON.stringify(value);\n }\n return String(value);\n };\n\n // Helper to check if field should be excluded\n const isExcluded = (key: string): boolean => {\n return display !== undefined && key in display && display[key] === null;\n };\n\n // Helper to apply transformer or default formatting\n const transformValue = (key: string, value: unknown, item: object, pretty = false): string => {\n if (display && key in display) {\n const transformer = display[key];\n if (transformer) {\n return transformer(value, item);\n }\n }\n return formatValue(value, pretty);\n };\n\n if (!Array.isArray(data)) {\n const entries = Object.entries(data).filter(([key]) => !isExcluded(key));\n const formattedEntries = entries.map(([key, value]) => [\n key,\n transformValue(key, value, data, true),\n ]);\n const t = renderTable(formattedEntries, { singleLine: false });\n process.stdout.write(renderFor(process.stdout, t));\n return;\n }\n\n if (data.length === 0) {\n return;\n }\n\n const allHeaders = Array.from(new Set(data.flatMap((item) => Object.keys(item))));\n const headers = allHeaders.filter((h) => !isExcluded(h));\n if (headers.length === 0) {\n return;\n }\n const rows = data.map((item) =>\n headers.map((header) =>\n transformValue(header, (item as Record<string, unknown>)[header], item),\n ),\n );\n\n const t = renderTable([headers, ...rows], {\n drawHorizontalLine: (lineIndex, rowCount) => {\n return lineIndex === 0 || lineIndex === 1 || lineIndex === rowCount;\n },\n });\n process.stdout.write(renderFor(process.stdout, t));\n },\n};\n"],"mappings":"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"}